From 1b106ef270a02d21ec39f9172cf7011bc7806bbe Mon Sep 17 00:00:00 2001 From: EmelyanenkoK Date: Tue, 13 Dec 2022 17:46:54 +0300 Subject: [PATCH] Use state with applied shards in liteserver (#553) Co-authored-by: SpyCheese --- validator/impl/liteserver.cpp | 14 +++++------ validator/interfaces/validator-manager.h | 3 ++- validator/manager-disk.cpp | 4 +++ validator/manager-disk.hpp | 4 ++- validator/manager-hardfork.hpp | 6 ++++- validator/manager.cpp | 31 +++++++++++++++++++++--- validator/manager.hpp | 7 +++++- validator/shard-client.cpp | 6 ++--- validator/validator.h | 2 ++ 9 files changed, 59 insertions(+), 18 deletions(-) diff --git a/validator/impl/liteserver.cpp b/validator/impl/liteserver.cpp index febdbf94..d9d2c333 100644 --- a/validator/impl/liteserver.cpp +++ b/validator/impl/liteserver.cpp @@ -232,7 +232,7 @@ void LiteQuery::perform_getMasterchainInfo(int mode) { return; } td::actor::send_closure_later( - manager_, &ton::validator::ValidatorManager::get_top_masterchain_state_block, + manager_, &ton::validator::ValidatorManager::get_last_liteserver_state_block, [Self = actor_id(this), return_state = bool(acc_state_promise_), mode](td::Result, BlockIdExt>> res) { if (res.is_error()) { td::actor::send_closure(Self, &LiteQuery::abort_query, res.move_as_error()); @@ -776,9 +776,9 @@ void LiteQuery::perform_getAccountState(BlockIdExt blkid, WorkchainId workchain, set_continuation([&]() -> void { continue_getAccountState(); }); request_mc_block_data_state(blkid); } else { - LOG(INFO) << "sending a get_top_masterchain_state_block query to manager"; + LOG(INFO) << "sending a get_last_liteserver_state_block query to manager"; td::actor::send_closure_later( - manager_, &ton::validator::ValidatorManager::get_top_masterchain_state_block, + manager_, &ton::validator::ValidatorManager::get_last_liteserver_state_block, [Self = actor_id(this)](td::Result, BlockIdExt>> res) -> void { if (res.is_error()) { td::actor::send_closure(Self, &LiteQuery::abort_query, res.move_as_error()); @@ -855,7 +855,7 @@ void LiteQuery::perform_getLibraries(std::vector library_list) { sort( library_list.begin(), library_list.end() ); library_list.erase( unique( library_list.begin(), library_list.end() ), library_list.end() ); td::actor::send_closure_later( - manager_, &ton::validator::ValidatorManager::get_top_masterchain_state_block, + manager_, &ton::validator::ValidatorManager::get_last_liteserver_state_block, [Self = actor_id(this), library_list](td::Result, BlockIdExt>> res) -> void { if (res.is_error()) { td::actor::send_closure(Self, &LiteQuery::abort_query, res.move_as_error()); @@ -1542,7 +1542,7 @@ void LiteQuery::perform_getShardInfo(BlockIdExt blkid, ShardIdFull shard, bool e } void LiteQuery::load_prevKeyBlock(ton::BlockIdExt blkid, td::Promise>> promise) { - td::actor::send_closure_later(manager_, &ton::validator::ValidatorManager::get_top_masterchain_state_block, + td::actor::send_closure_later(manager_, &ton::validator::ValidatorManager::get_last_liteserver_state_block, [Self = actor_id(this), blkid, promise = std::move(promise)]( td::Result, BlockIdExt>> res) mutable { td::actor::send_closure_later(Self, &LiteQuery::continue_loadPrevKeyBlock, blkid, @@ -1965,7 +1965,7 @@ void LiteQuery::perform_getBlockProof(ton::BlockIdExt from, ton::BlockIdExt to, }); } else { td::actor::send_closure_later( - manager_, &ton::validator::ValidatorManager::get_top_masterchain_state_block, + manager_, &ton::validator::ValidatorManager::get_last_liteserver_state_block, [Self = actor_id(this), from, to, mode](td::Result, BlockIdExt>> res) { if (res.is_error()) { td::actor::send_closure(Self, &LiteQuery::abort_query, res.move_as_error()); @@ -1978,7 +1978,7 @@ void LiteQuery::perform_getBlockProof(ton::BlockIdExt from, ton::BlockIdExt to, } } else if (mode & 2) { td::actor::send_closure_later( - manager_, &ton::validator::ValidatorManager::get_top_masterchain_state_block, + manager_, &ton::validator::ValidatorManager::get_last_liteserver_state_block, [Self = actor_id(this), from, mode](td::Result, BlockIdExt>> res) { if (res.is_error()) { td::actor::send_closure(Self, &LiteQuery::abort_query, res.move_as_error()); diff --git a/validator/interfaces/validator-manager.h b/validator/interfaces/validator-manager.h index 4ee276d3..ae15ed4c 100644 --- a/validator/interfaces/validator-manager.h +++ b/validator/interfaces/validator-manager.h @@ -161,7 +161,8 @@ class ValidatorManager : public ValidatorManagerInterface { virtual void update_last_known_key_block(BlockHandle handle, bool send_request) = 0; virtual void update_gc_block_handle(BlockHandle handle, td::Promise promise) = 0; - virtual void update_shard_client_block_handle(BlockHandle handle, td::Promise promise) = 0; + virtual void update_shard_client_block_handle(BlockHandle handle, td::Ref state, + td::Promise promise) = 0; virtual void truncate(BlockSeqno seqno, ConstBlockHandle handle, td::Promise promise) = 0; diff --git a/validator/manager-disk.cpp b/validator/manager-disk.cpp index 0e3dcae9..f14fa3af 100644 --- a/validator/manager-disk.cpp +++ b/validator/manager-disk.cpp @@ -875,6 +875,10 @@ void ValidatorManagerImpl::get_top_masterchain_state_block( std::pair, BlockIdExt>{last_masterchain_state_, last_masterchain_block_id_}); } +void get_last_liteserver_state_block(td::Promise, BlockIdExt>> promise) { + return get_top_masterchain_state_block(std::move(promise)); +} + void ValidatorManagerImpl::send_get_block_request(BlockIdExt id, td::uint32 priority, td::Promise promise) { UNREACHABLE(); diff --git a/validator/manager-disk.hpp b/validator/manager-disk.hpp index e73991f9..2745e02e 100644 --- a/validator/manager-disk.hpp +++ b/validator/manager-disk.hpp @@ -224,6 +224,7 @@ class ValidatorManagerImpl : public ValidatorManager { void get_top_masterchain_state(td::Promise> promise) override; void get_top_masterchain_block(td::Promise promise) override; void get_top_masterchain_state_block(td::Promise, BlockIdExt>> promise) override; + void get_last_liteserver_state_block(td::Promise, BlockIdExt>> promise) override; void send_get_block_request(BlockIdExt id, td::uint32 priority, td::Promise promise) override; void send_get_zero_state_request(BlockIdExt id, td::uint32 priority, td::Promise promise) override; @@ -351,7 +352,8 @@ class ValidatorManagerImpl : public ValidatorManager { } void update_last_known_key_block(BlockHandle handle, bool send_request) override { } - void update_shard_client_block_handle(BlockHandle handle, td::Promise promise) override { + void update_shard_client_block_handle(BlockHandle handle, td::Ref state, + td::Promise promise) override { } void prepare_stats(td::Promise>> promise) override { diff --git a/validator/manager-hardfork.hpp b/validator/manager-hardfork.hpp index 0ac871fc..6a145191 100644 --- a/validator/manager-hardfork.hpp +++ b/validator/manager-hardfork.hpp @@ -280,6 +280,9 @@ class ValidatorManagerImpl : public ValidatorManager { void get_top_masterchain_state_block(td::Promise, BlockIdExt>> promise) override { UNREACHABLE(); } + void get_last_liteserver_state_block(td::Promise, BlockIdExt>> promise) override { + UNREACHABLE(); + } void send_get_block_request(BlockIdExt id, td::uint32 priority, td::Promise promise) override { UNREACHABLE(); @@ -410,7 +413,8 @@ class ValidatorManagerImpl : public ValidatorManager { } void update_last_known_key_block(BlockHandle handle, bool send_request) override { } - void update_shard_client_block_handle(BlockHandle handle, td::Promise promise) override { + void update_shard_client_block_handle(BlockHandle handle, td::Ref state, + td::Promise promise) override { } void prepare_stats(td::Promise>> promise) override { diff --git a/validator/manager.cpp b/validator/manager.cpp index 19c16483..5199eb01 100644 --- a/validator/manager.cpp +++ b/validator/manager.cpp @@ -401,11 +401,12 @@ void ValidatorManagerImpl::add_external_message(td::Ref msg) { } } void ValidatorManagerImpl::check_external_message(td::BufferSlice data, td::Promise> promise) { - if (last_masterchain_state_.is_null()) { + auto state = do_get_last_liteserver_state(); + if (state.is_null()) { promise.set_error(td::Status::Error(ErrorCode::notready, "not ready")); return; } - run_check_external_message(std::move(data), last_masterchain_state_->get_ext_msg_limits(), actor_id(this), + run_check_external_message(std::move(data), state->get_ext_msg_limits(), actor_id(this), std::move(promise)); } @@ -1342,6 +1343,16 @@ void ValidatorManagerImpl::get_top_masterchain_state(td::Promise ValidatorManagerImpl::do_get_last_liteserver_state() { + if (last_masterchain_state_.is_null()) { + return {}; + } + if (last_liteserver_state_.is_null() || last_liteserver_state_->get_unix_time() < td::Clocks::system() - 30) { + last_liteserver_state_ = last_masterchain_state_; + } + return last_liteserver_state_; +} + void ValidatorManagerImpl::get_top_masterchain_block(td::Promise promise) { if (!last_masterchain_block_id_.is_valid()) { promise.set_error(td::Status::Error(ton::ErrorCode::notready, "not started")); @@ -1360,6 +1371,16 @@ void ValidatorManagerImpl::get_top_masterchain_state_block( } } +void ValidatorManagerImpl::get_last_liteserver_state_block( + td::Promise, BlockIdExt>> promise) { + auto state = do_get_last_liteserver_state(); + if (state.is_null()) { + promise.set_error(td::Status::Error(ton::ErrorCode::notready, "not started")); + } else { + promise.set_result(std::pair, BlockIdExt>{state, state->get_block_id()}); + } +} + void ValidatorManagerImpl::send_get_block_request(BlockIdExt id, td::uint32 priority, td::Promise promise) { callback_->download_block(id, priority, td::Timestamp::in(10.0), std::move(promise)); @@ -2274,9 +2295,13 @@ void ValidatorManagerImpl::advance_gc(BlockHandle handle, td::Ref promise) { +void ValidatorManagerImpl::update_shard_client_block_handle(BlockHandle handle, td::Ref state, + td::Promise promise) { shard_client_handle_ = std::move(handle); auto seqno = shard_client_handle_->id().seqno(); + if (last_liteserver_state_.is_null() || last_liteserver_state_->get_block_id().seqno() < seqno) { + last_liteserver_state_ = std::move(state); + } shard_client_update(seqno); promise.set_value(td::Unit()); } diff --git a/validator/manager.hpp b/validator/manager.hpp index d80cd43d..d133f83b 100644 --- a/validator/manager.hpp +++ b/validator/manager.hpp @@ -245,6 +245,9 @@ class ValidatorManagerImpl : public ValidatorManager { BlockHandle last_key_block_handle_; BlockHandle last_known_key_block_handle_; BlockHandle shard_client_handle_; + td::Ref last_liteserver_state_; + + td::Ref do_get_last_liteserver_state(); BlockHandle gc_masterchain_handle_; td::Ref gc_masterchain_state_; @@ -269,7 +272,8 @@ class ValidatorManagerImpl : public ValidatorManager { void advance_gc(BlockHandle handle, td::Ref state); void try_advance_gc_masterchain_block(); void update_gc_block_handle(BlockHandle handle, td::Promise promise) override; - void update_shard_client_block_handle(BlockHandle handle, td::Promise promise) override; + void update_shard_client_block_handle(BlockHandle handle, td::Ref state, + td::Promise promise) override; bool out_of_sync(); void applied_hardfork(); @@ -430,6 +434,7 @@ class ValidatorManagerImpl : public ValidatorManager { void get_top_masterchain_state(td::Promise> promise) override; void get_top_masterchain_block(td::Promise promise) override; void get_top_masterchain_state_block(td::Promise, BlockIdExt>> promise) override; + void get_last_liteserver_state_block(td::Promise, BlockIdExt>> promise) override; void send_get_block_request(BlockIdExt id, td::uint32 priority, td::Promise promise) override; void send_get_zero_state_request(BlockIdExt id, td::uint32 priority, td::Promise promise) override; diff --git a/validator/shard-client.cpp b/validator/shard-client.cpp index c7d87fb4..8fad3612 100644 --- a/validator/shard-client.cpp +++ b/validator/shard-client.cpp @@ -107,9 +107,6 @@ void ShardClient::start_up_init_mode() { void ShardClient::applied_all_shards() { LOG(DEBUG) << "shardclient: " << masterchain_block_handle_->id() << " finished"; - - masterchain_state_.clear(); - auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result R) { R.ensure(); td::actor::send_closure(SelfId, &ShardClient::saved_to_db); @@ -121,7 +118,8 @@ void ShardClient::applied_all_shards() { void ShardClient::saved_to_db() { CHECK(masterchain_block_handle_); td::actor::send_closure(manager_, &ValidatorManager::update_shard_client_block_handle, masterchain_block_handle_, - [](td::Unit) {}); + std::move(masterchain_state_), [](td::Unit) {}); + masterchain_state_.clear(); if (promise_) { promise_.set_value(td::Unit()); } diff --git a/validator/validator.h b/validator/validator.h index 87ea7688..0687b160 100644 --- a/validator/validator.h +++ b/validator/validator.h @@ -166,6 +166,8 @@ class ValidatorManagerInterface : public td::actor::Actor { virtual void get_top_masterchain_block(td::Promise promise) = 0; virtual void get_top_masterchain_state_block( td::Promise, BlockIdExt>> promise) = 0; + virtual void get_last_liteserver_state_block( + td::Promise, BlockIdExt>> promise) = 0; virtual void get_block_data(BlockHandle handle, td::Promise promise) = 0; virtual void check_zero_state_exists(BlockIdExt block_id, td::Promise promise) = 0;