Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions crates/node/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::primitives::ParticipantId;
use mpc_node_config::{AuthConfig, ConfigFile};
use mpc_primitives::ReconstructionThreshold;

use anyhow::Context;
use ed25519_dalek::{SigningKey, VerifyingKey};
Expand Down Expand Up @@ -62,11 +63,24 @@ impl MpcConfig {

#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct ParticipantsConfig {
/// The threshold for the MPC protocol.
pub threshold: u64,
/// The threshold for the MPC protocol — number of share-holders required
/// to reconstruct the secret. Wire format is a plain integer (the inner
/// type is `#[serde(transparent)]`), so this is wire-compatible with the
/// previous `u64` field.
pub threshold: ReconstructionThreshold,
Comment on lines +66 to +70
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Isn't this the governance threshold now? Do we want to have a separate notion between governance and reconstruction threshold? Otherwise, could we get rid of the existing Threshold type in our primitives crate favor of just having the ReconstructionThreshold everywhere?

pub participants: Vec<ParticipantInfo>,
}

impl ParticipantsConfig {
/// The threshold expressed in the form the threshold-signatures crypto
/// library consumes (a `usize`-backed `ReconstructionThreshold`).
pub fn ts_threshold(&self) -> anyhow::Result<threshold_signatures::ReconstructionThreshold> {
Ok(threshold_signatures::ReconstructionThreshold::from(
usize::try_from(self.threshold.inner())?,
))
}
}

#[cfg(test)]
impl ParticipantsConfig {
pub fn change_participant_pk(
Expand Down Expand Up @@ -563,7 +577,7 @@ pub mod tests {
let participant = gen_participant();
let non_participant = gen_participant();
let bogus_config = ParticipantsConfig {
threshold: 3,
threshold: ReconstructionThreshold::new(3),
participants: vec![participant.clone()],
};
assert_matches!(
Expand Down
9 changes: 3 additions & 6 deletions crates/node/src/coordinator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ use near_time::Clock;
use std::collections::HashMap;
use std::future::Future;
use std::sync::{Arc, Mutex};
use threshold_signatures::ReconstructionLowerBound;
use threshold_signatures::{confidential_key_derivation, ecdsa, frost::eddsa};
use tokio::select;
use tokio::sync::mpsc::unbounded_channel;
Expand Down Expand Up @@ -292,8 +291,7 @@ where
let (sender, receiver) = new_tls_mesh_network(&mpc_config, p2p_key).await?;
let (network_client, channel_receiver, _handle) =
run_network_client(Arc::new(sender), Box::new(receiver));
let threshold: usize = mpc_config.participants.threshold.try_into()?;
let threshold = ReconstructionLowerBound::from(threshold);
let threshold = mpc_config.participants.ts_threshold()?;
if mpc_config.is_leader_for_key_event() {
keygen_leader(
network_client,
Expand Down Expand Up @@ -520,7 +518,7 @@ where

sender
.wait_for_ready(
running_mpc_config.participants.threshold.try_into()?,
usize::try_from(running_mpc_config.participants.threshold.inner())?,
&running_participant_ids,
)
.await?;
Expand Down Expand Up @@ -718,11 +716,10 @@ where
None
};

let new_threshold: usize = mpc_config.participants.threshold.try_into()?;
let args = Arc::new(ResharingArgs {
previous_keyset,
existing_keyshares,
new_threshold: ReconstructionLowerBound::from(new_threshold),
new_threshold: mpc_config.participants.ts_threshold()?,
old_participants: current_running_state.participants,
});

Expand Down
6 changes: 5 additions & 1 deletion crates/node/src/indexer/fake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,11 @@ fn participants_config_to_threshold_parameters(
)
.expect("Failed to insert participant");
}
ThresholdParameters::new(participants, Threshold::new(participants_config.threshold)).unwrap()
ThresholdParameters::new(
participants,
Threshold::new(participants_config.threshold.inner()),
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Hmm, this type has not been renamed. It feels weird to just cast the reconstruction threshold to this other type here. Shouldn't this also be the ReconstructionThreshold so we don't have any ambiguous "threshold" concepts remaining? Long term I guess this should become the governance threshold, but if this is the case, we should already have the governance threshold in participants_config imo where we now have ReconstructionThreshold.

So I suggest one of two things:

  1. Use ReconstructionThreshold everywhere.
  2. Rename the existing primitiveThreshold type used in the contract for voting operations to GovernanceThreshold and separate the governance and reconstruction thresholds.

The second option seems like it deserves its own issue, so I'd lean on 1. here.

)
.unwrap()
}

/// Runs the fake indexer's shared state and logic. There's one instance of this per test.
Expand Down
7 changes: 4 additions & 3 deletions crates/node/src/indexer/participants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ pub fn convert_participant_infos(
}
Ok(ParticipantsConfig {
participants: converted,
threshold: threshold_parameters.threshold.0,
threshold: threshold_parameters.threshold.into(),
})
}

Expand Down Expand Up @@ -401,7 +401,8 @@ mod tests {
use near_indexer_primitives::types::AccountId;
use near_mpc_contract_interface::types::AccountId as DtoAccountId;
use near_mpc_contract_interface::types::{
ParticipantId, ParticipantInfo, Participants, Threshold, ThresholdParameters,
ParticipantId, ParticipantInfo, Participants, ReconstructionThreshold, Threshold,
ThresholdParameters,
};
use std::collections::HashMap;

Expand Down Expand Up @@ -493,7 +494,7 @@ mod tests {
};

let converted = convert_participant_infos(params, None).unwrap();
assert_eq!(converted.threshold, 3);
assert_eq!(converted.threshold, ReconstructionThreshold::new(3));
for (i, p) in converted.participants.iter().enumerate() {
assert!(p.near_account_id == account_ids[i]);
let expected_pk: near_sdk::PublicKey = account_id_to_pk[&account_ids[i]].clone().into();
Expand Down
16 changes: 8 additions & 8 deletions crates/node/src/key_events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use near_mpc_crypto_types::{KeyForDomain, Keyset};
use std::sync::Arc;
use std::time::Duration;
use threshold_signatures::{
confidential_key_derivation as ckd, frost_ed25519, frost_secp256k1, ReconstructionLowerBound,
confidential_key_derivation as ckd, frost_ed25519, frost_secp256k1, ReconstructionThreshold,
};
use tokio::sync::{mpsc, watch, RwLock};
use tokio::time::timeout;
Expand All @@ -47,7 +47,7 @@ pub async fn keygen_computation_inner(
generated_keys: Vec<KeyForDomain>,
key_id: KeyEventId,
domain: DomainConfig,
threshold: ReconstructionLowerBound,
threshold: ReconstructionThreshold,
) -> anyhow::Result<()> {
anyhow::ensure!(key_id.domain_id == domain.id, "Domain mismatch");
let keyshare_handle = keyshare_storage
Expand Down Expand Up @@ -124,7 +124,7 @@ async fn keygen_computation(
keyshare_storage: Arc<RwLock<KeyshareStorage>>,
chain_txn_sender: impl TransactionSender,
key_id: KeyEventId,
threshold: ReconstructionLowerBound,
threshold: ReconstructionThreshold,
) -> anyhow::Result<()> {
let key_event = wait_for_contract_catchup(&mut contract_key_event_id, key_id).await;
let inner = keygen_computation_inner(
Expand Down Expand Up @@ -160,7 +160,7 @@ async fn keygen_computation(
pub struct ResharingArgs {
pub previous_keyset: Keyset,
pub existing_keyshares: Option<Vec<Keyshare>>,
pub new_threshold: ReconstructionLowerBound,
pub new_threshold: ReconstructionThreshold,
pub old_participants: ParticipantsConfig,
}

Expand Down Expand Up @@ -416,7 +416,7 @@ pub async fn keygen_leader(
keyshare_storage: Arc<RwLock<KeyshareStorage>>,
mut key_event_receiver: watch::Receiver<ContractKeyEventInstance>,
chain_txn_sender: impl TransactionSender,
threshold: ReconstructionLowerBound,
threshold: ReconstructionThreshold,
) -> anyhow::Result<()> {
loop {
// Wait for all participants to be connected. Otherwise, computations are most likely going
Expand Down Expand Up @@ -500,7 +500,7 @@ pub async fn keygen_follower(
keyshare_storage: Arc<RwLock<KeyshareStorage>>,
key_event_receiver: watch::Receiver<ContractKeyEventInstance>,
chain_txn_sender: impl TransactionSender + 'static,
threshold: ReconstructionLowerBound,
threshold: ReconstructionThreshold,
) -> anyhow::Result<()> {
let mut tasks = AutoAbortTaskCollection::new();
loop {
Expand Down Expand Up @@ -900,9 +900,9 @@ mod tests {
Arc::new(ResharingArgs {
previous_keyset: Keyset::new(EpochId::new(5), vec![]),
existing_keyshares: None,
new_threshold: ReconstructionLowerBound::from(3),
new_threshold: threshold_signatures::ReconstructionThreshold::from(3usize),
old_participants: ParticipantsConfig {
threshold: 3,
threshold: mpc_primitives::ReconstructionThreshold::new(3),
participants: vec![],
},
})
Expand Down
2 changes: 1 addition & 1 deletion crates/node/src/p2p.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1026,7 +1026,7 @@ pub mod testing {
let mut configs = Vec::new();
for (i, singing_key) in p2p_keypairs.into_iter().enumerate() {
let participants = ParticipantsConfig {
threshold: threshold as u64,
threshold: mpc_primitives::ReconstructionThreshold::new(threshold as u64),
participants: participants.clone(),
};

Expand Down
6 changes: 3 additions & 3 deletions crates/node/src/providers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub use ecdsa::EcdsaSignatureProvider;
pub use ecdsa::EcdsaTaskId;
pub use robust_ecdsa::RobustEcdsaSignatureProvider;
use std::sync::Arc;
use threshold_signatures::ReconstructionLowerBound;
use threshold_signatures::ReconstructionThreshold;

/// The interface that defines the requirements for a signing schema to be correctly used in the code.
pub trait SignatureProvider {
Expand Down Expand Up @@ -51,15 +51,15 @@ pub trait SignatureProvider {
///
/// It drains `channel_receiver` until the required task is found, meaning these clients must not be run in parallel.
async fn run_key_generation_client(
threshold: ReconstructionLowerBound,
threshold: ReconstructionThreshold,
channel: NetworkTaskChannel,
) -> anyhow::Result<Self::KeygenOutput>;

/// Executes the key resharing protocol. This can only succeed if all new participants are online.
/// Both leaders and followers call this function.
/// It drains `channel_receiver` until the required task is found, meaning these clients must not be run in parallel.
async fn run_key_resharing_client(
new_threshold: ReconstructionLowerBound,
new_threshold: ReconstructionThreshold,
key_share: Option<Self::SecretShare>,
public_key: Self::PublicKey,
old_participants: &ParticipantsConfig,
Expand Down
6 changes: 3 additions & 3 deletions crates/node/src/providers/ckd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use threshold_signatures::confidential_key_derivation::{
ElementG1, KeygenOutput, SigningShare, VerifyingKey,
};

use threshold_signatures::ReconstructionLowerBound;
use threshold_signatures::ReconstructionThreshold;

use mpc_node_config::ConfigFile;

Expand Down Expand Up @@ -79,14 +79,14 @@ impl SignatureProvider for CKDProvider {
}

async fn run_key_generation_client(
threshold: ReconstructionLowerBound,
threshold: ReconstructionThreshold,
channel: NetworkTaskChannel,
) -> anyhow::Result<Self::KeygenOutput> {
Self::run_key_generation_client_internal(threshold, channel).await
}

async fn run_key_resharing_client(
new_threshold: ReconstructionLowerBound,
new_threshold: ReconstructionThreshold,
key_share: Option<SigningShare>,
public_key: VerifyingKey,
old_participants: &ParticipantsConfig,
Expand Down
10 changes: 5 additions & 5 deletions crates/node/src/providers/ckd/key_generation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ use rand::rngs::OsRng;
use threshold_signatures::confidential_key_derivation::KeygenOutput;
use threshold_signatures::confidential_key_derivation::BLS12381SHA256;
use threshold_signatures::participants::Participant;
use threshold_signatures::ReconstructionLowerBound;
use threshold_signatures::ReconstructionThreshold;

impl CKDProvider {
pub(super) async fn run_key_generation_client_internal(
threshold: ReconstructionLowerBound,
threshold: ReconstructionThreshold,
channel: NetworkTaskChannel,
) -> anyhow::Result<KeygenOutput> {
let key = KeyGenerationComputation { threshold }
Expand All @@ -25,7 +25,7 @@ impl CKDProvider {
/// Runs the key generation protocol, returning the key generated.
/// This protocol is identical for the leader and the followers.
pub struct KeyGenerationComputation {
threshold: ReconstructionLowerBound,
threshold: ReconstructionThreshold,
}

#[async_trait::async_trait]
Expand Down Expand Up @@ -68,7 +68,7 @@ mod tests {
use threshold_signatures::frost_core::Group;
use threshold_signatures::participants::Participant;
use threshold_signatures::test_utils::generate_participants;
use threshold_signatures::ReconstructionLowerBound;
use threshold_signatures::ReconstructionThreshold;
use threshold_signatures::{confidential_key_derivation as ckd, ParticipantList};
use tokio::sync::mpsc;

Expand Down Expand Up @@ -120,7 +120,7 @@ mod tests {
.ok_or_else(|| anyhow::anyhow!("No channel"))?
};
let key = KeyGenerationComputation {
threshold: ReconstructionLowerBound::from(3),
threshold: ReconstructionThreshold::from(3),
}
.perform_leader_centric_computation(channel, std::time::Duration::from_secs(60))
.await?;
Expand Down
17 changes: 8 additions & 9 deletions crates/node/src/providers/ckd/key_resharing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,20 @@ use threshold_signatures::confidential_key_derivation::KeygenOutput;
use threshold_signatures::confidential_key_derivation::SigningShare;
use threshold_signatures::confidential_key_derivation::{VerifyingKey, BLS12381SHA256};
use threshold_signatures::participants::Participant;
use threshold_signatures::ReconstructionLowerBound;
use threshold_signatures::ReconstructionThreshold;

impl CKDProvider {
pub(super) async fn run_key_resharing_client_internal(
new_threshold: ReconstructionLowerBound,
new_threshold: ReconstructionThreshold,
my_share: Option<SigningShare>,
public_key: VerifyingKey,
old_participants: &ParticipantsConfig,
channel: NetworkTaskChannel,
) -> anyhow::Result<KeygenOutput> {
let old_threshold: usize = old_participants.threshold.try_into()?;
let new_keyshare = KeyResharingComputation {
threshold: new_threshold,
old_participants: old_participants.participants.iter().map(|p| p.id).collect(),
old_threshold: ReconstructionLowerBound::from(old_threshold),
old_threshold: old_participants.ts_threshold()?,
my_share,
public_key,
}
Expand All @@ -49,9 +48,9 @@ impl CKDProvider {
/// the old threshold; or
/// - the threshold is larger than the number of participants.
pub struct KeyResharingComputation {
threshold: ReconstructionLowerBound,
threshold: ReconstructionThreshold,
old_participants: Vec<ParticipantId>,
old_threshold: ReconstructionLowerBound,
old_threshold: ReconstructionThreshold,
my_share: Option<SigningShare>,
public_key: VerifyingKey,
}
Expand Down Expand Up @@ -109,7 +108,7 @@ mod tests {
use threshold_signatures::frost_core::Group;
use threshold_signatures::participants::Participant;
use threshold_signatures::test_utils::{generate_participants_with_random_ids, run_keygen};
use threshold_signatures::ReconstructionLowerBound;
use threshold_signatures::ReconstructionThreshold;
use threshold_signatures::{confidential_key_derivation as ckd, ParticipantList};
use tokio::sync::mpsc;

Expand Down Expand Up @@ -155,9 +154,9 @@ mod tests {
.ok_or_else(|| anyhow::anyhow!("No channel"))?
};
let key = KeyResharingComputation {
threshold: ReconstructionLowerBound::from(THRESHOLD),
threshold: ReconstructionThreshold::from(THRESHOLD),
old_participants,
old_threshold: ReconstructionLowerBound::from(THRESHOLD),
old_threshold: ReconstructionThreshold::from(THRESHOLD),
my_share: keyshare,
public_key: pubkey,
}
Expand Down
4 changes: 1 addition & 3 deletions crates/node/src/providers/ckd/sign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use threshold_signatures::{
VerifyingKey,
},
participants::Participant,
ReconstructionLowerBound,
};

use crate::metrics;
Expand All @@ -29,8 +28,7 @@ impl CKDProvider {
) -> anyhow::Result<((ElementG1, ElementG1), VerifyingKey)> {
let ckd_request = self.ckd_request_store.get(id).await?;

let threshold: usize = self.mpc_config.participants.threshold.try_into()?;
let threshold = ReconstructionLowerBound::from(threshold);
let threshold = self.mpc_config.participants.ts_threshold()?;
let running_participants: Vec<_> = self
.mpc_config
.participants
Expand Down
Loading