diff --git a/crypto/vm/db/CellHashTable.h b/crypto/vm/db/CellHashTable.h index 7d0308b7..a251c4db 100644 --- a/crypto/vm/db/CellHashTable.h +++ b/crypto/vm/db/CellHashTable.h @@ -43,7 +43,7 @@ class CellHashTable { template void for_each(F &&f) { for (auto &info : set_) { - f(info); + f(const_cast(info)); } } template diff --git a/crypto/vm/db/CellStorage.cpp b/crypto/vm/db/CellStorage.cpp index a1b7365b..470c46a0 100644 --- a/crypto/vm/db/CellStorage.cpp +++ b/crypto/vm/db/CellStorage.cpp @@ -150,6 +150,20 @@ td::Result CellLoader::load(td::Slice hash, bool need_da return res; } +td::Result CellLoader::load_refcnt(td::Slice hash) { + LoadResult res; + std::string serialized; + TRY_RESULT(get_status, reader_->get(hash, serialized)); + if (get_status != KeyValue::GetStatus::Ok) { + DCHECK(get_status == KeyValue::GetStatus::NotFound); + return res; + } + res.status = LoadResult::Ok; + td::TlParser parser(serialized); + td::parse(res.refcnt_, parser); + return res; +} + CellStorer::CellStorer(KeyValue &kv) : kv_(kv) { } diff --git a/crypto/vm/db/CellStorage.h b/crypto/vm/db/CellStorage.h index b705b531..ba93ce20 100644 --- a/crypto/vm/db/CellStorage.h +++ b/crypto/vm/db/CellStorage.h @@ -48,6 +48,7 @@ class CellLoader { }; CellLoader(std::shared_ptr reader); td::Result load(td::Slice hash, bool need_data, ExtCellCreator &ext_cell_creator); + td::Result load_refcnt(td::Slice hash); // This only loads refcnt_, cell_ == null private: std::shared_ptr reader_; diff --git a/crypto/vm/db/DynamicBagOfCellsDb.cpp b/crypto/vm/db/DynamicBagOfCellsDb.cpp index 5441feea..f9fe69cb 100644 --- a/crypto/vm/db/DynamicBagOfCellsDb.cpp +++ b/crypto/vm/db/DynamicBagOfCellsDb.cpp @@ -27,6 +27,9 @@ #include "td/utils/ThreadSafeCounter.h" #include "vm/cellslice.h" +#include +#include "td/actor/actor.h" +#include "common/delay.h" namespace vm { namespace { @@ -138,8 +141,6 @@ class DynamicBagOfCellsDbImpl : public DynamicBagOfCellsDb, private ExtCellCreat if (cell->get_virtualization() != 0) { return; } - //LOG(ERROR) << "INC"; - //CellSlice(cell, nullptr).print_rec(std::cout); to_inc_.push_back(cell); } void dec(const Ref &cell) override { @@ -149,8 +150,6 @@ class DynamicBagOfCellsDbImpl : public DynamicBagOfCellsDb, private ExtCellCreat if (cell->get_virtualization() != 0) { return; } - //LOG(ERROR) << "DEC"; - //CellSlice(cell, nullptr).print_rec(std::cout); to_dec_.push_back(cell); } @@ -167,25 +166,20 @@ class DynamicBagOfCellsDbImpl : public DynamicBagOfCellsDb, private ExtCellCreat if (is_prepared_for_commit()) { return td::Status::OK(); } - //LOG(ERROR) << "dfs_new_cells_in_db"; for (auto &new_cell : to_inc_) { auto &new_cell_info = get_cell_info(new_cell); dfs_new_cells_in_db(new_cell_info); } - //return td::Status::OK(); - //LOG(ERROR) << "dfs_new_cells"; for (auto &new_cell : to_inc_) { auto &new_cell_info = get_cell_info(new_cell); dfs_new_cells(new_cell_info); } - //LOG(ERROR) << "dfs_old_cells"; for (auto &old_cell : to_dec_) { auto &old_cell_info = get_cell_info(old_cell); dfs_old_cells(old_cell_info); } - //LOG(ERROR) << "save_diff_prepare"; save_diff_prepare(); to_inc_.clear(); @@ -363,7 +357,6 @@ class DynamicBagOfCellsDbImpl : public DynamicBagOfCellsDb, private ExtCellCreat info.was = true; visited_.push_back(&info); } - //LOG(ERROR) << "dfs new " << td::format::escaped(info.cell->hash()); if (info.was_dfs_new_cells) { return; @@ -384,7 +377,6 @@ class DynamicBagOfCellsDbImpl : public DynamicBagOfCellsDb, private ExtCellCreat info.was = true; visited_.push_back(&info); } - //LOG(ERROR) << "dfs old " << td::format::escaped(info.cell->hash()); load_cell(info); @@ -405,7 +397,6 @@ class DynamicBagOfCellsDbImpl : public DynamicBagOfCellsDb, private ExtCellCreat } void save_diff(CellStorer &storer) { - //LOG(ERROR) << hash_table_.size(); for (auto info_ptr : visited_) { save_cell(*info_ptr, storer); } @@ -414,7 +405,6 @@ class DynamicBagOfCellsDbImpl : public DynamicBagOfCellsDb, private ExtCellCreat void save_cell_prepare(CellInfo &info) { if (info.refcnt_diff == 0) { - //CellSlice(info.cell, nullptr).print_rec(std::cout); return; } load_cell(info); @@ -450,15 +440,11 @@ class DynamicBagOfCellsDbImpl : public DynamicBagOfCellsDb, private ExtCellCreat if (info.db_refcnt == 0) { CHECK(info.in_db); - //LOG(ERROR) << "ERASE"; - //CellSlice(NoVm(), info.cell).print_rec(std::cout); storer.erase(info.cell->get_hash().as_slice()); info.in_db = false; hash_table_.erase(info.cell->get_hash().as_slice()); guard.dismiss(); } else { - //LOG(ERROR) << "SAVE " << info.db_refcnt; - //CellSlice(NoVm(), info.cell).print_rec(std::cout); auto loaded_cell = info.cell->load_cell().move_as_ok(); storer.set(info.db_refcnt, *loaded_cell.data_cell); info.in_db = true; @@ -482,7 +468,6 @@ class DynamicBagOfCellsDbImpl : public DynamicBagOfCellsDb, private ExtCellCreat CHECK(cell->is_loaded()); vm::CellSlice cs(vm::NoVm{}, cell); // FIXME for (unsigned i = 0; i < cs.size_refs(); i++) { - //LOG(ERROR) << "---> " << td::format::escaped(cell->ref(i)->hash()); f(get_cell_info(cs.prefetch_ref(i))); } } @@ -573,6 +558,177 @@ class DynamicBagOfCellsDbImpl : public DynamicBagOfCellsDb, private ExtCellCreat DynamicBocExtCellExtra{cell_db_reader_})); return std::move(res); } + + struct PrepareCommitAsyncState { + size_t remaining_ = 0; + std::shared_ptr executor_; + td::Promise promise_; + + struct CellInfo2 { + CellInfo *info; + std::vector parents; + unsigned remaining_children = 0; + Cell::Hash key() const { + return info->key(); + } + bool operator<(const CellInfo2 &other) const { + return key() < other.key(); + } + + friend bool operator<(const CellInfo2 &a, td::Slice b) { + return a.key().as_slice() < b; + } + + friend bool operator<(td::Slice a, const CellInfo2 &b) { + return a < b.key().as_slice(); + } + }; + + CellHashTable cells_; + }; + std::unique_ptr pca_state_; + + void prepare_commit_async(std::shared_ptr executor, td::Promise promise) override { + if (pca_state_) { + promise.set_error(td::Status::Error("Other prepare_commit_async is not finished")); + return; + } + if (is_prepared_for_commit()) { + promise.set_result(td::Unit()); + return; + } + pca_state_ = std::make_unique(); + pca_state_->executor_ = std::move(executor); + pca_state_->promise_ = std::move(promise); + for (auto &new_cell : to_inc_) { + dfs_new_cells_in_db_async(new_cell); + } + pca_state_->cells_.for_each([&](PrepareCommitAsyncState::CellInfo2 &info) { + ++pca_state_->remaining_; + if (info.remaining_children == 0) { + pca_load_from_db(&info); + } + }); + if (pca_state_->remaining_ == 0) { + prepare_commit_async_cont(); + } + } + + void dfs_new_cells_in_db_async(const td::Ref &cell, PrepareCommitAsyncState::CellInfo2 *parent = nullptr) { + bool exists = true; + pca_state_->cells_.apply(cell->get_hash().as_slice(), [&](PrepareCommitAsyncState::CellInfo2 &info) { + if (info.info == nullptr) { + exists = false; + info.info = &get_cell_info(cell); + } + }); + auto info = pca_state_->cells_.get_if_exists(cell->get_hash().as_slice()); + if (parent) { + info->parents.push_back(parent); + ++parent->remaining_children; + } + if (exists) { + return; + } + if (cell->is_loaded()) { + vm::CellSlice cs(vm::NoVm{}, cell); + for (unsigned i = 0; i < cs.size_refs(); i++) { + dfs_new_cells_in_db_async(cs.prefetch_ref(i), info); + } + } + } + + void pca_load_from_db(PrepareCommitAsyncState::CellInfo2 *info) { + pca_state_->executor_->execute_async( + [db = this, info, executor = pca_state_->executor_, loader = *loader_]() mutable { + auto res = loader.load_refcnt(info->info->cell->get_hash().as_slice()).move_as_ok(); + executor->execute_sync([db, info, res = std::move(res)]() { + db->pca_set_in_db(info, std::move(res)); + }); + }); + } + + void pca_set_in_db(PrepareCommitAsyncState::CellInfo2 *info, CellLoader::LoadResult result) { + info->info->sync_with_db = true; + if (result.status == CellLoader::LoadResult::Ok) { + info->info->in_db = true; + info->info->db_refcnt = result.refcnt(); + } else { + info->info->in_db = false; + } + for (PrepareCommitAsyncState::CellInfo2 *parent_info : info->parents) { + if (parent_info->info->sync_with_db) { + continue; + } + if (!info->info->in_db) { + pca_set_in_db(parent_info, {}); + } else if (--parent_info->remaining_children == 0) { + pca_load_from_db(parent_info); + } + } + if (--pca_state_->remaining_ == 0) { + prepare_commit_async_cont(); + } + } + + void prepare_commit_async_cont() { + for (auto &new_cell : to_inc_) { + auto &new_cell_info = get_cell_info(new_cell); + dfs_new_cells(new_cell_info); + } + + CHECK(pca_state_->remaining_ == 0); + for (auto &old_cell : to_dec_) { + auto &old_cell_info = get_cell_info(old_cell); + dfs_old_cells_async(old_cell_info); + } + if (pca_state_->remaining_ == 0) { + prepare_commit_async_cont2(); + } + } + + void dfs_old_cells_async(CellInfo &info) { + if (!info.was) { + info.was = true; + visited_.push_back(&info); + if (!info.sync_with_db) { + ++pca_state_->remaining_; + load_cell_async( + info.cell->get_hash().as_slice(), pca_state_->executor_, + [executor = pca_state_->executor_, db = this, info = &info](td::Result> R) { + R.ensure(); + executor->execute_sync([db, info]() { + CHECK(info->sync_with_db); + db->dfs_old_cells_async(*info); + if (--db->pca_state_->remaining_ == 0) { + db->prepare_commit_async_cont2(); + } + }); + }); + return; + } + } + info.refcnt_diff--; + if (!info.sync_with_db) { + return; + } + auto new_refcnt = info.refcnt_diff + info.db_refcnt; + CHECK(new_refcnt >= 0); + if (new_refcnt != 0) { + return; + } + + for_each(info, [this](auto &child_info) { dfs_old_cells_async(child_info); }); + } + + void prepare_commit_async_cont2() { + save_diff_prepare(); + to_inc_.clear(); + to_dec_.clear(); + pca_state_->promise_.set_result(td::Unit()); + pca_state_ = {}; + } + }; } // namespace diff --git a/crypto/vm/db/DynamicBagOfCellsDb.h b/crypto/vm/db/DynamicBagOfCellsDb.h index 3569208c..69cab52f 100644 --- a/crypto/vm/db/DynamicBagOfCellsDb.h +++ b/crypto/vm/db/DynamicBagOfCellsDb.h @@ -75,6 +75,7 @@ class DynamicBagOfCellsDb { virtual void load_cell_async(td::Slice hash, std::shared_ptr executor, td::Promise> promise) = 0; + virtual void prepare_commit_async(std::shared_ptr executor, td::Promise promise) = 0; }; } // namespace vm diff --git a/dht-server/dht-server.cpp b/dht-server/dht-server.cpp index 212a6fae..f729105f 100644 --- a/dht-server/dht-server.cpp +++ b/dht-server/dht-server.cpp @@ -170,7 +170,7 @@ ton::tl_object_ptr Config::tl() const { return ton::create_tl_object( out_port, std::move(addrs_vec), std::move(adnl_vec), std::move(dht_vec), std::move(val_vec), ton::PublicKeyHash::zero().tl(), std::move(full_node_slaves_vec), std::move(full_node_masters_vec), - std::move(liteserver_vec), std::move(control_vec), std::move(gc_vec)); + nullptr, std::move(liteserver_vec), std::move(control_vec), std::move(gc_vec)); } td::Result Config::config_add_network_addr(td::IPAddress in_ip, td::IPAddress out_ip, diff --git a/tdutils/td/utils/OptionParser.cpp b/tdutils/td/utils/OptionParser.cpp index b9584856..634570e1 100644 --- a/tdutils/td/utils/OptionParser.cpp +++ b/tdutils/td/utils/OptionParser.cpp @@ -33,7 +33,7 @@ void OptionParser::set_description(string description) { void OptionParser::add_option(Option::Type type, char short_key, Slice long_key, Slice description, std::function callback) { for (auto &option : options_) { - if (option.short_key == short_key || (!long_key.empty() && long_key == option.long_key)) { + if ((short_key != '\0' && option.short_key == short_key) || (!long_key.empty() && long_key == option.long_key)) { LOG(ERROR) << "Ignore duplicated option '" << short_key << "' '" << long_key << "'"; } } diff --git a/tl/generate/scheme/ton_api.tl b/tl/generate/scheme/ton_api.tl index 643825ea..e9b41182 100644 --- a/tl/generate/scheme/ton_api.tl +++ b/tl/generate/scheme/ton_api.tl @@ -588,12 +588,14 @@ engine.gc ids:(vector int256) = engine.Gc; engine.dht.config dht:(vector engine.dht) gc:engine.gc = engine.dht.Config; engine.validator.fullNodeMaster port:int adnl:int256 = engine.validator.FullNodeMaster; engine.validator.fullNodeSlave ip:int port:int adnl:PublicKey = engine.validator.FullNodeSlave; +engine.validator.fullNodeConfig ext_messages_broadcast_disabled:Bool = engine.validator.FullNodeConfig; engine.validator.config out_port:int addrs:(vector engine.Addr) adnl:(vector engine.adnl) dht:(vector engine.dht) validators:(vector engine.validator) fullnode:int256 fullnodeslaves:(vector engine.validator.fullNodeSlave) fullnodemasters:(vector engine.validator.fullNodeMaster) + fullnodeconfig:engine.validator.fullNodeConfig liteservers:(vector engine.liteServer) control:(vector engine.controlInterface) - gc:engine.gc = engine.validator.Config; + gc:engine.gc = engine.validator.Config; ---functions--- ---types--- @@ -642,6 +644,8 @@ engine.validator.onePerfTimerStat time:int min:double avg:double max:double = en engine.validator.perfTimerStatsByName name:string stats:(vector engine.validator.OnePerfTimerStat) = engine.validator.PerfTimerStatsByName; engine.validator.perfTimerStats stats:(vector engine.validator.PerfTimerStatsByName) = engine.validator.PerfTimerStats; +engine.validator.shardOutQueueSize size:int = engine.validator.ShardOutQueueSize; + ---functions--- @@ -693,6 +697,8 @@ engine.validator.signShardOverlayCertificate workchain:int shard:long signed_key engine.validator.importShardOverlayCertificate workchain:int shard:long signed_key:engine.validator.KeyHash cert:overlay.Certificate = engine.validator.Success; engine.validator.getPerfTimerStats name:string = engine.validator.PerfTimerStats; +engine.validator.getShardOutQueueSize flags:# block_id:tonNode.blockId dest_wc:flags.0?int dest_shard:flags.0?long = engine.validator.ShardOutQueueSize; +engine.validator.setExtMessagesBroadcastDisabled disabled:Bool = engine.validator.Success; ---types--- diff --git a/tl/generate/scheme/ton_api.tlo b/tl/generate/scheme/ton_api.tlo index 3c81ca06..702fbd6a 100644 Binary files a/tl/generate/scheme/ton_api.tlo and b/tl/generate/scheme/ton_api.tlo differ diff --git a/validator-engine-console/validator-engine-console-query.cpp b/validator-engine-console/validator-engine-console-query.cpp index 1aee7cc4..bd13225a 100644 --- a/validator-engine-console/validator-engine-console-query.cpp +++ b/validator-engine-console/validator-engine-console-query.cpp @@ -32,6 +32,7 @@ #include "terminal/terminal.h" #include "td/utils/filesystem.h" #include "overlay/overlays.h" +#include "ton/ton-tl.hpp" #include #include @@ -1055,3 +1056,54 @@ td::Status GetPerfTimerStatsJsonQuery::receive(td::BufferSlice data) { td::TerminalIO::output(std::string("wrote stats to " + file_name_ + "\n")); return td::Status::OK(); } + +td::Status GetShardOutQueueSizeQuery::run() { + TRY_RESULT_ASSIGN(block_id_.workchain, tokenizer_.get_token()); + TRY_RESULT_ASSIGN(block_id_.shard, tokenizer_.get_token()); + TRY_RESULT_ASSIGN(block_id_.seqno, tokenizer_.get_token()); + if (!tokenizer_.endl()) { + ton::ShardIdFull dest; + TRY_RESULT_ASSIGN(dest.workchain, tokenizer_.get_token()); + TRY_RESULT_ASSIGN(dest.shard, tokenizer_.get_token()); + dest_ = dest; + } + TRY_STATUS(tokenizer_.check_endl()); + return td::Status::OK(); +} + +td::Status GetShardOutQueueSizeQuery::send() { + auto b = ton::create_serialize_tl_object( + dest_ ? 1 : 0, ton::create_tl_block_id_simple(block_id_), dest_ ? dest_.value().workchain : 0, + dest_ ? dest_.value().shard : 0); + td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(b), create_promise()); + return td::Status::OK(); +} + +td::Status GetShardOutQueueSizeQuery::receive(td::BufferSlice data) { + TRY_RESULT_PREFIX(f, ton::fetch_tl_object(data.as_slice(), true), + "received incorrect answer: "); + td::TerminalIO::out() << "Queue_size: " << f->size_ << "\n"; + return td::Status::OK(); +} + +td::Status SetExtMessagesBroadcastDisabledQuery::run() { + TRY_RESULT(x, tokenizer_.get_token()); + if (x < 0 || x > 1) { + return td::Status::Error("value should be 0 or 1"); + } + value = x; + return td::Status::OK(); +} + +td::Status SetExtMessagesBroadcastDisabledQuery::send() { + auto b = ton::create_serialize_tl_object(value); + td::actor::send_closure(console_, &ValidatorEngineConsole::envelope_send_query, std::move(b), create_promise()); + return td::Status::OK(); +} + +td::Status SetExtMessagesBroadcastDisabledQuery::receive(td::BufferSlice data) { + TRY_RESULT_PREFIX(f, ton::fetch_tl_object(data.as_slice(), true), + "received incorrect answer: "); + td::TerminalIO::out() << "success\n"; + return td::Status::OK(); +} diff --git a/validator-engine-console/validator-engine-console-query.h b/validator-engine-console/validator-engine-console-query.h index ab2141dd..b1bdac7c 100644 --- a/validator-engine-console/validator-engine-console-query.h +++ b/validator-engine-console/validator-engine-console-query.h @@ -33,6 +33,7 @@ #include "td/utils/SharedSlice.h" #include "td/utils/port/IPAddress.h" #include "td/actor/actor.h" +#include "ton/ton-types.h" #include "keys/keys.hpp" @@ -1096,3 +1097,50 @@ class GetPerfTimerStatsJsonQuery : public Query { private: std::string file_name_; }; + +class GetShardOutQueueSizeQuery : public Query { + public: + GetShardOutQueueSizeQuery(td::actor::ActorId console, Tokenizer tokenizer) + : Query(console, std::move(tokenizer)) { + } + td::Status run() override; + td::Status send() override; + td::Status receive(td::BufferSlice data) override; + static std::string get_name() { + return "getshardoutqueuesize"; + } + static std::string get_help() { + return "getshardoutqueuesize [ ]\treturns number of messages in the " + "queue of the given shard. Destination shard is optional."; + } + std::string name() const override { + return get_name(); + } + + private: + ton::BlockId block_id_; + td::optional dest_; +}; + +class SetExtMessagesBroadcastDisabledQuery : public Query { + public: + SetExtMessagesBroadcastDisabledQuery(td::actor::ActorId console, Tokenizer tokenizer) + : Query(console, std::move(tokenizer)) { + } + td::Status run() override; + td::Status send() override; + td::Status receive(td::BufferSlice data) override; + static std::string get_name() { + return "setextmessagesbroadcastdisabled"; + } + static std::string get_help() { + return "setextmessagesbroadcastdisabled \tdisable broadcasting and rebroadcasting ext messages; value is 0 " + "or 1."; + } + std::string name() const override { + return get_name(); + } + + private: + bool value; +}; diff --git a/validator-engine-console/validator-engine-console.cpp b/validator-engine-console/validator-engine-console.cpp index 5ce8526b..01acced9 100644 --- a/validator-engine-console/validator-engine-console.cpp +++ b/validator-engine-console/validator-engine-console.cpp @@ -141,6 +141,8 @@ void ValidatorEngineConsole::run() { add_query_runner(std::make_unique>()); add_query_runner(std::make_unique>()); add_query_runner(std::make_unique>()); + add_query_runner(std::make_unique>()); + add_query_runner(std::make_unique>()); } bool ValidatorEngineConsole::envelope_send_query(td::BufferSlice query, td::Promise promise) { diff --git a/validator-engine/CMakeLists.txt b/validator-engine/CMakeLists.txt index 6c1ea7e2..d369a2c3 100644 --- a/validator-engine/CMakeLists.txt +++ b/validator-engine/CMakeLists.txt @@ -12,7 +12,7 @@ set(VALIDATOR_ENGINE_SOURCE add_executable(validator-engine ${VALIDATOR_ENGINE_SOURCE}) target_link_libraries(validator-engine overlay tdutils tdactor adnl tl_api dht - rldp catchain validatorsession full-node validator ton_validator validator + rldp rldp2 catchain validatorsession full-node validator ton_validator validator fift-lib memprof git ${JEMALLOC_LIBRARIES}) install(TARGETS validator-engine RUNTIME DESTINATION bin) diff --git a/validator-engine/validator-engine.cpp b/validator-engine/validator-engine.cpp index b6eb8b26..02ab42f9 100644 --- a/validator-engine/validator-engine.cpp +++ b/validator-engine/validator-engine.cpp @@ -69,7 +69,8 @@ #include #include #include "git.h" - +#include "block-auto.h" +#include "block-parse.h" Config::Config() { out_port = 3278; @@ -149,6 +150,10 @@ Config::Config(ton::ton_api::engine_validator_config &config) { config_add_full_node_master(s->port_, ton::PublicKeyHash{s->adnl_}).ensure(); } + if (config.fullnodeconfig_) { + full_node_config = ton::validator::fullnode::FullNodeConfig(config.fullnodeconfig_); + } + for (auto &serv : config.liteservers_) { config_add_lite_server(ton::PublicKeyHash{serv->id_}, serv->port_).ensure(); } @@ -219,6 +224,11 @@ ton::tl_object_ptr Config::tl() const { ton::create_tl_object(x.first, x.second.tl())); } + ton::tl_object_ptr full_node_config_obj = {}; + if (full_node_config != ton::validator::fullnode::FullNodeConfig()) { + full_node_config_obj = full_node_config.tl(); + } + std::vector> liteserver_vec; for (auto &x : liteservers) { liteserver_vec.push_back(ton::create_tl_object(x.second.tl(), x.first)); @@ -240,8 +250,8 @@ ton::tl_object_ptr Config::tl() const { } return ton::create_tl_object( out_port, std::move(addrs_vec), std::move(adnl_vec), std::move(dht_vec), std::move(val_vec), full_node.tl(), - std::move(full_node_slaves_vec), std::move(full_node_masters_vec), std::move(liteserver_vec), - std::move(control_vec), std::move(gc_vec)); + std::move(full_node_slaves_vec), std::move(full_node_masters_vec), std::move(full_node_config_obj), + std::move(liteserver_vec), std::move(control_vec), std::move(gc_vec)); } td::Result Config::config_add_network_addr(td::IPAddress in_ip, td::IPAddress out_ip, @@ -1742,6 +1752,7 @@ void ValidatorEngine::started_dht() { void ValidatorEngine::start_rldp() { rldp_ = ton::rldp::Rldp::create(adnl_.get()); + rldp2_ = ton::rldp2::Rldp::create(adnl_.get()); started_rldp(); } @@ -1804,7 +1815,7 @@ void ValidatorEngine::start_full_node() { } full_node_ = ton::validator::fullnode::FullNode::create( short_id, ton::adnl::AdnlNodeIdShort{config_.full_node}, validator_options_->zero_block_id().file_hash, - keyring_.get(), adnl_.get(), rldp_.get(), + config_.full_node_config, keyring_.get(), adnl_.get(), rldp_.get(), rldp2_.get(), default_dht_node_.is_zero() ? td::actor::ActorId{} : dht_nodes_[default_dht_node_].get(), overlay_manager_.get(), validator_manager_.get(), full_node_client_.get(), db_root_); } @@ -3333,6 +3344,112 @@ void ValidatorEngine::run_control_query(ton::ton_api::engine_validator_getPerfTi td::actor::send_closure(validator_manager_, &ton::validator::ValidatorManagerInterface::prepare_perf_timer_stats, std::move(P)); } +void ValidatorEngine::run_control_query(ton::ton_api::engine_validator_getShardOutQueueSize &query, + td::BufferSlice data, ton::PublicKeyHash src, td::uint32 perm, + td::Promise promise) { + if (!(perm & ValidatorEnginePermissions::vep_default)) { + promise.set_value(create_control_query_error(td::Status::Error(ton::ErrorCode::error, "not authorized"))); + return; + } + + if (validator_manager_.empty()) { + promise.set_value( + create_control_query_error(td::Status::Error(ton::ErrorCode::notready, "validator manager not started"))); + return; + } + + ton::BlockId block_id = ton::create_block_id_simple(query.block_id_); + if (!block_id.is_valid_ext()) { + promise.set_value(create_control_query_error(td::Status::Error(ton::ErrorCode::error, "invalid block id"))); + return; + } + td::optional dest; + if (query.flags_ & 1) { + dest = ton::ShardIdFull{query.dest_wc_, (ton::ShardId)query.dest_shard_}; + if (!dest.value().is_valid_ext()) { + promise.set_value(create_control_query_error(td::Status::Error(ton::ErrorCode::error, "invalid shard"))); + return; + } + } + + td::actor::send_closure( + validator_manager_, &ton::validator::ValidatorManagerInterface::get_block_by_seqno_from_db, + ton::AccountIdPrefixFull{block_id.workchain, block_id.shard}, block_id.seqno, + [=, promise = std::move(promise), + manager = validator_manager_.get()](td::Result R) mutable { + if (R.is_error()) { + promise.set_value(create_control_query_error(R.move_as_error())); + return; + } + auto handle = R.move_as_ok(); + if (handle->id().id != block_id) { + promise.set_value(create_control_query_error(td::Status::Error(ton::ErrorCode::notready, "no such block"))); + return; + } + td::actor::send_closure( + manager, &ton::validator::ValidatorManagerInterface::get_shard_state_from_db, handle, + [=, promise = std::move(promise)](td::Result> R) mutable { + auto res = [&]() -> td::Result { + TRY_RESULT(state, std::move(R)); + TRY_RESULT(outq_descr, state->message_queue()); + block::gen::OutMsgQueueInfo::Record qinfo; + if (!tlb::unpack_cell(outq_descr->root_cell(), qinfo)) { + return td::Status::Error(ton::ErrorCode::error, "invalid message queue"); + } + auto queue = std::make_unique(qinfo.out_queue->prefetch_ref(0), 352, + block::tlb::aug_OutMsgQueue); + if (dest) { + td::BitArray<96> prefix; + td::BitPtr ptr = prefix.bits(); + ptr.store_int(dest.value().workchain, 32); + ptr.advance(32); + ptr.store_uint(dest.value().shard, 64); + if (!queue->cut_prefix_subdict(prefix.bits(), 32 + dest.value().pfx_len())) { + return td::Status::Error(ton::ErrorCode::error, "invalid message queue"); + } + } + int size = 0; + queue->check_for_each([&](td::Ref, td::ConstBitPtr, int) -> bool { + ++size; + return true; + }); + return ton::create_serialize_tl_object(size); + }(); + if (res.is_error()) { + promise.set_value(create_control_query_error(res.move_as_error())); + } else { + promise.set_value(res.move_as_ok()); + } + }); + }); +} + +void ValidatorEngine::run_control_query(ton::ton_api::engine_validator_setExtMessagesBroadcastDisabled &query, td::BufferSlice data, ton::PublicKeyHash src, td::uint32 perm, + td::Promise promise) { + if (!(perm & ValidatorEnginePermissions::vep_modify)) { + promise.set_value(create_control_query_error(td::Status::Error(ton::ErrorCode::error, "not authorized"))); + return; + } + if (!started_) { + promise.set_value(create_control_query_error(td::Status::Error(ton::ErrorCode::notready, "not started"))); + return; + } + + if (config_.full_node_config.ext_messages_broadcast_disabled_ == query.disabled_) { + promise.set_value(ton::create_serialize_tl_object()); + return; + } + config_.full_node_config.ext_messages_broadcast_disabled_ = query.disabled_; + td::actor::send_closure(full_node_, &ton::validator::fullnode::FullNode::set_config, config_.full_node_config); + write_config([promise = std::move(promise)](td::Result R) mutable { + if (R.is_error()) { + promise.set_value(create_control_query_error(R.move_as_error())); + } else { + promise.set_value(ton::create_serialize_tl_object()); + } + }); +} + void ValidatorEngine::process_control_query(td::uint16 port, ton::adnl::AdnlNodeIdShort src, ton::adnl::AdnlNodeIdShort dst, td::BufferSlice data, td::Promise promise) { diff --git a/validator-engine/validator-engine.hpp b/validator-engine/validator-engine.hpp index 7284a5be..e2367419 100644 --- a/validator-engine/validator-engine.hpp +++ b/validator-engine/validator-engine.hpp @@ -30,6 +30,7 @@ #include "adnl/adnl.h" #include "auto/tl/ton_api.h" #include "rldp/rldp.h" +#include "rldp2/rldp.h" #include "dht/dht.h" #include "validator/manager.h" #include "validator/validator.h" @@ -85,6 +86,7 @@ struct Config { std::vector full_node_slaves; std::map full_node_masters; std::map liteservers; + ton::validator::fullnode::FullNodeConfig full_node_config; std::map controls; std::set gc; @@ -137,6 +139,7 @@ class ValidatorEngine : public td::actor::Actor { td::actor::ActorOwn adnl_network_manager_; td::actor::ActorOwn adnl_; td::actor::ActorOwn rldp_; + td::actor::ActorOwn rldp2_; std::map> dht_nodes_; ton::PublicKeyHash default_dht_node_ = ton::PublicKeyHash::zero(); td::actor::ActorOwn overlay_manager_; @@ -409,6 +412,10 @@ class ValidatorEngine : public td::actor::Actor { ton::PublicKeyHash src, td::uint32 perm, td::Promise promise); void run_control_query(ton::ton_api::engine_validator_getPerfTimerStats &query, td::BufferSlice data, ton::PublicKeyHash src, td::uint32 perm, td::Promise promise); + void run_control_query(ton::ton_api::engine_validator_getShardOutQueueSize &query, td::BufferSlice data, + ton::PublicKeyHash src, td::uint32 perm, td::Promise promise); + void run_control_query(ton::ton_api::engine_validator_setExtMessagesBroadcastDisabled &query, td::BufferSlice data, + ton::PublicKeyHash src, td::uint32 perm, td::Promise promise); template void run_control_query(T &query, td::BufferSlice data, ton::PublicKeyHash src, td::uint32 perm, td::Promise promise) { diff --git a/validator-session/validator-session.cpp b/validator-session/validator-session.cpp index 3f56e3a3..2902b082 100644 --- a/validator-session/validator-session.cpp +++ b/validator-session/validator-session.cpp @@ -45,8 +45,8 @@ void ValidatorSessionImpl::process_blocks(std::vector std::vector> msgs; if (generated_ && !sent_generated_) { - auto it = blocks_[0].find(generated_block_); - CHECK(it != blocks_[0].end()); + auto it = blocks_.find(generated_block_); + CHECK(it != blocks_.end()); auto &B = it->second; auto file_hash = sha256_bits256(B->data_); @@ -230,13 +230,15 @@ void ValidatorSessionImpl::process_broadcast(PublicKeyHash src, td::BufferSlice auto block_round = static_cast(candidate->round_); auto block_id = description().candidate_id(src_idx, candidate->root_hash_, file_hash, collated_data_file_hash); - if (block_round < cur_round_ || block_round >= cur_round_ + blocks_.size()) { + if ((td::int32)block_round < (td::int32)cur_round_ - MAX_PAST_ROUND_BLOCK || + block_round >= cur_round_ + MAX_FUTURE_ROUND_BLOCK) { VLOG(VALIDATOR_SESSION_NOTICE) << this << "[node " << src << "][broadcast " << block_id << "]: bad round=" << block_round << " cur_round" << cur_round_; return; } - auto it = blocks_[block_round - cur_round_].find(block_id); - if (it != blocks_[block_round - cur_round_].end()) { + auto it = blocks_.find(block_id); + if (it != blocks_.end()) { + it->second->round_ = std::max(it->second->round_, block_round); VLOG(VALIDATOR_SESSION_INFO) << this << "[node " << src << "][broadcast " << block_id << "]: duplicate"; return; } @@ -248,7 +250,7 @@ void ValidatorSessionImpl::process_broadcast(PublicKeyHash src, td::BufferSlice return; } - blocks_[block_round - cur_round_][block_id] = std::move(candidate); + blocks_[block_id] = std::move(candidate); VLOG(VALIDATOR_SESSION_WARNING) << this << ": received broadcast " << block_id; if (block_round != cur_round_) { @@ -407,7 +409,7 @@ void ValidatorSessionImpl::generated_block(td::uint32 round, ValidatorSessionCan td::actor::send_closure(catchain_, &catchain::CatChain::send_broadcast, std::move(B)); - blocks_[0].emplace(block_id, std::move(b)); + blocks_.emplace(block_id, std::move(b)); pending_generate_ = false; generated_ = true; generated_block_ = block_id; @@ -507,9 +509,10 @@ void ValidatorSessionImpl::try_approve_block(const SentBlock *block) { if (block) { auto T = td::Timestamp::at(round_started_at_.at() + description().get_delay(block->get_src_idx()) + 2.0); - auto it = blocks_[0].find(block_id); + auto it = blocks_.find(block_id); - if (it != blocks_[0].end()) { + if (it != blocks_.end()) { + it->second->round_ = std::max(it->second->round_, cur_round_); td::PerfWarningTimer timer{"too long block validation", 1.0}; auto &B = it->second; @@ -532,7 +535,6 @@ void ValidatorSessionImpl::try_approve_block(const SentBlock *block) { } }); pending_approve_.insert(block_id); - CHECK(static_cast(cur_round_) == B->round_); callback_->on_candidate(cur_round_, description().get_source_public_key(block->get_src_idx()), B->root_hash_, B->data_.clone(), B->collated_data_.clone(), std::move(P)); @@ -556,7 +558,7 @@ void ValidatorSessionImpl::try_approve_block(const SentBlock *block) { get_broadcast_p2p(id, block->get_file_hash(), block->get_collated_data_file_hash(), description().get_source_id(block->get_src_idx()), cur_round_, block->get_root_hash(), - std::move(P), td::Timestamp::in(2.0)); + std::move(P), td::Timestamp::in(15.0)); } else { LOG(VALIDATOR_SESSION_DEBUG) << this << ": no nodes to download candidate " << block << " from"; } @@ -773,7 +775,7 @@ void ValidatorSessionImpl::on_new_round(td::uint32 round) { } } - auto it = blocks_[0].find(SentBlock::get_block_id(block)); + auto it = blocks_.find(SentBlock::get_block_id(block)); bool have_block = (bool)block; if (!have_block) { callback_->on_block_skipped(cur_round_); @@ -788,7 +790,7 @@ void ValidatorSessionImpl::on_new_round(td::uint32 round) { cur_stats_.creator = description().get_source_id(block->get_src_idx()); cur_stats_.self = description().get_source_id(local_idx()); - if (it == blocks_[0].end()) { + if (it == blocks_.end()) { callback_->on_block_committed(cur_round_, description().get_source_public_key(block->get_src_idx()), block->get_root_hash(), block->get_file_hash(), td::BufferSlice(), std::move(export_sigs), std::move(export_approve_sigs), std::move(cur_stats_)); @@ -804,10 +806,14 @@ void ValidatorSessionImpl::on_new_round(td::uint32 round) { } else { stats_add_round(); } - for (size_t i = 0; i < blocks_.size() - 1; i++) { - blocks_[i] = std::move(blocks_[i + 1]); + auto it2 = blocks_.begin(); + while (it2 != blocks_.end()) { + if (it2->second->round_ < (td::int32)cur_round_ - MAX_PAST_ROUND_BLOCK) { + it2 = blocks_.erase(it2); + } else { + ++it2; + } } - blocks_[blocks_.size() - 1].clear(); } round_started_at_ = td::Timestamp::now(); diff --git a/validator-session/validator-session.hpp b/validator-session/validator-session.hpp index 54bba33d..e8274554 100644 --- a/validator-session/validator-session.hpp +++ b/validator-session/validator-session.hpp @@ -73,7 +73,7 @@ class ValidatorSessionImpl : public ValidatorSession { ValidatorSessionCandidateId signed_block_; td::BufferSlice signature_; - std::array>, 100> blocks_; + std::map> blocks_; catchain::CatChainSessionId unique_hash_; @@ -204,6 +204,8 @@ class ValidatorSessionImpl : public ValidatorSession { private: static const size_t MAX_REJECT_REASON_SIZE = 1024; + static const td::int32 MAX_FUTURE_ROUND_BLOCK = 100; + static const td::int32 MAX_PAST_ROUND_BLOCK = 20; }; } // namespace validatorsession diff --git a/validator/CMakeLists.txt b/validator/CMakeLists.txt index 65d7b348..573cd8e5 100644 --- a/validator/CMakeLists.txt +++ b/validator/CMakeLists.txt @@ -198,5 +198,5 @@ target_link_libraries(validator-disk PRIVATE tdutils tdactor adnl rldp tl_api dh target_link_libraries(validator-hardfork PRIVATE tdutils tdactor adnl rldp tl_api dht tdfec overlay catchain validatorsession ton_crypto ton_block ton_db) -target_link_libraries(full-node PRIVATE tdutils tdactor adnl rldp tl_api dht tdfec +target_link_libraries(full-node PRIVATE tdutils tdactor adnl rldp rldp2 tl_api dht tdfec overlay catchain validatorsession ton_crypto ton_block ton_db) diff --git a/validator/db/celldb.cpp b/validator/db/celldb.cpp index e142043e..c633e395 100644 --- a/validator/db/celldb.cpp +++ b/validator/db/celldb.cpp @@ -33,11 +33,11 @@ class CellDbAsyncExecutor : public vm::DynamicBagOfCellsDb::AsyncExecutor { explicit CellDbAsyncExecutor(td::actor::ActorId cell_db) : cell_db_(std::move(cell_db)) { } - void execute_async(std::function f) { + void execute_async(std::function f) override { class Runner : public td::actor::Actor { public: explicit Runner(std::function f) : f_(std::move(f)) {} - void start_up() { + void start_up() override { f_(); stop(); } @@ -47,7 +47,7 @@ class CellDbAsyncExecutor : public vm::DynamicBagOfCellsDb::AsyncExecutor { td::actor::create_actor("executeasync", std::move(f)).release(); } - void execute_sync(std::function f) { + void execute_sync(std::function f) override { td::actor::send_closure(cell_db_, &CellDbBase::execute_sync, std::move(f)); } private: @@ -83,23 +83,45 @@ void CellDbIn::start_up() { set_block(empty, std::move(e)); cell_db_->commit_write_batch().ensure(); } - last_gc_ = empty; } void CellDbIn::load_cell(RootHash hash, td::Promise> promise) { - boc_->load_cell_async(hash.as_slice(), async_executor, std::move(promise)); + enqueue([this, hash, promise = std::move(promise)](td::Result R) mutable { + if (R.is_error()) { + return; + } + promise.set_result(boc_->load_cell(hash.as_slice())); + release_db(); + }); } void CellDbIn::store_cell(BlockIdExt block_id, td::Ref cell, td::Promise> promise) { - td::PerfWarningTimer timer{"storecell", 0.1}; - auto key_hash = get_key_hash(block_id); - auto R = get_block(key_hash); - // duplicate - if (R.is_ok()) { - promise.set_result(boc_->load_cell(cell->get_hash().as_slice())); - return; - } + enqueue([this, block_id, cell = std::move(cell), promise = std::move(promise)](td::Result R0) mutable { + if (R0.is_error()) { + return; + } + promise = promise.wrap([timer = td::PerfWarningTimer{"storecell", 0.1}](td::Ref &&r) { return r; }); + auto key_hash = get_key_hash(block_id); + auto R = get_block(key_hash); + // duplicate + if (R.is_ok()) { + promise.set_result(boc_->load_cell(cell->get_hash().as_slice())); + release_db(); + return; + } + boc_->inc(cell); + boc_->prepare_commit_async( + async_executor, [=, SelfId = actor_id(this), promise = std::move(promise)](td::Result R) mutable { + R.ensure(); + td::actor::send_closure(SelfId, &CellDbIn::store_cell_cont, block_id, cell, std::move(promise)); + }); + }); +} + +void CellDbIn::store_cell_cont(BlockIdExt block_id, td::Ref cell, + td::Promise> promise) { + auto key_hash = get_key_hash(block_id); auto empty = get_empty_key_hash(); auto ER = get_block(empty); ER.ensure(); @@ -120,9 +142,7 @@ void CellDbIn::store_cell(BlockIdExt block_id, td::Ref cell, td::Promi P.prev = key_hash; } - boc_->inc(cell); - boc_->prepare_commit().ensure(); - vm::CellStorer stor{*cell_db_.get()}; + vm::CellStorer stor{*cell_db_}; cell_db_->begin_write_batch().ensure(); boc_->commit(stor).ensure(); set_block(empty, std::move(E)); @@ -134,24 +154,29 @@ void CellDbIn::store_cell(BlockIdExt block_id, td::Ref cell, td::Promi td::actor::send_closure(parent_, &CellDb::update_snapshot, cell_db_->snapshot()); promise.set_result(boc_->load_cell(cell->get_hash().as_slice())); + release_db(); } void CellDbIn::get_cell_db_reader(td::Promise> promise) { - promise.set_result(boc_->get_cell_db_reader()); + enqueue([this, promise = std::move(promise)](td::Result R) mutable { + if (R.is_error()) { + return; + } + promise.set_result(boc_->get_cell_db_reader()); + release_db(); + }); } void CellDbIn::alarm() { - auto R = get_block(last_gc_); - R.ensure(); - - auto N = R.move_as_ok(); + auto E = get_block(get_empty_key_hash()).move_as_ok(); + auto N = get_block(E.next).move_as_ok(); if (N.is_empty()) { - last_gc_ = N.next; alarm_timestamp() = td::Timestamp::in(0.1); return; } - auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result R) { + auto block_id = N.block_id; + auto P = td::PromiseCreator::lambda([SelfId = actor_id(this), block_id](td::Result R) { if (R.is_error()) { td::actor::send_closure(SelfId, &CellDbIn::skip_gc); } else { @@ -159,24 +184,19 @@ void CellDbIn::alarm() { if (!value) { td::actor::send_closure(SelfId, &CellDbIn::skip_gc); } else { - td::actor::send_closure(SelfId, &CellDbIn::gc); + td::actor::send_closure(SelfId, &CellDbIn::gc, block_id); } } }); - td::actor::send_closure(root_db_, &RootDb::allow_state_gc, N.block_id, std::move(P)); + td::actor::send_closure(root_db_, &RootDb::allow_state_gc, block_id, std::move(P)); } -void CellDbIn::gc() { - auto R = get_block(last_gc_); - R.ensure(); - - auto N = R.move_as_ok(); - +void CellDbIn::gc(BlockIdExt block_id) { auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result R) { R.ensure(); td::actor::send_closure(SelfId, &CellDbIn::gc_cont, R.move_as_ok()); }); - td::actor::send_closure(root_db_, &RootDb::get_block_handle_external, N.block_id, false, std::move(P)); + td::actor::send_closure(root_db_, &RootDb::get_block_handle_external, block_id, false, std::move(P)); } void CellDbIn::gc_cont(BlockHandle handle) { @@ -194,12 +214,30 @@ void CellDbIn::gc_cont(BlockHandle handle) { } void CellDbIn::gc_cont2(BlockHandle handle) { - td::PerfWarningTimer timer{"gccell", 0.1}; + enqueue([this, handle = std::move(handle)](td::Result R) mutable { + if (R.is_error()) { + return; + } + td::Promise promise = [timer = td::PerfWarningTimer{"gccell", 0.1}](td::Result) {}; + auto FR = get_block(get_key_hash(handle->id())); + FR.ensure(); + auto F = FR.move_as_ok(); + auto cell = boc_->load_cell(F.root_hash.as_slice()).move_as_ok(); - auto FR = get_block(last_gc_); + boc_->dec(cell); + boc_->prepare_commit_async(async_executor, [SelfId = actor_id(this), promise = std::move(promise), + block_id = handle->id()](td::Result R) mutable { + R.ensure(); + td::actor::send_closure(SelfId, &CellDbIn::gc_cont3, block_id, std::move(promise)); + }); + }); +} + +void CellDbIn::gc_cont3(BlockIdExt block_id, td::Promise promise) { + auto key_hash = get_key_hash(block_id); + auto FR = get_block(key_hash); FR.ensure(); auto F = FR.move_as_ok(); - auto PR = get_block(F.prev); PR.ensure(); auto P = PR.move_as_ok(); @@ -214,14 +252,10 @@ void CellDbIn::gc_cont2(BlockHandle handle) { N.next = N.prev; } - auto cell = boc_->load_cell(F.root_hash.as_slice()).move_as_ok(); - - boc_->dec(cell); - boc_->prepare_commit().ensure(); - vm::CellStorer stor{*cell_db_.get()}; + vm::CellStorer stor{*cell_db_}; cell_db_->begin_write_batch().ensure(); boc_->commit(stor).ensure(); - cell_db_->erase(get_key(last_gc_)).ensure(); + cell_db_->erase(get_key(key_hash)).ensure(); set_block(F.prev, std::move(P)); set_block(F.next, std::move(N)); cell_db_->commit_write_batch().ensure(); @@ -230,16 +264,33 @@ void CellDbIn::gc_cont2(BlockHandle handle) { boc_->set_loader(std::make_unique(cell_db_->snapshot())).ensure(); td::actor::send_closure(parent_, &CellDb::update_snapshot, cell_db_->snapshot()); - DCHECK(get_block(last_gc_).is_error()); - last_gc_ = F.next; + DCHECK(get_block(key_hash).is_error()); + promise.set_result(td::Unit()); + release_db(); +} + +void CellDbIn::enqueue(td::Promise promise) { + db_queue_.push(std::move(promise)); + process_event(); +} + +void CellDbIn::release_db() { + db_busy_ = false; + process_event(); +} + +void CellDbIn::process_event() { + if (db_busy_ || db_queue_.empty()) { + return; + } + db_busy_ = true; + auto promise = std::move(db_queue_.front()); + db_queue_.pop(); + promise.set_result(td::Unit()); } void CellDbIn::skip_gc() { - auto FR = get_block(last_gc_); - FR.ensure(); - auto F = FR.move_as_ok(); - last_gc_ = F.next; - alarm_timestamp() = td::Timestamp::in(0.01); + alarm_timestamp() = td::Timestamp::in(1.0); } std::string CellDbIn::get_key(KeyHash key_hash) { @@ -296,7 +347,7 @@ void CellDb::load_cell(RootHash hash, td::Promise> promise } else { promise.set_result(R.move_as_ok()); } - }); + }); boc_->load_cell_async(hash.as_slice(), async_executor, std::move(P)); } } diff --git a/validator/db/celldb.hpp b/validator/db/celldb.hpp index e54526b9..08d5a184 100644 --- a/validator/db/celldb.hpp +++ b/validator/db/celldb.hpp @@ -25,6 +25,7 @@ #include "ton/ton-types.h" #include "interfaces/block-handle.h" #include "auto/tl/ton_api.h" +#include namespace ton { @@ -84,11 +85,14 @@ class CellDbIn : public CellDbBase { static BlockIdExt get_empty_key(); KeyHash get_empty_key_hash(); - void gc(); + void gc(BlockIdExt block_id); void gc_cont(BlockHandle handle); void gc_cont2(BlockHandle handle); + void gc_cont3(BlockIdExt block_id, td::Promise promise); void skip_gc(); + void store_cell_cont(BlockIdExt block_id, td::Ref cell, td::Promise> promise); + td::actor::ActorId root_db_; td::actor::ActorId parent_; @@ -97,7 +101,12 @@ class CellDbIn : public CellDbBase { std::unique_ptr boc_; std::shared_ptr cell_db_; - KeyHash last_gc_; + std::queue> db_queue_; + bool db_busy_ = false; + + void enqueue(td::Promise promise); + void release_db(); + void process_event(); }; class CellDb : public CellDbBase { diff --git a/validator/full-node-shard.cpp b/validator/full-node-shard.cpp index 4cb5627d..0f495077 100644 --- a/validator/full-node-shard.cpp +++ b/validator/full-node-shard.cpp @@ -96,6 +96,7 @@ void FullNodeShardImpl::create_overlay() { std::make_unique(actor_id(this)), rules_, PSTRING() << "{ \"type\": \"shard\", \"shard_id\": " << get_shard() << ", \"workchain_id\": " << get_workchain() << " }"); td::actor::send_closure(rldp_, &rldp::Rldp::add_id, adnl_id_); + td::actor::send_closure(rldp2_, &rldp2::Rldp::add_id, adnl_id_); if (cert_) { td::actor::send_closure(overlays_, &overlay::Overlays::update_certificate, adnl_id_, overlay_id_, local_id_, cert_); } @@ -108,15 +109,17 @@ void FullNodeShardImpl::check_broadcast(PublicKeyHash src, td::BufferSlice broad } auto q = B.move_as_ok(); + if (config_.ext_messages_broadcast_disabled_) { + promise.set_error(td::Status::Error("rebroadcasting external messages is disabled")); + promise = [manager = validator_manager_, message = q->message_->data_.clone()](td::Result R) mutable { + if (R.is_ok()) { + td::actor::send_closure(manager, &ValidatorManagerInterface::new_external_message, std::move(message)); + } + }; + } td::actor::send_closure(validator_manager_, &ValidatorManagerInterface::check_external_message, std::move(q->message_->data_), - [promise = std::move(promise)](td::Result> R) mutable { - if (R.is_error()) { - promise.set_error(R.move_as_error()); - } else { - promise.set_result(td::Unit()); - } - }); + promise.wrap([](td::Ref) { return td::Unit(); })); } void FullNodeShardImpl::update_adnl_id(adnl::AdnlNodeIdShort adnl_id, td::Promise promise) { @@ -685,6 +688,9 @@ void FullNodeShardImpl::send_ihr_message(td::BufferSlice data) { } void FullNodeShardImpl::send_external_message(td::BufferSlice data) { + if (config_.ext_messages_broadcast_disabled_) { + return; + } if (!client_.empty()) { td::actor::send_closure(client_, &adnl::AdnlExtClient::send_query, "send_ext_query", create_serialize_tl_object_suffix( @@ -768,9 +774,11 @@ void FullNodeShardImpl::download_zero_state(BlockIdExt id, td::uint32 priority, void FullNodeShardImpl::download_persistent_state(BlockIdExt id, BlockIdExt masterchain_block_id, td::uint32 priority, td::Timestamp timeout, td::Promise promise) { + auto &b = choose_neighbour(); td::actor::create_actor(PSTRING() << "downloadstatereq" << id.id.to_str(), id, masterchain_block_id, - adnl_id_, overlay_id_, adnl::AdnlNodeIdShort::zero(), priority, timeout, - validator_manager_, rldp_, overlays_, adnl_, client_, std::move(promise)) + adnl_id_, overlay_id_, b.adnl_id, priority, timeout, validator_manager_, + b.use_rldp2() ? (td::actor::ActorId)rldp2_ : rldp_, + overlays_, adnl_, client_, std::move(promise)) .release(); } @@ -805,8 +813,9 @@ void FullNodeShardImpl::download_archive(BlockSeqno masterchain_seqno, std::stri td::Promise promise) { auto &b = choose_neighbour(); td::actor::create_actor( - "archive", masterchain_seqno, std::move(tmp_dir), adnl_id_, overlay_id_, adnl::AdnlNodeIdShort::zero(), timeout, - validator_manager_, rldp_, overlays_, adnl_, client_, create_neighbour_promise(b, std::move(promise))) + "archive", masterchain_seqno, std::move(tmp_dir), adnl_id_, overlay_id_, b.adnl_id, timeout, validator_manager_, + b.use_rldp2() ? (td::actor::ActorId)rldp2_ : rldp_, overlays_, adnl_, client_, + create_neighbour_promise(b, std::move(promise))) .release(); } @@ -1100,8 +1109,9 @@ void FullNodeShardImpl::ping_neighbours() { } FullNodeShardImpl::FullNodeShardImpl(ShardIdFull shard, PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id, - FileHash zero_state_file_hash, td::actor::ActorId keyring, - td::actor::ActorId adnl, td::actor::ActorId rldp, + FileHash zero_state_file_hash, FullNodeConfig config, + td::actor::ActorId keyring, td::actor::ActorId adnl, + td::actor::ActorId rldp, td::actor::ActorId rldp2, td::actor::ActorId overlays, td::actor::ActorId validator_manager, td::actor::ActorId client) @@ -1112,18 +1122,21 @@ FullNodeShardImpl::FullNodeShardImpl(ShardIdFull shard, PublicKeyHash local_id, , keyring_(keyring) , adnl_(adnl) , rldp_(rldp) + , rldp2_(rldp2) , overlays_(overlays) , validator_manager_(validator_manager) - , client_(client) { + , client_(client) + , config_(config) { } td::actor::ActorOwn FullNodeShard::create( ShardIdFull shard, PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id, FileHash zero_state_file_hash, - td::actor::ActorId keyring, td::actor::ActorId adnl, - td::actor::ActorId rldp, td::actor::ActorId overlays, - td::actor::ActorId validator_manager, td::actor::ActorId client) { - return td::actor::create_actor("tonnode", shard, local_id, adnl_id, zero_state_file_hash, keyring, - adnl, rldp, overlays, validator_manager, client); + FullNodeConfig config, td::actor::ActorId keyring, td::actor::ActorId adnl, + td::actor::ActorId rldp, td::actor::ActorId rldp2, + td::actor::ActorId overlays, td::actor::ActorId validator_manager, + td::actor::ActorId client) { + return td::actor::create_actor("tonnode", shard, local_id, adnl_id, zero_state_file_hash, config, + keyring, adnl, rldp, rldp2, overlays, validator_manager, client); } } // namespace fullnode diff --git a/validator/full-node-shard.h b/validator/full-node-shard.h index c1712baf..1b742fb9 100644 --- a/validator/full-node-shard.h +++ b/validator/full-node-shard.h @@ -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 promise) = 0; + virtual void set_config(FullNodeConfig config) = 0; virtual void send_ihr_message(td::BufferSlice data) = 0; virtual void send_external_message(td::BufferSlice data) = 0; @@ -68,9 +69,10 @@ class FullNodeShard : public td::actor::Actor { static td::actor::ActorOwn create( ShardIdFull shard, PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id, FileHash zero_state_file_hash, - td::actor::ActorId keyring, td::actor::ActorId adnl, - td::actor::ActorId rldp, td::actor::ActorId overlays, - td::actor::ActorId validator_manager, td::actor::ActorId client); + FullNodeConfig config, td::actor::ActorId keyring, td::actor::ActorId adnl, + td::actor::ActorId rldp, td::actor::ActorId rldp2, + td::actor::ActorId overlays, td::actor::ActorId validator_manager, + td::actor::ActorId client); }; } // namespace fullnode diff --git a/validator/full-node-shard.hpp b/validator/full-node-shard.hpp index a2dd5cc4..dcf4c649 100644 --- a/validator/full-node-shard.hpp +++ b/validator/full-node-shard.hpp @@ -44,6 +44,10 @@ struct Neighbour { void query_failed(); void update_roundtrip(double t); + bool use_rldp2() const { + return std::make_pair(proto_version, capabilities) >= std::make_pair(2, 2); + } + static Neighbour zero; }; @@ -66,7 +70,7 @@ class FullNodeShardImpl : public FullNodeShard { return 2; } static constexpr td::uint64 proto_capabilities() { - return 1; + return 2; } static constexpr td::uint32 max_neighbours() { return 16; @@ -81,6 +85,10 @@ class FullNodeShardImpl : public FullNodeShard { void create_overlay(); void update_adnl_id(adnl::AdnlNodeIdShort adnl_id, td::Promise promise) override; + void set_config(FullNodeConfig config) override { + config_ = config; + } + //td::Result fetch_block(td::BufferSlice data); void prevalidate_block(BlockIdExt block_id, td::BufferSlice data, td::BufferSlice proof, td::Promise promise); @@ -198,9 +206,9 @@ class FullNodeShardImpl : public FullNodeShard { } FullNodeShardImpl(ShardIdFull shard, PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id, - FileHash zero_state_file_hash, td::actor::ActorId keyring, + FileHash zero_state_file_hash, FullNodeConfig config, td::actor::ActorId keyring, td::actor::ActorId adnl, td::actor::ActorId rldp, - td::actor::ActorId overlays, + td::actor::ActorId rldp2, td::actor::ActorId overlays, td::actor::ActorId validator_manager, td::actor::ActorId client); @@ -220,6 +228,7 @@ class FullNodeShardImpl : public FullNodeShard { td::actor::ActorId keyring_; td::actor::ActorId adnl_; td::actor::ActorId rldp_; + td::actor::ActorId rldp2_; td::actor::ActorId overlays_; td::actor::ActorId validator_manager_; td::actor::ActorId client_; @@ -239,6 +248,8 @@ class FullNodeShardImpl : public FullNodeShard { td::Timestamp reload_neighbours_at_; td::Timestamp ping_neighbours_at_; adnl::AdnlNodeIdShort last_pinged_neighbour_ = adnl::AdnlNodeIdShort::zero(); + + FullNodeConfig config_; }; } // namespace fullnode diff --git a/validator/full-node.cpp b/validator/full-node.cpp index 6606f215..ebba50a0 100644 --- a/validator/full-node.cpp +++ b/validator/full-node.cpp @@ -20,6 +20,7 @@ #include "ton/ton-shard.h" #include "ton/ton-io.hpp" #include "td/actor/MultiPromise.h" +#include "full-node.h" namespace ton { @@ -110,6 +111,13 @@ void FullNodeImpl::update_adnl_id(adnl::AdnlNodeIdShort adnl_id, td::Promise R) { R.ensure(); @@ -123,8 +131,8 @@ void FullNodeImpl::initial_read_complete(BlockHandle top_handle) { void FullNodeImpl::add_shard(ShardIdFull shard) { while (true) { if (shards_.count(shard) == 0) { - shards_.emplace(shard, FullNodeShard::create(shard, local_id_, adnl_id_, zero_state_file_hash_, keyring_, adnl_, - rldp_, overlays_, validator_manager_, client_)); + shards_.emplace(shard, FullNodeShard::create(shard, local_id_, adnl_id_, zero_state_file_hash_, config_, keyring_, + adnl_, rldp_, rldp2_, overlays_, validator_manager_, client_)); if (all_validators_.size() > 0) { td::actor::send_closure(shards_[shard], &FullNodeShard::update_validators, all_validators_, sign_cert_by_); } @@ -449,8 +457,9 @@ void FullNodeImpl::start_up() { } FullNodeImpl::FullNodeImpl(PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id, FileHash zero_state_file_hash, - td::actor::ActorId keyring, td::actor::ActorId adnl, - td::actor::ActorId rldp, td::actor::ActorId dht, + FullNodeConfig config, td::actor::ActorId keyring, + td::actor::ActorId adnl, td::actor::ActorId rldp, + td::actor::ActorId rldp2, td::actor::ActorId dht, td::actor::ActorId overlays, td::actor::ActorId validator_manager, td::actor::ActorId client, std::string db_root) @@ -460,24 +469,40 @@ FullNodeImpl::FullNodeImpl(PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id , keyring_(keyring) , adnl_(adnl) , rldp_(rldp) + , rldp2_(rldp2) , dht_(dht) , overlays_(overlays) , validator_manager_(validator_manager) , client_(client) - , db_root_(db_root) { + , db_root_(db_root) + , config_(config) { add_shard(ShardIdFull{masterchainId}); } td::actor::ActorOwn FullNode::create(ton::PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id, - FileHash zero_state_file_hash, + FileHash zero_state_file_hash, FullNodeConfig config, td::actor::ActorId keyring, td::actor::ActorId adnl, td::actor::ActorId rldp, - td::actor::ActorId dht, + td::actor::ActorId rldp2, td::actor::ActorId dht, td::actor::ActorId overlays, td::actor::ActorId validator_manager, td::actor::ActorId client, std::string db_root) { - return td::actor::create_actor("fullnode", local_id, adnl_id, zero_state_file_hash, keyring, adnl, rldp, - dht, overlays, validator_manager, client, db_root); + return td::actor::create_actor("fullnode", local_id, adnl_id, zero_state_file_hash, config, keyring, + adnl, rldp, rldp2, dht, overlays, validator_manager, client, db_root); +} + +FullNodeConfig::FullNodeConfig(const tl_object_ptr &obj) + : ext_messages_broadcast_disabled_(obj->ext_messages_broadcast_disabled_) { +} + +tl_object_ptr FullNodeConfig::tl() const { + return create_tl_object(ext_messages_broadcast_disabled_); +} +bool FullNodeConfig::operator==(const FullNodeConfig &rhs) const { + return ext_messages_broadcast_disabled_ == rhs.ext_messages_broadcast_disabled_; +} +bool FullNodeConfig::operator!=(const FullNodeConfig &rhs) const { + return !(*this == rhs); } } // namespace fullnode diff --git a/validator/full-node.h b/validator/full-node.h index cdf39d6f..15d54b55 100644 --- a/validator/full-node.h +++ b/validator/full-node.h @@ -27,6 +27,7 @@ #include "adnl/adnl.h" #include "rldp/rldp.h" +#include "rldp2/rldp.h" #include "dht/dht.h" #include "overlay/overlays.h" #include "validator/validator.h" @@ -44,6 +45,16 @@ constexpr int VERBOSITY_NAME(FULL_NODE_INFO) = verbosity_DEBUG; constexpr int VERBOSITY_NAME(FULL_NODE_DEBUG) = verbosity_DEBUG; constexpr int VERBOSITY_NAME(FULL_NODE_EXTRA_DEBUG) = verbosity_DEBUG + 1; +struct FullNodeConfig { + FullNodeConfig() = default; + FullNodeConfig(const tl_object_ptr& obj); + tl_object_ptr tl() const; + bool operator==(const FullNodeConfig& rhs) const; + bool operator!=(const FullNodeConfig& rhs) const; + + bool ext_messages_broadcast_disabled_ = false; +}; + class FullNode : public td::actor::Actor { public: virtual ~FullNode() = default; @@ -61,6 +72,7 @@ class FullNode : public td::actor::Actor { td::Promise promise) = 0; virtual void update_adnl_id(adnl::AdnlNodeIdShort adnl_id, td::Promise promise) = 0; + virtual void set_config(FullNodeConfig config) = 0; static constexpr td::uint32 max_block_size() { return 4 << 20; @@ -73,10 +85,10 @@ class FullNode : public td::actor::Actor { } static td::actor::ActorOwn create(ton::PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id, - FileHash zero_state_file_hash, + FileHash zero_state_file_hash, FullNodeConfig config, td::actor::ActorId keyring, td::actor::ActorId adnl, td::actor::ActorId rldp, - td::actor::ActorId dht, + td::actor::ActorId rldp2, td::actor::ActorId dht, td::actor::ActorId overlays, td::actor::ActorId validator_manager, td::actor::ActorId client, std::string db_root); diff --git a/validator/full-node.hpp b/validator/full-node.hpp index 6d57f4a8..fc2dd75c 100644 --- a/validator/full-node.hpp +++ b/validator/full-node.hpp @@ -49,8 +49,8 @@ class FullNodeImpl : public FullNode { std::shared_ptr cert, td::Promise promise) override; - void update_adnl_id(adnl::AdnlNodeIdShort adnl_id, td::Promise promise) override; + void set_config(FullNodeConfig config) override; void add_shard(ShardIdFull shard); void del_shard(ShardIdFull shard); @@ -82,9 +82,9 @@ class FullNodeImpl : public FullNode { void start_up() override; FullNodeImpl(PublicKeyHash local_id, adnl::AdnlNodeIdShort adnl_id, FileHash zero_state_file_hash, - td::actor::ActorId keyring, td::actor::ActorId adnl, - td::actor::ActorId rldp, td::actor::ActorId dht, - td::actor::ActorId overlays, + FullNodeConfig config, td::actor::ActorId keyring, td::actor::ActorId adnl, + td::actor::ActorId rldp, td::actor::ActorId rldp2, + td::actor::ActorId dht, td::actor::ActorId overlays, td::actor::ActorId validator_manager, td::actor::ActorId client, std::string db_root); @@ -101,6 +101,7 @@ class FullNodeImpl : public FullNode { td::actor::ActorId keyring_; td::actor::ActorId adnl_; td::actor::ActorId rldp_; + td::actor::ActorId rldp2_; td::actor::ActorId dht_; td::actor::ActorId overlays_; td::actor::ActorId validator_manager_; @@ -112,6 +113,7 @@ class FullNodeImpl : public FullNode { std::vector all_validators_; std::set local_keys_; + FullNodeConfig config_; }; } // namespace fullnode diff --git a/validator/net/download-archive-slice.cpp b/validator/net/download-archive-slice.cpp index e3acb4ba..6235b8b0 100644 --- a/validator/net/download-archive-slice.cpp +++ b/validator/net/download-archive-slice.cpp @@ -29,7 +29,7 @@ namespace fullnode { DownloadArchiveSlice::DownloadArchiveSlice( BlockSeqno masterchain_seqno, std::string tmp_dir, adnl::AdnlNodeIdShort local_id, overlay::OverlayIdShort overlay_id, adnl::AdnlNodeIdShort download_from, td::Timestamp timeout, - td::actor::ActorId validator_manager, td::actor::ActorId rldp, + td::actor::ActorId validator_manager, td::actor::ActorId rldp, td::actor::ActorId overlays, td::actor::ActorId adnl, td::actor::ActorId client, td::Promise promise) : masterchain_seqno_(masterchain_seqno) @@ -144,6 +144,8 @@ void DownloadArchiveSlice::got_archive_info(td::BufferSlice data) { return; } + prev_logged_timer_ = td::Timer(); + LOG(INFO) << "downloading archive slice #" << masterchain_seqno_ << " from " << download_from_; get_archive_slice(); } @@ -159,12 +161,12 @@ void DownloadArchiveSlice::get_archive_slice() { auto q = create_serialize_tl_object(archive_id_, offset_, slice_size()); if (client_.empty()) { td::actor::send_closure(overlays_, &overlay::Overlays::send_query_via, download_from_, local_id_, overlay_id_, - "get_archive_slice", std::move(P), td::Timestamp::in(3.0), std::move(q), + "get_archive_slice", std::move(P), td::Timestamp::in(15.0), std::move(q), slice_size() + 1024, rldp_); } else { td::actor::send_closure(client_, &adnl::AdnlExtClient::send_query, "get_archive_slice", create_serialize_tl_object_suffix(std::move(q)), - td::Timestamp::in(1.0), std::move(P)); + td::Timestamp::in(15.0), std::move(P)); } } @@ -181,7 +183,16 @@ void DownloadArchiveSlice::got_archive_slice(td::BufferSlice data) { offset_ += data.size(); + double elapsed = prev_logged_timer_.elapsed(); + if (elapsed > 10.0) { + prev_logged_timer_ = td::Timer(); + LOG(INFO) << "downloading archive slice #" << masterchain_seqno_ << ": total=" << offset_ << " (" + << td::format::as_size((td::uint64)(double(offset_ - prev_logged_sum_) / elapsed)) << "/s)"; + prev_logged_sum_ = offset_; + } + if (data.size() < slice_size()) { + LOG(INFO) << "finished downloading arcrive slice #" << masterchain_seqno_ << ": total=" << offset_; finish_query(); } else { get_archive_slice(); diff --git a/validator/net/download-archive-slice.hpp b/validator/net/download-archive-slice.hpp index 6ef11d1a..0384ac8c 100644 --- a/validator/net/download-archive-slice.hpp +++ b/validator/net/download-archive-slice.hpp @@ -21,7 +21,6 @@ #include "overlay/overlays.h" #include "ton/ton-types.h" #include "validator/validator.h" -#include "rldp/rldp.h" #include "adnl/adnl-ext-client.h" #include "td/utils/port/FileFd.h" @@ -36,9 +35,9 @@ class DownloadArchiveSlice : public td::actor::Actor { DownloadArchiveSlice(BlockSeqno masterchain_seqno, std::string tmp_dir, adnl::AdnlNodeIdShort local_id, overlay::OverlayIdShort overlay_id, adnl::AdnlNodeIdShort download_from, td::Timestamp timeout, td::actor::ActorId validator_manager, - td::actor::ActorId rldp, td::actor::ActorId overlays, - td::actor::ActorId adnl, td::actor::ActorId client, - td::Promise promise); + td::actor::ActorId rldp, + td::actor::ActorId overlays, td::actor::ActorId adnl, + td::actor::ActorId client, td::Promise promise); void abort_query(td::Status reason); void alarm() override; @@ -51,7 +50,7 @@ class DownloadArchiveSlice : public td::actor::Actor { void got_archive_slice(td::BufferSlice data); static constexpr td::uint32 slice_size() { - return 1 << 17; + return 1 << 21; } private: @@ -68,11 +67,14 @@ class DownloadArchiveSlice : public td::actor::Actor { td::Timestamp timeout_; td::actor::ActorId validator_manager_; - td::actor::ActorId rldp_; + td::actor::ActorId rldp_; td::actor::ActorId overlays_; td::actor::ActorId adnl_; td::actor::ActorId client_; td::Promise promise_; + + td::uint64 prev_logged_sum_ = 0; + td::Timer prev_logged_timer_; }; } // namespace fullnode diff --git a/validator/net/download-block-new.cpp b/validator/net/download-block-new.cpp index ef5ed7e5..14754f64 100644 --- a/validator/net/download-block-new.cpp +++ b/validator/net/download-block-new.cpp @@ -201,12 +201,12 @@ void DownloadBlockNew::got_node_to_download(adnl::AdnlNodeIdShort node) { } if (client_.empty()) { td::actor::send_closure(overlays_, &overlay::Overlays::send_query_via, download_from_, local_id_, overlay_id_, - "get_proof", std::move(P), td::Timestamp::in(3.0), std::move(q), + "get_proof", std::move(P), td::Timestamp::in(15.0), std::move(q), FullNode::max_proof_size() + FullNode::max_block_size() + 128, rldp_); } else { td::actor::send_closure(client_, &adnl::AdnlExtClient::send_query, "get_prepare", create_serialize_tl_object_suffix(std::move(q)), - td::Timestamp::in(1.0), std::move(P)); + td::Timestamp::in(15.0), std::move(P)); } } diff --git a/validator/net/download-block.cpp b/validator/net/download-block.cpp index 5e7c0be9..9ca84be2 100644 --- a/validator/net/download-block.cpp +++ b/validator/net/download-block.cpp @@ -373,12 +373,12 @@ void DownloadBlock::got_block_data_description(td::BufferSlice data_description) auto q = create_serialize_tl_object(create_tl_block_id(block_id_)); if (client_.empty()) { td::actor::send_closure(overlays_, &overlay::Overlays::send_query_via, download_from_, local_id_, - overlay_id_, "get_block", std::move(P), td::Timestamp::in(3.0), std::move(q), + overlay_id_, "get_block", std::move(P), td::Timestamp::in(15.0), std::move(q), FullNode::max_block_size(), rldp_); } else { td::actor::send_closure(client_, &adnl::AdnlExtClient::send_query, "get_block", create_serialize_tl_object_suffix(std::move(q)), - td::Timestamp::in(3.0), std::move(P)); + td::Timestamp::in(15.0), std::move(P)); } }, [&](ton_api::tonNode_notFound &val) { diff --git a/validator/net/download-state.cpp b/validator/net/download-state.cpp index fedfaae8..2740ce41 100644 --- a/validator/net/download-state.cpp +++ b/validator/net/download-state.cpp @@ -32,9 +32,9 @@ DownloadState::DownloadState(BlockIdExt block_id, BlockIdExt masterchain_block_i overlay::OverlayIdShort overlay_id, adnl::AdnlNodeIdShort download_from, td::uint32 priority, td::Timestamp timeout, td::actor::ActorId validator_manager, - td::actor::ActorId rldp, td::actor::ActorId overlays, - td::actor::ActorId adnl, td::actor::ActorId client, - td::Promise promise) + td::actor::ActorId rldp, + td::actor::ActorId overlays, td::actor::ActorId adnl, + td::actor::ActorId client, td::Promise promise) : block_id_(block_id) , masterchain_block_id_(masterchain_block_id) , local_id_(local_id) @@ -115,7 +115,7 @@ void DownloadState::got_block_handle(BlockHandle handle) { void DownloadState::got_node_to_download(adnl::AdnlNodeIdShort node) { download_from_ = node; - LOG(INFO) << "downloading state " << block_id_ << " from " << download_from_; + LOG(INFO) << "downloading state " << block_id_.to_str() << " from " << download_from_; auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result R) mutable { if (R.is_error()) { @@ -192,8 +192,8 @@ void DownloadState::got_block_state_part(td::BufferSlice data, td::uint32 reques double elapsed = prev_logged_timer_.elapsed(); if (elapsed > 10.0) { prev_logged_timer_ = td::Timer(); - LOG(INFO) << "downloading state " << block_id_ << ": total=" << sum_ << - " (" << double(sum_ - prev_logged_sum_) / elapsed << " B/s)"; + LOG(INFO) << "downloading state " << block_id_.to_str() << ": total=" << sum_ << " (" + << td::format::as_size((td::uint64)(double(sum_ - prev_logged_sum_) / elapsed)) << "/s)"; prev_logged_sum_ = sum_; } @@ -210,7 +210,7 @@ void DownloadState::got_block_state_part(td::BufferSlice data, td::uint32 reques return; } - td::uint32 part_size = 1 << 18; + td::uint32 part_size = 1 << 21; auto P = td::PromiseCreator::lambda([SelfId = actor_id(this), part_size](td::Result R) { if (R.is_error()) { td::actor::send_closure(SelfId, &DownloadState::abort_query, R.move_as_error()); @@ -223,18 +223,18 @@ void DownloadState::got_block_state_part(td::BufferSlice data, td::uint32 reques create_tl_block_id(block_id_), create_tl_block_id(masterchain_block_id_), sum_, part_size); if (client_.empty()) { td::actor::send_closure(overlays_, &overlay::Overlays::send_query_via, download_from_, local_id_, overlay_id_, - "download state", std::move(P), td::Timestamp::in(10.0), std::move(query), + "download state", std::move(P), td::Timestamp::in(20.0), std::move(query), FullNode::max_state_size(), rldp_); } else { td::actor::send_closure(client_, &adnl::AdnlExtClient::send_query, "download state", create_serialize_tl_object_suffix(std::move(query)), - td::Timestamp::in(10.0), std::move(P)); + td::Timestamp::in(20.0), std::move(P)); } } void DownloadState::got_block_state(td::BufferSlice data) { state_ = std::move(data); - LOG(INFO) << "finished downloading state " << block_id_ << ": total=" << sum_; + LOG(INFO) << "finished downloading state " << block_id_.to_str() << ": total=" << sum_; finish_query(); } diff --git a/validator/net/download-state.hpp b/validator/net/download-state.hpp index a586f61f..7db1327f 100644 --- a/validator/net/download-state.hpp +++ b/validator/net/download-state.hpp @@ -21,7 +21,6 @@ #include "overlay/overlays.h" #include "ton/ton-types.h" #include "validator/validator.h" -#include "rldp/rldp.h" #include "adnl/adnl-ext-client.h" namespace ton { @@ -35,7 +34,7 @@ class DownloadState : public td::actor::Actor { DownloadState(BlockIdExt block_id, BlockIdExt masterchain_block_id, adnl::AdnlNodeIdShort local_id, overlay::OverlayIdShort overlay_id, adnl::AdnlNodeIdShort download_from, td::uint32 priority, td::Timestamp timeout, td::actor::ActorId validator_manager, - td::actor::ActorId rldp, td::actor::ActorId overlays, + td::actor::ActorId rldp, td::actor::ActorId overlays, td::actor::ActorId adnl, td::actor::ActorId client, td::Promise promise); @@ -62,7 +61,7 @@ class DownloadState : public td::actor::Actor { td::Timestamp timeout_; td::actor::ActorId validator_manager_; - td::actor::ActorId rldp_; + td::actor::ActorId rldp_; td::actor::ActorId overlays_; td::actor::ActorId adnl_; td::actor::ActorId client_; diff --git a/validator/state-serializer.cpp b/validator/state-serializer.cpp index 1bb932c6..4ac4fc70 100644 --- a/validator/state-serializer.cpp +++ b/validator/state-serializer.cpp @@ -148,7 +148,7 @@ void AsyncStateSerializer::next_iteration() { running_ = true; delay_action( [SelfId = actor_id(this), shard = shards_[next_idx_]]() { td::actor::send_closure(SelfId, &AsyncStateSerializer::request_shard_state, shard); }, - td::Timestamp::in(td::Random::fast(0, 4 * 3600))); + td::Timestamp::in(td::Random::fast(0, 1800))); return; } }