mirror of
https://github.com/ton-blockchain/ton
synced 2025-02-15 04:32:21 +00:00
Shardchain validation without monitoring shardchains
This commit is contained in:
parent
bdfca7afef
commit
996c23e506
22 changed files with 210 additions and 88 deletions
|
@ -236,9 +236,7 @@ class HardforkCreator : public td::actor::Actor {
|
|||
td::actor::send_closure(id_, &ton::validator::ValidatorManager::sync_complete,
|
||||
td::PromiseCreator::lambda([](td::Unit) {}));
|
||||
}
|
||||
void add_shard(ton::ShardIdFull) override {
|
||||
}
|
||||
void del_shard(ton::ShardIdFull) override {
|
||||
void subscribe_to_shard(ton::ShardIdFull) override {
|
||||
}
|
||||
void send_ihr_message(ton::AccountIdPrefixFull dst, td::BufferSlice data) override {
|
||||
}
|
||||
|
|
|
@ -98,6 +98,15 @@ void OverlayManager::create_public_overlay(adnl::AdnlNodeIdShort local_id, Overl
|
|||
std::move(callback), std::move(rules), scope));
|
||||
}
|
||||
|
||||
void OverlayManager::create_public_overlay_no_subscribe(adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id,
|
||||
OverlayPrivacyRules rules, td::string scope) {
|
||||
CHECK(!dht_node_.empty());
|
||||
auto id = overlay_id.compute_short_id();
|
||||
register_overlay(local_id, id,
|
||||
Overlay::create(keyring_, adnl_, actor_id(this), dht_node_, local_id, std::move(overlay_id), nullptr,
|
||||
std::move(rules), scope));
|
||||
}
|
||||
|
||||
void OverlayManager::create_private_overlay(adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id,
|
||||
std::vector<adnl::AdnlNodeIdShort> nodes,
|
||||
std::unique_ptr<Callback> callback, OverlayPrivacyRules rules) {
|
||||
|
|
|
@ -52,6 +52,8 @@ class OverlayManager : public Overlays {
|
|||
|
||||
void create_public_overlay(adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id,
|
||||
std::unique_ptr<Callback> callback, OverlayPrivacyRules rules, td::string scope) override;
|
||||
void create_public_overlay_no_subscribe(adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id,
|
||||
OverlayPrivacyRules rules, td::string scope) override;
|
||||
void create_private_overlay(adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id,
|
||||
std::vector<adnl::AdnlNodeIdShort> nodes, std::unique_ptr<Callback> callback,
|
||||
OverlayPrivacyRules rules) override;
|
||||
|
|
|
@ -149,6 +149,9 @@ void OverlayImpl::receive_query(adnl::AdnlNodeIdShort src, td::BufferSlice data,
|
|||
|
||||
if (R.is_error()) {
|
||||
// allow custom query to be here
|
||||
if (!subscribed()) {
|
||||
return;
|
||||
}
|
||||
callback_->receive_query(src, overlay_id_, std::move(data), std::move(promise));
|
||||
return;
|
||||
}
|
||||
|
@ -225,6 +228,9 @@ void OverlayImpl::receive_message(adnl::AdnlNodeIdShort src, td::BufferSlice dat
|
|||
}
|
||||
auto X = fetch_tl_object<ton_api::overlay_Broadcast>(data.clone(), true);
|
||||
if (X.is_error()) {
|
||||
if (!subscribed()) {
|
||||
return;
|
||||
}
|
||||
VLOG(OVERLAY_DEBUG) << this << ": received custom message";
|
||||
callback_->receive_message(src, overlay_id_, std::move(data));
|
||||
return;
|
||||
|
@ -268,7 +274,7 @@ void OverlayImpl::alarm() {
|
|||
}
|
||||
|
||||
if (public_) {
|
||||
if (peers_.size() > 0) {
|
||||
if (peers_.size() > 0 && subscribed()) {
|
||||
auto P = get_random_peer();
|
||||
if (P) {
|
||||
send_random_peers(P->get_id(), {});
|
||||
|
@ -336,7 +342,7 @@ void OverlayImpl::receive_dht_nodes(td::Result<dht::DhtValue> res, bool dummy) {
|
|||
}
|
||||
|
||||
void OverlayImpl::update_dht_nodes(OverlayNode node) {
|
||||
if (!public_) {
|
||||
if (!public_ || !subscribed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -497,6 +503,9 @@ void OverlayImpl::send_new_fec_broadcast_part(PublicKeyHash local_id, Overlay::B
|
|||
}
|
||||
|
||||
void OverlayImpl::deliver_broadcast(PublicKeyHash source, td::BufferSlice data) {
|
||||
if (!subscribed()) {
|
||||
return;
|
||||
}
|
||||
callback_->receive_broadcast(source, overlay_id_, std::move(data));
|
||||
}
|
||||
|
||||
|
@ -569,6 +578,9 @@ void OverlayImpl::set_privacy_rules(OverlayPrivacyRules rules) {
|
|||
}
|
||||
|
||||
void OverlayImpl::check_broadcast(PublicKeyHash src, td::BufferSlice data, td::Promise<td::Unit> promise) {
|
||||
if (!subscribed()) {
|
||||
return;
|
||||
}
|
||||
callback_->check_broadcast(src, overlay_id_, std::move(data), std::move(promise));
|
||||
}
|
||||
|
||||
|
|
|
@ -251,8 +251,15 @@ class OverlayImpl : public Overlay {
|
|||
}
|
||||
|
||||
private:
|
||||
bool subscribed() const {
|
||||
return (bool)callback_;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void process_query(adnl::AdnlNodeIdShort src, T &query, td::Promise<td::BufferSlice> promise) {
|
||||
if (!subscribed()) {
|
||||
return;
|
||||
}
|
||||
callback_->receive_query(src, overlay_id_, serialize_tl_object(&query, true), std::move(promise));
|
||||
}
|
||||
|
||||
|
|
|
@ -194,6 +194,8 @@ class Overlays : public td::actor::Actor {
|
|||
|
||||
virtual void create_public_overlay(adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id,
|
||||
std::unique_ptr<Callback> callback, OverlayPrivacyRules rules, td::string scope) = 0;
|
||||
virtual void create_public_overlay_no_subscribe(adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id,
|
||||
OverlayPrivacyRules rules, td::string scope) = 0;
|
||||
virtual void create_private_overlay(adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id,
|
||||
std::vector<adnl::AdnlNodeIdShort> nodes, std::unique_ptr<Callback> callback,
|
||||
OverlayPrivacyRules rules) = 0;
|
||||
|
|
|
@ -323,9 +323,7 @@ class TestNode : public td::actor::Actor {
|
|||
td::actor::send_closure(id_, &ton::validator::ValidatorManager::sync_complete,
|
||||
td::PromiseCreator::lambda([](td::Unit) {}));
|
||||
}
|
||||
void add_shard(ton::ShardIdFull) override {
|
||||
}
|
||||
void del_shard(ton::ShardIdFull) override {
|
||||
void subscribe_to_shard(ton::ShardIdFull) override {
|
||||
}
|
||||
void send_ihr_message(ton::AccountIdPrefixFull dst, td::BufferSlice data) override {
|
||||
}
|
||||
|
|
|
@ -1300,10 +1300,10 @@ td::Status ValidatorEngine::load_global_config() {
|
|||
|
||||
validator_options_ = ton::validator::ValidatorManagerOptions::create(zero_state, init_block);
|
||||
validator_options_.write().set_shard_check_function(
|
||||
[](ton::ShardIdFull shard, ton::CatchainSeqno cc_seqno,
|
||||
[masterchain_only = masterchain_only_](ton::ShardIdFull shard, ton::CatchainSeqno cc_seqno,
|
||||
ton::validator::ValidatorManagerOptions::ShardCheckMode mode) -> bool {
|
||||
if (mode == ton::validator::ValidatorManagerOptions::ShardCheckMode::m_monitor) {
|
||||
return true;
|
||||
return shard.is_masterchain() || !masterchain_only;
|
||||
}
|
||||
CHECK(mode == ton::validator::ValidatorManagerOptions::ShardCheckMode::m_validate);
|
||||
return true;
|
||||
|
@ -3648,6 +3648,9 @@ int main(int argc, char *argv[]) {
|
|||
});
|
||||
return td::Status::OK();
|
||||
});
|
||||
p.add_option('M', "masterchain-only", "don't track shardchains", [&]() {
|
||||
acts.push_back([&x]() { td::actor::send_closure(x, &ValidatorEngine::set_masterchain_only); });
|
||||
});
|
||||
td::uint32 threads = 7;
|
||||
p.add_checked_option(
|
||||
't', "threads", PSTRING() << "number of threads (default=" << threads << ")", [&](td::Slice fname) {
|
||||
|
|
|
@ -202,6 +202,7 @@ class ValidatorEngine : public td::actor::Actor {
|
|||
bool started_ = false;
|
||||
ton::BlockSeqno truncate_seqno_{0};
|
||||
std::string session_logs_file_;
|
||||
bool masterchain_only_ = false;
|
||||
|
||||
std::set<ton::CatchainSeqno> unsafe_catchains_;
|
||||
std::map<ton::BlockSeqno, std::pair<ton::CatchainSeqno, td::uint32>> unsafe_catchain_rotations_;
|
||||
|
@ -253,6 +254,9 @@ class ValidatorEngine : public td::actor::Actor {
|
|||
void add_key_to_set(ton::PublicKey key) {
|
||||
keys_[key.compute_short_id()] = key;
|
||||
}
|
||||
void set_masterchain_only() {
|
||||
masterchain_only_ = true;
|
||||
}
|
||||
void start_up() override;
|
||||
ValidatorEngine() {
|
||||
}
|
||||
|
|
|
@ -59,6 +59,10 @@ void run_fake_accept_block_query(BlockIdExt id, td::Ref<BlockData> data, std::ve
|
|||
td::Promise<td::Unit> promise);
|
||||
void run_hardfork_accept_block_query(BlockIdExt id, td::Ref<BlockData> data,
|
||||
td::actor::ActorId<ValidatorManager> manager, td::Promise<td::Unit> promise);
|
||||
void run_broadcast_only_accept_block_query(BlockIdExt id, td::Ref<BlockData> data, std::vector<BlockIdExt> prev,
|
||||
td::Ref<ValidatorSet> validator_set, td::Ref<BlockSignatureSet> signatures,
|
||||
td::Ref<BlockSignatureSet> approve_signatures,
|
||||
td::actor::ActorId<ValidatorManager> manager, td::Promise<td::Unit> promise);
|
||||
void run_apply_block_query(BlockIdExt id, td::Ref<BlockData> block, BlockIdExt masterchain_block_id,
|
||||
td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout,
|
||||
td::Promise<td::Unit> promise);
|
||||
|
|
|
@ -69,31 +69,41 @@ void Neighbour::update_roundtrip(double t) {
|
|||
}
|
||||
|
||||
void FullNodeShardImpl::create_overlay() {
|
||||
class Callback : public overlay::Overlays::Callback {
|
||||
public:
|
||||
void receive_message(adnl::AdnlNodeIdShort src, overlay::OverlayIdShort overlay_id, td::BufferSlice data) override {
|
||||
// just ignore
|
||||
}
|
||||
void receive_query(adnl::AdnlNodeIdShort src, overlay::OverlayIdShort overlay_id, td::BufferSlice data,
|
||||
td::Promise<td::BufferSlice> promise) override {
|
||||
td::actor::send_closure(node_, &FullNodeShardImpl::receive_query, src, std::move(data), std::move(promise));
|
||||
}
|
||||
void receive_broadcast(PublicKeyHash src, overlay::OverlayIdShort overlay_id, td::BufferSlice data) override {
|
||||
td::actor::send_closure(node_, &FullNodeShardImpl::receive_broadcast, src, std::move(data));
|
||||
}
|
||||
void check_broadcast(PublicKeyHash src, overlay::OverlayIdShort overlay_id, td::BufferSlice data,
|
||||
td::Promise<td::Unit> promise) override {
|
||||
td::actor::send_closure(node_, &FullNodeShardImpl::check_broadcast, src, std::move(data), std::move(promise));
|
||||
}
|
||||
Callback(td::actor::ActorId<FullNodeShardImpl> node) : node_(node) {
|
||||
}
|
||||
if (subscribed_) {
|
||||
class Callback : public overlay::Overlays::Callback {
|
||||
public:
|
||||
void receive_message(adnl::AdnlNodeIdShort src, overlay::OverlayIdShort overlay_id,
|
||||
td::BufferSlice data) override {
|
||||
// just ignore
|
||||
}
|
||||
void receive_query(adnl::AdnlNodeIdShort src, overlay::OverlayIdShort overlay_id, td::BufferSlice data,
|
||||
td::Promise<td::BufferSlice> promise) override {
|
||||
td::actor::send_closure(node_, &FullNodeShardImpl::receive_query, src, std::move(data), std::move(promise));
|
||||
}
|
||||
void receive_broadcast(PublicKeyHash src, overlay::OverlayIdShort overlay_id, td::BufferSlice data) override {
|
||||
td::actor::send_closure(node_, &FullNodeShardImpl::receive_broadcast, src, std::move(data));
|
||||
}
|
||||
void check_broadcast(PublicKeyHash src, overlay::OverlayIdShort overlay_id, td::BufferSlice data,
|
||||
td::Promise<td::Unit> promise) override {
|
||||
td::actor::send_closure(node_, &FullNodeShardImpl::check_broadcast, src, std::move(data), std::move(promise));
|
||||
}
|
||||
Callback(td::actor::ActorId<FullNodeShardImpl> node) : node_(node) {
|
||||
}
|
||||
|
||||
private:
|
||||
td::actor::ActorId<FullNodeShardImpl> node_;
|
||||
};
|
||||
private:
|
||||
td::actor::ActorId<FullNodeShardImpl> node_;
|
||||
};
|
||||
|
||||
td::actor::send_closure(overlays_, &overlay::Overlays::create_public_overlay, adnl_id_, overlay_id_full_.clone(),
|
||||
std::make_unique<Callback>(actor_id(this)), rules_, PSTRING() << "{ \"type\": \"shard\", \"shard_id\": " << get_shard() << ", \"workchain_id\": " << get_workchain() << " }");
|
||||
td::actor::send_closure(overlays_, &overlay::Overlays::create_public_overlay, adnl_id_, overlay_id_full_.clone(),
|
||||
std::make_unique<Callback>(actor_id(this)), rules_,
|
||||
PSTRING() << "{ \"type\": \"shard\", \"shard_id\": " << get_shard()
|
||||
<< ", \"workchain_id\": " << get_workchain() << " }");
|
||||
} else {
|
||||
td::actor::send_closure(overlays_, &overlay::Overlays::create_public_overlay_no_subscribe, adnl_id_,
|
||||
overlay_id_full_.clone(), rules_,
|
||||
PSTRING() << "{ \"type\": \"shard\", \"shard_id\": " << get_shard()
|
||||
<< ", \"workchain_id\": " << get_workchain() << " }");
|
||||
}
|
||||
|
||||
td::actor::send_closure(rldp_, &rldp::Rldp::add_id, adnl_id_);
|
||||
if (cert_) {
|
||||
|
@ -119,6 +129,15 @@ void FullNodeShardImpl::update_adnl_id(adnl::AdnlNodeIdShort adnl_id, td::Promis
|
|||
create_overlay();
|
||||
}
|
||||
|
||||
void FullNodeShardImpl::subscribe_to_shard() {
|
||||
if (subscribed_ || !client_.empty()) {
|
||||
return;
|
||||
}
|
||||
td::actor::send_closure(overlays_, &ton::overlay::Overlays::delete_overlay, adnl_id_, overlay_id_);
|
||||
subscribed_ = true;
|
||||
create_overlay();
|
||||
}
|
||||
|
||||
void FullNodeShardImpl::try_get_next_block(td::Timestamp timeout, td::Promise<ReceivedBlock> promise) {
|
||||
if (timeout.is_in_past()) {
|
||||
promise.set_error(td::Status::Error(ErrorCode::timeout, "timeout"));
|
||||
|
@ -576,8 +595,14 @@ void FullNodeShardImpl::process_broadcast(PublicKeyHash src, ton_api::tonNode_ex
|
|||
}
|
||||
|
||||
void FullNodeShardImpl::process_broadcast(PublicKeyHash src, ton_api::tonNode_newShardBlockBroadcast &query) {
|
||||
auto block_id = create_block_id(query.block_->block_);
|
||||
if (block_id.shard_full() != shard_) {
|
||||
LOG(WARNING) << "dropping newShardBlockBroadcast: expected shard " << shard_.to_str() << ", got shard "
|
||||
<< block_id.shard_full().to_str();
|
||||
return;
|
||||
}
|
||||
td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::new_shard_block,
|
||||
create_block_id(query.block_->block_), query.block_->cc_seqno_,
|
||||
block_id, query.block_->cc_seqno_,
|
||||
std::move(query.block_->data_));
|
||||
}
|
||||
|
||||
|
@ -588,6 +613,11 @@ void FullNodeShardImpl::process_broadcast(PublicKeyHash src, ton_api::tonNode_bl
|
|||
}
|
||||
|
||||
BlockIdExt block_id = create_block_id(query.id_);
|
||||
if (block_id.shard_full() != shard_) {
|
||||
LOG(WARNING) << "dropping blockBroadcast: expected shard " << shard_.to_str() << ", got shard "
|
||||
<< block_id.shard_full().to_str();
|
||||
return;
|
||||
}
|
||||
BlockBroadcast B{block_id,
|
||||
std::move(signatures),
|
||||
static_cast<UnixTime>(query.catchain_seqno_),
|
||||
|
@ -817,6 +847,10 @@ void FullNodeShardImpl::start_up() {
|
|||
}
|
||||
}
|
||||
|
||||
void FullNodeShardImpl::tear_down() {
|
||||
td::actor::send_closure(overlays_, &ton::overlay::Overlays::delete_overlay, adnl_id_, overlay_id_);
|
||||
}
|
||||
|
||||
void FullNodeShardImpl::sign_new_certificate(PublicKeyHash sign_by) {
|
||||
if (sign_by.is_zero()) {
|
||||
return;
|
||||
|
@ -1053,7 +1087,7 @@ FullNodeShardImpl::FullNodeShardImpl(ShardIdFull shard, PublicKeyHash local_id,
|
|||
td::actor::ActorId<adnl::Adnl> adnl, td::actor::ActorId<rldp::Rldp> rldp,
|
||||
td::actor::ActorId<overlay::Overlays> overlays,
|
||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
|
||||
td::actor::ActorId<adnl::AdnlExtClient> client)
|
||||
td::actor::ActorId<adnl::AdnlExtClient> client, bool subscribe)
|
||||
: shard_(shard)
|
||||
, local_id_(local_id)
|
||||
, adnl_id_(adnl_id)
|
||||
|
@ -1063,16 +1097,18 @@ FullNodeShardImpl::FullNodeShardImpl(ShardIdFull shard, PublicKeyHash local_id,
|
|||
, rldp_(rldp)
|
||||
, overlays_(overlays)
|
||||
, validator_manager_(validator_manager)
|
||||
, client_(client) {
|
||||
, client_(client)
|
||||
, subscribed_(subscribe) {
|
||||
}
|
||||
|
||||
td::actor::ActorOwn<FullNodeShard> FullNodeShard::create(
|
||||
ShardIdFull shard, PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id, FileHash zero_state_file_hash,
|
||||
td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<adnl::Adnl> adnl,
|
||||
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<overlay::Overlays> overlays,
|
||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager, td::actor::ActorId<adnl::AdnlExtClient> client) {
|
||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager, td::actor::ActorId<adnl::AdnlExtClient> client,
|
||||
bool subscribe) {
|
||||
return td::actor::create_actor<FullNodeShardImpl>("tonnode", shard, local_id, adnl_id, zero_state_file_hash, keyring,
|
||||
adnl, rldp, overlays, validator_manager, client);
|
||||
adnl, rldp, overlays, validator_manager, client, subscribe);
|
||||
}
|
||||
|
||||
} // namespace fullnode
|
||||
|
|
|
@ -36,6 +36,7 @@ class FullNodeShard : public td::actor::Actor {
|
|||
virtual ShardIdFull get_shard_full() const = 0;
|
||||
|
||||
virtual void update_adnl_id(adnl::AdnlNodeIdShort adnl_id, td::Promise<td::Unit> promise) = 0;
|
||||
virtual void subscribe_to_shard() = 0;
|
||||
|
||||
virtual void send_ihr_message(td::BufferSlice data) = 0;
|
||||
virtual void send_external_message(td::BufferSlice data) = 0;
|
||||
|
@ -70,7 +71,8 @@ class FullNodeShard : public td::actor::Actor {
|
|||
ShardIdFull shard, PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id, FileHash zero_state_file_hash,
|
||||
td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<adnl::Adnl> adnl,
|
||||
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<overlay::Overlays> overlays,
|
||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager, td::actor::ActorId<adnl::AdnlExtClient> client);
|
||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager, td::actor::ActorId<adnl::AdnlExtClient> client,
|
||||
bool subscribe);
|
||||
};
|
||||
|
||||
} // namespace fullnode
|
||||
|
|
|
@ -80,6 +80,7 @@ class FullNodeShardImpl : public FullNodeShard {
|
|||
|
||||
void create_overlay();
|
||||
void update_adnl_id(adnl::AdnlNodeIdShort adnl_id, td::Promise<td::Unit> promise) override;
|
||||
virtual void subscribe_to_shard() override;
|
||||
|
||||
//td::Result<Block> fetch_block(td::BufferSlice data);
|
||||
void prevalidate_block(BlockIdExt block_id, td::BufferSlice data, td::BufferSlice proof,
|
||||
|
@ -167,6 +168,7 @@ class FullNodeShardImpl : public FullNodeShard {
|
|||
void set_handle(BlockHandle handle, td::Promise<td::Unit> promise) override;
|
||||
|
||||
void start_up() override;
|
||||
void tear_down() override;
|
||||
void alarm() override;
|
||||
|
||||
void update_validators(std::vector<PublicKeyHash> public_key_hashes, PublicKeyHash local_hash) override;
|
||||
|
@ -202,7 +204,7 @@ class FullNodeShardImpl : public FullNodeShard {
|
|||
td::actor::ActorId<adnl::Adnl> adnl, td::actor::ActorId<rldp::Rldp> rldp,
|
||||
td::actor::ActorId<overlay::Overlays> overlays,
|
||||
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
|
||||
td::actor::ActorId<adnl::AdnlExtClient> client);
|
||||
td::actor::ActorId<adnl::AdnlExtClient> client, bool subscribe);
|
||||
|
||||
private:
|
||||
bool use_new_download() const {
|
||||
|
@ -239,6 +241,8 @@ class FullNodeShardImpl : public FullNodeShard {
|
|||
td::Timestamp reload_neighbours_at_;
|
||||
td::Timestamp ping_neighbours_at_;
|
||||
adnl::AdnlNodeIdShort last_pinged_neighbour_ = adnl::AdnlNodeIdShort::zero();
|
||||
|
||||
bool subscribed_ = false;
|
||||
};
|
||||
|
||||
} // namespace fullnode
|
||||
|
|
|
@ -120,14 +120,17 @@ void FullNodeImpl::initial_read_complete(BlockHandle top_handle) {
|
|||
td::actor::send_closure(it->second, &FullNodeShard::set_handle, top_handle, std::move(P));
|
||||
}
|
||||
|
||||
void FullNodeImpl::add_shard(ShardIdFull shard) {
|
||||
void FullNodeImpl::add_shard(ShardIdFull shard, bool subscribe) {
|
||||
while (true) {
|
||||
if (shards_.count(shard) == 0) {
|
||||
auto it = shards_.find(shard);
|
||||
if (it == shards_.end()) {
|
||||
shards_.emplace(shard, FullNodeShard::create(shard, local_id_, adnl_id_, zero_state_file_hash_, keyring_, adnl_,
|
||||
rldp_, overlays_, validator_manager_, client_));
|
||||
rldp_, overlays_, validator_manager_, client_, subscribe));
|
||||
if (all_validators_.size() > 0) {
|
||||
td::actor::send_closure(shards_[shard], &FullNodeShard::update_validators, all_validators_, sign_cert_by_);
|
||||
}
|
||||
} else if (subscribe) {
|
||||
td::actor::send_closure(it->second, &FullNodeShard::subscribe_to_shard);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
@ -148,7 +151,7 @@ void FullNodeImpl::sync_completed() {
|
|||
}
|
||||
|
||||
void FullNodeImpl::send_ihr_message(AccountIdPrefixFull dst, td::BufferSlice data) {
|
||||
auto shard = get_shard(ShardIdFull{masterchainId});
|
||||
auto shard = get_shard(dst);
|
||||
if (shard.empty()) {
|
||||
VLOG(FULL_NODE_WARNING) << "dropping OUT ihr message to unknown shard";
|
||||
return;
|
||||
|
@ -166,7 +169,7 @@ void FullNodeImpl::send_ext_message(AccountIdPrefixFull dst, td::BufferSlice dat
|
|||
}
|
||||
|
||||
void FullNodeImpl::send_shard_block_info(BlockIdExt block_id, CatchainSeqno cc_seqno, td::BufferSlice data) {
|
||||
auto shard = get_shard(ShardIdFull{masterchainId, shardIdAll});
|
||||
auto shard = get_shard(block_id.shard_full());
|
||||
if (shard.empty()) {
|
||||
VLOG(FULL_NODE_WARNING) << "dropping OUT shard block info message to unknown shard";
|
||||
return;
|
||||
|
@ -175,7 +178,7 @@ void FullNodeImpl::send_shard_block_info(BlockIdExt block_id, CatchainSeqno cc_s
|
|||
}
|
||||
|
||||
void FullNodeImpl::send_broadcast(BlockBroadcast broadcast) {
|
||||
auto shard = get_shard(ShardIdFull{masterchainId});
|
||||
auto shard = get_shard(broadcast.block_id.shard_full());
|
||||
if (shard.empty()) {
|
||||
VLOG(FULL_NODE_WARNING) << "dropping OUT broadcast to unknown shard";
|
||||
return;
|
||||
|
@ -381,11 +384,8 @@ void FullNodeImpl::start_up() {
|
|||
void initial_read_complete(BlockHandle handle) override {
|
||||
td::actor::send_closure(id_, &FullNodeImpl::initial_read_complete, handle);
|
||||
}
|
||||
void add_shard(ShardIdFull shard) override {
|
||||
td::actor::send_closure(id_, &FullNodeImpl::add_shard, shard);
|
||||
}
|
||||
void del_shard(ShardIdFull shard) override {
|
||||
td::actor::send_closure(id_, &FullNodeImpl::del_shard, shard);
|
||||
void subscribe_to_shard(ShardIdFull shard) override {
|
||||
td::actor::send_closure(id_, &FullNodeImpl::add_shard, shard, true);
|
||||
}
|
||||
void send_ihr_message(AccountIdPrefixFull dst, td::BufferSlice data) override {
|
||||
td::actor::send_closure(id_, &FullNodeImpl::send_ihr_message, dst, std::move(data));
|
||||
|
@ -465,7 +465,7 @@ FullNodeImpl::FullNodeImpl(PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id
|
|||
, validator_manager_(validator_manager)
|
||||
, client_(client)
|
||||
, db_root_(db_root) {
|
||||
add_shard(ShardIdFull{masterchainId});
|
||||
add_shard(ShardIdFull{masterchainId}, true);
|
||||
}
|
||||
|
||||
td::actor::ActorOwn<FullNode> FullNode::create(ton::PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id,
|
||||
|
|
|
@ -52,7 +52,7 @@ class FullNodeImpl : public FullNode {
|
|||
|
||||
void update_adnl_id(adnl::AdnlNodeIdShort adnl_id, td::Promise<td::Unit> promise) override;
|
||||
|
||||
void add_shard(ShardIdFull shard);
|
||||
void add_shard(ShardIdFull shard, bool subscribe = false);
|
||||
void del_shard(ShardIdFull shard);
|
||||
|
||||
void sync_completed();
|
||||
|
|
|
@ -92,6 +92,28 @@ AcceptBlockQuery::AcceptBlockQuery(ForceFork ffork, BlockIdExt id, td::Ref<Block
|
|||
state_hash_.clear();
|
||||
}
|
||||
|
||||
AcceptBlockQuery::AcceptBlockQuery(BroadcastOnly, BlockIdExt id, td::Ref<BlockData> data, std::vector<BlockIdExt> prev,
|
||||
td::Ref<ValidatorSet> validator_set, td::Ref<BlockSignatureSet> signatures,
|
||||
td::Ref<BlockSignatureSet> approve_signatures,
|
||||
td::actor::ActorId<ValidatorManager> manager, td::Promise<td::Unit> promise)
|
||||
: id_(id)
|
||||
, data_(std::move(data))
|
||||
, prev_(std::move(prev))
|
||||
, validator_set_(std::move(validator_set))
|
||||
, signatures_(std::move(signatures))
|
||||
, approve_signatures_(std::move(approve_signatures))
|
||||
, is_fake_(false)
|
||||
, is_fork_(false)
|
||||
, send_broadcast_(true)
|
||||
, broadcast_only_(false)
|
||||
, manager_(manager)
|
||||
, promise_(std::move(promise)) {
|
||||
state_keep_old_hash_.clear();
|
||||
state_old_hash_.clear();
|
||||
state_hash_.clear();
|
||||
CHECK(prev_.size() > 0);
|
||||
}
|
||||
|
||||
bool AcceptBlockQuery::precheck_header() {
|
||||
VLOG(VALIDATOR_DEBUG) << "precheck_header()";
|
||||
// 0. sanity check
|
||||
|
@ -384,6 +406,15 @@ void AcceptBlockQuery::start_up() {
|
|||
return;
|
||||
}
|
||||
|
||||
if (broadcast_only_) {
|
||||
if (!create_new_proof()) {
|
||||
fatal_error("cannot generate proof for block "s + id_.to_str());
|
||||
return;
|
||||
}
|
||||
applied();
|
||||
return;
|
||||
}
|
||||
|
||||
td::actor::send_closure(
|
||||
manager_, &ValidatorManager::get_block_handle, id_, true, [SelfId = actor_id(this)](td::Result<BlockHandle> R) {
|
||||
check_send_error(SelfId, R) ||
|
||||
|
|
|
@ -48,6 +48,7 @@ class AcceptBlockQuery : public td::actor::Actor {
|
|||
public:
|
||||
struct IsFake {};
|
||||
struct ForceFork {};
|
||||
struct BroadcastOnly{};
|
||||
AcceptBlockQuery(BlockIdExt id, td::Ref<BlockData> data, std::vector<BlockIdExt> prev,
|
||||
td::Ref<ValidatorSet> validator_set, td::Ref<BlockSignatureSet> signatures,
|
||||
td::Ref<BlockSignatureSet> approve_signatures, bool send_broadcast,
|
||||
|
@ -57,6 +58,10 @@ class AcceptBlockQuery : public td::actor::Actor {
|
|||
td::Promise<td::Unit> promise);
|
||||
AcceptBlockQuery(ForceFork ffork, BlockIdExt id, td::Ref<BlockData> data,
|
||||
td::actor::ActorId<ValidatorManager> manager, td::Promise<td::Unit> promise);
|
||||
AcceptBlockQuery(BroadcastOnly, BlockIdExt id, td::Ref<BlockData> data, std::vector<BlockIdExt> prev,
|
||||
td::Ref<ValidatorSet> validator_set, td::Ref<BlockSignatureSet> signatures,
|
||||
td::Ref<BlockSignatureSet> approve_signatures, td::actor::ActorId<ValidatorManager> manager,
|
||||
td::Promise<td::Unit> promise);
|
||||
|
||||
private:
|
||||
static constexpr td::uint32 priority() {
|
||||
|
@ -98,6 +103,7 @@ class AcceptBlockQuery : public td::actor::Actor {
|
|||
bool is_fake_;
|
||||
bool is_fork_;
|
||||
bool send_broadcast_;
|
||||
bool broadcast_only_{false};
|
||||
bool ancestors_split_{false}, is_key_block_{false};
|
||||
td::Timestamp timeout_ = td::Timestamp::in(600.0);
|
||||
td::actor::ActorId<ValidatorManager> manager_;
|
||||
|
|
|
@ -151,6 +151,17 @@ void run_hardfork_accept_block_query(BlockIdExt id, td::Ref<BlockData> data,
|
|||
.release();
|
||||
}
|
||||
|
||||
void run_broadcast_only_accept_block_query(BlockIdExt id, td::Ref<BlockData> data, std::vector<BlockIdExt> prev,
|
||||
td::Ref<ValidatorSet> validator_set, td::Ref<BlockSignatureSet> signatures,
|
||||
td::Ref<BlockSignatureSet> approve_signatures,
|
||||
td::actor::ActorId<ValidatorManager> manager,
|
||||
td::Promise<td::Unit> promise) {
|
||||
td::actor::create_actor<AcceptBlockQuery>("broadcastaccept", AcceptBlockQuery::BroadcastOnly(), id, std::move(data),
|
||||
prev, std::move(validator_set), std::move(signatures),
|
||||
std::move(approve_signatures), manager, std::move(promise))
|
||||
.release();
|
||||
}
|
||||
|
||||
void run_apply_block_query(BlockIdExt id, td::Ref<BlockData> block, BlockIdExt masterchain_block_id,
|
||||
td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout,
|
||||
td::Promise<td::Unit> promise) {
|
||||
|
|
|
@ -2367,7 +2367,7 @@ void ValidatorManagerImpl::get_shard_client_state(bool from_db, td::Promise<Bloc
|
|||
}
|
||||
|
||||
void ValidatorManagerImpl::subscribe_to_shard(ShardIdFull shard) {
|
||||
callback_->add_shard(shard);
|
||||
callback_->subscribe_to_shard(shard);
|
||||
}
|
||||
|
||||
void ValidatorManagerImpl::update_async_serializer_state(AsyncSerializerState state, td::Promise<td::Unit> promise) {
|
||||
|
@ -2396,7 +2396,7 @@ void ValidatorManagerImpl::get_archive_slice(td::uint64 archive_id, td::uint64 o
|
|||
}
|
||||
|
||||
bool ValidatorManagerImpl::is_validator() {
|
||||
return temp_keys_.size() > 0 || permanent_keys_.size() > 0;
|
||||
return true; // temp_keys_.size() > 0 || permanent_keys_.size() > 0;
|
||||
}
|
||||
|
||||
PublicKeyHash ValidatorManagerImpl::get_validator(ShardIdFull shard, td::Ref<ValidatorSet> val_set) {
|
||||
|
|
|
@ -121,9 +121,15 @@ void ValidatorGroup::accept_block_candidate(td::uint32 round_id, PublicKeyHash s
|
|||
td::actor::send_closure(manager_, &ValidatorManager::log_validator_session_stats, next_block_id, std::move(stats));
|
||||
auto block =
|
||||
block_data.size() > 0 ? create_block(next_block_id, std::move(block_data)).move_as_ok() : td::Ref<BlockData>{};
|
||||
accept_block_query(next_block_id, std::move(block), std::move(prev_block_ids_), std::move(sig_set),
|
||||
std::move(approve_sig_set), src == local_id_, std::move(promise));
|
||||
prev_block_ids_ = std::vector<BlockIdExt>{next_block_id};
|
||||
}
|
||||
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this), block_id = next_block_id, block, prev = prev_block_ids_,
|
||||
sig_set, approve_sig_set,
|
||||
void ValidatorGroup::accept_block_query(BlockIdExt block_id, td::Ref<BlockData> block, std::vector<BlockIdExt> prev,
|
||||
td::Ref<BlockSignatureSet> sig_set, td::Ref<BlockSignatureSet> approve_sig_set,
|
||||
bool send_broadcast, td::Promise<td::Unit> promise) {
|
||||
auto P = td::PromiseCreator::lambda([=, SelfId = actor_id(this),
|
||||
promise = std::move(promise)](td::Result<td::Unit> R) mutable {
|
||||
if (R.is_error()) {
|
||||
if (R.error().code() == ErrorCode::cancelled) {
|
||||
|
@ -131,35 +137,22 @@ void ValidatorGroup::accept_block_candidate(td::uint32 round_id, PublicKeyHash s
|
|||
return;
|
||||
}
|
||||
LOG_CHECK(R.error().code() == ErrorCode::timeout || R.error().code() == ErrorCode::notready) << R.move_as_error();
|
||||
td::actor::send_closure(SelfId, &ValidatorGroup::retry_accept_block_query, block_id, std::move(block),
|
||||
std::move(prev), std::move(sig_set), std::move(approve_sig_set), std::move(promise));
|
||||
td::actor::send_closure(SelfId, &ValidatorGroup::accept_block_query, block_id, std::move(block), std::move(prev),
|
||||
std::move(sig_set), std::move(approve_sig_set), false, std::move(promise));
|
||||
} else {
|
||||
promise.set_value(R.move_as_ok());
|
||||
}
|
||||
});
|
||||
|
||||
run_accept_block_query(next_block_id, std::move(block), prev_block_ids_, validator_set_, std::move(sig_set),
|
||||
std::move(approve_sig_set), src == local_id_, manager_, std::move(P));
|
||||
prev_block_ids_ = std::vector<BlockIdExt>{next_block_id};
|
||||
}
|
||||
|
||||
void ValidatorGroup::retry_accept_block_query(BlockIdExt block_id, td::Ref<BlockData> block,
|
||||
std::vector<BlockIdExt> prev, td::Ref<BlockSignatureSet> sig_set,
|
||||
td::Ref<BlockSignatureSet> approve_sig_set,
|
||||
td::Promise<td::Unit> promise) {
|
||||
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this), block_id, block, prev, sig_set, approve_sig_set,
|
||||
promise = std::move(promise)](td::Result<td::Unit> R) mutable {
|
||||
if (R.is_error()) {
|
||||
LOG_CHECK(R.error().code() == ErrorCode::timeout) << R.move_as_error();
|
||||
td::actor::send_closure(SelfId, &ValidatorGroup::retry_accept_block_query, block_id, std::move(block),
|
||||
std::move(prev), std::move(sig_set), std::move(approve_sig_set), std::move(promise));
|
||||
} else {
|
||||
promise.set_value(R.move_as_ok());
|
||||
}
|
||||
});
|
||||
|
||||
run_accept_block_query(block_id, std::move(block), prev, validator_set_, std::move(sig_set),
|
||||
std::move(approve_sig_set), false, manager_, std::move(P));
|
||||
if (shard_.is_masterchain() || lite_mode_) {
|
||||
run_accept_block_query(block_id, std::move(block), std::move(prev), validator_set_, std::move(sig_set),
|
||||
std::move(approve_sig_set), send_broadcast, manager_, std::move(P));
|
||||
} else if (send_broadcast) {
|
||||
run_broadcast_only_accept_block_query(block_id, std::move(block), std::move(prev), validator_set_,
|
||||
std::move(sig_set), std::move(approve_sig_set), manager_, std::move(P));
|
||||
} else {
|
||||
promise.set_value(td::Unit());
|
||||
}
|
||||
}
|
||||
|
||||
void ValidatorGroup::skip_round(td::uint32 round_id) {
|
||||
|
@ -311,8 +304,8 @@ void ValidatorGroup::start(std::vector<BlockIdExt> prev, BlockIdExt min_masterch
|
|||
|
||||
auto block =
|
||||
p.block.size() > 0 ? create_block(next_block_id, std::move(p.block)).move_as_ok() : td::Ref<BlockData>{};
|
||||
retry_accept_block_query(next_block_id, std::move(block), prev_block_ids_, std::move(p.sigs),
|
||||
std::move(p.approve_sigs), std::move(p.promise));
|
||||
accept_block_query(next_block_id, std::move(block), std::move(prev_block_ids_), std::move(p.sigs),
|
||||
std::move(p.approve_sigs), false, std::move(p.promise));
|
||||
prev_block_ids_ = std::vector<BlockIdExt>{next_block_id};
|
||||
}
|
||||
postponed_accept_.clear();
|
||||
|
|
|
@ -39,9 +39,9 @@ class ValidatorGroup : public td::actor::Actor {
|
|||
std::vector<BlockSignature> approve_signatures,
|
||||
validatorsession::ValidatorSessionStats stats, td::Promise<td::Unit> promise);
|
||||
void skip_round(td::uint32 round);
|
||||
void retry_accept_block_query(BlockIdExt block_id, td::Ref<BlockData> block, std::vector<BlockIdExt> prev,
|
||||
td::Ref<BlockSignatureSet> sigs, td::Ref<BlockSignatureSet> approve_sigs,
|
||||
td::Promise<td::Unit> promise);
|
||||
void accept_block_query(BlockIdExt block_id, td::Ref<BlockData> block, std::vector<BlockIdExt> prev,
|
||||
td::Ref<BlockSignatureSet> sigs, td::Ref<BlockSignatureSet> approve_sigs,
|
||||
bool send_broadcast, td::Promise<td::Unit> promise);
|
||||
void get_approved_candidate(PublicKey source, RootHash root_hash, FileHash file_hash,
|
||||
FileHash collated_data_file_hash, td::Promise<BlockCandidate> promise);
|
||||
BlockId create_next_block_id_simple() const;
|
||||
|
|
|
@ -111,8 +111,8 @@ class ValidatorManagerInterface : public td::actor::Actor {
|
|||
virtual ~Callback() = default;
|
||||
|
||||
virtual void initial_read_complete(BlockHandle top_masterchain_blocks) = 0;
|
||||
virtual void add_shard(ShardIdFull shard) = 0;
|
||||
virtual void del_shard(ShardIdFull shard) = 0;
|
||||
virtual void subscribe_to_shard(ShardIdFull shard) = 0;
|
||||
//virtual void del_shard(ShardIdFull shard) = 0;
|
||||
|
||||
virtual void send_ihr_message(AccountIdPrefixFull dst, td::BufferSlice data) = 0;
|
||||
virtual void send_ext_message(AccountIdPrefixFull dst, td::BufferSlice data) = 0;
|
||||
|
|
Loading…
Reference in a new issue