add mutable tx.
This commit is contained in:
parent
ed90c9a4a2
commit
69038ac55e
@ -65,6 +65,7 @@ bcoin.input = require('./bcoin/input');
|
|||||||
bcoin.output = require('./bcoin/output');
|
bcoin.output = require('./bcoin/output');
|
||||||
bcoin.coin = require('./bcoin/coin');
|
bcoin.coin = require('./bcoin/coin');
|
||||||
bcoin.tx = require('./bcoin/tx');
|
bcoin.tx = require('./bcoin/tx');
|
||||||
|
bcoin.mtx = require('./bcoin/mtx');
|
||||||
bcoin.txpool = require('./bcoin/tx-pool');
|
bcoin.txpool = require('./bcoin/tx-pool');
|
||||||
bcoin.block = require('./bcoin/block');
|
bcoin.block = require('./bcoin/block');
|
||||||
bcoin.ramdisk = require('./bcoin/ramdisk');
|
bcoin.ramdisk = require('./bcoin/ramdisk');
|
||||||
|
|||||||
@ -41,7 +41,6 @@ function Block(data, subtype) {
|
|||||||
this._raw = data._raw || null;
|
this._raw = data._raw || null;
|
||||||
this._size = data._size || 0;
|
this._size = data._size || 0;
|
||||||
|
|
||||||
this.network = data.network || false;
|
|
||||||
this.relayedBy = data.relayedBy || '0.0.0.0';
|
this.relayedBy = data.relayedBy || '0.0.0.0';
|
||||||
|
|
||||||
this._chain = data.chain;
|
this._chain = data.chain;
|
||||||
@ -78,17 +77,11 @@ function Block(data, subtype) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.verify();
|
if (!this._raw)
|
||||||
|
this._raw = this.render();
|
||||||
|
|
||||||
if (this.subtype === 'block' && !this.valid) {
|
if (!this._size)
|
||||||
this.txs = this.txs.map(function(tx) {
|
this._size = this._raw.length;
|
||||||
tx.block = null;
|
|
||||||
if (tx.ts === self.ts)
|
|
||||||
tx.ts = 0;
|
|
||||||
tx.height = -1;
|
|
||||||
return tx;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Block.prototype.hash = function hash(enc) {
|
Block.prototype.hash = function hash(enc) {
|
||||||
@ -99,7 +92,7 @@ Block.prototype.hash = function hash(enc) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Block.prototype.abbr = function abbr() {
|
Block.prototype.abbr = function abbr() {
|
||||||
if (this.network && this._raw)
|
if (this._raw)
|
||||||
return this._raw.slice(0, 80);
|
return this._raw.slice(0, 80);
|
||||||
|
|
||||||
var res = new Buffer(80);
|
var res = new Buffer(80);
|
||||||
@ -125,7 +118,7 @@ Block.verify = function verify(data, subtype) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Block.prototype.render = function render() {
|
Block.prototype.render = function render() {
|
||||||
if (this.network && this._raw)
|
if (this._raw)
|
||||||
return this._raw;
|
return this._raw;
|
||||||
return bcoin.protocol.framer.block(this, this.subtype);
|
return bcoin.protocol.framer.block(this, this.subtype);
|
||||||
};
|
};
|
||||||
@ -459,7 +452,6 @@ Block.prototype.toJSON = function toJSON() {
|
|||||||
type: 'block',
|
type: 'block',
|
||||||
subtype: this.subtype,
|
subtype: this.subtype,
|
||||||
height: this.height,
|
height: this.height,
|
||||||
network: this.network,
|
|
||||||
relayedBy: this.relayedBy,
|
relayedBy: this.relayedBy,
|
||||||
hash: utils.revHex(this.hash('hex')),
|
hash: utils.revHex(this.hash('hex')),
|
||||||
version: this.version,
|
version: this.version,
|
||||||
@ -507,7 +499,6 @@ Block.prototype.toCompact = function toCompact() {
|
|||||||
prevBlock: this.prevBlock,
|
prevBlock: this.prevBlock,
|
||||||
ts: this.ts,
|
ts: this.ts,
|
||||||
height: this.height,
|
height: this.height,
|
||||||
network: this.network,
|
|
||||||
relayedBy: this.relayedBy,
|
relayedBy: this.relayedBy,
|
||||||
block: utils.toHex(this.render())
|
block: utils.toHex(this.render())
|
||||||
};
|
};
|
||||||
@ -530,7 +521,6 @@ Block._fromCompact = function _fromCompact(json) {
|
|||||||
data = parser.parseBlock(raw);
|
data = parser.parseBlock(raw);
|
||||||
|
|
||||||
data.height = json.height;
|
data.height = json.height;
|
||||||
data.network = json.network;
|
|
||||||
data.relayedBy = json.relayedBy;
|
data.relayedBy = json.relayedBy;
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
|
|||||||
@ -22,7 +22,7 @@ function Input(options) {
|
|||||||
|
|
||||||
assert(typeof options.script !== 'string');
|
assert(typeof options.script !== 'string');
|
||||||
|
|
||||||
prevout = options.prevout || options.out;
|
prevout = options.prevout;
|
||||||
|
|
||||||
this.prevout = {
|
this.prevout = {
|
||||||
hash: prevout.hash,
|
hash: prevout.hash,
|
||||||
|
|||||||
1200
lib/bcoin/mtx.js
Normal file
1200
lib/bcoin/mtx.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -67,6 +67,9 @@ TXPool.prototype.add = function add(tx, noWrite) {
|
|||||||
if (!this._wallet.ownInput(tx) && !this._wallet.ownOutput(tx))
|
if (!this._wallet.ownInput(tx) && !this._wallet.ownOutput(tx))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (tx instanceof bcoin.tx)
|
||||||
|
tx = bcoin.mtx.fromTX(tx);
|
||||||
|
|
||||||
// Ignore stale pending transactions
|
// Ignore stale pending transactions
|
||||||
if (tx.ts === 0 && tx.ps + 2 * 24 * 3600 < utils.now()) {
|
if (tx.ts === 0 && tx.ps + 2 * 24 * 3600 < utils.now()) {
|
||||||
this._removeTX(tx, noWrite);
|
this._removeTX(tx, noWrite);
|
||||||
@ -77,7 +80,6 @@ TXPool.prototype.add = function add(tx, noWrite) {
|
|||||||
if (this._all[hash]) {
|
if (this._all[hash]) {
|
||||||
// Transaction was confirmed, update it in storage
|
// Transaction was confirmed, update it in storage
|
||||||
if (tx.ts !== 0 && this._all[hash].ts === 0) {
|
if (tx.ts !== 0 && this._all[hash].ts === 0) {
|
||||||
this._all[hash].ps = 0;
|
|
||||||
this._all[hash].ts = tx.ts;
|
this._all[hash].ts = tx.ts;
|
||||||
this._all[hash].block = tx.block;
|
this._all[hash].block = tx.block;
|
||||||
this._all[hash].height = tx.height;
|
this._all[hash].height = tx.height;
|
||||||
|
|||||||
1056
lib/bcoin/tx.js
1056
lib/bcoin/tx.js
File diff suppressed because it is too large
Load Diff
@ -23,7 +23,7 @@ describe('Wallet', function() {
|
|||||||
var w = bcoin.wallet();
|
var w = bcoin.wallet();
|
||||||
|
|
||||||
// Input transcation
|
// Input transcation
|
||||||
var src = bcoin.tx({
|
var src = bcoin.mtx({
|
||||||
outputs: [{
|
outputs: [{
|
||||||
value: 5460 * 2,
|
value: 5460 * 2,
|
||||||
address: w.getAddress()
|
address: w.getAddress()
|
||||||
@ -37,9 +37,9 @@ describe('Wallet', function() {
|
|||||||
return acc.iadd(out.value);
|
return acc.iadd(out.value);
|
||||||
}, new bn(0)).toString(10), 5460 * 2);
|
}, new bn(0)).toString(10), 5460 * 2);
|
||||||
|
|
||||||
var tx = bcoin.tx()
|
var tx = bcoin.mtx()
|
||||||
.input(src, 0)
|
.addInput(src, 0)
|
||||||
.out(w.getAddress(), 5460);
|
.addOutput(w.getAddress(), 5460);
|
||||||
|
|
||||||
w.sign(tx);
|
w.sign(tx);
|
||||||
assert(tx.verify());
|
assert(tx.verify());
|
||||||
@ -56,7 +56,7 @@ describe('Wallet', function() {
|
|||||||
w.addKey(k2);
|
w.addKey(k2);
|
||||||
|
|
||||||
// Input transcation
|
// Input transcation
|
||||||
var src = bcoin.tx({
|
var src = bcoin.mtx({
|
||||||
outputs: [{
|
outputs: [{
|
||||||
value: 5460 * 2,
|
value: 5460 * 2,
|
||||||
m: 1,
|
m: 1,
|
||||||
@ -71,9 +71,9 @@ describe('Wallet', function() {
|
|||||||
return acc.iadd(out.value);
|
return acc.iadd(out.value);
|
||||||
}, new bn(0)).toString(10), 5460 * 2);
|
}, new bn(0)).toString(10), 5460 * 2);
|
||||||
|
|
||||||
var tx = bcoin.tx()
|
var tx = bcoin.mtx()
|
||||||
.input(src, 0)
|
.addInput(src, 0)
|
||||||
.out(w.getAddress(), 5460);
|
.addOutput(w.getAddress(), 5460);
|
||||||
|
|
||||||
var maxSize = tx.maxSize();
|
var maxSize = tx.maxSize();
|
||||||
w.sign(tx);
|
w.sign(tx);
|
||||||
@ -86,31 +86,31 @@ describe('Wallet', function() {
|
|||||||
var f = bcoin.wallet();
|
var f = bcoin.wallet();
|
||||||
|
|
||||||
// Coinbase
|
// Coinbase
|
||||||
var t1 = bcoin.tx().out(w, 50000).out(w, 1000);
|
var t1 = bcoin.mtx().addOutput(w, 50000).addOutput(w, 1000);
|
||||||
// balance: 51000
|
// balance: 51000
|
||||||
w.sign(t1);
|
w.sign(t1);
|
||||||
var t2 = bcoin.tx().input(t1, 0) // 50000
|
var t2 = bcoin.mtx().addInput(t1, 0) // 50000
|
||||||
.out(w, 24000)
|
.addOutput(w, 24000)
|
||||||
.out(w, 24000);
|
.addOutput(w, 24000);
|
||||||
// balance: 49000
|
// balance: 49000
|
||||||
w.sign(t2);
|
w.sign(t2);
|
||||||
var t3 = bcoin.tx().input(t1, 1) // 1000
|
var t3 = bcoin.mtx().addInput(t1, 1) // 1000
|
||||||
.input(t2, 0) // 24000
|
.addInput(t2, 0) // 24000
|
||||||
.out(w, 23000);
|
.addOutput(w, 23000);
|
||||||
// balance: 47000
|
// balance: 47000
|
||||||
w.sign(t3);
|
w.sign(t3);
|
||||||
var t4 = bcoin.tx().input(t2, 1) // 24000
|
var t4 = bcoin.mtx().addInput(t2, 1) // 24000
|
||||||
.input(t3, 0) // 23000
|
.addInput(t3, 0) // 23000
|
||||||
.out(w, 11000)
|
.addOutput(w, 11000)
|
||||||
.out(w, 11000);
|
.addOutput(w, 11000);
|
||||||
// balance: 22000
|
// balance: 22000
|
||||||
w.sign(t4);
|
w.sign(t4);
|
||||||
var f1 = bcoin.tx().input(t4, 1) // 11000
|
var f1 = bcoin.mtx().addInput(t4, 1) // 11000
|
||||||
.out(f, 10000);
|
.addOutput(f, 10000);
|
||||||
// balance: 11000
|
// balance: 11000
|
||||||
w.sign(f1);
|
w.sign(f1);
|
||||||
var fake = bcoin.tx().input(t1, 1) // 1000 (already redeemed)
|
var fake = bcoin.mtx().addInput(t1, 1) // 1000 (already redeemed)
|
||||||
.out(w, 500);
|
.addOutput(w, 500);
|
||||||
// Script inputs but do not sign
|
// Script inputs but do not sign
|
||||||
w.scriptInputs(fake);
|
w.scriptInputs(fake);
|
||||||
// Fake signature
|
// Fake signature
|
||||||
@ -154,25 +154,25 @@ describe('Wallet', function() {
|
|||||||
var w2 = bcoin.wallet();
|
var w2 = bcoin.wallet();
|
||||||
|
|
||||||
// Coinbase
|
// Coinbase
|
||||||
var t1 = bcoin.tx().out(w1, 5460).out(w1, 5460).out(w1, 5460).out(w1, 5460);
|
var t1 = bcoin.mtx().addOutput(w1, 5460).addOutput(w1, 5460).addOutput(w1, 5460).addOutput(w1, 5460);
|
||||||
|
|
||||||
// Fake TX should temporarly change output
|
// Fake TX should temporarly change output
|
||||||
w1.addTX(t1);
|
w1.addTX(t1);
|
||||||
|
|
||||||
// Create new transaction
|
// Create new transaction
|
||||||
var t2 = bcoin.tx().out(w2, 5460);
|
var t2 = bcoin.mtx().addOutput(w2, 5460);
|
||||||
assert(w1.fill(t2));
|
assert(w1.fill(t2));
|
||||||
w1.sign(t2);
|
w1.sign(t2);
|
||||||
assert(t2.verify());
|
assert(t2.verify());
|
||||||
|
|
||||||
assert.equal(t2.funds('in').toString(10), 16380);
|
assert.equal(t2.getInputValue().toString(10), 16380);
|
||||||
// If change < dust and is added to outputs:
|
// If change < dust and is added to outputs:
|
||||||
// assert.equal(t2.funds('out').toString(10), 6380);
|
// assert.equal(t2.getOutputValue().toString(10), 6380);
|
||||||
// If change < dust and is added to fee:
|
// If change < dust and is added to fee:
|
||||||
assert.equal(t2.funds('out').toString(10), 5460);
|
assert.equal(t2.getOutputValue().toString(10), 5460);
|
||||||
|
|
||||||
// Create new transaction
|
// Create new transaction
|
||||||
var t3 = bcoin.tx().out(w2, 15000);
|
var t3 = bcoin.mtx().addOutput(w2, 15000);
|
||||||
try {
|
try {
|
||||||
w1.fill(t3);
|
w1.fill(t3);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -190,33 +190,33 @@ describe('Wallet', function() {
|
|||||||
var to = bcoin.wallet();
|
var to = bcoin.wallet();
|
||||||
|
|
||||||
// Coinbase
|
// Coinbase
|
||||||
var t1 = bcoin.tx().out(w1, 5460).out(w1, 5460).out(w1, 5460).out(w1, 5460);
|
var t1 = bcoin.mtx().addOutput(w1, 5460).addOutput(w1, 5460).addOutput(w1, 5460).addOutput(w1, 5460);
|
||||||
// Fake TX should temporarly change output
|
// Fake TX should temporarly change output
|
||||||
w1.addTX(t1);
|
w1.addTX(t1);
|
||||||
// Coinbase
|
// Coinbase
|
||||||
var t2 = bcoin.tx().out(w2, 5460).out(w2, 5460).out(w2, 5460).out(w2, 5460);
|
var t2 = bcoin.mtx().addOutput(w2, 5460).addOutput(w2, 5460).addOutput(w2, 5460).addOutput(w2, 5460);
|
||||||
// Fake TX should temporarly change output
|
// Fake TX should temporarly change output
|
||||||
w2.addTX(t2);
|
w2.addTX(t2);
|
||||||
|
|
||||||
// Create our tx with an output
|
// Create our tx with an output
|
||||||
var tx = bcoin.tx();
|
var tx = bcoin.mtx();
|
||||||
tx.out(to, 5460);
|
tx.addOutput(to, 5460);
|
||||||
|
|
||||||
var cost = tx.funds('out');
|
var cost = tx.getOutputValue();
|
||||||
var total = cost.add(new bn(constants.tx.minFee));
|
var total = cost.add(new bn(constants.tx.minFee));
|
||||||
|
|
||||||
var unspent1 = w1.unspent();
|
var unspent1 = w1.unspent();
|
||||||
var unspent2 = w2.unspent();
|
var unspent2 = w2.unspent();
|
||||||
|
|
||||||
// Add dummy output (for `left`) to calculate maximum TX size
|
// Add dummy output (for `left`) to calculate maximum TX size
|
||||||
tx.out(w1, new bn(0));
|
tx.addOutput(w1, new bn(0));
|
||||||
|
|
||||||
// Add our unspent inputs to sign
|
// Add our unspent inputs to sign
|
||||||
tx.input(unspent1[0]);
|
tx.addInput(unspent1[0]);
|
||||||
tx.input(unspent1[1]);
|
tx.addInput(unspent1[1]);
|
||||||
tx.input(unspent2[0]);
|
tx.addInput(unspent2[0]);
|
||||||
|
|
||||||
var left = tx.funds('in').sub(total);
|
var left = tx.getInputValue().sub(total);
|
||||||
if (left.cmpn(constants.tx.dustThreshold) < 0) {
|
if (left.cmpn(constants.tx.dustThreshold) < 0) {
|
||||||
tx.outputs[tx.outputs.length - 2].value.iadd(left);
|
tx.outputs[tx.outputs.length - 2].value.iadd(left);
|
||||||
left = new bn(0);
|
left = new bn(0);
|
||||||
@ -235,9 +235,9 @@ describe('Wallet', function() {
|
|||||||
|
|
||||||
// Sign transaction using `inputs` and `off` params.
|
// Sign transaction using `inputs` and `off` params.
|
||||||
tx.inputs.length = 0;
|
tx.inputs.length = 0;
|
||||||
tx.input(unspent1[1]);
|
tx.addInput(unspent1[1]);
|
||||||
tx.input(unspent1[2]);
|
tx.addInput(unspent1[2]);
|
||||||
tx.input(unspent2[1]);
|
tx.addInput(unspent2[1]);
|
||||||
assert.equal(w1.sign(tx, 'all'), 2);
|
assert.equal(w1.sign(tx, 'all'), 2);
|
||||||
assert.equal(w2.sign(tx, 'all'), 1);
|
assert.equal(w2.sign(tx, 'all'), 1);
|
||||||
|
|
||||||
@ -288,8 +288,8 @@ describe('Wallet', function() {
|
|||||||
assert.equal(w3.getAddress(), addr);
|
assert.equal(w3.getAddress(), addr);
|
||||||
|
|
||||||
// Add a shared unspent transaction to our wallets
|
// Add a shared unspent transaction to our wallets
|
||||||
var utx = bcoin.tx();
|
var utx = bcoin.mtx();
|
||||||
utx.output({ address: addr, value: 5460 * 10 });
|
utx.addOutput({ address: addr, value: 5460 * 10 });
|
||||||
|
|
||||||
// Simulate a confirmation
|
// Simulate a confirmation
|
||||||
utx.ps = 0;
|
utx.ps = 0;
|
||||||
@ -312,8 +312,8 @@ describe('Wallet', function() {
|
|||||||
assert.equal(w3.getAddress(), addr);
|
assert.equal(w3.getAddress(), addr);
|
||||||
|
|
||||||
// Create a tx requiring 2 signatures
|
// Create a tx requiring 2 signatures
|
||||||
var send = bcoin.tx();
|
var send = bcoin.mtx();
|
||||||
send.output({ address: receive.getAddress(), value: 5460 });
|
send.addOutput({ address: receive.getAddress(), value: 5460 });
|
||||||
assert(!send.verify());
|
assert(!send.verify());
|
||||||
var result = w1.fill(send, { m: w1.m, n: w1.n });
|
var result = w1.fill(send, { m: w1.m, n: w1.n });
|
||||||
assert(result);
|
assert(result);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user