diff --git a/crypto/vm/db/DynamicBagOfCellsDb.cpp b/crypto/vm/db/DynamicBagOfCellsDb.cpp index 4ff4ec30..5441feea 100644 --- a/crypto/vm/db/DynamicBagOfCellsDb.cpp +++ b/crypto/vm/db/DynamicBagOfCellsDb.cpp @@ -293,7 +293,9 @@ class DynamicBagOfCellsDbImpl : public DynamicBagOfCellsDb, private ExtCellCreat return db_->load_cell(hash); } TRY_RESULT(load_result, cell_loader_->load(hash, true, *this)); - CHECK(load_result.status == CellLoader::LoadResult::Ok); + if (load_result.status != CellLoader::LoadResult::Ok) { + return td::Status::Error("cell not found"); + } return std::move(load_result.cell()); } diff --git a/validator/state-serializer.cpp b/validator/state-serializer.cpp index d5d2f000..1bb932c6 100644 --- a/validator/state-serializer.cpp +++ b/validator/state-serializer.cpp @@ -82,13 +82,22 @@ void AsyncStateSerializer::alarm() { } void AsyncStateSerializer::request_masterchain_state() { - auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result> R) { + auto P = td::PromiseCreator::lambda([SelfId = actor_id(this), manager = manager_](td::Result> R) { if (R.is_error()) { td::actor::send_closure(SelfId, &AsyncStateSerializer::fail_handler, R.move_as_error_prefix("failed to get masterchain state: ")); } else { - td::actor::send_closure(SelfId, &AsyncStateSerializer::got_masterchain_state, - td::Ref(R.move_as_ok())); + td::actor::send_closure(manager, &ValidatorManager::get_cell_db_reader, + [SelfId, state = td::Ref(R.move_as_ok())]( + td::Result> R) mutable { + if (R.is_error()) { + td::actor::send_closure(SelfId, &AsyncStateSerializer::fail_handler, + R.move_as_error_prefix("failed to get cell db reader: ")); + } else { + td::actor::send_closure(SelfId, &AsyncStateSerializer::got_masterchain_state, + std::move(state), R.move_as_ok()); + } + }); } }); td::actor::send_closure(manager_, &ValidatorManager::get_shard_state_from_db, masterchain_handle_, std::move(P)); @@ -122,26 +131,13 @@ void AsyncStateSerializer::next_iteration() { CHECK(masterchain_handle_->id() == last_block_id_); if (attempt_ < max_attempt() && last_key_block_id_.id.seqno < last_block_id_.id.seqno && need_serialize(masterchain_handle_)) { - if (!cell_db_reader_) { - running_ = true; - auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result> R) { - if (R.is_error()) { - td::actor::send_closure(SelfId, &AsyncStateSerializer::fail_handler, - R.move_as_error_prefix("failed to get cell db reader: ")); - } else { - td::actor::send_closure(SelfId, &AsyncStateSerializer::got_cell_db_reader, R.move_as_ok()); - } - }); - td::actor::send_closure(manager_, &ValidatorManager::get_cell_db_reader, std::move(P)); - return; - } if (!have_masterchain_state_) { LOG(INFO) << "started serializing persistent state for " << masterchain_handle_->id().id; // block next attempts immediately, but send actual request later running_ = true; - delay_action( - [SelfId = actor_id(this)]() { td::actor::send_closure(SelfId, &AsyncStateSerializer::request_masterchain_state); }, - td::Timestamp::in(td::Random::fast(0, 3600))); + delay_action([SelfId = actor_id( + this)]() { td::actor::send_closure(SelfId, &AsyncStateSerializer::request_masterchain_state); }, + td::Timestamp::in(td::Random::fast(0, 3600))); return; } while (next_idx_ < shards_.size()) { @@ -159,7 +155,6 @@ void AsyncStateSerializer::next_iteration() { LOG(INFO) << "finished serializing persistent state for " << masterchain_handle_->id().id; last_key_block_ts_ = masterchain_handle_->unix_time(); last_key_block_id_ = masterchain_handle_->id(); - cell_db_reader_ = nullptr; } if (!saved_to_db_) { running_ = true; @@ -189,13 +184,6 @@ void AsyncStateSerializer::got_top_masterchain_handle(BlockIdExt block_id) { } } -void AsyncStateSerializer::got_cell_db_reader(std::shared_ptr cell_db_reader) { - cell_db_reader_ = std::move(cell_db_reader); - running_ = false; - attempt_ = 0; - next_iteration(); -} - void AsyncStateSerializer::got_masterchain_handle(BlockHandle handle) { CHECK(!masterchain_handle_); masterchain_handle_ = std::move(handle); @@ -204,18 +192,19 @@ void AsyncStateSerializer::got_masterchain_handle(BlockHandle handle) { next_iteration(); } -void AsyncStateSerializer::got_masterchain_state(td::Ref state) { +void AsyncStateSerializer::got_masterchain_state(td::Ref state, + std::shared_ptr cell_db_reader) { LOG(INFO) << "serializing masterchain state " << masterchain_handle_->id().id; have_masterchain_state_ = true; CHECK(next_idx_ == 0); CHECK(shards_.size() == 0); auto vec = state->get_shards(); - for (auto &v : vec) { + for (auto& v : vec) { shards_.push_back(v->top_block_id()); } - auto write_data = [hash = state->root_cell()->get_hash(), cell_db_reader = cell_db_reader_] (td::FileFd& fd) { + auto write_data = [hash = state->root_cell()->get_hash(), cell_db_reader](td::FileFd& fd) { return vm::std_boc_serialize_to_file_large(cell_db_reader, hash, fd, 31); }; auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result R) { @@ -234,20 +223,32 @@ void AsyncStateSerializer::stored_masterchain_state() { } void AsyncStateSerializer::got_shard_handle(BlockHandle handle) { - auto P = td::PromiseCreator::lambda([SelfId = actor_id(this), handle](td::Result> R) { - if (R.is_error()) { - td::actor::send_closure(SelfId, &AsyncStateSerializer::fail_handler, R.move_as_error()); - } else { - td::actor::send_closure(SelfId, &AsyncStateSerializer::got_shard_state, handle, R.move_as_ok()); - } - }); + auto P = td::PromiseCreator::lambda( + [SelfId = actor_id(this), handle, manager = manager_](td::Result> R) { + if (R.is_error()) { + td::actor::send_closure(SelfId, &AsyncStateSerializer::fail_handler, R.move_as_error()); + } else { + td::actor::send_closure( + manager, &ValidatorManager::get_cell_db_reader, + [SelfId, state = R.move_as_ok(), handle](td::Result> R) mutable { + if (R.is_error()) { + td::actor::send_closure(SelfId, &AsyncStateSerializer::fail_handler, + R.move_as_error_prefix("failed to get cell db reader: ")); + } else { + td::actor::send_closure(SelfId, &AsyncStateSerializer::got_shard_state, handle, std::move(state), + R.move_as_ok()); + } + }); + } + }); td::actor::send_closure(manager_, &ValidatorManager::get_shard_state_from_db, handle, std::move(P)); } -void AsyncStateSerializer::got_shard_state(BlockHandle handle, td::Ref state) { +void AsyncStateSerializer::got_shard_state(BlockHandle handle, td::Ref state, + std::shared_ptr cell_db_reader) { LOG(INFO) << "serializing shard state " << handle->id().id; - auto write_data = [hash = state->root_cell()->get_hash(), cell_db_reader = cell_db_reader_] (td::FileFd& fd) { + auto write_data = [hash = state->root_cell()->get_hash(), cell_db_reader](td::FileFd& fd) { return vm::std_boc_serialize_to_file_large(cell_db_reader, hash, fd, 31); }; auto P = td::PromiseCreator::lambda([SelfId = actor_id(this), handle](td::Result R) { diff --git a/validator/state-serializer.hpp b/validator/state-serializer.hpp index e971a3f8..ee2aace0 100644 --- a/validator/state-serializer.hpp +++ b/validator/state-serializer.hpp @@ -42,7 +42,6 @@ class AsyncStateSerializer : public td::actor::Actor { td::uint32 next_idx_ = 0; - std::shared_ptr cell_db_reader_ = nullptr; BlockHandle masterchain_handle_; bool have_masterchain_state_ = false; @@ -71,12 +70,11 @@ class AsyncStateSerializer : public td::actor::Actor { void next_iteration(); void got_top_masterchain_handle(BlockIdExt block_id); - void got_cell_db_reader(std::shared_ptr cell_db_reader); void got_masterchain_handle(BlockHandle handle_); - void got_masterchain_state(td::Ref state); + void got_masterchain_state(td::Ref state, std::shared_ptr cell_db_reader); void stored_masterchain_state(); void got_shard_handle(BlockHandle handle); - void got_shard_state(BlockHandle handle, td::Ref state); + void got_shard_state(BlockHandle handle, td::Ref state, std::shared_ptr cell_db_reader); void get_masterchain_seqno(td::Promise promise) { promise.set_result(last_block_id_.id.seqno);