1
0
Fork 0
mirror of https://github.com/ton-blockchain/ton synced 2025-03-09 15:40:10 +00:00

Validators temporary join shard overlays

This commit is contained in:
SpyCheese 2022-08-10 20:59:49 +03:00
parent 7749cbfa1f
commit 662435462e
18 changed files with 141 additions and 75 deletions

View file

@ -30,7 +30,6 @@
#include "td/utils/Status.h" #include "td/utils/Status.h"
#include "td/utils/overloaded.h" #include "td/utils/overloaded.h"
#include "keys/encryptor.h"
#include "td/utils/port/Poll.h" #include "td/utils/port/Poll.h"
#include <vector> #include <vector>
@ -92,7 +91,6 @@ void OverlayManager::delete_overlay(adnl::AdnlNodeIdShort local_id, OverlayIdSho
void OverlayManager::create_public_overlay(adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id, void OverlayManager::create_public_overlay(adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id,
std::unique_ptr<Callback> callback, OverlayPrivacyRules rules, td::string scope) { std::unique_ptr<Callback> callback, OverlayPrivacyRules rules, td::string scope) {
CHECK(!dht_node_.empty()); CHECK(!dht_node_.empty());
CHECK(callback != nullptr);
auto id = overlay_id.compute_short_id(); auto id = overlay_id.compute_short_id();
register_overlay(local_id, id, register_overlay(local_id, id,
Overlay::create(keyring_, adnl_, actor_id(this), dht_node_, local_id, std::move(overlay_id), Overlay::create(keyring_, adnl_, actor_id(this), dht_node_, local_id, std::move(overlay_id),
@ -100,12 +98,13 @@ void OverlayManager::create_public_overlay(adnl::AdnlNodeIdShort local_id, Overl
} }
void OverlayManager::create_public_overlay_external(adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id, void OverlayManager::create_public_overlay_external(adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id,
OverlayPrivacyRules rules, td::string scope) { std::unique_ptr<Callback> callback, OverlayPrivacyRules rules,
td::string scope) {
CHECK(!dht_node_.empty()); CHECK(!dht_node_.empty());
auto id = overlay_id.compute_short_id(); auto id = overlay_id.compute_short_id();
register_overlay(local_id, id, register_overlay(local_id, id,
Overlay::create(keyring_, adnl_, actor_id(this), dht_node_, local_id, std::move(overlay_id), nullptr, Overlay::create(keyring_, adnl_, actor_id(this), dht_node_, local_id, std::move(overlay_id),
std::move(rules), scope)); std::move(callback), std::move(rules), scope, true));
} }
void OverlayManager::create_private_overlay(adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id, void OverlayManager::create_private_overlay(adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id,
@ -155,16 +154,23 @@ void OverlayManager::receive_query(adnl::AdnlNodeIdShort src, adnl::AdnlNodeIdSh
auto M = R.move_as_ok(); 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<ton_api::overlay_message_removePeer>());
};
auto it = overlays_.find(dst); auto it = overlays_.find(dst);
if (it == overlays_.end()) { if (it == overlays_.end()) {
VLOG(OVERLAY_NOTICE) << this << ": query to unknown overlay " << M->overlay_ << "@" << dst << " from " << src; 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)); promise.set_error(td::Status::Error(ErrorCode::protoviolation, PSTRING() << "bad local_id " << dst));
send_remove_peer();
return; return;
} }
auto it2 = it->second.find(OverlayIdShort{M->overlay_}); auto it2 = it->second.find(overlay_id);
if (it2 == it->second.end()) { if (it2 == it->second.end()) {
VLOG(OVERLAY_NOTICE) << this << ": query to localid not in overlay " << M->overlay_ << "@" << dst << " from " << src; 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_)); promise.set_error(td::Status::Error(ErrorCode::protoviolation, PSTRING() << "bad overlay_id " << M->overlay_));
send_remove_peer();
return; return;
} }
@ -394,7 +400,7 @@ td::BufferSlice Certificate::to_sign(OverlayIdShort overlay_id, PublicKeyHash is
} }
} }
const PublicKeyHash Certificate::issuer_hash() const { PublicKeyHash Certificate::issuer_hash() const {
PublicKeyHash r; PublicKeyHash r;
issued_by_.visit( issued_by_.visit(
td::overloaded([&](const PublicKeyHash &x) { r = x; }, [&](const PublicKey &x) { r = x.compute_short_id(); })); td::overloaded([&](const PublicKeyHash &x) { r = x; }, [&](const PublicKey &x) { r = x.compute_short_id(); }));

View file

@ -53,7 +53,8 @@ class OverlayManager : public Overlays {
void create_public_overlay(adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id, void create_public_overlay(adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id,
std::unique_ptr<Callback> callback, OverlayPrivacyRules rules, td::string scope) override; std::unique_ptr<Callback> callback, OverlayPrivacyRules rules, td::string scope) override;
void create_public_overlay_external(adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id, void create_public_overlay_external(adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id,
OverlayPrivacyRules rules, td::string scope) override; std::unique_ptr<Callback> callback, OverlayPrivacyRules rules,
td::string scope) override;
void create_private_overlay(adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id, void create_private_overlay(adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id,
std::vector<adnl::AdnlNodeIdShort> nodes, std::unique_ptr<Callback> callback, std::vector<adnl::AdnlNodeIdShort> nodes, std::unique_ptr<Callback> callback,
OverlayPrivacyRules rules) override; OverlayPrivacyRules rules) override;

View file

@ -142,7 +142,7 @@ void OverlayImpl::receive_random_peers(adnl::AdnlNodeIdShort src, td::BufferSlic
void OverlayImpl::send_random_peers_cont(adnl::AdnlNodeIdShort src, OverlayNode node, void OverlayImpl::send_random_peers_cont(adnl::AdnlNodeIdShort src, OverlayNode node,
td::Promise<td::BufferSlice> promise) { td::Promise<td::BufferSlice> promise) {
std::vector<tl_object_ptr<ton_api::overlay_node>> vec; std::vector<tl_object_ptr<ton_api::overlay_node>> vec;
if (!is_external()) { if (!is_external_) {
vec.emplace_back(node.tl()); vec.emplace_back(node.tl());
} }

View file

@ -38,10 +38,10 @@ td::actor::ActorOwn<Overlay> Overlay::create(td::actor::ActorId<keyring::Keyring
td::actor::ActorId<OverlayManager> manager, td::actor::ActorId<OverlayManager> manager,
td::actor::ActorId<dht::Dht> dht_node, adnl::AdnlNodeIdShort local_id, td::actor::ActorId<dht::Dht> dht_node, adnl::AdnlNodeIdShort local_id,
OverlayIdFull overlay_id, std::unique_ptr<Overlays::Callback> callback, OverlayIdFull overlay_id, std::unique_ptr<Overlays::Callback> callback,
OverlayPrivacyRules rules, td::string scope) { OverlayPrivacyRules rules, td::string scope, bool is_external) {
auto R = td::actor::create_actor<OverlayImpl>("overlay", keyring, adnl, manager, dht_node, local_id, auto R = td::actor::create_actor<OverlayImpl>("overlay", keyring, adnl, manager, dht_node, local_id,
std::move(overlay_id), true, std::vector<adnl::AdnlNodeIdShort>(), std::move(overlay_id), true, std::vector<adnl::AdnlNodeIdShort>(),
std::move(callback), std::move(rules), scope); std::move(callback), std::move(rules), scope, is_external);
return td::actor::ActorOwn<Overlay>(std::move(R)); return td::actor::ActorOwn<Overlay>(std::move(R));
} }
@ -61,7 +61,7 @@ OverlayImpl::OverlayImpl(td::actor::ActorId<keyring::Keyring> keyring, td::actor
td::actor::ActorId<OverlayManager> manager, td::actor::ActorId<dht::Dht> dht_node, td::actor::ActorId<OverlayManager> manager, td::actor::ActorId<dht::Dht> dht_node,
adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id, bool pub, adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id, bool pub,
std::vector<adnl::AdnlNodeIdShort> nodes, std::unique_ptr<Overlays::Callback> callback, std::vector<adnl::AdnlNodeIdShort> nodes, std::unique_ptr<Overlays::Callback> callback,
OverlayPrivacyRules rules, td::string scope) OverlayPrivacyRules rules, td::string scope, bool is_external)
: keyring_(keyring) : keyring_(keyring)
, adnl_(adnl) , adnl_(adnl)
, manager_(manager) , manager_(manager)
@ -71,10 +71,11 @@ OverlayImpl::OverlayImpl(td::actor::ActorId<keyring::Keyring> keyring, td::actor
, callback_(std::move(callback)) , callback_(std::move(callback))
, public_(pub) , public_(pub)
, rules_(std::move(rules)) , rules_(std::move(rules))
, scope_(scope) { , scope_(scope)
, is_external_(is_external) {
overlay_id_ = id_full_.compute_short_id(); overlay_id_ = id_full_.compute_short_id();
if (is_external()) { if (is_external_) {
CHECK(public_); CHECK(public_);
VLOG(OVERLAY_INFO) << this << ": creating public external"; VLOG(OVERLAY_INFO) << this << ": creating public external";
} else { } else {
@ -92,7 +93,6 @@ OverlayImpl::OverlayImpl(td::actor::ActorId<keyring::Keyring> keyring, td::actor
void OverlayImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::overlay_getRandomPeers &query, void OverlayImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::overlay_getRandomPeers &query,
td::Promise<td::BufferSlice> promise) { td::Promise<td::BufferSlice> promise) {
CHECK(!is_external());
if (public_) { if (public_) {
VLOG(OVERLAY_DEBUG) << this << ": received " << query.peers_->nodes_.size() << " nodes from " << src VLOG(OVERLAY_DEBUG) << this << ": received " << query.peers_->nodes_.size() << " nodes from " << src
<< " in getRandomPeers query"; << " in getRandomPeers query";
@ -113,7 +113,6 @@ void OverlayImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::overlay_getR
void OverlayImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::overlay_getBroadcast &query, void OverlayImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::overlay_getBroadcast &query,
td::Promise<td::BufferSlice> promise) { td::Promise<td::BufferSlice> promise) {
CHECK(!is_external());
auto it = broadcasts_.find(query.hash_); auto it = broadcasts_.find(query.hash_);
if (it == broadcasts_.end()) { if (it == broadcasts_.end()) {
VLOG(OVERLAY_NOTICE) << this << ": received getBroadcastQuery(" << query.hash_ << ") from " << src VLOG(OVERLAY_NOTICE) << this << ": received getBroadcastQuery(" << query.hash_ << ") from " << src
@ -135,15 +134,16 @@ void OverlayImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::overlay_getB
void OverlayImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::overlay_getBroadcastList &query, void OverlayImpl::process_query(adnl::AdnlNodeIdShort src, ton_api::overlay_getBroadcastList &query,
td::Promise<td::BufferSlice> promise) { td::Promise<td::BufferSlice> promise) {
CHECK(!is_external());
VLOG(OVERLAY_WARNING) << this << ": DROPPING getBroadcastList query"; VLOG(OVERLAY_WARNING) << this << ": DROPPING getBroadcastList query";
promise.set_error(td::Status::Error(ErrorCode::protoviolation, "dropping get broadcast list query")); promise.set_error(td::Status::Error(ErrorCode::protoviolation, "dropping get broadcast list query"));
} }
void OverlayImpl::receive_query(adnl::AdnlNodeIdShort src, td::BufferSlice data, td::Promise<td::BufferSlice> promise) { void OverlayImpl::receive_query(adnl::AdnlNodeIdShort src, td::BufferSlice data, td::Promise<td::BufferSlice> promise) {
if (is_external()) { if (is_external_) {
LOG(OVERLAY_WARNING) << "dropping query in external overlay " << overlay_id_; LOG(OVERLAY_WARNING) << "dropping query in external overlay " << overlay_id_;
promise.set_error(td::Status::Error("overlay is external")); promise.set_error(td::Status::Error("overlay is external"));
td::actor::send_closure(manager_, &Overlays::send_message, src, local_id_, overlay_id_,
create_serialize_tl_object<ton_api::overlay_message_removePeer>());
return; return;
} }
if (!public_) { if (!public_) {
@ -171,32 +171,27 @@ void OverlayImpl::receive_query(adnl::AdnlNodeIdShort src, td::BufferSlice data,
td::Status OverlayImpl::process_broadcast(adnl::AdnlNodeIdShort message_from, td::Status OverlayImpl::process_broadcast(adnl::AdnlNodeIdShort message_from,
tl_object_ptr<ton_api::overlay_broadcast> bcast) { tl_object_ptr<ton_api::overlay_broadcast> bcast) {
CHECK(!is_external());
return BroadcastSimple::create(this, message_from, std::move(bcast)); return BroadcastSimple::create(this, message_from, std::move(bcast));
} }
td::Status OverlayImpl::process_broadcast(adnl::AdnlNodeIdShort message_from, td::Status OverlayImpl::process_broadcast(adnl::AdnlNodeIdShort message_from,
tl_object_ptr<ton_api::overlay_broadcastFec> b) { tl_object_ptr<ton_api::overlay_broadcastFec> b) {
CHECK(!is_external());
return OverlayFecBroadcastPart::create(this, message_from, std::move(b)); return OverlayFecBroadcastPart::create(this, message_from, std::move(b));
} }
td::Status OverlayImpl::process_broadcast(adnl::AdnlNodeIdShort message_from, td::Status OverlayImpl::process_broadcast(adnl::AdnlNodeIdShort message_from,
tl_object_ptr<ton_api::overlay_broadcastFecShort> b) { tl_object_ptr<ton_api::overlay_broadcastFecShort> b) {
CHECK(!is_external());
return OverlayFecBroadcastPart::create(this, message_from, std::move(b)); return OverlayFecBroadcastPart::create(this, message_from, std::move(b));
} }
td::Status OverlayImpl::process_broadcast(adnl::AdnlNodeIdShort message_from, td::Status OverlayImpl::process_broadcast(adnl::AdnlNodeIdShort message_from,
tl_object_ptr<ton_api::overlay_broadcastNotFound> bcast) { tl_object_ptr<ton_api::overlay_broadcastNotFound> bcast) {
CHECK(!is_external());
return td::Status::Error(ErrorCode::protoviolation, return td::Status::Error(ErrorCode::protoviolation,
PSTRING() << "received strange message broadcastNotFound from " << message_from); PSTRING() << "received strange message broadcastNotFound from " << message_from);
} }
td::Status OverlayImpl::process_broadcast(adnl::AdnlNodeIdShort message_from, td::Status OverlayImpl::process_broadcast(adnl::AdnlNodeIdShort message_from,
tl_object_ptr<ton_api::overlay_fec_received> msg) { tl_object_ptr<ton_api::overlay_fec_received> msg) {
CHECK(!is_external());
auto it = fec_broadcasts_.find(msg->hash_); auto it = fec_broadcasts_.find(msg->hash_);
if (it != fec_broadcasts_.end()) { if (it != fec_broadcasts_.end()) {
VLOG(OVERLAY_DEBUG) << this << ": received fec opt-out message from " << message_from << " for broadcast " VLOG(OVERLAY_DEBUG) << this << ": received fec opt-out message from " << message_from << " for broadcast "
@ -211,7 +206,6 @@ td::Status OverlayImpl::process_broadcast(adnl::AdnlNodeIdShort message_from,
td::Status OverlayImpl::process_broadcast(adnl::AdnlNodeIdShort message_from, td::Status OverlayImpl::process_broadcast(adnl::AdnlNodeIdShort message_from,
tl_object_ptr<ton_api::overlay_fec_completed> msg) { tl_object_ptr<ton_api::overlay_fec_completed> msg) {
CHECK(!is_external());
auto it = fec_broadcasts_.find(msg->hash_); auto it = fec_broadcasts_.find(msg->hash_);
if (it != fec_broadcasts_.end()) { if (it != fec_broadcasts_.end()) {
VLOG(OVERLAY_DEBUG) << this << ": received fec completed message from " << message_from << " for broadcast " VLOG(OVERLAY_DEBUG) << this << ": received fec completed message from " << message_from << " for broadcast "
@ -226,17 +220,12 @@ td::Status OverlayImpl::process_broadcast(adnl::AdnlNodeIdShort message_from,
td::Status OverlayImpl::process_broadcast(adnl::AdnlNodeIdShort message_from, td::Status OverlayImpl::process_broadcast(adnl::AdnlNodeIdShort message_from,
tl_object_ptr<ton_api::overlay_unicast> msg) { tl_object_ptr<ton_api::overlay_unicast> msg) {
CHECK(!is_external());
VLOG(OVERLAY_DEBUG) << this << ": received unicast from " << message_from; VLOG(OVERLAY_DEBUG) << this << ": received unicast from " << message_from;
callback_->receive_message(message_from, overlay_id_, std::move(msg->data_)); callback_->receive_message(message_from, overlay_id_, std::move(msg->data_));
return td::Status::OK(); return td::Status::OK();
} }
void OverlayImpl::receive_message(adnl::AdnlNodeIdShort src, td::BufferSlice data) { void OverlayImpl::receive_message(adnl::AdnlNodeIdShort src, td::BufferSlice data) {
if (is_external()) {
LOG(OVERLAY_WARNING) << "dropping message in external overlay " << overlay_id_;
return;
}
if (!public_) { if (!public_) {
if (peers_.get(src) == nullptr) { if (peers_.get(src) == nullptr) {
VLOG(OVERLAY_WARNING) << this << ": received query in private overlay from unknown source " << src; VLOG(OVERLAY_WARNING) << this << ": received query in private overlay from unknown source " << src;
@ -244,13 +233,29 @@ void OverlayImpl::receive_message(adnl::AdnlNodeIdShort src, td::BufferSlice dat
} }
} }
auto X = fetch_tl_object<ton_api::overlay_Broadcast>(data.clone(), true); auto X = fetch_tl_object<ton_api::overlay_Broadcast>(data.clone(), true);
if (X.is_error()) {
auto Y = fetch_tl_object<ton_api::overlay_message_removePeer>(data.clone(), true);
if (Y.is_ok()) {
VLOG(OVERLAY_DEBUG) << this << ": received removePeer message from " << src;
if (peers_.exists(src)) {
del_peer(src);
callback_->on_remove_peer(src);
}
return;
}
}
if (is_external_) {
LOG(OVERLAY_WARNING) << "dropping message in external overlay " << overlay_id_;
return;
}
if (X.is_error()) { if (X.is_error()) {
VLOG(OVERLAY_DEBUG) << this << ": received custom message"; VLOG(OVERLAY_DEBUG) << this << ": received custom message";
callback_->receive_message(src, overlay_id_, std::move(data)); callback_->receive_message(src, overlay_id_, std::move(data));
return; return;
} }
auto Q = X.move_as_ok(); auto Q = X.move_as_ok();
ton_api::downcast_call(*Q.get(), [Self = this, &Q, &src](auto &object) { ton_api::downcast_call(*Q, [Self = this, &Q, &src](auto &object) {
Self->process_broadcast(src, move_tl_object_as<std::remove_reference_t<decltype(object)>>(Q)); Self->process_broadcast(src, move_tl_object_as<std::remove_reference_t<decltype(object)>>(Q));
}); });
} }
@ -344,7 +349,7 @@ void OverlayImpl::receive_dht_nodes(td::Result<dht::DhtValue> res, bool dummy) {
VLOG(OVERLAY_NOTICE) << this << ": can not get value from DHT: " << res.move_as_error(); VLOG(OVERLAY_NOTICE) << this << ": can not get value from DHT: " << res.move_as_error();
} }
if (is_external()) { if (is_external_) {
return; return;
} }
@ -548,7 +553,7 @@ void OverlayImpl::send_new_fec_broadcast_part(PublicKeyHash local_id, Overlay::B
} }
void OverlayImpl::deliver_broadcast(PublicKeyHash source, td::BufferSlice data) { void OverlayImpl::deliver_broadcast(PublicKeyHash source, td::BufferSlice data) {
if (is_external()) { if (is_external_) {
return; return;
} }
callback_->receive_broadcast(source, overlay_id_, std::move(data)); callback_->receive_broadcast(source, overlay_id_, std::move(data));
@ -623,7 +628,7 @@ void OverlayImpl::set_privacy_rules(OverlayPrivacyRules rules) {
} }
void OverlayImpl::check_broadcast(PublicKeyHash src, td::BufferSlice data, td::Promise<td::Unit> promise) { void OverlayImpl::check_broadcast(PublicKeyHash src, td::BufferSlice data, td::Promise<td::Unit> promise) {
if (is_external()) { if (is_external_) {
promise.set_result(td::Unit()); promise.set_result(td::Unit());
return; return;
} }

View file

@ -42,7 +42,7 @@ class Overlay : public td::actor::Actor {
td::actor::ActorId<OverlayManager> manager, td::actor::ActorId<OverlayManager> manager,
td::actor::ActorId<dht::Dht> dht_node, adnl::AdnlNodeIdShort local_id, td::actor::ActorId<dht::Dht> dht_node, adnl::AdnlNodeIdShort local_id,
OverlayIdFull overlay_id, std::unique_ptr<Overlays::Callback> callback, OverlayIdFull overlay_id, std::unique_ptr<Overlays::Callback> callback,
OverlayPrivacyRules rules, td::string scope); OverlayPrivacyRules rules, td::string scope, bool is_external = false);
static td::actor::ActorOwn<Overlay> create(td::actor::ActorId<keyring::Keyring> keyring, static td::actor::ActorOwn<Overlay> create(td::actor::ActorId<keyring::Keyring> keyring,
td::actor::ActorId<adnl::Adnl> adnl, td::actor::ActorId<adnl::Adnl> adnl,
td::actor::ActorId<OverlayManager> manager, td::actor::ActorId<OverlayManager> manager,

View file

@ -113,7 +113,7 @@ class OverlayImpl : public Overlay {
td::actor::ActorId<OverlayManager> manager, td::actor::ActorId<dht::Dht> dht_node, td::actor::ActorId<OverlayManager> manager, td::actor::ActorId<dht::Dht> dht_node,
adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id, bool pub, adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id, bool pub,
std::vector<adnl::AdnlNodeIdShort> nodes, std::unique_ptr<Overlays::Callback> callback, std::vector<adnl::AdnlNodeIdShort> nodes, std::unique_ptr<Overlays::Callback> callback,
OverlayPrivacyRules rules, td::string scope = "{ \"type\": \"undefined\" }"); OverlayPrivacyRules rules, td::string scope = "{ \"type\": \"undefined\" }", bool is_external = false);
void update_dht_node(td::actor::ActorId<dht::Dht> dht) override { void update_dht_node(td::actor::ActorId<dht::Dht> dht) override {
dht_node_ = dht; dht_node_ = dht;
} }
@ -251,13 +251,8 @@ class OverlayImpl : public Overlay {
} }
private: private:
bool is_external() const {
return callback_ == nullptr;
}
template <class T> template <class T>
void process_query(adnl::AdnlNodeIdShort src, T &query, td::Promise<td::BufferSlice> promise) { void process_query(adnl::AdnlNodeIdShort src, T &query, td::Promise<td::BufferSlice> promise) {
CHECK(!is_external());
callback_->receive_query(src, overlay_id_, serialize_tl_object(&query, true), std::move(promise)); callback_->receive_query(src, overlay_id_, serialize_tl_object(&query, true), std::move(promise));
} }
@ -357,6 +352,7 @@ class OverlayImpl : public Overlay {
bool semi_public_ = false; bool semi_public_ = false;
OverlayPrivacyRules rules_; OverlayPrivacyRules rules_;
td::string scope_; td::string scope_;
bool is_external_ = false;
std::map<PublicKeyHash, std::shared_ptr<Certificate>> certs_; std::map<PublicKeyHash, std::shared_ptr<Certificate>> certs_;
class CachedEncryptor : public td::ListNode { class CachedEncryptor : public td::ListNode {

View file

@ -145,7 +145,7 @@ class Certificate {
bool is_fec) const; bool is_fec) const;
tl_object_ptr<ton_api::overlay_Certificate> tl() const; tl_object_ptr<ton_api::overlay_Certificate> tl() const;
const PublicKey &issuer() const; const PublicKey &issuer() const;
const PublicKeyHash issuer_hash() const; PublicKeyHash issuer_hash() const;
static td::Result<std::shared_ptr<Certificate>> create(tl_object_ptr<ton_api::overlay_Certificate> cert); static td::Result<std::shared_ptr<Certificate>> create(tl_object_ptr<ton_api::overlay_Certificate> cert);
static tl_object_ptr<ton_api::overlay_Certificate> empty_tl(); static tl_object_ptr<ton_api::overlay_Certificate> empty_tl();
@ -170,6 +170,8 @@ class Overlays : public td::actor::Actor {
td::Promise<td::Unit> promise) { td::Promise<td::Unit> promise) {
promise.set_value(td::Unit()); promise.set_value(td::Unit());
} }
virtual void on_remove_peer(adnl::AdnlNodeIdShort src) {
}
virtual ~Callback() = default; virtual ~Callback() = default;
}; };
@ -195,7 +197,8 @@ class Overlays : public td::actor::Actor {
virtual void create_public_overlay(adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id, virtual void create_public_overlay(adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id,
std::unique_ptr<Callback> callback, OverlayPrivacyRules rules, td::string scope) = 0; std::unique_ptr<Callback> callback, OverlayPrivacyRules rules, td::string scope) = 0;
virtual void create_public_overlay_external(adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id, virtual void create_public_overlay_external(adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id,
OverlayPrivacyRules rules, td::string scope) = 0; std::unique_ptr<Callback> callback, OverlayPrivacyRules rules,
td::string scope) = 0;
virtual void create_private_overlay(adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id, virtual void create_private_overlay(adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id,
std::vector<adnl::AdnlNodeIdShort> nodes, std::unique_ptr<Callback> callback, std::vector<adnl::AdnlNodeIdShort> nodes, std::unique_ptr<Callback> callback,
OverlayPrivacyRules rules) = 0; OverlayPrivacyRules rules) = 0;

View file

@ -211,6 +211,8 @@ overlay.message overlay:int256 = overlay.Message;
//overlay.randomPeers peers:(vector adnl.node) = overlay.RandomPeers; //overlay.randomPeers peers:(vector adnl.node) = overlay.RandomPeers;
overlay.broadcastList hashes:(vector int256) = overlay.BroadcastList; overlay.broadcastList hashes:(vector int256) = overlay.BroadcastList;
overlay.message.removePeer = overlay.message.InternalMessage;
overlay.fec.received hash:int256 = overlay.Broadcast; overlay.fec.received hash:int256 = overlay.Broadcast;
overlay.fec.completed hash:int256 = overlay.Broadcast; overlay.fec.completed hash:int256 = overlay.Broadcast;

Binary file not shown.

View file

@ -25,7 +25,6 @@
#include "ton/ton-shard.h" #include "ton/ton-shard.h"
#include "ton/ton-tl.hpp" #include "ton/ton-tl.hpp"
#include "ton/ton-io.hpp"
#include "adnl/utils.hpp" #include "adnl/utils.hpp"
#include "net/download-block-new.hpp" #include "net/download-block-new.hpp"
@ -71,38 +70,41 @@ void Neighbour::update_roundtrip(double t) {
} }
void FullNodeShardImpl::create_overlay() { 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));
}
void on_remove_peer(adnl::AdnlNodeIdShort src) override {
td::actor::send_closure(node_, &FullNodeShardImpl::remove_neighbour, src);
}
Callback(td::actor::ActorId<FullNodeShardImpl> node) : node_(node) {
}
private:
td::actor::ActorId<FullNodeShardImpl> node_;
};
if (active_) { if (active_) {
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_;
};
td::actor::send_closure(overlays_, &overlay::Overlays::create_public_overlay, adnl_id_, overlay_id_full_.clone(), td::actor::send_closure(overlays_, &overlay::Overlays::create_public_overlay, adnl_id_, overlay_id_full_.clone(),
std::make_unique<Callback>(actor_id(this)), rules_, std::make_unique<Callback>(actor_id(this)), rules_,
PSTRING() << "{ \"type\": \"shard\", \"shard_id\": " << get_shard() PSTRING() << "{ \"type\": \"shard\", \"shard_id\": " << get_shard()
<< ", \"workchain_id\": " << get_workchain() << " }"); << ", \"workchain_id\": " << get_workchain() << " }");
} else { } else {
td::actor::send_closure(overlays_, &overlay::Overlays::create_public_overlay_external, adnl_id_, td::actor::send_closure(overlays_, &overlay::Overlays::create_public_overlay_external, adnl_id_,
overlay_id_full_.clone(), rules_, overlay_id_full_.clone(), std::make_unique<Callback>(actor_id(this)), rules_,
PSTRING() << "{ \"type\": \"shard\", \"shard_id\": " << get_shard() PSTRING() << "{ \"type\": \"shard\", \"shard_id\": " << get_shard()
<< ", \"workchain_id\": " << get_workchain() << " }"); << ", \"workchain_id\": " << get_workchain() << " }");
} }
@ -124,6 +126,10 @@ void FullNodeShardImpl::check_broadcast(PublicKeyHash src, td::BufferSlice broad
std::move(q->message_->data_), std::move(promise)); std::move(q->message_->data_), std::move(promise));
} }
void FullNodeShardImpl::remove_neighbour(adnl::AdnlNodeIdShort id) {
neighbours_.erase(id);
}
void FullNodeShardImpl::update_adnl_id(adnl::AdnlNodeIdShort adnl_id, td::Promise<td::Unit> promise) { void FullNodeShardImpl::update_adnl_id(adnl::AdnlNodeIdShort adnl_id, td::Promise<td::Unit> promise) {
td::actor::send_closure(overlays_, &ton::overlay::Overlays::delete_overlay, adnl_id_, overlay_id_); td::actor::send_closure(overlays_, &ton::overlay::Overlays::delete_overlay, adnl_id_, overlay_id_);
adnl_id_ = adnl_id; adnl_id_ = adnl_id;

View file

@ -145,6 +145,7 @@ class FullNodeShardImpl : public FullNodeShard {
void process_broadcast(PublicKeyHash src, ton_api::tonNode_newShardBlockBroadcast &query); void process_broadcast(PublicKeyHash src, ton_api::tonNode_newShardBlockBroadcast &query);
void receive_broadcast(PublicKeyHash src, td::BufferSlice query); void receive_broadcast(PublicKeyHash src, td::BufferSlice query);
void check_broadcast(PublicKeyHash src, td::BufferSlice query, td::Promise<td::Unit> promise); void check_broadcast(PublicKeyHash src, td::BufferSlice query, td::Promise<td::Unit> promise);
void remove_neighbour(adnl::AdnlNodeIdShort id);
void send_ihr_message(td::BufferSlice data) override; void send_ihr_message(td::BufferSlice data) override;
void send_external_message(td::BufferSlice data) override; void send_external_message(td::BufferSlice data) override;

View file

@ -168,6 +168,8 @@ class ValidatorManager : public ValidatorManagerInterface {
virtual void log_validator_session_stats(BlockIdExt block_id, validatorsession::ValidatorSessionStats stats) = 0; virtual void log_validator_session_stats(BlockIdExt block_id, validatorsession::ValidatorSessionStats stats) = 0;
virtual void validated_new_block(BlockIdExt block_id) = 0;
static bool is_persistent_state(UnixTime ts, UnixTime prev_ts) { static bool is_persistent_state(UnixTime ts, UnixTime prev_ts) {
return ts / (1 << 17) != prev_ts / (1 << 17); return ts / (1 << 17) != prev_ts / (1 << 17);
} }

View file

@ -375,6 +375,8 @@ class ValidatorManagerImpl : public ValidatorManager {
void log_validator_session_stats(BlockIdExt block_id, validatorsession::ValidatorSessionStats stats) override { void log_validator_session_stats(BlockIdExt block_id, validatorsession::ValidatorSessionStats stats) override {
UNREACHABLE(); UNREACHABLE();
} }
void validated_new_block(BlockIdExt block_id) override {
}
void get_validator_sessions_info( void get_validator_sessions_info(
td::Promise<tl_object_ptr<ton_api::engine_validator_validatorSessionsInfo>> promise) override { td::Promise<tl_object_ptr<ton_api::engine_validator_validatorSessionsInfo>> promise) override {
UNREACHABLE(); UNREACHABLE();

View file

@ -435,6 +435,8 @@ class ValidatorManagerImpl : public ValidatorManager {
void log_validator_session_stats(BlockIdExt block_id, validatorsession::ValidatorSessionStats stats) override { void log_validator_session_stats(BlockIdExt block_id, validatorsession::ValidatorSessionStats stats) override {
UNREACHABLE(); UNREACHABLE();
} }
void validated_new_block(BlockIdExt block_id) override {
}
void get_validator_sessions_info( void get_validator_sessions_info(
td::Promise<tl_object_ptr<ton_api::engine_validator_validatorSessionsInfo>> promise) override { td::Promise<tl_object_ptr<ton_api::engine_validator_validatorSessionsInfo>> promise) override {
UNREACHABLE(); UNREACHABLE();

View file

@ -418,7 +418,7 @@ void ValidatorManagerImpl::new_ihr_message(td::BufferSlice data) {
} }
void ValidatorManagerImpl::new_shard_block(BlockIdExt block_id, CatchainSeqno cc_seqno, td::BufferSlice data) { void ValidatorManagerImpl::new_shard_block(BlockIdExt block_id, CatchainSeqno cc_seqno, td::BufferSlice data) {
if (!is_collator()) { if (!is_collator() && !is_validator()) {
return; return;
} }
if (!last_masterchain_block_handle_) { if (!last_masterchain_block_handle_) {
@ -1794,6 +1794,7 @@ void ValidatorManagerImpl::update_shards() {
opts.proto_version = std::max<td::uint32>(opts.proto_version, 1); opts.proto_version = std::max<td::uint32>(opts.proto_version, 1);
} }
auto opts_hash = opts.get_hash(); auto opts_hash = opts.get_hash();
extra_active_shards_.clear();
std::map<ShardIdFull, std::vector<BlockIdExt>> new_shards; std::map<ShardIdFull, std::vector<BlockIdExt>> new_shards;
std::set<ShardIdFull> future_shards; std::set<ShardIdFull> future_shards;
@ -1848,6 +1849,11 @@ void ValidatorManagerImpl::update_shards() {
default: default:
LOG(FATAL) << "state=" << static_cast<td::uint32>(v->fsm_state()); LOG(FATAL) << "state=" << static_cast<td::uint32>(v->fsm_state());
} }
cleanup_last_validated_blocks(v->top_block_id().id);
}
for (const auto& s : last_validated_blocks_) {
extra_active_shards_.insert(s.first);
} }
new_shards.emplace(ShardIdFull{masterchainId, shardIdAll}, std::vector<BlockIdExt>{last_masterchain_block_id_}); new_shards.emplace(ShardIdFull{masterchainId, shardIdAll}, std::vector<BlockIdExt>{last_masterchain_block_id_});
@ -1920,6 +1926,7 @@ void ValidatorManagerImpl::update_shards() {
auto validator_id = get_validator(shard, val_set); auto validator_id = get_validator(shard, val_set);
if (!validator_id.is_zero()) { if (!validator_id.is_zero()) {
extra_active_shards_.insert(shard);
auto val_group_id = get_validator_set_id(shard, val_set, opts_hash, key_seqno, opts); auto val_group_id = get_validator_set_id(shard, val_set, opts_hash, key_seqno, opts);
if (force_recover) { if (force_recover) {
@ -2012,7 +2019,25 @@ void ValidatorManagerImpl::update_shards() {
}); });
td::actor::send_closure(db_, &Db::update_destroyed_validator_sessions, gc_list_, std::move(P)); td::actor::send_closure(db_, &Db::update_destroyed_validator_sessions, gc_list_, std::move(P));
} }
} // namespace validator }
void ValidatorManagerImpl::cleanup_last_validated_blocks(BlockId new_block) {
auto process_shard = [&, this](ShardIdFull shard) {
auto it = last_validated_blocks_.find(shard);
if (it != last_validated_blocks_.end() && it->second < new_block.seqno) {
last_validated_blocks_.erase(it);
}
};
ShardIdFull shard = new_block.shard_full();
process_shard(shard);
if (shard.pfx_len() > 0) {
process_shard(shard_parent(shard));
}
if (shard.pfx_len() < max_shard_pfx_len) {
process_shard(shard_child(shard, true));
process_shard(shard_child(shard, false));
}
}
void ValidatorManagerImpl::written_destroyed_validator_sessions(std::vector<td::actor::ActorId<ValidatorGroup>> list) { void ValidatorManagerImpl::written_destroyed_validator_sessions(std::vector<td::actor::ActorId<ValidatorGroup>> list) {
for (auto &v : list) { for (auto &v : list) {
@ -2428,6 +2453,7 @@ void ValidatorManagerImpl::get_shard_client_state(bool from_db, td::Promise<Bloc
void ValidatorManagerImpl::update_shard_configuration(td::Ref<MasterchainState> state, void ValidatorManagerImpl::update_shard_configuration(td::Ref<MasterchainState> state,
std::set<ShardIdFull> shards_to_monitor) { std::set<ShardIdFull> shards_to_monitor) {
shards_to_monitor_ = shards_to_monitor; shards_to_monitor_ = shards_to_monitor;
shards_to_monitor.insert(extra_active_shards_.begin(), extra_active_shards_.end());
callback_->update_shard_configuration(std::move(state), std::move(shards_to_monitor)); callback_->update_shard_configuration(std::move(state), std::move(shards_to_monitor));
} }

View file

@ -543,6 +543,11 @@ class ValidatorManagerImpl : public ValidatorManager {
void get_validator_sessions_info( void get_validator_sessions_info(
td::Promise<tl_object_ptr<ton_api::engine_validator_validatorSessionsInfo>> promise) override; td::Promise<tl_object_ptr<ton_api::engine_validator_validatorSessionsInfo>> promise) override;
void validated_new_block(BlockIdExt block_id) override {
BlockSeqno &last = last_validated_blocks_[block_id.shard_full()];
last = std::max(last, block_id.seqno());
}
void add_collator(adnl::AdnlNodeIdShort id, ShardIdFull shard) override; void add_collator(adnl::AdnlNodeIdShort id, ShardIdFull shard) override;
private: private:
@ -606,13 +611,17 @@ class ValidatorManagerImpl : public ValidatorManager {
double max_mempool_num() const { double max_mempool_num() const {
return opts_->max_mempool_num(); return opts_->max_mempool_num();
} }
void cleanup_last_validated_blocks(BlockId new_block);
private: private:
std::map<BlockSeqno, WaitList<td::actor::Actor, td::Unit>> shard_client_waiters_; std::map<BlockSeqno, WaitList<td::actor::Actor, td::Unit>> shard_client_waiters_;
std::map<adnl::AdnlNodeIdShort, td::actor::ActorOwn<CollatorNode>> collator_nodes_; std::map<adnl::AdnlNodeIdShort, td::actor::ActorOwn<CollatorNode>> collator_nodes_;
std::set<ShardIdFull> shards_to_monitor_ = {ShardIdFull(masterchainId)}; std::set<ShardIdFull> shards_to_monitor_ = {ShardIdFull(masterchainId)};
std::set<ShardIdFull> extra_active_shards_;
std::map<ShardIdFull, BlockSeqno> last_validated_blocks_;
}; };
} // namespace validator } // namespace validator

View file

@ -59,10 +59,14 @@ void ValidatorGroup::validate_block_candidate(td::uint32 round_id, BlockCandidat
approved_candidates_cache_round_ = round_id; approved_candidates_cache_round_ = round_id;
approved_candidates_cache_.clear(); approved_candidates_cache_.clear();
} }
auto next_block_id = create_next_block_id(block.id.root_hash, block.id.file_hash);
block.id = next_block_id;
CacheKey cache_key = block_to_cache_key(block); CacheKey cache_key = block_to_cache_key(block);
auto it = approved_candidates_cache_.find(cache_key); auto it = approved_candidates_cache_.find(cache_key);
if (it != approved_candidates_cache_.end()) { if (it != approved_candidates_cache_.end()) {
promise.set_result(it->second); promise.set_result(it->second);
return;
} }
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this), round_id, block = block.clone(), auto P = td::PromiseCreator::lambda([SelfId = actor_id(this), round_id, block = block.clone(),
@ -96,9 +100,7 @@ void ValidatorGroup::validate_block_candidate(td::uint32 round_id, BlockCandidat
P.set_error(td::Status::Error(ErrorCode::notready, "validator group not started")); P.set_error(td::Status::Error(ErrorCode::notready, "validator group not started"));
return; return;
} }
auto next_block_id = create_next_block_id(block.id.root_hash, block.id.file_hash);
VLOG(VALIDATOR_DEBUG) << "validating block candidate " << next_block_id; VLOG(VALIDATOR_DEBUG) << "validating block candidate " << next_block_id;
block.id = next_block_id;
run_validate_query(shard_, min_masterchain_block_id_, prev_block_ids_, std::move(block), validator_set_, manager_, run_validate_query(shard_, min_masterchain_block_id_, prev_block_ids_, std::move(block), validator_set_, manager_,
td::Timestamp::in(10.0), std::move(P), lite_mode_ ? ValidateMode::lite : 0); td::Timestamp::in(10.0), std::move(P), lite_mode_ ? ValidateMode::lite : 0);
} }
@ -140,7 +142,10 @@ void ValidatorGroup::accept_block_candidate(td::uint32 round_id, PublicKeyHash s
void ValidatorGroup::accept_block_query(BlockIdExt block_id, td::Ref<BlockData> block, std::vector<BlockIdExt> prev, 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, td::Ref<BlockSignatureSet> sig_set, td::Ref<BlockSignatureSet> approve_sig_set,
bool send_broadcast, td::Promise<td::Unit> promise) { bool send_broadcast, td::Promise<td::Unit> promise, bool is_retry) {
if (!is_retry) {
td::actor::send_closure(manager_, &ValidatorManager::validated_new_block, block_id);
}
auto P = td::PromiseCreator::lambda([=, SelfId = actor_id(this), auto P = td::PromiseCreator::lambda([=, SelfId = actor_id(this),
promise = std::move(promise)](td::Result<td::Unit> R) mutable { promise = std::move(promise)](td::Result<td::Unit> R) mutable {
if (R.is_error()) { if (R.is_error()) {
@ -150,7 +155,7 @@ void ValidatorGroup::accept_block_query(BlockIdExt block_id, td::Ref<BlockData>
} }
LOG_CHECK(R.error().code() == ErrorCode::timeout || R.error().code() == ErrorCode::notready) << R.move_as_error(); LOG_CHECK(R.error().code() == ErrorCode::timeout || R.error().code() == ErrorCode::notready) << R.move_as_error();
td::actor::send_closure(SelfId, &ValidatorGroup::accept_block_query, block_id, std::move(block), std::move(prev), 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)); std::move(sig_set), std::move(approve_sig_set), false, std::move(promise), true);
} else { } else {
promise.set_value(R.move_as_ok()); promise.set_value(R.move_as_ok());
} }

View file

@ -41,7 +41,7 @@ class ValidatorGroup : public td::actor::Actor {
void skip_round(td::uint32 round); void skip_round(td::uint32 round);
void accept_block_query(BlockIdExt block_id, td::Ref<BlockData> block, std::vector<BlockIdExt> prev, void accept_block_query(BlockIdExt block_id, td::Ref<BlockData> block, std::vector<BlockIdExt> prev,
td::Ref<BlockSignatureSet> sigs, td::Ref<BlockSignatureSet> approve_sigs, td::Ref<BlockSignatureSet> sigs, td::Ref<BlockSignatureSet> approve_sigs,
bool send_broadcast, td::Promise<td::Unit> promise); bool send_broadcast, td::Promise<td::Unit> promise, bool is_retry = false);
void get_approved_candidate(PublicKey source, RootHash root_hash, FileHash file_hash, void get_approved_candidate(PublicKey source, RootHash root_hash, FileHash file_hash,
FileHash collated_data_file_hash, td::Promise<BlockCandidate> promise); FileHash collated_data_file_hash, td::Promise<BlockCandidate> promise);
BlockId create_next_block_id_simple() const; BlockId create_next_block_id_simple() const;