diff --git a/lib/wallet/txdb.js b/lib/wallet/txdb.js index 48c7de90..1f9e733a 100644 --- a/lib/wallet/txdb.js +++ b/lib/wallet/txdb.js @@ -886,6 +886,9 @@ class TXDB { async removeRecursive(wtx) { const {tx, hash} = wtx; + if (!await this.hasTX(hash)) + return null; + for (let i = 0; i < tx.outputs.length; i++) { const spent = await this.getSpent(hash, i); diff --git a/test/wallet-test.js b/test/wallet-test.js index 1cd9bb7e..2972c723 100644 --- a/test/wallet-test.js +++ b/test/wallet-test.js @@ -519,6 +519,36 @@ describe('Wallet', function() { assert.strictEqual((await wallet.getBalance()).unconfirmed, 0); }); + it('should handle double-spend (multiple inputs)', async () => { + const wallet = await wdb.create(); + const address = await wallet.receiveAddress(); + + const hash = random.randomBytes(32); + const input0 = Input.fromOutpoint(new Outpoint(hash, 0)); + const input1 = Input.fromOutpoint(new Outpoint(hash, 1)); + + const txa = new MTX(); + txa.addInput(input0); + txa.addInput(input1); + txa.addOutput(address, 50000); + await wdb.addTX(txa.toTX()); + assert.strictEqual((await wallet.getBalance()).unconfirmed, 50000); + + let conflict = false; + wallet.on('conflict', () => { + conflict = true; + }); + + const txb = new MTX(); + txb.addInput(input0); + txb.addInput(input1); + txb.addOutput(address, 49000); + await wdb.addTX(txb.toTX()); + + assert(conflict); + assert.strictEqual((await wallet.getBalance()).unconfirmed, 49000); + }); + it('should handle more missed txs', async () => { const alice = await wdb.create(); const bob = await wdb.create();