Skip to content

Commit 0f5c86c

Browse files
OttoAllmendingerllm-git
andcommitted
feat(abstract-utxo): add wasm-utxo decoding support to test suite
Add test scenarios that verify wasm-utxo as a transaction decoding backend. Rework test suite structure for better readability and clearer test naming. Skip tests for networks not supported by wasm-utxo. Issue: BTC-2806 Co-authored-by: llm-git <[email protected]>
1 parent c78c2f2 commit 0f5c86c

File tree

2 files changed

+53
-39
lines changed

2 files changed

+53
-39
lines changed

modules/abstract-utxo/test/unit/transaction.ts

Lines changed: 52 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ import {
1414
} from '@bitgo/sdk-core';
1515

1616
import { AbstractUtxoCoin, getReplayProtectionAddresses, generateAddress } from '../../src';
17+
import { SdkBackend } from '../../src/transaction/types';
1718

19+
import { hasWasmUtxoSupport } from './transaction/fixedScript/util';
1820
import {
1921
utxoCoins,
2022
shouldEqualJSON,
@@ -271,11 +273,16 @@ function run<TNumber extends number | bigint = number>(
271273
coin: AbstractUtxoCoin,
272274
inputScripts: testutil.InputScriptType[],
273275
txFormat: 'legacy' | 'psbt',
274-
amountType: 'number' | 'bigint' = 'number'
276+
{ decodeWith }: { decodeWith?: SdkBackend } = {}
275277
) {
276-
describe(`Transaction Stages ${coin.getChain()} (${amountType}) scripts=${inputScripts.join(
277-
','
278-
)} txFormat=${txFormat}`, function () {
278+
const amountType = coin.amountType;
279+
const title = [
280+
inputScripts.join(','),
281+
`txFormat=${txFormat}`,
282+
`amountType=${amountType}`,
283+
decodeWith ? `decodeWith=${decodeWith}` : '',
284+
];
285+
describe(`${title.join(' ')}`, function () {
279286
const bgUrl = common.Environments[defaultBitGo.getEnv()].uri;
280287

281288
const isTransactionWithKeyPathSpend = inputScripts.some((s) => s === 'taprootKeyPathSpend');
@@ -319,7 +326,8 @@ function run<TNumber extends number | bigint = number>(
319326
function getSignParams(
320327
prebuildHex: string,
321328
signer: BIP32Interface,
322-
cosigner: BIP32Interface
329+
cosigner: BIP32Interface,
330+
decodeWith: SdkBackend | undefined
323331
): WalletSignTransactionOptions {
324332
const txInfo = {
325333
unspents: txFormat === 'psbt' ? undefined : getUnspents(),
@@ -329,6 +337,7 @@ function run<TNumber extends number | bigint = number>(
329337
walletId: isTransactionWithKeyPathSpend ? wallet.id() : undefined,
330338
txHex: prebuildHex,
331339
txInfo,
340+
decodeWith,
332341
},
333342
prv: signer.toBase58(),
334343
pubs: walletKeys.triple.map((k) => k.neutered().toBase58()),
@@ -351,7 +360,7 @@ function run<TNumber extends number | bigint = number>(
351360

352361
// half-sign with the user key
353362
const result = (await wallet.signTransaction(
354-
getSignParams(prebuild.toBuffer().toString('hex'), signer, cosigner)
363+
getSignParams(prebuild.toBuffer().toString('hex'), signer, cosigner, decodeWith)
355364
)) as Promise<HalfSignedUtxoTransaction>;
356365

357366
if (scope) {
@@ -367,7 +376,7 @@ function run<TNumber extends number | bigint = number>(
367376
cosigner: BIP32Interface
368377
): Promise<FullySignedTransaction> {
369378
return (await wallet.signTransaction({
370-
...getSignParams(halfSigned.txHex, signer, cosigner),
379+
...getSignParams(halfSigned.txHex, signer, cosigner, decodeWith),
371380
isLastSignature: true,
372381
})) as FullySignedTransaction;
373382
}
@@ -533,27 +542,25 @@ function run<TNumber extends number | bigint = number>(
533542
async function testExplainTx(
534543
stageName: string,
535544
txHex: string,
536-
unspents?: utxolib.bitgo.Unspent<TNumber>[],
537-
pubs?: Triple<string>
545+
unspents: utxolib.bitgo.Unspent<TNumber>[],
546+
pubs: Triple<string> | undefined
538547
): Promise<void> {
539548
const explanation = await coin.explainTransaction<TNumber>({
540549
txHex,
541550
txInfo: {
542551
unspents,
543552
},
544553
pubs,
554+
decodeWith,
545555
});
546556

547-
explanation.should.have.properties(
548-
'displayOrder',
549-
'id',
550-
'outputs',
551-
'changeOutputs',
552-
'changeAmount',
553-
'outputAmount',
554-
'inputSignatures',
555-
'signatures'
556-
);
557+
const expectedProperties = ['id', 'outputs', 'changeOutputs', 'changeAmount', 'outputAmount'];
558+
559+
if (decodeWith !== 'wasm-utxo') {
560+
expectedProperties.push('displayOrder', 'inputSignatures', 'signatures');
561+
}
562+
563+
explanation.should.have.properties(...expectedProperties);
557564

558565
const expectedSignatureCount =
559566
stageName === 'prebuild' || pubs === undefined
@@ -623,38 +630,44 @@ function run<TNumber extends number | bigint = number>(
623630
? getUnspentsForPsbt().map((u) => ({ ...u, value: bitgo.toTNumber(u.value, amountType) as TNumber }))
624631
: getUnspents();
625632
await testExplainTx(stageName, txHex, unspents, pubs);
626-
await testExplainTx(stageName, txHex, unspents);
633+
if (decodeWith !== 'wasm-utxo') {
634+
await testExplainTx(stageName, txHex, unspents, undefined);
635+
}
627636
}
628637
});
629638
});
630639
}
631640

632-
function runWithAmountType(
633-
coin: AbstractUtxoCoin,
634-
inputScripts: testutil.InputScriptType[],
635-
txFormat: 'legacy' | 'psbt'
636-
) {
637-
const amountType = coin.amountType;
638-
if (amountType === 'bigint') {
639-
run<bigint>(coin, inputScripts, txFormat, amountType);
640-
} else {
641-
run(coin, inputScripts, txFormat, amountType);
642-
}
643-
}
644-
645-
utxoCoins.forEach((coin) =>
641+
function runTestForCoin(coin: AbstractUtxoCoin) {
646642
getScriptTypes2Of3().forEach((type) => {
647643
(['legacy', 'psbt'] as const).forEach((txFormat) => {
644+
if (!coin.supportsAddressType(type === 'taprootKeyPathSpend' ? 'p2trMusig2' : type)) {
645+
return;
646+
}
647+
648648
if ((type === 'taprootKeyPathSpend' || type === 'p2trMusig2') && txFormat !== 'psbt') {
649649
return;
650650
}
651-
if (coin.supportsAddressType(type === 'taprootKeyPathSpend' ? 'p2trMusig2' : type)) {
652-
runWithAmountType(coin, [type, type], txFormat);
653651

652+
run(coin, [type, type], txFormat);
653+
if (getReplayProtectionAddresses(coin.network).length) {
654+
run(coin, ['p2shP2pk', type], txFormat);
655+
}
656+
657+
if (txFormat === 'psbt' && hasWasmUtxoSupport(coin.network)) {
658+
run(coin, [type, type], txFormat, { decodeWith: 'wasm-utxo' });
654659
if (getReplayProtectionAddresses(coin.network).length) {
655-
runWithAmountType(coin, ['p2shP2pk', type], txFormat);
660+
run(coin, ['p2shP2pk', type], txFormat, { decodeWith: 'wasm-utxo' });
656661
}
657662
}
658663
});
659-
})
660-
);
664+
});
665+
}
666+
667+
describe('Transaction Suite', function () {
668+
utxoCoins.forEach((coin) => {
669+
describe(`${coin.getChain()}`, function () {
670+
runTestForCoin(coin);
671+
});
672+
});
673+
});

modules/abstract-utxo/test/unit/transaction/fixedScript/util.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export function hasWasmUtxoSupport(network: utxolib.Network): boolean {
44
return ![
55
utxolib.networks.bitcoincash,
66
utxolib.networks.bitcoingold,
7+
utxolib.networks.bitcoinsv,
78
utxolib.networks.ecash,
89
utxolib.networks.zcash,
910
].includes(utxolib.getMainnet(network));

0 commit comments

Comments
 (0)