Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ reth-rpc-convert = { git = "https://github.com/paradigmxyz/reth", tag = "v1.11.4
reth-rpc-engine-api = { git = "https://github.com/paradigmxyz/reth", tag = "v1.11.4" }
reth-rpc-eth-api = { git = "https://github.com/paradigmxyz/reth", tag = "v1.11.4" }
reth-rpc-eth-types = { git = "https://github.com/paradigmxyz/reth", tag = "v1.11.4" }
reth-storage-api = { git = "https://github.com/paradigmxyz/reth", tag = "v1.11.4" }
reth-transaction-pool = { git = "https://github.com/paradigmxyz/reth", tag = "v1.11.4" }
serde = { version = "1.0", features = ["derive"], default-features = false }
serde_json = "1.0"
Expand Down
22 changes: 21 additions & 1 deletion src/engine/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ use crate::{
hardforks::BerachainHardforks,
node::evm::config::{BerachainEvmConfig, BerachainNextBlockEnvAttributes},
primitives::{BerachainHeader, BerachainPrimitives},
transaction::BerachainTxEnvelope,
transaction::{BerachainTxEnvelope, pol::create_pol_transaction},
};
use alloy_consensus::Transaction;
use alloy_eips::eip7002::SYSTEM_ADDRESS;
use alloy_primitives::U256;
use alloy_rlp::Encodable;
use reth::{
Expand Down Expand Up @@ -234,6 +235,25 @@ where
PayloadBuilderError::Internal(err.into())
})?;

// Execute PoL as tx #0 post-Prague1. prev_proposer_pubkey was validated in
// apply_pre_execution_changes.
if chain_spec.is_prague1_active_at_timestamp(attributes.timestamp()) {
let prev_proposer_pubkey = attributes
.prev_proposer_pubkey
.expect("prev_proposer_pubkey validated by validate_proposer_pubkey_prague1");
Comment on lines +238 to +243

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

opened #272
Fixed the expect, it now returns a MissingProposerPubkey error instead of panicking.

The RLP length isn't something this PR changed. PoL was never counted in block_transactions_rlp_length before either, and the check after finish() already rejects any block over MAX_RLP_BLOCK_SIZE. PoL is only ~150-200 bytes and the loop already keeps a 1024 buffer, so leaving that as is.

let pol_envelope = create_pol_transaction(
chain_spec.clone(),
prev_proposer_pubkey,
builder.evm_mut().block().number(),
builder.evm_mut().block().basefee(),
)
.map_err(|err| PayloadBuilderError::Internal(err.into()))?;
builder.execute_transaction(pol_envelope.with_signer(SYSTEM_ADDRESS)).map_err(|err| {
warn!(target: "payload_builder", %err, "failed to execute PoL transaction");
PayloadBuilderError::evm(err)
})?;
}

// initialize empty blob sidecars at first. If cancun is active then this will be populated by
// blob sidecars if any.
let mut blob_sidecars = BlobSidecars::Empty;
Expand Down
10 changes: 8 additions & 2 deletions src/evm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,8 @@ where
}
TxKind::Call(to) => {
let mut result = self.transact_system_call(tx.caller, to, tx.data)?;
// Set gas_used to 0 for POL transactions
// POL transactions are system calls that always consume zero gas, regardless
// of whether they succeed, revert, or halt.
result.result = match result.result {
ExecutionResult::Success { reason, gas_refunded, logs, output, .. } => {
ExecutionResult::Success {
Expand All @@ -223,7 +224,12 @@ where
output,
}
}
other => other,
ExecutionResult::Revert { output, .. } => {
ExecutionResult::Revert { gas_used: 0, output }
}
ExecutionResult::Halt { reason, .. } => {
ExecutionResult::Halt { reason, gas_used: 0 }
}
};
Ok(result)
}
Expand Down
22 changes: 4 additions & 18 deletions src/node/evm/assembler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{
hardforks::BerachainHardforks,
node::evm::{block_context::BerachainBlockExecutionCtx, error::BerachainExecutionError},
primitives::{BerachainBlock, BerachainHeader},
transaction::{BerachainTxEnvelope, BerachainTxType, pol::create_pol_transaction},
transaction::{BerachainTxEnvelope, BerachainTxType},
};
use alloy_consensus::{Block, BlockBody, BlockHeader, EMPTY_OMMER_ROOT_HASH, TxReceipt, proofs};
use alloy_eips::merge::BEACON_NONCE;
Expand Down Expand Up @@ -53,7 +53,7 @@ where
evm_env,
execution_ctx: ctx,
parent,
mut transactions,
transactions,
output: BlockExecutionResult { receipts, requests, gas_used, blob_gas_used },
state_root,
..
Expand All @@ -64,27 +64,13 @@ where
// Validate proposer pubkey presence for Prague1
validate_proposer_pubkey_prague1(&*self.chain_spec, timestamp, ctx.prev_proposer_pubkey)?;

// Check if Prague1 is active and we need to inject POL transaction
// Post-Prague1, PoL must already be tx #0 with a matching receipt.
if self.chain_spec.is_prague1_active_at_timestamp(timestamp) {
let prev_proposer_pubkey = ctx.prev_proposer_pubkey.unwrap();

// Synthesize POL transaction and prepend to transactions list
let base_fee = evm_env.block_env.basefee();
let pol_transaction = create_pol_transaction(
self.chain_spec.clone(),
prev_proposer_pubkey,
evm_env.block_env.number(),
base_fee,
)?;

transactions.insert(0, pol_transaction);

// Validate that we have receipts after POL transaction execution
if receipts.is_empty() {
return Err(BerachainExecutionError::MissingPolReceipts.into());
}
Comment on lines +67 to 71

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#272
Updated the comment to match what's actually checked (PoL at index 0, receipts not empty).

Not adding receipt/tx alignment checks here since receipts are built in order during execution and a mismatch would fail on the root computation right below.


// Validate that the first transaction in the list is indeed a POL transaction
// Validate that the first transaction is a PoL transaction
if let Some(first_tx) = transactions.first() {
if !matches!(first_tx, BerachainTxEnvelope::Berachain(_)) {
return Err(BerachainExecutionError::MissingPolTransactionAtIndex0.into());
Expand Down
Loading