1
0
Fork 0
mirror of https://github.com/ton-blockchain/ton synced 2025-02-15 04:32:21 +00:00

Shardchain validation without monitoring shardchains

This commit is contained in:
SpyCheese 2022-07-18 18:35:06 +03:00
parent bdfca7afef
commit 996c23e506
22 changed files with 210 additions and 88 deletions

View file

@ -236,9 +236,7 @@ class HardforkCreator : public td::actor::Actor {
td::actor::send_closure(id_, &ton::validator::ValidatorManager::sync_complete,
td::PromiseCreator::lambda([](td::Unit) {}));
}
void add_shard(ton::ShardIdFull) override {
}
void del_shard(ton::ShardIdFull) override {
void subscribe_to_shard(ton::ShardIdFull) override {
}
void send_ihr_message(ton::AccountIdPrefixFull dst, td::BufferSlice data) override {
}

View file

@ -98,6 +98,15 @@ void OverlayManager::create_public_overlay(adnl::AdnlNodeIdShort local_id, Overl
std::move(callback), std::move(rules), scope));
}
void OverlayManager::create_public_overlay_no_subscribe(adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id,
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), nullptr,
std::move(rules), scope));
}
void OverlayManager::create_private_overlay(adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id,
std::vector<adnl::AdnlNodeIdShort> nodes,
std::unique_ptr<Callback> callback, OverlayPrivacyRules rules) {

View file

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

View file

@ -149,6 +149,9 @@ void OverlayImpl::receive_query(adnl::AdnlNodeIdShort src, td::BufferSlice data,
if (R.is_error()) {
// allow custom query to be here
if (!subscribed()) {
return;
}
callback_->receive_query(src, overlay_id_, std::move(data), std::move(promise));
return;
}
@ -225,6 +228,9 @@ void OverlayImpl::receive_message(adnl::AdnlNodeIdShort src, td::BufferSlice dat
}
auto X = fetch_tl_object<ton_api::overlay_Broadcast>(data.clone(), true);
if (X.is_error()) {
if (!subscribed()) {
return;
}
VLOG(OVERLAY_DEBUG) << this << ": received custom message";
callback_->receive_message(src, overlay_id_, std::move(data));
return;
@ -268,7 +274,7 @@ void OverlayImpl::alarm() {
}
if (public_) {
if (peers_.size() > 0) {
if (peers_.size() > 0 && subscribed()) {
auto P = get_random_peer();
if (P) {
send_random_peers(P->get_id(), {});
@ -336,7 +342,7 @@ void OverlayImpl::receive_dht_nodes(td::Result<dht::DhtValue> res, bool dummy) {
}
void OverlayImpl::update_dht_nodes(OverlayNode node) {
if (!public_) {
if (!public_ || !subscribed()) {
return;
}
@ -497,6 +503,9 @@ void OverlayImpl::send_new_fec_broadcast_part(PublicKeyHash local_id, Overlay::B
}
void OverlayImpl::deliver_broadcast(PublicKeyHash source, td::BufferSlice data) {
if (!subscribed()) {
return;
}
callback_->receive_broadcast(source, overlay_id_, std::move(data));
}
@ -569,6 +578,9 @@ void OverlayImpl::set_privacy_rules(OverlayPrivacyRules rules) {
}
void OverlayImpl::check_broadcast(PublicKeyHash src, td::BufferSlice data, td::Promise<td::Unit> promise) {
if (!subscribed()) {
return;
}
callback_->check_broadcast(src, overlay_id_, std::move(data), std::move(promise));
}

View file

@ -251,8 +251,15 @@ class OverlayImpl : public Overlay {
}
private:
bool subscribed() const {
return (bool)callback_;
}
template <class T>
void process_query(adnl::AdnlNodeIdShort src, T &query, td::Promise<td::BufferSlice> promise) {
if (!subscribed()) {
return;
}
callback_->receive_query(src, overlay_id_, serialize_tl_object(&query, true), std::move(promise));
}

View file

@ -194,6 +194,8 @@ class Overlays : public td::actor::Actor {
virtual void create_public_overlay(adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id,
std::unique_ptr<Callback> callback, OverlayPrivacyRules rules, td::string scope) = 0;
virtual void create_public_overlay_no_subscribe(adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id,
OverlayPrivacyRules rules, td::string scope) = 0;
virtual void create_private_overlay(adnl::AdnlNodeIdShort local_id, OverlayIdFull overlay_id,
std::vector<adnl::AdnlNodeIdShort> nodes, std::unique_ptr<Callback> callback,
OverlayPrivacyRules rules) = 0;

View file

@ -323,9 +323,7 @@ class TestNode : public td::actor::Actor {
td::actor::send_closure(id_, &ton::validator::ValidatorManager::sync_complete,
td::PromiseCreator::lambda([](td::Unit) {}));
}
void add_shard(ton::ShardIdFull) override {
}
void del_shard(ton::ShardIdFull) override {
void subscribe_to_shard(ton::ShardIdFull) override {
}
void send_ihr_message(ton::AccountIdPrefixFull dst, td::BufferSlice data) override {
}

View file

@ -1300,10 +1300,10 @@ td::Status ValidatorEngine::load_global_config() {
validator_options_ = ton::validator::ValidatorManagerOptions::create(zero_state, init_block);
validator_options_.write().set_shard_check_function(
[](ton::ShardIdFull shard, ton::CatchainSeqno cc_seqno,
[masterchain_only = masterchain_only_](ton::ShardIdFull shard, ton::CatchainSeqno cc_seqno,
ton::validator::ValidatorManagerOptions::ShardCheckMode mode) -> bool {
if (mode == ton::validator::ValidatorManagerOptions::ShardCheckMode::m_monitor) {
return true;
return shard.is_masterchain() || !masterchain_only;
}
CHECK(mode == ton::validator::ValidatorManagerOptions::ShardCheckMode::m_validate);
return true;
@ -3648,6 +3648,9 @@ int main(int argc, char *argv[]) {
});
return td::Status::OK();
});
p.add_option('M', "masterchain-only", "don't track shardchains", [&]() {
acts.push_back([&x]() { td::actor::send_closure(x, &ValidatorEngine::set_masterchain_only); });
});
td::uint32 threads = 7;
p.add_checked_option(
't', "threads", PSTRING() << "number of threads (default=" << threads << ")", [&](td::Slice fname) {

View file

@ -202,6 +202,7 @@ class ValidatorEngine : public td::actor::Actor {
bool started_ = false;
ton::BlockSeqno truncate_seqno_{0};
std::string session_logs_file_;
bool masterchain_only_ = false;
std::set<ton::CatchainSeqno> unsafe_catchains_;
std::map<ton::BlockSeqno, std::pair<ton::CatchainSeqno, td::uint32>> unsafe_catchain_rotations_;
@ -253,6 +254,9 @@ class ValidatorEngine : public td::actor::Actor {
void add_key_to_set(ton::PublicKey key) {
keys_[key.compute_short_id()] = key;
}
void set_masterchain_only() {
masterchain_only_ = true;
}
void start_up() override;
ValidatorEngine() {
}

View file

@ -59,6 +59,10 @@ void run_fake_accept_block_query(BlockIdExt id, td::Ref<BlockData> data, std::ve
td::Promise<td::Unit> promise);
void run_hardfork_accept_block_query(BlockIdExt id, td::Ref<BlockData> data,
td::actor::ActorId<ValidatorManager> manager, td::Promise<td::Unit> promise);
void run_broadcast_only_accept_block_query(BlockIdExt id, td::Ref<BlockData> data, std::vector<BlockIdExt> prev,
td::Ref<ValidatorSet> validator_set, td::Ref<BlockSignatureSet> signatures,
td::Ref<BlockSignatureSet> approve_signatures,
td::actor::ActorId<ValidatorManager> manager, td::Promise<td::Unit> promise);
void run_apply_block_query(BlockIdExt id, td::Ref<BlockData> block, BlockIdExt masterchain_block_id,
td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout,
td::Promise<td::Unit> promise);

View file

@ -69,31 +69,41 @@ void Neighbour::update_roundtrip(double t) {
}
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));
}
Callback(td::actor::ActorId<FullNodeShardImpl> node) : node_(node) {
}
if (subscribed_) {
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_;
};
private:
td::actor::ActorId<FullNodeShardImpl> node_;
};
td::actor::send_closure(overlays_, &overlay::Overlays::create_public_overlay, adnl_id_, overlay_id_full_.clone(),
std::make_unique<Callback>(actor_id(this)), rules_, PSTRING() << "{ \"type\": \"shard\", \"shard_id\": " << get_shard() << ", \"workchain_id\": " << get_workchain() << " }");
td::actor::send_closure(overlays_, &overlay::Overlays::create_public_overlay, adnl_id_, overlay_id_full_.clone(),
std::make_unique<Callback>(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_no_subscribe, adnl_id_,
overlay_id_full_.clone(), rules_,
PSTRING() << "{ \"type\": \"shard\", \"shard_id\": " << get_shard()
<< ", \"workchain_id\": " << get_workchain() << " }");
}
td::actor::send_closure(rldp_, &rldp::Rldp::add_id, adnl_id_);
if (cert_) {
@ -119,6 +129,15 @@ void FullNodeShardImpl::update_adnl_id(adnl::AdnlNodeIdShort adnl_id, td::Promis
create_overlay();
}
void FullNodeShardImpl::subscribe_to_shard() {
if (subscribed_ || !client_.empty()) {
return;
}
td::actor::send_closure(overlays_, &ton::overlay::Overlays::delete_overlay, adnl_id_, overlay_id_);
subscribed_ = true;
create_overlay();
}
void FullNodeShardImpl::try_get_next_block(td::Timestamp timeout, td::Promise<ReceivedBlock> promise) {
if (timeout.is_in_past()) {
promise.set_error(td::Status::Error(ErrorCode::timeout, "timeout"));
@ -576,8 +595,14 @@ void FullNodeShardImpl::process_broadcast(PublicKeyHash src, ton_api::tonNode_ex
}
void FullNodeShardImpl::process_broadcast(PublicKeyHash src, ton_api::tonNode_newShardBlockBroadcast &query) {
auto block_id = create_block_id(query.block_->block_);
if (block_id.shard_full() != shard_) {
LOG(WARNING) << "dropping newShardBlockBroadcast: expected shard " << shard_.to_str() << ", got shard "
<< block_id.shard_full().to_str();
return;
}
td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::new_shard_block,
create_block_id(query.block_->block_), query.block_->cc_seqno_,
block_id, query.block_->cc_seqno_,
std::move(query.block_->data_));
}
@ -588,6 +613,11 @@ void FullNodeShardImpl::process_broadcast(PublicKeyHash src, ton_api::tonNode_bl
}
BlockIdExt block_id = create_block_id(query.id_);
if (block_id.shard_full() != shard_) {
LOG(WARNING) << "dropping blockBroadcast: expected shard " << shard_.to_str() << ", got shard "
<< block_id.shard_full().to_str();
return;
}
BlockBroadcast B{block_id,
std::move(signatures),
static_cast<UnixTime>(query.catchain_seqno_),
@ -817,6 +847,10 @@ void FullNodeShardImpl::start_up() {
}
}
void FullNodeShardImpl::tear_down() {
td::actor::send_closure(overlays_, &ton::overlay::Overlays::delete_overlay, adnl_id_, overlay_id_);
}
void FullNodeShardImpl::sign_new_certificate(PublicKeyHash sign_by) {
if (sign_by.is_zero()) {
return;
@ -1053,7 +1087,7 @@ FullNodeShardImpl::FullNodeShardImpl(ShardIdFull shard, PublicKeyHash local_id,
td::actor::ActorId<adnl::Adnl> adnl, td::actor::ActorId<rldp::Rldp> rldp,
td::actor::ActorId<overlay::Overlays> overlays,
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
td::actor::ActorId<adnl::AdnlExtClient> client)
td::actor::ActorId<adnl::AdnlExtClient> client, bool subscribe)
: shard_(shard)
, local_id_(local_id)
, adnl_id_(adnl_id)
@ -1063,16 +1097,18 @@ FullNodeShardImpl::FullNodeShardImpl(ShardIdFull shard, PublicKeyHash local_id,
, rldp_(rldp)
, overlays_(overlays)
, validator_manager_(validator_manager)
, client_(client) {
, client_(client)
, subscribed_(subscribe) {
}
td::actor::ActorOwn<FullNodeShard> FullNodeShard::create(
ShardIdFull shard, PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id, FileHash zero_state_file_hash,
td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<adnl::Adnl> adnl,
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<overlay::Overlays> overlays,
td::actor::ActorId<ValidatorManagerInterface> validator_manager, td::actor::ActorId<adnl::AdnlExtClient> client) {
td::actor::ActorId<ValidatorManagerInterface> validator_manager, td::actor::ActorId<adnl::AdnlExtClient> client,
bool subscribe) {
return td::actor::create_actor<FullNodeShardImpl>("tonnode", shard, local_id, adnl_id, zero_state_file_hash, keyring,
adnl, rldp, overlays, validator_manager, client);
adnl, rldp, overlays, validator_manager, client, subscribe);
}
} // namespace fullnode

View file

@ -36,6 +36,7 @@ class FullNodeShard : public td::actor::Actor {
virtual ShardIdFull get_shard_full() const = 0;
virtual void update_adnl_id(adnl::AdnlNodeIdShort adnl_id, td::Promise<td::Unit> promise) = 0;
virtual void subscribe_to_shard() = 0;
virtual void send_ihr_message(td::BufferSlice data) = 0;
virtual void send_external_message(td::BufferSlice data) = 0;
@ -70,7 +71,8 @@ class FullNodeShard : public td::actor::Actor {
ShardIdFull shard, PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id, FileHash zero_state_file_hash,
td::actor::ActorId<keyring::Keyring> keyring, td::actor::ActorId<adnl::Adnl> adnl,
td::actor::ActorId<rldp::Rldp> rldp, td::actor::ActorId<overlay::Overlays> overlays,
td::actor::ActorId<ValidatorManagerInterface> validator_manager, td::actor::ActorId<adnl::AdnlExtClient> client);
td::actor::ActorId<ValidatorManagerInterface> validator_manager, td::actor::ActorId<adnl::AdnlExtClient> client,
bool subscribe);
};
} // namespace fullnode

View file

@ -80,6 +80,7 @@ class FullNodeShardImpl : public FullNodeShard {
void create_overlay();
void update_adnl_id(adnl::AdnlNodeIdShort adnl_id, td::Promise<td::Unit> promise) override;
virtual void subscribe_to_shard() override;
//td::Result<Block> fetch_block(td::BufferSlice data);
void prevalidate_block(BlockIdExt block_id, td::BufferSlice data, td::BufferSlice proof,
@ -167,6 +168,7 @@ class FullNodeShardImpl : public FullNodeShard {
void set_handle(BlockHandle handle, td::Promise<td::Unit> promise) override;
void start_up() override;
void tear_down() override;
void alarm() override;
void update_validators(std::vector<PublicKeyHash> public_key_hashes, PublicKeyHash local_hash) override;
@ -202,7 +204,7 @@ class FullNodeShardImpl : public FullNodeShard {
td::actor::ActorId<adnl::Adnl> adnl, td::actor::ActorId<rldp::Rldp> rldp,
td::actor::ActorId<overlay::Overlays> overlays,
td::actor::ActorId<ValidatorManagerInterface> validator_manager,
td::actor::ActorId<adnl::AdnlExtClient> client);
td::actor::ActorId<adnl::AdnlExtClient> client, bool subscribe);
private:
bool use_new_download() const {
@ -239,6 +241,8 @@ class FullNodeShardImpl : public FullNodeShard {
td::Timestamp reload_neighbours_at_;
td::Timestamp ping_neighbours_at_;
adnl::AdnlNodeIdShort last_pinged_neighbour_ = adnl::AdnlNodeIdShort::zero();
bool subscribed_ = false;
};
} // namespace fullnode

View file

@ -120,14 +120,17 @@ void FullNodeImpl::initial_read_complete(BlockHandle top_handle) {
td::actor::send_closure(it->second, &FullNodeShard::set_handle, top_handle, std::move(P));
}
void FullNodeImpl::add_shard(ShardIdFull shard) {
void FullNodeImpl::add_shard(ShardIdFull shard, bool subscribe) {
while (true) {
if (shards_.count(shard) == 0) {
auto it = shards_.find(shard);
if (it == shards_.end()) {
shards_.emplace(shard, FullNodeShard::create(shard, local_id_, adnl_id_, zero_state_file_hash_, keyring_, adnl_,
rldp_, overlays_, validator_manager_, client_));
rldp_, overlays_, validator_manager_, client_, subscribe));
if (all_validators_.size() > 0) {
td::actor::send_closure(shards_[shard], &FullNodeShard::update_validators, all_validators_, sign_cert_by_);
}
} else if (subscribe) {
td::actor::send_closure(it->second, &FullNodeShard::subscribe_to_shard);
} else {
break;
}
@ -148,7 +151,7 @@ void FullNodeImpl::sync_completed() {
}
void FullNodeImpl::send_ihr_message(AccountIdPrefixFull dst, td::BufferSlice data) {
auto shard = get_shard(ShardIdFull{masterchainId});
auto shard = get_shard(dst);
if (shard.empty()) {
VLOG(FULL_NODE_WARNING) << "dropping OUT ihr message to unknown shard";
return;
@ -166,7 +169,7 @@ void FullNodeImpl::send_ext_message(AccountIdPrefixFull dst, td::BufferSlice dat
}
void FullNodeImpl::send_shard_block_info(BlockIdExt block_id, CatchainSeqno cc_seqno, td::BufferSlice data) {
auto shard = get_shard(ShardIdFull{masterchainId, shardIdAll});
auto shard = get_shard(block_id.shard_full());
if (shard.empty()) {
VLOG(FULL_NODE_WARNING) << "dropping OUT shard block info message to unknown shard";
return;
@ -175,7 +178,7 @@ void FullNodeImpl::send_shard_block_info(BlockIdExt block_id, CatchainSeqno cc_s
}
void FullNodeImpl::send_broadcast(BlockBroadcast broadcast) {
auto shard = get_shard(ShardIdFull{masterchainId});
auto shard = get_shard(broadcast.block_id.shard_full());
if (shard.empty()) {
VLOG(FULL_NODE_WARNING) << "dropping OUT broadcast to unknown shard";
return;
@ -381,11 +384,8 @@ void FullNodeImpl::start_up() {
void initial_read_complete(BlockHandle handle) override {
td::actor::send_closure(id_, &FullNodeImpl::initial_read_complete, handle);
}
void add_shard(ShardIdFull shard) override {
td::actor::send_closure(id_, &FullNodeImpl::add_shard, shard);
}
void del_shard(ShardIdFull shard) override {
td::actor::send_closure(id_, &FullNodeImpl::del_shard, shard);
void subscribe_to_shard(ShardIdFull shard) override {
td::actor::send_closure(id_, &FullNodeImpl::add_shard, shard, true);
}
void send_ihr_message(AccountIdPrefixFull dst, td::BufferSlice data) override {
td::actor::send_closure(id_, &FullNodeImpl::send_ihr_message, dst, std::move(data));
@ -465,7 +465,7 @@ FullNodeImpl::FullNodeImpl(PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id
, validator_manager_(validator_manager)
, client_(client)
, db_root_(db_root) {
add_shard(ShardIdFull{masterchainId});
add_shard(ShardIdFull{masterchainId}, true);
}
td::actor::ActorOwn<FullNode> FullNode::create(ton::PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id,

View file

@ -52,7 +52,7 @@ class FullNodeImpl : public FullNode {
void update_adnl_id(adnl::AdnlNodeIdShort adnl_id, td::Promise<td::Unit> promise) override;
void add_shard(ShardIdFull shard);
void add_shard(ShardIdFull shard, bool subscribe = false);
void del_shard(ShardIdFull shard);
void sync_completed();

View file

@ -92,6 +92,28 @@ AcceptBlockQuery::AcceptBlockQuery(ForceFork ffork, BlockIdExt id, td::Ref<Block
state_hash_.clear();
}
AcceptBlockQuery::AcceptBlockQuery(BroadcastOnly, BlockIdExt id, td::Ref<BlockData> data, std::vector<BlockIdExt> prev,
td::Ref<ValidatorSet> validator_set, td::Ref<BlockSignatureSet> signatures,
td::Ref<BlockSignatureSet> approve_signatures,
td::actor::ActorId<ValidatorManager> manager, td::Promise<td::Unit> promise)
: id_(id)
, data_(std::move(data))
, prev_(std::move(prev))
, validator_set_(std::move(validator_set))
, signatures_(std::move(signatures))
, approve_signatures_(std::move(approve_signatures))
, is_fake_(false)
, is_fork_(false)
, send_broadcast_(true)
, broadcast_only_(false)
, manager_(manager)
, promise_(std::move(promise)) {
state_keep_old_hash_.clear();
state_old_hash_.clear();
state_hash_.clear();
CHECK(prev_.size() > 0);
}
bool AcceptBlockQuery::precheck_header() {
VLOG(VALIDATOR_DEBUG) << "precheck_header()";
// 0. sanity check
@ -384,6 +406,15 @@ void AcceptBlockQuery::start_up() {
return;
}
if (broadcast_only_) {
if (!create_new_proof()) {
fatal_error("cannot generate proof for block "s + id_.to_str());
return;
}
applied();
return;
}
td::actor::send_closure(
manager_, &ValidatorManager::get_block_handle, id_, true, [SelfId = actor_id(this)](td::Result<BlockHandle> R) {
check_send_error(SelfId, R) ||

View file

@ -48,6 +48,7 @@ class AcceptBlockQuery : public td::actor::Actor {
public:
struct IsFake {};
struct ForceFork {};
struct BroadcastOnly{};
AcceptBlockQuery(BlockIdExt id, td::Ref<BlockData> data, std::vector<BlockIdExt> prev,
td::Ref<ValidatorSet> validator_set, td::Ref<BlockSignatureSet> signatures,
td::Ref<BlockSignatureSet> approve_signatures, bool send_broadcast,
@ -57,6 +58,10 @@ class AcceptBlockQuery : public td::actor::Actor {
td::Promise<td::Unit> promise);
AcceptBlockQuery(ForceFork ffork, BlockIdExt id, td::Ref<BlockData> data,
td::actor::ActorId<ValidatorManager> manager, td::Promise<td::Unit> promise);
AcceptBlockQuery(BroadcastOnly, BlockIdExt id, td::Ref<BlockData> data, std::vector<BlockIdExt> prev,
td::Ref<ValidatorSet> validator_set, td::Ref<BlockSignatureSet> signatures,
td::Ref<BlockSignatureSet> approve_signatures, td::actor::ActorId<ValidatorManager> manager,
td::Promise<td::Unit> promise);
private:
static constexpr td::uint32 priority() {
@ -98,6 +103,7 @@ class AcceptBlockQuery : public td::actor::Actor {
bool is_fake_;
bool is_fork_;
bool send_broadcast_;
bool broadcast_only_{false};
bool ancestors_split_{false}, is_key_block_{false};
td::Timestamp timeout_ = td::Timestamp::in(600.0);
td::actor::ActorId<ValidatorManager> manager_;

View file

@ -151,6 +151,17 @@ void run_hardfork_accept_block_query(BlockIdExt id, td::Ref<BlockData> data,
.release();
}
void run_broadcast_only_accept_block_query(BlockIdExt id, td::Ref<BlockData> data, std::vector<BlockIdExt> prev,
td::Ref<ValidatorSet> validator_set, td::Ref<BlockSignatureSet> signatures,
td::Ref<BlockSignatureSet> approve_signatures,
td::actor::ActorId<ValidatorManager> manager,
td::Promise<td::Unit> promise) {
td::actor::create_actor<AcceptBlockQuery>("broadcastaccept", AcceptBlockQuery::BroadcastOnly(), id, std::move(data),
prev, std::move(validator_set), std::move(signatures),
std::move(approve_signatures), manager, std::move(promise))
.release();
}
void run_apply_block_query(BlockIdExt id, td::Ref<BlockData> block, BlockIdExt masterchain_block_id,
td::actor::ActorId<ValidatorManager> manager, td::Timestamp timeout,
td::Promise<td::Unit> promise) {

View file

@ -2367,7 +2367,7 @@ void ValidatorManagerImpl::get_shard_client_state(bool from_db, td::Promise<Bloc
}
void ValidatorManagerImpl::subscribe_to_shard(ShardIdFull shard) {
callback_->add_shard(shard);
callback_->subscribe_to_shard(shard);
}
void ValidatorManagerImpl::update_async_serializer_state(AsyncSerializerState state, td::Promise<td::Unit> promise) {
@ -2396,7 +2396,7 @@ void ValidatorManagerImpl::get_archive_slice(td::uint64 archive_id, td::uint64 o
}
bool ValidatorManagerImpl::is_validator() {
return temp_keys_.size() > 0 || permanent_keys_.size() > 0;
return true; // temp_keys_.size() > 0 || permanent_keys_.size() > 0;
}
PublicKeyHash ValidatorManagerImpl::get_validator(ShardIdFull shard, td::Ref<ValidatorSet> val_set) {

View file

@ -121,9 +121,15 @@ void ValidatorGroup::accept_block_candidate(td::uint32 round_id, PublicKeyHash s
td::actor::send_closure(manager_, &ValidatorManager::log_validator_session_stats, next_block_id, std::move(stats));
auto block =
block_data.size() > 0 ? create_block(next_block_id, std::move(block_data)).move_as_ok() : td::Ref<BlockData>{};
accept_block_query(next_block_id, std::move(block), std::move(prev_block_ids_), std::move(sig_set),
std::move(approve_sig_set), src == local_id_, std::move(promise));
prev_block_ids_ = std::vector<BlockIdExt>{next_block_id};
}
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this), block_id = next_block_id, block, prev = prev_block_ids_,
sig_set, approve_sig_set,
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,
bool send_broadcast, td::Promise<td::Unit> promise) {
auto P = td::PromiseCreator::lambda([=, SelfId = actor_id(this),
promise = std::move(promise)](td::Result<td::Unit> R) mutable {
if (R.is_error()) {
if (R.error().code() == ErrorCode::cancelled) {
@ -131,35 +137,22 @@ void ValidatorGroup::accept_block_candidate(td::uint32 round_id, PublicKeyHash s
return;
}
LOG_CHECK(R.error().code() == ErrorCode::timeout || R.error().code() == ErrorCode::notready) << R.move_as_error();
td::actor::send_closure(SelfId, &ValidatorGroup::retry_accept_block_query, block_id, std::move(block),
std::move(prev), std::move(sig_set), std::move(approve_sig_set), std::move(promise));
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));
} else {
promise.set_value(R.move_as_ok());
}
});
run_accept_block_query(next_block_id, std::move(block), prev_block_ids_, validator_set_, std::move(sig_set),
std::move(approve_sig_set), src == local_id_, manager_, std::move(P));
prev_block_ids_ = std::vector<BlockIdExt>{next_block_id};
}
void ValidatorGroup::retry_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::Promise<td::Unit> promise) {
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this), block_id, block, prev, sig_set, approve_sig_set,
promise = std::move(promise)](td::Result<td::Unit> R) mutable {
if (R.is_error()) {
LOG_CHECK(R.error().code() == ErrorCode::timeout) << R.move_as_error();
td::actor::send_closure(SelfId, &ValidatorGroup::retry_accept_block_query, block_id, std::move(block),
std::move(prev), std::move(sig_set), std::move(approve_sig_set), std::move(promise));
} else {
promise.set_value(R.move_as_ok());
}
});
run_accept_block_query(block_id, std::move(block), prev, validator_set_, std::move(sig_set),
std::move(approve_sig_set), false, manager_, std::move(P));
if (shard_.is_masterchain() || lite_mode_) {
run_accept_block_query(block_id, std::move(block), std::move(prev), validator_set_, std::move(sig_set),
std::move(approve_sig_set), send_broadcast, manager_, std::move(P));
} else if (send_broadcast) {
run_broadcast_only_accept_block_query(block_id, std::move(block), std::move(prev), validator_set_,
std::move(sig_set), std::move(approve_sig_set), manager_, std::move(P));
} else {
promise.set_value(td::Unit());
}
}
void ValidatorGroup::skip_round(td::uint32 round_id) {
@ -311,8 +304,8 @@ void ValidatorGroup::start(std::vector<BlockIdExt> prev, BlockIdExt min_masterch
auto block =
p.block.size() > 0 ? create_block(next_block_id, std::move(p.block)).move_as_ok() : td::Ref<BlockData>{};
retry_accept_block_query(next_block_id, std::move(block), prev_block_ids_, std::move(p.sigs),
std::move(p.approve_sigs), std::move(p.promise));
accept_block_query(next_block_id, std::move(block), std::move(prev_block_ids_), std::move(p.sigs),
std::move(p.approve_sigs), false, std::move(p.promise));
prev_block_ids_ = std::vector<BlockIdExt>{next_block_id};
}
postponed_accept_.clear();

View file

@ -39,9 +39,9 @@ class ValidatorGroup : public td::actor::Actor {
std::vector<BlockSignature> approve_signatures,
validatorsession::ValidatorSessionStats stats, td::Promise<td::Unit> promise);
void skip_round(td::uint32 round);
void retry_accept_block_query(BlockIdExt block_id, td::Ref<BlockData> block, std::vector<BlockIdExt> prev,
td::Ref<BlockSignatureSet> sigs, td::Ref<BlockSignatureSet> approve_sigs,
td::Promise<td::Unit> promise);
void accept_block_query(BlockIdExt block_id, td::Ref<BlockData> block, std::vector<BlockIdExt> prev,
td::Ref<BlockSignatureSet> sigs, td::Ref<BlockSignatureSet> approve_sigs,
bool send_broadcast, td::Promise<td::Unit> promise);
void get_approved_candidate(PublicKey source, RootHash root_hash, FileHash file_hash,
FileHash collated_data_file_hash, td::Promise<BlockCandidate> promise);
BlockId create_next_block_id_simple() const;

View file

@ -111,8 +111,8 @@ class ValidatorManagerInterface : public td::actor::Actor {
virtual ~Callback() = default;
virtual void initial_read_complete(BlockHandle top_masterchain_blocks) = 0;
virtual void add_shard(ShardIdFull shard) = 0;
virtual void del_shard(ShardIdFull shard) = 0;
virtual void subscribe_to_shard(ShardIdFull shard) = 0;
//virtual void del_shard(ShardIdFull shard) = 0;
virtual void send_ihr_message(AccountIdPrefixFull dst, td::BufferSlice data) = 0;
virtual void send_ext_message(AccountIdPrefixFull dst, td::BufferSlice data) = 0;