Skip to content

Commit

Permalink
Fix handling small out-of-sync in validate-query
Browse files Browse the repository at this point in the history
  • Loading branch information
SpyCheese committed Jan 13, 2025
1 parent cae9ccf commit 87c4b4a
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 30 deletions.
5 changes: 3 additions & 2 deletions validator/downloaders/wait-block-state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ void WaitBlockState::start() {
if (reading_from_db_) {
return;
}
if (handle_->received_state()) {
bool inited_proof = handle_->id().is_masterchain() ? handle_->inited_proof() : handle_->inited_proof_link();
if (handle_->received_state() && inited_proof) {
reading_from_db_ = true;

auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Ref<ShardState>> R) {
Expand Down Expand Up @@ -107,7 +108,7 @@ void WaitBlockState::start() {
});
td::actor::send_closure(manager_, &ValidatorManager::send_get_zero_state_request, handle_->id(), priority_,
std::move(P));
} else if (check_persistent_state_desc()) {
} else if (check_persistent_state_desc() && !handle_->received_state()) {
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Ref<ShardState>> R) {
if (R.is_error()) {
LOG(WARNING) << "failed to get persistent state: " << R.move_as_error();
Expand Down
59 changes: 32 additions & 27 deletions validator/impl/validate-query.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -346,16 +346,7 @@ void ValidateQuery::start_up() {
// return;
}
}
// 2. learn latest masterchain state and block id
LOG(DEBUG) << "sending get_top_masterchain_state_block() to Manager";
++pending;
td::actor::send_closure_later(manager, &ValidatorManager::get_top_masterchain_state_block,
[self = get_self()](td::Result<std::pair<Ref<MasterchainState>, BlockIdExt>> res) {
LOG(DEBUG) << "got answer to get_top_masterchain_state_block";
td::actor::send_closure_later(
std::move(self), &ValidateQuery::after_get_latest_mc_state, std::move(res));
});
// 3. load state(s) corresponding to previous block(s)
// 2. load state(s) corresponding to previous block(s)
prev_states.resize(prev_blocks.size());
for (int i = 0; (unsigned)i < prev_blocks.size(); i++) {
// 3.1. load state
Expand All @@ -368,21 +359,13 @@ void ValidateQuery::start_up() {
std::move(self), &ValidateQuery::after_get_shard_state, i, std::move(res));
});
}
// 4. unpack block candidate (while necessary data is being loaded)
// 3. unpack block candidate (while necessary data is being loaded)
if (!unpack_block_candidate()) {
reject_query("error unpacking block candidate");
return;
}
// 5. request masterchain state referred to in the block
// 4. request masterchain handle and state referred to in the block
if (!is_masterchain()) {
++pending;
td::actor::send_closure_later(manager, &ValidatorManager::wait_block_state_short, mc_blkid_, priority(), timeout,
[self = get_self()](td::Result<Ref<ShardState>> res) {
LOG(DEBUG) << "got answer to wait_block_state() query for masterchain block";
td::actor::send_closure_later(std::move(self), &ValidateQuery::after_get_mc_state,
std::move(res));
});
// 5.1. request corresponding block handle
++pending;
td::actor::send_closure_later(manager, &ValidatorManager::get_block_handle, mc_blkid_, true,
[self = get_self()](td::Result<BlockHandle> res) {
Expand Down Expand Up @@ -663,6 +646,19 @@ bool ValidateQuery::extract_collated_data() {
return true;
}

/**
* Send get_top_masterchain_state_block to manager, call after_get_latest_mc_state afterwards
*/
void ValidateQuery::request_latest_mc_state() {
++pending;
td::actor::send_closure_later(manager, &ValidatorManager::get_top_masterchain_state_block,
[self = get_self()](td::Result<std::pair<Ref<MasterchainState>, BlockIdExt>> res) {
LOG(DEBUG) << "got answer to get_top_masterchain_state_block";
td::actor::send_closure_later(
std::move(self), &ValidateQuery::after_get_latest_mc_state, std::move(res));
});
}

/**
* Callback function called after retrieving the latest masterchain state.
*
Expand Down Expand Up @@ -710,6 +706,7 @@ void ValidateQuery::after_get_latest_mc_state(td::Result<std::pair<Ref<Mastercha
* @param res The result of the masterchain state retrieval.
*/
void ValidateQuery::after_get_mc_state(td::Result<Ref<ShardState>> res) {
CHECK(!is_masterchain());
LOG(WARNING) << "in ValidateQuery::after_get_mc_state() for " << mc_blkid_.to_str();
--pending;
if (res.is_error()) {
Expand All @@ -720,6 +717,7 @@ void ValidateQuery::after_get_mc_state(td::Result<Ref<ShardState>> res) {
fatal_error("cannot process masterchain state for "s + mc_blkid_.to_str());
return;
}
request_latest_mc_state();
if (!pending) {
if (!try_validate()) {
fatal_error("cannot validate new block");
Expand All @@ -734,17 +732,21 @@ void ValidateQuery::after_get_mc_state(td::Result<Ref<ShardState>> res) {
*/
void ValidateQuery::got_mc_handle(td::Result<BlockHandle> res) {
LOG(DEBUG) << "in ValidateQuery::got_mc_handle() for " << mc_blkid_.to_str();
--pending;
if (res.is_error()) {
fatal_error(res.move_as_error());
return;
}
auto handle = res.move_as_ok();
if (!handle->inited_proof() && mc_blkid_.seqno()) {
fatal_error(-666, "reference masterchain block "s + mc_blkid_.to_str() + " for block " + id_.to_str() +
" does not have a valid proof");
return;
}
auto mc_handle = res.move_as_ok();
td::actor::send_closure_later(
manager, &ValidatorManager::wait_block_state, mc_handle, priority(), timeout,
[self = get_self(), id = id_, mc_handle](td::Result<Ref<ShardState>> res) {
LOG(DEBUG) << "got answer to wait_block_state() query for masterchain block";
if (res.is_ok() && mc_handle->id().seqno() > 0 && !mc_handle->inited_proof()) {
res = td::Status::Error(-666, "reference masterchain block "s + mc_handle->id().to_str() + " for block " +
id.to_str() + " does not have a valid proof");
}
td::actor::send_closure_later(std::move(self), &ValidateQuery::after_get_mc_state, std::move(res));
});
}

/**
Expand Down Expand Up @@ -778,6 +780,9 @@ void ValidateQuery::after_get_shard_state(int idx, td::Result<Ref<ShardState>> r
return;
}
}
if (is_masterchain()) {
request_latest_mc_state();
}
if (!pending) {
if (!try_validate()) {
fatal_error("cannot validate new block");
Expand Down
1 change: 1 addition & 0 deletions validator/impl/validate-query.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@ class ValidateQuery : public td::actor::Actor {
return actor_id(this);
}

void request_latest_mc_state();
void after_get_latest_mc_state(td::Result<std::pair<Ref<MasterchainState>, BlockIdExt>> res);
void after_get_mc_state(td::Result<Ref<ShardState>> res);
void got_mc_handle(td::Result<BlockHandle> res);
Expand Down
2 changes: 1 addition & 1 deletion validator/manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1343,7 +1343,7 @@ void ValidatorManagerImpl::written_handle(BlockHandle handle, td::Promise<td::Un
td::actor::send_closure(it->second.actor_, &WaitBlockData::force_read_from_db);
}
}
if (inited_state) {
if (inited_state && inited_proof) {
auto it = wait_state_.find(handle->id());
if (it != wait_state_.end()) {
td::actor::send_closure(it->second.actor_, &WaitBlockState::force_read_from_db);
Expand Down

0 comments on commit 87c4b4a

Please sign in to comment.