mtx: less overloading.
This commit is contained in:
parent
8987c0d870
commit
95c205b309
@ -415,8 +415,8 @@ cb.addOutput({
|
||||
// Create our redeeming transaction.
|
||||
var mtx = new bcoin.mtx();
|
||||
|
||||
// Add output 0 from our coinbase.
|
||||
mtx.addInput(cb, 0);
|
||||
// Add output 0 from our coinbase as an input.
|
||||
mtx.addTX(cb, 0);
|
||||
|
||||
// Send 10,000 satoshis to ourself,
|
||||
// creating a fee of 40,000 satoshis.
|
||||
|
||||
@ -5,16 +5,12 @@ var co = require('../lib/utils/co');
|
||||
var crypto = require('../lib/crypto/crypto');
|
||||
var WalletDB = require('../lib/wallet/walletdb');
|
||||
var MTX = require('../lib/primitives/mtx');
|
||||
var Outpoint = require('../lib/primitives/outpoint');
|
||||
var walletdb, runBench;
|
||||
|
||||
function dummy() {
|
||||
var hash = crypto.randomBytes(32).toString('hex');
|
||||
return {
|
||||
prevout: {
|
||||
hash: hash,
|
||||
index: 0
|
||||
}
|
||||
};
|
||||
return new Outpoint(hash, 0);
|
||||
}
|
||||
|
||||
walletdb = new WalletDB({
|
||||
@ -62,13 +58,13 @@ runBench = co(function* runBench() {
|
||||
// TX deposit
|
||||
jobs = [];
|
||||
for (i = 0; i < 10000; i++) {
|
||||
tx = new MTX()
|
||||
.addInput(dummy())
|
||||
.addOutput(addrs[(i + 0) % addrs.length], 50460)
|
||||
.addOutput(addrs[(i + 1) % addrs.length], 50460)
|
||||
.addOutput(addrs[(i + 2) % addrs.length], 50460)
|
||||
.addOutput(addrs[(i + 3) % addrs.length], 50460)
|
||||
.toTX();
|
||||
tx = new MTX();
|
||||
tx.addOutpoint(dummy());
|
||||
tx.addOutput(addrs[(i + 0) % addrs.length], 50460);
|
||||
tx.addOutput(addrs[(i + 1) % addrs.length], 50460);
|
||||
tx.addOutput(addrs[(i + 2) % addrs.length], 50460);
|
||||
tx.addOutput(addrs[(i + 3) % addrs.length], 50460);
|
||||
tx = tx.toTX();
|
||||
|
||||
jobs.push(walletdb.addTX(tx));
|
||||
}
|
||||
@ -80,16 +76,16 @@ runBench = co(function* runBench() {
|
||||
// TX redemption
|
||||
jobs = [];
|
||||
for (i = 0; i < 10000; i++) {
|
||||
tx = new MTX()
|
||||
.addInput(tx, 0)
|
||||
.addInput(tx, 1)
|
||||
.addInput(tx, 2)
|
||||
.addInput(tx, 3)
|
||||
.addOutput(addrs[(i + 0) % addrs.length], 50460)
|
||||
.addOutput(addrs[(i + 1) % addrs.length], 50460)
|
||||
.addOutput(addrs[(i + 2) % addrs.length], 50460)
|
||||
.addOutput(addrs[(i + 3) % addrs.length], 50460)
|
||||
.toTX();
|
||||
tx = new MTX();
|
||||
tx.addTX(tx, 0);
|
||||
tx.addTX(tx, 1);
|
||||
tx.addTX(tx, 2);
|
||||
tx.addTX(tx, 3);
|
||||
tx.addOutput(addrs[(i + 0) % addrs.length], 50460);
|
||||
tx.addOutput(addrs[(i + 1) % addrs.length], 50460);
|
||||
tx.addOutput(addrs[(i + 2) % addrs.length], 50460);
|
||||
tx.addOutput(addrs[(i + 3) % addrs.length], 50460);
|
||||
tx = tx.toTX();
|
||||
|
||||
jobs.push(walletdb.addTX(tx));
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ function Coin(options) {
|
||||
this.height = -1;
|
||||
this.value = 0;
|
||||
this.script = new Script();
|
||||
this.coinbase = true;
|
||||
this.coinbase = false;
|
||||
this.hash = encoding.NULL_HASH;
|
||||
this.index = 0;
|
||||
|
||||
|
||||
@ -125,18 +125,34 @@ MTX.prototype.clone = function clone() {
|
||||
};
|
||||
|
||||
/**
|
||||
* Add an outpoint as an input.
|
||||
* @param {Outpoint} outpoint
|
||||
* Add an input to the transaction.
|
||||
* @example
|
||||
* tx.addInput({ prevout: { hash: ... }, script: ... });
|
||||
* tx.addInput(new Input());
|
||||
* @param {Input|Object} options
|
||||
*/
|
||||
|
||||
MTX.prototype.addOutpoint = function addOutpoint(outpoint) {
|
||||
var input = Input.fromOutpoint(outpoint);
|
||||
MTX.prototype.addInput = function addInput(options) {
|
||||
var input = Input.fromOptions(options);
|
||||
this.inputs.push(input);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a coin as an input.
|
||||
* Add an outpoint as an input.
|
||||
* @param {Outpoint|Object} outpoint
|
||||
*/
|
||||
|
||||
MTX.prototype.addOutpoint = function addOutpoint(outpoint) {
|
||||
var prevout = Outpoint.fromOptions(outpoint);
|
||||
var input = Input.fromOutpoint(prevout);
|
||||
this.inputs.push(input);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a coin as an input. Note that this will
|
||||
* add the coin to the internal coin viewpoint.
|
||||
* @param {Coin} coin
|
||||
*/
|
||||
|
||||
@ -148,14 +164,15 @@ MTX.prototype.addCoin = function addCoin(coin) {
|
||||
input = Input.fromCoin(coin);
|
||||
|
||||
this.inputs.push(input);
|
||||
|
||||
this.view.addCoin(coin);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a transaction as an input.
|
||||
* Add a transaction as an input. Note that
|
||||
* this will add the coin to the internal
|
||||
* coin viewpoint.
|
||||
* @param {TX} tx
|
||||
* @param {Number} index
|
||||
* @param {Number?} height
|
||||
@ -170,51 +187,10 @@ MTX.prototype.addTX = function addTX(tx, index, height) {
|
||||
height = -1;
|
||||
|
||||
input = Input.fromTX(tx, index);
|
||||
|
||||
this.inputs.push(input);
|
||||
|
||||
coin = Coin.fromTX(tx, index, height);
|
||||
|
||||
this.view.addCoin(coin);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add an input to the transaction.
|
||||
* @example
|
||||
* tx.addInput({ prevout: { hash: ... }, script: ... });
|
||||
* tx.addInput(tx, index);
|
||||
* tx.addInput(new Outpoint(hash, index));
|
||||
* tx.addInput(Coin.fromTX(prev, prevIndex, -1));
|
||||
* @param {TX|Coin|Outpoint|Input|Object} coin
|
||||
* @param {Number?} index - Input of output if `coin` is a TX.
|
||||
* @param {Number?} height - Coin height if `coin` is a TX.
|
||||
*/
|
||||
|
||||
MTX.prototype.addInput = function addInput(coin, index, height) {
|
||||
var input = new Input();
|
||||
|
||||
if (coin instanceof TX) {
|
||||
input.fromTX(coin, index);
|
||||
coin = Coin.fromTX(coin, index, height || -1);
|
||||
}
|
||||
|
||||
if (coin instanceof Coin) {
|
||||
input.fromCoin(coin);
|
||||
this.view.addCoin(coin);
|
||||
this.inputs.push(input);
|
||||
return this;
|
||||
}
|
||||
|
||||
if (coin instanceof Outpoint) {
|
||||
input.prevout.fromOptions(coin);
|
||||
this.inputs.push(input);
|
||||
return this;
|
||||
}
|
||||
|
||||
input.fromOptions(coin);
|
||||
this.inputs.push(input);
|
||||
this.view.addCoin(coin);
|
||||
|
||||
return this;
|
||||
};
|
||||
@ -223,21 +199,14 @@ MTX.prototype.addInput = function addInput(coin, index, height) {
|
||||
* Add an output.
|
||||
* @example
|
||||
* tx.addOutput({ address: ..., value: 100000 });
|
||||
* tx.addOutput({ address: ..., value: Amount.value('0.1') });
|
||||
* tx.addOutput(address, Amount.value('0.1'));
|
||||
* @param {KeyRing|Base58Address|Address|Script|Output|Object} options
|
||||
* @param {Address|Script|Output|Object} options
|
||||
* @param {Amount?} value - Only needs to be present for non-output options.
|
||||
*/
|
||||
|
||||
MTX.prototype.addOutput = function addOutput(options, value) {
|
||||
var output;
|
||||
|
||||
if (options instanceof KeyRing)
|
||||
options = options.getAddress();
|
||||
|
||||
if (typeof options === 'string')
|
||||
options = Address.fromBase58(options);
|
||||
|
||||
if (options instanceof Address)
|
||||
options = Script.fromAddress(options);
|
||||
|
||||
@ -245,13 +214,12 @@ MTX.prototype.addOutput = function addOutput(options, value) {
|
||||
output.mutable = true;
|
||||
|
||||
if (options instanceof Script) {
|
||||
assert(util.isNumber(value));
|
||||
assert(value >= 0);
|
||||
assert(util.isUInt53(value), 'Value must be a uint53.');
|
||||
output.script.fromOptions(options);
|
||||
output.value = value;
|
||||
} else {
|
||||
output.fromOptions(options);
|
||||
assert(output.value >= 0);
|
||||
assert(util.isUInt53(output.value), 'Value must be a uint53.');
|
||||
}
|
||||
|
||||
this.outputs.push(output);
|
||||
@ -1223,7 +1191,7 @@ MTX.prototype.fund = co(function* fund(coins, options) {
|
||||
|
||||
// Add coins to transaction.
|
||||
for (i = 0; i < select.chosen.length; i++)
|
||||
this.addInput(select.chosen[i]);
|
||||
this.addCoin(select.chosen[i]);
|
||||
|
||||
// Attempt to subtract fee.
|
||||
if (select.shouldSubtract)
|
||||
@ -1717,7 +1685,7 @@ CoinSelector.prototype.fund = function fund() {
|
||||
if (!this.isSpendable(coin))
|
||||
continue;
|
||||
|
||||
this.tx.addInput(coin);
|
||||
this.tx.addCoin(coin);
|
||||
this.chosen.push(coin);
|
||||
|
||||
if (this.selection === 'all')
|
||||
|
||||
@ -27,30 +27,23 @@ describe('Chain', function() {
|
||||
|
||||
mineBlock = co(function* mineBlock(tip, tx) {
|
||||
var attempt = yield miner.createBlock(tip);
|
||||
var redeemer;
|
||||
var rtx;
|
||||
|
||||
if (!tx)
|
||||
return yield attempt.mineAsync();
|
||||
|
||||
redeemer = new MTX();
|
||||
rtx = new MTX();
|
||||
|
||||
redeemer.addOutput({
|
||||
address: wallet.getReceive(),
|
||||
value: 25 * 1e8
|
||||
});
|
||||
rtx.addTX(tx, 0);
|
||||
|
||||
redeemer.addOutput({
|
||||
address: wallet.getChange(),
|
||||
value: 5 * 1e8
|
||||
});
|
||||
rtx.addOutput(wallet.getReceive(), 25 * 1e8);
|
||||
rtx.addOutput(wallet.getChange(), 5 * 1e8);
|
||||
|
||||
redeemer.addInput(tx, 0);
|
||||
rtx.setLocktime(chain.height);
|
||||
|
||||
redeemer.setLocktime(chain.height);
|
||||
yield wallet.sign(rtx);
|
||||
|
||||
yield wallet.sign(redeemer);
|
||||
|
||||
attempt.addTX(redeemer.toTX(), redeemer.view);
|
||||
attempt.addTX(rtx.toTX(), rtx.view);
|
||||
|
||||
return yield attempt.mineAsync();
|
||||
});
|
||||
@ -326,7 +319,7 @@ describe('Chain', function() {
|
||||
value: 10 * 1e8
|
||||
});
|
||||
|
||||
redeemer.addInput(tx, 0);
|
||||
redeemer.addTX(tx, 0);
|
||||
|
||||
redeemer.setLocktime(chain.height);
|
||||
|
||||
@ -356,7 +349,7 @@ describe('Chain', function() {
|
||||
value: 10 * 1e8
|
||||
});
|
||||
|
||||
redeemer.addInput(csv, 0);
|
||||
redeemer.addTX(csv, 0);
|
||||
redeemer.setSequence(0, 1, false);
|
||||
|
||||
attempt = yield miner.createBlock();
|
||||
@ -382,7 +375,7 @@ describe('Chain', function() {
|
||||
value: 10 * 1e8
|
||||
});
|
||||
|
||||
redeemer.addInput(csv, 0);
|
||||
redeemer.addTX(csv, 0);
|
||||
redeemer.setSequence(0, 1, false);
|
||||
|
||||
attempt = yield miner.createBlock();
|
||||
@ -426,7 +419,7 @@ describe('Chain', function() {
|
||||
value: 10 * 1e8
|
||||
});
|
||||
|
||||
redeemer.addInput(csv, 0);
|
||||
redeemer.addTX(csv, 0);
|
||||
redeemer.setSequence(0, 2, false);
|
||||
|
||||
attempt = yield miner.createBlock();
|
||||
|
||||
@ -5,6 +5,7 @@ var consensus = require('../lib/protocol/consensus');
|
||||
var encoding = require('../lib/utils/encoding');
|
||||
var co = require('../lib/utils/co');
|
||||
var Amount = require('../lib/btc/amount');
|
||||
var Address = require('../lib/primitives/address');
|
||||
var MTX = require('../lib/primitives/mtx');
|
||||
var HTTP = require('../lib/http');
|
||||
var FullNode = require('../lib/node/fullnode');
|
||||
@ -61,17 +62,18 @@ describe('HTTP', function() {
|
||||
assert.equal(info.id, 'test');
|
||||
addr = info.account.receiveAddress;
|
||||
assert.equal(typeof addr, 'string');
|
||||
addr = Address.fromBase58(addr);
|
||||
}));
|
||||
|
||||
it('should fill with funds', cob(function* () {
|
||||
var tx, balance, receive, details;
|
||||
|
||||
// Coinbase
|
||||
tx = MTX()
|
||||
.addOutput(addr, 50460)
|
||||
.addOutput(addr, 50460)
|
||||
.addOutput(addr, 50460)
|
||||
.addOutput(addr, 50460);
|
||||
tx = new MTX();
|
||||
tx.addOutput(addr, 50460);
|
||||
tx.addOutput(addr, 50460);
|
||||
tx.addOutput(addr, 50460);
|
||||
tx.addOutput(addr, 50460);
|
||||
|
||||
tx.addInput(dummyInput);
|
||||
tx = tx.toTX();
|
||||
@ -116,7 +118,7 @@ describe('HTTP', function() {
|
||||
rate: 10000,
|
||||
outputs: [{
|
||||
value: 10000,
|
||||
address: addr
|
||||
address: addr.toBase58()
|
||||
}]
|
||||
};
|
||||
|
||||
|
||||
@ -41,31 +41,27 @@ describe('Mempool', function() {
|
||||
});
|
||||
|
||||
function dummy(prev, prevHash) {
|
||||
var funding = new MTX();
|
||||
var coin, entry;
|
||||
var fund, coin, entry;
|
||||
|
||||
if (!prevHash)
|
||||
prevHash = encoding.ONE_HASH.toString('hex');
|
||||
|
||||
coin = new Coin({
|
||||
version: 1,
|
||||
height: 0,
|
||||
value: 0,
|
||||
script: prev,
|
||||
coinbase: false,
|
||||
hash: prevHash,
|
||||
index: 0
|
||||
});
|
||||
coin = new Coin();
|
||||
coin.height = 0;
|
||||
coin.value = 0;
|
||||
coin.script = prev;
|
||||
coin.hash = prevHash;
|
||||
coin.index = 0;
|
||||
|
||||
funding.addInput(coin);
|
||||
fund = new MTX();
|
||||
fund.addCoin(coin);
|
||||
fund.addOutput(prev, 70000);
|
||||
|
||||
funding.addOutput({ value: 70000, script: prev });
|
||||
entry = MempoolEntry.fromTX(fund.toTX(), fund.view, 0);
|
||||
|
||||
entry = MempoolEntry.fromTX(funding.toTX(), funding.view, 0);
|
||||
mempool.trackEntry(entry, fund.view);
|
||||
|
||||
mempool.trackEntry(entry, funding.view);
|
||||
|
||||
return Coin.fromTX(funding, 0, -1);
|
||||
return Coin.fromTX(fund, 0, -1);
|
||||
}
|
||||
|
||||
it('should open mempool', cob(function* () {
|
||||
@ -86,58 +82,58 @@ describe('Mempool', function() {
|
||||
var w = wallet;
|
||||
var t1, t2, t3, t4, f1, fake, prev, sig, balance, txs;
|
||||
|
||||
t1 = new MTX()
|
||||
.addOutput(w.getAddress(), 50000)
|
||||
.addOutput(w.getAddress(), 10000);
|
||||
t1 = new MTX();
|
||||
t1.addOutput(w.getAddress(), 50000);
|
||||
t1.addOutput(w.getAddress(), 10000);
|
||||
|
||||
prev = new Script([kp.publicKey, opcodes.OP_CHECKSIG]);
|
||||
t1.addInput(dummy(prev));
|
||||
sig = t1.signature(0, prev, 70000, kp.privateKey, 'all', 0);
|
||||
t1.addCoin(dummy(prev));
|
||||
sig = t1.signature(0, prev, 70000, kp.privateKey, Script.hashType.ALL, 0);
|
||||
t1.inputs[0].script = new Script([sig]);
|
||||
|
||||
// balance: 51000
|
||||
yield w.sign(t1);
|
||||
t1 = t1.toTX();
|
||||
|
||||
t2 = new MTX()
|
||||
.addInput(t1, 0) // 50000
|
||||
.addOutput(w.getAddress(), 20000)
|
||||
.addOutput(w.getAddress(), 20000);
|
||||
t2 = new MTX();
|
||||
t2.addTX(t1, 0); // 50000
|
||||
t2.addOutput(w.getAddress(), 20000);
|
||||
t2.addOutput(w.getAddress(), 20000);
|
||||
|
||||
// balance: 49000
|
||||
yield w.sign(t2);
|
||||
t2 = t2.toTX();
|
||||
|
||||
t3 = new MTX()
|
||||
.addInput(t1, 1) // 10000
|
||||
.addInput(t2, 0) // 20000
|
||||
.addOutput(w.getAddress(), 23000);
|
||||
t3 = new MTX();
|
||||
t3.addTX(t1, 1); // 10000
|
||||
t3.addTX(t2, 0); // 20000
|
||||
t3.addOutput(w.getAddress(), 23000);
|
||||
|
||||
// balance: 47000
|
||||
yield w.sign(t3);
|
||||
t3 = t3.toTX();
|
||||
|
||||
t4 = new MTX()
|
||||
.addInput(t2, 1) // 24000
|
||||
.addInput(t3, 0) // 23000
|
||||
.addOutput(w.getAddress(), 11000)
|
||||
.addOutput(w.getAddress(), 11000);
|
||||
t4 = new MTX();
|
||||
t4.addTX(t2, 1); // 24000
|
||||
t4.addTX(t3, 0); // 23000
|
||||
t4.addOutput(w.getAddress(), 11000);
|
||||
t4.addOutput(w.getAddress(), 11000);
|
||||
|
||||
// balance: 22000
|
||||
yield w.sign(t4);
|
||||
t4 = t4.toTX();
|
||||
|
||||
f1 = new MTX()
|
||||
.addInput(t4, 1) // 11000
|
||||
.addOutput(new Address(), 9000);
|
||||
f1 = new MTX();
|
||||
f1.addTX(t4, 1); // 11000
|
||||
f1.addOutput(new Address(), 9000);
|
||||
|
||||
// balance: 11000
|
||||
yield w.sign(f1);
|
||||
f1 = f1.toTX();
|
||||
|
||||
fake = new MTX()
|
||||
.addInput(t1, 1) // 1000 (already redeemed)
|
||||
.addOutput(w.getAddress(), 6000); // 6000 instead of 500
|
||||
fake = new MTX();
|
||||
fake.addTX(t1, 1); // 1000 (already redeemed)
|
||||
fake.addOutput(w.getAddress(), 6000); // 6000 instead of 500
|
||||
|
||||
// Script inputs but do not sign
|
||||
yield w.template(fake);
|
||||
@ -185,19 +181,19 @@ describe('Mempool', function() {
|
||||
var kp = KeyRing.generate();
|
||||
var tx, prev, prevHash, sig;
|
||||
|
||||
tx = new MTX()
|
||||
.addOutput(w.getAddress(), 50000)
|
||||
.addOutput(w.getAddress(), 10000);
|
||||
tx = new MTX();
|
||||
tx.addOutput(w.getAddress(), 50000);
|
||||
tx.addOutput(w.getAddress(), 10000);
|
||||
|
||||
prev = new Script([kp.publicKey, opcodes.OP_CHECKSIG]);
|
||||
prevHash = crypto.randomBytes(32).toString('hex');
|
||||
|
||||
tx.addInput(dummy(prev, prevHash));
|
||||
tx.addCoin(dummy(prev, prevHash));
|
||||
tx.setLocktime(200);
|
||||
|
||||
chain.tip.height = 200;
|
||||
|
||||
sig = tx.signature(0, prev, 70000, kp.privateKey, 'all', 0);
|
||||
sig = tx.signature(0, prev, 70000, kp.privateKey, Script.hashType.ALL, 0);
|
||||
tx.inputs[0].script = new Script([sig]),
|
||||
|
||||
tx = tx.toTX();
|
||||
@ -211,18 +207,18 @@ describe('Mempool', function() {
|
||||
var kp = KeyRing.generate();
|
||||
var tx, prev, prevHash, sig, err;
|
||||
|
||||
tx = new MTX()
|
||||
.addOutput(w.getAddress(), 50000)
|
||||
.addOutput(w.getAddress(), 10000);
|
||||
tx = new MTX();
|
||||
tx.addOutput(w.getAddress(), 50000);
|
||||
tx.addOutput(w.getAddress(), 10000);
|
||||
|
||||
prev = new Script([kp.publicKey, opcodes.OP_CHECKSIG]);
|
||||
prevHash = crypto.randomBytes(32).toString('hex');
|
||||
|
||||
tx.addInput(dummy(prev, prevHash));
|
||||
tx.addCoin(dummy(prev, prevHash));
|
||||
tx.setLocktime(200);
|
||||
chain.tip.height = 200 - 1;
|
||||
|
||||
sig = tx.signature(0, prev, 70000, kp.privateKey, 'all', 0);
|
||||
sig = tx.signature(0, prev, 70000, kp.privateKey, Script.hashType.ALL, 0);
|
||||
tx.inputs[0].script = new Script([sig]),
|
||||
tx = tx.toTX();
|
||||
|
||||
@ -244,18 +240,18 @@ describe('Mempool', function() {
|
||||
|
||||
kp.witness = true;
|
||||
|
||||
tx = new MTX()
|
||||
.addOutput(w.getAddress(), 50000)
|
||||
.addOutput(w.getAddress(), 10000);
|
||||
tx = new MTX();
|
||||
tx.addOutput(w.getAddress(), 50000);
|
||||
tx.addOutput(w.getAddress(), 10000);
|
||||
|
||||
prev = new Script([0, kp.getKeyHash()]);
|
||||
prevHash = crypto.randomBytes(32).toString('hex');
|
||||
|
||||
tx.addInput(dummy(prev, prevHash));
|
||||
tx.addCoin(dummy(prev, prevHash));
|
||||
|
||||
prevs = Script.fromPubkeyhash(kp.getKeyHash());
|
||||
|
||||
sig = tx.signature(0, prevs, 70000, kp.privateKey, 'all', 1);
|
||||
sig = tx.signature(0, prevs, 70000, kp.privateKey, Script.hashType.ALL, 1);
|
||||
sig[sig.length - 1] = 0;
|
||||
|
||||
tx.inputs[0].witness = new Witness([sig, kp.publicKey]);
|
||||
@ -276,16 +272,16 @@ describe('Mempool', function() {
|
||||
var kp = KeyRing.generate();
|
||||
var tx, prev, prevHash, sig, err;
|
||||
|
||||
tx = new MTX()
|
||||
.addOutput(w.getAddress(), 50000)
|
||||
.addOutput(w.getAddress(), 10000);
|
||||
tx = new MTX();
|
||||
tx.addOutput(w.getAddress(), 50000);
|
||||
tx.addOutput(w.getAddress(), 10000);
|
||||
|
||||
prev = new Script([kp.publicKey, opcodes.OP_CHECKSIG]);
|
||||
prevHash = crypto.randomBytes(32).toString('hex');
|
||||
|
||||
tx.addInput(dummy(prev, prevHash));
|
||||
tx.addCoin(dummy(prev, prevHash));
|
||||
|
||||
sig = tx.signature(0, prev, 70000, kp.privateKey, 'all', 0);
|
||||
sig = tx.signature(0, prev, 70000, kp.privateKey, Script.hashType.ALL, 0);
|
||||
tx.inputs[0].script = new Script([sig]);
|
||||
tx.inputs[0].witness.push(new Buffer(0));
|
||||
tx = tx.toTX();
|
||||
@ -307,14 +303,14 @@ describe('Mempool', function() {
|
||||
|
||||
kp.witness = true;
|
||||
|
||||
tx = new MTX()
|
||||
.addOutput(w.getAddress(), 50000)
|
||||
.addOutput(w.getAddress(), 10000);
|
||||
tx = new MTX();
|
||||
tx.addOutput(w.getAddress(), 50000);
|
||||
tx.addOutput(w.getAddress(), 10000);
|
||||
|
||||
prev = new Script([0, kp.getKeyHash()]);
|
||||
prevHash = crypto.randomBytes(32).toString('hex');
|
||||
|
||||
tx.addInput(dummy(prev, prevHash));
|
||||
tx.addCoin(dummy(prev, prevHash));
|
||||
|
||||
tx = tx.toTX();
|
||||
|
||||
@ -334,14 +330,14 @@ describe('Mempool', function() {
|
||||
var kp = KeyRing.generate();
|
||||
var tx, prev, prevHash, err;
|
||||
|
||||
tx = new MTX()
|
||||
.addOutput(w.getAddress(), 50000)
|
||||
.addOutput(w.getAddress(), 10000);
|
||||
tx = new MTX();
|
||||
tx.addOutput(w.getAddress(), 50000);
|
||||
tx.addOutput(w.getAddress(), 10000);
|
||||
|
||||
prev = new Script([kp.publicKey, opcodes.OP_CHECKSIG]);
|
||||
prevHash = crypto.randomBytes(32).toString('hex');
|
||||
|
||||
tx.addInput(dummy(prev, prevHash));
|
||||
tx.addCoin(dummy(prev, prevHash));
|
||||
|
||||
tx = tx.toTX();
|
||||
|
||||
@ -359,9 +355,10 @@ describe('Mempool', function() {
|
||||
|
||||
it('should clear reject cache', cob(function* () {
|
||||
var w = wallet;
|
||||
var tx, input, block;
|
||||
var tx, input;
|
||||
|
||||
tx = new MTX().addOutput(w.getAddress(), 50000);
|
||||
tx = new MTX();
|
||||
tx.addOutput(w.getAddress(), 50000);
|
||||
|
||||
input = {
|
||||
prevout: {
|
||||
@ -374,11 +371,8 @@ describe('Mempool', function() {
|
||||
|
||||
tx = tx.toTX();
|
||||
|
||||
block = new Block();
|
||||
block.txs.push(tx);
|
||||
|
||||
assert(mempool.hasReject(cached.hash()));
|
||||
yield mempool.addBlock({ height: 1 }, block.txs);
|
||||
yield mempool.addBlock({ height: 1 }, [tx]);
|
||||
assert(!mempool.hasReject(cached.hash()));
|
||||
}));
|
||||
|
||||
|
||||
@ -12,6 +12,8 @@ var MTX = require('../lib/primitives/mtx');
|
||||
var Coin = require('../lib/primitives/coin');
|
||||
var KeyRing = require('../lib/primitives/keyring');
|
||||
var Address = require('../lib/primitives/address');
|
||||
var Input = require('../lib/primitives/input');
|
||||
var Outpoint = require('../lib/primitives/outpoint');
|
||||
var Script = require('../lib/script/script');
|
||||
var HD = require('../lib/hd');
|
||||
var scriptTypes = Script.types;
|
||||
@ -50,18 +52,13 @@ function dummy(hash) {
|
||||
if (!hash)
|
||||
hash = crypto.randomBytes(32).toString('hex');
|
||||
|
||||
return {
|
||||
prevout: {
|
||||
hash: hash,
|
||||
index: 0
|
||||
}
|
||||
};
|
||||
return Input.fromOutpoint(new Outpoint(hash, 0));
|
||||
}
|
||||
|
||||
describe('Wallet', function() {
|
||||
var walletdb, wallet, ewallet, ekey;
|
||||
var doubleSpendWallet, doubleSpend;
|
||||
var p2pkh, multisig;
|
||||
var testP2PKH, testMultisig;
|
||||
|
||||
walletdb = new WalletDB({
|
||||
name: 'wallet-test',
|
||||
@ -107,13 +104,10 @@ describe('Wallet', function() {
|
||||
w2.account.accountKey.toBase58());
|
||||
}));
|
||||
|
||||
p2pkh = co(function* p2pkh(witness, bullshitNesting) {
|
||||
testP2PKH = co(function* testP2PKH(witness, bullshitNesting) {
|
||||
var flags = Script.flags.STANDARD_VERIFY_FLAGS;
|
||||
var w, addr, src, tx;
|
||||
|
||||
if (witness)
|
||||
flags |= Script.flags.VERIFY_WITNESS;
|
||||
|
||||
w = yield walletdb.create({ witness: witness });
|
||||
|
||||
addr = Address.fromBase58(w.getAddress('base58'));
|
||||
@ -123,23 +117,15 @@ describe('Wallet', function() {
|
||||
else
|
||||
assert.equal(addr.type, scriptTypes.PUBKEYHASH);
|
||||
|
||||
src = new MTX({
|
||||
outputs: [{
|
||||
value: 5460 * 2,
|
||||
address: bullshitNesting
|
||||
? w.getNested()
|
||||
: w.getAddress()
|
||||
}, {
|
||||
value: 5460 * 2,
|
||||
address: new Address()
|
||||
}]
|
||||
});
|
||||
|
||||
src = new MTX();
|
||||
src.addInput(dummy());
|
||||
src.addOutput(bullshitNesting ? w.getNested() : w.getAddress(), 5460 * 2);
|
||||
src.addOutput(new Address(), 2 * 5460);
|
||||
src = src.toTX();
|
||||
|
||||
tx = new MTX()
|
||||
.addInput(src, 0)
|
||||
.addOutput(w.getAddress(), 5460);
|
||||
tx = new MTX();
|
||||
tx.addTX(src, 0);
|
||||
tx.addOutput(w.getAddress(), 5460);
|
||||
|
||||
yield w.sign(tx);
|
||||
|
||||
@ -147,19 +133,19 @@ describe('Wallet', function() {
|
||||
});
|
||||
|
||||
it('should sign/verify pubkeyhash tx', cob(function* () {
|
||||
yield p2pkh(false, false);
|
||||
yield testP2PKH(false, false);
|
||||
}));
|
||||
|
||||
it('should sign/verify witnesspubkeyhash tx', cob(function* () {
|
||||
yield p2pkh(true, false);
|
||||
yield testP2PKH(true, false);
|
||||
}));
|
||||
|
||||
it('should sign/verify witnesspubkeyhash tx with bullshit nesting', cob(function* () {
|
||||
yield p2pkh(true, true);
|
||||
yield testP2PKH(true, true);
|
||||
}));
|
||||
|
||||
it('should multisign/verify TX', cob(function* () {
|
||||
var w, k, keys, src, tx, maxSize;
|
||||
var w, k, script, src, tx, maxSize;
|
||||
|
||||
w = yield walletdb.create({
|
||||
type: 'multisig',
|
||||
@ -171,27 +157,21 @@ describe('Wallet', function() {
|
||||
|
||||
yield w.addSharedKey(k);
|
||||
|
||||
keys = [
|
||||
script = Script.fromMultisig(1, 2, [
|
||||
w.account.receive.getPublicKey(),
|
||||
k.derive('m/0/0').publicKey
|
||||
];
|
||||
]);
|
||||
|
||||
// Input transaction (bare 1-of-2 multisig)
|
||||
src = new MTX({
|
||||
outputs: [{
|
||||
value: 5460 * 2,
|
||||
script: Script.fromMultisig(1, 2, keys)
|
||||
}, {
|
||||
value: 5460 * 2,
|
||||
address: new Address()
|
||||
}]
|
||||
});
|
||||
|
||||
src = new MTX();
|
||||
src.addInput(dummy());
|
||||
src.addOutput(script, 5460 * 2);
|
||||
src.addOutput(new Address(), 5460 * 2);
|
||||
src = src.toTX();
|
||||
|
||||
tx = new MTX()
|
||||
.addInput(src, 0)
|
||||
.addOutput(w.getAddress(), 5460);
|
||||
tx = new MTX();
|
||||
tx.addTX(src, 0)
|
||||
tx.addOutput(w.getAddress(), 5460);
|
||||
|
||||
maxSize = yield tx.estimateSize();
|
||||
|
||||
@ -206,57 +186,54 @@ describe('Wallet', function() {
|
||||
var f = yield walletdb.create();
|
||||
var t1, t2, t3, t4, f1, fake, balance, txs;
|
||||
|
||||
doubleSpendWallet = w;
|
||||
|
||||
// Coinbase
|
||||
t1 = new MTX()
|
||||
.addOutput(w.getAddress(), 50000)
|
||||
.addOutput(w.getAddress(), 1000);
|
||||
t1.addInput(dummy());
|
||||
t1.ts = util.now();
|
||||
|
||||
// balance: 51000
|
||||
// yield w.sign(t1);
|
||||
t1 = new MTX();
|
||||
t1.addInput(dummy());
|
||||
t1.addOutput(w.getAddress(), 50000);
|
||||
t1.addOutput(w.getAddress(), 1000);
|
||||
t1 = t1.toTX();
|
||||
|
||||
t2 = new MTX()
|
||||
.addInput(t1, 0) // 50000
|
||||
.addOutput(w.getAddress(), 24000)
|
||||
.addOutput(w.getAddress(), 24000);
|
||||
t2 = new MTX();
|
||||
t2.addTX(t1, 0); // 50000
|
||||
t2.addOutput(w.getAddress(), 24000);
|
||||
t2.addOutput(w.getAddress(), 24000);
|
||||
|
||||
// Save for later.
|
||||
doubleSpendWallet = w;
|
||||
doubleSpend = Coin.fromTX(t1, 0, -1);
|
||||
|
||||
// balance: 49000
|
||||
yield w.sign(t2);
|
||||
t2 = t2.toTX();
|
||||
t3 = new MTX()
|
||||
.addInput(t1, 1) // 1000
|
||||
.addInput(t2, 0) // 24000
|
||||
.addOutput(w.getAddress(), 23000);
|
||||
t3 = new MTX();
|
||||
t3.addTX(t1, 1); // 1000
|
||||
t3.addTX(t2, 0); // 24000
|
||||
t3.addOutput(w.getAddress(), 23000);
|
||||
|
||||
// balance: 47000
|
||||
yield w.sign(t3);
|
||||
t3 = t3.toTX();
|
||||
t4 = new MTX()
|
||||
.addInput(t2, 1) // 24000
|
||||
.addInput(t3, 0) // 23000
|
||||
.addOutput(w.getAddress(), 11000)
|
||||
.addOutput(w.getAddress(), 11000);
|
||||
t4 = new MTX();
|
||||
t4.addTX(t2, 1); // 24000
|
||||
t4.addTX(t3, 0); // 23000
|
||||
t4.addOutput(w.getAddress(), 11000);
|
||||
t4.addOutput(w.getAddress(), 11000);
|
||||
|
||||
// balance: 22000
|
||||
yield w.sign(t4);
|
||||
t4 = t4.toTX();
|
||||
f1 = new MTX()
|
||||
.addInput(t4, 1) // 11000
|
||||
.addOutput(f.getAddress(), 10000);
|
||||
f1 = new MTX();
|
||||
f1.addTX(t4, 1); // 11000
|
||||
f1.addOutput(f.getAddress(), 10000);
|
||||
|
||||
// balance: 11000
|
||||
yield w.sign(f1);
|
||||
f1 = f1.toTX();
|
||||
|
||||
fake = new MTX()
|
||||
.addInput(t1, 1) // 1000 (already redeemed)
|
||||
.addOutput(w.getAddress(), 500);
|
||||
fake = new MTX();
|
||||
fake.addTX(t1, 1); // 1000 (already redeemed)
|
||||
fake.addOutput(w.getAddress(), 500);
|
||||
|
||||
// Script inputs but do not sign
|
||||
yield w.template(fake);
|
||||
@ -266,26 +243,23 @@ describe('Wallet', function() {
|
||||
// balance: 11000
|
||||
fake = fake.toTX();
|
||||
|
||||
// Fake TX should temporarly change output
|
||||
// Fake TX should temporarily change output.
|
||||
yield walletdb.addTX(fake);
|
||||
|
||||
yield walletdb.addTX(t4);
|
||||
|
||||
balance = yield w.getBalance();
|
||||
assert.equal(balance.unconfirmed, 22500);
|
||||
// assert.equal(balance.unconfirmed, 0);
|
||||
|
||||
yield walletdb.addTX(t1);
|
||||
|
||||
balance = yield w.getBalance();
|
||||
assert.equal(balance.unconfirmed, 72500);
|
||||
// assert.equal(balance.unconfirmed, 51000);
|
||||
|
||||
yield walletdb.addTX(t2);
|
||||
|
||||
balance = yield w.getBalance();
|
||||
assert.equal(balance.unconfirmed, 46500);
|
||||
// assert.equal(balance.unconfirmed, 49000);
|
||||
|
||||
yield walletdb.addTX(t3);
|
||||
|
||||
@ -315,8 +289,9 @@ describe('Wallet', function() {
|
||||
var w = doubleSpendWallet;
|
||||
var tx, txs, total, balance;
|
||||
|
||||
tx = new MTX().addOutput(w.getAddress(), 5000);
|
||||
tx.addInput(doubleSpend);
|
||||
tx = new MTX();
|
||||
tx.addCoin(doubleSpend);
|
||||
tx.addOutput(w.getAddress(), 5000);
|
||||
|
||||
txs = yield w.getHistory();
|
||||
assert.equal(txs.length, 5);
|
||||
@ -361,51 +336,51 @@ describe('Wallet', function() {
|
||||
f = yield walletdb.create();
|
||||
|
||||
// Coinbase
|
||||
t1 = new MTX()
|
||||
.addOutput(w.getAddress(), 50000)
|
||||
.addOutput(w.getAddress(), 1000);
|
||||
t1 = new MTX();
|
||||
t1.addInput(dummy());
|
||||
t1.addOutput(w.getAddress(), 50000);
|
||||
t1.addOutput(w.getAddress(), 1000);
|
||||
|
||||
// balance: 51000
|
||||
// yield w.sign(t1);
|
||||
t1 = t1.toTX();
|
||||
|
||||
t2 = new MTX()
|
||||
.addInput(t1, 0) // 50000
|
||||
.addOutput(w.getAddress(), 24000)
|
||||
.addOutput(w.getAddress(), 24000);
|
||||
t2 = new MTX();
|
||||
t2.addTX(t1, 0); // 50000
|
||||
t2.addOutput(w.getAddress(), 24000);
|
||||
t2.addOutput(w.getAddress(), 24000);
|
||||
|
||||
// balance: 49000
|
||||
yield w.sign(t2);
|
||||
t2 = t2.toTX();
|
||||
t3 = new MTX()
|
||||
.addInput(t1, 1) // 1000
|
||||
.addInput(t2, 0) // 24000
|
||||
.addOutput(w.getAddress(), 23000);
|
||||
t3 = new MTX();
|
||||
t3.addTX(t1, 1); // 1000
|
||||
t3.addTX(t2, 0); // 24000
|
||||
t3.addOutput(w.getAddress(), 23000);
|
||||
|
||||
// balance: 47000
|
||||
yield w.sign(t3);
|
||||
t3 = t3.toTX();
|
||||
t4 = new MTX()
|
||||
.addInput(t2, 1) // 24000
|
||||
.addInput(t3, 0) // 23000
|
||||
.addOutput(w.getAddress(), 11000)
|
||||
.addOutput(w.getAddress(), 11000);
|
||||
t4 = new MTX();
|
||||
t4.addTX(t2, 1); // 24000
|
||||
t4.addTX(t3, 0); // 23000
|
||||
t4.addOutput(w.getAddress(), 11000);
|
||||
t4.addOutput(w.getAddress(), 11000);
|
||||
|
||||
// balance: 22000
|
||||
yield w.sign(t4);
|
||||
t4 = t4.toTX();
|
||||
f1 = new MTX()
|
||||
.addInput(t4, 1) // 11000
|
||||
.addOutput(f.getAddress(), 10000);
|
||||
f1 = new MTX();
|
||||
f1.addTX(t4, 1); // 11000
|
||||
f1.addOutput(f.getAddress(), 10000);
|
||||
|
||||
// balance: 11000
|
||||
yield w.sign(f1);
|
||||
f1 = f1.toTX();
|
||||
|
||||
// fake = new MTX()
|
||||
// .addInput(t1, 1) // 1000 (already redeemed)
|
||||
// .addOutput(w.getAddress(), 500);
|
||||
// fake = new MTX();
|
||||
// fake.addTX(t1, 1); // 1000 (already redeemed)
|
||||
// fake.addOutput(w.getAddress(), 500);
|
||||
|
||||
// Script inputs but do not sign
|
||||
// yield w.template(fake);
|
||||
@ -431,19 +406,16 @@ describe('Wallet', function() {
|
||||
yield walletdb.addTX(t2);
|
||||
|
||||
balance = yield w.getBalance();
|
||||
//assert.equal(balance.unconfirmed, 71000);
|
||||
assert.equal(balance.unconfirmed, 47000);
|
||||
|
||||
yield walletdb.addTX(t3);
|
||||
|
||||
balance = yield w.getBalance();
|
||||
//assert.equal(balance.unconfirmed, 69000);
|
||||
assert.equal(balance.unconfirmed, 22000);
|
||||
|
||||
yield walletdb.addTX(f1);
|
||||
|
||||
balance = yield w.getBalance();
|
||||
//assert.equal(balance.unconfirmed, 58000);
|
||||
assert.equal(balance.unconfirmed, 11000);
|
||||
|
||||
txs = yield w.getHistory();
|
||||
@ -481,18 +453,19 @@ describe('Wallet', function() {
|
||||
|
||||
// Coinbase
|
||||
t1 = new MTX()
|
||||
.addOutput(w1.getAddress(), 5460)
|
||||
.addOutput(w1.getAddress(), 5460)
|
||||
.addOutput(w1.getAddress(), 5460)
|
||||
.addOutput(w1.getAddress(), 5460);
|
||||
|
||||
t1.addInput(dummy());
|
||||
t1.addOutput(w1.getAddress(), 5460);
|
||||
t1.addOutput(w1.getAddress(), 5460);
|
||||
t1.addOutput(w1.getAddress(), 5460);
|
||||
t1.addOutput(w1.getAddress(), 5460);
|
||||
|
||||
t1 = t1.toTX();
|
||||
|
||||
yield walletdb.addTX(t1);
|
||||
|
||||
// Create new transaction
|
||||
t2 = new MTX().addOutput(w2.getAddress(), 5460);
|
||||
t2 = new MTX();
|
||||
t2.addOutput(w2.getAddress(), 5460);
|
||||
yield w1.fund(t2, { rate: 10000, round: true });
|
||||
yield w1.sign(t2);
|
||||
view = t2.view;
|
||||
@ -501,15 +474,12 @@ describe('Wallet', function() {
|
||||
assert(t2.verify(view));
|
||||
|
||||
assert.equal(t2.getInputValue(view), 16380);
|
||||
|
||||
// assert.equal(t2.getOutputValue(), 5460); // minrelay=10000
|
||||
// assert.equal(t2.getFee(view), 10920); // minrelay=10000
|
||||
|
||||
assert.equal(t2.getOutputValue(), 6380); // minrelay=1000
|
||||
assert.equal(t2.getFee(view), 10000); // minrelay=1000
|
||||
assert.equal(t2.getOutputValue(), 6380);
|
||||
assert.equal(t2.getFee(view), 10000);
|
||||
|
||||
// Create new transaction
|
||||
t3 = new MTX().addOutput(w2.getAddress(), 15000);
|
||||
t3 = new MTX();
|
||||
t3.addOutput(w2.getAddress(), 15000);
|
||||
|
||||
try {
|
||||
yield w1.fund(t3, { rate: 10000, round: true });
|
||||
@ -528,12 +498,11 @@ describe('Wallet', function() {
|
||||
|
||||
// Coinbase
|
||||
t1 = new MTX()
|
||||
.addOutput(w1.getAddress(), 5460)
|
||||
.addOutput(w1.getAddress(), 5460)
|
||||
.addOutput(w1.getAddress(), 5460)
|
||||
.addOutput(w1.getAddress(), 5460);
|
||||
|
||||
t1.addInput(dummy(encoding.NULL_HASH));
|
||||
t1.addOutput(w1.getAddress(), 5460);
|
||||
t1.addOutput(w1.getAddress(), 5460);
|
||||
t1.addOutput(w1.getAddress(), 5460);
|
||||
t1.addOutput(w1.getAddress(), 5460);
|
||||
t1 = t1.toTX();
|
||||
|
||||
yield walletdb.addTX(t1);
|
||||
@ -566,7 +535,8 @@ describe('Wallet', function() {
|
||||
yield walletdb.addTX(t2);
|
||||
|
||||
// Create new transaction
|
||||
t3 = new MTX().addOutput(w2.getAddress(), 15000);
|
||||
t3 = new MTX();
|
||||
t3.addOutput(w2.getAddress(), 15000);
|
||||
|
||||
try {
|
||||
yield w1.fund(t3, { rate: 10000 });
|
||||
@ -586,23 +556,21 @@ describe('Wallet', function() {
|
||||
var t1, t2, tx, cost, total, coins1, coins2, left;
|
||||
|
||||
// Coinbase
|
||||
t1 = new MTX()
|
||||
.addOutput(w1.getAddress(), 5460)
|
||||
.addOutput(w1.getAddress(), 5460)
|
||||
.addOutput(w1.getAddress(), 5460)
|
||||
.addOutput(w1.getAddress(), 5460);
|
||||
|
||||
t1 = new MTX();
|
||||
t1.addInput(dummy());
|
||||
t1.addOutput(w1.getAddress(), 5460);
|
||||
t1.addOutput(w1.getAddress(), 5460);
|
||||
t1.addOutput(w1.getAddress(), 5460);
|
||||
t1.addOutput(w1.getAddress(), 5460);
|
||||
t1 = t1.toTX();
|
||||
|
||||
// Coinbase
|
||||
t2 = new MTX()
|
||||
.addOutput(w2.getAddress(), 5460)
|
||||
.addOutput(w2.getAddress(), 5460)
|
||||
.addOutput(w2.getAddress(), 5460)
|
||||
.addOutput(w2.getAddress(), 5460);
|
||||
|
||||
t2 = new MTX();
|
||||
t2.addInput(dummy());
|
||||
t2.addOutput(w2.getAddress(), 5460);
|
||||
t2.addOutput(w2.getAddress(), 5460);
|
||||
t2.addOutput(w2.getAddress(), 5460);
|
||||
t2.addOutput(w2.getAddress(), 5460);
|
||||
t2 = t2.toTX();
|
||||
|
||||
yield walletdb.addTX(t1);
|
||||
@ -622,9 +590,9 @@ describe('Wallet', function() {
|
||||
tx.addOutput(w1.getAddress(), 0);
|
||||
|
||||
// Add our unspent inputs to sign
|
||||
tx.addInput(coins1[0]);
|
||||
tx.addInput(coins1[1]);
|
||||
tx.addInput(coins2[0]);
|
||||
tx.addCoin(coins1[0]);
|
||||
tx.addCoin(coins1[1]);
|
||||
tx.addCoin(coins2[0]);
|
||||
|
||||
left = tx.getInputValue() - total;
|
||||
if (left === 0)
|
||||
@ -642,11 +610,10 @@ describe('Wallet', function() {
|
||||
// Verify
|
||||
assert.equal(tx.verify(), true);
|
||||
|
||||
// Sign transaction using `inputs` and `off` params.
|
||||
tx.inputs.length = 0;
|
||||
tx.addInput(coins1[1]);
|
||||
tx.addInput(coins1[2]);
|
||||
tx.addInput(coins2[1]);
|
||||
tx.addCoin(coins1[1]);
|
||||
tx.addCoin(coins1[2]);
|
||||
tx.addCoin(coins2[1]);
|
||||
|
||||
total = yield w1.sign(tx);
|
||||
assert.equal(total, 2);
|
||||
@ -658,16 +625,14 @@ describe('Wallet', function() {
|
||||
assert.equal(tx.verify(), true);
|
||||
}));
|
||||
|
||||
multisig = co(function* multisig(witness, bullshitNesting, cb) {
|
||||
testMultisig = co(function* testMultisig(witness, bullshitNesting, cb) {
|
||||
var flags = Script.flags.STANDARD_VERIFY_FLAGS;
|
||||
var options, w1, w2, w3, receive, b58, addr, paddr, utx, send, change;
|
||||
var rec = bullshitNesting ? 'nested' : 'receive';
|
||||
var depth = bullshitNesting ? 'nestedDepth' : 'receiveDepth';
|
||||
var options, w1, w2, w3, receive, b58;
|
||||
var addr, paddr, utx, send, change;
|
||||
var view, block;
|
||||
|
||||
if (witness)
|
||||
flags |= Script.flags.VERIFY_WITNESS;
|
||||
|
||||
// Create 3 2-of-3 wallets with our pubkeys as "shared keys"
|
||||
options = {
|
||||
witness: witness,
|
||||
@ -787,15 +752,15 @@ describe('Wallet', function() {
|
||||
});
|
||||
|
||||
it('should verify 2-of-3 scripthash tx', cob(function* () {
|
||||
yield multisig(false, false);
|
||||
yield testMultisig(false, false);
|
||||
}));
|
||||
|
||||
it('should verify 2-of-3 witnessscripthash tx', cob(function* () {
|
||||
yield multisig(true, false);
|
||||
yield testMultisig(true, false);
|
||||
}));
|
||||
|
||||
it('should verify 2-of-3 witnessscripthash tx with bullshit nesting', cob(function* () {
|
||||
yield multisig(true, true);
|
||||
yield testMultisig(true, true);
|
||||
}));
|
||||
|
||||
it('should fill tx with account 1', cob(function* () {
|
||||
@ -813,11 +778,11 @@ describe('Wallet', function() {
|
||||
rec = account.receive;
|
||||
|
||||
// Coinbase
|
||||
t1 = new MTX()
|
||||
.addOutput(rec.getAddress(), 5460)
|
||||
.addOutput(rec.getAddress(), 5460)
|
||||
.addOutput(rec.getAddress(), 5460)
|
||||
.addOutput(rec.getAddress(), 5460);
|
||||
t1 = new MTX();
|
||||
t1.addOutput(rec.getAddress(), 5460);
|
||||
t1.addOutput(rec.getAddress(), 5460);
|
||||
t1.addOutput(rec.getAddress(), 5460);
|
||||
t1.addOutput(rec.getAddress(), 5460);
|
||||
|
||||
t1.addInput(dummy());
|
||||
t1 = t1.toTX();
|
||||
@ -825,22 +790,20 @@ describe('Wallet', function() {
|
||||
yield walletdb.addTX(t1);
|
||||
|
||||
// Create new transaction
|
||||
t2 = new MTX().addOutput(w2.getAddress(), 5460);
|
||||
t2 = new MTX();
|
||||
t2.addOutput(w2.getAddress(), 5460);
|
||||
yield w1.fund(t2, { rate: 10000, round: true });
|
||||
yield w1.sign(t2);
|
||||
|
||||
assert(t2.verify());
|
||||
|
||||
assert.equal(t2.getInputValue(), 16380);
|
||||
|
||||
// assert.equal(t2.getOutputValue(), 5460); // minrelay=10000
|
||||
// assert.equal(t2.getFee(), 10920); // minrelay=10000
|
||||
|
||||
assert.equal(t2.getOutputValue(), 6380); // minrelay=1000
|
||||
assert.equal(t2.getFee(), 10000); // minrelay=1000
|
||||
assert.equal(t2.getOutputValue(), 6380);
|
||||
assert.equal(t2.getFee(), 10000);
|
||||
|
||||
// Create new transaction
|
||||
t3 = new MTX().addOutput(w2.getAddress(), 15000);
|
||||
t3 = new MTX();
|
||||
t3.addOutput(w2.getAddress(), 15000);
|
||||
|
||||
try {
|
||||
yield w1.fund(t3, { rate: 10000, round: true });
|
||||
@ -879,11 +842,11 @@ describe('Wallet', function() {
|
||||
w.account.receive.getAddress('base58'));
|
||||
|
||||
// Coinbase
|
||||
t1 = new MTX()
|
||||
.addOutput(w.getAddress(), 5460)
|
||||
.addOutput(w.getAddress(), 5460)
|
||||
.addOutput(w.getAddress(), 5460)
|
||||
.addOutput(account.receive.getAddress(), 5460);
|
||||
t1 = new MTX();
|
||||
t1.addOutput(w.getAddress(), 5460);
|
||||
t1.addOutput(w.getAddress(), 5460);
|
||||
t1.addOutput(w.getAddress(), 5460);
|
||||
t1.addOutput(account.receive.getAddress(), 5460);
|
||||
|
||||
t1.addInput(dummy());
|
||||
t1 = t1.toTX();
|
||||
@ -891,7 +854,8 @@ describe('Wallet', function() {
|
||||
yield walletdb.addTX(t1);
|
||||
|
||||
// Should fill from `foo` and fail
|
||||
t2 = new MTX().addOutput(w.getAddress(), 5460);
|
||||
t2 = new MTX();
|
||||
t2.addOutput(w.getAddress(), 5460);
|
||||
try {
|
||||
yield w.fund(t2, { rate: 10000, round: true, account: 'foo' });
|
||||
} catch (e) {
|
||||
@ -900,22 +864,23 @@ describe('Wallet', function() {
|
||||
assert(err);
|
||||
|
||||
// Should fill from whole wallet and succeed
|
||||
t2 = new MTX().addOutput(w.getAddress(), 5460);
|
||||
t2 = new MTX();
|
||||
t2.addOutput(w.getAddress(), 5460);
|
||||
yield w.fund(t2, { rate: 10000, round: true });
|
||||
|
||||
// Coinbase
|
||||
t1 = new MTX()
|
||||
.addOutput(account.receive.getAddress(), 5460)
|
||||
.addOutput(account.receive.getAddress(), 5460)
|
||||
.addOutput(account.receive.getAddress(), 5460);
|
||||
|
||||
t1 = new MTX();
|
||||
t1.addInput(dummy());
|
||||
t1.addOutput(account.receive.getAddress(), 5460);
|
||||
t1.addOutput(account.receive.getAddress(), 5460);
|
||||
t1.addOutput(account.receive.getAddress(), 5460);
|
||||
t1 = t1.toTX();
|
||||
|
||||
yield walletdb.addTX(t1);
|
||||
|
||||
t2 = new MTX().addOutput(w.getAddress(), 5460);
|
||||
// Should fill from `foo` and succeed
|
||||
t2 = new MTX();
|
||||
t2.addOutput(w.getAddress(), 5460);
|
||||
yield w.fund(t2, { rate: 10000, round: true, account: 'foo' });
|
||||
}));
|
||||
|
||||
@ -941,19 +906,19 @@ describe('Wallet', function() {
|
||||
w.master.key = null;
|
||||
|
||||
// Coinbase
|
||||
t1 = new MTX()
|
||||
.addOutput(w.getAddress(), 5460)
|
||||
.addOutput(w.getAddress(), 5460)
|
||||
.addOutput(w.getAddress(), 5460)
|
||||
.addOutput(w.getAddress(), 5460);
|
||||
|
||||
t1 = new MTX();
|
||||
t1.addInput(dummy());
|
||||
t1.addOutput(w.getAddress(), 5460);
|
||||
t1.addOutput(w.getAddress(), 5460);
|
||||
t1.addOutput(w.getAddress(), 5460);
|
||||
t1.addOutput(w.getAddress(), 5460);
|
||||
t1 = t1.toTX();
|
||||
|
||||
yield walletdb.addTX(t1);
|
||||
|
||||
// Create new transaction
|
||||
t2 = new MTX().addOutput(w.getAddress(), 5460);
|
||||
t2 = new MTX();
|
||||
t2.addOutput(w.getAddress(), 5460);
|
||||
yield w.fund(t2, { rate: 10000, round: true });
|
||||
|
||||
// Should fail
|
||||
@ -977,19 +942,19 @@ describe('Wallet', function() {
|
||||
var t1, t2;
|
||||
|
||||
// Coinbase
|
||||
t1 = new MTX()
|
||||
.addOutput(w1.getAddress(), 5460)
|
||||
.addOutput(w1.getAddress(), 5460)
|
||||
.addOutput(w1.getAddress(), 5460)
|
||||
.addOutput(w1.getAddress(), 5460);
|
||||
|
||||
t1 = new MTX();
|
||||
t1.addInput(dummy());
|
||||
t1.addOutput(w1.getAddress(), 5460);
|
||||
t1.addOutput(w1.getAddress(), 5460);
|
||||
t1.addOutput(w1.getAddress(), 5460);
|
||||
t1.addOutput(w1.getAddress(), 5460);
|
||||
t1 = t1.toTX();
|
||||
|
||||
yield walletdb.addTX(t1);
|
||||
|
||||
// Create new transaction
|
||||
t2 = new MTX().addOutput(w2.getAddress(), 21840);
|
||||
t2 = new MTX();
|
||||
t2.addOutput(w2.getAddress(), 21840);
|
||||
yield w1.fund(t2, { rate: 10000, round: true, subtractFee: true });
|
||||
yield w1.sign(t2);
|
||||
|
||||
@ -1006,13 +971,12 @@ describe('Wallet', function() {
|
||||
var options, t1, t2;
|
||||
|
||||
// Coinbase
|
||||
t1 = new MTX()
|
||||
.addOutput(w1.getAddress(), 5460)
|
||||
.addOutput(w1.getAddress(), 5460)
|
||||
.addOutput(w1.getAddress(), 5460)
|
||||
.addOutput(w1.getAddress(), 5460);
|
||||
|
||||
t1 = new MTX();
|
||||
t1.addInput(dummy());
|
||||
t1.addOutput(w1.getAddress(), 5460);
|
||||
t1.addOutput(w1.getAddress(), 5460);
|
||||
t1.addOutput(w1.getAddress(), 5460);
|
||||
t1.addOutput(w1.getAddress(), 5460);
|
||||
t1 = t1.toTX();
|
||||
|
||||
yield walletdb.addTX(t1);
|
||||
@ -1079,11 +1043,11 @@ describe('Wallet', function() {
|
||||
assert.equal(k.getHash('hex'), key.getHash('hex'));
|
||||
|
||||
// Coinbase
|
||||
t1 = new MTX()
|
||||
.addOutput(key.getAddress(), 5460)
|
||||
.addOutput(key.getAddress(), 5460)
|
||||
.addOutput(key.getAddress(), 5460)
|
||||
.addOutput(key.getAddress(), 5460);
|
||||
t1 = new MTX();
|
||||
t1.addOutput(key.getAddress(), 5460);
|
||||
t1.addOutput(key.getAddress(), 5460);
|
||||
t1.addOutput(key.getAddress(), 5460);
|
||||
t1.addOutput(key.getAddress(), 5460);
|
||||
|
||||
t1.addInput(dummy());
|
||||
t1 = t1.toTX();
|
||||
@ -1213,21 +1177,19 @@ describe('Wallet', function() {
|
||||
addr = alice.getAddress();
|
||||
|
||||
// Coinbase
|
||||
t1 = new MTX()
|
||||
.addOutput(addr, 50000);
|
||||
t1 = new MTX();
|
||||
t1.addInput(dummy());
|
||||
|
||||
// yield alice.sign(t1);
|
||||
t1.addOutput(addr, 50000);
|
||||
t1 = t1.toTX();
|
||||
|
||||
yield alice.add(t1);
|
||||
yield bob.add(t1);
|
||||
|
||||
// Bob misses this tx!
|
||||
t2 = new MTX()
|
||||
.addInput(t1, 0)
|
||||
.addOutput(addr, 24000)
|
||||
.addOutput(addr, 24000);
|
||||
t2 = new MTX();
|
||||
t2.addTX(t1, 0);
|
||||
t2.addOutput(addr, 24000);
|
||||
t2.addOutput(addr, 24000);
|
||||
|
||||
yield alice.sign(t2);
|
||||
t2 = t2.toTX();
|
||||
@ -1239,10 +1201,10 @@ describe('Wallet', function() {
|
||||
(yield bob.getBalance()).unconfirmed);
|
||||
|
||||
// Bob sees this one.
|
||||
t3 = new MTX()
|
||||
.addInput(t2, 0)
|
||||
.addInput(t2, 1)
|
||||
.addOutput(addr, 30000);
|
||||
t3 = new MTX();
|
||||
t3.addTX(t2, 0);
|
||||
t3.addTX(t2, 1);
|
||||
t3.addOutput(addr, 30000);
|
||||
|
||||
yield alice.sign(t3);
|
||||
t3 = t3.toTX();
|
||||
@ -1279,21 +1241,19 @@ describe('Wallet', function() {
|
||||
addr = alice.getAddress();
|
||||
|
||||
// Coinbase
|
||||
t1 = new MTX()
|
||||
.addOutput(addr, 50000);
|
||||
t1 = new MTX();
|
||||
t1.addInput(dummy());
|
||||
|
||||
// yield alice.sign(t1);
|
||||
t1.addOutput(addr, 50000);
|
||||
t1 = t1.toTX();
|
||||
|
||||
yield alice.add(t1);
|
||||
yield bob.add(t1);
|
||||
|
||||
// Bob misses this tx!
|
||||
t2 = new MTX()
|
||||
.addInput(t1, 0)
|
||||
.addOutput(addr, 24000)
|
||||
.addOutput(addr, 24000);
|
||||
t2 = new MTX();
|
||||
t2.addTX(t1, 0);
|
||||
t2.addOutput(addr, 24000);
|
||||
t2.addOutput(addr, 24000);
|
||||
|
||||
yield alice.sign(t2);
|
||||
t2 = t2.toTX();
|
||||
@ -1305,10 +1265,10 @@ describe('Wallet', function() {
|
||||
(yield bob.getBalance()).unconfirmed);
|
||||
|
||||
// Bob doublespends.
|
||||
t2a = new MTX()
|
||||
.addInput(t1, 0)
|
||||
.addOutput(addr, 10000)
|
||||
.addOutput(addr, 10000);
|
||||
t2a = new MTX();
|
||||
t2a.addTX(t1, 0);
|
||||
t2a.addOutput(addr, 10000);
|
||||
t2a.addOutput(addr, 10000);
|
||||
|
||||
yield bob.sign(t2a);
|
||||
t2a = t2a.toTX();
|
||||
@ -1316,10 +1276,10 @@ describe('Wallet', function() {
|
||||
yield bob.add(t2a);
|
||||
|
||||
// Bob sees this one.
|
||||
t3 = new MTX()
|
||||
.addInput(t2, 0)
|
||||
.addInput(t2, 1)
|
||||
.addOutput(addr, 30000);
|
||||
t3 = new MTX();
|
||||
t3.addTX(t2, 0);
|
||||
t3.addTX(t2, 1);
|
||||
t3.addOutput(addr, 30000);
|
||||
|
||||
yield alice.sign(t3);
|
||||
t3 = t3.toTX();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user