Skip to content

P2P Flashblocks Propagation #373

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

Draft
wants to merge 43 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
147c01f
wip
0xForerunner Jul 9, 2025
14c4297
wip
0xForerunner Jul 9, 2025
54af8b1
wip
0xForerunner Jul 9, 2025
9966ecb
wip
0xForerunner Jul 9, 2025
cddf97f
wip
0xForerunner Jul 10, 2025
89f5ee6
add capability to node
0xForerunner Jul 10, 2025
c3ad860
feat: add validation to node overlay
0xForerunner Jul 10, 2025
36201ba
FlashblocksNetworkBuilder
0xForerunner Jul 10, 2025
0dc7064
Pull out flashblocks-node
0xForerunner Jul 10, 2025
e94925e
add timestamp to Authorization
0xForerunner Jul 10, 2025
dc15ab1
wip
0xForerunner Jul 11, 2025
677574a
wip
0xForerunner Jul 11, 2025
9c3667a
wip
0xForerunner Jul 11, 2025
9944798
wip
0xForerunner Jul 11, 2025
1d0e8ad
wip
0xForerunner Jul 11, 2025
782b951
update vis
0xForerunner Jul 11, 2025
f225b5e
fix node
0xForerunner Jul 11, 2025
1fa5b68
rename vars
0xForerunner Jul 11, 2025
e6b0e9d
switch to Mutex for p2p state
0xForerunner Jul 14, 2025
4ac4633
update protocol to accept new blocks
0xForerunner Jul 14, 2025
0cbf403
move tests directory
0xForerunner Jul 14, 2025
dcf2a43
getting integration tests working
0xForerunner Jul 14, 2025
485adf0
get tests passing
0xForerunner Jul 14, 2025
6d252fe
get rid of duplicate code
0xForerunner Jul 15, 2025
a476ee9
rlp encoding
0xForerunner Jul 16, 2025
6c60ddd
fix rlpx message header
0xForerunner Jul 16, 2025
463c2f7
handle maximum flashblocks message size
0xForerunner Jul 16, 2025
8298f29
cleanup p2p handler
0xForerunner Jul 16, 2025
fd198aa
Don't resend flashblocks to the originating peer
0xForerunner Jul 16, 2025
fd06a6c
clear up comments
0xForerunner Jul 16, 2025
495ab62
remove stray if let
0xForerunner Jul 16, 2025
65125aa
reexport ed25519
0xForerunner Jul 16, 2025
7f82992
use mpsc for publish channel
0xForerunner Jul 17, 2025
ba36548
feat: reth 1.5.1
0xForerunner Jul 17, 2025
a7b4973
chore: cargo update
0xForerunner Jul 17, 2025
7e36324
chore: udeps
0xForerunner Jul 17, 2025
ad658fe
feat: flashblock size metric
0xForerunner Jul 17, 2025
69f50d3
fix: target in events
0xForerunner Jul 17, 2025
b40a313
feat: flashblocks node args
0xForerunner Jul 18, 2025
2f3a210
feat: check peer reputation
0xForerunner Jul 19, 2025
05b6eba
switch to broadcast
0xForerunner Jul 21, 2025
bf980dd
feat: switch to broadcast for publish chan
0xForerunner Jul 21, 2025
0abf5e8
target: flashblocks::p2p
0xForerunner Jul 21, 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
1,842 changes: 1,254 additions & 588 deletions Cargo.lock

Large diffs are not rendered by default.

17 changes: 16 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@ members = [
"crates/rollup-boost",
"crates/websocket-proxy",
"crates/flashblocks-rpc",
"crates/flashblocks-p2p",
"crates/flashblocks-node",
]

[workspace.dependencies]
rollup-boost = { path = "crates/rollup-boost" }
flashblocks-p2p = { path = "crates/flashblocks-p2p" }
flashblocks-rpc = { path = "crates/flashblocks-rpc" }

tracing = "0.1.4"
tracing-subscriber = { version = "0.3.11", features = ["env-filter", "json"] }
Expand All @@ -20,12 +24,22 @@ serde_json = "1.0.96"
metrics = "0.24.0"
metrics-derive = "0.1"
tokio = { version = "1", features = ["full"] }
tokio-stream = "0.1.17"
eyre = "0.6.12"
url = "2.2.0"
sha2 = { version = "0.10", default-features = false }

# Reth deps
reth-optimism-payload-builder = { git = "https://github.com/paradigmxyz/reth", tag = "v1.5.0" }
reth-optimism-payload-builder = { git = "https://github.com/paradigmxyz/reth", tag = "v1.5.1" }
reth = { git = "https://github.com/paradigmxyz/reth", tag = "v1.5.1" }
reth-ethereum = { git = "https://github.com/paradigmxyz/reth", tag = "v1.5.1" }
reth-eth-wire = { git = "https://github.com/paradigmxyz/reth", tag = "v1.5.1" }
reth-network = { git = "https://github.com/paradigmxyz/reth", tag = "v1.5.1" }
reth-network-peers = { git = "https://github.com/paradigmxyz/reth", tag = "v1.5.1" }
reth-node-api = { git = "https://github.com/paradigmxyz/reth", tag = "v1.5.1" }
reth-node-builder = { git = "https://github.com/paradigmxyz/reth", tag = "v1.5.1" }
reth-provider = { git = "https://github.com/paradigmxyz/reth", tag = "v1.5.1" }
reth-transaction-pool = { git = "https://github.com/paradigmxyz/reth", tag = "v1.5.1" }

# Alloy libraries
alloy-rpc-types-engine = "1.0.13"
Expand All @@ -38,6 +52,7 @@ alloy-consensus = "1.0.13"
alloy-rpc-types = "1.0.13"
alloy-genesis = "1.0.13"
alloy-rpc-client = "1.0.13"
alloy-rlp = "0.3.12"
alloy-provider = "1.0.13"
op-alloy-network = "0.18.7"
op-alloy-rpc-types-engine = "0.18.7"
Expand Down
66 changes: 66 additions & 0 deletions crates/flashblocks-node/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
[package]
name = "flashblocks-node"
version = "0.1.0"
edition = "2024"
license = "MIT"

[dependencies]
rollup-boost.workspace = true
flashblocks-p2p.workspace = true
flashblocks-rpc.workspace = true

reth-optimism-node = { git = "https://github.com/paradigmxyz/reth", tag = "v1.5.1" }
reth-optimism-cli = { git = "https://github.com/paradigmxyz/reth", tag = "v1.5.1" }
reth-rpc-eth-api = { git = "https://github.com/paradigmxyz/reth", tag = "v1.5.1" }
reth-optimism-primitives = { git = "https://github.com/paradigmxyz/reth", tag = "v1.5.1" }
reth-optimism-chainspec = { git = "https://github.com/paradigmxyz/reth", tag = "v1.5.1" }
reth-optimism-rpc = { git = "https://github.com/paradigmxyz/reth", tag = "v1.5.1" }
reth-optimism-evm = { git = "https://github.com/paradigmxyz/reth", tag = "v1.5.1" }
reth-optimism-forks = { git = "https://github.com/paradigmxyz/reth", tag = "v1.5.1" }
reth-provider = { git = "https://github.com/paradigmxyz/reth", tag = "v1.5.1" }
reth-primitives = { git = "https://github.com/paradigmxyz/reth", tag = "v1.5.1" }
reth-primitives-traits = { git = "https://github.com/paradigmxyz/reth", tag = "v1.5.1" }
reth-node-builder = { git = "https://github.com/paradigmxyz/reth", tag = "v1.5.1", features = [
"test-utils",
] }
reth-node-api = { git = "https://github.com/paradigmxyz/reth", tag = "v1.5.1" }
reth-tasks = { git = "https://github.com/paradigmxyz/reth", tag = "v1.5.1" }
reth-node-core = { git = "https://github.com/paradigmxyz/reth", tag = "v1.5.1" }
reth-db = { git = "https://github.com/paradigmxyz/reth", tag = "v1.5.1" }
reth-tracing = { git = "https://github.com/paradigmxyz/reth", tag = "v1.5.1" }
reth-rpc-server-types = { git = "https://github.com/paradigmxyz/reth", tag = "v1.5.1" }

reth-ethereum = { workspace = true, features = ["node", "network", "cli"] }
reth-eth-wire = { workspace = true }
reth-network = { workspace = true }
reth-network-peers = { workspace = true }
ed25519-dalek = { version = "2", features = ["serde"] }

alloy-eips.workspace = true
alloy-primitives.workspace = true
alloy-json-rpc.workspace = true
alloy-rpc-types.workspace = true
alloy-rpc-types-engine.workspace = true
alloy-rpc-types-eth.workspace = true
alloy-consensus.workspace = true
alloy-genesis.workspace = true
alloy-rpc-client.workspace = true
alloy-provider.workspace = true
op-alloy-network.workspace = true
op-alloy-consensus.workspace = true
op-alloy-rpc-types.workspace = true

tokio.workspace = true
tokio-tungstenite.workspace = true
url.workspace = true
tracing.workspace = true
clap.workspace = true
eyre.workspace = true
metrics.workspace = true
metrics-derive.workspace = true
serde_json.workspace = true
serde.workspace = true

jsonrpsee = { version = "0.25.1" }
futures-util = "0.3.31"
brotli = "8.0.1"
Original file line number Diff line number Diff line change
@@ -1,39 +1,41 @@
#![allow(missing_docs, rustdoc::missing_crate_level_docs)]

use clap::Parser;
use ed25519_dalek::VerifyingKey;
use flashblocks_node::FlashblocksNodeArgs;
use flashblocks_p2p::protocol::handler::FlashblocksHandler;
use flashblocks_rpc::{EthApiOverrideServer, FlashblocksApiExt, FlashblocksOverlay};
use reth_ethereum::network::{NetworkProtocols, protocol::IntoRlpxSubProtocol};
use reth_optimism_cli::{Cli, chainspec::OpChainSpecParser};
use reth_optimism_node::{OpNode, args::RollupArgs};
use tokio::sync::broadcast;
use tracing::info;

#[derive(Debug, Clone, PartialEq, Eq, clap::Args)]
#[derive(Debug, Clone, clap::Args)]
#[command(next_help_heading = "Rollup")]
struct FlashblocksRollupArgs {
#[command(flatten)]
rollup_args: RollupArgs,

#[arg(long = "flashblocks.enabled", default_value = "false")]
flashblocks_enabled: bool,
pub rollup_args: RollupArgs,

#[arg(long = "flashblocks.websocket-url", value_name = "WEBSOCKET_URL")]
websocket_url: url::Url,
#[command(flatten)]
pub flashblock_args: Option<FlashblocksNodeArgs>,
}

fn main() {
pub fn main() {
if let Err(err) =
Cli::<OpChainSpecParser, FlashblocksRollupArgs>::parse().run(async move |builder, args| {
let rollup_args = args.rollup_args;
let chain_spec = builder.config().chain.clone();
let (inbound_tx, inbound_rx) = broadcast::channel(100);
let (_publish_tx, publish_rx) = broadcast::channel(100);

let flashblocks_overlay = FlashblocksOverlay::new(chain_spec, inbound_rx);
flashblocks_overlay.clone().start()?;

info!(target: "reth::cli", "Launching Flashblocks RPC overlay node");
let handle = builder
.node(OpNode::new(rollup_args))
.extend_rpc_modules(move |ctx| {
if args.flashblocks_enabled {
let mut flashblocks_overlay =
FlashblocksOverlay::new(args.websocket_url, chain_spec);
flashblocks_overlay.start()?;

if args.flashblock_args.is_some() {
let eth_api = ctx.registry.eth_api().clone();
let api_ext = FlashblocksApiExt::new(eth_api.clone(), flashblocks_overlay);

Expand All @@ -43,6 +45,18 @@ fn main() {
})
.launch_with_debug_capabilities()
.await?;

let custom_rlpx_handler = FlashblocksHandler::new(
handle.node.network.clone(),
VerifyingKey::default(),
inbound_tx,
publish_rx,
);

handle
.node
.network
.add_rlpx_sub_protocol(custom_rlpx_handler.into_rlpx_sub_protocol());
handle.node_exit_future.await
})
{
Expand Down
19 changes: 19 additions & 0 deletions crates/flashblocks-node/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use clap::Args;
use ed25519_dalek::VerifyingKey;
use rollup_boost::parse_vk;

#[derive(Args, Clone, Debug)]
#[group(requires = "flashblocks")]
pub struct FlashblocksNodeArgs {
/// Enable Flashblocks client
#[arg(long, env, required = false)]
pub flashblocks: bool,

#[arg(
long = "flashblocks.authorizor_vk",
env = "FLASHBLOCKS_AUTHORIZOR_VK",
value_parser = parse_vk,
required = false,
)]
pub authorizor_vk: VerifyingKey,
}
Loading