Edit: see pull request described here:
http://forum.bitcoin.org/index.php?topic=7330.0It is a situation that is currently hard to reach, but nonetheless possible when moving wallet.dat files around, and can potentially leave you with a permanently corrupted wallet.
Consider this scenario:
- Alice receives a 50BTC coin
- Alice creates backup of her wallet
- Alice goes offline
- Bob imports A's wallet
- Bob sends 20BTC to Carol (sending 30BTC change to a reserve key)
- Alice comes online before Bob's transaction ends up in a block, or somehow does not receive the block it is in yet
- Alice sends 10BTC to Ted, using the 50BTC coin as input
The network already knows about Bob's spending of the 50BTC coin, so it will not accept Alice's transaction anymore. Alice should be using the 30BTC change coin, but does not know about this yet. The result is that Alice has a transaction in her wallet which will never be accepted by the network, but Alice still assumes it is valid. Even worse, Alice will try to use the 40BTC change of that transaction in further transactions as well, and those transactions (and everything resulting from its change) won't be accepted by the network either.
You may argue that copying wallet.dat files around is always a dangerous business, but I don't like the idea that being unaware of a transaction happening using one of your own keys can potentially break things.
I'm working on a patch to detect cases where the blockchain conflicts with a wallet, but the question is: what to do when it happens?
Some possibilities:
- Edge case, don't bother
- Silently drop the offending transaction from the wallet (very easy)
- At least give a warning message in the GUI (easy, but what to do in bitcoind?)
- Mark the transaction somehow as inactive, and show this in the GUI and RPC calls (needs some changes, including update to wallet.dat format if you want keep these permanently)
- Try to recreate the transaction, using inputs that do exist (after user confirmation in GUI, or using special RPC call)
- Automatically try to recreate the transactions (probably too dangerous)