Skip to content

Commit 2f86ad6

Browse files
committed
Expand signing serialization VMB tests
1 parent 7c7e74d commit 2f86ad6

19 files changed

Lines changed: 7245 additions & 1021 deletions

src/lib/vmb-tests/bch-vmb-test-utils.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -758,7 +758,15 @@ export const vmbTestDefinitionToVmbTests = (
758758
const scenarioDefinition = { extends: 'vmb_default', ...scenarioOverride };
759759

760760
const configuration = walletTemplateToCompilerConfiguration({
761-
entities: { tester: { variables: { key1: { type: 'HdKey' } } } },
761+
entities: {
762+
tester: {
763+
variables: {
764+
key1: { type: 'HdKey' },
765+
key2: { privateDerivationPath: 'm/2/i', type: 'HdKey' },
766+
key3: { privateDerivationPath: 'm/3/i', type: 'HdKey' },
767+
},
768+
},
769+
},
762770
scenarios: {
763771
[scenarioId]: scenarioDefinition,
764772
// eslint-disable-next-line @typescript-eslint/naming-convention, camelcase

src/lib/vmb-tests/bch-vmb-tests.signing-serialization.ts

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,18 @@ const algorithms = [
2121
'no_outputs',
2222
] as const;
2323

24+
const signatureTypes = [
25+
['schnorr signature', 'schnorr_signature'],
26+
['ECDSA signature', 'signature'],
27+
] as const;
28+
29+
const opcodePatterns = [
30+
['single sig', 'OP_2DUP OP_CHECKSIG OP_VERIFY OP_2DUP OP_CHECKSIGVERIFY'],
31+
['1-of-1 multisig', 'OP_2DUP OP_0 OP_ROT OP_ROT OP_1 OP_SWAP OP_1 OP_CHECKMULTISIG OP_VERIFY OP_2DUP OP_0 OP_ROT OP_ROT OP_1 OP_SWAP OP_1 OP_CHECKMULTISIGVERIFY'],
32+
['1-of-2 multisig (second key)', 'OP_2DUP <0> OP_ROT OP_ROT <1> OP_SWAP <key2.public_key> OP_SWAP <2> OP_CHECKMULTISIG OP_VERIFY OP_2DUP <0> OP_ROT OP_ROT <1> OP_SWAP <key2.public_key> OP_SWAP <2> OP_CHECKMULTISIGVERIFY'],
33+
['1-of-3 multisig (middle key)', 'OP_2DUP <0> OP_ROT OP_ROT <1> OP_SWAP <key2.public_key> OP_SWAP <key3.public_key> <3> OP_CHECKMULTISIG OP_VERIFY OP_2DUP <0> OP_ROT OP_ROT <1> OP_SWAP <key2.public_key> OP_SWAP <key3.public_key> <3> OP_CHECKMULTISIGVERIFY'],
34+
] as const;
35+
2436
/* eslint-disable @typescript-eslint/naming-convention, camelcase */
2537
const akaMap: { [key in (typeof algorithms)[number]]: string } = {
2638
all_outputs: 'SIGHASH_ALL|SIGHASH_FORKID',
@@ -38,15 +50,22 @@ const akaMap: { [key in (typeof algorithms)[number]]: string } = {
3850
};
3951
/* eslint-enable @typescript-eslint/naming-convention, camelcase */
4052

41-
const verifyAlgorithm = algorithms.map<VmbTestDefinition>((algorithm) => [
42-
`<signing_serialization.full_${algorithm}> <key1.schnorr_signature.${algorithm}>`,
43-
'<key1.public_key> OP_2DUP OP_CHECKSIGVERIFY OP_SWAP OP_SIZE <1> OP_SUB OP_SPLIT OP_DROP OP_ROT OP_SHA256 OP_ROT OP_CHECKDATASIG',
44-
`verify algorithm - ${algorithm} (${akaMap[algorithm]})`,
45-
algorithm.includes('all_utxos') ? (algorithm.includes('INVALID') ? ['chip_cashtokens_invalid'] : ['chip_cashtokens']) : ['default', 'chip_cashtokens'],
53+
// TODO: implement and verify schnorr multisig
54+
const combinatorial = algorithms.flatMap((algorithm) => signatureTypes.flatMap((signatureType) => opcodePatterns.flatMap((pattern) => [true, false].map((valid) => [algorithm, signatureType, pattern, valid] as const)))).filter(([_, signatureType, pattern]) => signatureType !== signatureTypes[0] || pattern === opcodePatterns[0]);
55+
56+
// eslint-disable-next-line complexity
57+
const verifyAlgorithm = combinatorial.map<VmbTestDefinition>(([algorithm, signatureType, pattern, valid]) => [
58+
`<signing_serialization.full_${algorithm}> <${valid ? 'key1' : 'key2'}.${signatureType[1]}.${algorithm}>`,
59+
`<key1.public_key> ${pattern[1]} OP_SWAP OP_SIZE <1> OP_SUB OP_SPLIT OP_DROP OP_ROT OP_SHA256 OP_ROT OP_3DUP OP_CHECKDATASIGVERIFY OP_CHECKDATASIG`,
60+
`verify algorithm - ${algorithm} (${akaMap[algorithm]}), ${signatureType[0]}, ${pattern[0]}, ${valid ? 'valid' : 'check failure'}`,
61+
valid ? (algorithm.includes('all_utxos') ? (algorithm.includes('INVALID') ? ['chip_cashtokens_invalid'] : ['chip_cashtokens']) : ['default', 'chip_cashtokens']) : ['invalid'],
4662
{ sourceOutputs: [{ lockingBytecode: ['slot'], valueSatoshis: 10_000 }], transaction: { inputs: [{ unlockingBytecode: ['slot'] }], outputs: [{ lockingBytecode: { script: 'vmbTestNullData' }, valueSatoshis: 0 }] } },
4763
]);
4864

49-
const changeScenario = (testDefinitions: VmbTestDefinition[], appendDescription: string, newScenario: WalletTemplateScenario) => testDefinitions.map<VmbTestDefinition>(([unlockingScript, redeemOrLockingScript, testDescription, testSetOverrideLabels]) => [unlockingScript, redeemOrLockingScript, `${testDescription}${appendDescription}`, testSetOverrideLabels, newScenario]);
65+
// eslint-disable-next-line @typescript-eslint/max-params
66+
const changeScenario = (testDefinitions: VmbTestDefinition[], appendDescription: string, newScenario: WalletTemplateScenario, labelChanger: (labels: NonNullable<VmbTestDefinition['3']>) => NonNullable<VmbTestDefinition['3']> = (labels) => labels) =>
67+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
68+
testDefinitions.map<VmbTestDefinition>(([unlockingScript, redeemOrLockingScript, testDescription, testSetOverrideLabels]) => [unlockingScript, redeemOrLockingScript, `${testDescription}${appendDescription}`, labelChanger(testSetOverrideLabels!), newScenario]);
5069

5170
const verifyAlgorithmWithP2pkhInput = changeScenario(verifyAlgorithm, ' (with P2PKH input)', { sourceOutputs: [simpleP2pkhOutput, { lockingBytecode: ['slot'], valueSatoshis: 10_000 }], transaction: { inputs: [simpleP2pkhInput, { unlockingBytecode: ['slot'] }], outputs: [{ lockingBytecode: { script: 'vmbTestNullData' }, valueSatoshis: 0 }] } });
5271

@@ -77,11 +96,9 @@ const verifyAlgorithmWithMultipleInputsAndOutputs = changeScenario(verifyAlgorit
7796
},
7897
});
7998

80-
const verifyAlgorithmWithTokensInMultipleInputsAndOutputs = algorithms.map<VmbTestDefinition>((algorithm) => [
81-
`<signing_serialization.full_${algorithm}> <key1.schnorr_signature.${algorithm}>`,
82-
'<key1.public_key> OP_2DUP OP_CHECKSIGVERIFY OP_SWAP OP_SIZE <1> OP_SUB OP_SPLIT OP_DROP OP_ROT OP_SHA256 OP_ROT OP_CHECKDATASIG',
83-
`verify algorithm - ${algorithm} (${akaMap[algorithm]}) (with all token types in multiple inputs and outputs)`,
84-
algorithm.includes('all_utxos') ? (algorithm.includes('INVALID') ? ['chip_cashtokens_invalid'] : ['chip_cashtokens']) : ['invalid', 'chip_cashtokens'],
99+
const verifyAlgorithmWithTokensInMultipleInputsAndOutputs = changeScenario(
100+
verifyAlgorithm,
101+
' (with all token types in multiple inputs and outputs)',
85102
{
86103
sourceOutputs: [
87104
{ ...simpleP2pkhOutput, token: { category: '0000000000000000000000000000000000000000000000000000000000000003', nft: { capability: 'minting' } } },
@@ -101,7 +118,8 @@ const verifyAlgorithmWithTokensInMultipleInputsAndOutputs = algorithms.map<VmbTe
101118
],
102119
},
103120
},
104-
]);
121+
(labels) => (labels[0] === 'default' ? ['invalid', 'chip_cashtokens'] : labels),
122+
);
105123

106124
export const signingSerializationTestDefinitionsBCH: VmbTestDefinitionGroup = [
107125
'Signing serializations',

src/lib/vmb-tests/bch-vmb-tests.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,7 @@ export const vmbTestDefinitionsBCH: VmbTestDefinitionGroup[] = [
419419
],
420420
],
421421
],
422+
['Formatting', [['<0> <520>', 'OP_NUM2BIN OP_HASH256 <520> OP_NUM2BIN OP_HASH256 <0x1ad88784b424b39ad15854e96346fc94f73db487c165f0a9bdd5f348ad4c463c> OP_EQUAL', 'NUM2BIN allows 32-byte number inputs']]],
422423
[
423424
'Transaction inspection',
424425
[

0 commit comments

Comments
 (0)