diff --git a/validator-engine/validator-engine.cpp b/validator-engine/validator-engine.cpp index cd14ae1e..4ed6ae56 100644 --- a/validator-engine/validator-engine.cpp +++ b/validator-engine/validator-engine.cpp @@ -1419,7 +1419,7 @@ td::Status ValidatorEngine::load_global_config() { h.push_back(b); } validator_options_.write().set_hardforks(std::move(h)); - validator_options_.write().set_validator_lite_mode(validator_lite_mode_); + validator_options_.write().set_validator_mode(validator_mode_); return td::Status::OK(); } @@ -3866,9 +3866,20 @@ int main(int argc, char *argv[]) { p.add_option('M', "not-all-shards", "monitor only a necessary set of shards instead of all", [&]() { acts.push_back([&x]() { td::actor::send_closure(x, &ValidatorEngine::set_not_all_shards); }); }); - p.add_option('\0', "lite-validator", "lite-mode validator (don't collate blocks, use collator nodes instead)", [&]() { - acts.push_back([&x]() { td::actor::send_closure(x, &ValidatorEngine::set_validator_lite_mode); }); - }); + p.add_option('\0', "lite-validator-shards", + "lite-mode validator for shard blocks (don't collate blocks, use collator nodes instead)", [&]() { + acts.push_back([&x]() { + td::actor::send_closure(x, &ValidatorEngine::set_validator_mode, + ton::validator::ValidatorManagerOptions::validator_lite_shards); + }); + }); + p.add_option('\0', "lite-validator-all", + "lite-mode validator for all blocks (don't collate blocks, use collator nodes instead)", [&]() { + acts.push_back([&x]() { + td::actor::send_closure(x, &ValidatorEngine::set_validator_mode, + ton::validator::ValidatorManagerOptions::validator_lite_all); + }); + }); td::uint32 threads = 7; p.add_checked_option( 't', "threads", PSTRING() << "number of threads (default=" << threads << ")", [&](td::Slice fname) { diff --git a/validator-engine/validator-engine.hpp b/validator-engine/validator-engine.hpp index 49010bc4..7e0db661 100644 --- a/validator-engine/validator-engine.hpp +++ b/validator-engine/validator-engine.hpp @@ -217,7 +217,8 @@ class ValidatorEngine : public td::actor::Actor { ton::BlockSeqno truncate_seqno_{0}; std::string session_logs_file_; bool not_all_shards_ = false; - bool validator_lite_mode_ = false; + ton::validator::ValidatorManagerOptions::ValidatorMode validator_mode_ = + ton::validator::ValidatorManagerOptions::validator_normal; std::set unsafe_catchains_; std::map> unsafe_catchain_rotations_; @@ -272,8 +273,8 @@ class ValidatorEngine : public td::actor::Actor { void set_not_all_shards() { not_all_shards_ = true; } - void set_validator_lite_mode() { - validator_lite_mode_ = true; + void set_validator_mode(ton::validator::ValidatorManagerOptions::ValidatorMode mode) { + validator_mode_ = mode; } void start_up() override; diff --git a/validator/collator-node.cpp b/validator/collator-node.cpp index c6afa541..193613c7 100644 --- a/validator/collator-node.cpp +++ b/validator/collator-node.cpp @@ -160,19 +160,19 @@ void CollatorNode::receive_query_cont(adnl::AdnlNodeIdShort src, ShardIdFull sha td::Ref min_mc_state, std::vector prev_blocks, Ed25519_PublicKey creator, td::Promise promise) { auto P = td::PromiseCreator::lambda([promise = std::move(promise), src](td::Result R) mutable { - if (R.is_error()) { - LOG(WARNING) << "Query from " << src << ", error: " << R.error(); - promise.set_result(serialize_error(R.move_as_error())); - } else { - LOG(INFO) << "Query from " << src << ", success"; - auto block = R.move_as_ok(); - auto result = create_serialize_tl_object( - create_tl_object(PublicKey{pubkeys::Ed25519{block.pubkey.as_bits256()}}.tl(), - create_tl_block_id(block.id), std::move(block.data), - std::move(block.collated_data))); - promise.set_result(std::move(result)); - } - }); + if (R.is_error()) { + LOG(WARNING) << "Query from " << src << ", error: " << R.error(); + promise.set_result(serialize_error(R.move_as_error())); + } else { + LOG(INFO) << "Query from " << src << ", success"; + auto block = R.move_as_ok(); + auto result = create_serialize_tl_object( + create_tl_object(PublicKey{pubkeys::Ed25519{block.pubkey.as_bits256()}}.tl(), + create_tl_block_id(block.id), std::move(block.data), + std::move(block.collated_data))); + promise.set_result(std::move(result)); + } + }); run_collate_query(shard, min_mc_state->get_block_id(), std::move(prev_blocks), creator, min_mc_state->get_validator_set(shard), manager_, td::Timestamp::in(10.0), std::move(P)); diff --git a/validator/manager.cpp b/validator/manager.cpp index c19e96f4..07266fb1 100644 --- a/validator/manager.cpp +++ b/validator/manager.cpp @@ -18,11 +18,9 @@ */ #include "manager.hpp" #include "validator-group.hpp" -#include "adnl/utils.hpp" #include "downloaders/wait-block-state.hpp" #include "downloaders/wait-block-state-merge.hpp" #include "downloaders/wait-block-data.hpp" -#include "validator-group.hpp" #include "fabric.h" #include "manager.h" #include "validate-broadcast.hpp" @@ -199,7 +197,7 @@ void ValidatorManagerImpl::validate_block(ReceivedBlock block, td::Promise R) mutable { + [SelfId = actor_id(this), promise = std::move(promise), id = blkid](td::Result R) mutable { if (R.is_error()) { promise.set_error(R.move_as_error()); } else { @@ -1241,7 +1239,7 @@ void ValidatorManagerImpl::write_handle(BlockHandle handle, td::Promise promise) { bool received = handle->received(); bool inited_state = handle->received_state(); - bool inited_proof = handle->id().is_masterchain() ? handle->inited_proof() : handle->inited_proof(); + bool inited_proof = handle->inited_proof(); if (handle->need_flush()) { handle->flush(actor_id(this), handle, std::move(promise)); @@ -1712,13 +1710,14 @@ bool ValidatorManagerImpl::out_of_sync() { void ValidatorManagerImpl::prestart_sync() { auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result R) { R.ensure(); - td::actor::send_closure(SelfId, &ValidatorManagerImpl::download_next_archive); + // Don't download archives + td::actor::send_closure(SelfId, &ValidatorManagerImpl::finish_prestart_sync); }); td::actor::send_closure(db_, &Db::set_async_mode, false, std::move(P)); } void ValidatorManagerImpl::download_next_archive() { - if (true) { + if (!out_of_sync()) { finish_prestart_sync(); return; } @@ -1836,6 +1835,13 @@ void ValidatorManagerImpl::new_masterchain_block() { for (auto &c : collator_nodes_) { td::actor::send_closure(c.second.actor, &CollatorNode::new_masterchain_block_notification, last_masterchain_state_); } + if (opts_->validator_mode() == ValidatorManagerOptions::validator_lite_shards && validating_masterchain()) { + // Prepare neighboours' queues for collating masterchain + for (const auto &desc : last_masterchain_state_->get_shards()) { + wait_out_msg_queue_proof(desc->top_block_id(), ShardIdFull(masterchainId), 0, td::Timestamp::in(10.0), + [](td::Ref) {}); + } + } if (last_masterchain_seqno_ % 1024 == 0) { LOG(WARNING) << "applied masterchain block " << last_masterchain_block_id_; @@ -2174,7 +2180,7 @@ td::actor::ActorOwn ValidatorManagerImpl::create_validator_group "validatorgroup", shard, validator_id, session_id, validator_set, last_masterchain_state_->get_collator_config(true), opts, keyring_, adnl_, rldp_, overlays_, db_root_, actor_id(this), init_session, opts_->check_unsafe_resync_allowed(validator_set->get_catchain_seqno()), - opts_->validator_lite_mode()); + opts_->validator_mode()); return G; } } @@ -2348,7 +2354,7 @@ void ValidatorManagerImpl::allow_block_state_gc(BlockIdExt block_id, td::Promise return; } auto shards = gc_masterchain_state_->get_shards(); - for (auto shard : shards) { + for (const auto &shard : shards) { if (shard_intersects(shard->shard(), block_id.shard_full())) { promise.set_result(block_id.id.seqno < shard->top_block_id().id.seqno); return; @@ -2564,7 +2570,14 @@ bool ValidatorManagerImpl::is_validator() { } bool ValidatorManagerImpl::is_collator() { - return !collator_nodes_.empty() || (!opts_->validator_lite_mode() && is_validator()); + return !collator_nodes_.empty() || + (opts_->validator_mode() != ValidatorManagerOptions::validator_lite_all && is_validator()); +} + +bool ValidatorManagerImpl::validating_masterchain() { + return !get_validator(ShardIdFull(masterchainId), + last_masterchain_state_->get_validator_set(ShardIdFull(masterchainId))) + .is_zero(); } PublicKeyHash ValidatorManagerImpl::get_validator(ShardIdFull shard, td::Ref val_set) { diff --git a/validator/manager.hpp b/validator/manager.hpp index 835f7de0..3debccb3 100644 --- a/validator/manager.hpp +++ b/validator/manager.hpp @@ -506,6 +506,7 @@ class ValidatorManagerImpl : public ValidatorManager { bool is_validator(); bool is_collator(); + bool validating_masterchain(); PublicKeyHash get_validator(ShardIdFull shard, td::Ref val_set); ValidatorManagerImpl(td::Ref opts, std::string db_root, diff --git a/validator/validator-group.cpp b/validator/validator-group.cpp index b4f665c3..7cc92f80 100644 --- a/validator/validator-group.cpp +++ b/validator/validator-group.cpp @@ -50,7 +50,8 @@ void ValidatorGroup::generate_block_candidate(td::uint32 round_id, td::Promise R) { td::actor::send_closure(SelfId, &ValidatorGroup::generated_block_candidate, std::move(cache), std::move(R)); }; - if (lite_mode_) { + if (mode_ == ValidatorManagerOptions::validator_lite_all || + (mode_ == ValidatorManagerOptions::validator_lite_shards && !shard_.is_masterchain())) { send_collate_query(round_id, td::Timestamp::in(10.0), std::move(P)); return; } @@ -197,7 +198,8 @@ void ValidatorGroup::accept_block_query(BlockIdExt block_id, td::Ref }); 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, shard_.is_masterchain() || !lite_mode_, manager_, + std::move(approve_sig_set), send_broadcast, + shard_.is_masterchain() || mode_ == ValidatorManagerOptions::validator_normal, manager_, std::move(P)); } diff --git a/validator/validator-group.hpp b/validator/validator-group.hpp index c7964ae5..6a78827d 100644 --- a/validator/validator-group.hpp +++ b/validator/validator-group.hpp @@ -65,7 +65,8 @@ class ValidatorGroup : public td::actor::Actor { td::actor::ActorId keyring, td::actor::ActorId adnl, td::actor::ActorId rldp, td::actor::ActorId overlays, std::string db_root, td::actor::ActorId validator_manager, bool create_session, - bool allow_unsafe_self_blocks_resync, bool lite_mode = false) + bool allow_unsafe_self_blocks_resync, + ValidatorManagerOptions::ValidatorMode mode = ValidatorManagerOptions::validator_normal) : shard_(shard) , local_id_(std::move(local_id)) , session_id_(session_id) @@ -80,7 +81,7 @@ class ValidatorGroup : public td::actor::Actor { , manager_(validator_manager) , init_(create_session) , allow_unsafe_self_blocks_resync_(allow_unsafe_self_blocks_resync) - , lite_mode_(lite_mode) { + , mode_(mode) { } private: @@ -125,7 +126,7 @@ class ValidatorGroup : public td::actor::Actor { bool init_ = false; bool started_ = false; bool allow_unsafe_self_blocks_resync_; - bool lite_mode_ = false; + ValidatorManagerOptions::ValidatorMode mode_; td::uint32 last_known_round_id_ = 0; struct CachedCollatedBlock { diff --git a/validator/validator-options.hpp b/validator/validator-options.hpp index e96292ad..ea100a50 100644 --- a/validator/validator-options.hpp +++ b/validator/validator-options.hpp @@ -112,8 +112,8 @@ struct ValidatorManagerOptionsImpl : public ValidatorManagerOptions { std::string get_session_logs_file() const override { return session_logs_file_; } - bool validator_lite_mode() const override { - return validator_lite_mode_; + ValidatorMode validator_mode() const override { + return validator_mode_; } void set_zero_block_id(BlockIdExt block_id) override { @@ -168,8 +168,8 @@ struct ValidatorManagerOptionsImpl : public ValidatorManagerOptions { void set_session_logs_file(std::string f) override { session_logs_file_ = std::move(f); } - void set_validator_lite_mode(bool value) override { - validator_lite_mode_ = value; + void set_validator_mode(ValidatorMode value) override { + validator_mode_ = value; } ValidatorManagerOptionsImpl *make_copy() const override { @@ -211,7 +211,7 @@ struct ValidatorManagerOptionsImpl : public ValidatorManagerOptions { BlockSeqno truncate_{0}; BlockSeqno sync_upto_{0}; std::string session_logs_file_; - bool validator_lite_mode_ = false; + ValidatorMode validator_mode_ = validator_normal; }; } // namespace validator diff --git a/validator/validator.h b/validator/validator.h index 343de082..4ce3f4d0 100644 --- a/validator/validator.h +++ b/validator/validator.h @@ -54,6 +54,8 @@ struct PerfTimerStats { struct ValidatorManagerOptions : public td::CntObject { public: + enum ValidatorMode { validator_normal, validator_lite_shards, validator_lite_all }; + virtual BlockIdExt zero_block_id() const = 0; virtual BlockIdExt init_block_id() const = 0; virtual bool need_monitor(ShardIdFull shard, const td::Ref& state) const = 0; @@ -79,7 +81,7 @@ struct ValidatorManagerOptions : public td::CntObject { virtual BlockSeqno get_truncate_seqno() const = 0; virtual BlockSeqno sync_upto() const = 0; virtual std::string get_session_logs_file() const = 0; - virtual bool validator_lite_mode() const = 0; + virtual ValidatorMode validator_mode() const = 0; virtual void set_zero_block_id(BlockIdExt block_id) = 0; virtual void set_init_block_id(BlockIdExt block_id) = 0; @@ -98,7 +100,7 @@ struct ValidatorManagerOptions : public td::CntObject { virtual void truncate_db(BlockSeqno seqno) = 0; virtual void set_sync_upto(BlockSeqno seqno) = 0; virtual void set_session_logs_file(std::string f) = 0; - virtual void set_validator_lite_mode(bool value) = 0; + virtual void set_validator_mode(ValidatorMode value) = 0; static td::Ref create( BlockIdExt zero_block_id, BlockIdExt init_block_id,