Skip to content

Commit

Permalink
feat: Run ecdsa component in consensus test framework
Browse files Browse the repository at this point in the history
  • Loading branch information
ninegua committed Jan 10, 2024
1 parent eee4085 commit 09bb6f3
Show file tree
Hide file tree
Showing 7 changed files with 159 additions and 43 deletions.
36 changes: 33 additions & 3 deletions rs/consensus/tests/framework/driver.rs
@@ -1,13 +1,15 @@
pub use super::types::*;
use ic_artifact_pool::{
certification_pool::CertificationPoolImpl, consensus_pool::ConsensusPoolImpl, dkg_pool,
certification_pool::CertificationPoolImpl, consensus_pool::ConsensusPoolImpl,
dkg_pool::DkgPoolImpl, ecdsa_pool::EcdsaPoolImpl,
};
use ic_config::artifact_pool::ArtifactPoolConfig;
use ic_consensus::consensus::ConsensusGossipImpl;
use ic_interfaces::{
certification,
consensus_pool::{ChangeAction, ChangeSet as ConsensusChangeSet},
dkg::ChangeAction as DkgChangeAction,
ecdsa::EcdsaChangeAction,
p2p::consensus::{ChangeSetProducer, MutablePool},
};
use ic_logger::{debug, ReplicaLogger};
Expand All @@ -28,11 +30,13 @@ impl<'a> ConsensusDriver<'a> {
consensus: Box<dyn ChangeSetProducer<ConsensusPoolImpl, ChangeSet = ConsensusChangeSet>>,
consensus_gossip: ConsensusGossipImpl,
dkg: ic_consensus::dkg::DkgImpl,
ecdsa: ic_consensus::ecdsa::EcdsaImpl,
certifier: Box<
dyn ChangeSetProducer<CertificationPoolImpl, ChangeSet = certification::ChangeSet> + 'a,
>,
consensus_pool: Arc<RwLock<ConsensusPoolImpl>>,
dkg_pool: Arc<RwLock<dkg_pool::DkgPoolImpl>>,
dkg_pool: Arc<RwLock<DkgPoolImpl>>,
ecdsa_pool: Arc<RwLock<EcdsaPoolImpl>>,
logger: ReplicaLogger,
metrics_registry: MetricsRegistry,
) -> ConsensusDriver<'a> {
Expand All @@ -49,17 +53,19 @@ impl<'a> ConsensusDriver<'a> {
consensus,
consensus_gossip,
dkg,
ecdsa,
certifier,
logger,
consensus_pool,
certification_pool,
ingress_pool,
dkg_pool,
ecdsa_pool,
consensus_priority,
}
}

/// Run a single step of consensus, dkg and certification by repeatedly
/// Run a single step of consensus, dkg, certification, and ecdsa by repeatedly
/// calling on_state_change and apply the changes until no more changes
/// occur.
///
Expand Down Expand Up @@ -132,6 +138,30 @@ impl<'a> ConsensusDriver<'a> {
certification_pool.apply_changes(changeset);
}
}
loop {
let changeset = self
.ecdsa
.on_state_change(&*self.ecdsa_pool.read().unwrap());
if changeset.is_empty() {
break;
}
{
for change_action in &changeset {
match change_action {
EcdsaChangeAction::AddToValidated(msg) => {
debug!(self.logger, "Ecdsa Message Deliver {:?}", msg);
to_deliver.push(InputMessage::Ecdsa(msg.clone()));
}
EcdsaChangeAction::MoveToValidated(msg) => {
debug!(self.logger, "Ecdsa Message Validated {:?}", msg);
}
_ => {}
}
}
let mut ecdsa_pool = self.ecdsa_pool.write().unwrap();
ecdsa_pool.apply_changes(changeset);
}
}
to_deliver
}
}
Expand Down
8 changes: 8 additions & 0 deletions rs/consensus/tests/framework/execution.rs
Expand Up @@ -71,6 +71,14 @@ fn execute_instance(
timestamp,
});
}
InputMessage::Ecdsa(msg) => {
let mut ecdsa_pool = instance.driver.ecdsa_pool.write().unwrap();
ecdsa_pool.insert(UnvalidatedArtifact {
message: msg,
peer_id: node_test_id(0),
timestamp,
});
}
},
// Repeat the polling
Input::TimerExpired(x) => {
Expand Down
37 changes: 32 additions & 5 deletions rs/consensus/tests/framework/mod.rs
Expand Up @@ -10,16 +10,18 @@ mod types;
pub use runner::ConsensusRunner;
pub use types::{
ConsensusDependencies, ConsensusDriver, ConsensusInstance, ConsensusModifier,
ConsensusRunnerConfig,
ConsensusRunnerConfig, StopPredicate,
};

use ic_crypto_temp_crypto::{NodeKeysToGenerate, TempCryptoComponent, TempCryptoComponentGeneric};
use ic_crypto_test_utils_ni_dkg::{initial_dkg_transcript, InitialNiDkgConfig};
use ic_ic00_types::{EcdsaCurve, EcdsaKeyId};
use ic_interfaces_registry::RegistryClient;
use ic_protobuf::registry::subnet::v1::{CatchUpPackageContents, InitialNiDkgTranscriptRecord};
use ic_registry_client_fake::FakeRegistryClient;
use ic_registry_client_helpers::crypto::CryptoRegistry;
use ic_registry_proto_data_provider::ProtoRegistryDataProvider;
use ic_registry_subnet_features::EcdsaConfig;
use ic_test_utilities::consensus::make_genesis;
use ic_test_utilities_registry::SubnetRecordBuilder;
use ic_types::{
Expand All @@ -28,7 +30,7 @@ use ic_types::{
threshold_sig::ni_dkg::{NiDkgTag, NiDkgTargetId},
KeyPurpose,
},
NodeId, RegistryVersion, SubnetId,
subnet_id_into_protobuf, NodeId, RegistryVersion, SubnetId,
};
use rand::{CryptoRng, Rng, SeedableRng};
use rand_chacha::ChaCha20Rng;
Expand All @@ -54,7 +56,20 @@ pub fn setup_subnet<R: Rng + CryptoRng>(
let registry_version = RegistryVersion::from(initial_version);
let data_provider = Arc::new(ProtoRegistryDataProvider::new());
let registry_client = Arc::new(FakeRegistryClient::new(Arc::clone(&data_provider) as Arc<_>));
let subnet_record = SubnetRecordBuilder::from(node_ids).build();
let ecdsa_key_id = EcdsaKeyId {
curve: EcdsaCurve::Secp256k1,
name: "test_key".to_string(),
};
let subnet_record = SubnetRecordBuilder::from(node_ids)
.with_dkg_interval_length(19)
.with_ecdsa_config(EcdsaConfig {
quadruples_to_create_in_advance: 4,
key_ids: vec![ecdsa_key_id.clone()],
max_queue_size: Some(40),
signature_request_timeout_ns: None,
idkg_key_rotation_period_ms: None,
})
.build();
data_provider
.add(
&ic_registry_keys::make_subnet_record_key(subnet_id),
Expand All @@ -79,7 +94,7 @@ pub fn setup_subnet<R: Rng + CryptoRng>(
data_provider
.add(
&ic_registry_keys::make_node_record_key(*node),
RegistryVersion::from(initial_version),
registry_version,
Some(ic_protobuf::registry::node::v1::NodeRecord::default()),
)
.expect("Could not add node record.");
Expand Down Expand Up @@ -155,10 +170,22 @@ pub fn setup_subnet<R: Rng + CryptoRng>(
data_provider
.add(
&ic_registry_keys::make_catch_up_package_contents_key(subnet_id),
RegistryVersion::from(initial_version),
registry_version,
Some(subnet_dkg),
)
.expect("Could not add node record.");

// Add ECDSA signing subnet to registry
data_provider
.add(
&ic_registry_keys::make_ecdsa_signing_subnet_list_key(&ecdsa_key_id),
registry_version,
Some(ic_protobuf::registry::crypto::v1::EcdsaSigningSubnetList {
subnets: vec![subnet_id_into_protobuf(subnet_id)],
}),
)
.expect("Could not add ECDSA signing subnet list");

registry_client.reload();
registry_client.update_to_latest_version();

Expand Down
25 changes: 18 additions & 7 deletions rs/consensus/tests/framework/runner.rs
Expand Up @@ -5,7 +5,7 @@ use ic_config::artifact_pool::ArtifactPoolConfig;
use ic_consensus::consensus::dkg_key_manager::DkgKeyManager;
use ic_consensus::{
certification::{CertificationCrypto, CertifierImpl},
dkg,
dkg, ecdsa,
};
use ic_consensus_utils::crypto::ConsensusCrypto;
use ic_consensus_utils::membership::Membership;
Expand Down Expand Up @@ -45,7 +45,7 @@ pub struct ConsensusRunner<'a> {
idle_since: RefCell<Time>,
pub time: Arc<FastForwardTimeSource>,
pub instances: Vec<ConsensusInstance<'a>>,
pub(crate) stop_predicate: StopPredicate<'a>,
pub(crate) stop_predicate: StopPredicate,
pub(crate) logger: ReplicaLogger,
pub(crate) rng: RefCell<ChaChaRng>,
pub(crate) config: ConsensusRunnerConfig,
Expand Down Expand Up @@ -111,7 +111,7 @@ impl<'a> ConsensusRunner<'a> {
ConsensusRunner {
idle_since: RefCell::new(now),
instances: Vec::new(),
stop_predicate: &stop_immediately,
stop_predicate: Box::new(stop_immediately),
time: time_source,
logger,
config,
Expand Down Expand Up @@ -149,7 +149,7 @@ impl<'a> ConsensusRunner<'a> {
)));
let fake_local_store_certified_time_reader =
Arc::new(FakeLocalStoreCertifiedTimeReader::new(self.time.clone()));

let malicious_flags = MaliciousFlags::default();
let (consensus, consensus_gossip) = ic_consensus::consensus::setup(
deps.replica_config.clone(),
Arc::clone(&deps.registry_client),
Expand All @@ -166,20 +166,29 @@ impl<'a> ConsensusRunner<'a> {
deps.message_routing.clone(),
deps.state_manager.clone(),
Arc::clone(&self.time) as Arc<_>,
MaliciousFlags::default(),
malicious_flags.clone(),
deps.metrics_registry.clone(),
replica_logger.clone(),
fake_local_store_certified_time_reader,
0,
);
let dkg = dkg::DkgImpl::new(
deps.replica_config.node_id,
consensus_crypto,
Arc::clone(&consensus_crypto),
deps.consensus_pool.read().unwrap().get_cache(),
dkg_key_manager,
deps.metrics_registry.clone(),
replica_logger.clone(),
);
let ecdsa = ecdsa::EcdsaImpl::new(
deps.replica_config.node_id,
deps.consensus_pool.read().unwrap().get_block_cache(),
consensus_crypto,
deps.state_manager.clone(),
deps.metrics_registry.clone(),
replica_logger.clone(),
malicious_flags,
);
let certifier = CertifierImpl::new(
deps.replica_config.clone(),
membership,
Expand All @@ -206,9 +215,11 @@ impl<'a> ConsensusRunner<'a> {
modifier.unwrap_or_else(|| Box::new(|x| Box::new(x)))(consensus),
consensus_gossip,
dkg,
ecdsa,
Box::new(certifier),
deps.consensus_pool.clone(),
deps.dkg_pool.clone(),
deps.ecdsa_pool.clone(),
replica_logger,
deps.metrics_registry.clone(),
),
Expand All @@ -220,7 +231,7 @@ impl<'a> ConsensusRunner<'a> {
/// Run until the given StopPredicate becomes true for all instances.
/// Return true if it runs to completion according to StopPredicate.
/// Otherwise return false, which indicates the network has stalled.
pub fn run_until(&mut self, pred: StopPredicate<'a>) -> bool {
pub fn run_until(&mut self, pred: StopPredicate) -> bool {
info!(self.logger, "{}", &self.config);
self.stop_predicate = pred;
loop {
Expand Down
17 changes: 10 additions & 7 deletions rs/consensus/tests/framework/types.rs
Expand Up @@ -6,15 +6,15 @@ use ic_artifact_pool::{
use ic_config::artifact_pool::ArtifactPoolConfig;
use ic_consensus::{
consensus::{ConsensusGossipImpl, ConsensusImpl},
dkg,
dkg, ecdsa,
};
use ic_https_outcalls_consensus::test_utils::FakeCanisterHttpPayloadBuilder;
use ic_interfaces::{
batch_payload::BatchPayloadBuilder,
certification::ChangeSet,
consensus_pool::ChangeSet as ConsensusChangeSet,
ingress_manager::IngressSelector,
messaging::{MessageRouting, XNetPayloadBuilder},
messaging::XNetPayloadBuilder,
p2p::consensus::{ChangeSetProducer, PriorityFnAndFilterProducer},
self_validating_payload::SelfValidatingPayloadBuilder,
time_source::TimeSource,
Expand All @@ -36,8 +36,8 @@ use ic_types::{
artifact::{ArtifactKind, Priority, PriorityFn},
artifact_kind::ConsensusArtifact,
consensus::{
certification::CertificationMessage, dkg::Message as DkgMessage, CatchUpPackage,
ConsensusMessage,
certification::CertificationMessage, dkg::Message as DkgMessage, ecdsa::EcdsaMessage,
CatchUpPackage, ConsensusMessage,
},
replica_config::ReplicaConfig,
time::{Time, UNIX_EPOCH},
Expand Down Expand Up @@ -112,6 +112,7 @@ pub enum InputMessage {
Consensus(ConsensusMessage),
Dkg(Box<DkgMessage>),
Certification(CertificationMessage),
Ecdsa(EcdsaMessage),
}

/// A Message is a tuple of [`InputMessage`] with a timestamp.
Expand Down Expand Up @@ -173,8 +174,8 @@ pub struct ConsensusDependencies {
pub dkg_pool: Arc<RwLock<dkg_pool::DkgPoolImpl>>,
pub ecdsa_pool: Arc<RwLock<ecdsa_pool::EcdsaPoolImpl>>,
pub canister_http_pool: Arc<RwLock<canister_http_pool::CanisterHttpPoolImpl>>,
pub message_routing: Arc<dyn MessageRouting>,
pub state_manager: Arc<dyn StateManager<State = ReplicatedState>>,
pub message_routing: Arc<FakeMessageRouting>,
pub state_manager: Arc<FakeStateManager>,
pub replica_config: ReplicaConfig,
pub metrics_registry: MetricsRegistry,
pub registry_client: Arc<dyn RegistryClient>,
Expand Down Expand Up @@ -256,7 +257,7 @@ impl fmt::Display for ConsensusInstance<'_> {
/// This is the type of predicates used by the ConsensusRunner to determine
/// whether or not it should terminate. It is evaluated for all consensus
/// instances at every time step.
pub type StopPredicate<'a> = &'a dyn Fn(&ConsensusInstance<'a>) -> bool;
pub type StopPredicate = Box<dyn Fn(&ConsensusInstance<'_>) -> bool>;

pub(crate) struct PriorityFnState<Artifact: ArtifactKind> {
priority_fn: PriorityFn<Artifact::Id, Artifact::Attribute>,
Expand Down Expand Up @@ -305,13 +306,15 @@ pub struct ConsensusDriver<'a> {
Box<dyn ChangeSetProducer<ConsensusPoolImpl, ChangeSet = ConsensusChangeSet>>,
pub(crate) consensus_gossip: ConsensusGossipImpl,
pub(crate) dkg: dkg::DkgImpl,
pub(crate) ecdsa: ecdsa::EcdsaImpl,
pub(crate) certifier:
Box<dyn ChangeSetProducer<CertificationPoolImpl, ChangeSet = ChangeSet> + 'a>,
pub(crate) logger: ReplicaLogger,
pub consensus_pool: Arc<RwLock<ConsensusPoolImpl>>,
pub certification_pool: Arc<RwLock<CertificationPoolImpl>>,
pub ingress_pool: RefCell<TestIngressPool>,
pub dkg_pool: Arc<RwLock<dkg_pool::DkgPoolImpl>>,
pub ecdsa_pool: Arc<RwLock<ecdsa_pool::EcdsaPoolImpl>>,
pub(crate) consensus_priority: RefCell<PriorityFnState<ConsensusArtifact>>,
}

Expand Down

0 comments on commit 09bb6f3

Please sign in to comment.