mirror of
				https://github.com/ton-blockchain/ton
				synced 2025-03-09 15:40:10 +00:00 
			
		
		
		
	Do not count gas on special accounts in block gas limits (enabled by config) (#856)
* Set higher gas limit for special accounts, don't add gas from special accounts to block total * Make removing special accounts from block gas limits enabled by config --------- Co-authored-by: SpyCheese <mikle98@yandex.ru>
This commit is contained in:
		
							parent
							
								
									3a5f3fcadd
								
							
						
					
					
						commit
						ff40c1f2a0
					
				
					 7 changed files with 36 additions and 21 deletions
				
			
		| 
						 | 
				
			
			@ -696,6 +696,11 @@ gas_prices_ext#de gas_price:uint64 gas_limit:uint64 special_gas_limit:uint64 gas
 | 
			
		|||
  block_gas_limit:uint64 freeze_due_limit:uint64 delete_due_limit:uint64 
 | 
			
		||||
  = GasLimitsPrices;
 | 
			
		||||
 | 
			
		||||
// same fields as gas_prices_ext; behavior differs
 | 
			
		||||
gas_prices_v3#df gas_price:uint64 gas_limit:uint64 special_gas_limit:uint64 gas_credit:uint64
 | 
			
		||||
  block_gas_limit:uint64 freeze_due_limit:uint64 delete_due_limit:uint64
 | 
			
		||||
  = GasLimitsPrices;
 | 
			
		||||
 | 
			
		||||
gas_flat_pfx#d1 flat_gas_limit:uint64 flat_gas_price:uint64 other:GasLimitsPrices
 | 
			
		||||
  = GasLimitsPrices;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -654,11 +654,16 @@ td::Result<GasLimitsPrices> Config::do_get_gas_limits_prices(td::Ref<vm::Cell> c
 | 
			
		|||
    res.delete_due_limit = r.delete_due_limit;
 | 
			
		||||
  };
 | 
			
		||||
  block::gen::GasLimitsPrices::Record_gas_prices_ext rec;
 | 
			
		||||
  block::gen::GasLimitsPrices::Record_gas_prices_v3 rec_v3;
 | 
			
		||||
  vm::CellSlice cs0 = cs;
 | 
			
		||||
  if (tlb::unpack(cs, rec)) {
 | 
			
		||||
    f(rec, rec.special_gas_limit);
 | 
			
		||||
  } else if (tlb::unpack(cs = cs0, rec_v3)) {
 | 
			
		||||
    f(rec_v3, rec_v3.special_gas_limit);
 | 
			
		||||
    res.special_full_limit = true;
 | 
			
		||||
  } else {
 | 
			
		||||
    block::gen::GasLimitsPrices::Record_gas_prices rec0;
 | 
			
		||||
    if (tlb::unpack(cs, rec0)) {
 | 
			
		||||
    if (tlb::unpack(cs = cs0, rec0)) {
 | 
			
		||||
      f(rec0, rec0.gas_limit);
 | 
			
		||||
    } else {
 | 
			
		||||
      return td::Status::Error(PSLICE() << "configuration parameter " << id
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -349,6 +349,7 @@ struct GasLimitsPrices {
 | 
			
		|||
  td::uint64 block_gas_limit{0};
 | 
			
		||||
  td::uint64 freeze_due_limit{0};
 | 
			
		||||
  td::uint64 delete_due_limit{0};
 | 
			
		||||
  bool special_full_limit{false};
 | 
			
		||||
 | 
			
		||||
  td::RefInt256 compute_gas_price(td::uint64 gas_used) const;
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1039,8 +1039,12 @@ bool ComputePhaseConfig::parse_GasLimitsPrices_internal(Ref<vm::CellSlice> cs, t
 | 
			
		|||
    delete_due_limit = td::make_refint(r.delete_due_limit);
 | 
			
		||||
  };
 | 
			
		||||
  block::gen::GasLimitsPrices::Record_gas_prices_ext rec;
 | 
			
		||||
  block::gen::GasLimitsPrices::Record_gas_prices_v3 rec_v3;
 | 
			
		||||
  if (tlb::csr_unpack(cs, rec)) {
 | 
			
		||||
    f(rec, rec.special_gas_limit);
 | 
			
		||||
  } else if (tlb::csr_unpack(cs, rec_v3)) {
 | 
			
		||||
    f(rec_v3, rec_v3.special_gas_limit);
 | 
			
		||||
    special_gas_full = true;
 | 
			
		||||
  } else {
 | 
			
		||||
    block::gen::GasLimitsPrices::Record_gas_prices rec0;
 | 
			
		||||
    if (tlb::csr_unpack(std::move(cs), rec0)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1142,7 +1146,7 @@ bool Transaction::compute_gas_limits(ComputePhase& cp, const ComputePhaseConfig&
 | 
			
		|||
    cp.gas_max = cfg.gas_bought_for(balance.grams);
 | 
			
		||||
  }
 | 
			
		||||
  cp.gas_credit = 0;
 | 
			
		||||
  if (trans_type != tr_ord) {
 | 
			
		||||
  if (trans_type != tr_ord || (account.is_special && cfg.special_gas_full)) {
 | 
			
		||||
    // may use all gas that can be bought using remaining balance
 | 
			
		||||
    cp.gas_limit = cp.gas_max;
 | 
			
		||||
  } else {
 | 
			
		||||
| 
						 | 
				
			
			@ -3203,8 +3207,8 @@ td::Result<vm::NewCellStorageStat::Stat> Transaction::estimate_block_storage_pro
 | 
			
		|||
 *
 | 
			
		||||
 * @returns True if the limits were successfully updated, False otherwise.
 | 
			
		||||
 */
 | 
			
		||||
bool Transaction::update_limits(block::BlockLimitStatus& blimst, bool with_size) const {
 | 
			
		||||
  if (!(blimst.update_lt(end_lt) && blimst.update_gas(gas_used()))) {
 | 
			
		||||
bool Transaction::update_limits(block::BlockLimitStatus& blimst, bool with_gas, bool with_size) const {
 | 
			
		||||
  if (!(blimst.update_lt(end_lt) && blimst.update_gas(with_gas ? gas_used() : 0))) {
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
  if (with_size) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -104,6 +104,7 @@ struct ComputePhaseConfig {
 | 
			
		|||
  td::uint64 gas_credit;
 | 
			
		||||
  td::uint64 flat_gas_limit = 0;
 | 
			
		||||
  td::uint64 flat_gas_price = 0;
 | 
			
		||||
  bool special_gas_full = false;
 | 
			
		||||
  static constexpr td::uint64 gas_infty = (1ULL << 63) - 1;
 | 
			
		||||
  td::RefInt256 gas_price256;
 | 
			
		||||
  td::RefInt256 max_gas_threshold;
 | 
			
		||||
| 
						 | 
				
			
			@ -119,12 +120,7 @@ struct ComputePhaseConfig {
 | 
			
		|||
  SizeLimitsConfig size_limits;
 | 
			
		||||
  int vm_log_verbosity = 0;
 | 
			
		||||
 | 
			
		||||
  ComputePhaseConfig(td::uint64 _gas_price = 0, td::uint64 _gas_limit = 0, td::uint64 _gas_credit = 0)
 | 
			
		||||
      : gas_price(_gas_price), gas_limit(_gas_limit), special_gas_limit(_gas_limit), gas_credit(_gas_credit) {
 | 
			
		||||
    compute_threshold();
 | 
			
		||||
  }
 | 
			
		||||
  ComputePhaseConfig(td::uint64 _gas_price, td::uint64 _gas_limit, td::uint64 _spec_gas_limit, td::uint64 _gas_credit)
 | 
			
		||||
      : gas_price(_gas_price), gas_limit(_gas_limit), special_gas_limit(_spec_gas_limit), gas_credit(_gas_credit) {
 | 
			
		||||
  ComputePhaseConfig() : gas_price(0), gas_limit(0), special_gas_limit(0), gas_credit(0) {
 | 
			
		||||
    compute_threshold();
 | 
			
		||||
  }
 | 
			
		||||
  void compute_threshold();
 | 
			
		||||
| 
						 | 
				
			
			@ -383,7 +379,7 @@ struct Transaction {
 | 
			
		|||
 | 
			
		||||
  td::Result<vm::NewCellStorageStat::Stat> estimate_block_storage_profile_incr(
 | 
			
		||||
      const vm::NewCellStorageStat& store_stat, const vm::CellUsageTree* usage_tree) const;
 | 
			
		||||
  bool update_limits(block::BlockLimitStatus& blk_lim_st, bool with_size = true) const;
 | 
			
		||||
  bool update_limits(block::BlockLimitStatus& blk_lim_st, bool with_gas = true, bool with_size = true) const;
 | 
			
		||||
 | 
			
		||||
  Ref<vm::Cell> commit(Account& _account);  // _account should point to the same account
 | 
			
		||||
  LtCellRef extract_out_msg(unsigned i);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2667,7 +2667,8 @@ 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_)) {
 | 
			
		||||
  if (!trans->update_limits(*block_limit_status_,
 | 
			
		||||
                            /* with_gas = */ !(acc->is_special && compute_phase_cfg_.special_gas_full))) {
 | 
			
		||||
    return fatal_error(-666, "cannot update block limit status to include the new transaction");
 | 
			
		||||
  }
 | 
			
		||||
  if (trans->commit(*acc).is_null()) {
 | 
			
		||||
| 
						 | 
				
			
			@ -2744,7 +2745,8 @@ 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_)) {
 | 
			
		||||
  if (!trans->update_limits(*block_limit_status_,
 | 
			
		||||
                            /* with_gas = */ !(acc->is_special && compute_phase_cfg_.special_gas_full))) {
 | 
			
		||||
    fatal_error("cannot update block limit status to include the new transaction");
 | 
			
		||||
    return {};
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4904,13 +4904,6 @@ bool ValidateQuery::check_one_transaction(block::Account& account, ton::LogicalT
 | 
			
		|||
  int trans_type = block::transaction::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::Transaction::tr_ord;
 | 
			
		||||
      if (in_msg_root.is_null()) {
 | 
			
		||||
        return reject_query(PSTRING() << "ordinary transaction " << lt << " of account " << addr.to_hex()
 | 
			
		||||
| 
						 | 
				
			
			@ -5058,10 +5051,19 @@ 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_, false)) {
 | 
			
		||||
  if (!trs->update_limits(*block_limit_status_,
 | 
			
		||||
                          /* with_gas = */ !account.is_special,
 | 
			
		||||
                          /* 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
 | 
			
		||||
    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
 | 
			
		||||
                                  << ", gas_limit_hard=" << block_limits_->gas.hard()
 | 
			
		||||
                                  << ", trx_gas_limit=" << compute_phase_cfg_.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()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue