Skip to content

Add DKG Ack states and fix signer state machine#229

Merged
xoloki merged 11 commits into
mainfrom
signer-state-machine
Apr 30, 2026
Merged

Add DKG Ack states and fix signer state machine#229
xoloki merged 11 commits into
mainfrom
signer-state-machine

Conversation

@xoloki
Copy link
Copy Markdown
Owner

@xoloki xoloki commented Apr 2, 2026

The state machine code in this repository is an artifact of the first attempt to implement sBTC, a wrapped BTC token on the Stacks blockchain, in a repository called sbtc-alpha.

The signer state machine was missing many elements of a typical state machine, all of which were present in the coordinator state machines. For example, it did not gate the handling of particular message types on certain states, nor did it effectively prevent improper state changes. This allowed protocol attacks, such as attempts to reuse nonces during signing.

One reason why this was never fixed is because the protocol as originally envisioned did not deal well with out-of-order message delivery, which happens frequently in a p2p network. So a coordinator might have received all DkgPublicShares from all signers, and thus signal that the signers should start sending DkgPrivateShares, triggering a state change on the signers. But if one signer received this coordinator message before receiving DkgPublicShares from one of the signers, strictness in handling messages based on state would cause that signer to ignore the late DkgPublicShares message.

To fix this, we add Ack/Done states to the protocol. This way state changes are gated on everyone having received all necessary information before progressing to the next state.

With this protocol change in place, we are now able to implement a proper state machine, and do so in this PR.

xoloki added 3 commits April 2, 2026 12:05
…e the case where in a p2p network the coordinator gets messages from signers before the signers get them from each other
@xoloki xoloki changed the title Update state machines so DKG waits for signers to catch up to coordinator Add DKG Ack states and fix signer state machine Apr 2, 2026
@xoloki xoloki marked this pull request as ready for review April 2, 2026 15:08
@xoloki xoloki self-assigned this Apr 2, 2026
@xoloki xoloki requested a review from jferrant April 2, 2026 15:08
Copy link
Copy Markdown
Collaborator

@djordon djordon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had one question which I think I answered myself, and some suggestions. Also, I ignored the FROST coordinator, the changes to process_timeout, and a some other things too.

Comment thread src/state_machine/coordinator/fire.rs
Comment thread src/state_machine/signer/mod.rs Outdated
Comment thread src/state_machine/signer/mod.rs Outdated
@xoloki xoloki requested a review from djordon April 2, 2026 16:19
@xoloki
Copy link
Copy Markdown
Owner Author

xoloki commented Apr 2, 2026

Good catch on the late dkg message handling @djordon, I wasn't waiting on receiving everything to Ack. Fixed now

@xoloki
Copy link
Copy Markdown
Owner Author

xoloki commented Apr 2, 2026

Added a check for DKG messages the coordinator didn't see, much tighter now

Comment thread src/state_machine/signer/mod.rs
Comment thread src/state_machine/signer/mod.rs
Copy link
Copy Markdown
Collaborator

@jferrant jferrant left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just have a couple comments. I can't quite remember exactly how WSTS coordinator/signer logic works so not 100% sure its a problem, but I would have expected all the signers to wait for the public shares from all other sgner ids in the done message before acking. But maybe that doesn't matter because the coordinator has them all at this point and ultimately signer doesn't care?

Comment thread src/state_machine/signer/mod.rs
Comment thread src/state_machine/signer/mod.rs
@xoloki
Copy link
Copy Markdown
Owner Author

xoloki commented Apr 2, 2026

Just have a couple comments. I can't quite remember exactly how WSTS coordinator/signer logic works so not 100% sure its a problem, but I would have expected all the signers to wait for the public shares from all other sgner ids in the done message before acking. But maybe that doesn't matter because the coordinator has them all at this point and ultimately signer doesn't care?

You are correct, that was missing in the initial code. It's there now.

@xoloki
Copy link
Copy Markdown
Owner Author

xoloki commented Apr 3, 2026

Added missing dkg_id checks in signer state machine, since this PR is about fixing that state machine and those missing checks were kinda crucial to prevent replay attacks

@xoloki
Copy link
Copy Markdown
Owner Author

xoloki commented Apr 3, 2026

Added sanity checks on the passed signer_ids in the Done packets, dropping them if any are bad. Deferring checking dkg_threshold until dkg_end since we already report that as DkgFailure::Threshold

@xoloki
Copy link
Copy Markdown
Owner Author

xoloki commented Apr 30, 2026

We weren't checking dkg_id in the signing parts of the signer state machine, fixed now

@xoloki
Copy link
Copy Markdown
Owner Author

xoloki commented Apr 30, 2026

We weren't checking to see if a signer had completed DKG before taking part in signing rounds. Now that's addressed on both the signer and coordinator sides.

@xoloki xoloki merged commit 31220cf into main Apr 30, 2026
5 checks passed
@xoloki xoloki deleted the signer-state-machine branch April 30, 2026 04:40
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.

3 participants