mirror of
https://github.com/ton-blockchain/ton
synced 2025-02-12 19:22:37 +00:00
Merge pull request #528 from SpyCheese/optimize-collator
Optimize calculation of storage stat, add logs to transaction.cpp
This commit is contained in:
commit
0686c08d57
2 changed files with 46 additions and 3 deletions
|
@ -24,6 +24,7 @@
|
|||
#include "td/utils/uint128.h"
|
||||
#include "ton/ton-shard.h"
|
||||
#include "vm/vm.h"
|
||||
#include "td/utils/Timer.h"
|
||||
|
||||
namespace {
|
||||
class StringLoggerTail : public td::LogInterface {
|
||||
|
@ -345,7 +346,7 @@ bool Account::unpack(Ref<vm::CellSlice> shard_account, Ref<vm::CellSlice> extra,
|
|||
block::gen::AccountStorage::Record storage;
|
||||
if (!(tlb::unpack_exact(acc_cs, acc) && (my_addr = acc.addr).not_null() && unpack_address(acc.addr.write()) &&
|
||||
compute_my_addr() && unpack_storage_info(acc.storage_stat.write()) &&
|
||||
tlb::csr_unpack(std::move(acc.storage), storage) &&
|
||||
tlb::csr_unpack(this->storage = std::move(acc.storage), storage) &&
|
||||
std::max(storage.last_trans_lt, 1ULL) > acc_info.last_trans_lt && balance.unpack(std::move(storage.balance)))) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1049,7 +1050,9 @@ bool Transaction::prepare_compute_phase(const ComputePhaseConfig& cfg) {
|
|||
|
||||
LOG(DEBUG) << "starting VM";
|
||||
cp.vm_init_state_hash = vm.get_state_hash();
|
||||
td::Timer timer;
|
||||
cp.exit_code = ~vm.run();
|
||||
double elapsed = timer.elapsed();
|
||||
LOG(DEBUG) << "VM terminated with exit code " << cp.exit_code;
|
||||
cp.out_of_gas = (cp.exit_code == ~(int)vm::Excno::out_of_gas);
|
||||
cp.vm_final_state_hash = vm.get_final_state_hash(cp.exit_code);
|
||||
|
@ -1065,7 +1068,8 @@ bool Transaction::prepare_compute_phase(const ComputePhaseConfig& cfg) {
|
|||
}
|
||||
LOG(INFO) << "steps: " << vm.get_steps_count() << " gas: used=" << gas.gas_consumed() << ", max=" << gas.gas_max
|
||||
<< ", limit=" << gas.gas_limit << ", credit=" << gas.gas_credit;
|
||||
LOG(INFO) << "out_of_gas=" << cp.out_of_gas << ", accepted=" << cp.accepted << ", success=" << cp.success;
|
||||
LOG(INFO) << "out_of_gas=" << cp.out_of_gas << ", accepted=" << cp.accepted << ", success=" << cp.success
|
||||
<< ", time=" << elapsed << "s";
|
||||
if (logger != nullptr) {
|
||||
cp.vm_log = logger->get_log();
|
||||
}
|
||||
|
@ -1930,6 +1934,32 @@ bool Account::store_acc_status(vm::CellBuilder& cb, int acc_status) const {
|
|||
return cb.store_long_bool(v, 2);
|
||||
}
|
||||
|
||||
static td::optional<vm::CellStorageStat> try_update_storage_stat(const vm::CellStorageStat& old_stat,
|
||||
td::Ref<vm::CellSlice> old_cs,
|
||||
td::Ref<vm::Cell> new_cell) {
|
||||
if (old_stat.cells == 0 || old_cs.is_null()) {
|
||||
return {};
|
||||
}
|
||||
vm::CellSlice new_cs = vm::CellSlice(vm::NoVm(), new_cell);
|
||||
if (old_cs->size_refs() != new_cs.size_refs()) {
|
||||
return {};
|
||||
}
|
||||
for (unsigned i = 0; i < old_cs->size_refs(); ++i) {
|
||||
if (old_cs->prefetch_ref(i)->get_hash() != new_cs.prefetch_ref(i)->get_hash()) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
if (old_stat.bits < old_cs->size()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
vm::CellStorageStat new_stat;
|
||||
new_stat.cells = old_stat.cells;
|
||||
new_stat.bits = old_stat.bits - old_cs->size() + new_cs.size();
|
||||
new_stat.public_cells = old_stat.public_cells;
|
||||
return new_stat;
|
||||
}
|
||||
|
||||
bool Transaction::compute_state() {
|
||||
if (new_total_state.not_null()) {
|
||||
return true;
|
||||
|
@ -1991,6 +2021,7 @@ bool Transaction::compute_state() {
|
|||
// code:(Maybe ^Cell) data:(Maybe ^Cell) library:(HashmapE 256 SimpleLib)
|
||||
}
|
||||
auto storage = cb.finalize();
|
||||
new_storage = td::Ref<vm::CellSlice>(true, vm::NoVm(), storage);
|
||||
if (si_pos) {
|
||||
auto cs_ref = load_cell_slice_ref(storage);
|
||||
CHECK(cs_ref.unique_write().skip_ext(si_pos));
|
||||
|
@ -1999,7 +2030,16 @@ bool Transaction::compute_state() {
|
|||
new_inner_state.clear();
|
||||
}
|
||||
vm::CellStorageStat& stats = new_storage_stat;
|
||||
CHECK(stats.compute_used_storage(Ref<vm::Cell>(storage)));
|
||||
auto new_stats = try_update_storage_stat(account.storage_stat, account.storage, storage);
|
||||
if (new_stats) {
|
||||
stats = new_stats.unwrap();
|
||||
} else {
|
||||
td::Timer timer;
|
||||
CHECK(stats.compute_used_storage(Ref<vm::Cell>(storage)));
|
||||
if (timer.elapsed() > 0.1) {
|
||||
LOG(INFO) << "Compute used storage took " << timer.elapsed() << "s";
|
||||
}
|
||||
}
|
||||
CHECK(cb.store_long_bool(1, 1) // account$1
|
||||
&& cb.append_cellslice_bool(account.my_addr) // addr:MsgAddressInt
|
||||
&& block::store_UInt7(cb, stats.cells) // storage_used$_ cells:(VarUInteger 7)
|
||||
|
@ -2308,6 +2348,7 @@ Ref<vm::Cell> Transaction::commit(Account& acc) {
|
|||
acc.last_trans_hash_ = root->get_hash().bits();
|
||||
acc.last_paid = last_paid;
|
||||
acc.storage_stat = new_storage_stat;
|
||||
acc.storage = new_storage;
|
||||
acc.balance = std::move(balance);
|
||||
acc.due_payment = std::move(due_payment);
|
||||
acc.total_state = std::move(new_total_state);
|
||||
|
|
|
@ -237,6 +237,7 @@ struct Account {
|
|||
td::RefInt256 due_payment;
|
||||
Ref<vm::Cell> orig_total_state; // ^Account
|
||||
Ref<vm::Cell> total_state; // ^Account
|
||||
Ref<vm::CellSlice> storage; // AccountStorage
|
||||
Ref<vm::CellSlice> inner_state; // StateInit
|
||||
ton::Bits256 state_hash; // hash of StateInit for frozen accounts
|
||||
Ref<vm::Cell> code, data, library, orig_library;
|
||||
|
@ -324,6 +325,7 @@ struct Transaction {
|
|||
ton::UnixTime last_paid;
|
||||
Ref<vm::Cell> root;
|
||||
Ref<vm::Cell> new_total_state;
|
||||
Ref<vm::CellSlice> new_storage;
|
||||
Ref<vm::CellSlice> new_inner_state;
|
||||
Ref<vm::Cell> new_code, new_data, new_library;
|
||||
Ref<vm::Cell> in_msg, in_msg_state;
|
||||
|
|
Loading…
Reference in a new issue