Skip to content

refactor!(consensus): standardize dkg with upstream commonware#1759

Merged
SuperFluffy merged 8 commits intomainfrom
janis/cw-709d24861c4ebe0091e50337f6d2f61d1547fdb1
Dec 30, 2025
Merged

refactor!(consensus): standardize dkg with upstream commonware#1759
SuperFluffy merged 8 commits intomainfrom
janis/cw-709d24861c4ebe0091e50337f6d2f61d1547fdb1

Conversation

@SuperFluffy
Copy link
Copy Markdown
Contributor

@SuperFluffy SuperFluffy commented Dec 25, 2025

This patch refactors the DKG actor to bring it in line with the upstream commonware "reshare" example.

This rework was forced by updates commonware to revision 709d24861c4ebe0091e50337f6d2f61d1547fdb1, which is the main branch right after commonwarexyz/monorepo#2439 was merged.

Dealer dealings, player ACKs, and their p2p communications are now no longer defined inside tempo, but employ their upstream versions.

The metadata DB API was removed in favor of journals, as in the commonware example. State management is now capable of dealing with replayed finalized blocks by checking data against an in-memory cache to avoid duplicates and maintain a consistent view. This makes atomic reads/writes unnecessary.

The DKG event loop is now also implemented in terms of a nested loop:

The outer loop iterates over epochs, while the inner loop iterates over finalized blocks.

Closes #1527
Closes #1566
Closes #1650
Closes #1672

@vercel
Copy link
Copy Markdown

vercel bot commented Dec 25, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Review Updated (UTC)
tempo-docs Ignored Ignored Preview Dec 29, 2025 7:14pm

@mergify mergify bot added the S-breaking-stf This PR includes a breaking STF change label Dec 25, 2025
@SuperFluffy SuperFluffy force-pushed the janis/cw-709d24861c4ebe0091e50337f6d2f61d1547fdb1 branch 3 times, most recently from 8b95fe2 to 15ea1d4 Compare December 25, 2025 23:29
@SuperFluffy SuperFluffy marked this pull request as ready for review December 25, 2025 23:29
@SuperFluffy SuperFluffy force-pushed the janis/cw-709d24861c4ebe0091e50337f6d2f61d1547fdb1 branch from 15ea1d4 to fa050f2 Compare December 25, 2025 23:30
Base automatically changed from janis/cw-4a5fca0223772b1a1627138d970ce231f876e6ff to main December 25, 2025 23:32
@SuperFluffy SuperFluffy force-pushed the janis/cw-709d24861c4ebe0091e50337f6d2f61d1547fdb1 branch 4 times, most recently from c65de9c to e4b7dca Compare December 29, 2025 11:08
This patch refactors the DKG actor to bring it in line with the upstream
commonware "reshare" example.

This rework was forced by updates commonware to revision 709d24861c4ebe0091e50337f6d2f61d1547fdb1,
which is the main branch right after commonwarexyz/monorepo#2439 was merged.

Dealer dealings, player ACKs, and their p2p communications are now no
longer defined inside tempo, but employ their upstream versions.

The metadata DB API was removed in favor of journals, as in the commonware
example. State management is now capable of dealing with replayed
finalized blocks by checking data against an in-memory cache to avoid
duplicates and maintain a consistent view. This makes atomic reads/writes
unnecessary.

The DKG event loop is now also implemented in terms of a nested loop:

The outer loop iterates over epochs, while the inner loop iterates
over finalized blocks.
@SuperFluffy SuperFluffy force-pushed the janis/cw-709d24861c4ebe0091e50337f6d2f61d1547fdb1 branch from e4b7dca to f3138b5 Compare December 29, 2025 11:18
Comment thread xtask/src/genesis_args.rs Outdated
Comment thread xtask/src/genesis_args.rs
Comment thread crates/dkg-onchain-artifacts/src/lib.rs
Comment thread crates/commonware-node/src/lib.rs
pub struct OnchainDkgOutcome {
pub epoch: Epoch,
pub output: Output<MinSig, PublicKey>,
pub next_players: ordered::Set<PublicKey>,
Copy link
Copy Markdown
Contributor

@joshieDo joshieDo Dec 29, 2025

Choose a reason for hiding this comment

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

maybe on write/read we could just set next_players to some kind of diff against the output.players -p1,+p2 etc

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

That seems like a reasonable optimization - but let's do that once we have a significant number of validators so that we need to start shaving off bytes?

Comment thread crates/commonware-node/src/dkg/manager/validators.rs
Comment on lines +245 to +250
let all_peers = state.construct_merged_peer_set();
self.metrics.peers.set(all_peers.len() as i64);
self.config
.peer_manager
.update(state.epoch.get(), all_peers)
.await;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

unsure on the implications right now but we're including inactive peers here as well, if a dealer/player was set to inactive in the contract, maybe we shouldnt connect to it ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

So the "syncers" are actually set by filtering all validators read from the contract. Even though peers are toggled off on-chain, they might still be participants for the purpose of consensus. For example, if the resharing process failed, we fall back to the dealer.

Comment thread crates/commonware-node/src/dkg/manager/ingress.rs
parent: (View, Digest),
round: Round,
) -> eyre::Result<PublicOutcome> {
digest: Digest,
Copy link
Copy Markdown
Contributor

@joshieDo joshieDo Dec 29, 2025

Choose a reason for hiding this comment

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

super nit: can we call these things block_hash or parent_hash instead of digest? i was lost on what this digest referred to when first glancing at it

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I feel you. I am following commonware nomenclature, and they are using digest instead of hash. Right now, we are referring to hash when it comes to talking to the EL, and use digest at the CL level.

If I do the change, I wonder if it would be equally confusing that I talk about hash but sometimes it's a B256 and sometimes wrapped in a Digest. :-/

Comment on lines 901 to 905
ensure!(
dkg_manager
.verify_intermediate_dealings(dealing)
.await
.wrap_err("failed request to verify DKG dealing")?,
"signature of intermediate DKG outcome could not be verified",
&dealer == proposer,
"proposer `{proposer}` is not the dealer `{dealer}` of the dealing \
in the block",
);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

while odd, is it a big deal?

Copy link
Copy Markdown
Contributor Author

@SuperFluffy SuperFluffy Dec 29, 2025

Choose a reason for hiding this comment

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

Well, I think we shouldn't permit a validator that is not the proposer to include dealer logs. We originally introduced this because the old commonware DKG logic would panic if you finalized it against dealings of unknown dealers. So this patch surfaced this check here, but it's technically not new logic.

I am not sure how this is still an attack vector. I think when checking the log against the current round the log would fail (well, unless the proposer acquired another dealer's signing key...).

me: PrivateKey,
round: Round,
share: Option<Share>,
seed: Summary,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

summary instead of seed ? (also for State { .. seed: })

Copy link
Copy Markdown
Contributor

@joshieDo joshieDo Dec 29, 2025

Choose a reason for hiding this comment

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

it can be a tad confusing either way, so id say lets stick to the types name

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

seed makes sense in that it's named after how it's used: state.seed is used an RNG source. So it kinda does make sense?

Comment thread crates/commonware-node/src/dkg/manager/actor/mod.rs
Comment thread crates/commonware-node/src/dkg/manager/actor/state.rs
Comment thread crates/commonware-node/src/dkg/manager/actor/state.rs
Comment thread crates/commonware-node/src/dkg/manager/actor/mod.rs Outdated
Comment thread crates/commonware-node/src/dkg/manager/actor/state.rs Outdated
@SuperFluffy SuperFluffy force-pushed the janis/cw-709d24861c4ebe0091e50337f6d2f61d1547fdb1 branch from 20e9138 to 3289ebd Compare December 29, 2025 19:09
joshieDo
joshieDo previously approved these changes Dec 29, 2025
@joshieDo joshieDo dismissed their stale review December 29, 2025 19:59

read_from_contract_on_epoch_boundary issue

@SuperFluffy SuperFluffy added this pull request to the merge queue Dec 30, 2025
Merged via the queue into main with commit c245ee2 Dec 30, 2025
18 checks passed
@SuperFluffy SuperFluffy deleted the janis/cw-709d24861c4ebe0091e50337f6d2f61d1547fdb1 branch December 30, 2025 12:43
github-merge-queue bot pushed a commit that referenced this pull request Dec 30, 2025
Updates commonware to v0.0.64.

There are no functional changes, but a plethora of new types and
refactors due to changing Commonware APIs. Highlights:

1. The static `epoch_length` was replaced with a `FixedEpocher`, which
is now passed to all our actors. All epoch utilities were also removed.
2. Rate limiters are now all operating at the p2p channel level and so
were removed from application logic (we only used them in the epoch
manager actor)
3. `application::Mailbox` also needs to implement `CertifiableAutomaton`
(no other code changes though)
4. public polynomials are now called `Sharing`.
5. a few traits are now imported from the new `commonware_math` crate.
6. we can now make use of `dkg::deal` and `dkg::deal_anonymous`,
simplifying test code and xtask


NOTE: this is marked as breaking because in between PR #1759 and this
patch commonware had a few other changes going into their 0.0.64
release. For example,
commonwarexyz/monorepo#2555
@Himess Himess mentioned this pull request Jan 1, 2026
1 task
github-merge-queue bot pushed a commit that referenced this pull request Jan 7, 2026
…1905)

Removes `--consensus.delete-signing-share`. It was no longer used since
#1759, so this is not breaking in any way.
0xKitsune pushed a commit that referenced this pull request Jan 7, 2026
…1905)

Removes `--consensus.delete-signing-share`. It was no longer used since
#1759, so this is not breaking in any way.
Zygimantass pushed a commit that referenced this pull request Jan 11, 2026
This patch refactors the DKG actor to bring it in line with the upstream
commonware "reshare" example.

This rework was forced by updates commonware to revision
709d24861c4ebe0091e50337f6d2f61d1547fdb1, which is the main branch right
after commonwarexyz/monorepo#2439 was merged.

Dealer dealings, player ACKs, and their p2p communications are now no
longer defined inside tempo, but employ their upstream versions.

The metadata DB API was removed in favor of journals, as in the
commonware example. State management is now capable of dealing with
replayed finalized blocks by checking data against an in-memory cache to
avoid duplicates and maintain a consistent view. This makes atomic
reads/writes unnecessary.

The DKG event loop is now also implemented in terms of a nested loop:

The outer loop iterates over epochs, while the inner loop iterates over
finalized blocks.

Closes #1527
Closes #1566 
Closes #1650 
Closes #1672
Zygimantass pushed a commit that referenced this pull request Jan 11, 2026
Updates commonware to v0.0.64.

There are no functional changes, but a plethora of new types and
refactors due to changing Commonware APIs. Highlights:

1. The static `epoch_length` was replaced with a `FixedEpocher`, which
is now passed to all our actors. All epoch utilities were also removed.
2. Rate limiters are now all operating at the p2p channel level and so
were removed from application logic (we only used them in the epoch
manager actor)
3. `application::Mailbox` also needs to implement `CertifiableAutomaton`
(no other code changes though)
4. public polynomials are now called `Sharing`.
5. a few traits are now imported from the new `commonware_math` crate.
6. we can now make use of `dkg::deal` and `dkg::deal_anonymous`,
simplifying test code and xtask


NOTE: this is marked as breaking because in between PR #1759 and this
patch commonware had a few other changes going into their 0.0.64
release. For example,
commonwarexyz/monorepo#2555
Zygimantass pushed a commit that referenced this pull request Jan 11, 2026
…1905)

Removes `--consensus.delete-signing-share`. It was no longer used since
#1759, so this is not breaking in any way.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-breaking-stf This PR includes a breaking STF change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Use ancestors stream instead of hand-rolling Write dealers, players into on chain DKG outcome

2 participants