Skip to content

Commit 084c899

Browse files
SDartayetcdiielsi
andauthored
feat(l1): block size limit in building (#4397)
**Motivation** Finish implementing [EIP-7934](https://eips.ethereum.org/EIPS/eip-7934) for the case of payload building. **Description** This pr includes a check of block size during building so it finishes when surpassing the 10MiB cap introduced in EIP-7934 for Osaka. Also, it updates the test runner to include the new exception. To test if the cap is respected I launched a local net with the dora service activated running `make localnet` and I used Dora to check the proposed blocks by ethrex. First I did this setting `MAX_RLP_BLOCK_SIZE = 1200` And I could verify the blocks proposed by ethrex were all really small, they only had three transactions. Here an example with some logs I added: Block 27 with its 3 transactions: <img width="564" height="255" alt="Screenshot 2025-10-30 at 17 57 50" src="https://github.com/user-attachments/assets/ecd7791b-7ffd-45ac-a81b-f21ca5afeb86" /> <img width="339" height="309" alt="Screenshot 2025-10-30 at 17 58 03" src="https://github.com/user-attachments/assets/afd5648b-cdaf-4e39-b368-779d67fac195" /> Here in the logs we can see when these transactions were added and how there was a forth one that didn't make it because it surpassed the rlp size limit: <img width="1029" height="516" alt="Screenshot 2025-10-30 at 18 31 05" src="https://github.com/user-attachments/assets/97bb979c-8fb5-489d-aec8-6d82365ab7c5" /> I also dropped the cap to 800 bytes and in that case all block proposed by ethrex were empty. This pr also adds support for the local ef tests runner. --------- Co-authored-by: cdiielsi <[email protected]> Co-authored-by: Camila Di Ielsi <[email protected]>
1 parent b233284 commit 084c899

File tree

5 files changed

+28
-2
lines changed

5 files changed

+28
-2
lines changed

crates/blockchain/payload.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use std::{
88

99
use ethrex_common::{
1010
Address, Bloom, Bytes, H256, U256,
11-
constants::{DEFAULT_OMMERS_HASH, DEFAULT_REQUESTS_HASH, GAS_PER_BLOB},
11+
constants::{DEFAULT_OMMERS_HASH, DEFAULT_REQUESTS_HASH, GAS_PER_BLOB, MAX_RLP_BLOCK_SIZE},
1212
types::{
1313
AccountUpdate, BlobsBundle, Block, BlockBody, BlockHash, BlockHeader, BlockNumber,
1414
ChainConfig, MempoolTransaction, Receipt, Transaction, TxType, Withdrawal, bloom_from_logs,
@@ -217,6 +217,7 @@ pub struct PayloadBuildContext {
217217
pub store: Store,
218218
pub vm: Evm,
219219
pub account_updates: Vec<AccountUpdate>,
220+
pub payload_size: u64,
220221
}
221222

222223
impl PayloadBuildContext {
@@ -237,6 +238,7 @@ impl PayloadBuildContext {
237238
let vm_db = StoreVmDatabase::new(storage.clone(), payload.header.parent_hash);
238239
let vm = new_evm(blockchain_type, vm_db)?;
239240

241+
let payload_size = payload.encode_to_vec().len() as u64;
240242
Ok(PayloadBuildContext {
241243
remaining_gas: payload.header.gas_limit,
242244
receipts: vec![],
@@ -250,6 +252,7 @@ impl PayloadBuildContext {
250252
store: storage.clone(),
251253
vm,
252254
account_updates: Vec::new(),
255+
payload_size,
253256
})
254257
}
255258

@@ -529,6 +532,20 @@ impl Blockchain {
529532
continue;
530533
}
531534

535+
// Check adding a transaction wouldn't exceed the Osaka block size limit of 10 MiB
536+
// if inclusion of the transaction puts the block size over the size limit
537+
// we don't add any more txs to the payload.
538+
let potential_rlp_block_size =
539+
context.payload_size + head_tx.encode_canonical_to_vec().len() as u64;
540+
if context
541+
.chain_config()
542+
.is_osaka_activated(context.payload.header.timestamp)
543+
&& potential_rlp_block_size > MAX_RLP_BLOCK_SIZE
544+
{
545+
break;
546+
}
547+
context.payload_size = potential_rlp_block_size;
548+
532549
// TODO: maybe fetch hash too when filtering mempool so we don't have to compute it here (we can do this in the same refactor as adding timestamp)
533550
let tx_hash = head_tx.tx.hash();
534551

tooling/ef_tests/blockchain/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,6 @@ test-sp1: $(VECTORS_TARGETS)
5151
test-stateless: $(VECTORS_TARGETS)
5252
cargo test --profile release-with-debug --features stateless
5353

54-
test: ## 🧪 Run blockchain tests with both VMs, and also stateless with LEVM
54+
test: ## 🧪 Run blockchain tests with LEVM both with state and stateless
5555
$(MAKE) test-levm
5656
$(MAKE) test-stateless

tooling/ef_tests/blockchain/deserialize.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,9 @@ where
120120
BlockExpectedException::SystemContractCallFailed,
121121
)
122122
}
123+
"BlockException.RLP_BLOCK_LIMIT_EXCEEDED" => BlockChainExpectedException::BlockException(
124+
BlockExpectedException::RlpBlockLimitExceeded,
125+
),
123126
_ => BlockChainExpectedException::Other,
124127
})
125128
.collect();

tooling/ef_tests/blockchain/test_runner.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,11 @@ fn exception_is_expected(
196196
BlockExpectedException::SystemContractCallFailed
197197
),
198198
ChainError::EvmError(EvmError::SystemContractCallFailed(_))
199+
) | (
200+
BlockChainExpectedException::BlockException(
201+
BlockExpectedException::RlpBlockLimitExceeded
202+
),
203+
ChainError::InvalidBlock(InvalidBlockError::MaximumRlpSizeExceeded(_, _))
199204
) | (
200205
BlockChainExpectedException::Other,
201206
_ //TODO: Decide whether to support more specific errors.

tooling/ef_tests/blockchain/types.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -605,5 +605,6 @@ pub enum BlockExpectedException {
605605
IncorrectBlockFormat,
606606
InvalidRequest,
607607
SystemContractCallFailed,
608+
RlpBlockLimitExceeded,
608609
Other, //TODO: Implement exceptions
609610
}

0 commit comments

Comments
 (0)