txdb: handle state and balance differently.
This commit is contained in:
parent
06a104c34d
commit
2e56a82280
@ -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'
|
||||
|
||||
@ -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)
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user