txdb: handle state and balance differently.

This commit is contained in:
Christopher Jeffrey 2016-10-17 22:09:29 -07:00
parent 06a104c34d
commit 2e56a82280
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
2 changed files with 57 additions and 118 deletions

View File

@ -551,18 +551,18 @@ Address.getHash = function getHash(data, enc) {
if (typeof data === 'string') {
if (data.length === 40 || data.length === 64)
return enc === 'hex' ? data : new Buffer(data, 'hex');
}
if (Buffer.isBuffer(data)) {
hash = data;
} else if (data instanceof Address) {
hash = data.hash;
} else {
try {
hash = Address.fromBase58(data).hash;
} catch (e) {
return;
}
} else if (Buffer.isBuffer(data)) {
hash = data;
} else if (data instanceof Address) {
hash = data.hash;
} else {
return;
}
return enc === 'hex'

View File

@ -217,7 +217,6 @@ function TXDB(wallet) {
this.locked = {};
this.state = null;
this.balance = null;
this.pending = null;
this.events = [];
@ -249,15 +248,13 @@ TXDB.prototype.open = co(function* open() {
this.logger.info('TXDB created for %s.', this.wallet.id);
}
this.balance = this.state.balance;
this.logger.info('TXDB State: tx=%d coin=%s.',
this.state.tx, this.state.coin);
this.logger.info(
'Balance: unconfirmed=%s confirmed=%s.',
utils.btc(this.balance.unconfirmed),
utils.btc(this.balance.confirmed));
utils.btc(this.state.unconfirmed),
utils.btc(this.state.confirmed));
});
/**
@ -312,7 +309,6 @@ TXDB.prototype.commit = co(function* commit() {
// with our new committed state.
if (this.pending.committed) {
this.state = this.pending;
this.balance = this.state.balance;
// Emit buffered events now that
// we know everything is written.
@ -478,7 +474,7 @@ TXDB.prototype.verifyInputs = co(function* verifyInputs(tx) {
var hash = tx.hash('hex');
var hasOrphans = false;
var orphans = [];
var i, input, prevout, address;
var i, input, prevout;
var path, key, coin, spent;
if (tx.isCoinbase())
@ -494,9 +490,6 @@ TXDB.prototype.verifyInputs = co(function* verifyInputs(tx) {
spent = yield this.isSpent(prevout.hash, prevout.index);
if (spent) {
if (tx.height === -1)
return false;
coin = yield this.getSpentCoin(spent, prevout);
assert(coin);
@ -523,8 +516,7 @@ TXDB.prototype.verifyInputs = co(function* verifyInputs(tx) {
continue;
}
address = input.getHash('hex');
path = yield this.wallet.hasPath(address);
path = yield this.wallet.hasPath(input.getAddress());
if (!path)
continue;
@ -761,16 +753,17 @@ TXDB.prototype._add = co(function* add(tx, info) {
this.put(layout.s(prevout.hash, prevout.index), spender);
this.pending.balance.unconfirmed -= coin.value;
this.pending.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.pending.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.pending.coin--;
}
this.put(layout.d(hash, i), coin.toRaw());
@ -791,13 +784,14 @@ TXDB.prototype._add = co(function* add(tx, info) {
coin = Coin.fromTX(tx, i);
raw = coin.toRaw();
this.pending.balance.unconfirmed += coin.value;
this.pending.unconfirmed += coin.value;
if (tx.height !== -1)
this.pending.balance.confirmed += coin.value;
this.pending.confirmed += coin.value;
this.put(layout.c(hash, i), raw);
this.put(layout.C(path.account, hash, i), DUMMY);
this.pending.coin++;
this.coinCache.set(key, raw);
}
@ -813,7 +807,7 @@ TXDB.prototype._add = co(function* add(tx, info) {
if (tx.height !== -1)
this.emit('confirmed', tx, info);
this.emit('balance', this.pending.balance, info);
this.emit('balance', this.pending.toBalance(), info);
return true;
});
@ -1017,7 +1011,7 @@ TXDB.prototype.confirm = co(function* confirm(tx, info) {
this.put(layout.d(hash, i), coin.toRaw());
this.put(layout.s(prevout.hash, prevout.index), spender);
this.pending.balance.unconfirmed -= coin.value;
this.pending.unconfirmed -= coin.value;
}
assert(coin.height !== -1);
@ -1032,7 +1026,8 @@ TXDB.prototype.confirm = co(function* confirm(tx, info) {
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.pending.coin--;
this.pending.confirmed -= coin.value;
this.spentCache.remove(key);
this.coinCache.remove(key);
@ -1058,7 +1053,8 @@ TXDB.prototype.confirm = co(function* confirm(tx, info) {
coin.height = tx.height;
raw = coin.toRaw();
this.pending.balance.confirmed += coin.value;
this.pending.confirmed += coin.value;
this.pending.coin++;
this.put(layout.c(hash, i), raw);
@ -1072,7 +1068,7 @@ TXDB.prototype.confirm = co(function* confirm(tx, info) {
this.emit('tx', tx, info);
this.emit('confirmed', tx, info);
this.emit('balance', this.pending.balance, info);
this.emit('balance', this.pending.toBalance(), info);
return true;
});
@ -1192,13 +1188,14 @@ TXDB.prototype.__remove = co(function* remove(tx, info) {
path = info.getPath(coin);
assert(path);
this.pending.balance.unconfirmed += coin.value;
this.pending.unconfirmed += coin.value;
this.del(layout.s(prevout.hash, prevout.index));
if (tx.height !== -1) {
raw = coin.toRaw();
this.pending.balance.confirmed += coin.value;
this.pending.confirmed += coin.value;
this.pending.coin++;
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);
@ -1221,10 +1218,11 @@ TXDB.prototype.__remove = co(function* remove(tx, info) {
coin = Coin.fromTX(tx, i);
this.pending.balance.unconfirmed -= coin.value;
this.pending.coin--;
this.pending.unconfirmed -= coin.value;
if (tx.height !== -1)
this.pending.balance.confirmed -= coin.value;
this.pending.confirmed -= coin.value;
this.del(layout.c(hash, i));
this.del(layout.C(path.account, hash, i));
@ -1236,7 +1234,7 @@ TXDB.prototype.__remove = co(function* remove(tx, info) {
this.put(layout.R, this.pending.commit());
this.emit('remove tx', tx, info);
this.emit('balance', this.pending.balance, info);
this.emit('balance', this.pending.toBalance(), info);
return info;
});
@ -1345,7 +1343,8 @@ TXDB.prototype.__unconfirm = co(function* unconfirm(tx, info) {
this.put(layout.c(prevout.hash, prevout.index), raw);
this.put(layout.C(path.account, prevout.hash, prevout.index), DUMMY);
this.pending.balance.confirmed += coin.value;
this.pending.coin++;
this.pending.confirmed += coin.value;
this.spentCache.set(key, spender);
this.coinCache.set(key, raw);
@ -1365,18 +1364,20 @@ TXDB.prototype.__unconfirm = co(function* unconfirm(tx, info) {
continue;
coin.height = -1;
raw = coin.toRaw();
this.pending.balance.confirmed -= coin.value;
this.pending.confirmed -= coin.value;
this.pending.coin++;
this.put(layout.c(hash, i), coin.toRaw());
this.put(layout.c(hash, i), raw);
this.coinCache.remove(key);
this.coinCache.set(key, raw);
}
this.put(layout.R, this.pending.commit());
this.emit('unconfirmed', tx, info);
this.emit('balance', this.pending.balance, info);
this.emit('balance', this.pending.toBalance(), info);
return info;
});
@ -2185,7 +2186,7 @@ TXDB.prototype.getBalance = co(function* getBalance(account) {
return yield this.getAccountBalance(account);
// Fast case
return this.balance;
return this.state.toBalance();
});
/**
@ -2248,8 +2249,7 @@ TXDB.prototype.zap = co(function* zap(account, age) {
var now = utils.now();
var i, txs, tx, hash;
if (!utils.isUInt32(age))
throw new Error('Age must be a number.');
assert(utils.isUInt32(age));
txs = yield this.getRange(account, {
start: 0,
@ -2304,66 +2304,12 @@ function Balance(wid, id, account) {
this.confirmed = 0;
}
Balance.prototype.clone = function clone() {
var balance = new Balance(this.wid, this.id, this.account);
balance.unconfirmed = this.unconfirmed;
balance.confirmed = this.confirmed;
return balance;
};
Balance.prototype.equal = function equal(balance) {
return this.wid === balance.wid
&& this.confirmed === balance.confirmed
&& this.unconfirmed === balance.unconfirmed;
};
Balance.prototype.add = function add(coin) {
if (coin.height === -1)
this.unconfirmed += coin.value;
else
this.confirmed += coin.value;
};
Balance.prototype.sub = function sub(coin) {
if (coin.height === -1)
this.unconfirmed -= coin.value;
else
this.confirmed -= coin.value;
};
Balance.prototype.confirm = function confirm(value) {
this.unconfirmed -= value;
this.confirmed += value;
};
Balance.prototype.unconfirm = function unconfirm(value) {
this.unconfirmed += value;
this.confirmed -= value;
};
Balance.prototype.toRaw = function toRaw(writer) {
var p = new BufferWriter(writer);
p.writeU64(this.unconfirmed);
p.writeU64(this.confirmed);
if (!writer)
p = p.render();
return p;
};
Balance.prototype.fromRaw = function fromRaw(data) {
var p = new BufferReader(data);
this.unconfirmed = p.readU53();
this.confirmed = p.readU53();
return this;
};
Balance.fromRaw = function fromRaw(wid, id, data) {
return new Balance(wid, id, -1).fromRaw(data);
};
Balance.prototype.toJSON = function toJSON(minimal) {
return {
wid: !minimal ? this.wid : undefined,
@ -2395,7 +2341,8 @@ function TXDBState(wid, id) {
this.id = id;
this.tx = 0;
this.coin = 0;
this.balance = new Balance(wid, id, -1);
this.unconfirmed = 0;
this.confirmed = 0;
this.committed = false;
}
@ -2403,7 +2350,8 @@ TXDBState.prototype.clone = function clone() {
var state = new TXDBState(this.wid, this.id);
state.tx = this.tx;
state.coin = this.coin;
state.balance = this.balance.clone();
state.unconfirmed = this.unconfirmed;
state.confirmed = this.confirmed;
return state;
};
@ -2412,12 +2360,20 @@ TXDBState.prototype.commit = function commit() {
return this.toRaw();
};
TXDBState.prototype.toBalance = function toBalance() {
var balance = new Balance(this.wid, this.id, -1);
balance.unconfirmed = this.unconfirmed;
balance.confirmed = this.confirmed;
return balance;
};
TXDBState.prototype.toRaw = function toRaw(writer) {
var p = new BufferWriter(writer);
p.writeU64(this.tx);
p.writeU64(this.coin);
this.balance.toRaw(p);
p.writeU64(this.unconfirmed);
p.writeU64(this.confirmed);
if (!writer)
p = p.render();
@ -2429,7 +2385,8 @@ TXDBState.prototype.fromRaw = function fromRaw(data) {
var p = new BufferReader(data);
this.tx = p.readU53();
this.coin = p.readU53();
this.balance.fromRaw(p);
this.unconfirmed = p.readU53();
this.confirmed = p.readU53();
return this;
};
@ -2437,32 +2394,14 @@ TXDBState.fromRaw = function fromRaw(wid, id, data) {
return new TXDBState(wid, id).fromRaw(data);
};
TXDBState.prototype.add = function add(coin) {
this.coin++;
return this.balance.add(coin);
};
TXDBState.prototype.sub = function sub(coin) {
this.coin--;
return this.balance.sub(coin);
};
TXDBState.prototype.confirm = function confirm(value) {
return this.balance.confirm(value);
};
TXDBState.prototype.unconfirm = function unconfirm(value) {
return this.balance.unconfirm(value);
};
TXDBState.prototype.toJSON = function toJSON(minimal) {
return {
wid: !minimal ? this.wid : undefined,
id: !minimal ? this.id : undefined,
tx: this.tx,
coin: this.coin,
unconfirmed: utils.btc(this.balance.unconfirmed),
confirmed: utils.btc(this.balance.confirmed)
unconfirmed: utils.btc(this.unconfirmed),
confirmed: utils.btc(this.confirmed)
};
};