Merge pull request #327 from nodar-chkuaselidze/test-input
Tests: Input
This commit is contained in:
commit
c1144a9955
241
test/data/bip69.json
Normal file
241
test/data/bip69.json
Normal file
@ -0,0 +1,241 @@
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"description": "Ordered by txId, descending (reverse-byte-order ascending)",
|
||||
"inputs": [
|
||||
{
|
||||
"txId": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"vout": 0
|
||||
},
|
||||
{
|
||||
"txId": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
|
||||
"vout": 0
|
||||
},
|
||||
{
|
||||
"txId": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
|
||||
"vout": 0
|
||||
},
|
||||
{
|
||||
"txId": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbff",
|
||||
"vout": 0
|
||||
},
|
||||
{
|
||||
"txId": "ffbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
|
||||
"vout": 0
|
||||
}
|
||||
],
|
||||
"expected": [0, 2, 3, 1, 4]
|
||||
},
|
||||
{
|
||||
"description": "Ordered by vout, ascending",
|
||||
"inputs": [
|
||||
{
|
||||
"txId": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"vout": 1
|
||||
},
|
||||
{
|
||||
"txId": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"vout": 2
|
||||
},
|
||||
{
|
||||
"txId": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"vout": 0
|
||||
}
|
||||
],
|
||||
"expected": [2, 0, 1]
|
||||
},
|
||||
{
|
||||
"description": "Ordered by txId, then vout",
|
||||
"inputs": [
|
||||
{
|
||||
"txId": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
"vout": 99
|
||||
},
|
||||
{
|
||||
"txId": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
|
||||
"vout": 99
|
||||
},
|
||||
{
|
||||
"txId": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
|
||||
"vout": 0
|
||||
},
|
||||
{
|
||||
"txId": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
|
||||
"vout": 0
|
||||
}
|
||||
],
|
||||
"expected": [0, 3, 1, 2]
|
||||
},
|
||||
{
|
||||
"description": "Sorting is irrelevant for equivalent inputs",
|
||||
"inputs": [
|
||||
{
|
||||
"txId": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
|
||||
"vout": 0
|
||||
},
|
||||
{
|
||||
"txId": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
|
||||
"vout": 1
|
||||
},
|
||||
{
|
||||
"txId": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
|
||||
"vout": 0
|
||||
},
|
||||
{
|
||||
"txId": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
|
||||
"vout": 1
|
||||
},
|
||||
{
|
||||
"txId": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
|
||||
"vout": 2
|
||||
}
|
||||
],
|
||||
"expected": [0, 2, 1, 3, 4]
|
||||
},
|
||||
{
|
||||
"description": "BIP69 test vector 1",
|
||||
"inputs": [
|
||||
{ "txId": "0e53ec5dfb2cb8a71fec32dc9a634a35b7e24799295ddd5278217822e0b31f57", "vout": 0 },
|
||||
{ "txId": "26aa6e6d8b9e49bb0630aac301db6757c02e3619feb4ee0eea81eb1672947024", "vout": 1 },
|
||||
{ "txId": "28e0fdd185542f2c6ea19030b0796051e7772b6026dd5ddccd7a2f93b73e6fc2", "vout": 0 },
|
||||
{ "txId": "381de9b9ae1a94d9c17f6a08ef9d341a5ce29e2e60c36a52d333ff6203e58d5d", "vout": 1 },
|
||||
{ "txId": "3b8b2f8efceb60ba78ca8bba206a137f14cb5ea4035e761ee204302d46b98de2", "vout": 0 },
|
||||
{ "txId": "402b2c02411720bf409eff60d05adad684f135838962823f3614cc657dd7bc0a", "vout": 1 },
|
||||
{ "txId": "54ffff182965ed0957dba1239c27164ace5a73c9b62a660c74b7b7f15ff61e7a", "vout": 1 },
|
||||
{ "txId": "643e5f4e66373a57251fb173151e838ccd27d279aca882997e005016bb53d5aa", "vout": 0 },
|
||||
{ "txId": "6c1d56f31b2de4bfc6aaea28396b333102b1f600da9c6d6149e96ca43f1102b1", "vout": 1 },
|
||||
{ "txId": "7a1de137cbafb5c70405455c49c5104ca3057a1f1243e6563bb9245c9c88c191", "vout": 0 },
|
||||
{ "txId": "7d037ceb2ee0dc03e82f17be7935d238b35d1deabf953a892a4507bfbeeb3ba4", "vout": 1 },
|
||||
{ "txId": "a5e899dddb28776ea9ddac0a502316d53a4a3fca607c72f66c470e0412e34086", "vout": 0 },
|
||||
{ "txId": "b4112b8f900a7ca0c8b0e7c4dfad35c6be5f6be46b3458974988e1cdb2fa61b8", "vout": 0 },
|
||||
{ "txId": "bafd65e3c7f3f9fdfdc1ddb026131b278c3be1af90a4a6ffa78c4658f9ec0c85", "vout": 0 },
|
||||
{ "txId": "de0411a1e97484a2804ff1dbde260ac19de841bebad1880c782941aca883b4e9", "vout": 1 },
|
||||
{ "txId": "f0a130a84912d03c1d284974f563c5949ac13f8342b8112edff52971599e6a45", "vout": 0 },
|
||||
{ "txId": "f320832a9d2e2452af63154bc687493484a0e7745ebd3aaf9ca19eb80834ad60", "vout": 0 }
|
||||
],
|
||||
"expected": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
|
||||
},
|
||||
{
|
||||
"description": "BIP69 test vector 2",
|
||||
"inputs": [
|
||||
{ "txId": "35288d269cee1941eaebb2ea85e32b42cdb2b04284a56d8b14dcc3f5c65d6055", "vout": 0 },
|
||||
{ "txId": "35288d269cee1941eaebb2ea85e32b42cdb2b04284a56d8b14dcc3f5c65d6055", "vout": 1 }
|
||||
],
|
||||
"expected": [0, 1]
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"description": "Ordered by Amount, ascending",
|
||||
"outputs": [
|
||||
{
|
||||
"script": "00000000",
|
||||
"value": 3000
|
||||
},
|
||||
{
|
||||
"script": "00000000",
|
||||
"value": 2000
|
||||
},
|
||||
{
|
||||
"script": "00000000",
|
||||
"value": 1000
|
||||
}
|
||||
],
|
||||
"expected": [2, 1, 0]
|
||||
},
|
||||
{
|
||||
"description": "Ordered by Script, ascending",
|
||||
"outputs": [
|
||||
{
|
||||
"script": "00000000",
|
||||
"value": 1000
|
||||
},
|
||||
{
|
||||
"script": "22222222",
|
||||
"value": 1000
|
||||
},
|
||||
{
|
||||
"script": "11111111",
|
||||
"value": 1000
|
||||
}
|
||||
],
|
||||
"expected": [0, 2, 1]
|
||||
},
|
||||
{
|
||||
"description": "Ordered by Amount, then Script",
|
||||
"outputs": [
|
||||
{
|
||||
"script": "11111111",
|
||||
"value": 1000
|
||||
},
|
||||
{
|
||||
"script": "11111111",
|
||||
"value": 2000
|
||||
},
|
||||
{
|
||||
"script": "00000000",
|
||||
"value": 3000
|
||||
},
|
||||
{
|
||||
"script": "00000000",
|
||||
"value": 2000
|
||||
}
|
||||
],
|
||||
"expected": [0, 3, 1, 2]
|
||||
},
|
||||
{
|
||||
"description": "Sorting is irrelevant for equivalent outputs",
|
||||
"outputs": [
|
||||
{
|
||||
"script": "00000000",
|
||||
"value": 2000
|
||||
},
|
||||
{
|
||||
"script": "11111111",
|
||||
"value": 2000
|
||||
},
|
||||
{
|
||||
"script": "00000000",
|
||||
"value": 2000
|
||||
},
|
||||
{
|
||||
"script": "11111111",
|
||||
"value": 3000
|
||||
},
|
||||
{
|
||||
"script": "22222222",
|
||||
"value": 3000
|
||||
}
|
||||
],
|
||||
"expected": [0, 2, 1, 3, 4]
|
||||
},
|
||||
{
|
||||
"description": "BIP69 test vector 1",
|
||||
"outputs": [
|
||||
{
|
||||
"script": "76a9144a5fba237213a062f6f57978f796390bdcf8d01588ac",
|
||||
"value": 400057456
|
||||
},
|
||||
{
|
||||
"script": "76a9145be32612930b8323add2212a4ec03c1562084f8488ac",
|
||||
"value": 40000000000
|
||||
}
|
||||
],
|
||||
"expected": [0, 1]
|
||||
},
|
||||
{
|
||||
"description": "BIP69 test vector 2",
|
||||
"outputs": [
|
||||
{
|
||||
"script": "41046a0765b5865641ce08dd39690aade26dfbf5511430ca428a3089261361cef170e3929a68aee3d8d4848b0c5111b0a37b82b86ad559fd2a745b44d8e8d9dfdc0cac",
|
||||
"value": 100000000
|
||||
},
|
||||
{
|
||||
"script": "41044a656f065871a353f216ca26cef8dde2f03e8c16202d2e8ad769f02032cb86a5eb5e56842e92e19141d60a01928f8dd2c875a390f67c1f6c94cfc617c0ea45afac",
|
||||
"value": 2400000000
|
||||
}
|
||||
],
|
||||
"expected": [0, 1]
|
||||
}
|
||||
]
|
||||
}
|
||||
260
test/input-test.js
Normal file
260
test/input-test.js
Normal file
@ -0,0 +1,260 @@
|
||||
/* eslint-env mocha */
|
||||
/* eslint prefer-arrow-callback: "off" */
|
||||
|
||||
'use strict';
|
||||
|
||||
const Input = require('../lib/primitives/input');
|
||||
const util = require('../lib/utils/util');
|
||||
const BufferReader = require('../lib/utils/reader');
|
||||
const assert = require('./util/assert');
|
||||
const common = require('./util/common');
|
||||
|
||||
// Take input rawbytes from the raw data format
|
||||
// p2pkh
|
||||
const tx1 = common.readTX('tx1');
|
||||
const input1 = tx1.getRaw().slice(5, 154);
|
||||
|
||||
// multisig
|
||||
const tx2 = common.readTX('tx3');
|
||||
const input2 = tx2.getRaw().slice(152, 339);
|
||||
|
||||
// p2sh multisig
|
||||
const tx3 = common.readTX('tx4');
|
||||
const input3 = tx3.getRaw().slice(5, 266);
|
||||
|
||||
const bip69tests = require('./data/bip69');
|
||||
|
||||
describe('Input', function() {
|
||||
it('should return same raw', () => {
|
||||
[input1, input2, input3].forEach((rawinput) => {
|
||||
const raw = rawinput.slice();
|
||||
const input = Input.fromRaw(raw);
|
||||
|
||||
assert.bufferEqual(raw, input.toRaw());
|
||||
});
|
||||
});
|
||||
|
||||
it('should return same raw on fromReader', () => {
|
||||
[input1, input2, input3].forEach((rawinput) => {
|
||||
const raw = rawinput.slice();
|
||||
const input = Input.fromReader(new BufferReader(raw));
|
||||
|
||||
assert.bufferEqual(raw, input.toRaw());
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse p2pkh input', () => {
|
||||
const raw = input1.slice();
|
||||
const rawprevout = raw.slice(0, 36);
|
||||
const rawscript = raw.slice(37, 145);
|
||||
|
||||
const input = Input.fromRaw(raw);
|
||||
|
||||
const type = input.getType();
|
||||
const addr = input.getAddress().toBase58();
|
||||
const prevout = input.prevout.toRaw();
|
||||
|
||||
assert.strictEqual(type, 'pubkeyhash');
|
||||
assert.strictEqual(addr, '1PM9ZgAV8Z4df1md2zRTF98tPjzTAfk2a6');
|
||||
assert.strictEqual(input.isCoinbase(), false);
|
||||
|
||||
assert.strictEqual(input.isFinal(), true);
|
||||
assert.strictEqual(input.isRBF(), false);
|
||||
assert.strictEqual(input.getSize(), raw.length);
|
||||
|
||||
assert.bufferEqual(input.script.toRaw(), rawscript);
|
||||
assert.bufferEqual(prevout, rawprevout);
|
||||
});
|
||||
|
||||
it('should parse multisig input', () => {
|
||||
const raw = input2.slice();
|
||||
const rawprevout = raw.slice(0, 36);
|
||||
const rawscript = raw.slice(37, 183);
|
||||
|
||||
const input = Input.fromRaw(raw);
|
||||
|
||||
const type = input.getType();
|
||||
const addr = input.getAddress();
|
||||
const prevout = input.prevout.toRaw();
|
||||
|
||||
assert.strictEqual(type, 'multisig');
|
||||
assert.strictEqual(addr, null);
|
||||
assert.strictEqual(input.isCoinbase(), false);
|
||||
|
||||
assert.strictEqual(input.isFinal(), true);
|
||||
assert.strictEqual(input.isRBF(), false);
|
||||
assert.strictEqual(input.getSize(), raw.length);
|
||||
|
||||
assert.bufferEqual(input.script.toRaw(), rawscript);
|
||||
assert.bufferEqual(prevout, rawprevout);
|
||||
});
|
||||
|
||||
it('should parse p2sh multisig input', () => {
|
||||
const raw = input3.slice();
|
||||
|
||||
const rawprevout = raw.slice(0, 36);
|
||||
const rawscript = raw.slice(37, 257);
|
||||
const rawredeem = raw.slice(186, 257);
|
||||
|
||||
const input = Input.fromRaw(raw);
|
||||
|
||||
const type = input.getType();
|
||||
const subtype = input.getSubtype();
|
||||
const addr = input.getAddress().toBase58();
|
||||
const prevout = input.prevout.toRaw();
|
||||
const redeem = input.getRedeem().toRaw();
|
||||
|
||||
assert.strictEqual(type, 'scripthash');
|
||||
assert.strictEqual(subtype, 'multisig');
|
||||
assert.strictEqual(addr, '3416sTvfjDT8YPJ6PywJE1Pm2GgWiv2guz');
|
||||
assert.strictEqual(input.isCoinbase(), false);
|
||||
|
||||
assert.strictEqual(input.isFinal(), false);
|
||||
assert.strictEqual(input.isRBF(), true);
|
||||
assert.strictEqual(input.getSize(), raw.length);
|
||||
|
||||
assert.bufferEqual(input.script.toRaw(), rawscript);
|
||||
assert.bufferEqual(prevout, rawprevout);
|
||||
assert.bufferEqual(redeem, rawredeem);
|
||||
});
|
||||
|
||||
// it('should parse p2wpkh')
|
||||
|
||||
it('should parse coinbase input', () => {
|
||||
const rawprevout = Buffer.from('' +
|
||||
// prevout hash
|
||||
'0000000000000000000000000000000000000000' +
|
||||
'000000000000000000000000' +
|
||||
// prevout index
|
||||
'ffffffff', 'hex');
|
||||
|
||||
const rawscript = Buffer.from('' +
|
||||
// length
|
||||
'50' +
|
||||
// raw script
|
||||
'0332f906047b20c6582f4254432e434f4d2f42436' +
|
||||
'f696e2ffabe6d6d911d3dbdeb854243e6eb04631d' +
|
||||
'017fd183eb54a78e06e9e0dc22f38e765fa267010' +
|
||||
'00000000000002503d49ad942020000000000', 'hex');
|
||||
|
||||
const sequence = Buffer.from('ffffffff', 'hex');
|
||||
|
||||
const raw = Buffer.alloc(40 + rawscript.length);
|
||||
|
||||
rawprevout.copy(raw, 0);
|
||||
rawscript.copy(raw, 36);
|
||||
sequence.copy(raw, raw.length - 4);
|
||||
|
||||
const input = Input.fromRaw(raw);
|
||||
|
||||
const type = input.getType();
|
||||
const prevout = input.prevout.toRaw();
|
||||
|
||||
assert.strictEqual(type, 'coinbase');
|
||||
assert.strictEqual(input.isCoinbase(), true);
|
||||
|
||||
assert.strictEqual(input.isFinal(), true);
|
||||
assert.strictEqual(input.isRBF(), false);
|
||||
assert.strictEqual(input.getSize(), raw.length);
|
||||
|
||||
assert.bufferEqual(input.script.toRaw(), rawscript.slice(1));
|
||||
assert.bufferEqual(prevout, rawprevout);
|
||||
});
|
||||
|
||||
it('should check zero signature script', () => {
|
||||
const rawprevout = Buffer.from('' +
|
||||
'759104b6b99f9f20d3de9e7ddbb2ac84cd8a8af2' +
|
||||
'd7a6cdc46ac9fbdc0a388b3c' +
|
||||
'ffffffff', 'hex');
|
||||
const rawscript = Buffer.from('00', 'hex');
|
||||
const sequence = Buffer.from('ffffffff', 'hex');
|
||||
|
||||
const raw = Buffer.alloc(41);
|
||||
|
||||
rawprevout.copy(raw, 0);
|
||||
rawscript.copy(raw, 36);
|
||||
sequence.copy(raw, raw.length - 4);
|
||||
|
||||
const input = Input.fromRaw(raw);
|
||||
|
||||
const type = input.getType();
|
||||
const prevout = input.prevout.toRaw();
|
||||
|
||||
assert.strictEqual(type, 'nonstandard');
|
||||
assert.strictEqual(input.isCoinbase(), false);
|
||||
|
||||
assert.strictEqual(input.isFinal(), true);
|
||||
assert.strictEqual(input.isRBF(), false);
|
||||
assert.strictEqual(input.getSize(), raw.length);
|
||||
|
||||
assert.bufferEqual(input.script.toRaw(), rawscript.slice(1));
|
||||
assert.bufferEqual(prevout, rawprevout);
|
||||
});
|
||||
|
||||
it('should be the same from same raw', () => {
|
||||
const raw = input1.slice();
|
||||
const inputObject1 = Input.fromRaw(raw);
|
||||
const inputObject2 = Input.fromRaw(raw);
|
||||
const equals = inputObject1.equals(inputObject2);
|
||||
|
||||
assert.strictEqual(equals, true);
|
||||
});
|
||||
|
||||
it('should clone input correctly', () => {
|
||||
const raw = input1.slice();
|
||||
const inputObject1 = Input.fromRaw(raw);
|
||||
const inputObject2 = inputObject1.clone();
|
||||
const equals = inputObject1.equals(inputObject2);
|
||||
|
||||
assert.strictEqual(inputObject1 !== inputObject2, true);
|
||||
assert.strictEqual(equals, true);
|
||||
});
|
||||
|
||||
it('should create input from Options', () => {
|
||||
const raw = input3.slice();
|
||||
const rawscript = raw.slice(37, 257);
|
||||
|
||||
const options = {
|
||||
prevout: {
|
||||
hash: '8759d7397a86d6c42dfe2c55612e523d' +
|
||||
'171e51708fec9e289118deb5ba994001',
|
||||
index: 1
|
||||
},
|
||||
script: rawscript,
|
||||
sequence: 0
|
||||
};
|
||||
|
||||
const inputRaw = Input.fromRaw(raw);
|
||||
const inputOptions = Input.fromOptions(options);
|
||||
|
||||
assert.strictEqual(inputRaw.equals(inputOptions), true);
|
||||
});
|
||||
|
||||
describe('BIP69', () => {
|
||||
bip69tests.inputs.forEach((test) => {
|
||||
it(`should sort: ${test.description}`, () => {
|
||||
const inputs = test.inputs.map((prevout, i) => {
|
||||
const input = Input.fromOptions({
|
||||
prevout: {
|
||||
hash: util.revHex(prevout.txId),
|
||||
index: prevout.vout
|
||||
}
|
||||
});
|
||||
|
||||
// to compare indexes
|
||||
input.i = i;
|
||||
|
||||
return input;
|
||||
});
|
||||
|
||||
const expected = test.expected;
|
||||
|
||||
inputs.sort((a, b) => {
|
||||
return a.compare(b);
|
||||
});
|
||||
|
||||
assert.deepStrictEqual(inputs.map(input => input.i), expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
Reference in New Issue
Block a user