public void FinneyAttack()
{
// A Finney attack is where a miner includes a transaction spending coins to themselves but does not
// broadcast it. When they find a solved block, they hold it back temporarily whilst they buy something with
// those same coins. After purchasing, they broadcast the block thus reversing the transaction. It can be
// done by any miner for products that can be bought at a chosen time and very quickly (as every second you
// withhold your block means somebody else might find it first, invalidating your work).
//
// Test that we handle ourselves performing the attack correctly: a double spend on the chain moves
// transactions from pending to dead.
//
// Note that the other way around, where a pending transaction sending us coins becomes dead,
// isn't tested because today BitCoinJ only learns about such transactions when they appear in the chain.
Transaction eventDead = null;
Transaction eventReplacement = null;
_wallet.DeadTransaction +=
(sender, e) =>
{
eventDead = e.DeadTx;
eventReplacement = e.ReplacementTx;
};
// Receive 1 BTC.
var nanos = Utils.ToNanoCoins(1, 0);
var t1 = TestUtils.CreateFakeTx(_params, nanos, _myAddress);
_wallet.Receive(t1, null, BlockChain.NewBlockType.BestChain);
// Create a send to a merchant.
var send1 = _wallet.CreateSend(new EcKey().ToAddress(_params), Utils.ToNanoCoins(0, 50));
// Create a double spend.
var send2 = _wallet.CreateSend(new EcKey().ToAddress(_params), Utils.ToNanoCoins(0, 50));
// Broadcast send1.
_wallet.ConfirmSend(send1);
// Receive a block that overrides it.
_wallet.Receive(send2, null, BlockChain.NewBlockType.BestChain);
Assert.AreEqual(send1, eventDead);
Assert.AreEqual(send2, eventReplacement);
}