wallet: store timestamp of transactions
This commit is contained in:
parent
292da0625e
commit
048bca0b8a
@ -20,9 +20,6 @@ function Chain(options) {
|
||||
this.block = {
|
||||
list: [],
|
||||
|
||||
// Bloom filter for all merkle trees
|
||||
merkleBloom: new bcoin.bloom(8 * 1024 * 1024, 16, 0xdeadbeed),
|
||||
|
||||
// Bloom filter for all known blocks
|
||||
bloom: new bcoin.bloom(8 * 1024 * 1024, 16, 0xdeadbeef)
|
||||
};
|
||||
@ -215,7 +212,6 @@ Chain.prototype._compress = function compress() {
|
||||
// Bloom filter rebuilt is needed
|
||||
this.block.list = this.block.list.slice(-1000);
|
||||
this.block.bloom.reset();
|
||||
this.block.merkleBloom.reset();
|
||||
|
||||
for (var i = 0; i < this.block.list.length; i++)
|
||||
this._bloomBlock(this.block.list[i]);
|
||||
@ -223,8 +219,6 @@ Chain.prototype._compress = function compress() {
|
||||
|
||||
Chain.prototype._bloomBlock = function _bloomBlock(block) {
|
||||
this.block.bloom.add(block.hash(), 'hex');
|
||||
for (var i = 0; i < block.hashes.length; i++)
|
||||
this.block.merkleBloom.add(block.hashes[i], 'hex');
|
||||
};
|
||||
|
||||
Chain.prototype.has = function has(hash, noProbe, cb) {
|
||||
@ -258,20 +252,6 @@ Chain.prototype.has = function has(hash, noProbe, cb) {
|
||||
return cb(!!this.orphan.map[hash]);
|
||||
};
|
||||
|
||||
Chain.prototype.hasMerkle = function hasMerkle(hash) {
|
||||
if (!this.block.merkleBloom.test(hash, 'hex'))
|
||||
return false;
|
||||
if (!this.strict)
|
||||
return true;
|
||||
|
||||
hash = utils.toHex(hash);
|
||||
for (var i = 0; i < this.block.list.length; i++)
|
||||
if (this.block.list[i].hasMerkle(hash))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
Chain.prototype.get = function get(hash, cb) {
|
||||
// Cached block found
|
||||
if (this.block.bloom.test(hash, 'hex')) {
|
||||
|
||||
@ -250,15 +250,16 @@ Peer.prototype._onPacket = function onPacket(packet) {
|
||||
else if (cmd === 'pong')
|
||||
return this._handlePong(payload);
|
||||
|
||||
if (cmd === 'merkleblock' || cmd === 'block')
|
||||
if (cmd === 'merkleblock' || cmd === 'block') {
|
||||
payload = bcoin.block(payload);
|
||||
else if (cmd === 'tx')
|
||||
payload = bcoin.tx(payload);
|
||||
if (this._res(cmd, payload)) {
|
||||
return;
|
||||
} else {
|
||||
this.emit(cmd, payload);
|
||||
this.lastBlock = payload;
|
||||
} else if (cmd === 'tx') {
|
||||
payload = bcoin.tx(payload, this.lastBlock);
|
||||
}
|
||||
if (this._res(cmd, payload))
|
||||
return;
|
||||
else
|
||||
this.emit(cmd, payload);
|
||||
};
|
||||
|
||||
Peer.prototype._handleVersion = function handleVersion(payload) {
|
||||
|
||||
@ -12,10 +12,11 @@ function TXPool(wallet) {
|
||||
|
||||
this._wallet = wallet;
|
||||
this._storage = wallet.storage;
|
||||
this._prefix = 'bt/' + wallet.getAddress() + '/tx/';
|
||||
this._prefix = wallet.prefix + 'tx/';
|
||||
this._all = {};
|
||||
this._unspent = {};
|
||||
this._orphans = {};
|
||||
this._lastTs = 0;
|
||||
|
||||
// Load TXs from storage
|
||||
this._init();
|
||||
@ -39,6 +40,9 @@ TXPool.prototype._init = function init() {
|
||||
s.on('error', function(err) {
|
||||
self.emit('error', err);
|
||||
});
|
||||
s.on('end', function() {
|
||||
self.emit('load', self._lastTs);
|
||||
});
|
||||
};
|
||||
|
||||
TXPool.prototype.add = function add(tx, noWrite) {
|
||||
@ -76,6 +80,8 @@ TXPool.prototype.add = function add(tx, noWrite) {
|
||||
if (!own)
|
||||
return;
|
||||
|
||||
var updated = false;
|
||||
|
||||
// Add unspent outputs or fullfill orphans
|
||||
for (var i = 0; i < tx.outputs.length; i++) {
|
||||
var out = tx.outputs[i];
|
||||
@ -84,7 +90,7 @@ TXPool.prototype.add = function add(tx, noWrite) {
|
||||
var orphan = this._orphans[key];
|
||||
if (!orphan) {
|
||||
this._unspent[key] = { tx: tx, index: i };
|
||||
this.emit('update');
|
||||
updated = true;
|
||||
continue;
|
||||
}
|
||||
delete this._orphans[key];
|
||||
@ -93,6 +99,10 @@ TXPool.prototype.add = function add(tx, noWrite) {
|
||||
orphan.tx.input(tx, orphan.index);
|
||||
}
|
||||
|
||||
this._lastTs = Math.max(tx.ts, this._lastTs);
|
||||
if (updated)
|
||||
this.emit('update', this._lastTs);
|
||||
|
||||
if (!noWrite && this._storage) {
|
||||
var self = this;
|
||||
this._storage.put(this._prefix + hash, tx.toJSON(), function(err) {
|
||||
|
||||
@ -4,9 +4,9 @@ var bn = require('bn.js');
|
||||
var bcoin = require('../bcoin');
|
||||
var utils = bcoin.utils;
|
||||
|
||||
function TX(data) {
|
||||
function TX(data, block) {
|
||||
if (!(this instanceof TX))
|
||||
return new TX(data);
|
||||
return new TX(data, block);
|
||||
this.type = 'tx';
|
||||
|
||||
if (!data)
|
||||
@ -16,6 +16,7 @@ function TX(data) {
|
||||
this.inputs = [];
|
||||
this.outputs = [];
|
||||
this.lock = data.lock || 0;
|
||||
this.ts = data.ts || 0;
|
||||
|
||||
this._hash = null;
|
||||
this._raw = data._raw || null;
|
||||
@ -30,6 +31,9 @@ function TX(data) {
|
||||
this.out(out, null);
|
||||
}, this);
|
||||
}
|
||||
|
||||
if (!data.ts && block && block.hasMerkle(this.hash('hex')))
|
||||
this.ts = block.ts;
|
||||
}
|
||||
module.exports = TX;
|
||||
|
||||
@ -174,10 +178,19 @@ TX.prototype.verify = function verify() {
|
||||
|
||||
TX.prototype.toJSON = function toJSON() {
|
||||
// Compact representation
|
||||
return utils.toBase58(this.render());
|
||||
var ts = new Array(4);
|
||||
bcoin.utils.writeU32(ts, this.ts, 0);
|
||||
return utils.toBase58(this.render().concat(ts));
|
||||
};
|
||||
|
||||
TX.fromJSON = function fromJSON(json) {
|
||||
// Compact representation
|
||||
return new TX(new bcoin.protocol.parser().parseTX(utils.fromBase58(json)));
|
||||
var data = utils.fromBase58(json);
|
||||
var tx = data.slice(0, -4);
|
||||
var ts = bcoin.utils.readU32(data, data.length - 4);
|
||||
|
||||
tx = new TX(new bcoin.protocol.parser().parseTX(tx));
|
||||
tx.ts = ts;
|
||||
|
||||
return tx;
|
||||
};
|
||||
|
||||
@ -37,6 +37,7 @@ function Wallet(options, passphrase) {
|
||||
this.key = bcoin.ecdsa.genKeyPair();
|
||||
}
|
||||
|
||||
this.prefix = 'bt/' + this.getAddress() + '/';
|
||||
this.tx = new bcoin.txPool(this);
|
||||
this._init();
|
||||
}
|
||||
@ -47,13 +48,17 @@ Wallet.prototype._init = function init() {
|
||||
// Notify owners about new accepted transactions
|
||||
var self = this;
|
||||
var prevBalance = null;
|
||||
this.tx.on('update', function(tx) {
|
||||
this.tx.on('update', function() {
|
||||
var b = this.balance();
|
||||
if (prevBalance && prevBalance.cmp(b) !== 0)
|
||||
self.emit('balance', b);
|
||||
prevBalance = b;
|
||||
});
|
||||
|
||||
this.tx.once('load', function(ts) {
|
||||
self.emit('load', ts);
|
||||
});
|
||||
|
||||
this.tx.on('error', function(err) {
|
||||
self.emit('error', err);
|
||||
});
|
||||
@ -186,7 +191,7 @@ Wallet.prototype.sign = function sign(tx, type) {
|
||||
return inputs.length;
|
||||
};
|
||||
|
||||
Wallet.prototype.addTX = function addTX(tx) {
|
||||
Wallet.prototype.addTX = function addTX(tx, block) {
|
||||
return this.tx.add(tx);
|
||||
};
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user