diff --git a/catchain/catchain-receiver.cpp b/catchain/catchain-receiver.cpp index b9b0373f..e7f5c019 100644 --- a/catchain/catchain-receiver.cpp +++ b/catchain/catchain-receiver.cpp @@ -486,7 +486,7 @@ void CatChainReceiverImpl::start_up() { } td::actor::send_closure(overlay_manager_, &overlay::Overlays::create_private_overlay, get_source(local_idx_)->get_adnl_id(), overlay_full_id_.clone(), std::move(ids), - make_callback(), overlay::OverlayPrivacyRules{0, std::move(root_keys)}); + make_callback(), overlay::OverlayPrivacyRules{0, 0, std::move(root_keys)}); CHECK(root_block_); diff --git a/overlay/overlay-broadcast.cpp b/overlay/overlay-broadcast.cpp index bade50e7..1c05f705 100644 --- a/overlay/overlay-broadcast.cpp +++ b/overlay/overlay-broadcast.cpp @@ -17,8 +17,14 @@ Copyright 2017-2020 Telegram Systems LLP */ #include "overlay-broadcast.hpp" +#include "adnl/adnl-node-id.hpp" +#include "common/util.h" #include "overlay.hpp" #include "keys/encryptor.h" +#include "td/actor/PromiseFuture.h" +#include "td/actor/actor.h" +#include "td/utils/Status.h" +#include "td/utils/port/Stat.h" namespace ton { @@ -33,7 +39,13 @@ td::Status BroadcastSimple::check_duplicate() { } td::Status BroadcastSimple::check_source() { - return overlay_->check_source_eligible(source_, cert_.get(), data_size()); + auto r = overlay_->check_source_eligible(source_, cert_.get(), data_size(), false); + if (r == BroadcastCheckResult::Forbidden) { + return td::Status::Error(ErrorCode::error, "broadcast is forbidden"); + } + + is_valid_ = r == BroadcastCheckResult::Allowed; + return td::Status::OK(); } td::BufferSlice BroadcastSimple::to_sign() { @@ -66,6 +78,14 @@ td::Status BroadcastSimple::distribute() { return td::Status::OK(); } +void BroadcastSimple::broadcast_checked(td::Result R) { + if (R.is_error()) { + return; + } + is_valid_ = true; + run_continue().ignore(); +} + tl_object_ptr BroadcastSimple::tl() const { return create_tl_object(source_.tl(), cert_ ? cert_->tl() : Certificate::empty_tl(), flags_, data_.clone(), date_, signature_.clone()); @@ -75,6 +95,25 @@ td::BufferSlice BroadcastSimple::serialize() { return serialize_tl_object(tl(), true); } +td::Status BroadcastSimple::run_continue() { + TRY_STATUS(distribute()); + deliver(); + return td::Status::OK(); +} + +td::Status BroadcastSimple::run() { + TRY_STATUS(run_checks()); + if (!is_valid_) { + auto P = td::PromiseCreator::lambda( + [id = broadcast_hash_, overlay_id = actor_id(overlay_)](td::Result R) mutable { + td::actor::send_closure(std::move(overlay_id), &OverlayImpl::broadcast_checked, id, std::move(R)); + }); + overlay_->check_broadcast(source_.compute_short_id(), data_.clone(), std::move(P)); + return td::Status::OK(); + } + return run_continue(); +} + td::Status BroadcastSimple::create(OverlayImpl *overlay, tl_object_ptr broadcast) { auto src = PublicKey{broadcast->src_}; auto data_hash = sha256_bits256(broadcast->data_.as_slice()); @@ -86,7 +125,7 @@ td::Status BroadcastSimple::create(OverlayImpl *overlay, tl_object_ptr(broadcast_hash, src, std::move(cert), broadcast->flags_, std::move(broadcast->data_), broadcast->date_, - std::move(broadcast->signature_), overlay); + std::move(broadcast->signature_), false, overlay); TRY_STATUS(B->run()); overlay->register_simple_broadcast(std::move(B)); return td::Status::OK(); @@ -100,7 +139,7 @@ td::Status BroadcastSimple::create_new(td::actor::ActorId overlay, auto date = static_cast(td::Clocks::system()); auto B = std::make_unique(broadcast_hash, PublicKey{}, nullptr, flags, std::move(data), date, - td::BufferSlice{}, nullptr); + td::BufferSlice{}, false, nullptr); auto to_sign = B->to_sign(); auto P = td::PromiseCreator::lambda( diff --git a/overlay/overlay-broadcast.hpp b/overlay/overlay-broadcast.hpp index 665c269d..da29695a 100644 --- a/overlay/overlay-broadcast.hpp +++ b/overlay/overlay-broadcast.hpp @@ -18,9 +18,16 @@ */ #pragma once +#include "adnl/adnl-local-id.h" +#include "adnl/adnl-node-id.hpp" #include "auto/tl/ton_api.h" +#include "common/refcnt.hpp" #include "overlay/overlay.h" +#include "td/actor/PromiseFuture.h" #include "td/utils/List.h" +#include "td/utils/Status.h" +#include "td/utils/buffer.h" +#include "td/utils/common.h" namespace ton { @@ -38,6 +45,7 @@ class BroadcastSimple : public td::ListNode { td::BufferSlice data_; td::uint32 date_; td::BufferSlice signature_; + bool is_valid_{false}; OverlayImpl *overlay_; @@ -52,7 +60,7 @@ class BroadcastSimple : public td::ListNode { public: BroadcastSimple(Overlay::BroadcastHash broadcast_hash, PublicKey source, std::shared_ptr cert, - td::uint32 flags, td::BufferSlice data, td::uint32 date, td::BufferSlice signature, + td::uint32 flags, td::BufferSlice data, td::uint32 date, td::BufferSlice signature, bool is_valid, OverlayImpl *overlay) : broadcast_hash_(broadcast_hash) , source_(std::move(source)) @@ -61,6 +69,7 @@ class BroadcastSimple : public td::ListNode { , data_(std::move(data)) , date_(date) , signature_(std::move(signature)) + , is_valid_(is_valid) , overlay_(overlay) { } @@ -80,17 +89,14 @@ class BroadcastSimple : public td::ListNode { } void deliver(); - td::Status run() { - TRY_STATUS(run_checks()); - TRY_STATUS(distribute()); - deliver(); - return td::Status::OK(); - } + td::Status run(); + td::Status run_continue(); tl_object_ptr tl() const; td::BufferSlice serialize(); void update_overlay(OverlayImpl *overlay); + void broadcast_checked(td::Result R); static td::Status create(OverlayImpl *overlay, tl_object_ptr broadcast); static td::Status create_new(td::actor::ActorId overlay, td::actor::ActorId keyring, diff --git a/overlay/overlay-fec-broadcast.cpp b/overlay/overlay-fec-broadcast.cpp index e368c620..6ab03800 100644 --- a/overlay/overlay-fec-broadcast.cpp +++ b/overlay/overlay-fec-broadcast.cpp @@ -54,7 +54,16 @@ td::Status OverlayFecBroadcastPart::check_duplicate() { } td::Status OverlayFecBroadcastPart::check_source() { - TRY_STATUS(overlay_->check_source_eligible(source_, cert_.get(), broadcast_size_)); + auto r = overlay_->check_source_eligible(source_, cert_.get(), broadcast_size_, true); + if (r == BroadcastCheckResult::Forbidden) { + return td::Status::Error(ErrorCode::error, "broadcast is forbidden"); + } + + // FIXME + if (r == BroadcastCheckResult::NeedCheck) { + return td::Status::Error(ErrorCode::error, "broadcast is forbidden"); + } + if (bcast_) { TRY_STATUS(bcast_->is_eligible_sender(source_)); } diff --git a/overlay/overlay-fec-broadcast.hpp b/overlay/overlay-fec-broadcast.hpp index 6d30d47c..0ce9c2ff 100644 --- a/overlay/overlay-fec-broadcast.hpp +++ b/overlay/overlay-fec-broadcast.hpp @@ -185,6 +185,9 @@ class BroadcastFec : public td::ListNode { } } + void broadcast_checked(td::Result R) { + } + private: bool ready_ = false; @@ -311,4 +314,3 @@ class OverlayFecBroadcastPart : public td::ListNode { } // namespace overlay } // namespace ton - diff --git a/overlay/overlay-manager.cpp b/overlay/overlay-manager.cpp index ae7c3dd5..059ad4e2 100644 --- a/overlay/overlay-manager.cpp +++ b/overlay/overlay-manager.cpp @@ -17,6 +17,7 @@ Copyright 2017-2020 Telegram Systems LLP */ #include "overlay-manager.h" +#include "auto/tl/ton_api.h" #include "overlay.h" #include "adnl/utils.hpp" @@ -268,17 +269,21 @@ void OverlayManager::save_to_db(adnl::AdnlNodeIdShort local_id, OverlayIdShort o db_.set(key, create_serialize_tl_object(std::move(obj))); } -Certificate::Certificate(PublicKey issued_by, td::int32 expire_at, td::uint32 max_size, td::BufferSlice signature) +Certificate::Certificate(PublicKey issued_by, td::int32 expire_at, td::uint32 max_size, td::uint32 flags, + td::BufferSlice signature) : issued_by_(issued_by) , expire_at_(expire_at) , max_size_(max_size) + , flags_(flags) , signature_(td::SharedSlice(signature.as_slice())) { } -Certificate::Certificate(PublicKeyHash issued_by, td::int32 expire_at, td::uint32 max_size, td::BufferSlice signature) +Certificate::Certificate(PublicKeyHash issued_by, td::int32 expire_at, td::uint32 max_size, td::uint32 flags, + td::BufferSlice signature) : issued_by_(issued_by) , expire_at_(expire_at) , max_size_(max_size) + , flags_(flags) , signature_(td::SharedSlice(signature.as_slice())) { } @@ -290,9 +295,19 @@ void Certificate::set_issuer(PublicKey issuer) { issued_by_ = issuer; } +constexpr td::uint32 cert_default_flags(td::uint32 max_size) { + return (max_size > Overlays::max_simple_broadcast_size() ? CertificateFlags::AllowFec : 0) | + CertificateFlags::Trusted; +} + td::BufferSlice Certificate::to_sign(OverlayIdShort overlay_id, PublicKeyHash issued_to) const { - return create_serialize_tl_object(overlay_id.tl(), issued_to.tl(), expire_at_, - max_size_); + if (flags_ == cert_default_flags(max_size_)) { + return create_serialize_tl_object(overlay_id.tl(), issued_to.tl(), expire_at_, + max_size_); + } else { + return create_serialize_tl_object(overlay_id.tl(), issued_to.tl(), expire_at_, + max_size_, flags_); + } } const PublicKeyHash Certificate::issuer_hash() const { @@ -307,32 +322,48 @@ const PublicKey &Certificate::issuer() const { td::Result> Certificate::create(tl_object_ptr cert) { std::shared_ptr res; - ton_api::downcast_call(*cert.get(), td::overloaded([&](ton_api::overlay_emptyCertificate &obj) { res = nullptr; }, - [&](ton_api::overlay_certificate &obj) { - res = std::make_shared( - PublicKey{obj.issued_by_}, obj.expire_at_, - static_cast(obj.max_size_), - std::move(obj.signature_)); - })); + ton_api::downcast_call(*cert.get(), + td::overloaded([&](ton_api::overlay_emptyCertificate &obj) { res = nullptr; }, + [&](ton_api::overlay_certificate &obj) { + res = std::make_shared(PublicKey{obj.issued_by_}, obj.expire_at_, + static_cast(obj.max_size_), + cert_default_flags(obj.max_size_), + std::move(obj.signature_)); + }, + [&](ton_api::overlay_certificateV2 &obj) { + res = std::make_shared(PublicKey{obj.issued_by_}, obj.expire_at_, + static_cast(obj.max_size_), + static_cast(obj.flags_), + std::move(obj.signature_)); + })); return std::move(res); } -td::Status Certificate::check(PublicKeyHash node, OverlayIdShort overlay_id, td::int32 unix_time, - td::uint32 size) const { +BroadcastCheckResult Certificate::check(PublicKeyHash node, OverlayIdShort overlay_id, td::int32 unix_time, + td::uint32 size, bool is_fec) const { if (size > max_size_) { - return td::Status::Error(ErrorCode::protoviolation, "too big broadcast size"); + return BroadcastCheckResult::Forbidden; } if (unix_time > expire_at_) { - return td::Status::Error(ErrorCode::protoviolation, "too old certificate"); + return BroadcastCheckResult::Forbidden; + } + if (is_fec && !(flags_ & CertificateFlags::AllowFec)) { + return BroadcastCheckResult::Forbidden; } - TRY_RESULT(E, issued_by_.get().create_encryptor()); + auto R1 = issued_by_.get().create_encryptor(); + if (R1.is_error()) { + return BroadcastCheckResult::Forbidden; + } + auto E = R1.move_as_ok(); auto B = to_sign(overlay_id, node); - TRY_STATUS(E->check_signature(B.as_slice(), signature_.as_slice())); + if (E->check_signature(B.as_slice(), signature_.as_slice()).is_error()) { + return BroadcastCheckResult::Forbidden; + } - return td::Status::OK(); + return (flags_ & CertificateFlags::Trusted) ? BroadcastCheckResult::Allowed : BroadcastCheckResult::NeedCheck; } tl_object_ptr Certificate::tl() const { diff --git a/overlay/overlay.cpp b/overlay/overlay.cpp index 47019c16..21ec9363 100644 --- a/overlay/overlay.cpp +++ b/overlay/overlay.cpp @@ -391,25 +391,21 @@ td::Status OverlayImpl::check_date(td::uint32 date) { return td::Status::OK(); } -td::Status OverlayImpl::check_source_eligible(PublicKey source, const Certificate *cert, td::uint32 size) { +BroadcastCheckResult OverlayImpl::check_source_eligible(PublicKey source, const Certificate *cert, td::uint32 size, + bool is_fec) { if (size == 0) { - return td::Status::Error(ErrorCode::protoviolation, "empty broadcast"); + return BroadcastCheckResult::Forbidden; } auto short_id = source.compute_short_id(); - auto r = rules_.max_size(source.compute_short_id()); - if (r >= size) { - return td::Status::OK(); + auto r = rules_.check_rules(source.compute_short_id(), size, is_fec); + if (!cert || r == BroadcastCheckResult::Allowed) { + return r; } - if (!cert) { - return td::Status::Error(ErrorCode::protoviolation, "source is not eligible"); - } - TRY_STATUS(cert->check(short_id, overlay_id_, static_cast(td::Clocks::system()), size)); - auto issuer_short = cert->issuer_hash(); - if (rules_.max_size(issuer_short) < size) { - return td::Status::Error(ErrorCode::protoviolation, "bad certificate"); - } - return td::Status::OK(); + + auto r2 = cert->check(short_id, overlay_id_, static_cast(td::Clocks::system()), size, is_fec); + r2 = broadcast_check_result_min(r2, rules_.check_rules(cert->issuer_hash(), size, is_fec)); + return broadcast_check_result_max(r, r2); } td::Status OverlayImpl::check_delivered(BroadcastHash hash) { @@ -539,6 +535,25 @@ void OverlayImpl::set_privacy_rules(OverlayPrivacyRules rules) { rules_ = std::move(rules); } +void OverlayImpl::check_broadcast(PublicKeyHash src, td::BufferSlice data, td::Promise promise) { + callback_->check_broadcast(src, overlay_id_, std::move(data), std::move(promise)); +} + +void OverlayImpl::broadcast_checked(Overlay::BroadcastHash hash, td::Result R) { + { + auto it = broadcasts_.find(hash); + if (it != broadcasts_.end()) { + it->second->broadcast_checked(std::move(R)); + } + } + { + auto it = fec_broadcasts_.find(hash); + if (it != fec_broadcasts_.end()) { + it->second->broadcast_checked(std::move(R)); + } + } +} + } // namespace overlay } // namespace ton diff --git a/overlay/overlay.hpp b/overlay/overlay.hpp index b087fc75..cbddd654 100644 --- a/overlay/overlay.hpp +++ b/overlay/overlay.hpp @@ -144,9 +144,12 @@ class OverlayImpl : public Overlay { void print(td::StringBuilder &sb) override; td::Status check_date(td::uint32 date); - td::Status check_source_eligible(PublicKey source, const Certificate *cert, td::uint32 size); + BroadcastCheckResult check_source_eligible(PublicKey source, const Certificate *cert, td::uint32 size, bool is_fec); td::Status check_delivered(BroadcastHash hash); + void broadcast_checked(Overlay::BroadcastHash hash, td::Result R); + void check_broadcast(PublicKeyHash src, td::BufferSlice data, td::Promise promise); + BroadcastFec *get_fec_broadcast(BroadcastHash hash); void register_fec_broadcast(std::unique_ptr bcast); void register_simple_broadcast(std::unique_ptr bcast); diff --git a/overlay/overlays.h b/overlay/overlays.h index 90f3877e..1ad55453 100644 --- a/overlay/overlays.h +++ b/overlay/overlays.h @@ -21,7 +21,11 @@ #include "adnl/adnl.h" #include "dht/dht.h" +#include "td/actor/PromiseFuture.h" #include "td/actor/actor.h" +#include "td/utils/Status.h" +#include "td/utils/buffer.h" +#include "td/utils/common.h" #include @@ -80,41 +84,64 @@ class OverlayIdFull { td::BufferSlice name_; }; +struct CertificateFlags { + enum Values : td::uint32 { AllowFec = 1, Trusted = 2 }; +}; + +enum BroadcastCheckResult { Forbidden = 1, NeedCheck = 2, Allowed = 3 }; + +inline BroadcastCheckResult broadcast_check_result_max(BroadcastCheckResult l, BroadcastCheckResult r) { + return static_cast(std::max(static_cast(l), static_cast(r))); +} +inline BroadcastCheckResult broadcast_check_result_min(BroadcastCheckResult l, BroadcastCheckResult r) { + return static_cast(std::min(static_cast(l), static_cast(r))); +} + class OverlayPrivacyRules { public: OverlayPrivacyRules() { } OverlayPrivacyRules(td::uint32 size) : max_unath_size_(size) { } - OverlayPrivacyRules(td::uint32 max_size, std::map authorized_keys) - : max_unath_size_(max_size), authorized_keys_(std::move(authorized_keys)) { + OverlayPrivacyRules(td::uint32 max_size, td::uint32 flags, std::map authorized_keys) + : max_unath_size_(max_size), flags_(flags), authorized_keys_(std::move(authorized_keys)) { } - td::uint32 max_size(PublicKeyHash hash) { + BroadcastCheckResult check_rules(PublicKeyHash hash, td::uint32 size, bool is_fec) { auto it = authorized_keys_.find(hash); if (it == authorized_keys_.end()) { - return max_unath_size_; + if (size > max_unath_size_) { + return BroadcastCheckResult::Forbidden; + } + if (!(flags_ & CertificateFlags::AllowFec) && is_fec) { + return BroadcastCheckResult::Forbidden; + } + return (flags_ & CertificateFlags::Trusted) ? BroadcastCheckResult::Allowed : BroadcastCheckResult::NeedCheck; } else { - return it->second; + return it->second >= size ? BroadcastCheckResult::Allowed : BroadcastCheckResult::Forbidden; } } private: td::uint32 max_unath_size_{0}; + td::uint32 flags_{0}; std::map authorized_keys_; }; class Certificate { public: - Certificate(PublicKeyHash issued_by, td::int32 expire_at, td::uint32 max_size, td::BufferSlice signature); - Certificate(PublicKey issued_by, td::int32 expire_at, td::uint32 max_size, td::BufferSlice signature); + Certificate(PublicKeyHash issued_by, td::int32 expire_at, td::uint32 max_size, td::uint32 flags, + td::BufferSlice signature); + Certificate(PublicKey issued_by, td::int32 expire_at, td::uint32 max_size, td::uint32 flags, + td::BufferSlice signature); Certificate() { } void set_signature(td::BufferSlice signature); void set_issuer(PublicKey issuer); td::BufferSlice to_sign(OverlayIdShort overlay_id, PublicKeyHash issued_to) const; - td::Status check(PublicKeyHash node, OverlayIdShort overlay_id, td::int32 unix_time, td::uint32 size) const; + BroadcastCheckResult check(PublicKeyHash node, OverlayIdShort overlay_id, td::int32 unix_time, td::uint32 size, + bool is_fec) const; tl_object_ptr tl() const; const PublicKey &issuer() const; const PublicKeyHash issuer_hash() const; @@ -126,6 +153,7 @@ class Certificate { td::Variant issued_by_; td::int32 expire_at_; td::uint32 max_size_; + td::uint32 flags_; td::SharedSlice signature_; }; @@ -137,6 +165,10 @@ class Overlays : public td::actor::Actor { virtual void receive_query(adnl::AdnlNodeIdShort src, OverlayIdShort overlay_id, td::BufferSlice data, td::Promise promise) = 0; virtual void receive_broadcast(PublicKeyHash src, OverlayIdShort overlay_id, td::BufferSlice data) = 0; + virtual void check_broadcast(PublicKeyHash src, OverlayIdShort overlay_id, td::BufferSlice data, + td::Promise promise) { + promise.set_value(td::Unit()); + } virtual ~Callback() = default; }; diff --git a/tl/generate/scheme/ton_api.tl b/tl/generate/scheme/ton_api.tl index 57ed9ddc..b226ca7f 100644 --- a/tl/generate/scheme/ton_api.tl +++ b/tl/generate/scheme/ton_api.tl @@ -219,9 +219,11 @@ overlay.broadcastFec.partId broadcast_hash:int256 data_hash:int256 seqno:int = o overlay.broadcast.toSign hash:int256 date:int = overlay.broadcast.ToSign; overlay.certificate issued_by:PublicKey expire_at:int max_size:int signature:bytes = overlay.Certificate; +overlay.certificateV2 issued_by:PublicKey expire_at:int max_size:int flags:int signature:bytes = overlay.Certificate; overlay.emptyCertificate = overlay.Certificate; overlay.certificateId overlay_id:int256 node:int256 expire_at:int max_size:int = overlay.CertificateId; +overlay.certificateIdV2 overlay_id:int256 node:int256 expire_at:int max_size:int flags:int = overlay.CertificateId; overlay.unicast data:bytes = overlay.Broadcast; overlay.broadcast src:PublicKey certificate:overlay.Certificate flags:int data:bytes date:int signature:bytes = overlay.Broadcast; diff --git a/tl/generate/scheme/ton_api.tlo b/tl/generate/scheme/ton_api.tlo index 823219b5..32f42b3c 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 bc295992..769ef8f3 100644 --- a/validator/full-node-shard.cpp +++ b/validator/full-node-shard.cpp @@ -16,6 +16,8 @@ Copyright 2017-2020 Telegram Systems LLP */ +#include "auto/tl/ton_api.h" +#include "overlays.h" #include "td/utils/SharedSlice.h" #include "full-node-shard.hpp" #include "full-node-shard-queries.hpp" @@ -79,6 +81,10 @@ void FullNodeShardImpl::create_overlay() { 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 promise) override { + td::actor::send_closure(node_, &FullNodeShardImpl::check_broadcast, src, std::move(data), std::move(promise)); + } Callback(td::actor::ActorId node) : node_(node) { } @@ -95,6 +101,17 @@ void FullNodeShardImpl::create_overlay() { } } +void FullNodeShardImpl::check_broadcast(PublicKeyHash src, td::BufferSlice broadcast, td::Promise promise) { + auto B = fetch_tl_object(std::move(broadcast), true); + if (B.is_error()) { + return promise.set_error(B.move_as_error_prefix("failed to parse external message broadcast: ")); + } + + auto q = B.move_as_ok(); + td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::check_external_message, + std::move(q->message_->data_), std::move(promise)); +} + void FullNodeShardImpl::update_adnl_id(adnl::AdnlNodeIdShort adnl_id, td::Promise promise) { td::actor::send_closure(overlays_, &ton::overlay::Overlays::delete_overlay, adnl_id_, overlay_id_); adnl_id_ = adnl_id; @@ -804,8 +821,9 @@ void FullNodeShardImpl::sign_new_certificate(PublicKeyHash sign_by) { return; } - ton::overlay::Certificate cert{sign_by, static_cast(td::Clocks::system() + 3600), - overlay::Overlays::max_fec_broadcast_size(), td::BufferSlice{}}; + ton::overlay::Certificate cert{ + sign_by, static_cast(td::Clocks::system() + 3600), overlay::Overlays::max_fec_broadcast_size(), + overlay::CertificateFlags::Trusted | overlay::CertificateFlags::AllowFec, td::BufferSlice{}}; auto to_sign = cert.to_sign(overlay_id_, local_id_); auto P = td::PromiseCreator::lambda( @@ -845,7 +863,7 @@ void FullNodeShardImpl::update_validators(std::vector public_key_ authorized_keys.emplace(key, overlay::Overlays::max_fec_broadcast_size()); } - rules_ = overlay::OverlayPrivacyRules{1 << 14, std::move(authorized_keys)}; + rules_ = overlay::OverlayPrivacyRules{1 << 14, 0, std::move(authorized_keys)}; td::actor::send_closure(overlays_, &overlay::Overlays::set_privacy_rules, adnl_id_, overlay_id_, rules_); if (update_cert) { @@ -949,8 +967,7 @@ void FullNodeShardImpl::update_neighbour_stats(adnl::AdnlNodeIdShort adnl_id, do } } -void FullNodeShardImpl::got_neighbour_capabilities(adnl::AdnlNodeIdShort adnl_id, double t, - td::BufferSlice data) { +void FullNodeShardImpl::got_neighbour_capabilities(adnl::AdnlNodeIdShort adnl_id, double t, td::BufferSlice data) { auto it = neighbours_.find(adnl_id); if (it == neighbours_.end()) { return; diff --git a/validator/full-node-shard.hpp b/validator/full-node-shard.hpp index 4aad637b..2c468374 100644 --- a/validator/full-node-shard.hpp +++ b/validator/full-node-shard.hpp @@ -19,6 +19,8 @@ #pragma once #include "full-node-shard.h" +#include "td/actor/PromiseFuture.h" +#include "td/utils/port/Poll.h" namespace ton { @@ -139,6 +141,7 @@ class FullNodeShardImpl : public FullNodeShard { void process_broadcast(PublicKeyHash src, ton_api::tonNode_externalMessageBroadcast &query); void process_broadcast(PublicKeyHash src, ton_api::tonNode_newShardBlockBroadcast &query); void receive_broadcast(PublicKeyHash src, td::BufferSlice query); + void check_broadcast(PublicKeyHash src, td::BufferSlice query, td::Promise promise); void send_ihr_message(td::BufferSlice data) override; void send_external_message(td::BufferSlice data) override; diff --git a/validator/manager-disk.hpp b/validator/manager-disk.hpp index 71818e6e..fa365ccf 100644 --- a/validator/manager-disk.hpp +++ b/validator/manager-disk.hpp @@ -124,6 +124,9 @@ class ValidatorManagerImpl : public ValidatorManager { //void get_block_description(BlockIdExt block_id, td::Promise promise) override; void new_external_message(td::BufferSlice data) override; + void check_external_message(td::BufferSlice data, td::Promise promise) override { + UNREACHABLE(); + } void new_ihr_message(td::BufferSlice data) override; void new_shard_block(BlockIdExt block_id, CatchainSeqno cc_seqno, td::BufferSlice data) override; diff --git a/validator/manager-hardfork.hpp b/validator/manager-hardfork.hpp index 506ee036..9938bcb2 100644 --- a/validator/manager-hardfork.hpp +++ b/validator/manager-hardfork.hpp @@ -144,6 +144,9 @@ class ValidatorManagerImpl : public ValidatorManager { void get_key_block_proof_link(BlockIdExt block_id, td::Promise promise) override; void new_external_message(td::BufferSlice data) override; + void check_external_message(td::BufferSlice data, td::Promise promise) override { + UNREACHABLE(); + } void new_ihr_message(td::BufferSlice data) override; void new_shard_block(BlockIdExt block_id, CatchainSeqno cc_seqno, td::BufferSlice data) override { UNREACHABLE(); diff --git a/validator/manager.hpp b/validator/manager.hpp index 672085d0..08de5060 100644 --- a/validator/manager.hpp +++ b/validator/manager.hpp @@ -20,6 +20,8 @@ #include "interfaces/validator-manager.h" #include "interfaces/db.h" +#include "td/actor/PromiseFuture.h" +#include "td/utils/port/Poll.h" #include "validator-group.hpp" #include "shard-client.hpp" #include "manager-init.h" @@ -325,6 +327,9 @@ class ValidatorManagerImpl : public ValidatorManager { //void get_block_description(BlockIdExt block_id, td::Promise promise) override; void new_external_message(td::BufferSlice data) override; + void check_external_message(td::BufferSlice data, td::Promise promise) override { + promise.set_value(td::Unit()); + } void new_ihr_message(td::BufferSlice data) override; void new_shard_block(BlockIdExt block_id, CatchainSeqno cc_seqno, td::BufferSlice data) override; diff --git a/validator/validator.h b/validator/validator.h index 54c35ee7..0cbdbe00 100644 --- a/validator/validator.h +++ b/validator/validator.h @@ -94,9 +94,8 @@ struct ValidatorManagerOptions : public td::CntObject { BlockIdExt zero_block_id, BlockIdExt init_block_id, std::function check_shard = [](ShardIdFull, CatchainSeqno, ShardCheckMode) { return true; }, - bool allow_blockchain_init = false, double sync_blocks_before = 300, - double block_ttl = 86400 * 7, double state_ttl = 3600, - double archive_ttl = 86400 * 365, double key_proof_ttl = 86400 * 3650, + bool allow_blockchain_init = false, double sync_blocks_before = 300, double block_ttl = 86400 * 7, + double state_ttl = 3600, double archive_ttl = 86400 * 365, double key_proof_ttl = 86400 * 3650, bool initial_sync_disabled = false); }; @@ -176,6 +175,7 @@ class ValidatorManagerInterface : public td::actor::Actor { virtual void write_handle(BlockHandle handle, td::Promise promise) = 0; virtual void new_external_message(td::BufferSlice data) = 0; + virtual void check_external_message(td::BufferSlice data, td::Promise promise) = 0; virtual void new_ihr_message(td::BufferSlice data) = 0; virtual void new_shard_block(BlockIdExt block_id, CatchainSeqno cc_seqno, td::BufferSlice data) = 0;