Add ZIP 327: Dandelion++ Transaction Propagation for Zcash P2P Nodes#1329
Open
y4ssi wants to merge 2 commits into
Open
Add ZIP 327: Dandelion++ Transaction Propagation for Zcash P2P Nodes#1329y4ssi wants to merge 2 commits into
y4ssi wants to merge 2 commits into
Conversation
This was referenced Jul 9, 2026
y4ssi
pushed a commit
to y4ssi/zebra-dpp
that referenced
this pull request
Jul 9, 2026
…P 327) Implements Dandelion++ stem/fluff transaction propagation for Zebra to reduce IP-to-transaction correlation for network observers. Per the draft ZIP 327 (zcash/zips#1329). Core mechanism: - Per-epoch stem-peer selection (10 min base + up to 2 min jitter), `zebra-network/src/dandelion/epoch.rs`. - Per-transaction propagation state with a 30 s stem timeout, `zebra-network/src/dandelion/state.rs`. - Fail-closed stem unicast: new `Request::AdvertiseTransactionIdsToPeer` variant routed by `PeerSet::route_to_peer()` to exactly the named stem peer; if that peer isn't ready it fails with `PeerError::NoReadyPeers` rather than falling back to a different peer (which would defeat the privacy property). The gossip task then promotes the tx to fluff. - Gossip task (`zebrad/src/components/mempool/dandelion_gossip.rs`) wired into zebrad startup, replacing the immediate-flood gossip. - `MempoolChangeKind::StemAdded`: locally-submitted txs (RPC Queue) are routed through stem; peer-relayed txs go directly to fluff. Stem-phase hiding (a stem tx MUST NOT be observable before it fluffs): - P2P `MempoolTransactionIds` and `TransactionsById` (getdata) handlers filter active-stem txids. - `getrawmempool` and `getrawtransaction` RPCs filter them. - The indexer gRPC `mempool_change` stream (Zaino/lightwalletd) suppresses `StemAdded` events until the tx fluffs. - All exposure filters gate on the `Stem` state (not the elapsed timeout), so a timed-out-but-not-yet-swept tx stays hidden until the gossip task actually broadcasts it. Robustness: - `PropagationStateMap` entries are removed on Mined/Invalidated and on fluff promotion, bounding memory. - The gossip task fails open on transient PeerSet readiness errors rather than terminating. Tests: 10 unit tests (epoch, propagation state, Phase 4 filters) + 2 PeerSet routing tests. Verified end-to-end on a 3-node regtest network; see docs/dandelion-e2e-regtest.md. A companion wallet-side change (Component A: direct P2P submission) is implemented in the Android and Swift SDKs (zcash/zcash-android-wallet-sdk#2010, zcash/zcash-swift-wallet-sdk#1804).
pacu
requested changes
Jul 9, 2026
| @@ -0,0 +1,262 @@ | |||
| ZIP: 327 | |||
Collaborator
There was a problem hiding this comment.
Zip number assigned is done by zip editors. Leave unassigned
y4ssi
pushed a commit
to zodl-inc/zcash-android-wallet-sdk
that referenced
this pull request
Jul 9, 2026
… 327/328) Adds an opt-in transaction submission path that sends transactions directly to a Zcash P2P full node via the native wire protocol instead of routing them through lightwalletd/Zaino. This closes the IP-to-transaction correlation gap at the submission boundary (a compact-block server otherwise sees the wallet IP and the transaction at the same instant). Component A of the Dandelion++ direct-submission design (ZIP 327 / ZIP 328). Default behaviour is unchanged: DandelionSubmitConfig.LightWalletD remains the default, and chain synchronisation always uses the lightwalletd endpoint regardless of this setting. - ZcashP2PSubmitter (TransactionSubmitter): DNS seeder discovery, TCP connect (5s timeout), version/verack handshake, tx message without a prior inv (unadvertised-tx convention), disconnect. java.net stdlib only. Advertises protocol version 170_150 (Zebra's NU6.2 minimum). - DandelionSubmitConfig: LightWalletD (default) or DirectP2P(network, fallbackToLightWalletD). - FallbackTransactionSubmitter: P2P primary, lwd fallback on transport error; node rejections surface immediately. - Wiring via a new dandelionSubmitConfig parameter (defaults preserve current behaviour). Related: ZIP 327 (zcash/zips#1329), ZIP 328 (zcash/zips#1330), ZcashFoundation/zebra#10928 (Component B).
y4ssi
pushed a commit
to zodl-inc/zcash-swift-wallet-sdk
that referenced
this pull request
Jul 9, 2026
… 327/328) Adds an opt-in transaction submission path that sends transactions directly to a Zcash P2P full node via the native wire protocol instead of routing them through lightwalletd/Zaino, closing the IP-to-transaction correlation gap at the submission boundary. Component A of the Dandelion++ direct-submission design (ZIP 327 / ZIP 328). iOS equivalent of zcash/zcash-android-wallet-sdk#2010. Default behaviour unchanged: .lightWalletD remains the default and chain sync always uses the lightwalletd endpoint. - ZcashP2PSubmitter (EndpointSubmitter): DNS seeder discovery, TCP connect, version/verack handshake, tx without a prior inv (unadvertised-tx convention), disconnect. Foundation + CommonCrypto only. Advertises protocol version 170_150 (Zebra's NU6.2 minimum). - DandelionSubmitConfig enum: .lightWalletD / .directP2P; ZcashP2PNetwork. - FallbackEndpointSubmitter: P2P primary, gRPC lwd fallback. - Wiring via Dependencies.setup() and Initializer (new dandelionSubmitConfig parameter; defaults preserve current behaviour). Related: ZIP 327 (zcash/zips#1329), ZIP 328 (zcash/zips#1330), ZcashFoundation/zebra#10928 (Component B).
y4ssi
pushed a commit
to y4ssi/zips
that referenced
this pull request
Jul 9, 2026
… Relay Specifies the wallet-side path (Component A) for submitting transactions directly to a Zcash full node over P2P instead of via a compact-block server, using the Dandelion++ stem-phase forwarding defined in ZIP 327. Closes the IP-to-transaction correlation gap at the submission boundary: no lightwalletd/Zaino operator sees the wallet IP and the transaction together. Covers peer discovery, the version/verack handshake, the unadvertised-tx submission hint, the no-concurrent-centralised-submission rule, and fallback. Reference implementations: zcash/zcash-android-wallet-sdk#2010 and zcash/zcash-swift-wallet-sdk#1804. Co-owned network/wallet ZIP; companion to ZIP 327 (zcash#1329).
Specifies how Zcash full nodes implement Dandelion++ stem/fluff transaction propagation to reduce IP-to-transaction correlation for network observers (Component B). Covers per-epoch stem-peer selection (10 min + up to 2 min jitter), fail-closed unicast, 30 s stem timeout, stem-phase hiding from MempoolTransactionIds/getdata/getrawmempool/ getrawtransaction and the indexer stream, and fluff-phase broadcast. No new P2P message type; incremental deployment. Reference implementation: ZcashFoundation/zebra#10928. Companion wallet-side spec: ZIP 328 (zcash#1330), with SDK implementations zcash/zcash-android-wallet-sdk#2010 and zcash/zcash-swift-wallet-sdk#1804.
… number to Unassigned, update ZIP 328 cross-references to PR links
y4ssi
pushed a commit
to y4ssi/zips
that referenced
this pull request
Jul 14, 2026
…set ZIP number to Unassigned, update all ZIP 327 cross-references to PR zcash#1329 links
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Proposes ZIP 327, a network-layer specification for Dandelion++ stem/fluff
transaction propagation in Zcash full nodes.
Problem: Zcash transactions are currently flood-broadcast immediately,
allowing passive network observers to correlate originating IP addresses with
transactions even for shielded txs whose content is cryptographically protected.
This ZIP specifies:
inv(no new P2P message type required)mempoolP2P responses or mempool RPCsScope: Full-node relay behavior (Component B). Wallet-side direct P2P submission
(Component A) is deferred to a companion ZIP 328 (in preparation).
Reference implementation: zcashfoundation/zebra#10928 — Component B.
E2e-verified on a 3-node regtest network 2026-07-09:
txid
87ffaf8f443e9b88aa5131bd3542bfc4abd6f8c2e8852d9482de0595048fc890accepted,30 s stem window confirmed, adversary observer saw no
invduring stem phase.Full test procedure and e2e evidence are in
docs/dandelion-e2e-regtest.mdin that PR.Test plan
cargo test -p zebra-network dandelion)