mirror of
https://github.com/ton-blockchain/ton
synced 2025-02-12 11:12:16 +00:00
Process VmVirtError in RunEmulator
This commit is contained in:
parent
b4f4aa3ca7
commit
34303ee8de
1 changed files with 64 additions and 58 deletions
|
@ -1875,72 +1875,78 @@ class RunEmulator : public td::actor::Actor {
|
|||
}
|
||||
|
||||
void inc() {
|
||||
if (stopped_ || ++count_ != 4) { // 4 -- block_id + mc_state_root + account_state + transactions
|
||||
if (stopped_ || ++count_ != 4) { // 4 -- block_id + mc_state_root + account_state + transactions
|
||||
return;
|
||||
}
|
||||
|
||||
auto r_config = block::ConfigInfo::extract_config(mc_state_root_, 0b11'11111111);
|
||||
if (r_config.is_error()) {
|
||||
check(r_config.move_as_error());
|
||||
return;
|
||||
}
|
||||
std::unique_ptr<block::ConfigInfo> config = r_config.move_as_ok();
|
||||
try {
|
||||
auto r_config = block::ConfigInfo::extract_config(mc_state_root_, 0b11'11111111);
|
||||
if (r_config.is_error()) {
|
||||
check(r_config.move_as_error());
|
||||
return;
|
||||
}
|
||||
std::unique_ptr<block::ConfigInfo> config = r_config.move_as_ok();
|
||||
|
||||
block::gen::ShardStateUnsplit::Record shard_state;
|
||||
if (!tlb::unpack_cell(mc_state_root_, shard_state)) {
|
||||
check(td::Status::Error("Failed to unpack masterchain state"));
|
||||
return;
|
||||
}
|
||||
vm::Dictionary libraries(shard_state.r1.libraries->prefetch_ref(), 256);
|
||||
block::gen::ShardStateUnsplit::Record shard_state;
|
||||
if (!tlb::unpack_cell(mc_state_root_, shard_state)) {
|
||||
check(td::Status::Error("Failed to unpack masterchain state"));
|
||||
return;
|
||||
}
|
||||
vm::Dictionary libraries(shard_state.r1.libraries->prefetch_ref(), 256);
|
||||
|
||||
auto r_shard_account = account_state_->to_shardAccountCellSlice();
|
||||
if (r_shard_account.is_error()) {
|
||||
check(r_shard_account.move_as_error());
|
||||
return;
|
||||
}
|
||||
td::Ref<vm::CellSlice> shard_account = r_shard_account.move_as_ok();
|
||||
auto r_shard_account = account_state_->to_shardAccountCellSlice();
|
||||
if (r_shard_account.is_error()) {
|
||||
check(r_shard_account.move_as_error());
|
||||
return;
|
||||
}
|
||||
td::Ref<vm::CellSlice> shard_account = r_shard_account.move_as_ok();
|
||||
|
||||
const block::StdAddress& address = account_state_->get_address();
|
||||
ton::UnixTime now = account_state_->get_sync_time();
|
||||
bool is_special = address.workchain == ton::masterchainId && config->is_special_smartcontract(address.addr);
|
||||
block::Account account(address.workchain, address.addr.bits());
|
||||
if (!account.unpack(std::move(shard_account), td::Ref<vm::CellSlice>(), now, is_special)) {
|
||||
check(td::Status::Error("Can't unpack shard account"));
|
||||
return;
|
||||
}
|
||||
|
||||
auto prev_blocks_info = config->get_prev_blocks_info();
|
||||
if (prev_blocks_info.is_error()) {
|
||||
check(prev_blocks_info.move_as_error());
|
||||
return;
|
||||
}
|
||||
emulator::TransactionEmulator trans_emulator(std::move(*config));
|
||||
trans_emulator.set_prev_blocks_info(prev_blocks_info.move_as_ok());
|
||||
trans_emulator.set_libs(std::move(libraries));
|
||||
trans_emulator.set_rand_seed(block_id_.rand_seed);
|
||||
td::Result<emulator::TransactionEmulator::EmulationChain> emulation_result = trans_emulator.emulate_transactions_chain(std::move(account), std::move(transactions_));
|
||||
|
||||
if (emulation_result.is_error()) {
|
||||
promise_.set_error(emulation_result.move_as_error());
|
||||
} else {
|
||||
account = std::move(emulation_result.move_as_ok().account);
|
||||
RawAccountState raw = std::move(account_state_->raw());
|
||||
raw.block_id = block_id_.id;
|
||||
raw.balance = account.get_balance().grams->to_long();
|
||||
raw.storage_last_paid = std::move(account.last_paid);
|
||||
raw.storage_stat = std::move(account.storage_stat);
|
||||
raw.code = std::move(account.code);
|
||||
raw.data = std::move(account.data);
|
||||
raw.state = std::move(account.total_state);
|
||||
raw.info.last_trans_lt = account.last_trans_lt_;
|
||||
raw.info.last_trans_hash = account.last_trans_hash_;
|
||||
raw.info.gen_utime = account.now_;
|
||||
|
||||
if (account.status == block::Account::acc_frozen) {
|
||||
raw.frozen_hash = (char*)account.state_hash.data();
|
||||
const block::StdAddress& address = account_state_->get_address();
|
||||
ton::UnixTime now = account_state_->get_sync_time();
|
||||
bool is_special = address.workchain == ton::masterchainId && config->is_special_smartcontract(address.addr);
|
||||
block::Account account(address.workchain, address.addr.bits());
|
||||
if (!account.unpack(std::move(shard_account), td::Ref<vm::CellSlice>(), now, is_special)) {
|
||||
check(td::Status::Error("Can't unpack shard account"));
|
||||
return;
|
||||
}
|
||||
|
||||
promise_.set_value(td::make_unique<AccountState>(address, std::move(raw), 0));
|
||||
auto prev_blocks_info = config->get_prev_blocks_info();
|
||||
if (prev_blocks_info.is_error()) {
|
||||
check(prev_blocks_info.move_as_error());
|
||||
return;
|
||||
}
|
||||
emulator::TransactionEmulator trans_emulator(std::move(*config));
|
||||
trans_emulator.set_prev_blocks_info(prev_blocks_info.move_as_ok());
|
||||
trans_emulator.set_libs(std::move(libraries));
|
||||
trans_emulator.set_rand_seed(block_id_.rand_seed);
|
||||
td::Result<emulator::TransactionEmulator::EmulationChain> emulation_result =
|
||||
trans_emulator.emulate_transactions_chain(std::move(account), std::move(transactions_));
|
||||
|
||||
if (emulation_result.is_error()) {
|
||||
promise_.set_error(emulation_result.move_as_error());
|
||||
} else {
|
||||
account = std::move(emulation_result.move_as_ok().account);
|
||||
RawAccountState raw = std::move(account_state_->raw());
|
||||
raw.block_id = block_id_.id;
|
||||
raw.balance = account.get_balance().grams->to_long();
|
||||
raw.storage_last_paid = std::move(account.last_paid);
|
||||
raw.storage_stat = std::move(account.storage_stat);
|
||||
raw.code = std::move(account.code);
|
||||
raw.data = std::move(account.data);
|
||||
raw.state = std::move(account.total_state);
|
||||
raw.info.last_trans_lt = account.last_trans_lt_;
|
||||
raw.info.last_trans_hash = account.last_trans_hash_;
|
||||
raw.info.gen_utime = account.now_;
|
||||
|
||||
if (account.status == block::Account::acc_frozen) {
|
||||
raw.frozen_hash = (char*)account.state_hash.data();
|
||||
}
|
||||
|
||||
promise_.set_value(td::make_unique<AccountState>(address, std::move(raw), 0));
|
||||
}
|
||||
} catch (vm::VmVirtError& err) {
|
||||
check(td::Status::Error(PSLICE() << "virtualization error while emulating transaction: " << err.get_msg()));
|
||||
return;
|
||||
}
|
||||
stopped_ = true;
|
||||
try_stop();
|
||||
|
|
Loading…
Reference in a new issue