According to Monero contributor selsta, when using the --tx-proxy option without noise_disabled:
[monerod] uses a combination of Tor, noise, randomized delays and Dandelion++ to break IP <-> txid linkage. [1]
However a comment in the source code suggests that this is not the case:
Dandelion++ over I2P/Tor should be an interesting case to investigate [2]
From my initial look at the code, it seems that noise and Dandelion++ are not the same thing, but I am not familiar with C++ or the Monero codebase so I could be wrong.
The follow up question (which is more important than the question in the title) is, what measures does one need to take to prevent transactions being linked to the same Tor circuit?
Assuming Dandelion++ is not used, does monerod take care to ensure that each transaction is sent over a separate circuit? The documentation on anonymity networks [3] has something to say about this, but it is quite vague. It suggests that it selects 2 different circuits to use for broadcasting every 5 minutes, but seems to imply that it relies on Tor dropping circuits after 10 minutes as its means of ensuring circuits aren't re-selected. However this isn't sufficient as Tor's circuity expiry ensures that circuits will no longer be used for NEW connections after 10 minutes, but does not drop existing connections. Also, hidden service circuits extend the 10 minutes every time data is sent over the circuit.
Assuming Dandelion++ is used, then sending multiple transactions over the same circuit shouldn't be a problem because the node will send relayed txs along the circuit as well as its own. And the circuits will be switched every epoch. One thing I wonder though, how does monerod behave when there are insufficient inbound connections to perform Dandelion++? I suspect this is much more of an issue for nodes that operate solely behind Tor. Or is it just the case that monerod can establish an outbound connection but then select it as being "inbound" for the purpose of Dandelion++? I think I've read that connections are directional for the purpose of p2p message exchange, but that might not be true.
UPDATE:
After reviewing some of the code I think I've partially answered the question.
Based on my understanding the disable_noise flag does impact Dandelion++ to some extent. If disable_noise is set then tx message/s are sent with the fluff flag set and the hidden service that receives them will immediately fluff. If disable_noise is not set then the tx message/s are sent without the fluff flag and the hidden service will handle them based on its own fluff/stem state.
I think the confusion is that, aside from setting the fluff flag, the other Dandelion++ stuff is not performed. There is no stem selection for Tor/I2P, nor is there any mixing of inbound txs with our outbound txs.
Assuming I've got this right, the question regarding Tor circuit reuse is very important. I haven't got a chance to review that section of the code just yet, so hopefully someone else can chime in.
[1] https://www.reddit.com/r/Monero/comments/jrh7mv/comment/gbt7bwp/?utm_source=reddit&utm_medium=web2x&context=3 [2] https://github.com/monero-project/monero/blob/master/src/cryptonote_protocol/levin_notify.cpp [3] https://github.com/monero-project/monero/blob/master/docs/ANONYMITY_NETWORKS.md