wallet/txdb: refactor.
This commit is contained in:
parent
8c923179dc
commit
c7fb41f4cd
@ -46,9 +46,9 @@ URI.prototype.fromOptions = function fromOptions(options) {
|
|||||||
this.message = options.message;
|
this.message = options.message;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.r) {
|
if (options.request) {
|
||||||
assert(typeof options.request === 'string');
|
assert(typeof options.request === 'string');
|
||||||
this.request = options.r;
|
this.request = options.request;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
|
|||||||
@ -441,13 +441,13 @@ TXDB.prototype.getOrphans = co(function* getOrphans(hash, index) {
|
|||||||
TXDB.prototype.verify = co(function* verify(tx, info) {
|
TXDB.prototype.verify = co(function* verify(tx, info) {
|
||||||
var i, input, prevout, address, coin, spent, conflict;
|
var i, input, prevout, address, coin, spent, conflict;
|
||||||
|
|
||||||
|
if (tx.isCoinbase())
|
||||||
|
return true;
|
||||||
|
|
||||||
for (i = 0; i < tx.inputs.length; i++) {
|
for (i = 0; i < tx.inputs.length; i++) {
|
||||||
input = tx.inputs[i];
|
input = tx.inputs[i];
|
||||||
prevout = input.prevout;
|
prevout = input.prevout;
|
||||||
|
|
||||||
if (tx.isCoinbase())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
address = input.getHash('hex');
|
address = input.getHash('hex');
|
||||||
|
|
||||||
// Only bother if this input is ours.
|
// Only bother if this input is ours.
|
||||||
@ -491,7 +491,7 @@ TXDB.prototype.verify = co(function* verify(tx, info) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.warning('Removing conflicting tx: %s.',
|
this.logger.warning('Handling conflicting tx: %s.',
|
||||||
utils.revHex(spent.hash));
|
utils.revHex(spent.hash));
|
||||||
|
|
||||||
// Remove the older double spender.
|
// Remove the older double spender.
|
||||||
@ -502,6 +502,8 @@ TXDB.prototype.verify = co(function* verify(tx, info) {
|
|||||||
if (!conflict)
|
if (!conflict)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
this.logger.warning('Removed conflict: %s.', conflict.tx.rhash);
|
||||||
|
|
||||||
// Emit the _removed_ transaction.
|
// Emit the _removed_ transaction.
|
||||||
this.emit('conflict', conflict.tx, conflict.info);
|
this.emit('conflict', conflict.tx, conflict.info);
|
||||||
}
|
}
|
||||||
@ -632,43 +634,42 @@ TXDB.prototype._add = co(function* add(tx, info) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Consume unspent money or add orphans
|
// Consume unspent money or add orphans
|
||||||
for (i = 0; i < tx.inputs.length; i++) {
|
if (!tx.isCoinbase()) {
|
||||||
input = tx.inputs[i];
|
for (i = 0; i < tx.inputs.length; i++) {
|
||||||
prevout = input.prevout;
|
input = tx.inputs[i];
|
||||||
|
prevout = input.prevout;
|
||||||
|
|
||||||
if (tx.isCoinbase())
|
address = input.getHash('hex');
|
||||||
continue;
|
path = info.getPath(address);
|
||||||
|
|
||||||
address = input.getHash('hex');
|
// Only bother if this input is ours.
|
||||||
path = info.getPath(address);
|
if (!path)
|
||||||
|
continue;
|
||||||
|
|
||||||
// Only bother if this input is ours.
|
key = prevout.hash + prevout.index;
|
||||||
if (!path)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
key = prevout.hash + prevout.index;
|
// s[outpoint-key] -> [spender-hash]|[spender-input-index]
|
||||||
|
spender = bcoin.outpoint.fromTX(tx, i).toRaw();
|
||||||
|
this.put(layout.s(prevout.hash, prevout.index), spender);
|
||||||
|
|
||||||
// s[outpoint-key] -> [spender-hash]|[spender-input-index]
|
// Add orphan, if no parent transaction is yet known
|
||||||
spender = bcoin.outpoint.fromTX(tx, i).toRaw();
|
if (!input.coin) {
|
||||||
this.put(layout.s(prevout.hash, prevout.index), spender);
|
try {
|
||||||
|
yield this.addOrphan(prevout, spender);
|
||||||
// Add orphan, if no parent transaction is yet known
|
} catch (e) {
|
||||||
if (!input.coin) {
|
this.drop();
|
||||||
try {
|
throw e;
|
||||||
yield this.addOrphan(prevout, spender);
|
}
|
||||||
} catch (e) {
|
continue;
|
||||||
this.drop();
|
|
||||||
throw e;
|
|
||||||
}
|
}
|
||||||
continue;
|
|
||||||
|
this.del(layout.c(prevout.hash, prevout.index));
|
||||||
|
this.del(layout.C(path.account, prevout.hash, prevout.index));
|
||||||
|
this.put(layout.d(hash, i), input.coin.toRaw());
|
||||||
|
this.balance.sub(input.coin);
|
||||||
|
|
||||||
|
this.coinCache.remove(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.del(layout.c(prevout.hash, prevout.index));
|
|
||||||
this.del(layout.C(path.account, prevout.hash, prevout.index));
|
|
||||||
this.put(layout.d(hash, i), input.coin.toRaw());
|
|
||||||
this.balance.sub(input.coin);
|
|
||||||
|
|
||||||
this.coinCache.remove(key);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add unspent outputs or resolve orphans
|
// Add unspent outputs or resolve orphans
|
||||||
@ -743,7 +744,7 @@ TXDB.prototype.removeConflict = co(function* removeConflict(hash, ref) {
|
|||||||
|
|
||||||
// If both are confirmed but replacement
|
// If both are confirmed but replacement
|
||||||
// is older than spender, do nothing.
|
// is older than spender, do nothing.
|
||||||
if (ref.ts < tx.ts)
|
if (ref.height < tx.height)
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
// If spender is unconfirmed and replacement
|
// If spender is unconfirmed and replacement
|
||||||
@ -1033,36 +1034,35 @@ TXDB.prototype.__remove = co(function* remove(tx, info) {
|
|||||||
this.del(layout.M(account, tx.ps, hash));
|
this.del(layout.M(account, tx.ps, hash));
|
||||||
}
|
}
|
||||||
|
|
||||||
yield this.fillHistory(tx);
|
if (!tx.isCoinbase()) {
|
||||||
|
yield this.fillHistory(tx);
|
||||||
|
|
||||||
for (i = 0; i < tx.inputs.length; i++) {
|
for (i = 0; i < tx.inputs.length; i++) {
|
||||||
input = tx.inputs[i];
|
input = tx.inputs[i];
|
||||||
key = input.prevout.hash + input.prevout.index;
|
key = input.prevout.hash + input.prevout.index;
|
||||||
prevout = input.prevout;
|
prevout = input.prevout;
|
||||||
address = input.getHash('hex');
|
address = input.getHash('hex');
|
||||||
|
|
||||||
if (tx.isCoinbase())
|
if (!input.coin)
|
||||||
break;
|
continue;
|
||||||
|
|
||||||
if (!input.coin)
|
path = info.getPath(address);
|
||||||
continue;
|
|
||||||
|
|
||||||
path = info.getPath(address);
|
if (!path)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (!path)
|
this.balance.add(input.coin);
|
||||||
continue;
|
|
||||||
|
|
||||||
this.balance.add(input.coin);
|
coin = input.coin.toRaw();
|
||||||
|
|
||||||
coin = input.coin.toRaw();
|
this.put(layout.c(prevout.hash, prevout.index), coin);
|
||||||
|
this.put(layout.C(path.account, prevout.hash, prevout.index), DUMMY);
|
||||||
|
this.del(layout.d(hash, i));
|
||||||
|
this.del(layout.s(prevout.hash, prevout.index));
|
||||||
|
this.del(layout.o(prevout.hash, prevout.index));
|
||||||
|
|
||||||
this.put(layout.c(prevout.hash, prevout.index), coin);
|
this.coinCache.set(key, coin);
|
||||||
this.put(layout.C(path.account, prevout.hash, prevout.index), DUMMY);
|
}
|
||||||
this.del(layout.d(hash, i));
|
|
||||||
this.del(layout.s(prevout.hash, prevout.index));
|
|
||||||
this.del(layout.o(prevout.hash, prevout.index));
|
|
||||||
|
|
||||||
this.coinCache.set(key, coin);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < tx.outputs.length; i++) {
|
for (i = 0; i < tx.outputs.length; i++) {
|
||||||
@ -1356,7 +1356,7 @@ TXDB.prototype.getUnconfirmedHashes = function getUnconfirmedHashes(account) {
|
|||||||
* @returns {Promise} - Returns {@link Hash}[].
|
* @returns {Promise} - Returns {@link Hash}[].
|
||||||
*/
|
*/
|
||||||
|
|
||||||
TXDB.prototype.getCoinHashes = function getCoinHashes(account) {
|
TXDB.prototype.getOutpoints = function getOutpoints(account) {
|
||||||
return this.iterate({
|
return this.iterate({
|
||||||
gte: account != null
|
gte: account != null
|
||||||
? layout.C(account, constants.NULL_HASH, 0)
|
? layout.C(account, constants.NULL_HASH, 0)
|
||||||
@ -1632,7 +1632,7 @@ TXDB.prototype.getCoins = function getCoins(account) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
TXDB.prototype.getAccountCoins = co(function* getCoins(account) {
|
TXDB.prototype.getAccountCoins = co(function* getCoins(account) {
|
||||||
var prevout = yield this.getCoinHashes(account);
|
var prevout = yield this.getOutpoints(account);
|
||||||
var coins = [];
|
var coins = [];
|
||||||
var i, op, coin;
|
var i, op, coin;
|
||||||
|
|
||||||
@ -1921,7 +1921,7 @@ TXDB.prototype.getBalance = co(function* getBalance(account) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
TXDB.prototype.getAccountBalance = co(function* getBalance(account) {
|
TXDB.prototype.getAccountBalance = co(function* getBalance(account) {
|
||||||
var prevout = yield this.getCoinHashes(account);
|
var prevout = yield this.getOutpoints(account);
|
||||||
var balance = new Balance(this.wallet);
|
var balance = new Balance(this.wallet);
|
||||||
var i, ckey, key, coin, op, data;
|
var i, ckey, key, coin, op, data;
|
||||||
|
|
||||||
|
|||||||
@ -441,17 +441,13 @@ WalletDB.prototype.getWalletID = co(function* getWalletID(id) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
WalletDB.prototype.get = co(function* get(wid) {
|
WalletDB.prototype.get = co(function* get(wid) {
|
||||||
var wallet, unlock;
|
var unlock;
|
||||||
|
|
||||||
wid = yield this.getWalletID(wid);
|
wid = yield this.getWalletID(wid);
|
||||||
|
|
||||||
if (!wid)
|
if (!wid)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
wallet = this.wallets[wid];
|
|
||||||
if (wallet)
|
|
||||||
return wallet;
|
|
||||||
|
|
||||||
// NOTE: Lock must start here!
|
|
||||||
unlock = yield this.readLock.lock(wid);
|
unlock = yield this.readLock.lock(wid);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -469,8 +465,16 @@ WalletDB.prototype.get = co(function* get(wid) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
WalletDB.prototype._get = co(function* get(wid) {
|
WalletDB.prototype._get = co(function* get(wid) {
|
||||||
var data = yield this.db.get(layout.w(wid));
|
var data, wallet;
|
||||||
var wallet;
|
|
||||||
|
// By the time the lock is released,
|
||||||
|
// the wallet may be watched.
|
||||||
|
wallet = this.wallets[wid];
|
||||||
|
|
||||||
|
if (wallet)
|
||||||
|
return wallet;
|
||||||
|
|
||||||
|
data = yield this.db.get(layout.w(wid));
|
||||||
|
|
||||||
if (!data)
|
if (!data)
|
||||||
return;
|
return;
|
||||||
@ -976,9 +980,9 @@ WalletDB.prototype._rescan = co(function* rescan(chaindb, height) {
|
|||||||
|
|
||||||
this.logger.info('Scanning for %d addresses.', hashes.length);
|
this.logger.info('Scanning for %d addresses.', hashes.length);
|
||||||
|
|
||||||
yield chaindb.scan(height, hashes, co(function *(block, txs) {
|
yield chaindb.scan(height, hashes, function(block, txs) {
|
||||||
yield self._addBlock(block, txs);
|
return self._addBlock(block, txs);
|
||||||
}));
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user