Skip to content

Commit

Permalink
Expand signing serialization VMB tests
Browse files Browse the repository at this point in the history
  • Loading branch information
bitjson committed Feb 12, 2024
1 parent 7c7e74d commit 2f86ad6
Show file tree
Hide file tree
Showing 19 changed files with 7,245 additions and 1,021 deletions.
10 changes: 9 additions & 1 deletion src/lib/vmb-tests/bch-vmb-test-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -758,7 +758,15 @@ export const vmbTestDefinitionToVmbTests = (
const scenarioDefinition = { extends: 'vmb_default', ...scenarioOverride };

const configuration = walletTemplateToCompilerConfiguration({
entities: { tester: { variables: { key1: { type: 'HdKey' } } } },
entities: {
tester: {
variables: {
key1: { type: 'HdKey' },
key2: { privateDerivationPath: 'm/2/i', type: 'HdKey' },
key3: { privateDerivationPath: 'm/3/i', type: 'HdKey' },
},
},
},
scenarios: {
[scenarioId]: scenarioDefinition,
// eslint-disable-next-line @typescript-eslint/naming-convention, camelcase
Expand Down
42 changes: 30 additions & 12 deletions src/lib/vmb-tests/bch-vmb-tests.signing-serialization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,18 @@ const algorithms = [
'no_outputs',
] as const;

const signatureTypes = [
['schnorr signature', 'schnorr_signature'],
['ECDSA signature', 'signature'],
] as const;

const opcodePatterns = [
['single sig', 'OP_2DUP OP_CHECKSIG OP_VERIFY OP_2DUP OP_CHECKSIGVERIFY'],
['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'],
['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'],
['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'],
] as const;

/* eslint-disable @typescript-eslint/naming-convention, camelcase */
const akaMap: { [key in (typeof algorithms)[number]]: string } = {
all_outputs: 'SIGHASH_ALL|SIGHASH_FORKID',
Expand All @@ -38,15 +50,22 @@ const akaMap: { [key in (typeof algorithms)[number]]: string } = {
};
/* eslint-enable @typescript-eslint/naming-convention, camelcase */

const verifyAlgorithm = algorithms.map<VmbTestDefinition>((algorithm) => [
`<signing_serialization.full_${algorithm}> <key1.schnorr_signature.${algorithm}>`,
'<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',
`verify algorithm - ${algorithm} (${akaMap[algorithm]})`,
algorithm.includes('all_utxos') ? (algorithm.includes('INVALID') ? ['chip_cashtokens_invalid'] : ['chip_cashtokens']) : ['default', 'chip_cashtokens'],
// TODO: implement and verify schnorr multisig
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]);

// eslint-disable-next-line complexity
const verifyAlgorithm = combinatorial.map<VmbTestDefinition>(([algorithm, signatureType, pattern, valid]) => [
`<signing_serialization.full_${algorithm}> <${valid ? 'key1' : 'key2'}.${signatureType[1]}.${algorithm}>`,
`<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`,
`verify algorithm - ${algorithm} (${akaMap[algorithm]}), ${signatureType[0]}, ${pattern[0]}, ${valid ? 'valid' : 'check failure'}`,
valid ? (algorithm.includes('all_utxos') ? (algorithm.includes('INVALID') ? ['chip_cashtokens_invalid'] : ['chip_cashtokens']) : ['default', 'chip_cashtokens']) : ['invalid'],
{ sourceOutputs: [{ lockingBytecode: ['slot'], valueSatoshis: 10_000 }], transaction: { inputs: [{ unlockingBytecode: ['slot'] }], outputs: [{ lockingBytecode: { script: 'vmbTestNullData' }, valueSatoshis: 0 }] } },
]);

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

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 }] } });

Expand Down Expand Up @@ -77,11 +96,9 @@ const verifyAlgorithmWithMultipleInputsAndOutputs = changeScenario(verifyAlgorit
},
});

const verifyAlgorithmWithTokensInMultipleInputsAndOutputs = algorithms.map<VmbTestDefinition>((algorithm) => [
`<signing_serialization.full_${algorithm}> <key1.schnorr_signature.${algorithm}>`,
'<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',
`verify algorithm - ${algorithm} (${akaMap[algorithm]}) (with all token types in multiple inputs and outputs)`,
algorithm.includes('all_utxos') ? (algorithm.includes('INVALID') ? ['chip_cashtokens_invalid'] : ['chip_cashtokens']) : ['invalid', 'chip_cashtokens'],
const verifyAlgorithmWithTokensInMultipleInputsAndOutputs = changeScenario(
verifyAlgorithm,
' (with all token types in multiple inputs and outputs)',
{
sourceOutputs: [
{ ...simpleP2pkhOutput, token: { category: '0000000000000000000000000000000000000000000000000000000000000003', nft: { capability: 'minting' } } },
Expand All @@ -101,7 +118,8 @@ const verifyAlgorithmWithTokensInMultipleInputsAndOutputs = algorithms.map<VmbTe
],
},
},
]);
(labels) => (labels[0] === 'default' ? ['invalid', 'chip_cashtokens'] : labels),
);

export const signingSerializationTestDefinitionsBCH: VmbTestDefinitionGroup = [
'Signing serializations',
Expand Down
1 change: 1 addition & 0 deletions src/lib/vmb-tests/bch-vmb-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,7 @@ export const vmbTestDefinitionsBCH: VmbTestDefinitionGroup[] = [
],
],
],
['Formatting', [['<0> <520>', 'OP_NUM2BIN OP_HASH256 <520> OP_NUM2BIN OP_HASH256 <0x1ad88784b424b39ad15854e96346fc94f73db487c165f0a9bdd5f348ad4c463c> OP_EQUAL', 'NUM2BIN allows 32-byte number inputs']]],
[
'Transaction inspection',
[
Expand Down
Loading

0 comments on commit 2f86ad6

Please sign in to comment.