test(pr3866): in-process coordinator↔chain FROST DKG end-to-end#4132
Merged
mswilkison merged 2 commits intoJul 2, 2026
Merged
Conversation
Chain the full FROST wallet-creation coordinator↔chain flow into ONE in-process run: a local FrostDKGChain emits FrostDKGStarted, the coordinator's OnFrostDKGStarted subscription handles it (dedup, block confirmation, DKG-state check, past-event lookup, group-membership resolution), executeFrostDKGIfPossible announces readiness and runs the REAL cgo tbtc-signer DKG, and the assembled result is submitted back through SubmitFrostDKGResult, after which the wallet is verified registered on the chain. Previously the coordinator↔chain wiring and the real cgo DKG execution were covered separately (frost_dkg_coordinator_test.go with stub results; frost_dkg_execution_frost_native_test.go in isolation) and never in one flow. The DKG output is real: a thin recording wrapper delegates to the cgo engine and captures the x-only group key, which the test asserts equals the key submitted on-chain byte-for-byte (no injected/fake result can pass), is a valid secp256k1 point, and backs a registered wallet. The group is reduced to 3 seats held by one node because the cgo engine is a process-global OnceLock<Mutex> and its development dealer DKG holds all key packages in one engine (n>=2; the library rejects n==1). Gated frost_native && frost_tbtc_signer && cgo, so plain frost_native builds are unaffected. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
P1: probe the real linked libfrost_tbtc up front. The build-tagged tbtc-signer engine registers whether or not the lib is linked, so the prior availability check passed even with an absent/stale lib and the missing ABI only surfaced inside the coordinator goroutine's RunDKGWithSeed, making the test hang until the 90s deadline instead of skipping. Now exercise the once-per-process ABI preflight up front via a raw seeded RunDKGWithSeed and route the result through a helper mirroring the reference skipFrostUnavailable: ErrNativeCryptographyUnavailable SKIPS (or FATALs under KEEP_CORE_FROST_REQUIRE_CGO), any other error fails. The probe runs on the raw engine so it never pollutes the recording wrapper's captured key. P2: remove the recovery-goroutine race. initializeFrostDKGCoordinator also launches recoverFrostDKGCoordinatorState; if it observed AwaitingResult before the OnFrostDKGStarted subscription, it could drive the DKG via the waitForConfirmation=false bypass and the deduplicator would suppress the subscription path, passing the test without exercising the confirmation flow. The chain now signals when recovery has completed its initial IDLE scan (the first GetFrostDKGState reader), and the test waits for that signal before flipping to AwaitingResult+emitting - so only the subscription's block-confirmation path can run. A deterministic assertion (submit block >= emit block + dkgStartedConfirmationBlocks) proves the confirmation waitForBlockHeight path was exercised and guards against silent regression. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
24bb1b5
into
feat/frost-schnorr-migration-scaffold
18 checks passed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this adds
An in-process integration test that chains the full FROST wallet-creation
coordinator↔chain flow into ONE run:
New file:
pkg/tbtc/frost_dkg_coordinator_chain_e2e_frost_native_test.go(build-gated
frost_native && frost_tbtc_signer && cgo).Why
Today the coordinator↔chain wiring and the real cgo DKG execution are tested
separately and never in one flow:
frost_dkg_coordinator_test.godrives the chain plumbing with stub results.frost_dkg_execution_frost_native_test.godrives the real DKG in isolation.This closes that gap: event delivery, confirmation, membership resolution,
readiness announcement, result assembly/signature collection, on-chain
submission, and wallet registration all run together against a real cgo DKG
output.
What is REAL vs REDUCED
Real
executeFrostDKGcalls the process-global cgotbtc-signer engine (
buildTaggedTBTCSignerEngine, registered viaRegisterNativeExecutionFFISigningPrimitiveForBuild). The x-only group keythat lands on-chain is the exact key the engine produced.
FrostDKGChaininterface (
SubmitFrostDKGResult) — not injected into chain state directly.OnFrostDKGStartedsubscription registered byinitializeFrostDKGCoordinator; confirmation, state check, past-event lookup,membership resolution, readiness announcement, DKG-result operator-signature
collection, and delayed submission all run as in production.
Reduced (documented)
held by ONE operator/node. The cgo engine is a process-global
OnceLock<Mutex>, so N independent real-custody participants cannot runconcurrently in one OS process. The tbtc-signer development dealer DKG by
design has a single engine hold every participant's key package — which is
exactly this shape. The cgo library rejects
n == 1(
participants must contain at least 2 entries), so the minimum honestreduction is
n >= 2; the test usesGroupSize=3, GroupQuorum=2, HonestThreshold=2.TBTC_SIGNER_PROFILE=development(plus ahermetic state-encryption key + per-process state path, mirroring the existing
real-cgo reference harness). Bootstrap/dealer DKG is disabled under the
production profile, which requires distributed DKG wiring across processes.
Nothing about the crypto or the submission is faked: the DKG output comes from
the real engine and the submission goes through the chain interface.
Load-bearing assertion
A thin recording wrapper delegates every engine method to the real cgo engine
and captures the exact x-only key returned by
RunDKGWithSeed. The test thenasserts the on-chain submitted
Result.XOnlyOutputKey:fake result can pass),
(
IsFrostWalletRegistered).How to run
Proof lines from a passing run:
Without the cgo lib linked the test skips (or fails when
KEEP_CORE_FROST_REQUIRE_CGO=true), so it stays inert where real crypto isunavailable. It is excluded from the plain
frost_nativebuild, so the existingcoordinator tests are unaffected (
go test -tags frost_native ./pkg/tbtc/stays green).
Not covered / follow-up
This is an in-process rehearsal with one node holding all seats. It does NOT
cover the fully-live path:
production distributed DKG (not the development dealer DKG), which is what
TBTC_SIGNER_PROFILE=productionrequires.emitting
DkgStarted, realSelectFrostGroup, and on-chain resultvalidation / challenge / approve, instead of the test-local
FrostDKGChain.network (here a single operator's signature satisfies the reduced group's
threshold with no network round-trip).
Those belong in a multi-process / system-test rehearsal and are out of scope for
this in-process integration test.
🤖 Generated with Claude Code