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

Add account state by transaction and emulator (extended) (#592)

* account_state_by_transaction

* Correct time calculation

* Bug fixes

* Refactor

* namespace block::transaction

* smc.forget

* RunEmulator: remove wallet_id

* Refactor & fixes

* AccountStateByTransaction: use shardchain block instead of masterchain block

* transaction emulator core

* refactor

* tx emulator major functionality

* small format changes

* readme

* clean

* return json, add support for init messages

* tx emulator readme

* refactor getConfigParam and getConfigAll

* add shardchain_libs_boc parameter

* option to change verbosity level of transaction emulator

* fix deserializing ShardAccount with account_none

* add mode needSpecialSmc when unpack config

* emulator: block::Transaction -> block::transaction::Transaction

* Refactor

* emulator: Fix bug

* emulator: Support for emulator-extern

* emulator: Refactor

* Return vm log and vm exit code.

* fix build on macos, emulator_static added

* adjust documentation

* ignore_chksig for external messages

* tvm emulator, run get method

* Added more params for transaction emulator

* Added setters for optional transaction emulator params, moved libs to a new setter

* Added actions cell output to transaction emulator

* fix tonlib build

* refactoring, rand seed as hex size 64, tvm emulator send message

* tvm send message, small refactoring

* fix config decoding, rename

* improve documentation

* macos export symbols

* Added run_get_method to transaction emulator emscipten wrapper

* Fixed empty action list serialization

* Changed actions list cell to serialize as json null instead of empty string in transaction emulator

* stack as boc

* log gas remaining

* Fix prev_block_id

* fix build errors

* Refactor fetch_config_params

* fix failing unwrap of optional rand_seed

* lookup correct shard, choose prev_block based on account shard

* fix tonlib android jni build

---------

Co-authored-by: legaii <jgates.ardux@gmail.com>
Co-authored-by: ms <dungeon666master@protonmail.com>
Co-authored-by: krigga <krigga7@gmail.com>
This commit is contained in:
EmelyanenkoK 2023-02-02 10:03:45 +03:00 committed by GitHub
parent adf67aa869
commit 3b3c25b654
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
32 changed files with 2095 additions and 158 deletions

View file

@ -20,6 +20,7 @@
#include "block/block.h"
#include "block/block-parse.h"
#include "block/block-auto.h"
#include "crypto/openssl/rand.hpp"
#include "td/utils/bits.h"
#include "td/utils/uint128.h"
#include "ton/ton-shard.h"
@ -513,6 +514,7 @@ td::RefInt256 Account::compute_storage_fees(ton::UnixTime now, const std::vector
return StoragePrices::compute_storage_fees(now, pricing, storage_stat, last_paid, is_special, is_masterchain());
}
namespace transaction {
Transaction::Transaction(const Account& _account, int ttype, ton::LogicalTime req_start_lt, ton::UnixTime _now,
Ref<vm::Cell> _inmsg)
: trans_type(ttype)
@ -745,6 +747,7 @@ bool Transaction::prepare_credit_phase() {
total_fees += std::move(collected);
return true;
}
} // namespace transaction
bool ComputePhaseConfig::parse_GasLimitsPrices(Ref<vm::Cell> cell, td::RefInt256& freeze_due_limit,
td::RefInt256& delete_due_limit) {
@ -837,6 +840,7 @@ td::RefInt256 ComputePhaseConfig::compute_gas_price(td::uint64 gas_used) const {
: td::rshift(gas_price256 * (gas_used - flat_gas_limit), 16, 1) + flat_gas_price;
}
namespace transaction {
bool Transaction::compute_gas_limits(ComputePhase& cp, const ComputePhaseConfig& cfg) {
// Compute gas limits
if (account.is_special) {
@ -1057,13 +1061,21 @@ bool Transaction::prepare_compute_phase(const ComputePhaseConfig& cfg) {
std::unique_ptr<StringLoggerTail> logger;
auto vm_log = vm::VmLog();
if (cfg.with_vm_log) {
logger = std::make_unique<StringLoggerTail>();
size_t log_max_size = cfg.vm_log_verbosity > 0 ? 1024 * 1024 : 256;
logger = std::make_unique<StringLoggerTail>(log_max_size);
vm_log.log_interface = logger.get();
vm_log.log_options = td::LogOptions(VERBOSITY_NAME(DEBUG), true, false);
if (cfg.vm_log_verbosity > 1) {
vm_log.log_mask |= vm::VmLog::ExecLocation;
if (cfg.vm_log_verbosity > 2) {
vm_log.log_mask |= vm::VmLog::DumpStack | vm::VmLog::GasRemaining;
}
}
}
vm::VmState vm{new_code, std::move(stack), gas, 1, new_data, vm_log, compute_vm_libraries(cfg)};
vm.set_max_data_depth(cfg.max_vm_data_depth);
vm.set_c7(prepare_vm_c7(cfg)); // tuple with SmartContractInfo
vm.set_chksig_always_succeed(cfg.ignore_chksig);
// vm.incr_stack_trace(1); // enable stack dump after each step
LOG(DEBUG) << "starting VM";
@ -1338,6 +1350,7 @@ int Transaction::try_action_change_library(vm::CellSlice& cs, ActionPhase& ap, c
ap.spec_actions++;
return 0;
}
} // namespace transaction
// msg_fwd_fees = (lump_price + ceil((bit_price * msg.bits + cell_price * msg.cells)/2^16)) nanograms
// ihr_fwd_fees = ceil((msg_fwd_fees * ihr_price_factor)/2^16) nanograms
@ -1372,6 +1385,7 @@ td::RefInt256 MsgPrices::get_next_part(td::RefInt256 total) const {
return (std::move(total) * next_frac) >> 16;
}
namespace transaction {
bool Transaction::check_replace_src_addr(Ref<vm::CellSlice>& src_addr) const {
int t = (int)src_addr->prefetch_ulong(2);
if (!t && src_addr->size_ext() == 2) {
@ -1978,6 +1992,7 @@ bool Transaction::prepare_bounce_phase(const ActionPhaseConfig& cfg) {
bp.ok = true;
return true;
}
} // namespace transaction
/*
*
@ -2033,6 +2048,7 @@ static td::optional<vm::CellStorageStat> try_update_storage_stat(const vm::CellS
return new_stat;
}
namespace transaction {
bool Transaction::compute_state() {
if (new_total_state.not_null()) {
return true;
@ -2460,6 +2476,7 @@ void Transaction::extract_out_msgs(std::vector<LtCellRef>& list) {
list.emplace_back(start_lt + i + 1, std::move(out_msgs[i]));
}
}
} // namespace transaction
void Account::push_transaction(Ref<vm::Cell> trans_root, ton::LogicalTime trans_lt) {
transactions.emplace_back(trans_lt, std::move(trans_root));
@ -2503,4 +2520,82 @@ bool Account::libraries_changed() const {
}
}
td::Status FetchConfigParams::fetch_config_params(const block::Config& config,
Ref<vm::Cell>* old_mparams,
std::vector<block::StoragePrices>* storage_prices,
block::StoragePhaseConfig* storage_phase_cfg,
td::BitArray<256>* rand_seed,
block::ComputePhaseConfig* compute_phase_cfg,
block::ActionPhaseConfig* action_phase_cfg,
td::RefInt256* masterchain_create_fee,
td::RefInt256* basechain_create_fee,
ton::WorkchainId wc,
ton::UnixTime now) {
*old_mparams = config.get_config_param(9);
{
auto res = config.get_storage_prices();
if (res.is_error()) {
return res.move_as_error();
}
*storage_prices = res.move_as_ok();
}
if (rand_seed->is_zero()) {
// generate rand seed
prng::rand_gen().strong_rand_bytes(rand_seed->data(), 32);
LOG(DEBUG) << "block random seed set to " << rand_seed->to_hex();
}
TRY_RESULT(size_limits, config.get_size_limits_config());
{
// compute compute_phase_cfg / storage_phase_cfg
auto cell = config.get_config_param(wc == ton::masterchainId ? 20 : 21);
if (cell.is_null()) {
return td::Status::Error(-668, "cannot fetch current gas prices and limits from masterchain configuration");
}
if (!compute_phase_cfg->parse_GasLimitsPrices(std::move(cell), storage_phase_cfg->freeze_due_limit,
storage_phase_cfg->delete_due_limit)) {
return td::Status::Error(-668, "cannot unpack current gas prices and limits from masterchain configuration");
}
compute_phase_cfg->block_rand_seed = *rand_seed;
compute_phase_cfg->max_vm_data_depth = size_limits.max_vm_data_depth;
compute_phase_cfg->global_config = config.get_root_cell();
compute_phase_cfg->suspended_addresses = config.get_suspended_addresses(now);
}
{
// compute action_phase_cfg
block::gen::MsgForwardPrices::Record rec;
auto cell = config.get_config_param(24);
if (cell.is_null() || !tlb::unpack_cell(std::move(cell), rec)) {
return td::Status::Error(-668, "cannot fetch masterchain message transfer prices from masterchain configuration");
}
action_phase_cfg->fwd_mc =
block::MsgPrices{rec.lump_price, rec.bit_price, rec.cell_price, rec.ihr_price_factor,
(unsigned)rec.first_frac, (unsigned)rec.next_frac};
cell = config.get_config_param(25);
if (cell.is_null() || !tlb::unpack_cell(std::move(cell), rec)) {
return td::Status::Error(-668, "cannot fetch standard message transfer prices from masterchain configuration");
}
action_phase_cfg->fwd_std =
block::MsgPrices{rec.lump_price, rec.bit_price, rec.cell_price, rec.ihr_price_factor,
(unsigned)rec.first_frac, (unsigned)rec.next_frac};
action_phase_cfg->workchains = &config.get_workchain_list();
action_phase_cfg->bounce_msg_body = (config.has_capability(ton::capBounceMsgBody) ? 256 : 0);
action_phase_cfg->size_limits = size_limits;
}
{
// fetch block_grams_created
auto cell = config.get_config_param(14);
if (cell.is_null()) {
*basechain_create_fee = *masterchain_create_fee = td::zero_refint();
} else {
block::gen::BlockCreateFees::Record create_fees;
if (!(tlb::unpack_cell(cell, create_fees) &&
block::tlb::t_Grams.as_integer_to(create_fees.masterchain_block_fee, *masterchain_create_fee) &&
block::tlb::t_Grams.as_integer_to(create_fees.basechain_block_fee, *basechain_create_fee))) {
return td::Status::Error(-668, "cannot unpack BlockCreateFees from configuration parameter #14");
}
}
}
return td::Status::OK();
}
} // namespace block