From 2fddb006cc0b5abf8c45a1c04d0b3b0bed27d1f7 Mon Sep 17 00:00:00 2001 From: Otto Allmendinger Date: Tue, 17 Sep 2024 13:53:02 +0200 Subject: [PATCH] feat: add tests for maxWeightToSatisfy Issue: BTC-1460 --- .../test/fixedScriptToDescriptor.ts | 74 ++++++++++++++++--- 1 file changed, 64 insertions(+), 10 deletions(-) diff --git a/packages/wasm-miniscript/test/fixedScriptToDescriptor.ts b/packages/wasm-miniscript/test/fixedScriptToDescriptor.ts index 22cabe2..b3abeb9 100644 --- a/packages/wasm-miniscript/test/fixedScriptToDescriptor.ts +++ b/packages/wasm-miniscript/test/fixedScriptToDescriptor.ts @@ -8,6 +8,48 @@ const scriptTypes = ["p2sh", "p2shP2wsh", "p2wsh"] as const; const scope = ["external", "internal"] as const; const index = [0, 1, 2]; +/** Get the expected max weight to satisfy the descriptor */ +function getExpectedMaxWeightToSatisfy(scriptType: utxolib.bitgo.outputScripts.ScriptType2Of3) { + switch (scriptType) { + case "p2sh": + return 256; + case "p2shP2wsh": + return 99; + case "p2wsh": + return 64; + default: + throw new Error("unexpected script type"); + } +} + +/** Compute the total size of the input, including overhead */ +function getTotalInputSize(vSize: number) { + const sizeOpPushData1 = 1; + const sizeOpPushData2 = 2; + return ( + 32 /* txid */ + + 4 /* vout */ + + 4 /* nSequence */ + + (vSize < 255 ? sizeOpPushData1 : sizeOpPushData2) + + vSize + ); +} + +/** Get the full expected vSize of the input including overhead */ +function getExpectedVSize(scriptType: utxolib.bitgo.outputScripts.ScriptType2Of3) { + // https://github.com/BitGo/BitGoJS/blob/master/modules/unspents/docs/input-costs.md + switch (scriptType) { + case "p2sh": + return 298; + case "p2shP2wsh": + return 140; + case "p2wsh": + return 105; + default: + throw new Error("unexpected script type"); + } +} + function runTest( scriptType: utxolib.bitgo.outputScripts.ScriptType2Of3, index: number, @@ -24,11 +66,16 @@ function runTest( scriptType, ).scriptPubKey; - it("descriptor should have expected format", function () { - const descriptor = Descriptor.fromString( + let descriptor: Descriptor; + + before(function () { + descriptor = Descriptor.fromString( getDescriptorForScriptType(rootWalletKeys, scriptType, scope), "derivable", ); + }); + + it("descriptor should have expected format", function () { const [x1, x2, x3] = rootWalletKeys.triple.map((xpub) => xpub.neutered().toBase58()); if (scriptType === "p2sh" && scope === "external") { // spot check @@ -49,16 +96,23 @@ function runTest( }); it("address should match descriptor", function () { - const scriptFromDescriptor = Buffer.from( - Descriptor.fromString( - getDescriptorForScriptType(rootWalletKeys, scriptType, scope), - "derivable", - ) - .atDerivationIndex(index) - .scriptPubkey(), - ); + const scriptFromDescriptor = Buffer.from(descriptor.atDerivationIndex(index).scriptPubkey()); assert.deepStrictEqual(scriptUtxolib.toString("hex"), scriptFromDescriptor.toString("hex")); }); + + it("should have expected weights", function () { + assert.ok(Number.isInteger(descriptor.maxWeightToSatisfy())); + const vSize = Math.ceil(descriptor.maxWeightToSatisfy() / 4); + console.log( + scriptType, + "scriptLength", + descriptor.atDerivationIndex(0).encode().length, + "vSize", + vSize, + ); + assert.equal(vSize, getExpectedMaxWeightToSatisfy(scriptType)); + assert.equal(getTotalInputSize(vSize), getExpectedVSize(scriptType)); + }); }); }