Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
7d2c988
feat(crypto): CRP-2618 allow omitting pre_signature_to_create_in_adva…
fspreiss Nov 26, 2025
a5e83ae
clippy
fspreiss Nov 27, 2025
3effb13
clippy
fspreiss Nov 27, 2025
e9b7538
fix tests
fspreiss Nov 27, 2025
5f76711
Merge branch 'master' into franzstefan/CRP-2618-empty-pre-sig-to-crea…
fspreiss Dec 8, 2025
24c324c
start to add tests
fspreiss Dec 9, 2025
8ee0e68
Merge branch 'master' into franzstefan/CRP-2618-empty-pre-sig-to-crea…
fspreiss Dec 12, 2025
0b9f27e
update ic-admin: require field to be present
fspreiss Dec 12, 2025
a6ee6f3
fmt
fspreiss Dec 12, 2025
de3a495
cleanup
fspreiss Dec 12, 2025
d6fc7df
fix compiler issues
fspreiss Dec 12, 2025
b453670
add tests
fspreiss Dec 12, 2025
8239910
fix recovery test
fspreiss Dec 13, 2025
6767e6b
Merge branch 'master' into franzstefan/CRP-2618-empty-pre-sig-to-crea…
fspreiss Dec 16, 2025
07069b0
registry canister changelog
fspreiss Dec 17, 2025
4f8e5b3
Address review comments.
fspreiss Dec 17, 2025
74da19d
Add two tests
fspreiss Dec 18, 2025
ce73375
Address many review comments
fspreiss Jan 6, 2026
10eee83
Refactor tests to remove code duplication
fspreiss Jan 6, 2026
7416a11
Make invaraint check more concise.
fspreiss Jan 6, 2026
3752ec9
Merge branch 'master' into franzstefan/CRP-2618-empty-pre-sig-to-crea…
fspreiss Jan 6, 2026
ddeb9a2
Simplify panic unit tests in rs/registry/admin/bin
fspreiss Jan 8, 2026
e5c0aff
Turn panic tests into white-box tests
fspreiss Jan 8, 2026
4e0d695
Revert "Turn panic tests into white-box tests"
fspreiss Jan 8, 2026
897e8b5
Merge branch 'master' into franzstefan/CRP-2618-empty-pre-sig-to-crea…
fspreiss Jan 12, 2026
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
4 changes: 2 additions & 2 deletions rs/consensus/dkg/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1626,7 +1626,7 @@ mod tests {
.with_chain_key_config(ChainKeyConfig {
key_configs: vec![KeyConfig {
key_id: MasterPublicKeyId::VetKd(key_id.clone()),
pre_signatures_to_create_in_advance: 0,
pre_signatures_to_create_in_advance: None,
max_queue_size: 20,
}],
signature_request_timeout_ns: None,
Expand Down Expand Up @@ -2118,7 +2118,7 @@ mod tests {
ChainKeyConfig {
key_configs: vec![KeyConfig {
key_id: MasterPublicKeyId::VetKd(test_vet_key()),
pre_signatures_to_create_in_advance: 0,
pre_signatures_to_create_in_advance: None,
max_queue_size: 20,
}],
signature_request_timeout_ns: None,
Expand Down
6 changes: 3 additions & 3 deletions rs/consensus/dkg/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,23 +191,23 @@ mod tests {
algorithm: SchnorrAlgorithm::Ed25519,
name: String::from("schnorr_key_to_ignore"),
}),
pre_signatures_to_create_in_advance: 50,
pre_signatures_to_create_in_advance: Some(50),
max_queue_size: 50,
},
KeyConfig {
key_id: MasterPublicKeyId::VetKd(VetKdKeyId {
curve: VetKdCurve::Bls12_381_G2,
name: String::from("first_vet_kd_key"),
}),
pre_signatures_to_create_in_advance: 0,
pre_signatures_to_create_in_advance: None,
max_queue_size: 50,
},
KeyConfig {
key_id: MasterPublicKeyId::VetKd(VetKdKeyId {
curve: VetKdCurve::Bls12_381_G2,
name: String::from("second_vet_kd_key"),
}),
pre_signatures_to_create_in_advance: 0,
pre_signatures_to_create_in_advance: None,
max_queue_size: 50,
},
],
Expand Down
8 changes: 4 additions & 4 deletions rs/consensus/idkg/src/payload_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1010,7 +1010,7 @@ mod tests {
let chain_key_config = ChainKeyConfig {
key_configs: vec![KeyConfig {
key_id: key_id.clone().into(),
pre_signatures_to_create_in_advance: PRE_SIGNATURES_TO_CREATE_IN_ADVANCE,
pre_signatures_to_create_in_advance: Some(PRE_SIGNATURES_TO_CREATE_IN_ADVANCE),
max_queue_size: 1,
}],
..ChainKeyConfig::default()
Expand Down Expand Up @@ -2355,7 +2355,7 @@ mod tests {
let chain_key_config = ChainKeyConfig {
key_configs: vec![KeyConfig {
key_id: key_id.clone().into(),
pre_signatures_to_create_in_advance: 1,
pre_signatures_to_create_in_advance: Some(1),
max_queue_size: 1,
}],
signature_request_timeout_ns: Some(100000),
Expand Down Expand Up @@ -2458,7 +2458,7 @@ mod tests {
let chain_key_config = ChainKeyConfig {
key_configs: vec![KeyConfig {
key_id: key_id.clone().into(),
pre_signatures_to_create_in_advance: 1,
pre_signatures_to_create_in_advance: Some(1),
max_queue_size: 1,
}],
signature_request_timeout_ns: Some(100000),
Expand Down Expand Up @@ -2617,7 +2617,7 @@ mod tests {
let chain_key_config = ChainKeyConfig {
key_configs: vec![KeyConfig {
key_id: key_id.clone().into(),
pre_signatures_to_create_in_advance: 1,
pre_signatures_to_create_in_advance: Some(1),
max_queue_size: 1,
}],
signature_request_timeout_ns: Some(100000),
Expand Down
11 changes: 6 additions & 5 deletions rs/consensus/idkg/src/payload_builder/pre_signatures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,8 @@ fn make_new_pre_signatures_if_needed_helper(
.key_configs
.iter()
.find(|key_config| &key_config.key_id == key_id.inner())
.map(|key_config| key_config.pre_signatures_to_create_in_advance as usize)
.and_then(|key_config| key_config.pre_signatures_to_create_in_advance)
.map(|pre_sigs_to_create| pre_sigs_to_create as usize)
else {
return new_pre_signatures;
};
Expand Down Expand Up @@ -592,7 +593,7 @@ pub(super) fn make_new_pre_signatures_by_priority(
};
let max_stash_size = chain_key_config
.key_config(key_id.inner())
.map(|config| config.pre_signatures_to_create_in_advance)
.and_then(|config| config.pre_signatures_to_create_in_advance)
.unwrap_or_default();
priority_queue.push(PrioritizedStash {
count: *total_pre_signatures.get(key_id).unwrap_or(&0),
Expand Down Expand Up @@ -1107,7 +1108,7 @@ pub(super) mod tests {
.into_iter()
.map(|(key_id, max)| KeyConfig {
key_id: key_id.inner().clone(),
pre_signatures_to_create_in_advance: max as u32,
pre_signatures_to_create_in_advance: Some(max as u32),
max_queue_size: 20,
})
.collect(),
Expand Down Expand Up @@ -1417,7 +1418,7 @@ pub(super) mod tests {
let chain_key_config = ChainKeyConfig {
key_configs: vec![KeyConfig {
key_id: key_id.clone().into(),
pre_signatures_to_create_in_advance,
pre_signatures_to_create_in_advance: Some(pre_signatures_to_create_in_advance),
max_queue_size: 1,
}],
..ChainKeyConfig::default()
Expand Down Expand Up @@ -1483,7 +1484,7 @@ pub(super) mod tests {
let chain_key_config = ChainKeyConfig {
key_configs: vec![KeyConfig {
key_id: key_id.clone().into(),
pre_signatures_to_create_in_advance,
pre_signatures_to_create_in_advance: Some(pre_signatures_to_create_in_advance),
max_queue_size: 1,
}],
..ChainKeyConfig::default()
Expand Down
95 changes: 89 additions & 6 deletions rs/consensus/idkg/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,12 @@ pub fn get_idkg_chain_key_config_if_enabled(
// Skip keys that don't need to run IDKG protocol
.filter(|key_config| key_config.key_id.is_idkg_key())
// A key that has `presignatures_to_create_in_advance` set to 0 is not active
.filter(|key_config| key_config.pre_signatures_to_create_in_advance != 0)
.filter(|key_config| {
key_config
.pre_signatures_to_create_in_advance
.unwrap_or_default()
!= 0
})
.count();

if num_active_key_ids == 0 {
Expand Down Expand Up @@ -623,6 +628,7 @@ mod tests {
IDkgPayloadTestHelper, create_available_pre_signature_with_key_transcript_and_height,
set_up_idkg_payload,
};
use assert_matches::assert_matches;
use ic_config::artifact_pool::ArtifactPoolConfig;
use ic_consensus_mocks::{Dependencies, dependencies};
use ic_crypto_test_utils_canister_threshold_sigs::{
Expand All @@ -631,7 +637,7 @@ mod tests {
};
use ic_crypto_test_utils_reproducible_rng::reproducible_rng;
use ic_logger::no_op_logger;
use ic_management_canister_types_private::{EcdsaKeyId, SchnorrKeyId};
use ic_management_canister_types_private::{EcdsaKeyId, SchnorrKeyId, VetKdKeyId};
use ic_protobuf::registry::subnet::v1::EcdsaInitialization;
use ic_registry_client_fake::FakeRegistryClient;
use ic_registry_subnet_features::KeyConfig;
Expand Down Expand Up @@ -835,7 +841,7 @@ mod tests {
key_id: MasterPublicKeyId::Ecdsa(
EcdsaKeyId::from_str("Secp256k1:some_key").unwrap(),
),
pre_signatures_to_create_in_advance: 1,
pre_signatures_to_create_in_advance: Some(1),
max_queue_size: 3,
}],
..ChainKeyConfig::default()
Expand All @@ -859,14 +865,14 @@ mod tests {
key_id: MasterPublicKeyId::Ecdsa(
EcdsaKeyId::from_str("Secp256k1:some_key_1").unwrap(),
),
pre_signatures_to_create_in_advance: 1,
pre_signatures_to_create_in_advance: Some(1),
max_queue_size: 3,
};
let key_config_2 = KeyConfig {
key_id: MasterPublicKeyId::Schnorr(
SchnorrKeyId::from_str("Ed25519:some_key_2").unwrap(),
),
pre_signatures_to_create_in_advance: 1,
pre_signatures_to_create_in_advance: Some(1),
max_queue_size: 3,
};

Expand Down Expand Up @@ -900,7 +906,7 @@ mod tests {
key_id: MasterPublicKeyId::Ecdsa(
EcdsaKeyId::from_str("Secp256k1:some_key").unwrap(),
),
pre_signatures_to_create_in_advance: 0,
pre_signatures_to_create_in_advance: Some(0),
max_queue_size: 3,
}],
..ChainKeyConfig::default()
Expand All @@ -916,6 +922,83 @@ mod tests {
})
}

#[test]
fn test_get_chain_key_config_if_enabled_malformed_with_pre_sigs_to_create_for_ecdsa_being_none()
{
ic_test_utilities::artifact_pool_config::with_test_pool_config(|pool_config| {
let malformed_chain_key_config = ChainKeyConfig {
key_configs: vec![KeyConfig {
key_id: MasterPublicKeyId::Ecdsa(
EcdsaKeyId::from_str("Secp256k1:some_key").unwrap(),
),
pre_signatures_to_create_in_advance: None,
max_queue_size: 3,
}],
..ChainKeyConfig::default()
};
let (subnet_id, registry, version) =
set_up_get_chain_key_config_test(&malformed_chain_key_config, pool_config);

let result =
get_idkg_chain_key_config_if_enabled(subnet_id, version, registry.as_ref());

assert_matches!(result, Err(RegistryClientError::DecodeError{ error })
if error.contains("\
failed with Missing required struct field: \
KeyConfig::pre_signatures_to_create_in_advance\
")
);
})
}

#[test]
fn test_get_chain_key_config_if_enabled_malformed_with_pre_sigs_to_create_for_vetkd_being_some_0()
{
ic_test_utilities::artifact_pool_config::with_test_pool_config(|pool_config| {
let malformed_chain_key_config = ChainKeyConfig {
key_configs: vec![KeyConfig {
key_id: MasterPublicKeyId::VetKd(
VetKdKeyId::from_str("Bls12_381_G2:some_key").unwrap(),
),
pre_signatures_to_create_in_advance: Some(0),
max_queue_size: 3,
}],
..ChainKeyConfig::default()
};
let (subnet_id, registry, version) =
set_up_get_chain_key_config_test(&malformed_chain_key_config, pool_config);

let config =
get_idkg_chain_key_config_if_enabled(subnet_id, version, registry.as_ref());

assert_matches!(config, Ok(None));
})
}

#[test]
fn test_get_chain_key_config_if_enabled_malformed_with_pre_sigs_to_create_for_vetkd_being_some_1()
{
ic_test_utilities::artifact_pool_config::with_test_pool_config(|pool_config| {
let malformed_chain_key_config = ChainKeyConfig {
key_configs: vec![KeyConfig {
key_id: MasterPublicKeyId::VetKd(
VetKdKeyId::from_str("Bls12_381_G2:some_key").unwrap(),
),
pre_signatures_to_create_in_advance: Some(1),
max_queue_size: 3,
}],
..ChainKeyConfig::default()
};
let (subnet_id, registry, version) =
set_up_get_chain_key_config_test(&malformed_chain_key_config, pool_config);

let config =
get_idkg_chain_key_config_if_enabled(subnet_id, version, registry.as_ref());

assert_matches!(config, Ok(None));
})
}

fn add_available_pre_signatures_with_key_transcript(
idkg_payload: &mut IDkgPayload,
key_transcript: UnmaskedTranscript,
Expand Down
8 changes: 3 additions & 5 deletions rs/consensus/tests/framework/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,9 @@ pub fn setup_subnet<R: Rng + CryptoRng>(
.iter()
.map(|key_id| KeyConfig {
key_id: key_id.clone(),
pre_signatures_to_create_in_advance: if key_id.requires_pre_signatures() {
4
} else {
0
},
pre_signatures_to_create_in_advance: key_id
.requires_pre_signatures()
.then_some(4),
max_queue_size: 40,
})
.collect(),
Expand Down
2 changes: 1 addition & 1 deletion rs/consensus/vetkd/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1066,7 +1066,7 @@ mod tests {
key_id: MasterPublicKeyId::VetKd(
VetKdKeyId::from_str("bls12_381_g2:unused_key").unwrap(),
),
pre_signatures_to_create_in_advance: 0,
pre_signatures_to_create_in_advance: None,
max_queue_size: 3,
}],
..ChainKeyConfig::default()
Expand Down
6 changes: 3 additions & 3 deletions rs/consensus/vetkd/src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,19 +82,19 @@ pub(super) fn as_past_payload(payload: &[u8]) -> PastPayload<'_> {
pub(super) fn make_chain_key_config() -> ChainKeyConfig {
let key_config = KeyConfig {
key_id: MasterPublicKeyId::Ecdsa(EcdsaKeyId::from_str("Secp256k1:some_key_1").unwrap()),
pre_signatures_to_create_in_advance: 1,
pre_signatures_to_create_in_advance: Some(1),
max_queue_size: 3,
};
let key_config_1 = KeyConfig {
key_id: MasterPublicKeyId::VetKd(VetKdKeyId::from_str("bls12_381_g2:some_key").unwrap()),
pre_signatures_to_create_in_advance: 0,
pre_signatures_to_create_in_advance: None,
max_queue_size: 3,
};
let key_config_2 = KeyConfig {
key_id: MasterPublicKeyId::VetKd(
VetKdKeyId::from_str("bls12_381_g2:some_other_key").unwrap(),
),
pre_signatures_to_create_in_advance: 0,
pre_signatures_to_create_in_advance: None,
max_queue_size: 3,
};

Expand Down
4 changes: 3 additions & 1 deletion rs/execution_environment/src/scheduler/test_utilities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -878,7 +878,9 @@ impl SchedulerTestBuilder {
key_id.clone(),
ChainKeySettings {
max_queue_size: 20,
pre_signatures_to_create_in_advance: 5,
pre_signatures_to_create_in_advance: key_id
.requires_pre_signatures()
.then_some(5),
},
);
}
Expand Down
16 changes: 13 additions & 3 deletions rs/execution_environment/src/scheduler/threshold_signatures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,11 @@ pub(crate) fn update_signature_request_contexts(
let max_stash_size = registry_settings
.chain_key_settings
.get(&key_id)
.map(|setting| setting.pre_signatures_to_create_in_advance)
.map(|setting| {
setting
.pre_signatures_to_create_in_advance
.unwrap_or_default()
})
.unwrap_or_default() as usize;
let exceeding = stash.pre_signatures.len().saturating_sub(max_stash_size);
if exceeding > 0 {
Expand Down Expand Up @@ -127,7 +131,11 @@ pub(crate) fn update_signature_request_contexts(
let max_ongoing_signatures = registry_settings
.chain_key_settings
.get(&key_id)
.map(|setting| setting.pre_signatures_to_create_in_advance)
.map(|setting| {
setting
.pre_signatures_to_create_in_advance
.unwrap_or_default()
})
.unwrap_or_default() as usize;

match_delivered_pre_signatures_by_key_id(
Expand Down Expand Up @@ -633,7 +641,9 @@ mod tests {
.map(|key_id| {
let settings = ChainKeySettings {
max_queue_size: 20,
pre_signatures_to_create_in_advance: max_stash_size,
pre_signatures_to_create_in_advance: key_id
.requires_pre_signatures()
.then_some(max_stash_size),
};
(key_id.inner().clone(), settings)
})
Expand Down
2 changes: 1 addition & 1 deletion rs/interfaces/src/execution_environment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1462,7 +1462,7 @@ pub struct RegistryExecutionSettings {
#[derive(Clone, Eq, PartialEq, Debug)]
pub struct ChainKeySettings {
pub max_queue_size: u32,
pub pre_signatures_to_create_in_advance: u32,
pub pre_signatures_to_create_in_advance: Option<u32>,
}

pub trait Scheduler: Send {
Expand Down
Loading
Loading