Skip to content

Commit 2ee4d6b

Browse files
committed
Keep track of code deposit gas when executing contract code
1 parent d5bae3f commit 2ee4d6b

File tree

4 files changed

+21
-1
lines changed

4 files changed

+21
-1
lines changed

test/EVMHost.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ void EVMHost::reset()
161161
recorded_calls.clear();
162162
// Clear EIP-2929 account access indicator
163163
recorded_account_accesses.clear();
164+
m_totalCodeDepositGas = 0;
164165

165166
// Mark all precompiled contracts as existing. Existing here means to have a balance (as per EIP-161).
166167
// NOTE: keep this in sync with `EVMHost::call` below.
@@ -203,6 +204,7 @@ void EVMHost::newTransactionFrame()
203204
// Otherwise, the previous behavior (pre-Cancun) is maintained.
204205
accounts.erase(address);
205206
newlyCreatedAccounts.clear();
207+
m_totalCodeDepositGas = 0;
206208
recorded_selfdestructs.clear();
207209
}
208210

@@ -392,15 +394,18 @@ evmc::Result EVMHost::call(evmc_message const& _message) noexcept
392394

393395
if (message.kind == EVMC_CREATE || message.kind == EVMC_CREATE2)
394396
{
395-
result.gas_left -= static_cast<int64_t>(evmasm::GasCosts::createDataGas * result.output_size);
397+
int64_t codeDepositGas = static_cast<int64_t>(evmasm::GasCosts::createDataGas * result.output_size);
398+
result.gas_left -= codeDepositGas;
396399
if (result.gas_left < 0)
397400
{
401+
m_totalCodeDepositGas += -result.gas_left;
398402
result.gas_left = 0;
399403
result.status_code = EVMC_OUT_OF_GAS;
400404
// TODO clear some fields?
401405
}
402406
else
403407
{
408+
m_totalCodeDepositGas += codeDepositGas;
404409
result.create_address = message.recipient;
405410
destination.code = evmc::bytes(result.output_data, result.output_data + result.output_size);
406411
destination.codehash = convertToEVMC(keccak256({result.output_data, result.output_size}));

test/EVMHost.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ class EVMHost: public evmc::MockedHost
9494
/// @returns contents of storage at @param _addr.
9595
StorageMap const& get_address_storage(evmc::address const& _addr);
9696

97+
u256 totalCodeDepositGas() const { return m_totalCodeDepositGas; }
98+
9799
static Address convertFromEVMC(evmc::address const& _addr);
98100
static evmc::address convertToEVMC(Address const& _addr);
99101
static util::h256 convertFromEVMC(evmc::bytes32 const& _data);
@@ -137,6 +139,11 @@ class EVMHost: public evmc::MockedHost
137139
langutil::EVMVersion m_evmVersion;
138140
/// EVM version requested from EVMC (matches the above)
139141
evmc_revision m_evmRevision;
142+
143+
/// The part of the total cost of the current transaction that paid for the code deposits.
144+
/// I.e. GAS_CODE_DEPOSIT times the total size of deployed code of all newly created contracts,
145+
/// including the current contract itself if it was a creation transaction.
146+
u256 m_totalCodeDepositGas;
140147
};
141148

142149
class EVMHostPrinter

test/ExecutionFramework.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ void ExecutionFramework::sendMessage(bytes const& _data, bool _isCreation, u256
191191
auto const gasRefund = std::min(u256(result.gas_refund), totalGasUsed / refundRatio);
192192

193193
m_gasUsed = totalGasUsed - gasRefund;
194+
m_gasUsedForCodeDeposit = m_evmcHost->totalCodeDepositGas();
194195
m_transactionSuccessful = (result.status_code == EVMC_SUCCESS);
195196

196197
if (m_showMessages)
@@ -199,6 +200,7 @@ void ExecutionFramework::sendMessage(bytes const& _data, bool _isCreation, u256
199200
std::cout << " result: " << static_cast<size_t>(result.status_code) << std::endl;
200201
std::cout << " gas used: " << m_gasUsed.str() << std::endl;
201202
std::cout << " gas used (without refund): " << totalGasUsed.str() << std::endl;
203+
std::cout << " code deposits only: " << m_gasUsedForCodeDeposit.str() << std::endl;
202204
std::cout << " gas refund (total): " << result.gas_refund << std::endl;
203205
std::cout << " gas refund (bound): " << gasRefund.str() << std::endl;
204206
}

test/ExecutionFramework.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,13 @@ class ExecutionFramework
303303
util::h160 m_sender = account(0);
304304
util::h160 m_contractAddress;
305305
bytes m_output;
306+
307+
/// Total gas used by the transaction, after refund.
306308
u256 m_gasUsed;
309+
310+
/// The portion of @a m_gasUsed spent on code deposits of newly created contracts.
311+
/// May exceed @a m_gasUsed in rare corner cases due to refunds.
312+
u256 m_gasUsedForCodeDeposit;
307313
};
308314

309315
#define ABI_CHECK(result, expectation) do { \

0 commit comments

Comments
 (0)