tx-pool: save spending TXs
This commit is contained in:
parent
cf2e0042ff
commit
2ee4c7cd3a
@ -53,13 +53,14 @@ TXPool.prototype.add = function add(tx, noWrite) {
|
||||
// Transaction was confirmed, update it in storage
|
||||
if (tx.ts !== 0 && this._all[hash].ts === 0) {
|
||||
this._all[hash].ts = tx.ts;
|
||||
this._storeTX(hash, tx);
|
||||
if (this._storage)
|
||||
this._storeTX(hash, tx);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
this._all[hash] = tx;
|
||||
|
||||
var own = this._wallet.own(tx);
|
||||
var own = this._wallet.ownOutput(tx);
|
||||
var update = false;
|
||||
|
||||
// Consume unspent money or add orphans
|
||||
@ -87,6 +88,10 @@ TXPool.prototype.add = function add(tx, noWrite) {
|
||||
if (!own) {
|
||||
if (updated)
|
||||
this.emit('update', this._lastTs);
|
||||
|
||||
// Save spending TXs without adding unspents
|
||||
if (this._storage && this._wallet.ownInput(tx))
|
||||
this._storeTX(hash, tx);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -130,8 +135,9 @@ TXPool.prototype._storeTX = function _storeTX(hash, tx) {
|
||||
TXPool.prototype.all = function all() {
|
||||
return Object.keys(this._all).map(function(key) {
|
||||
return this._all[key];
|
||||
}, this).filter(function(item) {
|
||||
return this._wallet.own(item.tx, item.index);
|
||||
}, this).filter(function(tx) {
|
||||
return this._wallet.ownOutput(tx) ||
|
||||
this._wallet.ownInput(tx);
|
||||
}, this);
|
||||
};
|
||||
|
||||
@ -139,7 +145,7 @@ TXPool.prototype.unspent = function unspent() {
|
||||
return Object.keys(this._unspent).map(function(key) {
|
||||
return this._unspent[key];
|
||||
}, this).filter(function(item) {
|
||||
return this._wallet.own(item.tx, item.index);
|
||||
return this._wallet.ownOutput(item.tx, item.index);
|
||||
}, this);
|
||||
};
|
||||
|
||||
|
||||
@ -163,7 +163,9 @@ TX.prototype.subscriptHash = function subscriptHash(index, s, type) {
|
||||
|
||||
TX.prototype.verify = function verify() {
|
||||
return this.inputs.every(function(input, i) {
|
||||
assert(input.out.tx);
|
||||
if (!input.out.tx)
|
||||
return false;
|
||||
|
||||
assert(input.out.tx.outputs.length > input.out.index);
|
||||
|
||||
var subscript = input.out.tx.getSubscript(input.out.index);
|
||||
|
||||
@ -142,7 +142,7 @@ Wallet.prototype.validateAddress = function validateAddress(addr) {
|
||||
};
|
||||
Wallet.validateAddress = Wallet.prototype.validateAddress;
|
||||
|
||||
Wallet.prototype.own = function own(tx, index) {
|
||||
Wallet.prototype.ownOutput = function ownOutput(tx, index) {
|
||||
var hash = this.getHash();
|
||||
var key = this.getPublicKey();
|
||||
var outputs = tx.outputs.filter(function(output, i) {
|
||||
@ -165,6 +165,32 @@ Wallet.prototype.own = function own(tx, index) {
|
||||
return outputs;
|
||||
};
|
||||
|
||||
Wallet.prototype.ownInput = function ownInput(tx, index) {
|
||||
var hash = this.getHash();
|
||||
var key = this.getPublicKey();
|
||||
|
||||
var inputs = tx.inputs.filter(function(input, i) {
|
||||
if (index !== undefined && index !== i)
|
||||
return false;
|
||||
|
||||
if (!input.out.tx)
|
||||
return false;
|
||||
|
||||
var s = input.out.tx.outputs[input.out.index].script;
|
||||
if (bcoin.script.isPubkeyhash(s, hash))
|
||||
return true;
|
||||
|
||||
if (bcoin.script.isMultisig(s, key))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}, this);
|
||||
if (inputs.length === 0)
|
||||
return false;
|
||||
|
||||
return inputs;
|
||||
};
|
||||
|
||||
Wallet.prototype.sign = function sign(tx, type) {
|
||||
if (!type)
|
||||
type = 'all';
|
||||
@ -172,7 +198,7 @@ Wallet.prototype.sign = function sign(tx, type) {
|
||||
|
||||
// Filter inputs that this wallet own
|
||||
var inputs = tx.inputs.filter(function(input) {
|
||||
return input.out.tx && this.own(input.out.tx);
|
||||
return input.out.tx && this.ownOutput(input.out.tx);
|
||||
}, this);
|
||||
var pub = this.getPublicKey();
|
||||
|
||||
|
||||
@ -31,8 +31,8 @@ describe('Wallet', function() {
|
||||
address: w.getAddress() + 'x'
|
||||
}]
|
||||
});
|
||||
assert(w.own(src));
|
||||
assert.equal(w.own(src).reduce(function(acc, out) {
|
||||
assert(w.ownOutput(src));
|
||||
assert.equal(w.ownOutput(src).reduce(function(acc, out) {
|
||||
return acc.iadd(out.value);
|
||||
}, new bn(0)).toString(10), 5460 * 2);
|
||||
|
||||
@ -58,8 +58,8 @@ describe('Wallet', function() {
|
||||
address: w.getAddress() + 'x'
|
||||
}]
|
||||
});
|
||||
assert(w.own(src));
|
||||
assert.equal(w.own(src).reduce(function(acc, out) {
|
||||
assert(w.ownOutput(src));
|
||||
assert.equal(w.ownOutput(src).reduce(function(acc, out) {
|
||||
return acc.iadd(out.value);
|
||||
}, new bn(0)).toString(10), 5460 * 2);
|
||||
|
||||
@ -75,6 +75,7 @@ describe('Wallet', function() {
|
||||
|
||||
it('should have TX pool and be serializable', function() {
|
||||
var w = bcoin.wallet();
|
||||
var f = bcoin.wallet();
|
||||
|
||||
// Coinbase
|
||||
var t1 = bcoin.tx().out(w, 50000).out(w, 1000);
|
||||
@ -86,13 +87,22 @@ describe('Wallet', function() {
|
||||
.out(w, 23000);
|
||||
var t4 = bcoin.tx().input(t2.hash(), 1)
|
||||
.input(t3.hash(), 0)
|
||||
.out(w, 22000);
|
||||
.out(w, 11000)
|
||||
.out(w, 11000);
|
||||
var f1 = bcoin.tx().input(t4.hash(), 1)
|
||||
.out(f, 10000);
|
||||
w.sign(t1);
|
||||
w.sign(t2);
|
||||
w.sign(t3);
|
||||
w.sign(t4);
|
||||
w.sign(f1);
|
||||
|
||||
// Just for debugging
|
||||
t1.hint = 't1';
|
||||
t2.hint = 't2';
|
||||
t3.hint = 't3';
|
||||
t4.hint = 't4';
|
||||
f1.hint = 'f1';
|
||||
|
||||
w.addTX(t4);
|
||||
assert.equal(w.balance().toString(10), '22000');
|
||||
@ -102,8 +112,16 @@ describe('Wallet', function() {
|
||||
assert.equal(w.balance().toString(10), '47000');
|
||||
w.addTX(t3);
|
||||
assert.equal(w.balance().toString(10), '22000');
|
||||
w.addTX(f1);
|
||||
assert.equal(w.balance().toString(10), '11000');
|
||||
assert(w.all().some(function(tx) {
|
||||
return tx.hash('hex') === f1.hash('hex');
|
||||
}));
|
||||
|
||||
var w2 = bcoin.wallet.fromJSON(w.toJSON());
|
||||
assert.equal(w2.balance().toString(10), '22000');
|
||||
assert.equal(w2.balance().toString(10), '11000');
|
||||
assert(w2.all().some(function(tx) {
|
||||
return tx.hash('hex') === f1.hash('hex');
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user