fcoin/test/mempool-test.js
2016-09-06 15:15:36 -07:00

240 lines
7.3 KiB
JavaScript

'use strict';
var bn = require('bn.js');
var bcoin = require('../').set('main');
var constants = bcoin.constants;
var utils = bcoin.utils;
var crypto = require('../lib/crypto/crypto');
var assert = require('assert');
var opcodes = constants.opcodes;
describe('Mempool', function() {
this.timeout(5000);
var chain = new bcoin.chain({
name: 'mp-chain',
db: 'memory'
});
var mempool = new bcoin.mempool({
chain: chain,
name: 'mempool-test',
db: 'memory'
});
var walletdb = new bcoin.walletdb({
name: 'mempool-wallet-test',
db: 'memory',
verify: true
});
var w;
mempool.on('error', function() {});
it('should open mempool', function(cb) {
mempool.open(cb);
});
it('should open walletdb', function(cb) {
walletdb.open(cb);
});
it('should open wallet', function(cb) {
walletdb.create({}, function(err, wallet) {
assert.ifError(err);
w = wallet;
cb();
});
});
it('should handle incoming orphans and TXs', function(cb) {
var kp = bcoin.keyring.generate();
// Coinbase
var t1 = bcoin.mtx().addOutput(w, 50000).addOutput(w, 10000); // 10000 instead of 1000
var prev = new bcoin.script([kp.publicKey, opcodes.OP_CHECKSIG]);
var dummyInput = {
prevout: {
hash: constants.ONE_HASH.toString('hex'),
index: 0
},
coin: {
version: 1,
height: 0,
value: 70000,
script: prev,
coinbase: false,
hash: constants.ONE_HASH.toString('hex'),
index: 0
},
script: new bcoin.script([]),
sequence: 0xffffffff
};
t1.addInput(dummyInput);
t1.inputs[0].script = new bcoin.script([t1.signature(0, prev, kp.privateKey, 'all', 0)]),
// balance: 51000
w.sign(t1, function(err, total) {
assert.ifError(err);
t1 = t1.toTX();
var t2 = bcoin.mtx().addInput(t1, 0) // 50000
.addOutput(w, 20000)
.addOutput(w, 20000);
// balance: 49000
w.sign(t2, function(err, total) {
assert.ifError(err);
t2 = t2.toTX();
var t3 = bcoin.mtx().addInput(t1, 1) // 10000
.addInput(t2, 0) // 20000
.addOutput(w, 23000);
// balance: 47000
w.sign(t3, function(err, total) {
assert.ifError(err);
t3 = t3.toTX();
var t4 = bcoin.mtx().addInput(t2, 1) // 24000
.addInput(t3, 0) // 23000
.addOutput(w, 11000)
.addOutput(w, 11000);
// balance: 22000
w.sign(t4, function(err, total) {
assert.ifError(err);
t4 = t4.toTX();
var f1 = bcoin.mtx().addInput(t4, 1) // 11000
.addOutput(bcoin.address.fromData(new Buffer([])).toBase58(), 9000);
// balance: 11000
w.sign(f1, function(err, total) {
assert.ifError(err);
f1 = f1.toTX();
var fake = bcoin.mtx().addInput(t1, 1) // 1000 (already redeemed)
.addOutput(w, 6000); // 6000 instead of 500
// Script inputs but do not sign
w.template(fake, function(err) {
assert.ifError(err);
// Fake signature
fake.inputs[0].script.set(0, new Buffer([0,0,0,0,0,0,0,0,0]));
fake.inputs[0].script.compile();
fake = fake.toTX();
// balance: 11000
[t2, t3, t4, f1, fake].forEach(function(tx) {
tx.inputs.forEach(function(input) {
delete input.coin;
});
});
mempool.addTX(fake, function(err) {
assert.ifError(err);
mempool.addTX(t4, function(err) {
assert.ifError(err);
var balance = mempool.getBalance();
assert.equal(balance, 0);
mempool.addTX(t1, function(err) {
assert.ifError(err);
var balance = mempool.getBalance();
assert.equal(balance, 60000);
mempool.addTX(t2, function(err) {
assert.ifError(err);
var balance = mempool.getBalance();
assert.equal(balance, 50000);
mempool.addTX(t3, function(err) {
assert.ifError(err);
var balance = mempool.getBalance();
assert.equal(balance, 22000);
mempool.addTX(f1, function(err) {
assert.ifError(err);
var balance = mempool.getBalance();
assert.equal(balance, 20000);
var txs = mempool.getHistory();
assert(txs.some(function(tx) {
return tx.hash('hex') === f1.hash('hex');
}));
cb();
});
});
});
});
});
});
});
});
});
});
});
});
});
it('should handle locktime', function(cb) {
var kp = bcoin.keyring.generate();
// Coinbase
var t1 = bcoin.mtx().addOutput(w, 50000).addOutput(w, 10000); // 10000 instead of 1000
var prev = new bcoin.script([kp.publicKey, opcodes.OP_CHECKSIG]);
var prevHash = crypto.randomBytes(32).toString('hex');
var dummyInput = {
prevout: {
hash: prevHash,
index: 0
},
coin: {
version: 1,
height: 0,
value: 70000,
script: prev,
coinbase: false,
hash: prevHash,
index: 0
},
script: new bcoin.script([]),
sequence: 0xffffffff
};
t1.addInput(dummyInput);
t1.setLocktime(200);
chain.tip.height = 200;
t1.inputs[0].script = new bcoin.script([t1.signature(0, prev, kp.privateKey, 'all', 0)]),
t1 = t1.toTX();
mempool.addTX(t1, function(err) {
chain.tip.height = 0;
assert.ifError(err);
cb();
});
});
it('should handle invalid locktime', function(cb) {
var kp = bcoin.keyring.generate();
// Coinbase
var t1 = bcoin.mtx().addOutput(w, 50000).addOutput(w, 10000); // 10000 instead of 1000
var prev = new bcoin.script([kp.publicKey, opcodes.OP_CHECKSIG]);
var prevHash = crypto.randomBytes(32).toString('hex');
var dummyInput = {
prevout: {
hash: prevHash,
index: 0
},
coin: {
version: 1,
height: 0,
value: 70000,
script: prev,
coinbase: false,
hash: prevHash,
index: 0
},
script: new bcoin.script([]),
sequence: 0xffffffff
};
t1.addInput(dummyInput);
t1.setLocktime(200);
chain.tip.height = 200 - 1;
t1.inputs[0].script = new bcoin.script([t1.signature(0, prev, kp.privateKey, 'all', 0)]),
t1 = t1.toTX();
mempool.addTX(t1, function(err) {
chain.tip.height = 0;
assert(err);
cb();
});
});
it('should destroy mempool', function(cb) {
mempool.close(cb);
});
});