mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
Change recursion to loop in CellSlice
This commit is contained in:
parent
5baf3276a4
commit
bb5bc6178c
3 changed files with 38 additions and 41 deletions
|
@ -327,8 +327,7 @@ bool Account::unpack(Ref<vm::CellSlice> shard_account, Ref<vm::CellSlice> extra,
|
||||||
block::gen::t_ShardAccount.print(std::cerr, *shard_account);
|
block::gen::t_ShardAccount.print(std::cerr, *shard_account);
|
||||||
}
|
}
|
||||||
block::gen::ShardAccount::Record acc_info;
|
block::gen::ShardAccount::Record acc_info;
|
||||||
if (!(block::gen::t_ShardAccount.validate_csr(shard_account) &&
|
if (!(block::tlb::t_ShardAccount.validate_csr(shard_account) && tlb::unpack_exact(shard_account.write(), acc_info))) {
|
||||||
block::tlb::t_ShardAccount.validate_csr(shard_account) && tlb::unpack_exact(shard_account.write(), acc_info))) {
|
|
||||||
LOG(ERROR) << "account " << addr.to_hex() << " state is invalid";
|
LOG(ERROR) << "account " << addr.to_hex() << " state is invalid";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2013,7 +2012,6 @@ bool Transaction::compute_state() {
|
||||||
std::cerr << "new account state: ";
|
std::cerr << "new account state: ";
|
||||||
block::gen::t_Account.print_ref(std::cerr, new_total_state);
|
block::gen::t_Account.print_ref(std::cerr, new_total_state);
|
||||||
}
|
}
|
||||||
CHECK(block::gen::t_Account.validate_ref(new_total_state));
|
|
||||||
CHECK(block::tlb::t_Account.validate_ref(new_total_state));
|
CHECK(block::tlb::t_Account.validate_ref(new_total_state));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1055,44 +1055,47 @@ std::ostream& operator<<(std::ostream& os, Ref<CellSlice> cs_ref) {
|
||||||
|
|
||||||
// If can_be_special is not null, then it is allowed to load special cell
|
// If can_be_special is not null, then it is allowed to load special cell
|
||||||
// Flag whether loaded cell is actually special will be stored into can_be_special
|
// Flag whether loaded cell is actually special will be stored into can_be_special
|
||||||
VirtualCell::LoadedCell load_cell_slice_impl(const Ref<Cell>& cell, bool* can_be_special) {
|
VirtualCell::LoadedCell load_cell_slice_impl(Ref<Cell> cell, bool* can_be_special) {
|
||||||
auto* vm_state_interface = VmStateInterface::get();
|
while (true) {
|
||||||
if (vm_state_interface) {
|
auto* vm_state_interface = VmStateInterface::get();
|
||||||
vm_state_interface->register_cell_load(cell->get_hash());
|
if (vm_state_interface) {
|
||||||
}
|
vm_state_interface->register_cell_load(cell->get_hash());
|
||||||
auto r_loaded_cell = cell->load_cell();
|
|
||||||
if (r_loaded_cell.is_error()) {
|
|
||||||
throw VmError{Excno::cell_und, "failed to load cell"};
|
|
||||||
}
|
|
||||||
auto loaded_cell = r_loaded_cell.move_as_ok();
|
|
||||||
if (loaded_cell.data_cell->special_type() == DataCell::SpecialType::PrunnedBranch) {
|
|
||||||
auto virtualization = loaded_cell.virt.get_virtualization();
|
|
||||||
if (virtualization != 0) {
|
|
||||||
throw VmVirtError{virtualization};
|
|
||||||
}
|
}
|
||||||
}
|
auto r_loaded_cell = cell->load_cell();
|
||||||
if (can_be_special) {
|
if (r_loaded_cell.is_error()) {
|
||||||
*can_be_special = loaded_cell.data_cell->is_special();
|
throw VmError{Excno::cell_und, "failed to load cell"};
|
||||||
} else if (loaded_cell.data_cell->is_special()) {
|
}
|
||||||
if (loaded_cell.data_cell->special_type() == DataCell::SpecialType::Library) {
|
auto loaded_cell = r_loaded_cell.move_as_ok();
|
||||||
if (vm_state_interface) {
|
if (loaded_cell.data_cell->special_type() == DataCell::SpecialType::PrunnedBranch) {
|
||||||
CellSlice cs(std::move(loaded_cell));
|
auto virtualization = loaded_cell.virt.get_virtualization();
|
||||||
DCHECK(cs.size() == Cell::hash_bits + 8);
|
if (virtualization != 0) {
|
||||||
auto library_cell = vm_state_interface->load_library(cs.data_bits() + 8);
|
throw VmVirtError{virtualization};
|
||||||
if (library_cell.not_null()) {
|
|
||||||
//TODO: fix infinity loop
|
|
||||||
return load_cell_slice_impl(library_cell, nullptr);
|
|
||||||
}
|
|
||||||
throw VmError{Excno::cell_und, "failed to load library cell"};
|
|
||||||
}
|
}
|
||||||
throw VmError{Excno::cell_und, "failed to load library cell (no vm_state_interface available)"};
|
|
||||||
} else if (loaded_cell.data_cell->special_type() == DataCell::SpecialType::PrunnedBranch) {
|
|
||||||
CHECK(loaded_cell.virt.get_virtualization() == 0);
|
|
||||||
throw VmError{Excno::cell_und, "trying to load prunned cell"};
|
|
||||||
}
|
}
|
||||||
throw VmError{Excno::cell_und, "unexpected special cell"};
|
if (can_be_special) {
|
||||||
|
*can_be_special = loaded_cell.data_cell->is_special();
|
||||||
|
} else if (loaded_cell.data_cell->is_special()) {
|
||||||
|
if (loaded_cell.data_cell->special_type() == DataCell::SpecialType::Library) {
|
||||||
|
if (vm_state_interface) {
|
||||||
|
CellSlice cs(std::move(loaded_cell));
|
||||||
|
DCHECK(cs.size() == Cell::hash_bits + 8);
|
||||||
|
auto library_cell = vm_state_interface->load_library(cs.data_bits() + 8);
|
||||||
|
if (library_cell.not_null()) {
|
||||||
|
cell = library_cell;
|
||||||
|
can_be_special = nullptr;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
throw VmError{Excno::cell_und, "failed to load library cell"};
|
||||||
|
}
|
||||||
|
throw VmError{Excno::cell_und, "failed to load library cell (no vm_state_interface available)"};
|
||||||
|
} else if (loaded_cell.data_cell->special_type() == DataCell::SpecialType::PrunnedBranch) {
|
||||||
|
CHECK(loaded_cell.virt.get_virtualization() == 0);
|
||||||
|
throw VmError{Excno::cell_und, "trying to load prunned cell"};
|
||||||
|
}
|
||||||
|
throw VmError{Excno::cell_und, "unexpected special cell"};
|
||||||
|
}
|
||||||
|
return loaded_cell;
|
||||||
}
|
}
|
||||||
return loaded_cell;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CellSlice load_cell_slice(const Ref<Cell>& cell) {
|
CellSlice load_cell_slice(const Ref<Cell>& cell) {
|
||||||
|
|
|
@ -2313,10 +2313,6 @@ bool ValidateQuery::precheck_one_account_update(td::ConstBitPtr acc_id, Ref<vm::
|
||||||
"AccountBlock for this account");
|
"AccountBlock for this account");
|
||||||
}
|
}
|
||||||
if (new_value.not_null()) {
|
if (new_value.not_null()) {
|
||||||
if (!block::gen::t_ShardAccount.validate_csr(10000, new_value)) {
|
|
||||||
return reject_query("new state of account "s + acc_id.to_hex(256) +
|
|
||||||
" failed to pass automated validity checks for ShardAccount");
|
|
||||||
}
|
|
||||||
if (!block::tlb::t_ShardAccount.validate_csr(10000, new_value)) {
|
if (!block::tlb::t_ShardAccount.validate_csr(10000, new_value)) {
|
||||||
return reject_query("new state of account "s + acc_id.to_hex(256) +
|
return reject_query("new state of account "s + acc_id.to_hex(256) +
|
||||||
" failed to pass hand-written validity checks for ShardAccount");
|
" failed to pass hand-written validity checks for ShardAccount");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue