261 lines
7.4 KiB
JavaScript
261 lines
7.4 KiB
JavaScript
/* 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);
|
|
});
|
|
});
|
|
});
|
|
});
|