Skip to content

feat: update scroll consensus #314

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Aug 18, 2025
Merged
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
2 changes: 2 additions & 0 deletions Cargo.lock

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

4 changes: 2 additions & 2 deletions crates/scroll/alloy/consensus/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ extern crate alloc as std;
mod transaction;
pub use transaction::{
ScrollAdditionalInfo, ScrollL1MessageTransactionFields, ScrollPooledTransaction,
ScrollTransactionInfo, ScrollTxEnvelope, ScrollTxType, ScrollTypedTransaction, TxL1Message,
L1_MESSAGE_TRANSACTION_TYPE, L1_MESSAGE_TX_TYPE_ID,
ScrollTransaction, ScrollTransactionInfo, ScrollTxEnvelope, ScrollTxType,
ScrollTypedTransaction, TxL1Message, L1_MESSAGE_TRANSACTION_TYPE, L1_MESSAGE_TX_TYPE_ID,
};

mod receipt;
Expand Down
24 changes: 24 additions & 0 deletions crates/scroll/alloy/consensus/src/transaction/envelope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,30 @@ impl ScrollTxEnvelope {
}
}

/// A Scroll chain transaction.
pub trait ScrollTransaction {
/// Returns true if the transaction is a L1 message.
fn is_l1_message(&self) -> bool;
/// Returns the queue index if the transaction is a L1 message, None otherwise.
fn queue_index(&self) -> Option<u64>;
}

impl ScrollTransaction for ScrollTxEnvelope {
fn is_l1_message(&self) -> bool {
match self {
Self::Legacy(_) | Self::Eip2930(_) | Self::Eip1559(_) | Self::Eip7702(_) => false,
Self::L1Message(_) => true,
}
}

fn queue_index(&self) -> Option<u64> {
match self {
Self::Legacy(_) | Self::Eip2930(_) | Self::Eip1559(_) | Self::Eip7702(_) => None,
Self::L1Message(tx) => Some(tx.queue_index),
}
}
}

#[cfg(feature = "reth-codec")]
impl ToTxCompact for ScrollTxEnvelope {
fn to_tx_compact(&self, buf: &mut (impl BufMut + AsMut<[u8]>)) {
Expand Down
2 changes: 1 addition & 1 deletion crates/scroll/alloy/consensus/src/transaction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ mod tx_type;
pub use tx_type::{ScrollTxType, L1_MESSAGE_TX_TYPE_ID};

mod envelope;
pub use envelope::ScrollTxEnvelope;
pub use envelope::{ScrollTransaction, ScrollTxEnvelope};

mod l1_message;
pub use l1_message::{ScrollL1MessageTransactionFields, TxL1Message, L1_MESSAGE_TRANSACTION_TYPE};
Expand Down
6 changes: 5 additions & 1 deletion crates/scroll/consensus/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ workspace = true
[dependencies]
# alloy
alloy-consensus.workspace = true
alloy-primitives.workspace = true
alloy-primitives = { workspace = true, features = ["getrandom"] }

# reth
reth-chainspec.workspace = true
Expand All @@ -26,6 +26,7 @@ reth-primitives-traits.workspace = true

# scroll
reth-scroll-primitives = { workspace = true, default-features = false }
scroll-alloy-consensus.workspace = true
scroll-alloy-hardforks.workspace = true

# misc
Expand All @@ -34,3 +35,6 @@ tracing.workspace = true

[package.metadata.cargo-udeps.ignore]
normal = ["reth-primitives"]

[dev-dependencies]
reth-scroll-chainspec.workspace = true
9 changes: 9 additions & 0 deletions crates/scroll/consensus/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,12 @@ use alloy_primitives::U256;

/// The maximum value Rollup fee.
pub const MAX_ROLLUP_FEE: U256 = U256::from_limbs([u64::MAX, 0, 0, 0]);

/// The block difficulty for in turn signing in the Clique consensus.
pub const CLIQUE_IN_TURN_DIFFICULTY: U256 = U256::from_limbs([2, 0, 0, 0]);

/// The block difficulty for out of turn signing in the Clique consensus.
pub const CLIQUE_NO_TURN_DIFFICULTY: U256 = U256::from_limbs([1, 0, 0, 0]);

/// Maximum allowed base fee. We would only go above this if L1 base fee hits 2931 Gwei.
pub const SCROLL_MAXIMUM_BASE_FEE: u64 = 10000000000;
48 changes: 48 additions & 0 deletions crates/scroll/consensus/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
use crate::constants::SCROLL_MAXIMUM_BASE_FEE;

use alloy_primitives::{Address, B256, B64, U256};
use reth_consensus::ConsensusError;

/// Scroll consensus error.
Expand All @@ -6,10 +9,55 @@ pub enum ScrollConsensusError {
/// L1 [`ConsensusError`], that also occurs on L2.
#[error(transparent)]
Eth(#[from] ConsensusError),
/// Invalid L1 messages order.
#[error("invalid L1 message order")]
InvalidL1MessageOrder,
/// Block has non zero coinbase.
#[error("block coinbase not zero: {0}")]
CoinbaseNotZero(Address),
/// Block has non zero nonce.
#[error("block nonce not zero: {0:?}")]
NonceNotZero(Option<B64>),
/// Block has invalid clique nonce.
#[error("block nonce should be 0x0 or 0xffffffffffffffff: {0:?}")]
InvalidCliqueNonce(Option<B64>),
/// Block has non zero mix hash.
#[error("block mix hash not zero: {0:?}")]
MixHashNotZero(Option<B256>),
/// Block difficulty is not one.
#[error("block difficulty not one: {0}")]
DifficultyNotOne(U256),
/// Block has invalid clique difficulty.
#[error("block difficulty should be 1 or 2: {0}")]
InvalidCliqueDifficulty(U256),
/// Block extra data missing vanity.
#[error("block extra data missing vanity")]
MissingVanity,
/// Block extra data missing signature.
#[error("block extra data missing signature")]
MissingSignature,
/// Block extra data with invalid checkpoint signers.
#[error("block extra data contains invalid checkpoint signers")]
InvalidCheckpointSigners,
/// Block base fee present before Curie.
#[error("block base fee is set before Curie fork activation")]
UnexpectedBaseFee,
/// Block base fee over limit.
#[error("block base fee is over limit of {SCROLL_MAXIMUM_BASE_FEE}")]
BaseFeeOverLimit,
/// Block body has non-empty withdrawals list.
#[error("non-empty block body withdrawals list")]
WithdrawalsNonEmpty,
/// Chain spec yielded unexpected blob params.
#[error("unexpected blob params at timestamp")]
UnexpectedBlobParams,
}

impl From<ScrollConsensusError> for ConsensusError {
fn from(value: ScrollConsensusError) -> Self {
match value {
ScrollConsensusError::Eth(eth) => eth,
err => Self::Other(err.to_string()),
}
}
}
4 changes: 3 additions & 1 deletion crates/scroll/consensus/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
extern crate alloc;

mod constants;
pub use constants::MAX_ROLLUP_FEE;
pub use constants::{
CLIQUE_IN_TURN_DIFFICULTY, CLIQUE_NO_TURN_DIFFICULTY, MAX_ROLLUP_FEE, SCROLL_MAXIMUM_BASE_FEE,
};

mod error;
pub use error::ScrollConsensusError;
Expand Down
Loading
Loading