txdb: cleanup.

This commit is contained in:
Christopher Jeffrey 2016-10-17 18:05:38 -07:00
parent 4232cdc6b9
commit 06a104c34d
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
4 changed files with 182 additions and 179 deletions

View File

@ -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');

View File

@ -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);
}

View File

@ -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);

View File

@ -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* () {