Submitting this in the hopes somebody might pick it up and run with it (see the TODO list at end):
Instead of dropping double-spent transactions, relay them to peers. Why? To make it easier for merchants to quickly detect attempted fraud for low-value, in-person purchases.
A bloom filter is used so that only the first double-spend is relayed, to prevent an attacker from mounting a network denial-of-service attack by flooding it with double-spends of a transaction output they control.
Peter Todd pointed out a possible try-to-DoS-network-bandwidth attack that this enables that works like this:
- Attacker starts with an unspent transaction input.
- Attacker sends a small-in-size first spend with a small fee.
- Attacker double-spends the transaction input with a very large (e.g. 100K) transaction with a large fee.
Since miners will mine the first, small transaction (it might even pay a higher fee-per-kilobyte, but pay lower overall fee), an attacker can waste network bandwidth for a low cost. Whether or not attackers will actually do this isn't clear, they don't directly gain anything by wasting network bandwidth.
The right solution to that possible DoS attack is for nodes to have a bandwidth budget for 'tx' messages, and start dropping messages (perhaps starting with the largest double-spends) if that budget is exceeded.
Other things on the TODO:
Bitcoin-Qt should warn the user if a zero-confirmation transaction is double-spent, and should have a notion of "dead" transactions (another spend made it into a block). NOTE: I found it is easy to create double spends running three local nodes in -regtest mode, and the raw transactions API (create/sign a pair of double-spending transactions, then sendrawtransaction them from two nodes at the same time).
The RPC calls that give transaction information should report (somehow) double-spend attempts and "dead" transactions.
Write up a test plan for all of the above.