diff --git a/AGENTS.md b/AGENTS.md index cec4b89df0..bb7efb4305 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -65,7 +65,7 @@ The project uses a zero-dependency core package pattern: ### P2P Architecture -- Built on libp2p with GossipSub and Kademlia DHT +- Built on libp2p with FloodSub and Kademlia DHT - Nodes advertise capabilities (full/light, DA layers) - Automatic peer discovery with rendezvous points diff --git a/CHANGELOG.md b/CHANGELOG.md index 502b9bb1e5..67fc992e16 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changes +- Improve P2P gossiping by switching pubsub internals from `GossipSub` to `FloodSub` [#3263](https://github.com/evstack/ev-node/pull/3263) - Add `sequencer_blocks_synchronized_total` Prometheus counter metric tracking blocks synced by source (DA/P2P) [#3259](https://github.com/evstack/ev-node/pull/3259) - Make it easier to override `DefaultMaxBlobSize` by ldflags [#3235](https://github.com/evstack/ev-node/pull/3235) - Add solo sequencer (simple in memory single sequencer without force inclusion) [#3235](https://github.com/evstack/ev-node/pull/3235) diff --git a/docs/adr/adr-003-peer-discovery.md b/docs/adr/adr-003-peer-discovery.md index 4510013479..cee8d59df0 100644 --- a/docs/adr/adr-003-peer-discovery.md +++ b/docs/adr/adr-003-peer-discovery.md @@ -11,12 +11,12 @@ Libp2p provides multiple ways to discover peers (DHT, mDNS, PubSub peer exchange ## Proposed network architecture 1. There will be a set of well-known, application-agnostic seed nodes. Every Evolve client will be able to connect to such node, addresses will be saved in configuration. - - This does not limit applications as they can still create independent networks with separate set of seed nodes. + - This does not limit applications as they can still create independent networks with separate set of seed nodes. 2. Nodes in the network will serve DHT. It will be used for active peer discovery. Client of each optimistic network will be able to find other peers in this particular network. - - All nodes will cooperate on the same DHT. - - ChainID will be used to advertise that client participates in a particular optimistic network. + - All nodes will cooperate on the same DHT. + - ChainID will be used to advertise that client participates in a particular optimistic network. 3. Nodes from multiple networks will help with peer discovery (via single DHT). -4. After connecting to nodes found in DHT, GossipSub will handle peer lists for clients. +4. After connecting to nodes found in DHT, FloodSub will handle peer lists for clients. ### Pros @@ -30,11 +30,11 @@ Libp2p provides multiple ways to discover peers (DHT, mDNS, PubSub peer exchange ## Alternatives 1. Joining public IPFS DHT for peer discovery. - - pros: large network - finding peers should be very easy - - cons: we may affect public IPFS network stability in case of misconfiguration, possibly lot of unrelated traffic + - pros: large network - finding peers should be very easy + - cons: we may affect public IPFS network stability in case of misconfiguration, possibly lot of unrelated traffic 2. Custom peer-exchange protocol. - - pros: full flexibility of implementation - - cons: need to create from scratch and test + - pros: full flexibility of implementation + - cons: need to create from scratch and test 3. Re-use of existing peer discovery mechanism like `discv5` - - pros: ready & battle-tested software - - cons: use different network stack, requires lot of integration + - pros: ready & battle-tested software + - cons: use different network stack, requires lot of integration diff --git a/docs/overview/architecture.md b/docs/overview/architecture.md index d0ba6ece2c..955e634df8 100644 --- a/docs/overview/architecture.md +++ b/docs/overview/architecture.md @@ -41,13 +41,13 @@ Evolve uses a modular architecture where each component has a well-defined inter The block package is the heart of ev-node. It's organized into specialized components: -| Component | Responsibility | Runs On | -|-----------|---------------|---------| -| **Executor** | Produces blocks by getting batches from sequencer and executing via execution layer | Aggregator only | -| **Reaper** | Scrapes transactions from execution layer mempool and submits to sequencer | Aggregator only | -| **Syncer** | Coordinates block sync from DA layer and P2P network | All nodes | -| **Submitter** | Submits blocks to DA layer and tracks inclusion | Aggregator only | -| **Cache** | Manages in-memory state for headers, data, and pending submissions | All nodes | +| Component | Responsibility | Runs On | +| ------------- | ----------------------------------------------------------------------------------- | --------------- | +| **Executor** | Produces blocks by getting batches from sequencer and executing via execution layer | Aggregator only | +| **Reaper** | Scrapes transactions from execution layer mempool and submits to sequencer | Aggregator only | +| **Syncer** | Coordinates block sync from DA layer and P2P network | All nodes | +| **Submitter** | Submits blocks to DA layer and tracks inclusion | Aggregator only | +| **Cache** | Manages in-memory state for headers, data, and pending submissions | All nodes | ### Component Interaction @@ -81,12 +81,12 @@ The block package is the heart of ev-node. It's organized into specialized compo Evolve supports several node configurations: -| Type | Block Production | Full Validation | DA Submission | Use Case | -|------|-----------------|-----------------|---------------|----------| -| **Aggregator** | Yes | Yes | Yes | Block producer (sequencer) | -| **Full Node** | No | Yes | No | RPC provider, validator | -| **Light Node** | No | Headers only | No | Mobile, embedded clients | -| **Attester** | No | Yes | No | Soft consensus participant | +| Type | Block Production | Full Validation | DA Submission | Use Case | +| -------------- | ---------------- | --------------- | ------------- | -------------------------- | +| **Aggregator** | Yes | Yes | Yes | Block producer (sequencer) | +| **Full Node** | No | Yes | No | RPC provider, validator | +| **Light Node** | No | Headers only | No | Mobile, embedded clients | +| **Attester** | No | Yes | No | Soft consensus participant | ### Aggregator @@ -158,7 +158,7 @@ User Tx → Execution Layer Mempool Built on libp2p with: -- **GossipSub** for transaction and block propagation +- **FloodSub** for transaction and block propagation - **Kademlia DHT** for peer discovery - **Topics**: `{chainID}-tx`, `{chainID}-header`, `{chainID}-data` diff --git a/pkg/p2p/README.md b/pkg/p2p/README.md index 2c261db5ac..ec653afd94 100644 --- a/pkg/p2p/README.md +++ b/pkg/p2p/README.md @@ -51,12 +51,12 @@ type P2PConfig struct { ### Configuration Parameters -| Parameter | Description | Default | Example | -|-----------|-------------|---------|---------| -| ListenAddress | The address where the node listens for incoming P2P connections | `/ip4/0.0.0.0/tcp/7676` | `/ip4/0.0.0.0/tcp/7676` | -| Seeds | Comma-separated list of seed nodes (bootstrap nodes) | "" | `/ip4/1.2.3.4/tcp/7676/p2p/12D3KooWA8EXV3KjBxEU...,/ip4/5.6.7.8/tcp/7676/p2p/12D3KooWJN9ByvD...` | -| BlockedPeers | Comma-separated list of peer IDs to block | "" | `12D3KooWA8EXV3KjBxEU...,12D3KooWJN9ByvD...` | -| AllowedPeers | Comma-separated list of peer IDs to explicitly allow | "" | `12D3KooWA8EXV3KjBxEU...,12D3KooWJN9ByvD...` | +| Parameter | Description | Default | Example | +| ------------- | --------------------------------------------------------------- | ----------------------- | ------------------------------------------------------------------------------------------------ | +| ListenAddress | The address where the node listens for incoming P2P connections | `/ip4/0.0.0.0/tcp/7676` | `/ip4/0.0.0.0/tcp/7676` | +| Seeds | Comma-separated list of seed nodes (bootstrap nodes) | "" | `/ip4/1.2.3.4/tcp/7676/p2p/12D3KooWA8EXV3KjBxEU...,/ip4/5.6.7.8/tcp/7676/p2p/12D3KooWJN9ByvD...` | +| BlockedPeers | Comma-separated list of peer IDs to block | "" | `12D3KooWA8EXV3KjBxEU...,12D3KooWJN9ByvD...` | +| AllowedPeers | Comma-separated list of peer IDs to explicitly allow | "" | `12D3KooWA8EXV3KjBxEU...,12D3KooWJN9ByvD...` | ## libp2p Components @@ -69,7 +69,7 @@ graph LR Client --> DHT["Kademlia DHT"] Client --> Discovery["Routing Discovery"] Client --> Gater["Connection Gater"] - Client --> PubSub["GossipSub PubSub"] + Client --> PubSub["FloodSub PubSub"] Host --> Transport["Transport Protocols"] Host --> Security["Security Protocols"] @@ -96,7 +96,7 @@ graph LR - Used for finding other peers within the same network - Bootstrapped with seed nodes defined in configuration -3. **GossipSub**: Publish-subscribe protocol for message dissemination +3. **FloodSub**: Publish-subscribe protocol for message dissemination - Used for gossiping transactions, headers, and blocks - Provides efficient message propagation with reduced bandwidth overhead - Supports message validation through custom validators @@ -118,7 +118,7 @@ sequenceDiagram participant P as P2P Client participant H as libp2p Host participant D as DHT - participant G as GossipSub + participant G as FloodSub participant N as Network/Other Peers A->>P: NewClient(config, chainID, datastore, logger, metrics) @@ -163,7 +163,7 @@ The P2P clients in full and light nodes handle transaction validation differentl ## Message Gossiping -Messages (transactions, blocks, etc.) are gossiped through the network using GossipSub topics. The topic format is: +Messages (transactions, blocks, etc.) are gossiped through the network using FloodSub topics. The topic format is: `+` diff --git a/pkg/p2p/client.go b/pkg/p2p/client.go index 0093a8ad60..e89b96b30b 100644 --- a/pkg/p2p/client.go +++ b/pkg/p2p/client.go @@ -450,7 +450,7 @@ func (c *Client) tryConnect(ctx context.Context, peer peer.AddrInfo) { func (c *Client) setupGossiping(ctx context.Context) error { var err error - c.ps, err = pubsub.NewGossipSub(ctx, c.host) + c.ps, err = pubsub.NewFloodSub(ctx, c.host) if err != nil { return err }