Skip to content

feat: consensus #68

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 13 commits into from
Apr 24, 2025
53 changes: 22 additions & 31 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -143,6 +143,7 @@ reth-network = { git = "https://github.com/scroll-tech/reth.git", default-featur
reth-network-api = { git = "https://github.com/scroll-tech/reth.git", default-features = false }
reth-network-peers = { git = "https://github.com/scroll-tech/reth.git", default-features = false }
reth-primitives = { git = "https://github.com/scroll-tech/reth.git", default-features = false }
reth-primitives-traits = { git = "https://github.com/scroll-tech/reth.git", default-features = false }
reth-provider = { git = "https://github.com/scroll-tech/reth.git", default-features = false }
reth-tasks = { git = "https://github.com/scroll-tech/reth.git" }
reth-tokio-util = { git = "https://github.com/scroll-tech/reth.git", default-features = false }
@@ -180,7 +181,6 @@ futures = { version = "0.3", default-features = false }
parking_lot = "0.12"
rand = { version = "0.9" }
reqwest = "0.12"
secp256k1 = { version = "0.29", default-features = false }
serde = { version = "1.0" }
sea-orm = { version = "1.1.0" }
thiserror = "2.0"
4 changes: 1 addition & 3 deletions bin/rollup/Cargo.toml
Original file line number Diff line number Diff line change
@@ -9,8 +9,8 @@ exclude.workspace = true
[dependencies]
# alloy
alloy-chains.workspace = true
alloy-provider.workspace = true
alloy-primitives.workspace = true
alloy-provider.workspace = true
alloy-rpc-types-engine.workspace = true
alloy-rpc-client.workspace = true
alloy-transport.workspace = true
@@ -58,7 +58,6 @@ rollup-node-watcher.workspace = true
clap = { version = "4", features = ["derive", "env"] }
eyre.workspace = true
reqwest = { version = "0.12", default-features = false }
secp256k1 = { workspace = true, features = ["global-context", "recovery"] }
tokio = { workspace = true, features = ["full"] }
tracing.workspace = true

@@ -110,7 +109,6 @@ serde = [
"scroll-engine/serde",
"scroll-network/serde",
"scroll-wire/serde",
"secp256k1/serde",
"rollup-node-manager/serde",
"alloy-chains/serde",
"reth-transaction-pool/serde",
3 changes: 3 additions & 0 deletions bin/rollup/src/args.rs
Original file line number Diff line number Diff line change
@@ -6,6 +6,9 @@ use std::path::PathBuf;
/// A struct that represents the arguments for the rollup node.
#[derive(Debug, clap::Args)]
pub struct ScrollRollupNodeArgs {
/// Whether the rollup node should be run in test mode.
#[arg(long)]
pub test: bool,
/// A bool to represent if new blocks should be bridged from the eth wire protocol to the
/// scroll wire protocol.
#[arg(long, default_value_t = false)]
6 changes: 3 additions & 3 deletions bin/rollup/src/import.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
use alloy_primitives::Signature;
use reth_network::import::{BlockImport as RethBlockImport, NewBlockEvent};
use reth_network_peers::PeerId;
use reth_scroll_primitives::ScrollBlock;
use scroll_network::NewBlockWithPeer;
use secp256k1::ecdsa::Signature;
use std::{
sync::Arc,
task::{Context, Poll},
};
use tokio::sync::mpsc::UnboundedSender;
use tracing::{trace, warn};

const ECDSA_SIGNATURE_LEN: usize = 64;
const ECDSA_SIGNATURE_LEN: usize = 65;

/// A block import implementation for the eth-wire protocol that sends block to the scroll-wire
/// protocol.
@@ -42,7 +42,7 @@ impl BridgeBlockImport {
if let Some(signature) = extra_data
.len()
.checked_sub(ECDSA_SIGNATURE_LEN)
.and_then(|i| Signature::from_compact(&extra_data[i..]).ok())
.and_then(|i| Signature::from_raw(&extra_data[i..]).ok())
{
let block = block.block.clone();
trace!(target: "scroll::bridge::import", peer_id = %peer_id, block = ?block.hash_slow(), "Received new block from eth-wire protocol");
43 changes: 34 additions & 9 deletions bin/rollup/src/network.rs
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@ use reth_rpc_builder::config::RethRpcServerConfig;
use reth_scroll_chainspec::ScrollChainSpec;
use reth_scroll_primitives::ScrollPrimitives;
use reth_transaction_pool::{PoolTransaction, TransactionPool};
use rollup_node_manager::{PoAConsensus, RollupNodeManager};
use rollup_node_manager::{Consensus, NoopConsensus, PoAConsensus, RollupNodeManager};
use rollup_node_providers::{beacon_provider, DatabaseL1MessageProvider, OnlineL1Provider};
use rollup_node_sequencer::Sequencer;
use rollup_node_watcher::L1Watcher;
@@ -90,18 +90,21 @@ where
// Create the scroll network manager.
let scroll_network_manager = ScrollNetworkManager::from_parts(handle.clone(), events);

// Spawn the scroll network manager.
let consensus = PoAConsensus::new(vec![]);
let payload_provider = NoopExecutionPayloadProvider;

// Spawn the engine driver.
let auth_port = ctx.config().rpc.auth_port;
let auth_secret = ctx.config().rpc.auth_jwt_secret(ctx.config().datadir().jwt())?;

let engine_api = ScrollAuthEngineApiProvider::new(
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_hash());
let payload_provider = NoopExecutionPayloadProvider;

let fcs = if let Some(named) = ctx.config().chain.chain.named() {
ForkchoiceState::head_from_named_chain(named)
} else {
ForkchoiceState::head_from_genesis(ctx.config().chain.genesis_header().hash_slow())
};
let engine = EngineDriver::new(
Arc::new(engine_api),
Arc::new(payload_provider),
@@ -130,7 +133,7 @@ where
let chain_spec = ctx.chain_spec();

// Spawn the L1Watcher
let l1_notification_rx = if let Some(l1_rpc_url) = self.config.l1_provider_args.l1_rpc_url {
let provider = if let Some(url) = self.config.l1_provider_args.l1_rpc_url {
let L1ProviderArgs { max_retries, initial_backoff, compute_units_per_second, .. } =
self.config.l1_provider_args;
let client = RpcClient::builder()
@@ -139,8 +142,30 @@ where
initial_backoff,
compute_units_per_second,
))
.http(l1_rpc_url);
let provider = ProviderBuilder::new().on_client(client);
.http(url);
Some(ProviderBuilder::new().on_client(client))
} else {
None
};

// Create the consensus.
let consensus: Box<dyn Consensus> = if self.config.test {
Box::new(NoopConsensus::default())
} else {
let mut poa = PoAConsensus::new(vec![]);
if let Some(ref provider) = provider {
// Initialize the consensus
poa.initialize(
provider,
ctx.config().chain.chain.named().expect("expected named chain"),
)
.await;
}
Box::new(poa)
};

let l1_notification_rx = if let Some(provider) = provider {
// Spawn the L1Watcher
Some(L1Watcher::spawn(provider, WATCHER_START_BLOCK_NUMBER).await)
} else {
None
1 change: 1 addition & 0 deletions bin/rollup/tests/e2e.rs
Original file line number Diff line number Diff line change
@@ -133,6 +133,7 @@ pub async fn build_bridge_node(
// Create the node for a bridge node that will bridge messages from the eth-wire protocol
// to the scroll-wire protocol.
let node_args = ScrollRollupNodeArgs {
test: true,
enable_eth_scroll_wire_bridge: true,
enable_scroll_wire: true,
database_path: Some(PathBuf::from("sqlite::memory:")),
2 changes: 1 addition & 1 deletion crates/engine/src/driver.rs
Original file line number Diff line number Diff line change
@@ -65,7 +65,7 @@ where

Copy link
Collaborator Author

@greged93 greged93 Apr 24, 2025

Choose a reason for hiding this comment

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

I know we talked about reintroducing these lines of code:

        if self.forkchoice_state.is_genesis() {
            let block_num_hash = block.parent_num_hash();
            self.forkchoice_state = ForkchoiceState::from_block_info(BlockInfo {
                number: block_num_hash.number,
                hash: block_num_hash.hash,
            });
        }

and I tried running the node with them, but I didn't see any trigger of the pipeline sync. I think what happened is that it hits this path in the match, meaning it doesn't trigger a sync. My opinion is to keep the code as is, and implement a EL sync and CL sync similar to what optimism are doing.

EDIT: forgot to link the code in Reth.
https://github.com/scroll-tech/reth/blob/1b8ff78f46d5e95dd10876fd8145c27db598a0b0/crates/engine/tree/src/tree/mod.rs#L2075

/// Sets the finalized block info.
pub fn set_finalized_block_info(&mut self, block_info: BlockInfo) {
self.fcs.update_safe_block_info(block_info);
self.fcs.update_finalized_block_info(block_info);
}

/// Sets the payload building duration.
Loading