@@ -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 */
10771077bool 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