diff --git a/crypto/block/mc-config.cpp b/crypto/block/mc-config.cpp index 31826acf..8d592c21 100644 --- a/crypto/block/mc-config.cpp +++ b/crypto/block/mc-config.cpp @@ -2203,7 +2203,7 @@ Ref ConfigInfo::lookup_library(td::ConstBitPtr root_hash) const { CollatorConfig Config::get_collator_config(bool need_collator_nodes) const { CollatorConfig collator_config; gen::CollatorConfig::Record rec; - auto cell = get_config_param(-41); + auto cell = get_config_param(41, -41); if (cell.is_null() || !tlb::unpack_cell(std::move(cell), rec)) { return collator_config; } diff --git a/overlay/overlay-manager.cpp b/overlay/overlay-manager.cpp index b7ca1270..f9a79878 100644 --- a/overlay/overlay-manager.cpp +++ b/overlay/overlay-manager.cpp @@ -105,16 +105,6 @@ void OverlayManager::create_public_overlay_ex(adnl::AdnlNodeIdShort local_id, Ov std::move(callback), std::move(rules), scope, announce_self)); } -void OverlayManager::create_public_overlay_external(adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id, - std::unique_ptr callback, 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), - std::move(callback), std::move(rules), scope, true)); -} - void OverlayManager::create_private_overlay(adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id, std::vector nodes, std::unique_ptr callback, OverlayPrivacyRules rules) { @@ -162,23 +152,16 @@ void OverlayManager::receive_query(adnl::AdnlNodeIdShort src, adnl::AdnlNodeIdSh auto M = R.move_as_ok(); - OverlayIdShort overlay_id{M->overlay_}; - auto send_remove_peer = [&, this]() { - send_message(src, dst, overlay_id, create_serialize_tl_object()); - }; - auto it = overlays_.find(dst); if (it == overlays_.end()) { VLOG(OVERLAY_NOTICE) << this << ": query to unknown overlay " << M->overlay_ << "@" << dst << " from " << src; promise.set_error(td::Status::Error(ErrorCode::protoviolation, PSTRING() << "bad local_id " << dst)); - send_remove_peer(); return; } - auto it2 = it->second.find(overlay_id); + auto it2 = it->second.find(OverlayIdShort{M->overlay_}); if (it2 == it->second.end()) { VLOG(OVERLAY_NOTICE) << this << ": query to localid not in overlay " << M->overlay_ << "@" << dst << " from " << src; promise.set_error(td::Status::Error(ErrorCode::protoviolation, PSTRING() << "bad overlay_id " << M->overlay_)); - send_remove_peer(); return; } @@ -380,6 +363,19 @@ void OverlayManager::set_priority_broadcast_receivers(adnl::AdnlNodeIdShort loca td::actor::send_closure(it2->second, &Overlay::set_priority_broadcast_receivers, std::move(nodes)); } +void OverlayManager::forget_peer(adnl::AdnlNodeIdShort local_id, OverlayIdShort overlay, + adnl::AdnlNodeIdShort peer_id) { + auto it = overlays_.find(local_id); + if (it == overlays_.end()) { + return; + } + auto it2 = it->second.find(overlay); + if (it2 == it->second.end()) { + return; + } + td::actor::send_closure(it2->second, &Overlay::forget_peer, peer_id); +} + Certificate::Certificate(PublicKey issued_by, td::int32 expire_at, td::uint32 max_size, td::uint32 flags, td::BufferSlice signature) : issued_by_(issued_by) @@ -421,7 +417,7 @@ td::BufferSlice Certificate::to_sign(OverlayIdShort overlay_id, PublicKeyHash is } } -PublicKeyHash Certificate::issuer_hash() const { +const PublicKeyHash Certificate::issuer_hash() const { PublicKeyHash r; issued_by_.visit( td::overloaded([&](const PublicKeyHash &x) { r = x; }, [&](const PublicKey &x) { r = x.compute_short_id(); })); diff --git a/overlay/overlay-manager.h b/overlay/overlay-manager.h index f7ed32ba..5b59b371 100644 --- a/overlay/overlay-manager.h +++ b/overlay/overlay-manager.h @@ -98,6 +98,7 @@ class OverlayManager : public Overlays { void set_priority_broadcast_receivers(adnl::AdnlNodeIdShort local_id, OverlayIdShort overlay, std::vector nodes) override; + void forget_peer(adnl::AdnlNodeIdShort local_id, OverlayIdShort overlay, adnl::AdnlNodeIdShort peer_id) override; struct PrintId {}; diff --git a/overlay/overlay.cpp b/overlay/overlay.cpp index f0bd3b9c..c4cf8428 100644 --- a/overlay/overlay.cpp +++ b/overlay/overlay.cpp @@ -231,7 +231,7 @@ void OverlayImpl::receive_message(adnl::AdnlNodeIdShort src, td::BufferSlice dat return; } auto Q = X.move_as_ok(); - ton_api::downcast_call(*Q, [Self = this, &Q, &src](auto &object) { + ton_api::downcast_call(*Q.get(), [Self = this, &Q, &src](auto &object) { Self->process_broadcast(src, move_tl_object_as>(Q)); }); } diff --git a/overlay/overlay.h b/overlay/overlay.h index 4289142c..5141ae53 100644 --- a/overlay/overlay.h +++ b/overlay/overlay.h @@ -70,6 +70,7 @@ class Overlay : public td::actor::Actor { //virtual void receive_broadcast(td::BufferSlice data) = 0; //virtual void subscribe(std::unique_ptr callback) = 0; virtual void set_priority_broadcast_receivers(std::vector nodes) = 0; + virtual void forget_peer(adnl::AdnlNodeIdShort peer_id) = 0; }; } // namespace overlay diff --git a/overlay/overlay.hpp b/overlay/overlay.hpp index 208aba7f..a8fd7f30 100644 --- a/overlay/overlay.hpp +++ b/overlay/overlay.hpp @@ -278,7 +278,11 @@ class OverlayImpl : public Overlay { priority_broadcast_receivers_ = std::move(nodes); } - void wait_neighbours_not_empty(td::Promise promise, int max_retries = 10); + void forget_peer(adnl::AdnlNodeIdShort peer_id) override { + del_peer(peer_id); + } + + void wait_neighbours_not_empty(td::Promise promise, int max_retries = 20); private: template diff --git a/overlay/overlays.h b/overlay/overlays.h index def80d75..1141efee 100644 --- a/overlay/overlays.h +++ b/overlay/overlays.h @@ -145,7 +145,7 @@ class Certificate { bool is_fec) const; tl_object_ptr tl() const; const PublicKey &issuer() const; - PublicKeyHash issuer_hash() const; + const PublicKeyHash issuer_hash() const; static td::Result> create(tl_object_ptr cert); static tl_object_ptr empty_tl(); @@ -170,8 +170,6 @@ class Overlays : public td::actor::Actor { td::Promise promise) { promise.set_value(td::Unit()); } - virtual void on_remove_peer(adnl::AdnlNodeIdShort src) { - } virtual ~Callback() = default; }; @@ -242,6 +240,7 @@ class Overlays : public td::actor::Actor { virtual void set_priority_broadcast_receivers(adnl::AdnlNodeIdShort local_id, OverlayIdShort overlay, std::vector nodes) = 0; + virtual void forget_peer(adnl::AdnlNodeIdShort local_id, OverlayIdShort overlay, adnl::AdnlNodeIdShort peer_id) = 0; }; } // namespace overlay diff --git a/tl/generate/scheme/ton_api.tl b/tl/generate/scheme/ton_api.tl index 004b1dd2..08d4c9df 100644 --- a/tl/generate/scheme/ton_api.tl +++ b/tl/generate/scheme/ton_api.tl @@ -218,8 +218,6 @@ overlay.message overlay:int256 = overlay.Message; //overlay.randomPeers peers:(vector adnl.node) = overlay.RandomPeers; overlay.broadcastList hashes:(vector int256) = overlay.BroadcastList; -overlay.message.removePeer = overlay.message.InternalMessage; - overlay.fec.received hash:int256 = overlay.Broadcast; overlay.fec.completed hash:int256 = overlay.Broadcast; @@ -424,6 +422,8 @@ tonNode.archiveInfo id:long = tonNode.ArchiveInfo; tonNode.outMsgQueueProof queue_proof:bytes block_state_proof:bytes = tonNode.OutMsgQueueProof; tonNode.outMsgQueueProofEmpty = tonNode.OutMsgQueueProof; +tonNode.forgetPeer = tonNode.ForgetPeer; + ---functions--- tonNode.getNextBlockDescription prev_block:tonNode.blockIdExt = tonNode.BlockDescription; diff --git a/tl/generate/scheme/ton_api.tlo b/tl/generate/scheme/ton_api.tlo index 97c2bda2..9dc8c51b 100644 Binary files a/tl/generate/scheme/ton_api.tlo and b/tl/generate/scheme/ton_api.tlo differ diff --git a/tonlib/tonlib/QueryTraits.h b/tonlib/tonlib/QueryTraits.h index bf480f64..b583cd05 100644 --- a/tonlib/tonlib/QueryTraits.h +++ b/tonlib/tonlib/QueryTraits.h @@ -114,6 +114,13 @@ struct QueryTraits { } }; +template<> +struct QueryTraits { + static ton::ShardIdFull get_shard(const ton::lite_api::liteServer_getAccountStatePrunned& q) { + return ton::AccountIdPrefixFull(q.account_->workchain_, q.account_->id_.bits().get_uint(64)).as_leaf_shard(); + } +}; + template<> struct QueryTraits { static ton::ShardIdFull get_shard(const ton::lite_api::liteServer_runSmcMethod& q) { @@ -198,5 +205,12 @@ struct QueryTraits { } }; +template<> +struct QueryTraits { + static ton::ShardIdFull get_shard(const ton::lite_api::liteServer_getShardBlockProof& q) { + return ton::ShardIdFull(q.id_->workchain_, q.id_->shard_); + } +}; + } // namespace tonlib diff --git a/validator-engine-console/validator-engine-console.cpp b/validator-engine-console/validator-engine-console.cpp index a1a0135b..97e7690a 100644 --- a/validator-engine-console/validator-engine-console.cpp +++ b/validator-engine-console/validator-engine-console.cpp @@ -144,6 +144,8 @@ void ValidatorEngineConsole::run() { add_query_runner(std::make_unique>()); add_query_runner(std::make_unique>()); add_query_runner(std::make_unique>()); + add_query_runner(std::make_unique>()); + add_query_runner(std::make_unique>()); } bool ValidatorEngineConsole::envelope_send_query(td::BufferSlice query, td::Promise promise) { diff --git a/validator/full-node-shard.cpp b/validator/full-node-shard.cpp index 35a9b851..69804a07 100644 --- a/validator/full-node-shard.cpp +++ b/validator/full-node-shard.cpp @@ -88,7 +88,7 @@ void FullNodeShardImpl::create_overlay() { public: void receive_message(adnl::AdnlNodeIdShort src, overlay::OverlayIdShort overlay_id, td::BufferSlice data) override { - // just ignore + td::actor::send_closure(node_, &FullNodeShardImpl::receive_message, src, std::move(data)); } void receive_query(adnl::AdnlNodeIdShort src, overlay::OverlayIdShort overlay_id, td::BufferSlice data, td::Promise promise) override { @@ -101,26 +101,23 @@ void FullNodeShardImpl::create_overlay() { td::Promise promise) override { td::actor::send_closure(node_, &FullNodeShardImpl::check_broadcast, src, std::move(data), std::move(promise)); } - void on_remove_peer(adnl::AdnlNodeIdShort src) override { - td::actor::send_closure(node_, &FullNodeShardImpl::remove_neighbour, src); - } Callback(td::actor::ActorId node) : node_(node) { } private: td::actor::ActorId node_; }; - if (is_active()) { td::actor::send_closure(overlays_, &overlay::Overlays::create_public_overlay, adnl_id_, overlay_id_full_.clone(), std::make_unique(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_external, adnl_id_, - overlay_id_full_.clone(), std::make_unique(actor_id(this)), rules_, + td::actor::send_closure(overlays_, &overlay::Overlays::create_public_overlay_ex, adnl_id_, overlay_id_full_.clone(), + std::make_unique(actor_id(this)), rules_, PSTRING() << "{ \"type\": \"shard\", \"shard_id\": " << get_shard() - << ", \"workchain_id\": " << get_workchain() << " }"); + << ", \"workchain_id\": " << get_workchain() << " }", + false); } td::actor::send_closure(rldp_, &rldp::Rldp::add_id, adnl_id_); @@ -647,6 +644,8 @@ void FullNodeShardImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNod void FullNodeShardImpl::receive_query(adnl::AdnlNodeIdShort src, td::BufferSlice query, td::Promise promise) { if (!is_active()) { + td::actor::send_closure(overlays_, &overlay::Overlays::send_message, src, adnl_id_, overlay_id_, + create_serialize_tl_object()); promise.set_error(td::Status::Error("shard is inactive")); return; } @@ -658,6 +657,16 @@ void FullNodeShardImpl::receive_query(adnl::AdnlNodeIdShort src, td::BufferSlice ton_api::downcast_call(*B.move_as_ok().get(), [&](auto &obj) { this->process_query(src, obj, std::move(promise)); }); } +void FullNodeShardImpl::receive_message(adnl::AdnlNodeIdShort src, td::BufferSlice data) { + auto B = fetch_tl_object(std::move(data), true); + if (B.is_error()) { + return; + } + VLOG(FULL_NODE_DEBUG) << "Got tonNode.forgetPeer from " << src; + neighbours_.erase(src); + td::actor::send_closure(overlays_, &overlay::Overlays::forget_peer, adnl_id_, overlay_id_, src); +} + void FullNodeShardImpl::process_broadcast(PublicKeyHash src, ton_api::tonNode_ihrMessageBroadcast &query) { td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::new_ihr_message, std::move(query.message_->data_)); diff --git a/validator/full-node-shard.h b/validator/full-node-shard.h index 847091c6..633c9340 100644 --- a/validator/full-node-shard.h +++ b/validator/full-node-shard.h @@ -31,7 +31,7 @@ namespace fullnode { enum FullNodeShardMode { active, // Node can answer queries about the shard active_temp, // Like 'active', but queries about shard state are not allowed (only blocks) - inactive // Node is not a part of the overlay (overlay is_external) + inactive // Node is not a part of the overlay }; diff --git a/validator/full-node-shard.hpp b/validator/full-node-shard.hpp index 1cb2957d..7d80792b 100644 --- a/validator/full-node-shard.hpp +++ b/validator/full-node-shard.hpp @@ -142,6 +142,7 @@ class FullNodeShardImpl : public FullNodeShard { // void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_prepareNextKeyBlockProof &query, // td::Promise promise); void receive_query(adnl::AdnlNodeIdShort src, td::BufferSlice query, td::Promise promise); + void receive_message(adnl::AdnlNodeIdShort src, td::BufferSlice data); void process_broadcast(PublicKeyHash src, ton_api::tonNode_blockBroadcast &query); void process_broadcast(PublicKeyHash src, ton_api::tonNode_ihrMessageBroadcast &query); diff --git a/validator/full-node.cpp b/validator/full-node.cpp index 72af6fe8..42e8511f 100644 --- a/validator/full-node.cpp +++ b/validator/full-node.cpp @@ -17,10 +17,8 @@ Copyright 2017-2020 Telegram Systems LLP */ #include "full-node.hpp" -#include "ton/ton-shard.h" #include "ton/ton-io.hpp" #include "td/actor/MultiPromise.h" -#include "ton/ton-types.h" namespace ton { @@ -140,12 +138,8 @@ void FullNodeImpl::update_shard_configuration(td::Ref state, s new_shards.insert(ShardIdFull(masterchainId)); std::set workchains; auto cut_shard = [&](ShardIdFull shard) -> ShardIdFull { - unsigned pfx_len = shard.pfx_len(); - unsigned min_split = state->soft_min_split_depth(shard.workchain); - if (min_split < pfx_len) { - return shard_prefix(shard, min_split); - } - return shard; + int min_split = state->soft_min_split_depth(shard.workchain); + return min_split < shard.pfx_len() ? shard_prefix(shard, min_split) : shard; }; auto set_active = [&](ShardIdFull shard, FullNodeShardMode mode) { while (new_active.emplace(shard, mode).second && shard.pfx_len() > 0) { @@ -388,6 +382,7 @@ void FullNodeImpl::download_out_msg_queue_proof(BlockIdExt block_id, ShardIdFull } td::actor::ActorId FullNodeImpl::get_shard(ShardIdFull shard) { + ShardIdFull shard0 = shard; while (true) { auto it = shards_.find(shard); if (it != shards_.end() && it->second.exists) { @@ -404,6 +399,7 @@ td::actor::ActorId FullNodeImpl::get_shard(ShardIdFull shard) { } shard = shard_parent(shard); } + shard = shard0; auto it = shards_.find(shard); if (it == shards_.end()) { it = shards_.emplace(shard = ShardIdFull(shard.workchain), ShardInfo{}).first; diff --git a/validator/manager.cpp b/validator/manager.cpp index 3015e882..c19e96f4 100644 --- a/validator/manager.cpp +++ b/validator/manager.cpp @@ -583,6 +583,10 @@ void ValidatorManagerImpl::run_ext_query(td::BufferSlice data, td::Promise> promise) { + if (last_masterchain_state_.not_null() && !opts_->need_monitor(handle->id().shard_full(), last_masterchain_state_)) { + return promise.set_error( + td::Status::Error(PSTRING() << "not monitoring shard " << handle->id().shard_full().to_str())); + } auto it = wait_state_.find(handle->id()); if (it == wait_state_.end()) { auto P = td::PromiseCreator::lambda([SelfId = actor_id(this), handle](td::Result> R) { @@ -678,6 +682,10 @@ void ValidatorManagerImpl::wait_block_data_short(BlockIdExt block_id, td::uint32 void ValidatorManagerImpl::wait_block_state_merge(BlockIdExt left_id, BlockIdExt right_id, td::uint32 priority, td::Timestamp timeout, td::Promise> promise) { + if (last_masterchain_state_.not_null() && !opts_->need_monitor(left_id.shard_full(), last_masterchain_state_)) { + return promise.set_error( + td::Status::Error(PSTRING() << "not monitoring shard " << left_id.shard_full().to_str())); + } td::actor::create_actor("merge", left_id, right_id, priority, actor_id(this), timeout, std::move(promise)) .release(); @@ -1604,6 +1612,7 @@ void ValidatorManagerImpl::started(ValidatorManagerInitResult R) { td::actor::send_closure(SelfId, &ValidatorManagerImpl::read_gc_list, R.move_as_ok()); } }); + td::actor::send_closure(db_, &Db::get_destroyed_validator_sessions, std::move(P)); auto Q = td::PromiseCreator::lambda( diff --git a/validator/validator-group.cpp b/validator/validator-group.cpp index 601fc526..b4f665c3 100644 --- a/validator/validator-group.cpp +++ b/validator/validator-group.cpp @@ -139,6 +139,13 @@ void ValidatorGroup::validate_block_candidate(td::uint32 round_id, BlockCandidat collator_config_.full_collated_data ? ValidateMode::full_collated_data : 0); } +void ValidatorGroup::update_approve_cache(td::uint32 round_id, CacheKey key, UnixTime value) { + if (approved_candidates_cache_round_ != round_id) { + return; + } + approved_candidates_cache_[key] = value; +} + void ValidatorGroup::accept_block_candidate(td::uint32 round_id, PublicKeyHash src, td::BufferSlice block_data, RootHash root_hash, FileHash file_hash, std::vector signatures, @@ -382,8 +389,8 @@ void ValidatorGroup::get_session_info( td::actor::send_closure(session_, &validatorsession::ValidatorSession::get_session_info, std::move(P)); } -void ValidatorGroup::send_collate_query(td::uint32 round_id, td::Timestamp timeout, - td::Promise promise, unsigned max_retries) { +void ValidatorGroup::send_collate_query(td::uint32 round_id, td::Timestamp timeout, td::Promise promise, + unsigned max_retries) { if (round_id < last_known_round_id_) { promise.set_error(td::Status::Error("too old")); return; @@ -391,9 +398,11 @@ void ValidatorGroup::send_collate_query(td::uint32 round_id, td::Timestamp timeo adnl::AdnlNodeIdShort collator = adnl::AdnlNodeIdShort::zero(); // TODO: some way to choose node (similar to "unreliability" in full-node) int cnt = 0; - for (const block::CollatorNodeDescr& c : collator_config_.collator_nodes) { - if (shard_intersects(shard_, c.shard) && td::Random::fast(0, cnt) == 0) { - collator = adnl::AdnlNodeIdShort(c.adnl_id); + for (const block::CollatorNodeDescr &c : collator_config_.collator_nodes) { + if (shard_intersects(shard_, c.shard)) { + if (td::Random::fast(0, cnt) == 0) { + collator = adnl::AdnlNodeIdShort(c.adnl_id); + } ++cnt; } } @@ -438,8 +447,8 @@ void ValidatorGroup::send_collate_query(td::uint32 round_id, td::Timestamp timeo size_t max_answer_size = config_.max_block_size + config_.max_collated_data_size + 256; td::Timestamp query_timeout = td::Timestamp::in(10.0); query_timeout.relax(timeout); - td::actor::send_closure(rldp_, &rldp::Rldp::send_query_ex, local_adnl_id_, collator, "collatequery", - std::move(P), timeout, std::move(query), max_answer_size); + td::actor::send_closure(rldp_, &rldp::Rldp::send_query_ex, local_adnl_id_, collator, "collatequery", std::move(P), + timeout, std::move(query), max_answer_size); } void ValidatorGroup::receive_collate_query_response(td::uint32 round_id, td::BufferSlice data, @@ -460,15 +469,11 @@ void ValidatorGroup::receive_collate_query_response(td::uint32 round_id, td::Buf return; } auto key = PublicKey{b->source_}; - if (!key.is_ed25519()) { + if (key != local_id_full_) { promise.set_error(td::Status::Error("collate query: block candidate source mismatch")); return; } auto e_key = Ed25519_PublicKey{key.ed25519_value().raw()}; - if (e_key != Ed25519_PublicKey{local_id_full_.ed25519_value().raw()}) { - promise.set_error(td::Status::Error("collate query: block candidate source mismatch")); - return; - } auto block_id = ton::create_block_id(b->id_); if (block_id.shard_full() != shard_) { promise.set_error(td::Status::Error("collate query: shard mismatch"));