txdb: cleanup.
This commit is contained in:
parent
4232cdc6b9
commit
06a104c34d
@ -212,7 +212,8 @@ function TXDB(wallet) {
|
||||
this.logger = wallet.db.logger;
|
||||
this.network = wallet.db.network;
|
||||
this.options = wallet.db.options;
|
||||
this.coinCache = new LRU.Nil(10000);
|
||||
this.coinCache = new LRU(10000);
|
||||
this.spentCache = new LRU(10000);
|
||||
|
||||
this.locked = {};
|
||||
this.state = null;
|
||||
@ -254,10 +255,9 @@ TXDB.prototype.open = co(function* open() {
|
||||
this.state.tx, this.state.coin);
|
||||
|
||||
this.logger.info(
|
||||
'Balance: unconfirmed=%s confirmed=%s total=%s.',
|
||||
'Balance: unconfirmed=%s confirmed=%s.',
|
||||
utils.btc(this.balance.unconfirmed),
|
||||
utils.btc(this.balance.confirmed),
|
||||
utils.btc(this.balance.total));
|
||||
utils.btc(this.balance.confirmed));
|
||||
});
|
||||
|
||||
/**
|
||||
@ -490,6 +490,26 @@ TXDB.prototype.verifyInputs = co(function* verifyInputs(tx) {
|
||||
for (i = 0; i < tx.inputs.length; i++) {
|
||||
input = tx.inputs[i];
|
||||
prevout = input.prevout;
|
||||
|
||||
spent = yield this.isSpent(prevout.hash, prevout.index);
|
||||
|
||||
if (spent) {
|
||||
if (tx.height === -1)
|
||||
return false;
|
||||
|
||||
coin = yield this.getSpentCoin(spent, prevout);
|
||||
assert(coin);
|
||||
|
||||
input.coin = coin;
|
||||
|
||||
if (this.options.verify && tx.height === -1) {
|
||||
if (!(yield tx.verifyInputAsync(i)))
|
||||
return false;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
coin = yield this.getCoin(prevout.hash, prevout.index);
|
||||
|
||||
if (coin) {
|
||||
@ -503,31 +523,13 @@ TXDB.prototype.verifyInputs = co(function* verifyInputs(tx) {
|
||||
continue;
|
||||
}
|
||||
|
||||
spent = yield this.isSpent(prevout.hash, prevout.index);
|
||||
address = input.getHash('hex');
|
||||
path = yield this.wallet.hasPath(address);
|
||||
|
||||
if (!spent) {
|
||||
address = input.getHash('hex');
|
||||
path = yield this.wallet.hasPath(address);
|
||||
|
||||
if (!path)
|
||||
continue;
|
||||
|
||||
orphans[i] = true;
|
||||
if (!path)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tx.height === -1)
|
||||
return false;
|
||||
|
||||
coin = yield this.getSpentCoin(spent, prevout);
|
||||
assert(coin);
|
||||
|
||||
input.coin = coin;
|
||||
|
||||
if (this.options.verify && tx.height === -1) {
|
||||
if (!(yield tx.verifyInputAsync(i)))
|
||||
return false;
|
||||
}
|
||||
orphans[i] = true;
|
||||
}
|
||||
|
||||
for (i = 0; i < tx.inputs.length; i++) {
|
||||
@ -696,7 +698,7 @@ TXDB.prototype.add = co(function* add(tx) {
|
||||
TXDB.prototype._add = co(function* add(tx, info) {
|
||||
var hash, path, account;
|
||||
var i, result, input, output, coin;
|
||||
var prevout, key, spender, coins;
|
||||
var prevout, key, spender, raw;
|
||||
|
||||
assert(!tx.mutable, 'Cannot add mutable TX to wallet.');
|
||||
|
||||
@ -759,17 +761,19 @@ TXDB.prototype._add = co(function* add(tx, info) {
|
||||
|
||||
this.put(layout.s(prevout.hash, prevout.index), spender);
|
||||
|
||||
this.pending.balance.unconfirmed -= coin.value;
|
||||
|
||||
if (tx.height === -1) {
|
||||
this.put(layout.S(prevout.hash, prevout.index), spender);
|
||||
this.spentCache.set(key, spender);
|
||||
} else {
|
||||
this.pending.balance.confirmed -= coin.value;
|
||||
this.del(layout.c(prevout.hash, prevout.index));
|
||||
this.del(layout.C(path.account, prevout.hash, prevout.index));
|
||||
this.coinCache.remove(key);
|
||||
}
|
||||
|
||||
this.put(layout.d(hash, i), coin.toRaw());
|
||||
this.pending.sub(coin);
|
||||
|
||||
this.coinCache.remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
@ -785,15 +789,17 @@ TXDB.prototype._add = co(function* add(tx, info) {
|
||||
continue;
|
||||
|
||||
coin = Coin.fromTX(tx, i);
|
||||
raw = coin.toRaw();
|
||||
|
||||
this.pending.add(coin);
|
||||
this.pending.balance.unconfirmed += coin.value;
|
||||
|
||||
coin = coin.toRaw();
|
||||
if (tx.height !== -1)
|
||||
this.pending.balance.confirmed += coin.value;
|
||||
|
||||
this.put(layout.c(hash, i), coin);
|
||||
this.put(layout.c(hash, i), raw);
|
||||
this.put(layout.C(path.account, hash, i), DUMMY);
|
||||
|
||||
this.coinCache.set(key, coin);
|
||||
this.coinCache.set(key, raw);
|
||||
}
|
||||
|
||||
this.pending.tx++;
|
||||
@ -928,8 +934,13 @@ TXDB.prototype.isSpent = co(function* isSpent(hash, index) {
|
||||
*/
|
||||
|
||||
TXDB.prototype.isSpending = co(function* isSpending(hash, index) {
|
||||
var key = layout.S(hash, index);
|
||||
var data = yield this.get(key);
|
||||
var key = hash + index;
|
||||
var data = this.spentCache.get(key);
|
||||
|
||||
if (data)
|
||||
return Outpoint.fromRaw(data);
|
||||
|
||||
data = yield this.get(layout.S(hash, index));
|
||||
|
||||
if (!data)
|
||||
return;
|
||||
@ -951,7 +962,7 @@ TXDB.prototype.confirm = co(function* confirm(tx, info) {
|
||||
var hash = tx.hash('hex');
|
||||
var i, account, existing, output, coin;
|
||||
var input, prevout, path, spender, coins;
|
||||
var address, key, spent;
|
||||
var key, raw;
|
||||
|
||||
existing = yield this.getTX(hash);
|
||||
|
||||
@ -1001,22 +1012,29 @@ TXDB.prototype.confirm = co(function* confirm(tx, info) {
|
||||
if (!coin)
|
||||
continue;
|
||||
|
||||
spender = Outpoint.fromTX(tx, i).toRaw();
|
||||
|
||||
this.put(layout.d(hash, i), coin.toRaw());
|
||||
this.pending.sub(coin);
|
||||
this.put(layout.s(prevout.hash, prevout.index), spender);
|
||||
|
||||
this.pending.balance.unconfirmed -= coin.value;
|
||||
}
|
||||
|
||||
assert(coin.height !== -1);
|
||||
|
||||
// Only bother if this input is ours.
|
||||
path = info.getPath(coin);
|
||||
assert(path);
|
||||
|
||||
key = prevout.hash + prevout.index;
|
||||
|
||||
spender = Outpoint.fromTX(tx, i).toRaw();
|
||||
|
||||
this.del(layout.S(prevout.hash, prevout.index));
|
||||
this.del(layout.c(prevout.hash, prevout.index));
|
||||
this.del(layout.C(path.account, prevout.hash, prevout.index));
|
||||
|
||||
this.pending.balance.confirmed -= coin.value;
|
||||
|
||||
this.spentCache.remove(key);
|
||||
this.coinCache.remove(key);
|
||||
}
|
||||
}
|
||||
@ -1029,25 +1047,22 @@ TXDB.prototype.confirm = co(function* confirm(tx, info) {
|
||||
if (!info.hasPath(output))
|
||||
continue;
|
||||
|
||||
spent = yield this.isSpending(prevout.hash, prevout.index);
|
||||
|
||||
// Update spent coin.
|
||||
if (spent)
|
||||
yield this.updateSpentCoin(spent, tx, i);
|
||||
yield this.updateSpentCoin(tx, i);
|
||||
|
||||
coin = yield this.getCoin(hash, i);
|
||||
|
||||
if (!coin)
|
||||
continue;
|
||||
|
||||
this.pending.confirm(coin.value);
|
||||
|
||||
coin.height = tx.height;
|
||||
coin = coin.toRaw();
|
||||
raw = coin.toRaw();
|
||||
|
||||
this.put(layout.c(hash, i), coin);
|
||||
this.pending.balance.confirmed += coin.value;
|
||||
|
||||
this.coinCache.set(key, coin);
|
||||
this.put(layout.c(hash, i), raw);
|
||||
|
||||
this.coinCache.set(key, raw);
|
||||
}
|
||||
|
||||
this.put(layout.R, this.pending.commit());
|
||||
@ -1138,7 +1153,7 @@ 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, coins;
|
||||
var input, output, coin, coins, raw;
|
||||
|
||||
this.del(layout.t(hash));
|
||||
|
||||
@ -1177,19 +1192,22 @@ TXDB.prototype.__remove = co(function* remove(tx, info) {
|
||||
path = info.getPath(coin);
|
||||
assert(path);
|
||||
|
||||
this.pending.add(coin);
|
||||
this.pending.balance.unconfirmed += coin.value;
|
||||
|
||||
coin = coin.toRaw();
|
||||
this.del(layout.s(prevout.hash, prevout.index));
|
||||
|
||||
if (tx.height !== -1) {
|
||||
this.put(layout.c(prevout.hash, prevout.index), coin);
|
||||
raw = coin.toRaw();
|
||||
this.pending.balance.confirmed += coin.value;
|
||||
this.put(layout.c(prevout.hash, prevout.index), raw);
|
||||
this.put(layout.C(path.account, prevout.hash, prevout.index), DUMMY);
|
||||
this.coinCache.set(key, raw);
|
||||
} else {
|
||||
this.del(layout.S(prevout.hash, prevout.index));
|
||||
this.spentCache.remove(key);
|
||||
}
|
||||
this.del(layout.d(hash, i));
|
||||
|
||||
this.coinCache.set(key, coin);
|
||||
this.del(layout.d(hash, i));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1203,7 +1221,10 @@ TXDB.prototype.__remove = co(function* remove(tx, info) {
|
||||
|
||||
coin = Coin.fromTX(tx, i);
|
||||
|
||||
this.pending.sub(coin);
|
||||
this.pending.balance.unconfirmed -= coin.value;
|
||||
|
||||
if (tx.height !== -1)
|
||||
this.pending.balance.confirmed -= coin.value;
|
||||
|
||||
this.del(layout.c(hash, i));
|
||||
this.del(layout.C(path.account, hash, i));
|
||||
@ -1277,7 +1298,8 @@ TXDB.prototype._unconfirm = co(function* unconfirm(hash) {
|
||||
TXDB.prototype.__unconfirm = co(function* unconfirm(tx, info) {
|
||||
var hash = tx.hash('hex');
|
||||
var height = tx.height;
|
||||
var i, account, output, key, coin;
|
||||
var i, account, output, key, coin, coins;
|
||||
var input, prevout, path, spender, raw;
|
||||
|
||||
if (height === -1)
|
||||
return;
|
||||
@ -1295,10 +1317,9 @@ TXDB.prototype.__unconfirm = co(function* unconfirm(tx, info) {
|
||||
this.del(layout.H(account, height, hash));
|
||||
}
|
||||
|
||||
var input, prevout, coin, path, spender;
|
||||
// Consume unspent money or add orphans
|
||||
if (!tx.isCoinbase()) {
|
||||
var coins = yield this.fillHistory(tx);
|
||||
coins = yield this.fillHistory(tx);
|
||||
|
||||
for (i = 0; i < tx.inputs.length; i++) {
|
||||
input = tx.inputs[i];
|
||||
@ -1309,6 +1330,10 @@ TXDB.prototype.__unconfirm = co(function* unconfirm(tx, info) {
|
||||
if (!coin)
|
||||
continue;
|
||||
|
||||
assert(coin.height !== -1);
|
||||
|
||||
raw = coin.toRaw();
|
||||
|
||||
path = info.getPath(coin);
|
||||
assert(path);
|
||||
|
||||
@ -1317,33 +1342,35 @@ TXDB.prototype.__unconfirm = co(function* unconfirm(tx, info) {
|
||||
spender = Outpoint.fromTX(tx, i).toRaw();
|
||||
|
||||
this.put(layout.S(prevout.hash, prevout.index), spender);
|
||||
this.put(layout.c(prevout.hash, prevout.index), coin.toRaw());
|
||||
this.put(layout.c(prevout.hash, prevout.index), raw);
|
||||
this.put(layout.C(path.account, prevout.hash, prevout.index), DUMMY);
|
||||
|
||||
this.coinCache.remove(key);
|
||||
this.pending.balance.confirmed += coin.value;
|
||||
|
||||
this.spentCache.set(key, spender);
|
||||
this.coinCache.set(key, raw);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < tx.outputs.length; i++) {
|
||||
output = tx.outputs[i];
|
||||
key = hash + i;
|
||||
coin = yield this.getCoin(hash, i);
|
||||
|
||||
// Update spent coin.
|
||||
if (!coin) {
|
||||
var spent = yield this.isSpent(prevout.hash, prevout.index);
|
||||
yield this.updateSpentCoin(spent, tx, i);
|
||||
yield this.updateSpentCoin(tx, i);
|
||||
|
||||
coin = yield this.getCoin(hash, i);
|
||||
|
||||
if (!coin)
|
||||
continue;
|
||||
}
|
||||
|
||||
this.pending.unconfirm(coin.value);
|
||||
coin.height = -1;
|
||||
|
||||
coin.height = tx.height;
|
||||
coin = coin.toRaw();
|
||||
this.pending.balance.confirmed -= coin.value;
|
||||
|
||||
this.put(layout.c(hash, i), coin);
|
||||
this.put(layout.c(hash, i), coin.toRaw());
|
||||
|
||||
this.coinCache.set(key, coin);
|
||||
this.coinCache.remove(key);
|
||||
}
|
||||
|
||||
this.put(layout.R, this.pending.commit());
|
||||
@ -1828,7 +1855,7 @@ TXDB.prototype.getPending = co(function* getPending(account) {
|
||||
* @returns {Promise} - Returns {@link Coin}[].
|
||||
*/
|
||||
|
||||
TXDB.prototype.getCoins = co(function* getCoins(account) {
|
||||
TXDB.prototype.getCoins = co(function* getCoins(account, all) {
|
||||
var self = this;
|
||||
var out = [];
|
||||
var i, coins, coin;
|
||||
@ -1854,6 +1881,9 @@ TXDB.prototype.getCoins = co(function* getCoins(account) {
|
||||
}
|
||||
});
|
||||
|
||||
if (all)
|
||||
return coins;
|
||||
|
||||
for (i = 0; i < coins.length; i++) {
|
||||
coin = coins[i];
|
||||
if (yield this.isSpending(coin.hash, coin.index))
|
||||
@ -1870,7 +1900,7 @@ TXDB.prototype.getCoins = co(function* getCoins(account) {
|
||||
* @returns {Promise} - Returns {@link Coin}[].
|
||||
*/
|
||||
|
||||
TXDB.prototype.getAccountCoins = co(function* getCoins(account) {
|
||||
TXDB.prototype.getAccountCoins = co(function* getCoins(account, all) {
|
||||
var prevout = yield this.getOutpoints(account);
|
||||
var coins = [];
|
||||
var i, op, coin;
|
||||
@ -1882,6 +1912,11 @@ TXDB.prototype.getAccountCoins = co(function* getCoins(account) {
|
||||
if (!coin)
|
||||
continue;
|
||||
|
||||
if (!all) {
|
||||
if (yield this.isSpending(coin.hash, coin.index))
|
||||
continue;
|
||||
}
|
||||
|
||||
coins.push(coin);
|
||||
}
|
||||
|
||||
@ -1942,8 +1977,13 @@ TXDB.prototype.fillCoins = co(function* fillCoins(tx) {
|
||||
|
||||
coin = yield this.getCoin(prevout.hash, prevout.index);
|
||||
|
||||
if (coin)
|
||||
input.coin = coin;
|
||||
if (!coin)
|
||||
continue;
|
||||
|
||||
if (yield this.isSpending(coin.hash, coin.index))
|
||||
continue;
|
||||
|
||||
input.coin = coin;
|
||||
}
|
||||
|
||||
return tx;
|
||||
@ -2100,13 +2140,14 @@ TXDB.prototype.getSpentCoin = co(function* getSpentCoin(spent, prevout) {
|
||||
* @returns {Promise}
|
||||
*/
|
||||
|
||||
TXDB.prototype.updateSpentCoin = co(function* updateSpentCoin(spent, tx, i) {
|
||||
var prevout, coin;
|
||||
TXDB.prototype.updateSpentCoin = co(function* updateSpentCoin(tx, i) {
|
||||
var prevout = Outpoint.fromTX(tx, i);
|
||||
var spent = yield this.isSpent(prevout.hash, prevout.index);
|
||||
var coin;
|
||||
|
||||
if (!spent)
|
||||
return;
|
||||
|
||||
prevout = Outpoint.fromTX(tx, i);
|
||||
coin = yield this.getSpentCoin(spent, prevout);
|
||||
|
||||
if (!coin)
|
||||
@ -2153,22 +2194,20 @@ TXDB.prototype.getBalance = co(function* getBalance(account) {
|
||||
* @returns {Promise} - Returns {@link Balance}.
|
||||
*/
|
||||
|
||||
TXDB.prototype.getWalletBalance = co(function* getWalletBalance(account) {
|
||||
var self = this;
|
||||
TXDB.prototype.getWalletBalance = co(function* getWalletBalance() {
|
||||
var coins = yield this.getCoins(true);
|
||||
var balance = new Balance(this.wallet.wid, this.wallet.id, -1);
|
||||
var i, coin;
|
||||
|
||||
yield this.range({
|
||||
gte: layout.c(constants.NULL_HASH, 0x00000000),
|
||||
lte: layout.c(constants.HIGH_HASH, 0xffffffff),
|
||||
parse: function(key, data) {
|
||||
var parts = layout.cc(key);
|
||||
var hash = parts[0];
|
||||
var index = parts[1];
|
||||
var ckey = hash + index;
|
||||
balance.addRaw(data);
|
||||
self.coinCache.set(ckey, data);
|
||||
}
|
||||
});
|
||||
for (i = 0; i < coins.length; i++) {
|
||||
coin = coins[i];
|
||||
|
||||
if (coin.height !== -1)
|
||||
balance.confirmed += coin.value;
|
||||
|
||||
if (!(yield this.isSpending(coin.hash, coin.index)))
|
||||
balance.unconfirmed += coin.value;
|
||||
}
|
||||
|
||||
return balance;
|
||||
});
|
||||
@ -2179,30 +2218,19 @@ TXDB.prototype.getWalletBalance = co(function* getWalletBalance(account) {
|
||||
* @returns {Promise} - Returns {@link Balance}.
|
||||
*/
|
||||
|
||||
TXDB.prototype.getAccountBalance = co(function* getBalance(account) {
|
||||
var prevout = yield this.getOutpoints(account);
|
||||
TXDB.prototype.getAccountBalance = co(function* getAccountBalance(account) {
|
||||
var coins = yield this.getAccountCoins(account, true);
|
||||
var balance = new Balance(this.wallet.wid, this.wallet.id, account);
|
||||
var i, ckey, key, coin, op, data;
|
||||
var i, coin;
|
||||
|
||||
for (i = 0; i < prevout.length; i++) {
|
||||
op = prevout[i];
|
||||
ckey = op.hash + op.index;
|
||||
coin = this.coinCache.get(ckey);
|
||||
for (i = 0; i < coins.length; i++) {
|
||||
coin = coins[i];
|
||||
|
||||
if (coin) {
|
||||
balance.addRaw(coin);
|
||||
continue;
|
||||
}
|
||||
if (coin.height !== -1)
|
||||
balance.confirmed += coin.value;
|
||||
|
||||
key = layout.c(op.hash, op.index);
|
||||
data = yield this.get(key);
|
||||
|
||||
if (!data)
|
||||
continue;
|
||||
|
||||
balance.addRaw(data);
|
||||
|
||||
this.coinCache.set(ckey, data);
|
||||
if (!(yield this.isSpending(coin.hash, coin.index)))
|
||||
balance.unconfirmed += coin.value;
|
||||
}
|
||||
|
||||
return balance;
|
||||
@ -2274,26 +2302,22 @@ function Balance(wid, id, account) {
|
||||
this.account = account;
|
||||
this.unconfirmed = 0;
|
||||
this.confirmed = 0;
|
||||
this.total = 0;
|
||||
}
|
||||
|
||||
Balance.prototype.clone = function clone() {
|
||||
var balance = new Balance(this.wid, this.id, this.account);
|
||||
balance.unconfirmed = this.unconfirmed;
|
||||
balance.confirmed = this.confirmed;
|
||||
balance.total = this.total;
|
||||
return balance;
|
||||
};
|
||||
|
||||
Balance.prototype.equal = function equal(balance) {
|
||||
return this.wid === balance.wid
|
||||
&& this.total === balance.total
|
||||
&& this.confirmed === balance.confirmed
|
||||
&& this.unconfirmed === balance.unconfirmed;
|
||||
};
|
||||
|
||||
Balance.prototype.add = function add(coin) {
|
||||
this.total += coin.value;
|
||||
if (coin.height === -1)
|
||||
this.unconfirmed += coin.value;
|
||||
else
|
||||
@ -2301,7 +2325,6 @@ Balance.prototype.add = function add(coin) {
|
||||
};
|
||||
|
||||
Balance.prototype.sub = function sub(coin) {
|
||||
this.total -= coin.value;
|
||||
if (coin.height === -1)
|
||||
this.unconfirmed -= coin.value;
|
||||
else
|
||||
@ -2318,20 +2341,6 @@ Balance.prototype.unconfirm = function unconfirm(value) {
|
||||
this.confirmed -= value;
|
||||
};
|
||||
|
||||
Balance.prototype.addRaw = function addRaw(data) {
|
||||
var height = data.readUInt32LE(4, true);
|
||||
var value = utils.read64N(data, 8);
|
||||
|
||||
assert(data.length >= 16);
|
||||
|
||||
this.total += value;
|
||||
|
||||
if (height === 0x7fffffff)
|
||||
this.unconfirmed += value;
|
||||
else
|
||||
this.confirmed += value;
|
||||
};
|
||||
|
||||
Balance.prototype.toRaw = function toRaw(writer) {
|
||||
var p = new BufferWriter(writer);
|
||||
|
||||
@ -2348,8 +2357,6 @@ Balance.prototype.fromRaw = function fromRaw(data) {
|
||||
var p = new BufferReader(data);
|
||||
this.unconfirmed = p.readU53();
|
||||
this.confirmed = p.readU53();
|
||||
this.total += this.unconfirmed;
|
||||
this.total += this.confirmed;
|
||||
return this;
|
||||
};
|
||||
|
||||
@ -2363,8 +2370,7 @@ Balance.prototype.toJSON = function toJSON(minimal) {
|
||||
id: !minimal ? this.id : undefined,
|
||||
account: !minimal ? this.account : undefined,
|
||||
unconfirmed: utils.btc(this.unconfirmed),
|
||||
confirmed: utils.btc(this.confirmed),
|
||||
total: utils.btc(this.total)
|
||||
confirmed: utils.btc(this.confirmed)
|
||||
};
|
||||
};
|
||||
|
||||
@ -2372,7 +2378,6 @@ Balance.prototype.toString = function toString() {
|
||||
return '<Balance'
|
||||
+ ' unconfirmed=' + utils.btc(this.unconfirmed)
|
||||
+ ' confirmed=' + utils.btc(this.confirmed)
|
||||
+ ' total=' + utils.btc(this.total)
|
||||
+ '>';
|
||||
};
|
||||
|
||||
@ -2457,8 +2462,7 @@ TXDBState.prototype.toJSON = function toJSON(minimal) {
|
||||
tx: this.tx,
|
||||
coin: this.coin,
|
||||
unconfirmed: utils.btc(this.balance.unconfirmed),
|
||||
confirmed: utils.btc(this.balance.confirmed),
|
||||
total: utils.btc(this.balance.total)
|
||||
confirmed: utils.btc(this.balance.confirmed)
|
||||
};
|
||||
};
|
||||
|
||||
@ -2470,11 +2474,6 @@ TXDBState.prototype.inspect = function inspect() {
|
||||
* Helpers
|
||||
*/
|
||||
|
||||
function Conflict(tx, info) {
|
||||
this.tx = tx;
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
function Orphan(tx, i) {
|
||||
this.tx = tx;
|
||||
this.hash = tx.hash('hex');
|
||||
|
||||
@ -1435,7 +1435,7 @@ WalletDB.prototype._removeBlock = co(function* removeBlock(entry) {
|
||||
// Unwrite the tip as fast as we can.
|
||||
yield this.unwriteBlock(block);
|
||||
|
||||
for (i = 0; i < block.hashes.length; i++) {
|
||||
for (i = block.hashes.length - 1; i >= 0; i--) {
|
||||
hash = block.hashes[i];
|
||||
yield this._unconfirmTX(hash);
|
||||
}
|
||||
|
||||
@ -120,9 +120,8 @@ describe('Chain', function() {
|
||||
yield co.timeout(100);
|
||||
|
||||
balance = yield wallet.getBalance();
|
||||
assert.equal(balance.unconfirmed, 0);
|
||||
assert.equal(balance.unconfirmed, 500 * 1e8);
|
||||
assert.equal(balance.confirmed, 500 * 1e8);
|
||||
assert.equal(balance.total, 500 * 1e8);
|
||||
}));
|
||||
|
||||
it('should handle a reorg', cob(function* () {
|
||||
@ -158,9 +157,8 @@ describe('Chain', function() {
|
||||
yield co.timeout(100);
|
||||
|
||||
balance = yield wallet.getBalance();
|
||||
assert.equal(balance.unconfirmed, 500 * 1e8);
|
||||
assert.equal(balance.unconfirmed, 1050 * 1e8);
|
||||
assert.equal(balance.confirmed, 550 * 1e8);
|
||||
assert.equal(balance.total, 1050 * 1e8);
|
||||
}));
|
||||
|
||||
it('should check main chain', cob(function* () {
|
||||
@ -221,9 +219,8 @@ describe('Chain', function() {
|
||||
yield co.timeout(100);
|
||||
|
||||
balance = yield wallet.getBalance();
|
||||
assert.equal(balance.unconfirmed, 500 * 1e8);
|
||||
assert.equal(balance.unconfirmed, 1200 * 1e8);
|
||||
assert.equal(balance.confirmed, 700 * 1e8);
|
||||
assert.equal(balance.total, 1200 * 1e8);
|
||||
|
||||
assert(wallet.account.receiveDepth >= 8);
|
||||
assert(wallet.account.changeDepth >= 7);
|
||||
|
||||
@ -188,6 +188,7 @@ describe('Wallet', function() {
|
||||
.addOutput(w.getAddress(), 50000)
|
||||
.addOutput(w.getAddress(), 1000);
|
||||
t1.addInput(dummyInput);
|
||||
t1.height = 1;
|
||||
|
||||
// balance: 51000
|
||||
yield w.sign(t1);
|
||||
@ -245,30 +246,30 @@ describe('Wallet', function() {
|
||||
yield walletdb.addTX(t4);
|
||||
|
||||
balance = yield w.getBalance();
|
||||
//assert.equal(balance.total, 22500);
|
||||
assert.equal(balance.total, 0);
|
||||
//assert.equal(balance.unconfirmed, 22500);
|
||||
assert.equal(balance.unconfirmed, 0);
|
||||
|
||||
yield walletdb.addTX(t1);
|
||||
|
||||
balance = yield w.getBalance();
|
||||
//assert.equal(balance.total, 73000);
|
||||
assert.equal(balance.total, 51000);
|
||||
//assert.equal(balance.unconfirmed, 73000);
|
||||
assert.equal(balance.unconfirmed, 51000);
|
||||
|
||||
yield walletdb.addTX(t2);
|
||||
|
||||
balance = yield w.getBalance();
|
||||
//assert.equal(balance.total, 47000);
|
||||
assert.equal(balance.total, 49000);
|
||||
//assert.equal(balance.unconfirmed, 47000);
|
||||
assert.equal(balance.unconfirmed, 49000);
|
||||
|
||||
yield walletdb.addTX(t3);
|
||||
|
||||
balance = yield w.getBalance();
|
||||
assert.equal(balance.total, 22000);
|
||||
assert.equal(balance.unconfirmed, 22000);
|
||||
|
||||
yield walletdb.addTX(f1);
|
||||
|
||||
balance = yield w.getBalance();
|
||||
assert.equal(balance.total, 11000);
|
||||
assert.equal(balance.unconfirmed, 11000);
|
||||
|
||||
txs = yield w.getHistory();
|
||||
assert(txs.some(function(tx) {
|
||||
@ -276,12 +277,16 @@ describe('Wallet', function() {
|
||||
}));
|
||||
|
||||
balance = yield f.getBalance();
|
||||
assert.equal(balance.total, 10000);
|
||||
assert.equal(balance.unconfirmed, 10000);
|
||||
|
||||
txs = yield f.getHistory();
|
||||
assert(txs.some(function(tx) {
|
||||
return tx.hash('hex') === f1.hash('hex');
|
||||
}));
|
||||
|
||||
t2.ts = utils.now();
|
||||
t2.height = 1;
|
||||
yield walletdb.addTX(t2);
|
||||
}));
|
||||
|
||||
it('should cleanup spenders after double-spend', cob(function* () {
|
||||
@ -290,6 +295,8 @@ describe('Wallet', function() {
|
||||
|
||||
tx = bcoin.mtx().addOutput(w.getAddress(), 5000);
|
||||
tx.addInput(doubleSpend.coin);
|
||||
tx.ts = utils.now();
|
||||
tx.height = 1;
|
||||
|
||||
txs = yield w.getHistory();
|
||||
assert.equal(txs.length, 5);
|
||||
@ -303,12 +310,12 @@ describe('Wallet', function() {
|
||||
tx = tx.toTX();
|
||||
|
||||
balance = yield w.getBalance();
|
||||
assert.equal(balance.total, 11000);
|
||||
assert.equal(balance.unconfirmed, 11000);
|
||||
|
||||
yield walletdb.addTX(tx);
|
||||
|
||||
balance = yield w.getBalance();
|
||||
assert.equal(balance.total, 6000);
|
||||
assert.equal(balance.unconfirmed, 6000);
|
||||
|
||||
txs = yield w.getHistory();
|
||||
assert.equal(txs.length, 2);
|
||||
@ -415,7 +422,7 @@ describe('Wallet', function() {
|
||||
|
||||
assert(err);
|
||||
assert(balance);
|
||||
assert(balance.total === 5460);
|
||||
assert(balance.unconfirmed === 5460);
|
||||
}));
|
||||
|
||||
it('should sign multiple inputs using different keys', cob(function* () {
|
||||
@ -897,7 +904,7 @@ describe('Wallet', function() {
|
||||
it('should get account balance', cob(function* () {
|
||||
var w = wallet;
|
||||
var balance = yield w.getBalance('foo');
|
||||
assert.equal(balance.total, 21840);
|
||||
assert.equal(balance.unconfirmed, 21840);
|
||||
}));
|
||||
|
||||
it('should import privkey', cob(function* () {
|
||||
@ -1031,8 +1038,8 @@ describe('Wallet', function() {
|
||||
it('should recover from a missed tx', cob(function* () {
|
||||
var alice, addr, bob, t1, t2, t3;
|
||||
|
||||
// walletdb.options.verify = false;
|
||||
// walletdb.options.resolution = false;
|
||||
walletdb.options.verify = false;
|
||||
walletdb.options.resolution = false;
|
||||
|
||||
alice = yield walletdb.create({ master: KEY1 });
|
||||
bob = yield walletdb.create({ master: KEY1 });
|
||||
@ -1062,8 +1069,8 @@ describe('Wallet', function() {
|
||||
yield alice.add(t2);
|
||||
|
||||
assert.notEqual(
|
||||
(yield alice.getBalance()).total,
|
||||
(yield bob.getBalance()).total);
|
||||
(yield alice.getBalance()).unconfirmed,
|
||||
(yield bob.getBalance()).unconfirmed);
|
||||
|
||||
// Bob sees this one.
|
||||
t3 = bcoin.mtx()
|
||||
@ -1074,13 +1081,13 @@ describe('Wallet', function() {
|
||||
yield alice.sign(t3);
|
||||
t3 = t3.toTX();
|
||||
|
||||
assert.equal((yield bob.getBalance()).total, 50000);
|
||||
assert.equal((yield bob.getBalance()).unconfirmed, 50000);
|
||||
|
||||
yield alice.add(t3);
|
||||
yield bob.add(t3);
|
||||
|
||||
assert.equal((yield alice.getBalance()).total, 30000);
|
||||
// assert.equal((yield bob.getBalance()).total, 80000);
|
||||
assert.equal((yield alice.getBalance()).unconfirmed, 30000);
|
||||
// assert.equal((yield bob.getBalance()).unconfirmed, 80000);
|
||||
|
||||
// Bob sees t2 on the chain.
|
||||
t2.height = 3;
|
||||
@ -1092,14 +1099,14 @@ describe('Wallet', function() {
|
||||
t3.ts = utils.now();
|
||||
yield bob.add(t3);
|
||||
|
||||
assert.equal((yield bob.getBalance()).total, 30000);
|
||||
assert.equal((yield bob.getBalance()).unconfirmed, 30000);
|
||||
}));
|
||||
|
||||
it('should recover from a missed tx and double spend', cob(function* () {
|
||||
var alice, addr, bob, t1, t2, t3, t2a;
|
||||
|
||||
// walletdb.options.verify = false;
|
||||
// walletdb.options.resolution = false;
|
||||
walletdb.options.verify = false;
|
||||
walletdb.options.resolution = false;
|
||||
|
||||
alice = yield walletdb.create({ master: KEY1 });
|
||||
bob = yield walletdb.create({ master: KEY1 });
|
||||
@ -1129,8 +1136,8 @@ describe('Wallet', function() {
|
||||
yield alice.add(t2);
|
||||
|
||||
assert.notEqual(
|
||||
(yield alice.getBalance()).total,
|
||||
(yield bob.getBalance()).total);
|
||||
(yield alice.getBalance()).unconfirmed,
|
||||
(yield bob.getBalance()).unconfirmed);
|
||||
|
||||
// Bob doublespends.
|
||||
t2a = bcoin.mtx()
|
||||
@ -1152,13 +1159,13 @@ describe('Wallet', function() {
|
||||
yield alice.sign(t3);
|
||||
t3 = t3.toTX();
|
||||
|
||||
assert.equal((yield bob.getBalance()).total, 20000);
|
||||
assert.equal((yield bob.getBalance()).unconfirmed, 20000);
|
||||
|
||||
yield alice.add(t3);
|
||||
yield bob.add(t3);
|
||||
|
||||
assert.equal((yield alice.getBalance()).total, 30000);
|
||||
// assert.equal((yield bob.getBalance()).total, 80000);
|
||||
assert.equal((yield alice.getBalance()).unconfirmed, 30000);
|
||||
// assert.equal((yield bob.getBalance()).unconfirmed, 80000);
|
||||
|
||||
// Bob sees t2 on the chain.
|
||||
t2.height = 3;
|
||||
@ -1170,7 +1177,7 @@ describe('Wallet', function() {
|
||||
t3.ts = utils.now();
|
||||
yield bob.add(t3);
|
||||
|
||||
assert.equal((yield bob.getBalance()).total, 30000);
|
||||
assert.equal((yield bob.getBalance()).unconfirmed, 30000);
|
||||
}));
|
||||
|
||||
it('should cleanup', cob(function* () {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user