Skip to content

Commit

Permalink
Revert "perfs: optimize script.decomplie return type"
Browse files Browse the repository at this point in the history
This reverts commit 6ec2822.
  • Loading branch information
jasonandjay committed May 10, 2024
1 parent 6ec2822 commit ac6a5b2
Show file tree
Hide file tree
Showing 17 changed files with 53 additions and 39 deletions.
2 changes: 1 addition & 1 deletion src/payments/p2sh.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ function p2sh(a, opts) {
// is the redeem output empty/invalid?
if (redeem.output) {
const decompile = bscript.decompile(redeem.output);
if (decompile.length < 1)
if (!decompile || decompile.length < 1)
throw new TypeError('Redeem.output too short');
if (redeem.output.byteLength > 520)
throw new TypeError(
Expand Down
2 changes: 1 addition & 1 deletion src/payments/p2tr.js
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ function p2tr(a, opts) {
throw new TypeError('Redeem.redeemVersion and witness mismatch');
}
if (a.redeem.output) {
if (!bscript.decompile(a.redeem.output).length)
if (bscript.decompile(a.redeem.output).length === 0)
throw new TypeError('Redeem.output is invalid');
// output redeem is constructed from the witness
if (o.redeem.output && !a.redeem.output.equals(o.redeem.output))
Expand Down
9 changes: 6 additions & 3 deletions src/payments/p2wsh.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,8 @@ function p2wsh(a, opts) {
// is the redeem output non-empty/valid?
if (a.redeem.output) {
const decompile = bscript.decompile(a.redeem.output);
if (!decompile.length) throw new TypeError('Redeem.output is invalid');
if (!decompile || decompile.length < 1)
throw new TypeError('Redeem.output is invalid');
if (a.redeem.output.byteLength > 3600)
throw new TypeError(
'Redeem.output unspendable if larger than 3600 bytes',
Expand All @@ -197,7 +198,9 @@ function p2wsh(a, opts) {
if (
(a.redeem.input && _rchunks().some(chunkHasUncompressedPubkey)) ||
(a.redeem.output &&
bscript.decompile(a.redeem.output).some(chunkHasUncompressedPubkey))
(bscript.decompile(a.redeem.output) || []).some(
chunkHasUncompressedPubkey,
))
) {
throw new TypeError(
'redeem.input or redeem.output contains uncompressed pubkey',
Expand All @@ -210,7 +213,7 @@ function p2wsh(a, opts) {
throw new TypeError('Witness and redeem.output mismatch');
if (
a.witness.some(chunkHasUncompressedPubkey) ||
bscript.decompile(wScript).some(chunkHasUncompressedPubkey)
(bscript.decompile(wScript) || []).some(chunkHasUncompressedPubkey)
)
throw new TypeError('Witness contains uncompressed pubkey');
}
Expand Down
6 changes: 3 additions & 3 deletions src/psbt.js
Original file line number Diff line number Diff line change
Expand Up @@ -1636,7 +1636,7 @@ function pubkeyInOutput(pubkey, output, outputIndex, cache) {
function redeemFromFinalScriptSig(finalScript) {
if (!finalScript) return;
const decomp = bscript.decompile(finalScript);
if (!decomp.length) return;
if (!decomp) return;
const lastItem = decomp[decomp.length - 1];
if (
!Buffer.isBuffer(lastItem) ||
Expand All @@ -1645,7 +1645,7 @@ function redeemFromFinalScriptSig(finalScript) {
)
return;
const sDecomp = bscript.decompile(lastItem);
if (!sDecomp.length) return;
if (!sDecomp) return;
return lastItem;
}
function redeemFromFinalWitnessScript(finalScript) {
Expand All @@ -1654,7 +1654,7 @@ function redeemFromFinalWitnessScript(finalScript) {
const lastItem = decomp[decomp.length - 1];
if (isPubkeyLike(lastItem)) return;
const sDecomp = bscript.decompile(lastItem);
if (!sDecomp.length) return;
if (!sDecomp) return;
return lastItem;
}
function compressPubkey(pubkey) {
Expand Down
6 changes: 3 additions & 3 deletions src/psbt/psbtutils.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ function pubkeyPositionInScript(pubkey, script) {
const pubkeyHash = (0, crypto_1.hash160)(pubkey);
const pubkeyXOnly = pubkey.slice(1, 33); // slice before calling?
const decompiled = bscript.decompile(script);
if (!decompiled.length) throw new Error('Unknown script error');
if (decompiled === null) throw new Error('Unknown script error');
return decompiled.findIndex(element => {
if (typeof element === 'number') return false;
return (
Expand Down Expand Up @@ -173,10 +173,10 @@ function extractPartialSigs(input) {
function getPsigsFromInputFinalScripts(input) {
const scriptItems = !input.finalScriptSig
? []
: bscript.decompile(input.finalScriptSig);
: bscript.decompile(input.finalScriptSig) || [];
const witnessItems = !input.finalScriptWitness
? []
: bscript.decompile(input.finalScriptWitness);
: bscript.decompile(input.finalScriptWitness) || [];
return scriptItems
.concat(witnessItems)
.filter(item => {
Expand Down
2 changes: 1 addition & 1 deletion src/script.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export declare function countNonPushOnlyOPs(value: Stack): number;
* @throws Error if the compilation fails.
*/
export declare function compile(chunks: Buffer | Stack): Buffer;
export declare function decompile(buffer: Buffer | Array<number | Buffer>): Stack;
export declare function decompile(buffer: Buffer | Array<number | Buffer>): Array<number | Buffer> | null;
/**
* Converts the given chunks into an ASM (Assembly) string representation.
* If the chunks parameter is a Buffer, it will be decompiled into a Stack before conversion.
Expand Down
5 changes: 3 additions & 2 deletions src/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ function compile(chunks) {
}
exports.compile = compile;
function decompile(buffer) {
// TODO: remove me
if (chunksIsArray(buffer)) return buffer;
typeforce(types.Buffer, buffer);
const chunks = [];
Expand All @@ -125,10 +126,10 @@ function decompile(buffer) {
if (opcode > ops_1.OPS.OP_0 && opcode <= ops_1.OPS.OP_PUSHDATA4) {
const d = pushdata.decode(buffer, i);
// did reading a pushDataInt fail?
if (d === null) return [];
if (d === null) return null;
i += d.size;
// attempt to read too much data?
if (i + d.number > buffer.length) return [];
if (i + d.number > buffer.length) return null;
const data = buffer.slice(i, i + d.number);
i += d.number;
// decompile minimally
Expand Down
2 changes: 1 addition & 1 deletion test/script.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ describe('script', () => {
() => {
const chunks = bscript.decompile(Buffer.from(f.script, 'hex'));

assert.deepStrictEqual(chunks, []);
assert.strictEqual(chunks, null);
},
);
});
Expand Down
7 changes: 4 additions & 3 deletions ts_src/payments/embed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,16 @@ export function p2data(a: Payment, opts?: PaymentOpts): Payment {
});
lazy.prop(o, 'data', () => {
if (!a.output) return;
return bscript.decompile(a.output).slice(1);
return bscript.decompile(a.output)!.slice(1);
});

// extended validation
if (opts.validate) {
if (a.output) {
const chunks = bscript.decompile(a.output);
if (chunks[0] !== OPS.OP_RETURN) throw new TypeError('Output is invalid');
if (!chunks.slice(1).every(typef.Buffer))
if (chunks![0] !== OPS.OP_RETURN)
throw new TypeError('Output is invalid');
if (!chunks!.slice(1).every(typef.Buffer))
throw new TypeError('Output is invalid');

if (a.data && !stacksEqual(a.data, o.data as Buffer[]))
Expand Down
4 changes: 2 additions & 2 deletions ts_src/payments/p2ms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export function p2ms(a: Payment, opts?: PaymentOpts): Payment {
function decode(output: Buffer | Stack): void {
if (decoded) return;
decoded = true;
chunks = bscript.decompile(output);
chunks = bscript.decompile(output) as Stack;
o.m = (chunks[0] as number) - OP_INT_BASE;
o.n = (chunks[chunks.length - 2] as number) - OP_INT_BASE;
o.pubkeys = chunks.slice(1, -2) as Buffer[];
Expand Down Expand Up @@ -90,7 +90,7 @@ export function p2ms(a: Payment, opts?: PaymentOpts): Payment {
});
lazy.prop(o, 'signatures', () => {
if (!a.input) return;
return bscript.decompile(a.input).slice(1);
return bscript.decompile(a.input)!.slice(1);
});
lazy.prop(o, 'input', () => {
if (!a.signatures) return;
Expand Down
9 changes: 6 additions & 3 deletions ts_src/payments/p2sh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,10 @@ export function p2sh(a: Payment, opts?: PaymentOpts): Payment {
lazy.prop(o, 'input', () => {
if (!a.redeem || !a.redeem.input || !a.redeem.output) return;
return bscript.compile(
([] as Stack).concat(bscript.decompile(a.redeem.input), a.redeem.output),
([] as Stack).concat(
bscript.decompile(a.redeem.input) as Stack,
a.redeem.output,
),
);
});
lazy.prop(o, 'witness', () => {
Expand Down Expand Up @@ -154,7 +157,7 @@ export function p2sh(a: Payment, opts?: PaymentOpts): Payment {
// is the redeem output empty/invalid?
if (redeem.output) {
const decompile = bscript.decompile(redeem.output);
if (decompile.length < 1)
if (!decompile || decompile.length < 1)
throw new TypeError('Redeem.output too short');
if (redeem.output.byteLength > 520)
throw new TypeError(
Expand All @@ -179,7 +182,7 @@ export function p2sh(a: Payment, opts?: PaymentOpts): Payment {
if (hasInput && hasWitness)
throw new TypeError('Input and witness provided');
if (hasInput) {
const richunks = bscript.decompile(redeem.input);
const richunks = bscript.decompile(redeem.input) as Stack;
if (!bscript.isPushOnly(richunks))
throw new TypeError('Non push-only scriptSig');
}
Expand Down
2 changes: 1 addition & 1 deletion ts_src/payments/p2tr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ export function p2tr(a: Payment, opts?: PaymentOpts): Payment {
}

if (a.redeem.output) {
if (!bscript.decompile(a.redeem.output).length)
if (bscript.decompile(a.redeem.output)!.length === 0)
throw new TypeError('Redeem.output is invalid');

// output redeem is constructed from the witness
Expand Down
9 changes: 6 additions & 3 deletions ts_src/payments/p2wsh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,8 @@ export function p2wsh(a: Payment, opts?: PaymentOpts): Payment {
// is the redeem output non-empty/valid?
if (a.redeem.output) {
const decompile = bscript.decompile(a.redeem.output);
if (!decompile.length) throw new TypeError('Redeem.output is invalid');
if (!decompile || decompile.length < 1)
throw new TypeError('Redeem.output is invalid');
if (a.redeem.output.byteLength > 3600)
throw new TypeError(
'Redeem.output unspendable if larger than 3600 bytes',
Expand Down Expand Up @@ -211,7 +212,9 @@ export function p2wsh(a: Payment, opts?: PaymentOpts): Payment {
if (
(a.redeem.input && _rchunks().some(chunkHasUncompressedPubkey)) ||
(a.redeem.output &&
bscript.decompile(a.redeem.output).some(chunkHasUncompressedPubkey))
(bscript.decompile(a.redeem.output) || []).some(
chunkHasUncompressedPubkey,
))
) {
throw new TypeError(
'redeem.input or redeem.output contains uncompressed pubkey',
Expand All @@ -225,7 +228,7 @@ export function p2wsh(a: Payment, opts?: PaymentOpts): Payment {
throw new TypeError('Witness and redeem.output mismatch');
if (
a.witness.some(chunkHasUncompressedPubkey) ||
bscript.decompile(wScript).some(chunkHasUncompressedPubkey)
(bscript.decompile(wScript) || []).some(chunkHasUncompressedPubkey)
)
throw new TypeError('Witness contains uncompressed pubkey');
}
Expand Down
6 changes: 3 additions & 3 deletions ts_src/psbt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2148,7 +2148,7 @@ function redeemFromFinalScriptSig(
): Buffer | undefined {
if (!finalScript) return;
const decomp = bscript.decompile(finalScript);
if (!decomp.length) return;
if (!decomp) return;
const lastItem = decomp[decomp.length - 1];
if (
!Buffer.isBuffer(lastItem) ||
Expand All @@ -2157,7 +2157,7 @@ function redeemFromFinalScriptSig(
)
return;
const sDecomp = bscript.decompile(lastItem);
if (!sDecomp.length) return;
if (!sDecomp) return;
return lastItem;
}

Expand All @@ -2169,7 +2169,7 @@ function redeemFromFinalWitnessScript(
const lastItem = decomp[decomp.length - 1];
if (isPubkeyLike(lastItem)) return;
const sDecomp = bscript.decompile(lastItem);
if (!sDecomp.length) return;
if (!sDecomp) return;
return lastItem;
}

Expand Down
6 changes: 3 additions & 3 deletions ts_src/psbt/psbtutils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export function pubkeyPositionInScript(pubkey: Buffer, script: Buffer): number {
const pubkeyXOnly = pubkey.slice(1, 33); // slice before calling?

const decompiled = bscript.decompile(script);
if (!decompiled.length) throw new Error('Unknown script error');
if (decompiled === null) throw new Error('Unknown script error');

return decompiled.findIndex(element => {
if (typeof element === 'number') return false;
Expand Down Expand Up @@ -178,10 +178,10 @@ function extractPartialSigs(input: PsbtInput): Buffer[] {
function getPsigsFromInputFinalScripts(input: PsbtInput): PartialSig[] {
const scriptItems = !input.finalScriptSig
? []
: bscript.decompile(input.finalScriptSig);
: bscript.decompile(input.finalScriptSig) || [];
const witnessItems = !input.finalScriptWitness
? []
: bscript.decompile(input.finalScriptWitness);
: bscript.decompile(input.finalScriptWitness) || [];
return scriptItems
.concat(witnessItems)
.filter(item => {
Expand Down
13 changes: 8 additions & 5 deletions ts_src/script.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,10 @@ export function compile(chunks: Buffer | Stack): Buffer {
return buffer;
}

export function decompile(buffer: Buffer | Array<number | Buffer>): Stack {
export function decompile(
buffer: Buffer | Array<number | Buffer>,
): Array<number | Buffer> | null {
// TODO: remove me
if (chunksIsArray(buffer)) return buffer;

typeforce(types.Buffer, buffer);
Expand All @@ -127,11 +130,11 @@ export function decompile(buffer: Buffer | Array<number | Buffer>): Stack {
const d = pushdata.decode(buffer, i);

// did reading a pushDataInt fail?
if (d === null) return [];
if (d === null) return null;
i += d.size;

// attempt to read too much data?
if (i + d.number > buffer.length) return [];
if (i + d.number > buffer.length) return null;

const data = buffer.slice(i, i + d.number);
i += d.number;
Expand Down Expand Up @@ -163,7 +166,7 @@ export function decompile(buffer: Buffer | Array<number | Buffer>): Stack {
*/
export function toASM(chunks: Buffer | Array<number | Buffer>): string {
if (chunksIsBuffer(chunks)) {
chunks = decompile(chunks);
chunks = decompile(chunks) as Stack;
}

return chunks
Expand Down Expand Up @@ -208,7 +211,7 @@ export function fromASM(asm: string): Buffer {
* @returns The stack of buffers.
*/
export function toStack(chunks: Buffer | Array<number | Buffer>): Buffer[] {
chunks = decompile(chunks);
chunks = decompile(chunks) as Stack;
typeforce(isPushOnly, chunks);

return chunks.map(op => {
Expand Down
2 changes: 1 addition & 1 deletion ts_src/transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ export class Transaction {

// ignore OP_CODESEPARATOR
const ourScript = bscript.compile(
bscript.decompile(prevOutScript).filter(x => {
bscript.decompile(prevOutScript)!.filter(x => {
return x !== opcodes.OP_CODESEPARATOR;
}),
);
Expand Down

0 comments on commit ac6a5b2

Please sign in to comment.