Skip to content

Commit 1c0a9b9

Browse files
authored
test: Set blob gas budget from the protocol max (#1555)
So far we were pre-validating the block header blob_gas_used against the protocol max. This was correct, but hid expected per-tx blob gas limit exceeded errors. Changed behavior: start with the protocol max and validate each tx. Compare the block header value at the end. The block validity outcome is unchanged; only the reported error differs (a per-tx blob gas error instead of a block-level one). Matches EELS and other implementations.
1 parent 0cd0dec commit 1c0a9b9

1 file changed

Lines changed: 15 additions & 10 deletions

File tree

test/blockchaintest/blockchaintest_runner.cpp

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,22 +41,27 @@ struct TransitionResult
4141

4242
namespace
4343
{
44+
/// Transition the state with a block of transactions.
45+
///
46+
/// This assumes block-level validity, but transaction may be invalid.
47+
///
48+
/// @param blob_gas_limit The per-block blob-gas budget set by the protocol maximum.
4449
TransitionResult apply_block(const TestState& state, evmc::VM& vm, const state::BlockInfo& block,
4550
const state::BlockHashes& block_hashes, const std::vector<state::Transaction>& txs,
46-
evmc_revision rev, std::optional<int64_t> block_reward)
51+
evmc_revision rev, int64_t blob_gas_limit, std::optional<int64_t> block_reward)
4752
{
4853
TestState block_state(state);
4954
system_call_block_start(block_state, block, block_hashes, rev, vm);
5055

5156
std::vector<state::Log> txs_logs;
5257
int64_t block_gas_left = block.gas_limit;
53-
auto blob_gas_left = static_cast<int64_t>(block.blob_gas_used.value_or(0));
5458

5559
std::vector<RejectedTransaction> rejected_txs;
5660
std::vector<state::TransactionReceipt> receipts;
5761

5862
int64_t cumulative_gas_used = 0;
5963
int64_t block_gas_used = 0;
64+
auto blob_gas_left = blob_gas_limit;
6065

6166
for (size_t i = 0; i < txs.size(); ++i)
6267
{
@@ -200,10 +205,6 @@ bool validate_block(evmc_revision rev, state::BlobParams blob_params, const Test
200205
parent_header->excess_blob_gas.value_or(0), parent_header->base_fee_per_gas,
201206
parent_blob_base_fee))
202207
return false;
203-
204-
// Ensure the total blob gas spent is at most equal to the limit
205-
if (*test_block.block_info.blob_gas_used > state::max_blob_gas_per_block(blob_params))
206-
return false;
207208
}
208209
else
209210
{
@@ -308,6 +309,8 @@ void run_blockchain_tests(std::span<const BlockchainTest> tests, evmc::VM& vm)
308309

309310
const auto rev = rev_schedule.get_revision(bi.timestamp);
310311
const auto blob_params = get_blob_params(c.network, c.blob_schedule, bi.timestamp);
312+
const auto blob_gas_limit =
313+
static_cast<int64_t>(state::max_blob_gas_per_block(blob_params));
311314

312315
SCOPED_TRACE(std::string{evmc::to_string(rev)} + '/' + std::to_string(case_index) +
313316
'/' + c.name + '/' + std::to_string(test_block.block_info.number));
@@ -323,7 +326,7 @@ void run_blockchain_tests(std::span<const BlockchainTest> tests, evmc::VM& vm)
323326
const auto& pre_state = parent_data_it->second.post_state;
324327

325328
auto res = apply_block(pre_state, vm, bi, block_hashes, test_block.transactions,
326-
rev, mining_reward(rev));
329+
rev, blob_gas_limit, mining_reward(rev));
327330

328331
ASSERT_TRUE(res.requests.has_value());
329332

@@ -346,7 +349,8 @@ void run_blockchain_tests(std::span<const BlockchainTest> tests, evmc::VM& vm)
346349

347350
EXPECT_TRUE(res.rejected.empty())
348351
<< "Invalid transaction in block expected to be valid";
349-
EXPECT_TRUE(res.blob_gas_left == 0)
352+
EXPECT_EQ(blob_gas_limit - res.blob_gas_left,
353+
static_cast<int64_t>(bi.blob_gas_used.value_or(0)))
350354
<< "Transactions used more or less blob gas than expected in block header";
351355

352356
EXPECT_EQ(state::mpt_hash(inserted_it->second.post_state),
@@ -381,12 +385,13 @@ void run_blockchain_tests(std::span<const BlockchainTest> tests, evmc::VM& vm)
381385
const auto& pre_state = parent_data_it->second.post_state;
382386

383387
const auto res = apply_block(pre_state, vm, bi, block_hashes,
384-
test_block.transactions, rev, mining_reward(rev));
388+
test_block.transactions, rev, blob_gas_limit, mining_reward(rev));
385389
if (!res.requests.has_value())
386390
continue;
387391
if (!res.rejected.empty())
388392
continue;
389-
if (res.blob_gas_left != 0)
393+
if (blob_gas_limit - res.blob_gas_left !=
394+
static_cast<int64_t>(bi.blob_gas_used.value_or(0)))
390395
continue;
391396

392397
if (state::mpt_hash(res.block_state) != test_block.expected_block_header.state_root)

0 commit comments

Comments
 (0)