mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
Count gas usage for ordinar transactions on special accounts in separate counter (#872)
* Improve checking total gas usage in collator and validator --------- Co-authored-by: SpyCheese <mikle98@yandex.ru>
This commit is contained in:
parent
d91643face
commit
2e231ec2ff
4 changed files with 28 additions and 13 deletions
|
@ -244,7 +244,7 @@ class Collator final : public td::actor::Actor {
|
|||
Ref<vm::Cell>& in_msg);
|
||||
bool create_ticktock_transactions(int mask);
|
||||
bool create_ticktock_transaction(const ton::StdSmcAddress& smc_addr, ton::LogicalTime req_start_lt, int mask);
|
||||
Ref<vm::Cell> create_ordinary_transaction(Ref<vm::Cell> msg_root);
|
||||
Ref<vm::Cell> create_ordinary_transaction(Ref<vm::Cell> msg_root, bool is_special_tx = false);
|
||||
bool check_cur_validator_set();
|
||||
bool unpack_last_mc_state();
|
||||
bool unpack_last_state();
|
||||
|
|
|
@ -2667,8 +2667,7 @@ bool Collator::create_ticktock_transaction(const ton::StdSmcAddress& smc_addr, t
|
|||
return fatal_error(td::Status::Error(
|
||||
-666, std::string{"cannot serialize new transaction for smart contract "} + smc_addr.to_hex()));
|
||||
}
|
||||
if (!trans->update_limits(*block_limit_status_,
|
||||
/* with_gas = */ !(acc->is_special && compute_phase_cfg_.special_gas_full))) {
|
||||
if (!trans->update_limits(*block_limit_status_, /* with_gas = */ false)) {
|
||||
return fatal_error(-666, "cannot update block limit status to include the new transaction");
|
||||
}
|
||||
if (trans->commit(*acc).is_null()) {
|
||||
|
@ -2684,10 +2683,11 @@ bool Collator::create_ticktock_transaction(const ton::StdSmcAddress& smc_addr, t
|
|||
* Creates an ordinary transaction using a given message.
|
||||
*
|
||||
* @param msg_root The root of the message to be processed serialized using Message TLB-scheme.
|
||||
* @param is_special_tx True if creating a special transaction (mint/recover), false otherwise.
|
||||
*
|
||||
* @returns The root of the serialized transaction, or an empty reference if the transaction creation fails.
|
||||
*/
|
||||
Ref<vm::Cell> Collator::create_ordinary_transaction(Ref<vm::Cell> msg_root) {
|
||||
Ref<vm::Cell> Collator::create_ordinary_transaction(Ref<vm::Cell> msg_root, bool is_special_tx) {
|
||||
ton::StdSmcAddress addr;
|
||||
auto cs = vm::load_cell_slice(msg_root);
|
||||
bool external;
|
||||
|
@ -2746,7 +2746,7 @@ Ref<vm::Cell> Collator::create_ordinary_transaction(Ref<vm::Cell> msg_root) {
|
|||
std::unique_ptr<block::transaction::Transaction> trans = res.move_as_ok();
|
||||
|
||||
if (!trans->update_limits(*block_limit_status_,
|
||||
/* with_gas = */ !(acc->is_special && compute_phase_cfg_.special_gas_full))) {
|
||||
/* with_gas = */ !(is_special_tx && compute_phase_cfg_.special_gas_full))) {
|
||||
fatal_error("cannot update block limit status to include the new transaction");
|
||||
return {};
|
||||
}
|
||||
|
@ -3019,7 +3019,7 @@ int Collator::process_one_new_message(block::NewOutMsg msg, bool enqueue_only, R
|
|||
return -1;
|
||||
}
|
||||
// 1. create a Transaction processing this Message
|
||||
auto trans_root = create_ordinary_transaction(msg.msg);
|
||||
auto trans_root = create_ordinary_transaction(msg.msg, is_special != nullptr);
|
||||
if (trans_root.is_null()) {
|
||||
fatal_error("cannot create transaction for re-processing output message");
|
||||
return -1;
|
||||
|
|
|
@ -4685,6 +4685,7 @@ bool ValidateQuery::check_one_transaction(block::Account& account, ton::LogicalT
|
|||
bool external{false}, ihr_delivered{false}, need_credit_phase{false};
|
||||
// check input message
|
||||
block::CurrencyCollection money_imported(0), money_exported(0);
|
||||
bool is_special_tx = false; // recover/mint transaction
|
||||
if (in_msg_root.not_null()) {
|
||||
auto in_descr_cs = in_msg_dict_->lookup(in_msg_root->get_hash().as_bitslice());
|
||||
if (in_descr_cs.is_null()) {
|
||||
|
@ -4700,6 +4701,7 @@ bool ValidateQuery::check_one_transaction(block::Account& account, ton::LogicalT
|
|||
<< " has an invalid InMsg record (not one of msg_import_ext, msg_import_fin, "
|
||||
"msg_import_imm or msg_import_ihr)");
|
||||
}
|
||||
is_special_tx = is_special_in_msg(*in_descr_cs);
|
||||
// once we know there is a InMsg with correct hash, we already know that it contains a message with this hash (by the verification of InMsg), so it is our message
|
||||
// have still to check its destination address and imported value
|
||||
// and that it refers to this transaction
|
||||
|
@ -4717,7 +4719,7 @@ bool ValidateQuery::check_one_transaction(block::Account& account, ton::LogicalT
|
|||
<< " processed inbound message created later at logical time "
|
||||
<< info.created_lt);
|
||||
}
|
||||
if (info.created_lt != start_lt_ || !is_special_in_msg(*in_descr_cs)) {
|
||||
if (info.created_lt != start_lt_ || !is_special_tx) {
|
||||
msg_proc_lt_.emplace_back(addr, lt, info.created_lt);
|
||||
}
|
||||
dest = std::move(info.dest);
|
||||
|
@ -5057,19 +5059,31 @@ 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 (!trs->update_limits(*block_limit_status_,
|
||||
/* with_gas = */ !account.is_special && !trs->gas_limit_overridden,
|
||||
/* with_size = */ false)) {
|
||||
if (!trs->update_limits(*block_limit_status_, /* with_gas = */ false, /* with_size = */ false)) {
|
||||
return fatal_error(PSTRING() << "cannot update block limit status to include transaction " << lt << " of account "
|
||||
<< addr.to_hex());
|
||||
}
|
||||
if (block_limit_status_->gas_used > block_limits_->gas.hard() + compute_phase_cfg_.gas_limit) {
|
||||
// Note that block_limit_status_->gas_used does not include transactions in special accounts
|
||||
|
||||
// Collator should stop if total gas usage exceeds limits, including transactions on special accounts, but without
|
||||
// ticktocks and mint/recover.
|
||||
// Here Validator checks a weaker condition
|
||||
if (!is_special_tx && !trs->gas_limit_overridden && trans_type == block::transaction::Transaction::tr_ord) {
|
||||
(account.is_special ? total_special_gas_used_ : total_gas_used_) += trs->gas_used();
|
||||
}
|
||||
if (total_gas_used_ > block_limits_->gas.hard() + compute_phase_cfg_.gas_limit) {
|
||||
return reject_query(PSTRING() << "gas block limits are exceeded: total_gas_used > gas_limit_hard + trx_gas_limit ("
|
||||
<< "total_gas_used=" << block_limit_status_->gas_used
|
||||
<< "total_gas_used=" << total_gas_used_
|
||||
<< ", gas_limit_hard=" << block_limits_->gas.hard()
|
||||
<< ", trx_gas_limit=" << compute_phase_cfg_.gas_limit << ")");
|
||||
}
|
||||
if (total_special_gas_used_ > block_limits_->gas.hard() + compute_phase_cfg_.special_gas_limit) {
|
||||
return reject_query(
|
||||
PSTRING() << "gas block limits are exceeded: total_special_gas_used > gas_limit_hard + special_gas_limit ("
|
||||
<< "total_special_gas_used=" << total_special_gas_used_
|
||||
<< ", gas_limit_hard=" << block_limits_->gas.hard()
|
||||
<< ", special_gas_limit=" << compute_phase_cfg_.special_gas_limit << ")");
|
||||
}
|
||||
|
||||
auto trans_root2 = trs->commit(account);
|
||||
if (trans_root2.is_null()) {
|
||||
return reject_query(PSTRING() << "the re-created transaction " << lt << " for smart contract " << addr.to_hex()
|
||||
|
|
|
@ -195,6 +195,7 @@ class ValidateQuery : public td::actor::Actor {
|
|||
ton::LogicalTime prev_key_block_lt_;
|
||||
std::unique_ptr<block::BlockLimits> block_limits_;
|
||||
std::unique_ptr<block::BlockLimitStatus> block_limit_status_;
|
||||
td::uint64 total_gas_used_{0}, total_special_gas_used_{0};
|
||||
|
||||
LogicalTime start_lt_, end_lt_;
|
||||
UnixTime prev_now_{~0u}, now_{~0u};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue