1
0
Fork 0
mirror of https://github.com/ton-blockchain/ton synced 2025-03-09 15:40:10 +00:00

Simplify loading virtual states from collated data, fix message queue cleanup

This commit is contained in:
SpyCheese 2025-01-27 11:49:18 +03:00
parent 54e498a3ba
commit 0763691f70
5 changed files with 45 additions and 75 deletions

View file

@ -1243,10 +1243,21 @@ bool ValidateQuery::check_this_shard_mc_info() {
* @returns True if the previous state is computed successfully, false otherwise.
*/
bool ValidateQuery::compute_prev_state() {
if (!is_masterchain() && full_collated_data_) {
return compute_prev_state_from_collated_data();
}
CHECK(prev_states.size() == 1u + after_merge_);
CHECK(prev_states.size() == prev_blocks.size());
if (!is_masterchain() && full_collated_data_) {
for (size_t i = 0; i < prev_states.size(); i++) {
Ref<vm::Cell> root = get_virt_state_root(prev_blocks[i]);
if (root.is_null()) {
return reject_query(PSTRING() << "cannot get previous state from collated data: " << prev_blocks[i].to_str());
}
auto r_state = create_shard_state(prev_blocks[i], std::move(root));
if (r_state.is_error()) {
return reject_query("failed to parse previous state from collated data", r_state.move_as_error());
}
prev_states[i] = r_state.move_as_ok();
}
}
// Extend validator timeout if previous block is too old
UnixTime prev_ts = prev_states[0]->get_unix_time();
if (after_merge_) {
@ -1274,46 +1285,6 @@ bool ValidateQuery::compute_prev_state() {
return true;
}
bool ValidateQuery::compute_prev_state_from_collated_data() {
td::Bits256 state_hash;
if (id_.seqno() == 1) {
if (prev_blocks.size() != 1) {
return reject_query("seqno is 1, but number of previous blocks is not 1");
}
state_hash = prev_blocks[0].root_hash;
} else {
std::vector<Ref<vm::Cell>> prev_state_roots(prev_blocks.size());
for (size_t i = 0; i < prev_blocks.size(); ++i) {
prev_state_roots[i] = get_virt_state_root(prev_blocks[i].root_hash);
if (prev_state_roots[i].is_null()) {
return reject_query(PSTRING() << "cannot get hash of previous state root: " << prev_blocks[i]);
}
}
if (prev_state_roots.size() == 1) {
state_hash = prev_state_roots[0]->get_hash().bits();
} else {
CHECK(prev_state_roots.size() == 2);
Ref<vm::Cell> merged;
if (!block::gen::t_ShardState.cell_pack_split_state(merged, prev_state_roots[0], prev_state_roots[1])) {
return fatal_error(-667, "cannot construct mechanically merged previously state");
}
state_hash = merged->get_hash().bits();
}
}
if (state_hash != prev_state_hash_) {
return reject_query("previous state hash mismatch for block "s + id_.to_str() + " : block header declares " +
prev_state_hash_.to_hex() + " , actual " + state_hash.to_hex());
}
auto it = virt_roots_.find(state_hash);
if (it == virt_roots_.end()) {
return reject_query(PSTRING() << "no state root for previous block in collated data (hash = "
<< state_hash.to_hex() << ")");
}
prev_state_root_ = it->second;
return true;
}
/**
* Computes the next shard state using the previous state and the block's Merkle update.
*/
@ -1574,21 +1545,11 @@ bool ValidateQuery::request_neighbor_queues() {
++i;
continue;
}
td::Bits256 state_root_hash;
if (descr.blk_.seqno() == 0) {
state_root_hash = descr.blk_.root_hash;
} else {
Ref<vm::Cell> state_root = get_virt_state_root(descr.blk_.root_hash);
if (state_root.is_null()) {
return reject_query(PSTRING() << "cannot get hash of state root: " << descr.blk_);
}
state_root_hash = state_root->get_hash().bits();
auto state_root = get_virt_state_root(descr.blk_);
if (state_root.is_null()) {
return reject_query(PSTRING() << "cannot get state root form collated data: " << descr.blk_.to_str());
}
auto it = virt_roots_.find(state_root_hash);
if (it == virt_roots_.end()) {
return reject_query(PSTRING() << "cannot get state root form collated data: " << descr.blk_);
}
auto state = ShardStateQ::fetch(descr.blk_, {}, it->second);
auto state = ShardStateQ::fetch(descr.blk_, {}, std::move(state_root));
if (state.is_error()) {
return reject_query("cannot fetch shard state from collated data", state.move_as_error());
}
@ -6898,22 +6859,23 @@ bool ValidateQuery::postcheck_value_flow() {
return true;
}
Ref<vm::Cell> ValidateQuery::get_virt_state_root(td::Bits256 block_root_hash) {
auto it = virt_roots_.find(block_root_hash);
Ref<vm::Cell> ValidateQuery::get_virt_state_root(const BlockIdExt& block_id) {
auto it = virt_roots_.find(block_id.root_hash);
if (it == virt_roots_.end()) {
return {};
}
Ref<vm::Cell> root = it->second;
if (block_id.seqno() == 0) {
return root;
}
block::gen::Block::Record block;
if (!tlb::unpack_cell(root, block)) {
return {};
}
vm::CellSlice upd_cs{vm::NoVmSpec(), block.state_update};
if (!(upd_cs.is_special() && upd_cs.prefetch_long(8) == 4 // merkle update
&& upd_cs.size_ext() == 0x20228)) {
return {};
}
return vm::MerkleProof::virtualize_raw(upd_cs.prefetch_ref(1), {0, 1});
td::Bits256 state_root_hash = upd_cs.prefetch_ref(1)->get_hash(0).bits();
it = virt_roots_.find(state_root_hash);
return it == virt_roots_.end() ? Ref<vm::Cell>{} : it->second;
}
/**