Skip to content

feat: generalize the debug config into multi-transaction sequences - #10

Open
RaoulSchaffranek wants to merge 4 commits into
mainfrom
feature/multi-tx-debug-config
Open

feat: generalize the debug config into multi-transaction sequences#10
RaoulSchaffranek wants to merge 4 commits into
mainfrom
feature/multi-tx-debug-config

Conversation

@RaoulSchaffranek

@RaoulSchaffranek RaoulSchaffranek commented Jul 28, 2026

Copy link
Copy Markdown
Member

Summary

Generalizes the debugger's launch config from a single fixed invoke into an ordered sequence of transactions executed against one accumulating komet-node ledger, with the last transaction traced by default. This unblocks debugging contracts that need setup transactions — constructors, seeded state, and multi-step flows — not just a bare single call.

Driven test-first (test-writer / implementer / reviewer loop, red proven before green).

What's new

  • config.tsnormalizeConfig: folds both the new transactions + trace schema and the legacy single-invoke config into one canonical { steps, trace }. Validates handle references, duplicate ids, and the trace selector (by index, invoke id, or "last").
  • specEncode.ts: spec-driven argument encoding straight from the wasm's own contractspecv0 (composites / enums / structs / tuples), plus ${sourceAddress} / ${contract:id} substitution.
  • SequenceRunner.ts: executes N transactions against one ledger. It never throws on a FAILED tx (a reverting / trapping tx stays traceable — the trace is fetched regardless of status), assigns a distinct incrementing sequence per tx so byte-identical invokes are not deduped by komet-node, and uses a deterministic source account (never Keypair.random()).
  • SorobanTxBuilder / TurnkeyPipeline: thread per-tx sequence numbers and route both legacy and new configs through the runner.

Testing

Unit + integration suites for each milestone (multitxConfig, specEncode, sequenceRunner) plus a real-komet-node e2e (sequenceRunner.e2e.test.ts) covering constructor-as-invoke + state persistence, no-throw-on-trap, and anti-dedup.

Also makes the e2e's node presence-probe timeout configurable (KOMET_NODE_PROBE_TIMEOUT_MS, default 30s) so the suite can run against a locally-built dev node whose cold start exceeds the old 10s ceiling.

Composite call arguments

The e2e's composite scenario (supply(Vec<(AssetKey,i128)>)) currently asserts that the released komet-node rejects vec/map call arguments. That server-side gap is fixed in runtimeverification/komet-node#52; once it ships in a release, this scenario flips to a positive trace assertion (verified locally end-to-end against a dev node built from that branch — all four e2e scenarios pass).

Replace the fixed 4-step TurnkeyPipeline with a config that defines an
ordered sequence of transactions, tracing the last by default.

- config.ts: normalizeConfig folds a new `transactions`+`trace` schema and
  the legacy single-invoke config into a canonical `{ steps, trace }`, with
  handle validation and trace selection by index, invoke id, or "last".
- specEncode.ts: spec-driven argument encoding from the wasm's own contract
  spec (composites/enums/structs/tuples) plus ${sourceAddress}/${contract:id}
  substitution.
- SequenceRunner.ts: executes N transactions against one accumulating ledger;
  never throws on a FAILED tx (a reverting tx stays traceable), assigns a
  distinct incrementing sequence per tx to defeat komet-node dedup, and uses
  a deterministic source account.
- SorobanTxBuilder/TurnkeyPipeline: thread per-tx sequence numbers; route both
  legacy and new configs through the runner.
- Fixtures + unit and real-komet-node e2e suites (constructor-as-invoke,
  composite args, state persistence, revert tracing).

Constructor initialization is expressed as an explicit invoke tx, since komet
drops CreateContractV2 constructor args.
The e2e `before` hook probes `<command> --help` to fail loudly when the node
is missing. The 10s ceiling is fine for the kup binary (which answers
instantly) but too tight for a locally-built dev node run from source, whose
cold start imports ~15s of K/pyk machinery before `--help` returns — the probe
would time out and abort the suite even though the node is present and healthy.

Default the probe timeout to 30s and allow overriding it via
KOMET_NODE_PROBE_TIMEOUT_MS. The value is only a ceiling, so a fast binary is
unaffected.
Replace the single-invoke-only configuration reference with the generalized
`transactions` + `trace` schema: deploy/invoke steps, handle references, the
trace selector, named `args` (with composite/enum/tuple shapes), and the
`${sourceAddress}` / `${contract:<id>}` substitution tokens. Keep the
single-call shorthand documented as a convenience.
The debugger accepted two live launch-config shapes: a legacy top-level
`function`/`args`/`contract`/`wasmPath` single-invoke config, and the
newer `transactions` sequence. Collapse to one: `transactions` (+ an
optional `trace` selector) is now the only live format. Offline replay
via `rawTrace` (+ an optional `wasmPath` for symbols) is unchanged.

- normalizeConfig now requires a `transactions` array; the desugaring of
  the legacy shape is gone. A leftover top-level `function` throws a
  migration error pointing at the new format.
- SorobanLaunchArgs drops the top-level `function`/`args`/`contract`/
  `buildCommand`/`debugInfo` fields; build options live on deploy steps.
- The soroban-trace CLI keeps its `--contract`/`--function`/`--args`
  flags but now builds a `transactions` config internally.
- The extension provider requires `transactions` or `rawTrace`, and
  injects the resolved build command into each deploy step.
- Update the launch schema, examples, and README; add a full config
  reference at docs/debug-config.md (single tx, multi-contract system,
  composite argument types).
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