Remote Node vs Local Node: What a Wallet Leaks (2026)
We measured two public Monero endpoints: eight methods answered, nine refused with -32601, and a 272 KB block handed back as 1,401 bytes. Here is what a node can and cannot see, plus the Dandelion++ constants that decide it.
Two questions get merged into one, and that is where the bad advice comes from. Question one: can the server your wallet talks to see what you are doing? Question two: does the blockchain record who you are? At 18:00 UTC on 27 October 2026 we measured the first one directly. Two public Monero endpoints, node.monerodevs.org:18089 and xmr-node.cakewallet.com:18081, reported the same tip hash c0268f79 and the same height, 3,793,455. Both answered eight read-only methods and refused nine others with JSON-RPC error -32601, Method not found. That single result says more about a remote node than any privacy slogan.
Every RPC call is a line in someone else's log: your IP, the method name, its arguments, a timestamp. On our two test endpoints the allowed set was get_info, get_version, get_block_count, get_block, get_last_block_header, get_block_headers_range, get_fee_estimate and get_output_histogram. The refused set was get_peer_list, get_connections, get_net_stats, get_transaction_pool, get_transaction_pool_hashes, get_transactions, get_outs, get_coinbase_tx_sum and send_raw_transaction. Restricted mode also blanks fields instead of removing them, which is a useful tell: get_info returned restricted true, incoming and outgoing connection counts 0, alt_blocks 0, start_time 0, free_space 18,446,744,073,709,551,615 (that is 2^64-1, the unsigned maximum) and an empty version string. The source does exactly that, field by field: restricted ? 0 : value. (how Monero fees work)
A wallet never asks a node for your balance. It asks for blocks, downloads them, and decrypts with the view key on your own machine. That is why node choice and key custody are separate problems. It also explains why a header-only public endpoint cannot sync a wallet: get_block at height 3,793,455 reported 272,341 bytes and 38 transactions, but the blob it returned was 1,401 bytes — 0.51 percent, the header plus the miner transaction only. A 1,000-block header range came back as 891,929 bytes of JSON. A full mainnet database is 295,279,001,600 bytes, 275.0 GiB. Nobody syncs that through a stripped endpoint.
So the honest boundary looks like this. A remote node learns your IP, roughly when you are online, which block heights you request, and — if it accepts broadcasts — the txid of your transaction together with the IP that submitted it. It does not learn your addresses, your balance or your outputs: it never holds your view key, and amounts on chain are already hidden. What it actually gains is correlation. An IP that keeps asking for new blocks is a wallet. An IP that submits a transaction at 18:0x is probably the person who built it.
Running your own node removes the third party from that path. The transaction is relayed by your daemon, and Monero wraps relay in Dandelion++. The constants are literal: CRYPTONOTE_DANDELIONPP_STEMS is 2 outgoing stem connections per epoch, an epoch lasts 10 minutes plus or minus 30 seconds, the embargo averages 39 seconds, and the fluff probability is 20 out of 100 — levin_notify.cpp draws an index below 100 and compares it against that constant, so one epoch in five broadcasts immediately instead of stemming. A default node keeps 12 outgoing connections and 2 anchor connections.
None of that changes what the chain records. Your input, the deposit address the swap site gave you, the amount and the timestamp stay linked no matter which node relayed the bytes. The network layer is unchanged too: your ISP still sees a long-lived encrypted connection to the Monero P2P network, and traffic analysis on that connection is a different attack surface from RPC logs. In practice a local node moves the IP-to-transaction link from an operator you never met to your ISP and to the first peers that saw the transaction — a smaller audience, not an empty one. If the network layer is the thing you care about, the tool is --proxy socks5://127.0.0.1:9050, and --proxy-allow-dns-leaks defaults to false.
It is worth seeing what a worse version of this looks like. We opened one unauthenticated TLS connection to electrum.blockstream.info:50002, on Bitcoin. It introduced itself as electrs-esplora 0.4.1, protocol 1.4 — no key, no account, no handshake. We asked for the scripthash of a single address and got 67,156 history entries, a confirmed balance of 5,769,022,283 sat plus 3,672 unconfirmed, and a live subscription that pushes updates. A Bitcoin light wallet has to tell a server exactly which addresses it owns, one scripthash at a time. Monero's remote-node model is narrower: blocks, heights, fees, broadcast. Same words, light client, very different amount of information handed over. (how Monero fees work)
Six checks before you point a wallet at a node you do not run. First, read restricted in get_info; true means it is somebody's public endpoint. Second, treat Method not found as a signal rather than a bug, because that is how a public endpoint hides state-changing and hash-lookup calls. Third, never query your own transaction hash through a public node you do not trust; that is the one call that pins an IP to a txid. Fourth, if you broadcast through a remote node, assume the operator kept the first-seen timestamp. Fifth, route the daemon through Tor with --proxy and leave --proxy-allow-dns-leaks at false. Sixth, if you run a node, keep --public-node off unless you mean to serve strangers — the flag exists to offer restricted, view-only RPC to other people. (Is Tor safe for swaps?)
Where this matters for an actual swap: the order itself never asks which node you use or connects to your wallet. VeilSwap takes a from-asset, a to-asset, an amount, a payout address and a refund address; the deposit address is generated per order. So node choice changes what your IP reveals to infrastructure, not what the order reveals. The rest is arithmetic, quoted at 18:0x UTC on 27 October 2026: 100, 500, 1,000 and 5,000 USDT-TRC20 bought 0.14632886, 0.80265134, 1.62303474 and 8.18504305 XMR — 683.39, 622.94, 616.13 and 610.87 dollars per XMR, so the small order carries about 11 percent more fixed cost. 1 XMR sold for 581.884075 USDT, and 0.05 BTC bought 6.60798844 XMR at 132.15977 XMR per BTC, an implied BTC near 79,699 dollars, while spot was 599.33 for XMR and 80,546 for BTC. Live quotes move; the page is the reference. In the same window a 1,534-byte transaction at the 20,000 piconero-per-byte floor cost 0.00003068 XMR, about two cents. (recovering misdirected funds)
The short version. A remote node is an observer with a timestamp, not a key holder: it can correlate an IP with activity and with a submission, and it cannot read amounts, addresses or balances. A local node takes that observer off the broadcast path and hands the same correlation to your ISP, while Dandelion++ hides the origin in four epochs out of five. Neither choice touches the on-chain record. Pick the node for what it leaks, pick the chain for what it stores, and check the restricted flag before you trust either.