diff --git a/lib/wallet/txdb.js b/lib/wallet/txdb.js index d29d9557..7123d7ab 100644 --- a/lib/wallet/txdb.js +++ b/lib/wallet/txdb.js @@ -489,7 +489,7 @@ TXDB.prototype.verifyInputs = co(function* verifyInputs(tx) { if (coin) { input.coin = coin; - if (this.options.verify) { + if (this.options.verify && tx.height === -1) { if (!(yield tx.verifyInputAsync(i))) return false; } @@ -515,7 +515,7 @@ TXDB.prototype.verifyInputs = co(function* verifyInputs(tx) { input.coin = coin; - if (this.options.verify) { + if (this.options.verify && tx.height === -1) { if (!(yield tx.verifyInputAsync(i))) return false; } @@ -568,7 +568,8 @@ TXDB.prototype.verifyInputs = co(function* verifyInputs(tx) { TXDB.prototype.resolveOutputs = co(function* resolveOutputs(tx, resolved) { var hash = tx.hash('hex'); - var i, input, output, key, orphans, orphan, coin, valid; + var i, j, input, output, key; + var orphans, orphan, coin, valid; if (!resolved) resolved = []; @@ -587,8 +588,8 @@ TXDB.prototype.resolveOutputs = co(function* resolveOutputs(tx, resolved) { coin = Coin.fromTX(tx, i); - while (orphans.length) { - orphan = orphans.pop(); + for (j = 0; j < orphans.length; j++) { + orphan = orphans[j]; valid = true; input = orphan.tx.inputs[orphan.index]; @@ -597,7 +598,7 @@ TXDB.prototype.resolveOutputs = co(function* resolveOutputs(tx, resolved) { assert(input.prevout.hash === hash); assert(input.prevout.index === i); - if (this.options.verify) + if (this.options.verify && orphan.tx.height === -1) valid = yield orphan.tx.verifyInputAsync(orphan.index); if (valid) { @@ -768,7 +769,7 @@ TXDB.prototype._add = co(function* add(tx, info) { this.put(layout.t(hash), tx.toExtended()); - if (tx.ts === 0) + if (tx.height === -1) this.put(layout.p(hash), DUMMY); else this.put(layout.h(tx.height, hash), DUMMY); @@ -780,7 +781,7 @@ TXDB.prototype._add = co(function* add(tx, info) { this.put(layout.T(account, hash), DUMMY); - if (tx.ts === 0) + if (tx.height === -1) this.put(layout.P(account, hash), DUMMY); else this.put(layout.H(account, tx.height, hash), DUMMY); @@ -804,7 +805,6 @@ TXDB.prototype._add = co(function* add(tx, info) { key = prevout.hash + prevout.index; - // s[outpoint-key] -> [spender-hash]|[spender-input-index] spender = Outpoint.fromTX(tx, i).toRaw(); this.put(layout.s(prevout.hash, prevout.index), spender); @@ -848,7 +848,7 @@ TXDB.prototype._add = co(function* add(tx, info) { this.emit('tx', tx, info); - if (tx.ts !== 0) + if (tx.height !== -1) this.emit('confirmed', tx, info); this.emit('balance', this.pending.balance, info); @@ -1005,21 +1005,14 @@ TXDB.prototype.confirm = co(function* confirm(tx, info) { return false; // Existing tx is already confirmed. Ignore. - if (existing.ts !== 0) + if (existing.height !== -1) return true; // The incoming tx won't confirm the // existing one anyway. Ignore. - if (tx.ts === 0) + if (tx.height === -1) return true; - // Tricky - update the tx and coin in storage, - // and remove pending flag to mark as confirmed. - assert(tx.height >= 0); - - // Clear any locked coins to free up memory. - this.unlockTX(tx); - // Save the original received time. tx.ps = existing.ps; @@ -1062,6 +1055,9 @@ TXDB.prototype.confirm = co(function* confirm(tx, info) { this.put(layout.R, this.pending.commit()); + // Clear any locked coins to free up memory. + this.unlockTX(tx); + this.emit('tx', tx, info); this.emit('confirmed', tx, info); this.emit('balance', this.pending.balance, info); @@ -1141,11 +1137,11 @@ TXDB.prototype.lazyRemove = co(function* lazyRemove(tx) { TXDB.prototype.__remove = co(function* remove(tx, info) { var hash = tx.hash('hex'); var i, path, account, key, prevout; - var input, output, coin; + var input, output, coin, coins; this.del(layout.t(hash)); - if (tx.ts === 0) + if (tx.height === -1) this.del(layout.p(hash)); else this.del(layout.h(tx.height, hash)); @@ -1157,7 +1153,7 @@ TXDB.prototype.__remove = co(function* remove(tx, info) { this.del(layout.T(account, hash)); - if (tx.ts === 0) + if (tx.height === -1) this.del(layout.P(account, hash)); else this.del(layout.H(account, tx.height, hash)); @@ -1166,24 +1162,23 @@ TXDB.prototype.__remove = co(function* remove(tx, info) { } if (!tx.isCoinbase()) { - yield this.fillHistory(tx); + coins = yield this.fillHistory(tx); for (i = 0; i < tx.inputs.length; i++) { input = tx.inputs[i]; key = input.prevout.hash + input.prevout.index; prevout = input.prevout; + coin = coins[i]; - if (!input.coin) + if (!coin) continue; - path = info.getPath(input.coin); + path = info.getPath(coin); + assert(path); - if (!path) - continue; + this.pending.add(coin); - this.pending.add(input.coin); - - coin = input.coin.toRaw(); + coin = coin.toRaw(); this.put(layout.c(prevout.hash, prevout.index), coin); this.put(layout.C(path.account, prevout.hash, prevout.index), DUMMY); @@ -1283,10 +1278,7 @@ TXDB.prototype.__unconfirm = co(function* unconfirm(tx, info) { if (height === -1) return; - tx.height = -1; - tx.ts = 0; - tx.index = -1; - tx.block = null; + tx.unsetBlock(); this.put(layout.t(hash), tx.toExtended()); @@ -1857,15 +1849,16 @@ TXDB.prototype.getAccountCoins = co(function* getCoins(account) { * @returns {Promise} - Returns {@link TX}. */ -TXDB.prototype.fillHistory = function fillHistory(tx) { +TXDB.prototype.fillHistory = co(function* fillHistory(tx) { + var coins = []; var hash; if (tx.isCoinbase()) - return Promise.resolve(tx); + return coins; hash = tx.hash('hex'); - return this.range({ + yield this.range({ gte: layout.d(hash, 0x00000000), lte: layout.d(hash, 0xffffffff), parse: function(key, value) { @@ -1876,9 +1869,12 @@ TXDB.prototype.fillHistory = function fillHistory(tx) { coin.hash = input.prevout.hash; coin.index = input.prevout.index; input.coin = coin; + coins[index] = coin; } }); -}; + + return coins; +}); /** * Fill a transaction with coins. @@ -2192,7 +2188,7 @@ TXDB.prototype.zap = co(function* zap(account, age) { tx = txs[i]; hash = tx.hash('hex'); - if (tx.ts !== 0) + if (tx.height !== -1) continue; assert(now - tx.ps >= age);