Skip to content

test: Go simnet harness for charon/pluto e2e duty tests#526

Open
varex83agent wants to merge 1 commit into
mainfrom
test/go-simnet-harness
Open

test: Go simnet harness for charon/pluto e2e duty tests#526
varex83agent wants to merge 1 commit into
mainfrom
test/go-simnet-harness

Conversation

@varex83agent

Copy link
Copy Markdown
Collaborator

What

Adds test-infra/harness/, a Go test harness that runs simnet-style end-to-end attester duty tests over distributed-validator clusters mixing charon nodes (in-process, reusing charon's own app.Run) and pluto nodes (subprocesses of the pluto binary), plus a CI workflow.

Charon v1.7.1 (our parity reference) is consumed as a regular Go module dependency — no fork. The harness reuses its cluster.NewForT deterministic fixtures, testutil/beaconmock, testutil/validatormock and testutil/relay directly.

Design

                relay (in-process libp2p)
                beaconmock (shared chain state, deterministic duties)
                    ▲ Go              ▲ HTTP (per-node gateway + submission capture)
             charon app.Run      pluto run / charon run (subprocess)
             (in-process)             ▲ validator API
                                 validatormock (harness-driven over HTTP)
  • Per-node HTTP beacon gateways over one shared beaconmock. Charon's beaconmock implements dynamic behaviour (duties, validators, attestation data) only on its Go client interface; its HTTP server serves static stubs. The gateway fronts the shared mock over real HTTP so external processes get a complete beacon API, and captures each node's submissions for assertions.
  • Real p2p partial-signature exchange. Upstream simnet uses an in-memory ParSigEx transport; the harness omits it so out-of-process nodes participate in QBFT consensus and threshold signing.
  • Assertions at the beacon boundary: for some slot, every node must submit an attestation, and all payloads must be identical after JSON normalization (group-signed threshold aggregates). The in-process baseline additionally uses upstream-style BroadcastCallback assertions.

Scenarios

Test Cluster Status
TestSimnetAttesterCharonInProcess 3× charon, in-process bmock ✅ passes (~5s)
TestSimnetAttesterCharonViaGateway 3× charon via HTTP gateway ✅ passes (~4s)
TestSimnetAttesterPluto 3× pluto ⏭ skips until pluto run lands
TestSimnetAttesterMixed 2× charon + 2× pluto, threshold 3 ⏭ skips until pluto run lands

The pluto scenarios probe $PLUTO_BIN run --help and activate automatically once the run command exists. The subprocess path is already validated end-to-end today: pointing PLUTO_BIN at a charon binary (which accepts the same flags) passes the mixed scenario in ~5s, covering the on-disk fixture layout, run flags, readiness polling, HTTP-driven validator mock and capture assertions.

CI

.github/workflows/go-harness.yml:

  • charon-simnet: charon-only scenarios, no Rust build — fast signal.
  • pluto-simnet: builds pluto-cli (same steps as dkg-runner) and runs the full suite with PLUTO_BIN set.

Notes

  • The two replace directives in go.mod are copied from charon's own go.mod (Go does not propagate a dependency's replaces); they must move in lockstep when bumping the pinned charon version.
  • pluto run requirements for the scenarios to activate are documented in the README (charon-equivalent flags + validator API on the configured address).
  • Follow-ups: proposer/sync-committee scenarios (direct translation of upstream simnet's beaconmock options) and below-threshold fault injection.

🤖 Generated with Claude Code

Add test-infra/harness, a Go module that reuses charon v1.7.1 as a
library (cluster fixtures, beaconmock, validatormock, relay) to run
simnet-style end-to-end attester duty tests over clusters mixing
in-process charon nodes and subprocess pluto nodes.

Since charon's beaconmock only implements dynamic behaviour on its Go
client interface, the harness adds a per-node HTTP gateway fronting one
shared mock, serving duties/validators/attestation endpoints over real
HTTP and capturing submissions per node for assertions. Unlike upstream
simnet, partial-signature exchange runs over real p2p so out-of-process
nodes participate in consensus and threshold signing.

Scenarios: all-charon in-process (baseline), all-charon via gateway
(validates the gateway), all-pluto and 2+2 mixed with threshold 3
(skip until `pluto run` lands, then activate automatically). The
subprocess path is validated today by pointing PLUTO_BIN at a charon
binary, which passes the mixed scenario in ~5s.

CI runs the charon scenarios standalone for fast signal, plus the full
suite with a freshly built pluto binary.

Co-Authored-By: Bohdan Ohorodnii <35969035+varex83@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant