After a transaction has traveled along a Dandelion stem for a random number of
hops, it transitions into the fluff phase of routing. The transaction is shared
with the network through the existing process of diffusion. In practice, this
fluff mechanism is enforced by a weighted coin flip at each node. If the random
value is below some threshold, the Dandelion transaction is transformed into a
typical transaction. In our testing, we have chosen a probability of ten percent
that a given Dandelion transaction enters fluff phase when leaving a given node.
This value strikes a good balance between stem path length and transaction
spreading latency.
Note that Dandelion's expected precision guarantees are a population-level
metric, whereas the expected recall guarantees can be interpreted as an
individual-level metric. Expected recall is equivalent to the probability that
an adversary associates a single transaction with a given source. These
guarantees are probabilistic. They do not address scenarios in which a node has
been eclipsed by other nodes, or when a node is specifically targeted by an
ISP-like adversary. Individuals who are concerned about targeted deanonymization
should still use Tor.
At a high level, Dandelion is like an "anonymity inoculation" for the public at
large - including users who are not aware of Bitcoin's privacy issues. Higher
adoption leads to greater benefits, even for users who do not use Tor. Early
adopters of Dandelion still receive privacy benefits. In the worst case when no
neighbors support Dandelion, transactions make at least one hop before
diffusing. Note that any solution based only on routing cannot be perfectly
anonymous due to the fundamental lower bounds on precision and recall shown in
the original Dandelion paper. Dandelion provides near-optimal anonymity
guarantees among such solutions.
==Specification==
Dandelion can be specified with a handful of features: Dandelion transaction
support, Dandelion routing data and logic, periodic Dandelion route shuffling,
memory pool logic, the fluff mechanism, transaction embargoes, and Dandelion
transaction logic. Specification details are summarized below.
===Dandelion transaction support===
During the stem phase, transactions are "Dandelion transactions." When a
Dandelion transaction enters fluff phase, it becomes a typical Bitcoin
transaction. Dandelion transactions and typical transactions differ only in
their <code>NetMsgType</code>.
Dandelion (stem phase) transactions MUST be differentiable from typical Bitcoin
transactions.
===Dandelion routing data and logic===
Dandelion routing during the stem phase requires notions of inbound peers,
outbound peers, Dandelion destinations, and Dandelion routes. Inbound peers
consist of all currently connected peers that initiated the peer connection.
Outbound peers consist of all currently connected peers that were connected to
by this node. Dandelion destinations are a subset of outbound peers. The number
of Dandelion destinations is limited by the
<code>DANDELION_MAX_DESTINATIONS</code> parameter. In the reference
implementation, this parameter is set to two. Our tests have shown that this
value provides both privacy and robustness (see the reference paper for more
details on the parameter tradeoffs). Dandelion routes are a map of inbound peers
to Dandelion destinations. Every inbound peer is mapped to a Dandelion
destination.
Note that a Dandelion node may choose a different
<code>DANDELION_MAX_DESTINATIONS</code> parameter without splitting from the
privacy graph. When mapping inbound connections to outbound connections for
Dandelion routes, we implement the following routing logic. First, select a set
of Dandelion destinations from the set of outbound peers. This set of Dandelion
destinations is of size less than or equal to
<code>DANDELION_MAX_DESTINATIONS</code>. For each inbound connection, first
identify the subset of Dandelion destinations with the least number of routes.
For example, some subset of Dandelion destinations may be affiliated with zero
routes while all other Dandelion destinations are affiliated with one or more
routes. From this subset, select one Dandelion destination uniformly at random.
Establish a Dandelion route from the inbound connection to this Dandelion
destination.
For a given Dandelion routing epoch, two distinct Dandelion destinations SHOULD
be selected uniformly at random from the set of outbound connections. All
Dandelion transactions that arrive via a given inbound connection MUST be
transmitted to the same Dandelion destination. When choosing a Dandelion
destination for a given inbound connection, the destination MUST be selected
uniformly at random from the set of Dandelion destinations with the least number
of inbound connections mapped to them.
===Periodic Dandelion route shuffling===
The map of Dandelion routes is cleared and reconstructed every ten minutes on
average. We have chosen the value of ten minutes heuristically in order to make
privacy graph learning difficult for adversaries. Note that a Dandelion node may
choose a different average shuffle time without splitting from the privacy
graph.
Dandelion routes MUST be cleared and reconstructed at random intervals.
Dandelion routes SHOULD be cleared and reconstructed every ten minutes on
average.
===Memory pool logic===
Dandelion transactions are segregated from typical transactions. The
<code>mempool</code> remains unchanged. Another instance of the
<code>CTxMemPool</code> class, called the <code>stempool</code>, is used for
Dandelion transactions. Information flows from <code>mempool</code> to
<code>stempool</code> in order to ensure proper transaction propagation.
Information does not flow from <code>stempool</code> to <code>mempool</code>,
except when a Dandelion transaction fluffs into a typical transaction.
When a Dandelion transaction arrives, the transaction MUST be added to the
stempool and MUST NOT be added to the mempool. When a typical Bitcoin
transaction arrives, the transaction MUST be added to the mempool and MUST be
added to the stempool. When a Dandelion transaction fluffs, the transaction MUST
be added to the mempool.
===The fluff mechanism===
When relaying a Dandelion transaction along a Dandelion route, there is a 10%
chance that the Dandelion transaction becomes a typical Bitcoin transaction and
is therefore relayed via diffusion. In our testing, this value strikes a good
balance between stem path length and transaction spreading latency. Note that a
Dandelion node may choose a different chance of fluffing without splitting from
the privacy graph.
When a node prepares to transmit a Dandelion transaction, the node MUST flip a
biased coin. If the outcome is "Dandelion transaction," then the node MUST
transmit the transaction to the appropriate Dandelion destination. Otherwise,
the node MUST convert the Dandelion transaction into a typical Bitcoin
transaction. A Dandelion transaction SHOULD fluff into a typical Bitcoin
transaction with a 10% probability.
===Transaction embargoes===
During the stem phase, transactions are relayed along a single path. If any node
in this path were to receive the Dandelion transaction and go offline, then the
transaction would cease to propagate. To increase robustness, every node that
forwards a Dandelion transaction initializes a timer at the time of reception.
If the Dandelion transaction does not appear in the memory pool by the time the
timer expires, then the transaction enters fluff phase and is forwarded via
diffusion.
When a Dandelion transaction arrives, the node MUST set an embargo timer for a
random time in the future. If the Dandelion transaction arrives as a typical
Bitcoin transaction, the node MUST cancel the timer. If the timer expires before
the Dandelion transaction is observed as a typical Bitcoin transaction, then the
node MUST fluff the Dandelion transaction.
===Dandelion transaction logic===
The following cases define a node's behavior when receiving network packets
referencing Dandelion transactions.
* Receive INV for Dandelion TX: If the peer is inbound and the Dandelion transaction has not been received from this peer, then reply with GETDATA.
* Receive GETDATA for Dandelion TX: If the peer is not inbound and the Dandelion transaction has been advertised to this peer, then reply with the Dandelion transaction.
* Receive Dandelion TX: If the peer is inbound, then relay the Dandelion TX to the appropriate Dandelion destination.
==Implementation==
A reference implementation is available at the following URL: