Skip to content

Commit c0eadac

Browse files
committed
Run VMB benchmarks in CI
1 parent 18e1614 commit c0eadac

18 files changed

+80
-47
lines changed

.changeset/nervous-carrots-punch.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@bitauth/libauth': patch
3+
---
4+
5+
Run VMB benchmarks in CI

.github/workflows/ci.yml

+19-2
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,32 @@ jobs:
2626
CI_NODE_INDEX: ${{ matrix.runner_index }}
2727
CI_NODE_TOTAL: ${{ matrix.runners_per_version }}
2828
- run: yarn cov:lcov
29-
if: ${{ matrix.node-version }} == 20
29+
if: ${{ matrix.node-version == 20 }}
3030
- name: Upload test coverage
31-
if: ${{ matrix.node-version }} == 20
31+
if: ${{ matrix.node-version == 20 }}
3232
uses: codecov/codecov-action@v4
3333
with:
3434
fail_ci_if_error: true
3535
token: ${{ secrets.CODECOV_TOKEN }}
3636
verbose: true
3737

38+
vmb-benchmarks:
39+
runs-on: ubuntu-latest
40+
strategy:
41+
fail-fast: false
42+
name: Run VMB Benchmarks
43+
steps:
44+
- uses: actions/checkout@v4
45+
with:
46+
submodules: 'recursive'
47+
- name: Install Node.js
48+
uses: actions/setup-node@v4
49+
with:
50+
node-version: '20'
51+
- run: yarn install --immutable --immutable-cache
52+
- run: yarn build
53+
- run: yarn bench:vmb_tests
54+
3855
check-policies:
3956
runs-on: ubuntu-latest
4057
name: Check Policies

config/.ava.vmb_bench.config.js

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
export default {
2+
files: ['src/lib/vmb-tests/benchmark-bch-vmb-tests.spec.ts'],
3+
typescript: {
4+
compile: false,
5+
rewritePaths: {
6+
'src/': 'build/',
7+
},
8+
},
9+
};

package.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171
"test:unit:vmb_tests": "c8 ava src/lib/vmb-tests/bch-vmb-tests.spec.ts --serial",
7272
"test:unit:vmb_test": "node --enable-source-maps 'build/lib/vmb-tests/run-bch-vmb-test.spec.helper.js'",
7373
"dev:vmb_tests": "yarn gen:vmb_tests && yarn build:tsc && ava src/lib/vmb-tests/bch-vmb-tests.spec.ts --serial --fail-fast",
74-
"bench:vmb_tests": "ava src/lib/vmb-tests/benchmark-bch-vmb-tests.spec.ts --serial",
74+
"bench:vmb_tests": "ava --config config/.ava.vmb_bench.config.js src/lib/vmb-tests/benchmark-bch-vmb-tests.spec.ts --serial",
7575
"bench": "yarn build && yarn bench:browser-deps && yarn bench:vmb_tests && yarn bench:test",
7676
"bench:test": "ava --config config/.ava.bench.config.js --serial --timeout=2m 2>&1 | tee bench.log",
7777
"bench:browser-deps": "cpy '.yarn/artifacts/*.js' build/bench",
@@ -167,7 +167,8 @@
167167
"--experimental-json-modules",
168168
"--experimental-global-webcrypto",
169169
"# ^ needed for node v18"
170-
]
170+
],
171+
"files": ["!src/lib/vmb-tests/benchmark-bch-vmb-tests.spec.ts"]
171172
},
172173
"config": {
173174
"commitizen": {

src/lib/address/base58-address.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ import {
1515
} from '../lib.js';
1616

1717
// eslint-disable-next-line import/no-restricted-paths, import/no-internal-modules
18-
import keyIoInvalid from './fixtures/key_io_invalid.json' assert { type: 'json' };
18+
import keyIoInvalid from './fixtures/key_io_invalid.json' with { type: 'json' };
1919
// eslint-disable-next-line import/no-restricted-paths, import/no-internal-modules
20-
import keyIoValid from './fixtures/key_io_valid.json' assert { type: 'json' };
20+
import keyIoValid from './fixtures/key_io_valid.json' with { type: 'json' };
2121

2222
import { fc, testProp } from '@fast-check/ava';
2323

src/lib/address/cash-address.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import {
3131
} from '../lib.js';
3232

3333
// eslint-disable-next-line import/no-restricted-paths, import/no-internal-modules
34-
import cashAddrJson from './fixtures/cashaddr.json' assert { type: 'json' };
34+
import cashAddrJson from './fixtures/cashaddr.json' with { type: 'json' };
3535

3636
import fc from 'fast-check';
3737

src/lib/format/base-convert.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
} from '../lib.js';
1414

1515
// eslint-disable-next-line import/no-restricted-paths, import/no-internal-modules
16-
import base58Json from './fixtures/base58_encode_decode.json' assert { type: 'json' };
16+
import base58Json from './fixtures/base58_encode_decode.json' with { type: 'json' };
1717

1818
import { fc, testProp } from '@fast-check/ava';
1919

src/lib/key/bip39.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ import {
3535
} from '../lib.js';
3636

3737
// eslint-disable-next-line import/no-restricted-paths, import/no-internal-modules
38-
import bip39ExtendedVectors from './fixtures/bip39.extended-vectors.json' assert { type: 'json' };
38+
import bip39ExtendedVectors from './fixtures/bip39.extended-vectors.json' with { type: 'json' };
3939
// eslint-disable-next-line import/no-restricted-paths, import/no-internal-modules
40-
import bip39TrezorVectorsRaw from './fixtures/bip39.trezor.json' assert { type: 'json' };
40+
import bip39TrezorVectorsRaw from './fixtures/bip39.trezor.json' with { type: 'json' };
4141

4242
import { fc, testProp } from '@fast-check/ava';
4343
import { entropyToMnemonic, mnemonicToSeedSync } from 'bip39';

src/lib/message/transaction-encoding.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ import {
2424
} from '../lib.js';
2525

2626
// eslint-disable-next-line import/no-restricted-paths, import/no-internal-modules
27-
import tokenPrefixInvalidJson from './fixtures/token-prefix-invalid.json' assert { type: 'json' };
27+
import tokenPrefixInvalidJson from './fixtures/token-prefix-invalid.json' with { type: 'json' };
2828
// eslint-disable-next-line import/no-restricted-paths, import/no-internal-modules
29-
import tokenPrefixValidJson from './fixtures/token-prefix-valid.json' assert { type: 'json' };
29+
import tokenPrefixValidJson from './fixtures/token-prefix-valid.json' with { type: 'json' };
3030

3131
test('decodeTransaction', (t) => {
3232
/**

src/lib/transaction/transaction-e2e.spec.helper.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
/* eslint-disable import/no-internal-modules */
2-
import twoOfTwoRecoverableJson from './fixtures/templates/2-of-2-recoverable.json' assert { type: 'json' };
3-
import twoOfThreeJson from './fixtures/templates/2-of-3.json' assert { type: 'json' };
4-
import cashChannelsJson from './fixtures/templates/cash-channels-v1.json' assert { type: 'json' };
5-
import p2pkhJson from './fixtures/templates/p2pkh.json' assert { type: 'json' };
6-
import sigOfSigJson from './fixtures/templates/sig-of-sig.json' assert { type: 'json' };
2+
import twoOfTwoRecoverableJson from './fixtures/templates/2-of-2-recoverable.json' with { type: 'json' };
3+
import twoOfThreeJson from './fixtures/templates/2-of-3.json' with { type: 'json' };
4+
import cashChannelsJson from './fixtures/templates/cash-channels-v1.json' with { type: 'json' };
5+
import p2pkhJson from './fixtures/templates/p2pkh.json' with { type: 'json' };
6+
import sigOfSigJson from './fixtures/templates/sig-of-sig.json' with { type: 'json' };
77

88
export {
99
twoOfTwoRecoverableJson,

src/lib/vm/instruction-sets/common/signing-serialization.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
numberToBinInt32TwosCompliment,
1212
} from '../../../lib.js';
1313
// eslint-disable-next-line import/no-internal-modules, import/no-restricted-paths
14-
import sighashTests from '../xec/fixtures/satoshi-client/sighash.json' assert { type: 'json' };
14+
import sighashTests from '../xec/fixtures/satoshi-client/sighash.json' with { type: 'json' };
1515

1616
const tests = Object.values(sighashTests)
1717
.filter((e) => e.length !== 1 && e.length < 8)

src/lib/vm/instruction-sets/xec/xec.script-tests.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ import {
1414
} from '../../../lib.js';
1515

1616
// eslint-disable-next-line import/no-restricted-paths, import/no-internal-modules
17-
import scriptTestsAddendum from './fixtures/satoshi-client/script-tests-addendum.json' assert { type: 'json' };
17+
import scriptTestsAddendum from './fixtures/satoshi-client/script-tests-addendum.json' with { type: 'json' };
1818
// eslint-disable-next-line import/no-restricted-paths, import/no-internal-modules
19-
import scriptTests from './fixtures/satoshi-client/script_tests.json' assert { type: 'json' };
19+
import scriptTests from './fixtures/satoshi-client/script_tests.json' with { type: 'json' };
2020

2121
const tests = Object.values(scriptTests)
2222
.filter((e) => e.length !== 1 && e.length < 7)

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

+14-14
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,19 @@ import {
2525
import { vmbTestsBch } from './bch-vmb-tests.js';
2626
import type { TestedVM, VmName } from './bch-vmb-tests.spec.helper.js';
2727
/* eslint-disable import/no-restricted-paths, import/no-internal-modules */
28-
import vmbTestsBchChipLoopsInvalidJson from './generated/CHIPs/bch_vmb_tests_chip_loops_invalid.json' assert { type: 'json' };
29-
import vmbTestsBchChipLoopsNonstandardJson from './generated/CHIPs/bch_vmb_tests_chip_loops_nonstandard.json' assert { type: 'json' };
30-
import vmbTestsBchChipLoopsStandardJson from './generated/CHIPs/bch_vmb_tests_chip_loops_standard.json' assert { type: 'json' };
31-
import vmbTestsBchJson from './generated/bch_vmb_tests.json' assert { type: 'json' };
32-
import vmbTestsBch2023InvalidJson from './generated/bch_vmb_tests_2023_invalid.json' assert { type: 'json' };
33-
import vmbTestsBch2023NonstandardJson from './generated/bch_vmb_tests_2023_nonstandard.json' assert { type: 'json' };
34-
import vmbTestsBch2023StandardJson from './generated/bch_vmb_tests_2023_standard.json' assert { type: 'json' };
35-
import vmbTestsBch2025InvalidJson from './generated/bch_vmb_tests_2025_invalid.json' assert { type: 'json' };
36-
import vmbTestsBch2025NonstandardJson from './generated/bch_vmb_tests_2025_nonstandard.json' assert { type: 'json' };
37-
import vmbTestsBch2025StandardJson from './generated/bch_vmb_tests_2025_standard.json' assert { type: 'json' };
38-
import vmbTestsBch2026InvalidJson from './generated/bch_vmb_tests_2026_invalid.json' assert { type: 'json' };
39-
import vmbTestsBch2026NonstandardJson from './generated/bch_vmb_tests_2026_nonstandard.json' assert { type: 'json' };
40-
import vmbTestsBch2026StandardJson from './generated/bch_vmb_tests_2026_standard.json' assert { type: 'json' };
28+
import vmbTestsBchChipLoopsInvalidJson from './generated/CHIPs/bch_vmb_tests_chip_loops_invalid.json' with { type: 'json' };
29+
import vmbTestsBchChipLoopsNonstandardJson from './generated/CHIPs/bch_vmb_tests_chip_loops_nonstandard.json' with { type: 'json' };
30+
import vmbTestsBchChipLoopsStandardJson from './generated/CHIPs/bch_vmb_tests_chip_loops_standard.json' with { type: 'json' };
31+
import vmbTestsBchJson from './generated/bch_vmb_tests.json' with { type: 'json' };
32+
import vmbTestsBch2023InvalidJson from './generated/bch_vmb_tests_2023_invalid.json' with { type: 'json' };
33+
import vmbTestsBch2023NonstandardJson from './generated/bch_vmb_tests_2023_nonstandard.json' with { type: 'json' };
34+
import vmbTestsBch2023StandardJson from './generated/bch_vmb_tests_2023_standard.json' with { type: 'json' };
35+
import vmbTestsBch2025InvalidJson from './generated/bch_vmb_tests_2025_invalid.json' with { type: 'json' };
36+
import vmbTestsBch2025NonstandardJson from './generated/bch_vmb_tests_2025_nonstandard.json' with { type: 'json' };
37+
import vmbTestsBch2025StandardJson from './generated/bch_vmb_tests_2025_standard.json' with { type: 'json' };
38+
import vmbTestsBch2026InvalidJson from './generated/bch_vmb_tests_2026_invalid.json' with { type: 'json' };
39+
import vmbTestsBch2026NonstandardJson from './generated/bch_vmb_tests_2026_nonstandard.json' with { type: 'json' };
40+
import vmbTestsBch2026StandardJson from './generated/bch_vmb_tests_2026_standard.json' with { type: 'json' };
4141

4242
/* eslint-enable import/no-restricted-paths, import/no-internal-modules */
4343

@@ -57,7 +57,7 @@ test('bch_vmb_tests.json is up to date and contains no test ID collisions', asyn
5757
t.deepEqual(
5858
allTestCases,
5959
vmbTestsBchJson,
60-
'New test definitions were added to `bch-vmb.tests.ts`, but the generated tests were not updated. Run "yarn gen:vmb-tests" to correct this issue. (Note: tsc watch tasks don\'t always update cached JSON imports when the source file changes. You may need to restart tsc to clear this error after re-generating tests.)',
60+
'New test definitions were added to `bch-vmb.tests.ts`, but the generated tests were not updated. Run "yarn gen:vmb_tests" to correct this issue. (Note: tsc watch tasks don\'t always update cached JSON imports when the source file changes. You may need to restart tsc to clear this error after re-generating tests.)',
6161
);
6262

6363
const testCaseIds = allTestCases.map((testCase) => testCase[0]);

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
vms,
1717
} from './bch-vmb-tests.spec.helper.js';
1818
/* eslint-disable import/no-restricted-paths, import/no-internal-modules */
19-
import vmbTestsBchJson from './generated/bch_vmb_tests.json' assert { type: 'json' };
19+
import vmbTestsBchJson from './generated/bch_vmb_tests.json' with { type: 'json' };
2020
/* eslint-enable import/no-restricted-paths, import/no-internal-modules */
2121

2222
import { Bench } from 'tinybench';
@@ -46,8 +46,8 @@ test('Baseline benchmark has expected VMB test ID', (t) => {
4646
});
4747

4848
test('Run VMB tests marked with "[benchmark]"', async (t) => {
49-
const twentyMinutes = 1_200_000;
50-
t.timeout(twentyMinutes);
49+
const sixtyMinutes = 3_600_000;
50+
t.timeout(sixtyMinutes);
5151
const plannedBenchmarks = benchmarks.map((testDefinition) => {
5252
const [
5353
shortId,

src/lib/vmb-tests/readme.md

+8-7
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,13 @@ Like the C++ implementation's [`script_tests.json`](../vm/instruction-sets/xec/f
1212

1313
Each VMB test is an array including:
1414

15-
- A short, unique identifier for the test (based on the hash of the test contents)
16-
- A string describing the purpose/behavior of the test
17-
- The unlocking script under test (disassembled, i.e. human-readable)
18-
- The locking script under test (disassembled)
19-
- The full, encoded test transaction
20-
- An encoded list of unspent transaction outputs (UTXOs) with which to verify the test transaction (ordered to match the input order of the test transaction)
15+
0. **`shortId`** - A short, unique identifier for the test (based on the hash of the test contents)
16+
1. **`testDescription`** - A string describing the purpose/behavior of the test
17+
2. **`unlockingScriptAsm`** - The unlocking script under test (disassembled, i.e. human-readable)
18+
3. **`redeemOrLockingScriptAsm`** - The locking script under test (disassembled)
19+
4. **`testTransactionHex`** - The full, encoded test transaction
20+
5. **`sourceOutputsHex`** - An encoded list of unspent transaction outputs (UTXOs) with which to verify the test transaction (ordered to match the input order of the test transaction)
21+
6. **`inputIndex` (default: `0`)** - The input index of the primary input under test (evaluating the scripts from array index `2` and `3` above); if not specified, the primary input under test is input `0`.
2122

2223
Every test vector in each VM's master test file (e.g. [`bch_vmb_tests.json`](./generated/bch_vmb_tests.json)) also includes a list of labels indicating the VM configurations for which the test vector applies. This master test file is automatically broken up into a variety of smaller, single-configuration test files for easier use (e.g. [`bch_vmb_tests_2025_standard.json`](./generated/bch_vmb_tests_2025_standard.json)).
2324

@@ -53,4 +54,4 @@ For an example of VMB test usage, see [`bch-vmb-tests.spec.ts`](./bch-vmb-tests.
5354

5455
### Generating VMB Tests
5556

56-
Libauth's VMB tests are generated by the `yarn gen:vmb-tests` package script and committed to the repo. (Libauth's continuous integration tests also ensure that VMB tests remain up to date and passing on Libauth's VM implementations.)
57+
Libauth's VMB tests are generated by the `yarn gen:vmb_tests` package script and committed to the repo. (Libauth's continuous integration tests also ensure that VMB tests remain up to date and passing on Libauth's VM implementations.)

src/lib/vmb-tests/run-bch-vmb-test.spec.helper.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212

1313
import { baselineBenchmarkId, isVm, vms } from './bch-vmb-tests.spec.helper.js';
1414
// eslint-disable-next-line import/no-internal-modules
15-
import vmbTestsBchJson from './generated/bch_vmb_tests.json' assert { type: 'json' };
15+
import vmbTestsBchJson from './generated/bch_vmb_tests.json' with { type: 'json' };
1616

1717
import { Bench } from 'tinybench';
1818

src/lib/vmb-tests/write-bch-vmb-tests.spec.helper.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* eslint-disable functional/no-expression-statements */
22

33
/**
4-
* This script generates all bch_vmb_tests, run it with: `yarn gen:vmb-tests`.
4+
* This script generates all bch_vmb_tests, run it with: `yarn gen:vmb_tests`.
55
*/
66
import { writeFileSync } from 'node:fs';
77
import { resolve } from 'node:path';

src/lib/vmb-tests/write-reasons-bch-vmb-tests.spec.helper.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* eslint-disable functional/no-expression-statements */
22
/**
33
* This script produces a `*reasons.json` file for every VMB test that is
4-
* expected to fail. Run it with: `yarn gen:vmb-tests`.
4+
* expected to fail. Run it with: `yarn gen:vmb_tests`.
55
*/
66
import { readFileSync, writeFileSync } from 'node:fs';
77
import { resolve } from 'node:path';

0 commit comments

Comments
 (0)