Skip to content

feat: integrate sequencer with node #65

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 68 commits into from
Apr 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
a04f6b7
test: move calldata to files
greged93 Mar 21, 2025
4c328cc
feat: batch header decoding
greged93 Mar 21, 2025
53af94f
feat: improve codec interface
greged93 Mar 21, 2025
c17d65e
chore: manifests fixes
greged93 Mar 21, 2025
a2929e0
feat: revert some codec changes
greged93 Mar 24, 2025
05cc350
feat: wip derivation pipeline
greged93 Mar 24, 2025
54a557c
feat: batch header v7
greged93 Mar 24, 2025
a5e31c9
feat: add batch abstraction
greged93 Mar 24, 2025
57c0992
feat: basic derivation pipeline
greged93 Mar 24, 2025
2edae45
feat: implement batch data hash
greged93 Mar 24, 2025
113f18e
feat: move PayloadData
greged93 Mar 25, 2025
9186662
feat: improve batch data hash computation
greged93 Mar 25, 2025
42bbace
test: derivation
greged93 Mar 25, 2025
50962ca
chore: cleaning
greged93 Mar 25, 2025
2aa6b85
fix: lints
greged93 Mar 25, 2025
32e56fc
fix: lints
greged93 Mar 25, 2025
2f56e24
fix: skip wasm for derivation pipeline
greged93 Mar 25, 2025
fb85ecf
fix: data hash computation for batch
greged93 Mar 26, 2025
6341957
Merge branch 'main' into feat/derivation-pipeline
greged93 Mar 26, 2025
23be55b
fix: lint
greged93 Mar 26, 2025
df9d787
fix: lint
greged93 Mar 26, 2025
4bba46d
fix: lints
greged93 Mar 26, 2025
485f66c
fix: answer comments
greged93 Apr 1, 2025
b1b223e
fix: lints
greged93 Apr 1, 2025
1cf831a
feat: wip
greged93 Mar 25, 2025
f1de162
feat: changes to the data model
greged93 Mar 26, 2025
86f3880
fix: codec issue
greged93 Mar 26, 2025
a8f18d9
feat: modify derivation pipeline to fetch blob
greged93 Mar 26, 2025
d5c7313
test: move test data to file
greged93 Mar 26, 2025
3a6da41
fix: lints
greged93 Mar 26, 2025
eeb7a63
fix: answer comments
greged93 Apr 1, 2025
52f35cf
test: fix migration
greged93 Apr 1, 2025
0e5fa79
Merge branch 'main' into feat/integrate-batch-changes
greged93 Apr 2, 2025
72831db
fix: comments
greged93 Apr 2, 2025
82cbcac
feat: providers crate
greged93 Mar 26, 2025
27c0c59
feat: l1 providers crate
greged93 Mar 26, 2025
e5be688
feat: l1 provider implementation
greged93 Mar 27, 2025
b4188fa
feat: l1 message provider
greged93 Mar 27, 2025
59c1603
feat: pipeline modifications
greged93 Mar 27, 2025
58c1e8e
fix: avoid iterating the cache
greged93 Mar 27, 2025
b47d913
chore: simplify derivation pipeline interface
greged93 Apr 1, 2025
1ceab4f
fix: lints
greged93 Apr 1, 2025
1fe124e
fix: rebasing
greged93 Apr 1, 2025
aca4f24
fix: answer comments
greged93 Apr 2, 2025
2778837
feat: add sequencer
frisitano Apr 3, 2025
0a55743
sequencer initial implementation
frisitano Apr 7, 2025
5b73485
Merge branch 'main' into feat/sequencer
frisitano Apr 7, 2025
1ffad5f
sequencer implementation
frisitano Apr 9, 2025
0625ba0
sequencer implementation
frisitano Apr 9, 2025
57be97d
Merge branch 'main' into feat/sequencer
frisitano Apr 9, 2025
1655bee
refactor sequencer provider
frisitano Apr 10, 2025
906dac6
sequencer implementation
frisitano Apr 10, 2025
6b42b1b
lint
frisitano Apr 10, 2025
cde0bef
lint deps
frisitano Apr 10, 2025
c4a7453
address comments
frisitano Apr 11, 2025
f21edce
feat: sequencer integration
frisitano Apr 17, 2025
5c3858d
Merge branch 'main' into feat/sequencer-rnm-integration
frisitano Apr 17, 2025
aef55ba
remove redundant file
frisitano Apr 17, 2025
47337da
add std feature for scroll-reth-primitives
frisitano Apr 17, 2025
dee0907
comments and clean up
frisitano Apr 18, 2025
dd0fb48
feat: L1 message delay
frisitano Apr 18, 2025
74feda5
feat: integrate sequencer with node
frisitano Apr 22, 2025
08f9173
Merge branch 'main' into feat/integrate-sequencer-with-node
frisitano Apr 23, 2025
30d8e4b
merge conflict resoltuion
frisitano Apr 23, 2025
7932b42
chore: introduce README and repoint deps
frisitano Apr 23, 2025
431cf03
Merge branch 'main' into feat/integrate-sequencer-with-node
frisitano Apr 24, 2025
322e07e
address feedback
frisitano Apr 24, 2025
51abcb2
lints
frisitano Apr 24, 2025
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
602 changes: 299 additions & 303 deletions Cargo.lock

Large diffs are not rendered by default.

160 changes: 159 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,159 @@
# rollup-node
# Scroll Rollup Node Workspace

[![test](https://github.com/scroll-tech/rollup-node/actions/workflows/test.yaml/badge.svg)](https://github.com/scroll-tech/rollup-node/actions/workflows/test.yaml)
[![lint](https://github.com/scroll-tech/rollup-node/actions/workflows/lint.yaml/badge.svg)](https://github.com/scroll-tech/rollup-node/actions/workflows/lint.yaml)
![License](https://img.shields.io/badge/license-MIT-blue)
![Rust](https://img.shields.io/badge/rust-2021-orange)

## Overview

This repository is a modular Rust workspace for the Scroll rollup node. It is designed for extensibility, maintainability, and ease of contribution. It consists of multiple internal crates (libraries) and a main binary crate, organized for clear separation of concerns and reusability.

## Directory Structure

```
.
├── bin/
│ └── rollup/ # Main binary crate (the node)
│ ├── src/
│ └── assets/
├── crates/ # Internal library crates
│ ├── codec/
│ ├── database/
│ │ ├── db/
│ │ └── migration/
│ ├── derivation-pipeline/
│ ├── engine/
│ ├── indexer/
│ ├── l1/
│ ├── network/
│ ├── node/
│ ├── primitives/
│ ├── providers/
│ ├── scroll-wire/
│ ├── sequencer/
│ └── watcher/
├── Cargo.toml # Workspace manifest
└── ...
```

## Crate Descriptions

- **bin/rollup/**: The main binary crate. This is the entry point for running the rollup node.
- **crates/codec/**: Implements encoding/decoding logic for rollup data and payloads.
- **crates/database/db/**: Database abstraction and storage logic for batches, blocks, and messages.
- **crates/database/migration/**: Database schema migrations using SeaORM.
- **crates/derivation-pipeline/**: Stateless pipeline for transforming batches into block-building payloads.
- **crates/engine/**: Core engine logic for block execution, fork choice, and payload management.
- **crates/indexer/**: Indexes L1 and L2 data for efficient querying and notification.
- **crates/l1/**: Primitives and ABI bindings for L1 contracts and messages.
- **crates/network/**: P2P networking stack for node communication.
- **crates/node/**: Node manager and orchestration logic.
- **crates/primitives/**: Shared primitive types (blocks, batches, attributes, etc.).
- **crates/providers/**: Abstractions for data providers (L1, beacon, block, etc.).
- **crates/scroll-wire/**: Wire protocol definitions for Scroll-specific networking.
- **crates/sequencer/**: Sequencer logic for ordering and batching transactions.
- **crates/watcher/**: Monitors L1 chain state and handles reorgs and notifications.

## Building the Project

Ensure you have [Rust](https://www.rust-lang.org/tools/install) installed.

To build the main binary:

```sh
cargo build --bin rollup-node
```

Or, from the binary crate directory:

```sh
cd bin/rollup
cargo build
```

## Running the Node

After building, run the node with:

```sh
cargo run --workspace --bin rollup-node -- [ARGS]
```

Replace `[ARGS]` with any runtime arguments you require.

## Running Tests

To run all tests across the workspace:

```sh
make test
```

To test a specific crate:

```sh
cargo test -p <crate-name>
```

## Running Lints

To run all lints across the workspace:

```sh
make lint
```

## Building a Release Binary

For optimized production builds:

```sh
cargo build --release --bin rollup-node
```

The release binary will be located at `target/release/rollup-node`.

## Running a Sequencer Node

To run a sequencer node you should build the binary in release mode using the instructions defined above.

Then, you can run the sequencer node with the following command:

```sh
./target/release/rollup-node node --chain dev -d --scroll-sequencer-enabled --http --http.api admin,debug,eth,net,trace,txpool,web3,rpc,reth,ots,flashbots,miner,mev
```

This will start a dev node in sequencer mode with all rpc apis enabled. You can adjust the `--http.api` flag to include or exclude specific APIs as needed.

The chain will be configured with a genesis that funds 20 addresses derived from the mnemonic:
```
test test test test test test test test test test test junk
```


A list of sequencer specific configuration options can be seen below:

```sh
--scroll-sequencer-enabled
Enable the scroll block sequencer
--scroll-block-time <SCROLL_BLOCK_TIME>
The block time for the sequencer [default: 2000]
--payload-building-duration <PAYLOAD_BUILDING_DURATION>
The payload building duration for the sequencer (milliseconds) [default: 500]
--max-l1-messages-per-block <MAX_L1_MESSAGES_PER_BLOCK>
The max L1 messages per block for the sequencer [default: 4]
--fee-recipient <FEE_RECIPIENT>
The fee recipient for the sequencer [default: 0x5300000000000000000000000000000000000005]
```

## Contributing

- Fork and clone the repository.
- Use `make pr` to ensure code quality.
- Submit pull requests with clear descriptions.
- See each crate's README or source for more details on its purpose and usage.

---

For more details, see the documentation in each crate or open an issue if you have questions!
2 changes: 1 addition & 1 deletion bin/rollup/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ serde_json = { version = "1.0.94", default-features = false, features = ["alloc"
tokio = { workspace = true, features = ["full"] }

[features]
default = ["serde"]
test-utils = [
"reth-network/test-utils",
"reth-node-builder/test-utils",
Expand Down Expand Up @@ -118,4 +119,3 @@ serde = [
[[bin]]
name = "rollup-node"
path = "src/main.rs"
required-features = ["serde"]
24 changes: 14 additions & 10 deletions bin/rollup/src/args.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::constants;
use alloy_primitives::Address;
use reth_scroll_chainspec::SCROLL_FEE_VAULT_ADDRESS;
use std::path::PathBuf;

/// A struct that represents the arguments for the rollup node.
Expand All @@ -23,7 +24,7 @@ pub struct ScrollRollupNodeArgs {
pub l1_provider_args: L1ProviderArgs,
/// The sequencer arguments
#[command(flatten)]
pub sequencer_args: Option<SequencerArgs>,
pub sequencer_args: SequencerArgs,
}

#[derive(Debug, clap::Args)]
Expand All @@ -33,9 +34,9 @@ pub struct L1ProviderArgs {
pub l1_rpc_url: Option<reqwest::Url>,
/// The URL for the Beacon RPC URL.
#[arg(long)]
pub beacon_rpc_url: reqwest::Url,
pub beacon_rpc_url: Option<reqwest::Url>,
/// The compute units per second for the provider.
#[arg(long)]
#[arg(long, default_value_t = constants::PROVIDER_COMPUTE_UNITS_PER_SECOND)]
pub compute_units_per_second: u64,
/// The max amount of retries for the provider.
#[arg(long, default_value_t = constants::PROVIDER_MAX_RETRIES)]
Expand All @@ -45,18 +46,21 @@ pub struct L1ProviderArgs {
pub initial_backoff: u64,
}

#[derive(Debug, Clone, clap::Args)]
#[derive(Debug, Default, clap::Args)]
pub struct SequencerArgs {
/// Enable the scroll block sequencer.
#[arg(long, default_value_t = false)]
pub scroll_sequencer_enabled: bool,
/// The block time for the sequencer.
#[arg(long)]
pub block_time: u64,
#[arg(long, default_value_t = constants::DEFAULT_BLOCK_TIME)]
pub scroll_block_time: u64,
/// The payload building duration for the sequencer (milliseconds)
#[arg(long)]
#[arg(long, default_value_t = constants::DEFAULT_PAYLOAD_BUILDING_DURATION)]
pub payload_building_duration: u64,
/// The max L1 messages per block for the sequencer.
#[arg(long)]
#[arg(long, default_value_t = constants::DEFAULT_MAX_L1_MESSAGES_PER_BLOCK)]
pub max_l1_messages_per_block: u64,
/// The fee recipient for the sequencer.
#[arg(long)]
pub fee_recipient: Option<Address>,
#[arg(long, default_value_t = SCROLL_FEE_VAULT_ADDRESS)]
pub fee_recipient: Address,
}
12 changes: 12 additions & 0 deletions bin/rollup/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,15 @@ pub const PROVIDER_MAX_RETRIES: u32 = 10;

/// The initial backoff for the L1 provider.
pub const PROVIDER_INITIAL_BACKOFF: u64 = 100;

/// The default provider compute units per second.
pub const PROVIDER_COMPUTE_UNITS_PER_SECOND: u64 = 50;

/// The default block time in milliseconds for the sequencer.
pub const DEFAULT_BLOCK_TIME: u64 = 2000;

/// The default payload building duration in milliseconds for the sequencer.
pub const DEFAULT_PAYLOAD_BUILDING_DURATION: u64 = 500;

/// The default max L1 messages per block for the sequencer.
pub const DEFAULT_MAX_L1_MESSAGES_PER_BLOCK: u64 = 4;
44 changes: 21 additions & 23 deletions bin/rollup/src/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,19 +101,12 @@ where
auth_secret,
self.config.engine_api_url.unwrap_or(format!("http://localhost:{auth_port}").parse()?),
);
let fcs =
ForkchoiceState::head_from_genesis(ctx.config().chain.genesis_header().hash_slow());
let fcs = ForkchoiceState::head_from_genesis(ctx.config().chain.genesis_hash());
let engine = EngineDriver::new(
Arc::new(engine_api),
Arc::new(payload_provider),
fcs,
Duration::from_millis(
self.config
.sequencer_args
.as_ref()
.map(|args| args.payload_building_duration)
.unwrap_or(0),
),
Duration::from_millis(self.config.sequencer_args.payload_building_duration),
);

// Instantiate the database
Expand All @@ -137,10 +130,9 @@ where
let chain_spec = ctx.chain_spec();

// Spawn the L1Watcher
let l1_provider_args = self.config.l1_provider_args;
let l1_notification_rx = if let Some(l1_rpc_url) = l1_provider_args.l1_rpc_url {
let l1_notification_rx = if let Some(l1_rpc_url) = self.config.l1_provider_args.l1_rpc_url {
let L1ProviderArgs { max_retries, initial_backoff, compute_units_per_second, .. } =
l1_provider_args;
self.config.l1_provider_args;
let client = RpcClient::builder()
.layer(RetryBackoffLayer::new(
max_retries,
Expand All @@ -155,25 +147,31 @@ where
};

// Construct the l1 provider.
let beacon_provider = beacon_provider(l1_provider_args.beacon_rpc_url.to_string());
let l1_messages_provider = DatabaseL1MessageProvider::new(db.clone(), 0);
let l1_provider = OnlineL1Provider::new(
beacon_provider,
PROVIDER_BLOB_CACHE_SIZE,
l1_messages_provider.clone(),
)
.await;
let l1_provider = if let Some(url) = self.config.l1_provider_args.beacon_rpc_url {
let beacon_provider = beacon_provider(url.to_string());
let l1_provider = OnlineL1Provider::new(
beacon_provider,
PROVIDER_BLOB_CACHE_SIZE,
l1_messages_provider.clone(),
)
.await;
Some(l1_provider)
} else {
None
};

// Construct the Sequencer.
let (sequencer, block_time) = if let Some(args) = self.config.sequencer_args {
let (sequencer, block_time) = if self.config.sequencer_args.scroll_sequencer_enabled {
let args = &self.config.sequencer_args;
let sequencer = Sequencer::new(
Arc::new(l1_messages_provider),
args.fee_recipient.unwrap_or_default(),
args.fee_recipient,
args.max_l1_messages_per_block,
0,
0,
);
(Some(sequencer), Some(args.block_time))
(Some(sequencer), Some(args.scroll_block_time))
} else {
(None, None)
};
Expand All @@ -192,7 +190,7 @@ where
block_time,
);

ctx.task_executor().spawn(rollup_node_manager);
ctx.task_executor().spawn_critical("rollup_node_manager", rollup_node_manager);

info!(target: "scroll::reth::cli", enode=%handle.local_node_record(), "P2P networking initialized");
Ok(handle)
Expand Down
10 changes: 6 additions & 4 deletions bin/rollup/tests/e2e.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use reth_scroll_chainspec::ScrollChainSpec;
use reth_scroll_engine_primitives::ScrollPayloadBuilderAttributes;
use reth_scroll_node::{ScrollNetworkPrimitives, ScrollNode};
use reth_tasks::TaskManager;
use rollup_node::{L1ProviderArgs, ScrollRollupNodeArgs};
use rollup_node::{L1ProviderArgs, ScrollRollupNodeArgs, SequencerArgs};
use scroll_alloy_rpc_types_engine::ScrollPayloadAttributes;
use scroll_network::{NewBlockWithPeer, SCROLL_MAINNET};
use scroll_wire::ScrollWireConfig;
Expand Down Expand Up @@ -138,14 +138,16 @@ pub async fn build_bridge_node(
database_path: Some(PathBuf::from("sqlite::memory:")),
l1_provider_args: L1ProviderArgs {
l1_rpc_url: None,
// <https://docs.arbitrum.io/run-arbitrum-node/l1-ethereum-beacon-chain-rpc-providers>
beacon_rpc_url: reqwest::Url::parse("https://eth-beacon-chain.drpc.org/rest/")?,
beacon_rpc_url: None,
compute_units_per_second: 100,
max_retries: 10,
initial_backoff: 100,
},
engine_api_url: None,
sequencer_args: None,
sequencer_args: SequencerArgs {
scroll_sequencer_enabled: false,
..SequencerArgs::default()
},
};
let node = ScrollNode;
let NodeHandle { node, node_exit_future: _ } = NodeBuilder::new(node_config.clone())
Expand Down
Loading