🌱Dandelion++ Transaction Relay

Stop network-level deanonymization. Even a well-connected observer can't pinpoint which IP originated your transaction.

The attack Dandelion++ defends

In standard Bitcoin-style relay, when you send a transaction your node broadcasts it to all peers simultaneously. A network observer with many connections — say, a chain analytics firm running 5,000 sniffer nodes — uses timing analysis: the IP that broadcast first is almost certainly the originator.

How Dandelion++ works (BIP-156)

Dandelion++ splits propagation into two phases:

  1. Stem phase

    Your node forwards the transaction along a random single-path "stem". Each node selects 2 stem peers per 10-minute epoch and forwards stem transactions to exactly one of them.

  2. Fluff phase

    At each hop, there's a 10% chance to transition to "fluff" — normal broadcast to all peers. After 10 hops or 30 seconds (whichever comes first), fluff is forced.

An observer sees the transaction "appear" from a random node deep in the stem — not from the originator.

Configuration constants

DANDELION_EPOCH_SECONDS      = 600    # stem peer rotation every 10 min
DANDELION_STEM_PEERS         = 2      # outbound stem relays per epoch
DANDELION_FLUFF_PROBABILITY  = 0.10   # 10% fluff chance per hop
DANDELION_EMBARGO_SECONDS    = 30     # force-fluff timeout
DANDELION_MAX_STEM_HOPS      = 10     # maximum stem length

Step-by-step

  1. Verify it's enabled

    Dandelion++ is active from genesis — there is no flag to enable or disable it. Confirm via debug log:

    $ tail -f ~/.MaryJaneCoin/debug.log | grep -i dandelion
    Dandelion: selected stem peer 95.216.x.x:14200 for epoch 145
    Dandelion: stem-relayed tx abc123... to 95.216.x.x:14200
  2. Combine with Tor for full origin privacy

    Dandelion++ hides which node first broadcast. Tor hides which IP that node has. Use both:

    # MaryJaneCoin.conf
    proxy=127.0.0.1:9050
    onlynet=ipv4

    See the Tor tutorial for the full setup.

  3. Watch a transaction propagate

    $ MaryJaneCoind sendtoaddress "M..." 100
    $ tail -f ~/.MaryJaneCoin/debug.log | grep -i "dandelion\|fluff"
    Dandelion: stem-relayed tx d4f3... hops=1
    Dandelion: stem-relayed tx d4f3... hops=2
    Dandelion: fluff transition tx d4f3... hops=3 reason=probability
    Dandelion: broadcasting tx d4f3... to 8 peers
Why this beats simple broadcasting Even if an attacker controls 50% of all peers in the network, the stem path randomly enters their nodes mid-route. By the time fluff fires, the path has already left the originator far behind.
What it doesn't protect Dandelion++ only protects origin privacy. It does not hide transaction contents. For that you need stealth addresses (recipient privacy) and ring mixing (amount privacy).