Skip to content

Commit

Permalink
Require round-trip match for valid BIP vectors
Browse files Browse the repository at this point in the history
Found and fixed a couple bugs in the process
  • Loading branch information
reardencode committed Apr 5, 2022
1 parent 4042478 commit f686bed
Show file tree
Hide file tree
Showing 11 changed files with 44 additions and 38 deletions.
9 changes: 2 additions & 7 deletions src/lib/converter/input/tapLeafScript.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
const typeFields_1 = require('../../typeFields');
const varuint = require('../varint');
function decode(keyVal) {
if (keyVal.key[0] !== typeFields_1.InputTypes.TAP_LEAF_SCRIPT) {
throw new Error(
Expand Down Expand Up @@ -29,14 +28,10 @@ function decode(keyVal) {
exports.decode = decode;
function encode(tScript) {
const head = Buffer.from([typeFields_1.InputTypes.TAP_LEAF_SCRIPT]);
const _offset = varuint.encodingLength(tScript.script.length);
const value = Buffer.allocUnsafe(_offset + tScript.script.length + 1);
varuint.encode(tScript.script.length, value);
value[_offset + tScript.script.length] = tScript.leafVersion;
tScript.script.copy(value, _offset);
const verBuf = Buffer.from([tScript.leafVersion]);
return {
key: Buffer.concat([head, tScript.controlBlock]),
value,
value: Buffer.concat([tScript.script, verBuf]),
};
}
exports.encode = encode;
Expand Down
2 changes: 1 addition & 1 deletion src/lib/converter/output/tapTree.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { KeyValue, TapTree } from '../../interfaces';
export declare function decode(keyVal: KeyValue): TapTree;
export declare function encode(tree: TapTree): KeyValue;
export declare const expected = "[{ depth: number; leafVersion: number, script: Buffer; }]";
export declare const expected = "{ leaves: [{ depth: number; leafVersion: number, script: Buffer; }] }";
export declare function check(data: any): data is TapTree;
export declare function canAdd(currentData: any, newData: any): boolean;
11 changes: 6 additions & 5 deletions src/lib/converter/output/tapTree.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ function decode(keyVal) {
});
_offset += scriptLen;
}
return data;
return { leaves: data };
}
exports.decode = decode;
function encode(tree) {
const key = Buffer.from([typeFields_1.OutputTypes.TAP_TREE]);
const bufs = [].concat(
...tree.map(tapLeaf => [
...tree.leaves.map(tapLeaf => [
Buffer.of(tapLeaf.depth, tapLeaf.leafVersion),
varuint.encode(tapLeaf.script.length),
tapLeaf.script,
Expand All @@ -41,11 +41,12 @@ function encode(tree) {
};
}
exports.encode = encode;
exports.expected = '[{ depth: number; leafVersion: number, script: Buffer; }]';
exports.expected =
'{ leaves: [{ depth: number; leafVersion: number, script: Buffer; }] }';
function check(data) {
return (
Array.isArray(data) &&
data.every(
Array.isArray(data.leaves) &&
data.leaves.every(
tapLeaf =>
tapLeaf.depth >= 0 &&
tapLeaf.depth <= 128 &&
Expand Down
4 changes: 2 additions & 2 deletions src/lib/converter/shared/tapBip32Derivation.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ function makeConverter(TYPE_BYTE) {
value: keyVal.value.slice(nHashesLen + nHashes * 32),
});
const leafHashes = new Array(nHashes);
for (let i = nHashesLen; i < nHashesLen + 32 * nHashes; i += 32) {
leafHashes[i] = keyVal.value.slice(i, i + 32);
for (let i = 0, _offset = nHashesLen; i < nHashes; i++, _offset += 32) {
leafHashes[i] = keyVal.value.slice(_offset, _offset + 32);
}
return Object.assign({}, base, { leafHashes });
}
Expand Down
4 changes: 3 additions & 1 deletion src/lib/interfaces.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,9 @@ export declare type TapMerkleRoot = Buffer;
export interface TapLeaf extends TapScript {
depth: number;
}
export declare type TapTree = TapLeaf[];
export interface TapTree {
leaves: TapLeaf[];
}
export declare type TransactionIOCountGetter = (txBuffer: Buffer) => {
inputCount: number;
outputCount: number;
Expand Down
9 changes: 7 additions & 2 deletions src/tests/fromBIP/valid.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,14 @@ const valid_1 = require('../fixtures/valid');
const txTools_1 = require('../utils/txTools');
for (const f of valid_1.fixtures) {
tape(`Test: Should not throw`, t => {
let psbt;
t.doesNotThrow(() => {
psbt_1.Psbt.fromBase64(f, txTools_1.transactionFromBuffer);
});
psbt = psbt_1.Psbt.fromBase64(f, txTools_1.transactionFromBuffer);
}, 'fromBase64');
t.doesNotThrow(() => {
const out = psbt.toBase64();
t.equal(out, f);
}, 'toBase64');
t.end();
});
}
10 changes: 2 additions & 8 deletions ts_src/lib/converter/input/tapLeafScript.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { KeyValue, TapLeafScript } from '../../interfaces';
import { InputTypes } from '../../typeFields';
import * as varuint from '../varint';

export function decode(keyVal: KeyValue): TapLeafScript {
if (keyVal.key[0] !== InputTypes.TAP_LEAF_SCRIPT) {
Expand Down Expand Up @@ -31,16 +30,11 @@ export function decode(keyVal: KeyValue): TapLeafScript {

export function encode(tScript: TapLeafScript): KeyValue {
const head = Buffer.from([InputTypes.TAP_LEAF_SCRIPT]);
const _offset = varuint.encodingLength(tScript.script.length);
const value = Buffer.allocUnsafe(_offset + tScript.script.length + 1);

varuint.encode(tScript.script.length, value);
value[_offset + tScript.script.length] = tScript.leafVersion;
tScript.script.copy(value, _offset);
const verBuf = Buffer.from([tScript.leafVersion]);

return {
key: Buffer.concat([head, tScript.controlBlock]),
value,
value: Buffer.concat([tScript.script, verBuf]),
};
}

Expand Down
14 changes: 7 additions & 7 deletions ts_src/lib/converter/output/tapTree.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { KeyValue, TapTree } from '../../interfaces';
import { KeyValue, TapLeaf, TapTree } from '../../interfaces';
import { OutputTypes } from '../../typeFields';
import * as varuint from '../varint';

Expand All @@ -10,7 +10,7 @@ export function decode(keyVal: KeyValue): TapTree {
);
}
let _offset = 0;
const data: TapTree = [];
const data: TapLeaf[] = [];
while (_offset < keyVal.value.length) {
const depth = keyVal.value[_offset++];
const leafVersion = keyVal.value[_offset++];
Expand All @@ -23,13 +23,13 @@ export function decode(keyVal: KeyValue): TapTree {
});
_offset += scriptLen;
}
return data;
return { leaves: data };
}

export function encode(tree: TapTree): KeyValue {
const key = Buffer.from([OutputTypes.TAP_TREE]);
const bufs = ([] as Buffer[]).concat(
...tree.map(tapLeaf => [
...tree.leaves.map(tapLeaf => [
Buffer.of(tapLeaf.depth, tapLeaf.leafVersion),
varuint.encode(tapLeaf.script.length),
tapLeaf.script,
Expand All @@ -42,11 +42,11 @@ export function encode(tree: TapTree): KeyValue {
}

export const expected =
'[{ depth: number; leafVersion: number, script: Buffer; }]';
'{ leaves: [{ depth: number; leafVersion: number, script: Buffer; }] }';
export function check(data: any): data is TapTree {
return (
Array.isArray(data) &&
data.every(
Array.isArray(data.leaves) &&
data.leaves.every(
(tapLeaf: any) =>
tapLeaf.depth >= 0 &&
tapLeaf.depth <= 128 &&
Expand Down
4 changes: 2 additions & 2 deletions ts_src/lib/converter/shared/tapBip32Derivation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ export function makeConverter(
value: keyVal.value.slice(nHashesLen + nHashes * 32),
});
const leafHashes: Buffer[] = new Array(nHashes);
for (let i = nHashesLen; i < nHashesLen + 32 * nHashes; i += 32) {
leafHashes[i] = keyVal.value.slice(i, i + 32);
for (let i = 0, _offset = nHashesLen; i < nHashes; i++, _offset += 32) {
leafHashes[i] = keyVal.value.slice(_offset, _offset + 32);
}
return { ...base, leafHashes };
}
Expand Down
4 changes: 3 additions & 1 deletion ts_src/lib/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,9 @@ export interface TapLeaf extends TapScript {
depth: number;
}

export type TapTree = TapLeaf[];
export interface TapTree {
leaves: TapLeaf[];
}

export type TransactionIOCountGetter = (
txBuffer: Buffer,
Expand Down
11 changes: 9 additions & 2 deletions ts_src/tests/fromBIP/valid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,16 @@ import { transactionFromBuffer } from '../utils/txTools';

for (const f of fixtures) {
tape(`Test: Should not throw`, t => {
let psbt: Psbt;
t.doesNotThrow(() => {
Psbt.fromBase64(f, transactionFromBuffer);
});
psbt = Psbt.fromBase64(f, transactionFromBuffer);
}, 'fromBase64');

t.doesNotThrow(() => {
const out = psbt.toBase64();
t.equal(out, f);
}, 'toBase64');

t.end();
});
}

0 comments on commit f686bed

Please sign in to comment.