diff --git a/tl/generate/scheme/ton_api.tl b/tl/generate/scheme/ton_api.tl index ef8679d6..81f7192e 100644 --- a/tl/generate/scheme/ton_api.tl +++ b/tl/generate/scheme/ton_api.tl @@ -408,8 +408,7 @@ tonNode.dataList data:(vector bytes) = tonNode.DataList; tonNode.dataFull id:tonNode.blockIdExt proof:bytes block:bytes is_link:Bool = tonNode.DataFull; tonNode.dataFullEmpty = tonNode.DataFull; -tonNode.capabilities version:int capabilities:long = tonNode.Capabilities; -tonNode.capabilitiesV2 version:int capabilities:long have_state:Bool = tonNode.Capabilities; +tonNode.capabilities#f5bf60c0 version_major:int version_minor:int flags:# = tonNode.Capabilities; tonNode.success = tonNode.Success; @@ -457,7 +456,6 @@ tonNode.getOutMsgQueueProof dst_shard:tonNode.shardId blocks:(vector tonNode.blo limits:tonNode.importedMsgQueueLimits = tonNode.OutMsgQueueProof; tonNode.getCapabilities = tonNode.Capabilities; -tonNode.getCapabilitiesV2 = tonNode.Capabilities; tonNode.slave.sendExtMessage message:tonNode.externalMessage = tonNode.Success; @@ -660,7 +658,7 @@ engine.validator.overlayStatsNode adnl_id:int256 ip_addr:string bdcst_errors:int engine.validator.overlayStats overlay_id:int256 overlay_id_full:PublicKey adnl_id:int256 scope:string nodes:(vector engine.validator.overlayStatsNode) stats:(vector engine.validator.oneStat) extra:string = engine.validator.OverlayStats; engine.validator.overlaysStats overlays:(vector engine.validator.overlayStats) = engine.validator.OverlaysStats; -engine.validator.shardOverlayStats.neighbour id:string proto_verison:int capabilities:long +engine.validator.shardOverlayStats.neighbour id:string verison_major:int version_minor:int flags:# roundtrip:double unreliability:double has_state:string = engine.validator.shardOverlayStats.Neighbour; engine.validator.shardOverlayStats shard:string mode:string neighbours:(vector engine.validator.shardOverlayStats.neighbour) = engine.validator.ShardOverlayStats; diff --git a/tl/generate/scheme/ton_api.tlo b/tl/generate/scheme/ton_api.tlo index 9680b01e..c44ee331 100644 Binary files a/tl/generate/scheme/ton_api.tlo and b/tl/generate/scheme/ton_api.tlo differ diff --git a/validator/full-node-shard.cpp b/validator/full-node-shard.cpp index d64dff25..d70cea8f 100644 --- a/validator/full-node-shard.cpp +++ b/validator/full-node-shard.cpp @@ -51,21 +51,10 @@ namespace fullnode { Neighbour Neighbour::zero = Neighbour{adnl::AdnlNodeIdShort::zero()}; -void Neighbour::update_proto_version(ton_api::tonNode_Capabilities &q) { - ton_api::downcast_call(q, td::overloaded( - [&](ton_api::tonNode_capabilities &x) { - proto_version = x.version_; - capabilities = x.capabilities_; - if (!supports_v2()) { - has_state_known = has_state = true; - } - }, - [&](ton_api::tonNode_capabilitiesV2 &x) { - proto_version = x.version_; - capabilities = x.capabilities_; - has_state_known = true; - has_state = x.have_state_; - })); +void Neighbour::update_proto_version(ton_api::tonNode_capabilities &q) { + version_major = q.version_major_; + version_minor = q.version_minor_; + flags = q.flags_; } void Neighbour::query_success(double t) { @@ -188,7 +177,7 @@ void FullNodeShardImpl::try_get_next_block(td::Timestamp timeout, td::Promise= 1) { + if (!b.adnl_id.is_zero() && b.version_major >= 1) { VLOG(FULL_NODE_DEBUG) << "using new download method with adnlid=" << b.adnl_id; td::actor::create_actor("downloadnext", adnl_id_, overlay_id_, handle_->id(), b.adnl_id, download_next_priority(), timeout, validator_manager_, rldp_, overlays_, @@ -631,14 +620,12 @@ void FullNodeShardImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNod void FullNodeShardImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_getCapabilities &query, td::Promise promise) { VLOG(FULL_NODE_DEBUG) << "Got query getCapabilities from " << src; - promise.set_value(create_serialize_tl_object(proto_version(), proto_capabilities())); -} - -void FullNodeShardImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_getCapabilitiesV2 &query, - td::Promise promise) { - VLOG(FULL_NODE_DEBUG) << "Got query getCapabilitiesV2 from " << src; - promise.set_value(create_serialize_tl_object(proto_version(), proto_capabilities(), - mode_ == FullNodeShardMode::active)); + td::uint32 flags = 0; + if (mode_ != FullNodeShardMode::active) { + flags |= Neighbour::FLAG_NO_STATE; + } + promise.set_value( + create_serialize_tl_object(proto_version_major(), proto_version_minor(), flags)); } void FullNodeShardImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_getArchiveInfo &query, @@ -878,7 +865,7 @@ void FullNodeShardImpl::send_broadcast(BlockBroadcast broadcast) { void FullNodeShardImpl::download_block(BlockIdExt id, td::uint32 priority, td::Timestamp timeout, td::Promise promise) { auto &b = choose_neighbour(); - if (!b.adnl_id.is_zero() && b.proto_version >= 1) { + if (!b.adnl_id.is_zero() && b.version_major >= 1) { VLOG(FULL_NODE_DEBUG) << "new block download"; td::actor::create_actor("downloadreq", id, adnl_id_, overlay_id_, b.adnl_id, priority, timeout, validator_manager_, rldp_, overlays_, adnl_, client_, @@ -1173,7 +1160,7 @@ void FullNodeShardImpl::got_neighbours(std::vector vec) { if (neighbours_.size() == max_neighbours()) { td::uint32 neighbours_with_state = 0; for (const auto &n : neighbours_) { - if (n.second.has_state) { + if (n.second.has_state_known() && n.second.has_state()) { ++neighbours_with_state; } } @@ -1183,7 +1170,8 @@ void FullNodeShardImpl::got_neighbours(std::vector vec) { td::uint32 cnt = 0; double u = 0; for (auto &n : neighbours_) { - if (neighbours_with_state <= min_neighbours_with_state() && n.second.has_state) { + if (neighbours_with_state <= min_neighbours_with_state() && n.second.has_state_known() && + n.second.has_state()) { continue; } if (n.second.unreliability > u) { @@ -1224,18 +1212,18 @@ const Neighbour &FullNodeShardImpl::choose_neighbour(bool require_state) const { for (auto &x : neighbours_) { if (require_state) { - if (attempt == 0 && !x.second.has_state) { + if (attempt == 0 && !(x.second.has_state_known() && x.second.has_state())) { continue; } - if (attempt == 1 && x.second.has_state_known) { + if (attempt == 1 && x.second.has_state_known()) { continue; } } auto unr = static_cast(x.second.unreliability - min_unreliability); - if (x.second.proto_version < proto_version()) { + if (x.second.version_major < proto_version_major()) { unr += 4; - } else if (x.second.proto_version == proto_version() && x.second.capabilities < proto_capabilities()) { + } else if (x.second.version_major == proto_version_major() && x.second.version_minor < proto_version_minor()) { unr += 2; } @@ -1272,7 +1260,7 @@ void FullNodeShardImpl::got_neighbour_capabilities(adnl::AdnlNodeIdShort adnl_id if (it == neighbours_.end()) { return; } - auto F = fetch_tl_object(std::move(data), true); + auto F = fetch_tl_object(std::move(data), true); if (F.is_error()) { it->second.query_failed(); } else { @@ -1305,12 +1293,7 @@ void FullNodeShardImpl::ping_neighbours() { td::Time::now() - start_time, R.move_as_ok()); } }); - td::BufferSlice q; - if (it->second.supports_v2()) { - q = create_serialize_tl_object(); - } else { - q = create_serialize_tl_object(); - } + td::BufferSlice q = create_serialize_tl_object(); td::actor::send_closure(overlays_, &overlay::Overlays::send_query, it->first, adnl_id_, overlay_id_, "get_prepare_block", std::move(P), td::Timestamp::in(1.0), std::move(q)); @@ -1338,11 +1321,12 @@ void FullNodeShardImpl::get_stats_extra(td::Promise promise) { const auto &n = p.second; auto f = create_tl_object(); f->id_ = n.adnl_id.bits256_value().to_hex(); - f->proto_verison_ = n.proto_version; - f->capabilities_ = n.capabilities; + f->verison_major_ = n.version_major; + f->version_minor_ = n.version_minor; + f->flags_ = n.flags; f->roundtrip_ = n.roundtrip; f->unreliability_ = n.unreliability; - f->has_state_ = (n.has_state_known ? (n.has_state ? "true" : "false") : "undefined"); + f->has_state_ = (n.has_state_known() ? (n.has_state() ? "true" : "false") : "undefined"); res->neighbours_.push_back(std::move(f)); } promise.set_result(td::json_encode(td::ToJson(*res), true)); diff --git a/validator/full-node-shard.hpp b/validator/full-node-shard.hpp index b1417e22..834fee85 100644 --- a/validator/full-node-shard.hpp +++ b/validator/full-node-shard.hpp @@ -31,30 +31,33 @@ namespace fullnode { struct Neighbour { adnl::AdnlNodeIdShort adnl_id; - td::uint32 proto_version = 0; - td::uint64 capabilities = 0; + td::uint32 version_major = 0; + td::uint32 version_minor = 0; + td::uint32 flags = 0; double roundtrip = 0; double roundtrip_relax_at = 0; double roundtrip_weight = 0; double unreliability = 0; - bool has_state_known = false; - bool has_state = false; Neighbour(adnl::AdnlNodeIdShort adnl_id) : adnl_id(std::move(adnl_id)) { } - void update_proto_version(ton_api::tonNode_Capabilities &q); + void update_proto_version(ton_api::tonNode_capabilities &q); void query_success(double t); void query_failed(); void update_roundtrip(double t); bool use_rldp2() const { - return std::make_pair(proto_version, capabilities) >= std::make_pair(2, 2); + return std::make_pair(version_major, version_minor) >= std::make_pair(2, 2); } - bool supports_v2() const { - return proto_version >= 3; + bool has_state() const { + return !(flags & FLAG_NO_STATE); + } + bool has_state_known() const { + return version_major != 0; } static Neighbour zero; + static constexpr td::uint32 FLAG_NO_STATE = 1; }; class FullNodeShardImpl : public FullNodeShard { @@ -72,11 +75,11 @@ class FullNodeShardImpl : public FullNodeShard { static constexpr td::uint32 download_next_priority() { return 1; } - static constexpr td::uint32 proto_version() { + static constexpr td::uint32 proto_version_major() { return 3; } - static constexpr td::uint64 proto_capabilities() { - return 2; + static constexpr td::uint32 proto_version_minor() { + return 0; } static constexpr td::uint32 max_neighbours() { return 16; @@ -146,8 +149,6 @@ class FullNodeShardImpl : public FullNodeShard { td::Promise promise); void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_getCapabilities &query, td::Promise promise); - void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_getCapabilitiesV2 &query, - td::Promise promise); void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_getArchiveInfo &query, td::Promise promise); void process_query(adnl::AdnlNodeIdShort src, ton_api::tonNode_getArchiveSlice &query, @@ -216,7 +217,7 @@ class FullNodeShardImpl : public FullNodeShard { template td::Promise create_neighbour_promise(const Neighbour &x, td::Promise p, bool require_state = false) { return td::PromiseCreator::lambda([id = x.adnl_id, SelfId = actor_id(this), p = std::move(p), ts = td::Time::now(), - ignore_error = require_state && !x.has_state_known](td::Result R) mutable { + ignore_error = require_state && !x.has_state_known()](td::Result R) mutable { if (R.is_error() && R.error().code() != ErrorCode::notready && R.error().code() != ErrorCode::cancelled) { if (!ignore_error) { td::actor::send_closure(SelfId, &FullNodeShardImpl::update_neighbour_stats, id, td::Time::now() - ts, false);