Skip to content

Conversation

@noot
Copy link
Contributor

@noot noot commented Sep 24, 2025

📝 Summary

  • implement p2p crate which implements a simple libp2p node
  • p2p node has the ability to support various stream protocols and broadcasting to all peers on a protocol
  • note: this is not gossip; messages will only be sent to directly-connected peers. we currently assume a very small builder network (<10 nodes) so direct connectivity is okay, but for larger networks, this will need to be extended.
  • update flashblocks payload builder to broadcast newly built flashblock payloads over p2p
  • implement payload handler to handle incoming flashblock payloads from peers
  • NOTE: syncing and execution of flashblocks is not yet implemented; it will be added to the payload handler in a follow up PR.

future extensions:

  • connection management/max peer count/peer persistence
  • flashblock sync and execution
  • test fallback building (if one builder fails in the middle of a block after building some flashblocks, can another builder take over flashblock building?) be out of scope for this PR, as the main goal of this PR is to ensure flashblock sync over p2p.

💡 Motivation and Context

see https://hackmd.io/@nZ-twauPRISEa6G9zg3XRw/H1fekrwolx

✅ I have completed the following steps:

  • Run make lint
  • Run make test
  • Added tests (if applicable)

Copy link
Contributor

@akundaz akundaz left a comment

Choose a reason for hiding this comment

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

How are you handling the race conditions p2p introduces? Like if two builder build different flashblocks or something like that.

Not really sure what's happening in the p2p crate, please make sure it's documented well so that others can contribute easily

loop {
match reader.next().await {
Some(Ok(str)) => {
let payload: M = serde_json::from_str(&str)
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't deserialization happen in op-rbuilder code?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i originally had it there, i was debating if the serialization format should be internal or external to the p2p layer. i'm going to refactor this to not be json anyways. could change the p2p layer back to just handle Bytes instead of Message if you prefer that

Copy link
Contributor

Choose a reason for hiding this comment

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

sounds good, i'll look again after you refactor

Copy link
Contributor

Choose a reason for hiding this comment

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

looks better now that it's over Message, just fix the error messages about flashblocks

@noot
Copy link
Contributor Author

noot commented Sep 30, 2025

How are you handling the race conditions p2p introduces? Like if two builder build different flashblocks or something like that.

out of scope for this PR, i am assuming the high availability setup will be used where op-conductor will manage which party is building at a specific time.

Not really sure what's happening in the p2p crate, please make sure it's documented well so that others can contribute easily

yes will add! PR is still draft, not ready for review yet tbh, will ping you again when it's fully ready.

&self.evm_config
}

pub(super) fn into_op_payload_builder_ctx(
Copy link
Collaborator

Choose a reason for hiding this comment

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

why not for conversions between the types?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i'm probably going to remove this function after cleanup

@noot noot marked this pull request as ready for review October 6, 2025 00:15
@noot noot requested review from SozinM and karim-agha as code owners October 6, 2025 00:15
@noot noot changed the title feat: implement p2p layer for flashblocks feat: implement p2p layer and broadcast flashblocks Oct 6, 2025
@noot noot requested review from akundaz and avalonche October 6, 2025 00:22
Copilot AI review requested due to automatic review settings October 14, 2025 22:17
@noot noot requested a review from 0x416e746f6e as a code owner October 14, 2025 22:17
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR implements a P2P layer for flashblocks using libp2p to enable broadcasting and receiving flashblock payloads between builder nodes. The implementation adds a new p2p crate with basic networking capabilities and integrates it into the flashblocks payload builder to broadcast newly built payloads.

  • Implements P2P crate with libp2p node supporting stream protocols and broadcasting
  • Updates flashblocks payload builder to broadcast payloads over P2P instead of just WebSocket
  • Adds payload handler to manage incoming P2P flashblock messages and route them to the payload builder service

Reviewed Changes

Copilot reviewed 15 out of 16 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
crates/p2p/src/lib.rs Core P2P node implementation with libp2p networking, message handling, and stream management
crates/p2p/src/outgoing.rs Outgoing stream handler for broadcasting messages to connected peers
crates/p2p/src/behaviour.rs libp2p network behavior configuration with protocols like identify, ping, mDNS
crates/op-rbuilder/src/builders/flashblocks/service.rs Integration of P2P node into flashblocks service with payload handler
crates/op-rbuilder/src/builders/flashblocks/payload_handler.rs Handler for routing built payloads and incoming P2P messages
crates/op-rbuilder/src/builders/flashblocks/payload.rs Updated payload builder to send payloads via channel instead of direct engine calls
crates/op-rbuilder/src/builders/flashblocks/p2p.rs P2P message types and conversions for flashblock payloads
crates/op-rbuilder/src/args/op.rs Added CLI arguments for P2P configuration

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 17 out of 18 changed files in this pull request and generated 1 comment.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@noot noot requested a review from avalonche October 21, 2025 20:11
pub client: Client,
/// Sender for sending built payloads to [`PayloadHandler`],
/// which broadcasts outgoing payloads via p2p.
pub payload_tx: mpsc::Sender<OpBuiltPayload>,
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you clean up the naming a bit since there are also "payload_tx" metrics that are unrelated to this?

Copy link
Contributor Author

@noot noot Oct 27, 2025

Choose a reason for hiding this comment

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

it's standard for channels to have _tx or _rx at the end, so i renamed the metrics, let me know if that's okay

use alloy_evm::Database;
use alloy_op_evm::OpEvm;
use alloy_primitives::{Address, B256, Bytes, TxKind, U256, keccak256, map::foldhash::HashMap};
use alloy_primitives::{Address, B256, Bytes, TxKind, U256, keccak256, map::DefaultHashBuilder};
Copy link
Contributor

Choose a reason for hiding this comment

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

What is this change for? It looks like we're only using the alloy hashmap in this file

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i'm not sure exactly why but the previous version doesn't compile for me, even though i didn't make changes:

error[E0308]: mismatched types
   --> crates/op-rbuilder/src/builders/builder_tx.rs:373:36
    |
373 |                     state_changes: state,
    |                                    ^^^^^ expected `HashMap<Address, Account, RandomState>`, found `HashMap<Address, Account, DefaultHashBuilder>`
    |
    = note: expected struct `HashMap<_, _, alloy_primitives::map::foldhash::fast::RandomState>`
               found struct `HashMap<_, _, DefaultHashBuilder>`

error[E0308]: mismatched types
   --> crates/op-rbuilder/src/flashtestations/builder_tx.rs:232:29
    |
232 |         evm.db_mut().commit(state_changes);
    |                      ------ ^^^^^^^^^^^^^ expected `HashMap<Address, Account, DefaultHashBuilder>`, found `HashMap<Address, Account, RandomState>`
    |                      |
    |                      arguments to this method are incorrect
    |
    = note: expected struct `HashMap<_, _, DefaultHashBuilder>`
               found struct `HashMap<_, _, alloy_primitives::map::foldhash::fast::RandomState>`
note: method defined here
   --> /home/e/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/revm-database-interface-7.0.5/src/lib.rs:72:8
    |
72  |     fn commit(&mut self, changes: HashMap<Address, Account>);
    |        ^^^^^^

For more information about this error, try `rustc --explain E0308`.
error: could not compile `op-rbuilder` (lib) due to 2 previous errors

i'm still trying to debug this but this was a stopgap change just so i can have the PR up still

Copilot AI review requested due to automatic review settings October 27, 2025 16:32
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 17 out of 18 changed files in this pull request and generated 7 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@noot noot requested a review from akundaz October 27, 2025 16:36
loop {
tokio::select! {
Some(payload) = built_rx.recv() => {
let _ = payload_events_handle.send(Events::BuiltPayload(payload.clone()));
Copy link
Collaborator

Choose a reason for hiding this comment

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

Add some logging around this errors pls

flashblocks_leeway_time: 100,
flashblocks_fixed: false,
..Default::default()
flashblocks_fixed: false, ..Default::default()
Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's change it back? Is it rustfmt that formatted it that way?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i think it wasn't formatted by rustfmt since it's in a macro, fixed it

flashblocks: FlashblocksArgs {
flashblocks_number_contract_address: Some(FLASHBLOCKS_NUMBER_ADDRESS),
..Default::default()
flashblocks_number_contract_address: Some(FLASHBLOCKS_NUMBER_ADDRESS), ..Default::default()
Copy link
Collaborator

Choose a reason for hiding this comment

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

same

pub gas_used: u64,
pub output: T::Return,
pub state_changes: HashMap<Address, Account>,
pub state_changes: HashMap<Address, Account, DefaultHashBuilder>,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Wow, this looks strange, what's reason for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

see https://github.com/flashbots/op-rbuilder/actions/runs/18853582189/job/53795775017?pr=275 and #275 (comment)

i have no idea why this is happening, thought it was maybe a local issue but it's happening on CI also.

@SozinM
Copy link
Collaborator

SozinM commented Oct 27, 2025

General Q:
should we make params like trusted peers to make sure that only out builder would be able to link and send events?

Copilot AI review requested due to automatic review settings October 27, 2025 19:31
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 19 out of 20 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copilot AI review requested due to automatic review settings October 27, 2025 19:40
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 19 out of 20 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@noot
Copy link
Contributor Author

noot commented Oct 27, 2025

should we make params like trusted peers to make sure that only out builder would be able to link and send events?

do you mean so that only trusted peers are able to form connections? that could definitely be added as a flag, i plan to do a follow-up with more connection management features. i would say it's out of scope for this PR as it's already large, and is its own feature

Copilot AI review requested due to automatic review settings October 27, 2025 20:22
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 19 out of 20 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@noot noot merged commit 8f08b2e into main Oct 27, 2025
4 checks passed
@noot noot deleted the noot/p2p branch October 27, 2025 21:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants