Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
node-version: [20.x]

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6

- uses: pnpm/action-setup@v3
with:
Expand Down Expand Up @@ -47,10 +47,10 @@ jobs:
runs-on: ubuntu-latest
needs: [build-and-test]
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6

# go-sdk is required by the Go conformance runner (replace directive)
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
repository: bsv-blockchain/go-sdk
path: go-sdk
Expand Down
141 changes: 141 additions & 0 deletions .github/workflows/codegen.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
name: Codegen — OpenAPI → Go, TypeScript, Python types
on:
push:
paths:
- 'specs/**/*.yaml'
branches: [main]
workflow_dispatch:

jobs:
generate-go-types:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-go@v5
with:
go-version: '1.22'
- name: Install oapi-codegen
run: go install github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen@latest
- name: Generate Go types from overlay spec
run: |
mkdir -p conformance/generated/overlay
oapi-codegen -generate types -package overlay \
specs/overlay/overlay-http.yaml \
> conformance/generated/overlay/types.gen.go
- name: Generate Go types from ARC spec
run: |
mkdir -p conformance/generated/broadcast
oapi-codegen -generate types -package broadcast \
specs/broadcast/arc.yaml \
> conformance/generated/broadcast/types.gen.go
- name: Generate Go types from message-box spec
run: |
mkdir -p conformance/generated/messaging
oapi-codegen -generate types -package messaging \
specs/messaging/message-box-http.yaml \
> conformance/generated/messaging/types.gen.go
- name: Commit generated types (if changed)
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: "chore(codegen): regenerate Go types from OpenAPI specs"
file_pattern: "conformance/generated/**"

generate-ts-types:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: Generate TS types from overlay spec
run: |
mkdir -p conformance/generated/overlay
npx --yes openapi-typescript@latest specs/overlay/overlay-http.yaml \
-o conformance/generated/overlay/types.gen.d.ts
- name: Generate TS types from ARC spec
run: |
mkdir -p conformance/generated/broadcast
npx --yes openapi-typescript@latest specs/broadcast/arc.yaml \
-o conformance/generated/broadcast/types.gen.d.ts
- name: Generate TS types from message-box spec
run: |
mkdir -p conformance/generated/messaging
npx --yes openapi-typescript@latest specs/messaging/message-box-http.yaml \
-o conformance/generated/messaging/types.gen.d.ts
- uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: "chore(codegen): regenerate TS types from OpenAPI specs"
file_pattern: "conformance/generated/**/*.d.ts"

generate-py-types:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install datamodel-code-generator
run: pip install datamodel-code-generator
- name: Generate Python types from overlay spec
run: |
mkdir -p conformance/generated/overlay
datamodel-codegen \
--input specs/overlay/overlay-http.yaml \
--input-file-type openapi \
--output conformance/generated/overlay/models.py \
--output-model-type pydantic_v2.BaseModel
- name: Generate Python types from ARC spec
run: |
mkdir -p conformance/generated/broadcast
datamodel-codegen \
--input specs/broadcast/arc.yaml \
--input-file-type openapi \
--output conformance/generated/broadcast/models.py \
--output-model-type pydantic_v2.BaseModel
- name: Generate Python types from message-box spec
run: |
mkdir -p conformance/generated/messaging
datamodel-codegen \
--input specs/messaging/message-box-http.yaml \
--input-file-type openapi \
--output conformance/generated/messaging/models.py \
--output-model-type pydantic_v2.BaseModel
- uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: "chore(codegen): regenerate Python types from OpenAPI specs"
file_pattern: "conformance/generated/**/*.py"

# NOTE: Rust codegen (typify / progenitor) requires a Cargo workspace context
# that does not exist in this repository. Placeholder files are committed
# instead; run the commands below manually inside a Rust project that
# imports these specs.
create-rust-placeholders:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Create Rust codegen placeholder files
run: |
mkdir -p conformance/generated/overlay
cat > conformance/generated/overlay/types.rs.TODO <<'EOF'
# To generate Rust types for the overlay spec:
# cargo add typify
# typify specs/overlay/overlay-http.yaml > src/types.rs
EOF

mkdir -p conformance/generated/broadcast
cat > conformance/generated/broadcast/types.rs.TODO <<'EOF'
# To generate Rust types for the broadcast (ARC) spec:
# cargo add typify
# typify specs/broadcast/arc.yaml > src/types.rs
EOF

mkdir -p conformance/generated/messaging
cat > conformance/generated/messaging/types.rs.TODO <<'EOF'
# To generate Rust types for the messaging spec:
# cargo add typify
# typify specs/messaging/message-box-http.yaml > src/types.rs
EOF
- uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: "chore(codegen): add Rust placeholder TODO files"
file_pattern: "conformance/generated/**/*.TODO"
63 changes: 63 additions & 0 deletions .github/workflows/conformance.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
name: Conformance

on:
push:
branches: [main, phase2/boundary-specs]
pull_request:
branches: [main]

jobs:
go-runner:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-go@v5
with:
go-version: '1.22'
- name: Create reports directory
run: mkdir -p conformance/reports
- name: Run Go conformance runner
run: |
go run . \
-vectors ../../vectors \
--report ../../reports/go-results.xml \
--json-report ../../reports/go-results.json
working-directory: ${{ github.workspace }}/conformance/runner/go
- name: Upload Go conformance reports
if: always()
uses: actions/upload-artifact@v4
with:
name: go-conformance-reports
path: conformance/reports/
retention-days: 30

ts-runner:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v4
with:
node-version: '20'
- uses: pnpm/action-setup@v3
with:
version: 9
- name: Install deps
run: pnpm install --no-frozen-lockfile
- name: Build TS SDK
run: pnpm --filter @bsv/sdk run build
- name: Create reports directory
run: mkdir -p conformance/reports
- name: Run TS conformance runner
run: |
pnpm --filter @bsv/conformance-runner-ts test -- \
--json --outputFile=../../reports/ts-results.json
env:
NODE_OPTIONS: --experimental-vm-modules
working-directory: ${{ github.workspace }}/conformance/runner/ts
- name: Upload TS conformance reports
if: always()
uses: actions/upload-artifact@v4
with:
name: ts-conformance-reports
path: conformance/reports/
retention-days: 30
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
id-token: write # required for npm OIDC provenance

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6

- uses: pnpm/action-setup@v3
with:
Expand Down
18 changes: 16 additions & 2 deletions conformance/META.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,22 @@
"BRC-100": []
},
"stats": {
"total_files": 15,
"total_vectors": 202,
"total_files": 27,
"total_vectors": 238,
"last_updated": "2026-04-24"
},
"regression_index": {
"beef-v2-txid-panic": "go-sdk#306",
"privatekey-modular-reduction": "ts-sdk#31",
"merkle-path-odd-node": "go-sdk#298",
"uhrp-url-parity": "go-sdk#310",
"script-lshift-truncation": "ts-sdk#493",
"script-shift-endianness": "ts-sdk#377",
"tx-sequence-zero-sighash": "ts-sdk#371",
"script-writebin-empty": "ts-sdk#336",
"script-fromasm-numeric-token": "ts-sdk#42",
"fee-model-mismatch": "go-sdk#267",
"bip276-hex-decode": "go-sdk#286",
"beef-isvalid-hydration": "go-sdk#167"
}
}
16 changes: 16 additions & 0 deletions conformance/REGRESSION_QUEUE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Regression Vector Queue

Issues that were reviewed but could not be converted to deterministic vectors due to insufficient detail in the issue body. Each entry notes what additional information is needed.

| Issue | Title | Needs |
|-------|-------|-------|
| ts-sdk#203 | Resource Exhaustion in Script Interpreter | No deterministic expected output — the issue describes a DoS via exponential stack growth but does not specify a memory limit or error message that implementations must produce. Need: agreed policy limit (bytes) and required error string. |
| ts-sdk#109 | Script template length estimate doesn't account for larger signatures | Not a crypto/encoding bug — affects only fee estimation heuristics in RPuzzle template. No expected output. Need: concrete expected unlock script max size (73 bytes instead of 71). |
| ts-sdk#241 | Negative number handling in wallet wire encoding | WalletWire is an application-layer substrate, not a Tier 0 crypto/tx path. No cross-language parity impact. Need: wire encoding spec to derive deterministic expected hex. |
| go-sdk#211 | BEEF IsValid/Verify algorithm is unstable — gives different results for the same input | The instability stems from map iteration order in Go (non-deterministic), not from a wrong output for a known input. A deterministic vector cannot capture this race condition. Need: a unit test not a conformance vector. |
| go-sdk#96 | BEEF decode error: "There are no leaves at height" | The BUMP hex in the issue is a complex real-world payload. The error is in the Merkle proof decoder for an uncommon tree shape. Need: a minimal reduced BUMP hex that triggers the edge case, plus the correct parsed leaf count at each height. |
| go-sdk#74 | BEEF generated from complex tree cannot be parsed back to sdk.Transaction | Issue body contains only Go test code with embedded BEEF hex blobs, no expected TxIDs or verification results. Need: expected TxID of the final spending transaction to write a deterministic check. |
| ts-sdk#371 | Sequence Number 0 gets reset to MAX | The issue is fully described but the fix is SDK-internal (don't overwrite missing sequence with default during array-literal construction). The regression vector (tx-sequence-zero-sighash) covers the observable behaviour. Captured — no further action needed here. |
| ts-sdk#54 | OP_IF OP_RETURN terminates early — script eval error | The issue shows that OP_IF + OP_1 + OP_RETURN + OP_ENDIF should return true, but no txid or script hex with known valid CHECKSIG is given. Would require adding to sdk/scripts/evaluation.json rather than a regression file. Deferred to evaluation vector set. |
| go-sdk#261 | Go-SDK cannot process transactions which generate large data items on stack | Script template provided uses NUM2BIN with a 10 MB argument. No expected pass/fail outcome is specified — just that it "should validate successfully". Need: exact script hex and whether the script passes or returns a specific error. |
| ts-sdk#259 | PushDrop.parse doesn't support lockPosition='after' | Parser bug in application-layer template, not in core tx/crypto path. Insufficient inputs (no example token locking script hex + expected field parse output). |
Empty file.
33 changes: 33 additions & 0 deletions conformance/generated/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# conformance/generated

This directory contains Go type definitions that are **automatically generated** from the OpenAPI specs in `specs/`.

Do not edit files in this directory by hand — they will be overwritten the next time the codegen workflow runs.

## How generation works

The `.github/workflows/codegen.yml` workflow runs `oapi-codegen` against each OpenAPI spec whenever a `*.yaml` file under `specs/` changes on the `main` branch (or on manual dispatch):

| Spec | Generated package | Output path |
|------|-------------------|-------------|
| `specs/overlay/overlay-http.yaml` | `overlay` | `conformance/generated/overlay/types.gen.go` |
| `specs/broadcast/arc.yaml` | `broadcast` | `conformance/generated/broadcast/types.gen.go` |
| `specs/messaging/message-box-http.yaml` | `messaging` | `conformance/generated/messaging/types.gen.go` |

## Regenerating locally

```bash
go install github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen@latest

oapi-codegen -generate types -package overlay \
specs/overlay/overlay-http.yaml \
> conformance/generated/overlay/types.gen.go

oapi-codegen -generate types -package broadcast \
specs/broadcast/arc.yaml \
> conformance/generated/broadcast/types.gen.go

oapi-codegen -generate types -package messaging \
specs/messaging/message-box-http.yaml \
> conformance/generated/messaging/types.gen.go
```
3 changes: 3 additions & 0 deletions conformance/generated/broadcast/types.rs.TODO
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# To generate Rust types for the broadcast (ARC) spec:
# cargo add typify
# typify specs/broadcast/arc.yaml > src/types.rs
3 changes: 3 additions & 0 deletions conformance/generated/messaging/types.rs.TODO
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# To generate Rust types for the messaging spec:
# cargo add typify
# typify specs/messaging/message-box-http.yaml > src/types.rs
3 changes: 3 additions & 0 deletions conformance/generated/overlay/types.rs.TODO
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# To generate Rust types for the overlay spec:
# cargo add typify
# typify specs/overlay/overlay-http.yaml > src/types.rs
4 changes: 1 addition & 3 deletions conformance/runner/go/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module github.com/bsv-blockchain/ts-stack/conformance/runner/go

go 1.25.0

require github.com/bsv-blockchain/go-sdk v0.0.0
require github.com/bsv-blockchain/go-sdk v1.2.23

require (
github.com/davecgh/go-spew v1.1.1 // indirect
Expand All @@ -13,5 +13,3 @@ require (
golang.org/x/net v0.51.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

replace github.com/bsv-blockchain/go-sdk => ../../../go-sdk
4 changes: 4 additions & 0 deletions conformance/runner/go/go.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
github.com/bsv-blockchain/go-sdk v1.2.23 h1:DRZWaqgW6Ra+uFe1+sLFi+WPcjTdBm8NAwfr6ODOF68=
github.com/bsv-blockchain/go-sdk v1.2.23/go.mod h1:5mmw1QLusuAkjWmQgUOurQYCXdIsQEsWXbAZ9zwme3g=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
Expand All @@ -10,6 +12,8 @@ golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts=
golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos=
golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo=
golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y=
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
Expand Down
Loading
Loading