[Backport release-mainnet-1.2.0-rc] fix(libp2p): add network discriminators#4443
Conversation
* test(libp2p): snapshot mainnet protocol identifiers
- Extract three helpers in `network/node.rs` returning the libp2p
protocol identifiers used today (gossipsub prefix `None` = libp2p
default, kademlia `/ipfs/kad/1.0.0`, direct message
`/HotShot/direct_message/1.0`).
- Wire the helpers into the swarm builder so they are the single source
of truth.
- Add an `insta` snapshot test that locks in the values. A future change
that would silently shift these strings (and partition mainnet from
itself) now fails the snapshot.
* feat(libp2p): partition non-mainnet networks via chain-id discriminator
- Add `network_discriminator: Option<String>` to `NetworkNodeConfig`.
`None` keeps mainnet's libp2p protocol strings byte-identical to
today; `Some(d)` appends `/{d}` to gossipsub's `protocol_id_prefix`,
the kademlia `StreamProtocol`, and the request-response direct
message `StreamProtocol`. Identify's `protocol_version` is left
untouched since it does not gate substream negotiation.
- Plumb the discriminator through `Libp2pNetwork::from_config`.
- At the espresso-node call site, derive the discriminator from
`genesis.chain_config.chain_id`: `None` when chain_id is 1
(mainnet), else `Some(chain_id.to_string())`. Decaf and other
non-mainnet networks now run on distinct libp2p protocols and
cannot merge with mainnet at the gossipsub or kademlia layers.
- The snapshot test added in the previous commit confirms the
mainnet path is unchanged.
* doc(libp2p): tighten network_discriminator field comment
* test(libp2p): snapshot decaf protocol identifiers
- Extract three `gossipsub_prefix` / `kad_protocol` /
`direct_message_protocol` wrappers that take an optional
discriminator and call the existing mainnet helpers when `None`.
- Replace the inline match arms in `NetworkNode::new` with calls to
these wrappers so production code and tests share a single path.
- Add a decaf snapshot test alongside the mainnet one, both routed
through a shared `snapshot_for(discriminator)` helper. Decaf's
chain_id (`0xdecaf` = 912559) produces protocol IDs like
`/ipfs/kad/1.0.0/912559`.
* refactor(libp2p): type network_discriminator as Option<U256>
- Discriminator is always a chain id; use `U256` rather than `String`
at the libp2p-networking boundary.
- Format chain ids as hex with the `0x` prefix in the protocol
strings, matching the spelling in `data/genesis/decaf.toml`. Decaf's
protocols become `/ipfs/kad/1.0.0/0xdecaf`, etc.
- Test reads naturally as `snapshot_for(Some(U256::from(0xdecafu64)))`.
- Mainnet snapshot is unchanged (still goes through the `None`
branch).
* refactor(node): promote MAINNET_CHAIN_ID to lib.rs, type as ChainId
- Move the constant out of `api/unlock_schedule.rs` so the libp2p
call site can reuse it instead of comparing against a bare
`U256::ONE`.
- Retype from `u64 = 1` to `ChainId = ChainId(U256::ONE)` so callers
no longer wrap it in `U256::from(...)` or `ChainId(...)` at each
use site.
(cherry picked from commit 284de7a)
|
Claude finished @sveitser's task in 1m 18s —— View job Reviewing backport PR #4443
Review SummaryThis is a clean backport of #4418, adding network discriminators to libp2p protocol strings (gossipsub, Kademlia, direct messages) so that non-mainnet networks are isolated at the protocol level. Mainnet ( Verdict: Looks good. The design is sound and the implementation is clean. A few observations below. Strengths
Minor Observations
No Issues FoundThe backport is faithful to the original PR. No bugs, security issues, or performance concerns identified. All call sites of |
Backport of #4418 to
release-mainnet-1.2.0-rc.