From 20c20e236b4a9341174dd648e98c9d5585f1fcc7 Mon Sep 17 00:00:00 2001 From: SpyCheese Date: Tue, 10 Dec 2024 15:46:28 +0300 Subject: [PATCH] Check peer version before getOutMsgQueueProof --- validator/full-node-shard.cpp | 30 +++++++++++++++++++++--------- validator/full-node-shard.hpp | 2 +- validator/manager.cpp | 2 +- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/validator/full-node-shard.cpp b/validator/full-node-shard.cpp index 7d33a195..e62bfe42 100644 --- a/validator/full-node-shard.cpp +++ b/validator/full-node-shard.cpp @@ -1005,7 +1005,7 @@ void FullNodeShardImpl::download_out_msg_queue_proof(ShardIdFull dst_shard, std: block::ImportedMsgQueueLimits limits, td::Timestamp timeout, td::Promise>> promise) { // TODO: maybe more complex download (like other requests here) - auto &b = choose_neighbour(); + auto &b = choose_neighbour(3, 0); // Required version: 3.0 if (b.adnl_id == adnl::AdnlNodeIdShort::zero()) { promise.set_error(td::Status::Error(ErrorCode::notready, "no nodes")); return; @@ -1252,24 +1252,36 @@ void FullNodeShardImpl::got_neighbours(std::vector vec) { } } -const Neighbour &FullNodeShardImpl::choose_neighbour() const { +const Neighbour &FullNodeShardImpl::choose_neighbour(td::uint32 required_version_major, + td::uint32 required_version_minor) const { if (neighbours_.size() == 0) { return Neighbour::zero; } + auto is_eligible = + [&](const Neighbour &n) { + return n.version_major > required_version_major || + (n.version_major == required_version_major && n.version_minor >= required_version_minor); + }; double min_unreliability = 1e9; - for (auto &x : neighbours_) { - min_unreliability = std::min(min_unreliability, x.second.unreliability); + for (auto &[_, x] : neighbours_) { + if (!is_eligible(x)) { + continue; + } + min_unreliability = std::min(min_unreliability, x.unreliability); } const Neighbour *best = nullptr; td::uint32 sum = 0; - for (auto &x : neighbours_) { - auto unr = static_cast(x.second.unreliability - min_unreliability); + for (auto &[_, x] : neighbours_) { + if (!is_eligible(x)) { + continue; + } + auto unr = static_cast(x.unreliability - min_unreliability); - if (x.second.version_major < proto_version_major()) { + if (x.version_major < proto_version_major()) { unr += 4; - } else if (x.second.version_major == proto_version_major() && x.second.version_minor < proto_version_minor()) { + } else if (x.version_major == proto_version_major() && x.version_minor < proto_version_minor()) { unr += 2; } @@ -1279,7 +1291,7 @@ const Neighbour &FullNodeShardImpl::choose_neighbour() const { auto w = 1 << (f - unr); sum += w; if (td::Random::fast(0, sum - 1) <= w - 1) { - best = &x.second; + best = &x; } } } diff --git a/validator/full-node-shard.hpp b/validator/full-node-shard.hpp index fd1ef943..59f671c9 100644 --- a/validator/full-node-shard.hpp +++ b/validator/full-node-shard.hpp @@ -209,7 +209,7 @@ class FullNodeShardImpl : public FullNodeShard { void got_neighbours(std::vector res); void update_neighbour_stats(adnl::AdnlNodeIdShort adnl_id, double t, bool success); void got_neighbour_capabilities(adnl::AdnlNodeIdShort adnl_id, double t, td::BufferSlice data); - const Neighbour &choose_neighbour() const; + const Neighbour &choose_neighbour(td::uint32 required_version_major = 0, td::uint32 required_version_minor = 0) const; template td::Promise create_neighbour_promise(const Neighbour &x, td::Promise p, bool require_state = false) { diff --git a/validator/manager.cpp b/validator/manager.cpp index b8394bdc..31278788 100644 --- a/validator/manager.cpp +++ b/validator/manager.cpp @@ -1794,7 +1794,7 @@ void ValidatorManagerImpl::send_validator_telemetry(PublicKeyHash key, void ValidatorManagerImpl::send_get_out_msg_queue_proof_request( ShardIdFull dst_shard, std::vector blocks, block::ImportedMsgQueueLimits limits, td::Promise>> promise) { - callback_->download_out_msg_queue_proof(dst_shard, std::move(blocks), limits, td::Timestamp::in(10.0), + callback_->download_out_msg_queue_proof(dst_shard, std::move(blocks), limits, td::Timestamp::in(5.0), std::move(promise)); }