diff --git a/Cargo.lock b/Cargo.lock index 204b2ca6d..2aa491949 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8048,7 +8048,7 @@ dependencies = [ [[package]] name = "wsts" version = "10.0.0" -source = "git+https://github.com/Trust-Machines/wsts.git?rev=b7c009e4903bcf03351847a9341c25a26d36c042#b7c009e4903bcf03351847a9341c25a26d36c042" +source = "git+https://github.com/Trust-Machines/wsts.git?rev=53ae23f5f35def420877ccc8c0fe3662e64e38a1#53ae23f5f35def420877ccc8c0fe3662e64e38a1" dependencies = [ "aes-gcm", "bs58 0.5.1", diff --git a/protobufs/crypto/wsts/wsts.proto b/protobufs/crypto/wsts/wsts.proto index 0f9fcd5eb..3d664d1de 100644 --- a/protobufs/crypto/wsts/wsts.proto +++ b/protobufs/crypto/wsts/wsts.proto @@ -228,6 +228,8 @@ message DkgStatus { MissingPrivateShares missing_private_shares = 5; // DKG private shares were bad from these signer_ids BadPrivateShares bad_private_shares = 6; + // The DKG threshold was not met + Threshold threshold = 7; } } @@ -318,3 +320,6 @@ message SignatureShare { // The key IDs of the party repeated uint32 key_ids = 3; } + +// The DKG threshold has not been upheld by the coordinator. +message Threshold {} diff --git a/signer/Cargo.toml b/signer/Cargo.toml index 6b0f37fb1..34fd14b5f 100644 --- a/signer/Cargo.toml +++ b/signer/Cargo.toml @@ -53,7 +53,7 @@ tracing-attributes.workspace = true tracing-subscriber = { workspace = true } url.workspace = true # wsts.workspace = true -wsts = { git = "https://github.com/Trust-Machines/wsts.git", rev = "b7c009e4903bcf03351847a9341c25a26d36c042" } +wsts = { git = "https://github.com/Trust-Machines/wsts.git", rev = "53ae23f5f35def420877ccc8c0fe3662e64e38a1" } hex.workspace = true cfg-if = "1.0" include_dir = "0.7.4" diff --git a/signer/src/proto/convert.rs b/signer/src/proto/convert.rs index cf910fd20..2b95b8ff2 100644 --- a/signer/src/proto/convert.rs +++ b/signer/src/proto/convert.rs @@ -804,6 +804,7 @@ impl From for proto::DkgStatus { DkgFailure::BadPrivateShares(inner) => { proto::dkg_status::Mode::BadPrivateShares(inner.into()) } + DkgFailure::Threshold => proto::dkg_status::Mode::Threshold(proto::Threshold {}), }, }; proto::DkgStatus { mode: Some(mode) } @@ -828,6 +829,7 @@ impl TryFrom for DkgStatus { proto::dkg_status::Mode::BadPrivateShares(inner) => { DkgStatus::Failure(DkgFailure::BadPrivateShares(inner.try_into()?)) } + proto::dkg_status::Mode::Threshold(_) => DkgStatus::Failure(DkgFailure::Threshold), }) } } diff --git a/signer/src/proto/generated/crypto.wsts.rs b/signer/src/proto/generated/crypto.wsts.rs index 804b91422..3b933cac6 100644 --- a/signer/src/proto/generated/crypto.wsts.rs +++ b/signer/src/proto/generated/crypto.wsts.rs @@ -373,7 +373,7 @@ pub struct ProofIdentifier { #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct DkgStatus { - #[prost(oneof = "dkg_status::Mode", tags = "1, 2, 3, 4, 5, 6")] + #[prost(oneof = "dkg_status::Mode", tags = "1, 2, 3, 4, 5, 6, 7")] pub mode: ::core::option::Option, } /// Nested message and enum types in `DkgStatus`. @@ -399,6 +399,9 @@ pub mod dkg_status { /// DKG private shares were bad from these signer_ids #[prost(message, tag = "6")] BadPrivateShares(super::BadPrivateShares), + /// The DKG threshold was not met + #[prost(message, tag = "7")] + Threshold(super::Threshold), } } /// DKG completed successfully @@ -514,3 +517,7 @@ pub struct SignatureShare { #[prost(uint32, repeated, tag = "3")] pub key_ids: ::prost::alloc::vec::Vec, } +/// The DKG threshold has not been upheld by the coordinator. +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct Threshold {} diff --git a/signer/src/wsts_state_machine.rs b/signer/src/wsts_state_machine.rs index d5d69c9e9..2f8d29ea0 100644 --- a/signer/src/wsts_state_machine.rs +++ b/signer/src/wsts_state_machine.rs @@ -15,6 +15,8 @@ use crate::storage::model; use crate::storage::model::SigHash; use bitcoin::hashes::Hash as _; +use hashbrown::HashMap; +use hashbrown::HashSet; use wsts::common::PolyCommitment; use wsts::state_machine::coordinator::Coordinator as _; use wsts::state_machine::coordinator::State as WstsState; @@ -81,6 +83,7 @@ impl SignerStateMachine { .try_into() .map_err(|_| error::Error::TypeConversion)?; let num_keys = num_parties; + let dkg_threshold = num_parties; let p256k1_public_key = p256k1::keys::PublicKey::from(&signer_pub_key); let id: u32 = *signers @@ -89,7 +92,19 @@ impl SignerStateMachine { .ok_or_else(|| error::Error::MissingPublicKey)? .0; - let public_keys = wsts::state_machine::PublicKeys { signers, key_ids }; + let signer_key_ids: HashMap> = signers + .iter() + .map(|(&signer_id, _)| { + let mut keys = HashSet::new(); + keys.insert(signer_id + 1); + (signer_id, keys) + }) + .collect(); + let public_keys = wsts::state_machine::PublicKeys { + signers, + key_ids, + signer_key_ids, + }; let key_ids = vec![id + 1]; @@ -99,13 +114,15 @@ impl SignerStateMachine { let state_machine = WstsStateMachine::new( threshold, + dkg_threshold, num_parties, num_keys, id, key_ids, signer_private_key.into(), public_keys, - ); + ) + .map_err(Error::Wsts)?; Ok(Self(state_machine)) }