diff --git a/crypto/block/transaction.cpp b/crypto/block/transaction.cpp index 3b2334d6..0620c823 100644 --- a/crypto/block/transaction.cpp +++ b/crypto/block/transaction.cpp @@ -2265,9 +2265,15 @@ bool Transaction::would_fit(unsigned cls, const block::BlockLimitStatus& blimst) return blimst.would_fit(cls, end_lt, gas_used(), &extra); } -bool Transaction::update_limits(block::BlockLimitStatus& blimst) const { - return blimst.update_lt(end_lt) && blimst.update_gas(gas_used()) && blimst.add_proof(new_total_state) && - blimst.add_cell(root) && blimst.add_transaction() && blimst.add_account(is_first); +bool Transaction::update_limits(block::BlockLimitStatus& blimst, bool with_size) const { + if (!(blimst.update_lt(end_lt) && blimst.update_gas(gas_used()))) { + return false; + } + if (with_size) { + return blimst.add_proof(new_total_state) && blimst.add_cell(root) && blimst.add_transaction() && + blimst.add_account(is_first); + } + return true; } /* diff --git a/crypto/block/transaction.h b/crypto/block/transaction.h index 75762260..2c4f4175 100644 --- a/crypto/block/transaction.h +++ b/crypto/block/transaction.h @@ -359,7 +359,7 @@ struct Transaction { const vm::NewCellStorageStat& store_stat, const vm::CellUsageTree* usage_tree) const; bool update_block_storage_profile(vm::NewCellStorageStat& store_stat, const vm::CellUsageTree* usage_tree) const; bool would_fit(unsigned cls, const block::BlockLimitStatus& blk_lim_st) const; - bool update_limits(block::BlockLimitStatus& blk_lim_st) const; + bool update_limits(block::BlockLimitStatus& blk_lim_st, bool with_size = true) const; Ref commit(Account& _account); // _account should point to the same account LtCellRef extract_out_msg(unsigned i); diff --git a/validator/impl/collator-impl.h b/validator/impl/collator-impl.h index 1c9faa58..c13049cf 100644 --- a/validator/impl/collator-impl.h +++ b/validator/impl/collator-impl.h @@ -73,6 +73,7 @@ class Collator final : public td::actor::Actor { Ref validator_set_; td::actor::ActorId manager; td::Timestamp timeout; + td::Timestamp soft_timeout_, medium_timeout_; td::Promise main_promise; ton::BlockSeqno last_block_seqno{0}; ton::BlockSeqno prev_mc_block_seqno{0}; diff --git a/validator/impl/collator.cpp b/validator/impl/collator.cpp index 84d75e88..07a827c2 100644 --- a/validator/impl/collator.cpp +++ b/validator/impl/collator.cpp @@ -67,6 +67,8 @@ Collator::Collator(ShardIdFull shard, bool is_hardfork, UnixTime min_ts, BlockId , validator_set_(std::move(validator_set)) , manager(manager) , timeout(timeout) + , soft_timeout_(td::Timestamp::at(timeout.at() - 3.0)) + , medium_timeout_(td::Timestamp::at(timeout.at() - 1.5)) , main_promise(std::move(promise)) , perf_timer_("collate", 0.1, [manager](double duration) { send_closure(manager, &ValidatorManager::add_perf_timer_stat, "collate", duration); @@ -2503,6 +2505,11 @@ int Collator::process_one_new_message(block::NewOutMsg msg, bool enqueue_only, R block_full_ = true; return 3; } + if (soft_timeout_.is_in_past(td::Timestamp::now())) { + LOG(WARNING) << "soft timeout reached, stop processing new messages"; + block_full_ = true; + return 3; + } return 1; } @@ -2767,6 +2774,11 @@ bool Collator::process_inbound_internal_messages() { LOG(INFO) << "BLOCK FULL, stop processing inbound internal messages"; break; } + if (soft_timeout_.is_in_past(td::Timestamp::now())) { + block_full_ = true; + LOG(WARNING) << "soft timeout reached, stop processing inbound internal messages"; + break; + } auto kv = nb_out_msgs_->extract_cur(); CHECK(kv && kv->msg.not_null()); LOG(DEBUG) << "processing inbound message with (lt,hash)=(" << kv->lt << "," << kv->key.to_hex() @@ -2800,6 +2812,10 @@ bool Collator::process_inbound_external_messages() { LOG(INFO) << "BLOCK FULL, stop processing external messages"; break; } + if (medium_timeout_.is_in_past(td::Timestamp::now())) { + LOG(WARNING) << "medium timeout reached, stop processing inbound external messages"; + break; + } auto ext_msg = ext_msg_pair.first; ton::Bits256 hash{ext_msg->get_hash().bits()}; int r = process_external_message(std::move(ext_msg)); diff --git a/validator/impl/validate-query.cpp b/validator/impl/validate-query.cpp index 0649473d..a6b4ebce 100644 --- a/validator/impl/validate-query.cpp +++ b/validator/impl/validate-query.cpp @@ -734,6 +734,8 @@ bool ValidateQuery::try_unpack_mc_state() { return fatal_error(limits.move_as_error()); } block_limits_ = limits.move_as_ok(); + block_limits_->start_lt = start_lt_; + block_limit_status_ = std::make_unique(*block_limits_); if (!fetch_config_params()) { return false; } @@ -4335,6 +4337,13 @@ bool ValidateQuery::check_one_transaction(block::Account& account, ton::LogicalT int trans_type = block::Transaction::tr_none; switch (tag) { case block::gen::TransactionDescr::trans_ord: { + if (!block_limit_status_->fits(block::ParamLimits::cl_medium)) { + return reject_query(PSTRING() << "cannod add ordinary transaction because hard block limits are exceeded: " + << "gas_used=" << block_limit_status_->gas_used + << "(limit=" << block_limits_->gas.hard() << "), " + << "lt_delta=" << block_limit_status_->cur_lt - block_limits_->start_lt + << "(limit=" << block_limits_->lt_delta.hard() << ")"); + } trans_type = block::Transaction::tr_ord; if (in_msg_root.is_null()) { return reject_query(PSTRING() << "ordinary transaction " << lt << " of account " << addr.to_hex() @@ -4480,7 +4489,7 @@ bool ValidateQuery::check_one_transaction(block::Account& account, ton::LogicalT return reject_query(PSTRING() << "cannot re-create the serialization of transaction " << lt << " for smart contract " << addr.to_hex()); } - if (block_limit_status_ && !trs->update_limits(*block_limit_status_)) { + if (!trs->update_limits(*block_limit_status_, false)) { return fatal_error(PSTRING() << "cannot update block limit status to include transaction " << lt << " of account " << addr.to_hex()); }