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
5 changes: 5 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions crates/scroll/alloy/evm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ revm-scroll = { workspace = true, default-features = false }
# scroll
scroll-alloy-consensus = { workspace = true, default-features = false }
scroll-alloy-hardforks = { workspace = true, default-features = false }
reth-scroll-primitives = { workspace = true, features = ["serde", "serde-bincode-compat", "reth-codec"] }

# misc
auto_impl = { workspace = true, default-features = false }
Expand Down
5 changes: 3 additions & 2 deletions crates/scroll/alloy/evm/src/system_caller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ mod tests {
use reth_evm::ConfigureEvm;
use reth_scroll_chainspec::{ScrollChainConfig, ScrollChainSpecBuilder};
use reth_scroll_evm::ScrollEvmConfig;
use reth_scroll_primitives::{ScrollBlock, ScrollHeader};
use revm::{
bytecode::Bytecode,
database::{EmptyDBTyped, State},
Expand Down Expand Up @@ -146,7 +147,7 @@ mod tests {
let block: Block<ScrollTxEnvelope, _> = Block { header, body: BlockBody::default() };

// initiate the evm and apply the block hashes contract call.
let mut evm = evm_config.evm_for_block(state, &block.header);
let mut evm = evm_config.evm_for_block(state, &ScrollHeader { inner: block.header.clone() });
system_caller.apply_blockhashes_contract_call(block.parent_hash, &mut evm).unwrap();

// assert the storage slot remains unchanged.
Expand Down Expand Up @@ -189,7 +190,7 @@ mod tests {
gas_limit: 20_000_000,
..Default::default()
};
let block: Block<ScrollTxEnvelope, _> = Block { header, body: BlockBody::default() };
let block: Block<ScrollTxEnvelope, _> = ScrollBlock { header: ScrollHeader { inner: header }, body: BlockBody::default() };

// initiate the evm and apply the block hashes contract call.
let mut evm = evm_config.evm_for_block(state, &block.header);
Expand Down
3 changes: 3 additions & 0 deletions crates/scroll/alloy/network/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ alloy-provider = { workspace = true, default-features = false }
scroll-alloy-consensus = { workspace = true, default-features = false }
scroll-alloy-rpc-types = { workspace = true, default-features = false }

# reth
reth-scroll-primitives = { workspace = true, features = ["serde", "serde-bincode-compat", "reth-codec"] }

# alloy
alloy-consensus = { workspace = true, default-features = false }
alloy-network = { workspace = true, default-features = false }
Expand Down
1 change: 1 addition & 0 deletions crates/scroll/chainspec/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ reth-trie-common = { workspace = true, default-features = false }

# scroll
reth-scroll-forks = { workspace = true, default-features = false }
reth-scroll-primitives = { workspace = true, features = ["serde", "serde-bincode-compat", "reth-codec"] }
scroll-alloy-hardforks = { workspace = true, default-features = false }

# ethereum
Expand Down
2 changes: 1 addition & 1 deletion crates/scroll/chainspec/src/dev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub static SCROLL_DEV: LazyLock<Arc<ScrollChainSpec>> = LazyLock::new(|| {
ScrollChainSpec {
inner: ChainSpec {
chain: Chain::dev(),
genesis_header: SealedHeader::new_unhashed(make_genesis_header(&genesis)),
genesis_header: SealedHeader::new_unhashed(make_genesis_header(&genesis).inner),
genesis,
paris_block_and_final_difficulty: Some((0, U256::from(0))),
hardforks: DEV_HARDFORKS.clone(),
Expand Down
52 changes: 29 additions & 23 deletions crates/scroll/chainspec/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use reth_ethereum_forks::{
};
use reth_network_peers::NodeRecord;
use reth_primitives_traits::SealedHeader;
use reth_scroll_primitives::ScrollHeader;
use scroll_alloy_hardforks::{ScrollHardfork, ScrollHardforks};

use alloy_eips::eip7840::BlobParams;
Expand Down Expand Up @@ -203,7 +204,7 @@ impl ScrollChainSpec {
if header.base_fee_per_gas.is_none() && feynman_active_at_genesis {
header.base_fee_per_gas = Some(0);
}
spec.inner.genesis_header = SealedHeader::new_unhashed(header);
spec.inner.genesis_header = SealedHeader::new_unhashed(header.inner);

// Use Scroll's EIP-1559 params from Feynman onwards.
spec.inner.base_fee_params = BaseFeeParamsKind::Variable(
Expand Down Expand Up @@ -242,7 +243,7 @@ pub struct ScrollChainSpec {
}

impl EthChainSpec for ScrollChainSpec {
type Header = Header;
type Header = ScrollHeader;

fn chain(&self) -> alloy_chains::Chain {
self.inner.chain()
Expand Down Expand Up @@ -276,8 +277,11 @@ impl EthChainSpec for ScrollChainSpec {
Box::new(ChainSpec::display_hardforks(self))
}

fn genesis_header(&self) -> &Header {
self.inner.genesis_header()
fn genesis_header(&self) -> &ScrollHeader {
// Store as a static to avoid lifetime issues
use std::sync::OnceLock;
static GENESIS_HEADER: OnceLock<ScrollHeader> = OnceLock::new();
GENESIS_HEADER.get_or_init(|| ScrollHeader { inner: self.inner.genesis_header().clone() })
}

fn genesis(&self) -> &Genesis {
Expand All @@ -300,25 +304,27 @@ impl EthereumCapabilities for ScrollChainSpec {
}
}

fn make_genesis_header(genesis: &Genesis) -> Header {
Header {
gas_limit: genesis.gas_limit,
difficulty: genesis.difficulty,
nonce: genesis.nonce.into(),
extra_data: genesis.extra_data.clone(),
state_root: reth_trie_common::root::state_root_ref_unhashed(&genesis.alloc),
timestamp: genesis.timestamp,
mix_hash: genesis.mix_hash,
beneficiary: genesis.coinbase,
base_fee_per_gas: genesis
.base_fee_per_gas
.map(|b| b.try_into().expect("base fee should fit in u64")),
withdrawals_root: None,
parent_beacon_block_root: None,
blob_gas_used: None,
excess_blob_gas: None,
requests_hash: None,
..Default::default()
fn make_genesis_header(genesis: &Genesis) -> ScrollHeader {
ScrollHeader {
inner: Header {
gas_limit: genesis.gas_limit,
difficulty: genesis.difficulty,
nonce: genesis.nonce.into(),
extra_data: genesis.extra_data.clone(),
state_root: reth_trie_common::root::state_root_ref_unhashed(&genesis.alloc),
timestamp: genesis.timestamp,
mix_hash: genesis.mix_hash,
beneficiary: genesis.coinbase,
base_fee_per_gas: genesis
.base_fee_per_gas
.map(|b| b.try_into().expect("base fee should fit in u64")),
withdrawals_root: None,
parent_beacon_block_root: None,
blob_gas_used: None,
excess_blob_gas: None,
requests_hash: None,
..Default::default()
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/scroll/chainspec/src/scroll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub static SCROLL_MAINNET: LazyLock<Arc<ScrollChainSpec>> = LazyLock::new(|| {
// TODO(scroll): migrate to Chain::scroll() (introduced in https://github.com/alloy-rs/chains/pull/112) when alloy-chains is bumped to version 0.1.48
chain: Chain::from_named(NamedChain::Scroll),
genesis_header: SealedHeader::new(
make_genesis_header(&genesis),
make_genesis_header(&genesis).inner,
SCROLL_MAINNET_GENESIS_HASH,
),
genesis,
Expand Down
2 changes: 1 addition & 1 deletion crates/scroll/chainspec/src/scroll_sepolia.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub static SCROLL_SEPOLIA: LazyLock<Arc<ScrollChainSpec>> = LazyLock::new(|| {
// TODO(scroll): migrate to Chain::scroll_sepolia() (introduced in https://github.com/alloy-rs/chains/pull/112) when alloy-chains is bumped to version 0.1.48
chain: Chain::from_named(NamedChain::ScrollSepolia),
genesis_header: SealedHeader::new(
make_genesis_header(&genesis),
make_genesis_header(&genesis).inner,
SCROLL_SEPOLIA_GENESIS_HASH,
),
genesis,
Expand Down
81 changes: 41 additions & 40 deletions crates/scroll/engine-primitives/src/payload/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use reth_engine_primitives::EngineTypes;
use reth_payload_primitives::{BuiltPayload, PayloadTypes};
use reth_primitives::{Block, BlockBody, Header};
use reth_primitives_traits::{NodePrimitives, SealedBlock};
use reth_scroll_primitives::ScrollBlock;
use reth_scroll_primitives::{ScrollBlock, ScrollHeader, ScrollTransactionSigned};
use scroll_alloy_hardforks::ScrollHardforks;
use scroll_alloy_rpc_types_engine::ScrollPayloadAttributes;

Expand Down Expand Up @@ -99,14 +99,14 @@ impl PayloadTypes for ScrollPayloadTypes {
/// Scroll implementation of the [`ExecutionPayload::try_into_block`], which will fail with
/// [`PayloadError::ExtraData`] due to the Scroll blocks containing extra data for the Clique
/// consensus.
pub fn try_into_block<T: Decodable2718, CS: ScrollHardforks>(
pub fn try_into_block<CS: ScrollHardforks>(
value: ExecutionData,
chainspec: Arc<CS>,
) -> Result<Block<T>, PayloadError> {
) -> Result<ScrollBlock, PayloadError> {
let mut block = match value.payload {
ExecutionPayload::V1(payload) => try_payload_v1_to_block(payload, chainspec)?,
ExecutionPayload::V2(payload) => try_payload_v2_to_block(payload, chainspec)?,
ExecutionPayload::V3(payload) => try_payload_v3_to_block(payload, chainspec)?,
ExecutionPayload::V1(payload) => try_payload_v1_to_block(payload, &*chainspec)?,
ExecutionPayload::V2(payload) => try_payload_v2_to_block(payload, &*chainspec)?,
ExecutionPayload::V3(payload) => try_payload_v3_to_block(payload, &*chainspec)?,
};

block.header.parent_beacon_block_root = value.sidecar.parent_beacon_block_root();
Expand All @@ -116,10 +116,10 @@ pub fn try_into_block<T: Decodable2718, CS: ScrollHardforks>(
}

/// Tries to convert an [`ExecutionPayloadV1`] to [`Block`].
fn try_payload_v1_to_block<T: Decodable2718, CS: ScrollHardforks>(
fn try_payload_v1_to_block<CS: ScrollHardforks>(
payload: ExecutionPayloadV1,
chainspec: CS,
) -> Result<Block<T>, PayloadError> {
) -> Result<ScrollBlock, PayloadError> {
// WARNING: It’s allowed for a base fee in EIP1559 to increase unbounded. We assume that
// it will fit in an u64. This is not always necessarily true, although it is extremely
// unlikely not to be the case, a u64 maximum would have 2^64 which equates to 18 ETH per
Expand All @@ -137,7 +137,7 @@ fn try_payload_v1_to_block<T: Decodable2718, CS: ScrollHardforks>(
.map(|tx| {
let mut buf = tx.as_ref();

let tx = T::decode_2718(&mut buf).map_err(alloy_rlp::Error::from)?;
let tx = ScrollTransactionSigned::decode_2718(&mut buf).map_err(alloy_rlp::Error::from)?;

if !buf.is_empty() {
return Err(alloy_rlp::Error::UnexpectedLength);
Expand All @@ -153,39 +153,41 @@ fn try_payload_v1_to_block<T: Decodable2718, CS: ScrollHardforks>(
buf.put_slice(item)
});

let header = Header {
parent_hash: payload.parent_hash,
beneficiary: payload.fee_recipient,
state_root: payload.state_root,
transactions_root,
receipts_root: payload.receipts_root,
withdrawals_root: None,
logs_bloom: payload.logs_bloom,
number: payload.block_number,
gas_limit: payload.gas_limit,
gas_used: payload.gas_used,
timestamp: payload.timestamp,
mix_hash: payload.prev_randao,
base_fee_per_gas: basefee,
blob_gas_used: None,
excess_blob_gas: None,
parent_beacon_block_root: None,
requests_hash: None,
extra_data: payload.extra_data,
// Defaults
ommers_hash: EMPTY_OMMER_ROOT_HASH,
difficulty: U256::ONE,
nonce: Default::default(),
let header = ScrollHeader {
inner: Header {
parent_hash: payload.parent_hash,
beneficiary: payload.fee_recipient,
state_root: payload.state_root,
transactions_root,
receipts_root: payload.receipts_root,
withdrawals_root: None,
logs_bloom: payload.logs_bloom,
number: payload.block_number,
gas_limit: payload.gas_limit,
gas_used: payload.gas_used,
timestamp: payload.timestamp,
mix_hash: payload.prev_randao,
base_fee_per_gas: basefee,
blob_gas_used: None,
excess_blob_gas: None,
parent_beacon_block_root: None,
requests_hash: None,
extra_data: payload.extra_data,
// Defaults
ommers_hash: EMPTY_OMMER_ROOT_HASH,
difficulty: U256::ONE,
nonce: Default::default(),
}
};

Ok(Block { header, body: BlockBody { transactions, ..Default::default() } })
}

/// Tries to convert an [`ExecutionPayloadV2`] to [`Block`].
fn try_payload_v2_to_block<T: Decodable2718, CS: ScrollHardforks>(
fn try_payload_v2_to_block<CS: ScrollHardforks>(
payload: ExecutionPayloadV2,
chainspec: CS,
) -> Result<Block<T>, PayloadError> {
) -> Result<ScrollBlock, PayloadError> {
// this performs the same conversion as the underlying V1 payload, but calculates the
// withdrawals root and adds withdrawals
let mut base_sealed_block = try_payload_v1_to_block(payload.payload_inner, chainspec)?;
Expand All @@ -196,10 +198,10 @@ fn try_payload_v2_to_block<T: Decodable2718, CS: ScrollHardforks>(
}

/// Tries to convert an [`ExecutionPayloadV3`] to [`Block`].
fn try_payload_v3_to_block<T: Decodable2718, CS: ScrollHardforks>(
fn try_payload_v3_to_block<CS: ScrollHardforks>(
payload: ExecutionPayloadV3,
chainspec: CS,
) -> Result<Block<T>, PayloadError> {
) -> Result<ScrollBlock, PayloadError> {
// this performs the same conversion as the underlying V2 payload, but inserts the blob gas
// used and excess blob gas
let mut base_block = try_payload_v2_to_block(payload.payload_inner, chainspec)?;
Expand All @@ -218,7 +220,6 @@ mod tests {
use arbitrary::{Arbitrary, Unstructured};
use rand::Rng;
use reth_scroll_chainspec::SCROLL_MAINNET;
use reth_scroll_primitives::ScrollTransactionSigned;

#[test]
fn test_can_convert_execution_v1_payload_into_block() -> eyre::Result<()> {
Expand Down Expand Up @@ -247,7 +248,7 @@ mod tests {
});
let execution_data = ExecutionData::new(execution_payload, Default::default());

let _: Block<ScrollTransactionSigned> =
let _: ScrollBlock =
try_into_block(execution_data, SCROLL_MAINNET.clone())?;

Ok(())
Expand Down Expand Up @@ -283,7 +284,7 @@ mod tests {
});
let execution_data = ExecutionData::new(execution_payload, Default::default());

let _: Block<ScrollTransactionSigned> =
let _: ScrollBlock =
try_into_block(execution_data, SCROLL_MAINNET.clone())?;

Ok(())
Expand Down Expand Up @@ -323,7 +324,7 @@ mod tests {
});
let execution_data = ExecutionData::new(execution_payload, Default::default());

let _: Block<ScrollTransactionSigned> =
let _: ScrollBlock =
try_into_block(execution_data, SCROLL_MAINNET.clone())?;

Ok(())
Expand Down
Loading
Loading