Skip to content

Phase 7.3 PR1b: interactive_aggregate cgo bridge + candidate-culprit typed error#4073

Merged
mswilkison merged 1 commit into
feat/frost-schnorr-migration-scaffoldfrom
feat/frost-7.3-interactive-aggregate-bridge
Jun 16, 2026
Merged

Phase 7.3 PR1b: interactive_aggregate cgo bridge + candidate-culprit typed error#4073
mswilkison merged 1 commit into
feat/frost-schnorr-migration-scaffoldfrom
feat/frost-7.3-interactive-aggregate-bridge

Conversation

@mswilkison

Copy link
Copy Markdown
Contributor

What

Completes the interactive engine bridge (PR1 #4072 added open/round1/round2/abort). InteractiveAggregate aggregates the responsive subset's signature shares for an attempt into the BIP-340 signature — the engine resolves verifying material from the session's own DKG state, so no public key package crosses the FFI.

The one non-mechanical piece: surfacing candidate culprits

On a share-verification failure the engine returns the candidate culprits in the error payload (ErrorResponse.candidate_culprits — u16 Go member ids, omitted for other errors), but the Go error envelope was code/message only. So:

  • add candidate_culprits to buildTaggedTBTCSignerErrorResponse + buildTaggedTBTCSignerStructuredError (additive — empty for every other error, no behavior change elsewhere);
  • add a typed InteractiveAggregateShareVerificationError{SessionID, AttemptID, CandidateCulprits, Message}; InteractiveAggregate maps the aggregate_share_verification_failed code to it (session/attempt filled from the caller's request, which the payload doesn't echo). The PR3 runner will errors.As it and feed the culprits to the envelope-bound f+1 blame adjudication.

The culprits are documented as pure-crypto candidates, NOT authoritative blame — a coordinator that aggregated honest shares against a substituted package/root would make honest shares appear here (consistent with the engine + #4062). They're carried as the wire []uint16; PR3 converts u16 → group.MemberIndex (range-checked) at the orchestration boundary.

Scope / blast radius

  • Additive — method on the concrete engine only; the NativeTBTCSignerEngine interface is not widened, so no fakes change (confirmed via repo-wide go vet -tags frost_native ./...).
  • The error-envelope changes are additive: other operations decode with an empty culprit list.

Tests

Payload builder (fields, rejections incl. empty session/attempt/package/shares/share-data) + decoder (success / malformed JSON) + interpretInteractiveAggregateError (share-verification → typed error carrying culprits + session/attempt; any other error → passthrough preserving ErrNativeBridgeOperationFailed) + the error-payload culprit extraction (and that non-culprit errors decode to an empty list).

Validation

⚠️ client-* CI does not build these cgo-tagged files. Validated locally: default / frost_native / frost_native+frost_tbtc_signer+cgo builds, signing suite, repo-wide frost_native vet, gofmt — all green.

Next (Phase 7.3)

Coordinator.MarkSucceeded + an explicit active-attempt object → the in-process runner (happy + sad/blame path, fake bus) → real pkg/net transport → executor integration → t-of-included finalize → delete the transitional coarse path.

🤖 Generated with Claude Code

…typed error

Completes the interactive engine bridge (PR1 = #4072 was open/round1/round2/abort).
InteractiveAggregate aggregates the responsive subset's shares for an attempt
into the BIP-340 signature; the engine resolves verifying material from the
session's own DKG state (no public key package crosses the FFI).

The one non-mechanical piece: on a share-verification failure the engine returns
the CANDIDATE CULPRITS in the error payload (ErrorResponse.candidate_culprits,
u16 Go member ids, omitted for other errors), but the Go error envelope was
code/message only. So:
- add candidate_culprits to buildTaggedTBTCSignerErrorResponse +
  buildTaggedTBTCSignerStructuredError (additive; empty for every other error,
  so no behavior change elsewhere);
- add a typed InteractiveAggregateShareVerificationError{SessionID, AttemptID,
  CandidateCulprits, Message}; InteractiveAggregate maps the
  aggregate_share_verification_failed code to it (session/attempt filled from
  the caller's request, which the payload doesn't echo). The runner errors.As
  it and feeds the culprits to the envelope-bound f+1 blame adjudication.

The culprits are documented as PURE-CRYPTO candidates, NOT authoritative blame
(a coordinator that aggregated honest shares against a substituted package/root
would make honest shares appear here) - consistent with the engine + #4062.

ADDITIVE: method on the concrete engine only (interface not widened; no fakes
touched - repo-wide frost_native vet clean). Carries the wire u16 ids; PR3
converts u16 -> group.MemberIndex.

Tests: payload builder (fields, rejections) + decoder (success/malformed) +
interpretInteractiveAggregateError (share-verification -> typed error with
culprits; other error -> passthrough preserving ErrNativeBridgeOperationFailed)
+ error-payload culprit extraction. Builds clean under default / frost_native /
cgo; signing suite + repo-wide frost_native vet + gofmt green. (client-* CI does
not build the cgo tags; validated locally.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c16ea490-3d5a-40f2-b435-ffeab9006694

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/frost-7.3-interactive-aggregate-bridge

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@mswilkison mswilkison merged commit d0edfef into feat/frost-schnorr-migration-scaffold Jun 16, 2026
16 checks passed
@mswilkison mswilkison deleted the feat/frost-7.3-interactive-aggregate-bridge branch June 16, 2026 13:05
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