Skip to content

Commit 2ce2c8f

Browse files
authored
Count account_dict size in block size estimation (#1261)
* Count account_dict size in block size estimation * Fix updating account dict estimator
1 parent d04cdfa commit 2ce2c8f

File tree

3 files changed

+49
-3
lines changed

3 files changed

+49
-3
lines changed

crypto/block/block.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -719,8 +719,8 @@ td::uint64 BlockLimitStatus::estimate_block_size(const vm::NewCellStorageStat::S
719719
if (extra) {
720720
sum += *extra;
721721
}
722-
return 2000 + (sum.bits >> 3) + sum.cells * 12 + sum.internal_refs * 3 + sum.external_refs * 40 + accounts * 200 +
723-
transactions * 200 + (extra ? 200 : 0) + extra_out_msgs * 300 + public_library_diff * 700;
722+
return 2000 + (sum.bits >> 3) + sum.cells * 12 + sum.internal_refs * 3 + sum.external_refs * 40 + transactions * 200 +
723+
(extra ? 200 : 0) + extra_out_msgs * 300 + public_library_diff * 700;
724724
}
725725

726726
int BlockLimitStatus::classify() const {

validator/impl/collator-impl.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,10 @@ class Collator final : public td::actor::Actor {
220220
td::uint64 defer_out_queue_size_limit_;
221221
td::uint64 hard_defer_out_queue_size_limit_;
222222

223+
std::unique_ptr<vm::AugmentedDictionary> account_dict_estimator_;
224+
std::set<td::Bits256> account_dict_estimator_added_accounts_;
225+
unsigned account_dict_ops_{0};
226+
223227
bool msg_metadata_enabled_ = false;
224228
bool deferring_messages_enabled_ = false;
225229
bool store_out_msg_queue_size_ = false;
@@ -323,6 +327,7 @@ class Collator final : public td::actor::Actor {
323327
bool insert_out_msg(Ref<vm::Cell> out_msg, td::ConstBitPtr msg_hash);
324328
bool register_out_msg_queue_op(bool force = false);
325329
bool register_dispatch_queue_op(bool force = false);
330+
bool update_account_dict_estimation(const block::transaction::Transaction& trans);
326331
bool update_min_mc_seqno(ton::BlockSeqno some_mc_seqno);
327332
bool combine_account_transactions();
328333
bool update_public_libraries();

validator/impl/collator.cpp

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1064,7 +1064,7 @@ bool Collator::split_last_state(block::ShardState& ss) {
10641064
/**
10651065
* Imports the shard state data into the Collator object.
10661066
*
1067-
* SETS: account_dict, shard_libraries_, mc_state_extra
1067+
* SETS: account_dict = account_dict_estimator_, shard_libraries_, mc_state_extra
10681068
* total_balance_ = old_total_balance_, total_validator_fees_
10691069
* SETS: overload_history_, underload_history_
10701070
* SETS: prev_state_utime_, prev_state_lt_, prev_vert_seqno_
@@ -1076,6 +1076,7 @@ bool Collator::split_last_state(block::ShardState& ss) {
10761076
*/
10771077
bool Collator::import_shard_state_data(block::ShardState& ss) {
10781078
account_dict = std::move(ss.account_dict_);
1079+
account_dict_estimator_ = std::make_unique<vm::AugmentedDictionary>(*account_dict);
10791080
shard_libraries_ = std::move(ss.shard_libraries_);
10801081
mc_state_extra_ = std::move(ss.mc_state_extra_);
10811082
overload_history_ = ss.overload_history_;
@@ -2742,6 +2743,9 @@ bool Collator::create_ticktock_transaction(const ton::StdSmcAddress& smc_addr, t
27422743
return fatal_error(
27432744
td::Status::Error(-666, std::string{"cannot commit new transaction for smart contract "} + smc_addr.to_hex()));
27442745
}
2746+
if (!update_account_dict_estimation(*trans)) {
2747+
return fatal_error(-666, "cannot update account dict size estimation");
2748+
}
27452749
update_max_lt(acc->last_trans_end_lt_);
27462750
block::MsgMetadata new_msg_metadata{0, acc->workchain, acc->addr, trans->start_lt};
27472751
register_new_msgs(*trans, std::move(new_msg_metadata));
@@ -2835,6 +2839,10 @@ Ref<vm::Cell> Collator::create_ordinary_transaction(Ref<vm::Cell> msg_root,
28352839
fatal_error("cannot commit new transaction for smart contract "s + addr.to_hex());
28362840
return {};
28372841
}
2842+
if (!update_account_dict_estimation(*trans)) {
2843+
fatal_error("cannot update account dict size estimation");
2844+
return {};
2845+
}
28382846

28392847
td::optional<block::MsgMetadata> new_msg_metadata;
28402848
if (external || is_special_tx) {
@@ -5038,6 +5046,39 @@ bool Collator::register_dispatch_queue_op(bool force) {
50385046
}
50395047
}
50405048

5049+
/**
5050+
* Update size estimation for the account dictionary.
5051+
* This is required to count the depth of the ShardAccounts dictionary in the block size estimation.
5052+
* account_dict_estimator_ is used for block limits only.
5053+
*
5054+
* @param trans Newly-created transaction.
5055+
*
5056+
* @returns True on success, false otherwise.
5057+
*/
5058+
bool Collator::update_account_dict_estimation(const block::transaction::Transaction& trans) {
5059+
const block::Account& acc = trans.account;
5060+
if (acc.orig_total_state->get_hash() != acc.total_state->get_hash() &&
5061+
account_dict_estimator_added_accounts_.insert(acc.addr).second) {
5062+
// see combine_account_transactions
5063+
if (acc.status == block::Account::acc_nonexist) {
5064+
account_dict_estimator_->lookup_delete(acc.addr);
5065+
} else {
5066+
vm::CellBuilder cb;
5067+
if (!(cb.store_ref_bool(acc.total_state) // account_descr$_ account:^Account
5068+
&& cb.store_bits_bool(acc.last_trans_hash_) // last_trans_hash:bits256
5069+
&& cb.store_long_bool(acc.last_trans_lt_, 64) // last_trans_lt:uint64
5070+
&& account_dict_estimator_->set_builder(acc.addr, cb))) {
5071+
return false;
5072+
}
5073+
}
5074+
}
5075+
++account_dict_ops_;
5076+
if (!(account_dict_ops_ & 15)) {
5077+
return block_limit_status_->add_proof(account_dict_estimator_->get_root_cell());
5078+
}
5079+
return true;
5080+
}
5081+
50415082
/**
50425083
* Creates a new shard state and the Merkle update.
50435084
*

0 commit comments

Comments
 (0)