Skip to content

Commit 09bb6f3

Browse files
committed
feat: Run ecdsa component in consensus test framework
1 parent eee4085 commit 09bb6f3

File tree

7 files changed

+159
-43
lines changed

7 files changed

+159
-43
lines changed

rs/consensus/tests/framework/driver.rs

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
pub use super::types::*;
22
use ic_artifact_pool::{
3-
certification_pool::CertificationPoolImpl, consensus_pool::ConsensusPoolImpl, dkg_pool,
3+
certification_pool::CertificationPoolImpl, consensus_pool::ConsensusPoolImpl,
4+
dkg_pool::DkgPoolImpl, ecdsa_pool::EcdsaPoolImpl,
45
};
56
use ic_config::artifact_pool::ArtifactPoolConfig;
67
use ic_consensus::consensus::ConsensusGossipImpl;
78
use ic_interfaces::{
89
certification,
910
consensus_pool::{ChangeAction, ChangeSet as ConsensusChangeSet},
1011
dkg::ChangeAction as DkgChangeAction,
12+
ecdsa::EcdsaChangeAction,
1113
p2p::consensus::{ChangeSetProducer, MutablePool},
1214
};
1315
use ic_logger::{debug, ReplicaLogger};
@@ -28,11 +30,13 @@ impl<'a> ConsensusDriver<'a> {
2830
consensus: Box<dyn ChangeSetProducer<ConsensusPoolImpl, ChangeSet = ConsensusChangeSet>>,
2931
consensus_gossip: ConsensusGossipImpl,
3032
dkg: ic_consensus::dkg::DkgImpl,
33+
ecdsa: ic_consensus::ecdsa::EcdsaImpl,
3134
certifier: Box<
3235
dyn ChangeSetProducer<CertificationPoolImpl, ChangeSet = certification::ChangeSet> + 'a,
3336
>,
3437
consensus_pool: Arc<RwLock<ConsensusPoolImpl>>,
35-
dkg_pool: Arc<RwLock<dkg_pool::DkgPoolImpl>>,
38+
dkg_pool: Arc<RwLock<DkgPoolImpl>>,
39+
ecdsa_pool: Arc<RwLock<EcdsaPoolImpl>>,
3640
logger: ReplicaLogger,
3741
metrics_registry: MetricsRegistry,
3842
) -> ConsensusDriver<'a> {
@@ -49,17 +53,19 @@ impl<'a> ConsensusDriver<'a> {
4953
consensus,
5054
consensus_gossip,
5155
dkg,
56+
ecdsa,
5257
certifier,
5358
logger,
5459
consensus_pool,
5560
certification_pool,
5661
ingress_pool,
5762
dkg_pool,
63+
ecdsa_pool,
5864
consensus_priority,
5965
}
6066
}
6167

62-
/// Run a single step of consensus, dkg and certification by repeatedly
68+
/// Run a single step of consensus, dkg, certification, and ecdsa by repeatedly
6369
/// calling on_state_change and apply the changes until no more changes
6470
/// occur.
6571
///
@@ -132,6 +138,30 @@ impl<'a> ConsensusDriver<'a> {
132138
certification_pool.apply_changes(changeset);
133139
}
134140
}
141+
loop {
142+
let changeset = self
143+
.ecdsa
144+
.on_state_change(&*self.ecdsa_pool.read().unwrap());
145+
if changeset.is_empty() {
146+
break;
147+
}
148+
{
149+
for change_action in &changeset {
150+
match change_action {
151+
EcdsaChangeAction::AddToValidated(msg) => {
152+
debug!(self.logger, "Ecdsa Message Deliver {:?}", msg);
153+
to_deliver.push(InputMessage::Ecdsa(msg.clone()));
154+
}
155+
EcdsaChangeAction::MoveToValidated(msg) => {
156+
debug!(self.logger, "Ecdsa Message Validated {:?}", msg);
157+
}
158+
_ => {}
159+
}
160+
}
161+
let mut ecdsa_pool = self.ecdsa_pool.write().unwrap();
162+
ecdsa_pool.apply_changes(changeset);
163+
}
164+
}
135165
to_deliver
136166
}
137167
}

rs/consensus/tests/framework/execution.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,14 @@ fn execute_instance(
7171
timestamp,
7272
});
7373
}
74+
InputMessage::Ecdsa(msg) => {
75+
let mut ecdsa_pool = instance.driver.ecdsa_pool.write().unwrap();
76+
ecdsa_pool.insert(UnvalidatedArtifact {
77+
message: msg,
78+
peer_id: node_test_id(0),
79+
timestamp,
80+
});
81+
}
7482
},
7583
// Repeat the polling
7684
Input::TimerExpired(x) => {

rs/consensus/tests/framework/mod.rs

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,18 @@ mod types;
1010
pub use runner::ConsensusRunner;
1111
pub use types::{
1212
ConsensusDependencies, ConsensusDriver, ConsensusInstance, ConsensusModifier,
13-
ConsensusRunnerConfig,
13+
ConsensusRunnerConfig, StopPredicate,
1414
};
1515

1616
use ic_crypto_temp_crypto::{NodeKeysToGenerate, TempCryptoComponent, TempCryptoComponentGeneric};
1717
use ic_crypto_test_utils_ni_dkg::{initial_dkg_transcript, InitialNiDkgConfig};
18+
use ic_ic00_types::{EcdsaCurve, EcdsaKeyId};
1819
use ic_interfaces_registry::RegistryClient;
1920
use ic_protobuf::registry::subnet::v1::{CatchUpPackageContents, InitialNiDkgTranscriptRecord};
2021
use ic_registry_client_fake::FakeRegistryClient;
2122
use ic_registry_client_helpers::crypto::CryptoRegistry;
2223
use ic_registry_proto_data_provider::ProtoRegistryDataProvider;
24+
use ic_registry_subnet_features::EcdsaConfig;
2325
use ic_test_utilities::consensus::make_genesis;
2426
use ic_test_utilities_registry::SubnetRecordBuilder;
2527
use ic_types::{
@@ -28,7 +30,7 @@ use ic_types::{
2830
threshold_sig::ni_dkg::{NiDkgTag, NiDkgTargetId},
2931
KeyPurpose,
3032
},
31-
NodeId, RegistryVersion, SubnetId,
33+
subnet_id_into_protobuf, NodeId, RegistryVersion, SubnetId,
3234
};
3335
use rand::{CryptoRng, Rng, SeedableRng};
3436
use rand_chacha::ChaCha20Rng;
@@ -54,7 +56,20 @@ pub fn setup_subnet<R: Rng + CryptoRng>(
5456
let registry_version = RegistryVersion::from(initial_version);
5557
let data_provider = Arc::new(ProtoRegistryDataProvider::new());
5658
let registry_client = Arc::new(FakeRegistryClient::new(Arc::clone(&data_provider) as Arc<_>));
57-
let subnet_record = SubnetRecordBuilder::from(node_ids).build();
59+
let ecdsa_key_id = EcdsaKeyId {
60+
curve: EcdsaCurve::Secp256k1,
61+
name: "test_key".to_string(),
62+
};
63+
let subnet_record = SubnetRecordBuilder::from(node_ids)
64+
.with_dkg_interval_length(19)
65+
.with_ecdsa_config(EcdsaConfig {
66+
quadruples_to_create_in_advance: 4,
67+
key_ids: vec![ecdsa_key_id.clone()],
68+
max_queue_size: Some(40),
69+
signature_request_timeout_ns: None,
70+
idkg_key_rotation_period_ms: None,
71+
})
72+
.build();
5873
data_provider
5974
.add(
6075
&ic_registry_keys::make_subnet_record_key(subnet_id),
@@ -79,7 +94,7 @@ pub fn setup_subnet<R: Rng + CryptoRng>(
7994
data_provider
8095
.add(
8196
&ic_registry_keys::make_node_record_key(*node),
82-
RegistryVersion::from(initial_version),
97+
registry_version,
8398
Some(ic_protobuf::registry::node::v1::NodeRecord::default()),
8499
)
85100
.expect("Could not add node record.");
@@ -155,10 +170,22 @@ pub fn setup_subnet<R: Rng + CryptoRng>(
155170
data_provider
156171
.add(
157172
&ic_registry_keys::make_catch_up_package_contents_key(subnet_id),
158-
RegistryVersion::from(initial_version),
173+
registry_version,
159174
Some(subnet_dkg),
160175
)
161176
.expect("Could not add node record.");
177+
178+
// Add ECDSA signing subnet to registry
179+
data_provider
180+
.add(
181+
&ic_registry_keys::make_ecdsa_signing_subnet_list_key(&ecdsa_key_id),
182+
registry_version,
183+
Some(ic_protobuf::registry::crypto::v1::EcdsaSigningSubnetList {
184+
subnets: vec![subnet_id_into_protobuf(subnet_id)],
185+
}),
186+
)
187+
.expect("Could not add ECDSA signing subnet list");
188+
162189
registry_client.reload();
163190
registry_client.update_to_latest_version();
164191

rs/consensus/tests/framework/runner.rs

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use ic_config::artifact_pool::ArtifactPoolConfig;
55
use ic_consensus::consensus::dkg_key_manager::DkgKeyManager;
66
use ic_consensus::{
77
certification::{CertificationCrypto, CertifierImpl},
8-
dkg,
8+
dkg, ecdsa,
99
};
1010
use ic_consensus_utils::crypto::ConsensusCrypto;
1111
use ic_consensus_utils::membership::Membership;
@@ -45,7 +45,7 @@ pub struct ConsensusRunner<'a> {
4545
idle_since: RefCell<Time>,
4646
pub time: Arc<FastForwardTimeSource>,
4747
pub instances: Vec<ConsensusInstance<'a>>,
48-
pub(crate) stop_predicate: StopPredicate<'a>,
48+
pub(crate) stop_predicate: StopPredicate,
4949
pub(crate) logger: ReplicaLogger,
5050
pub(crate) rng: RefCell<ChaChaRng>,
5151
pub(crate) config: ConsensusRunnerConfig,
@@ -111,7 +111,7 @@ impl<'a> ConsensusRunner<'a> {
111111
ConsensusRunner {
112112
idle_since: RefCell::new(now),
113113
instances: Vec::new(),
114-
stop_predicate: &stop_immediately,
114+
stop_predicate: Box::new(stop_immediately),
115115
time: time_source,
116116
logger,
117117
config,
@@ -149,7 +149,7 @@ impl<'a> ConsensusRunner<'a> {
149149
)));
150150
let fake_local_store_certified_time_reader =
151151
Arc::new(FakeLocalStoreCertifiedTimeReader::new(self.time.clone()));
152-
152+
let malicious_flags = MaliciousFlags::default();
153153
let (consensus, consensus_gossip) = ic_consensus::consensus::setup(
154154
deps.replica_config.clone(),
155155
Arc::clone(&deps.registry_client),
@@ -166,20 +166,29 @@ impl<'a> ConsensusRunner<'a> {
166166
deps.message_routing.clone(),
167167
deps.state_manager.clone(),
168168
Arc::clone(&self.time) as Arc<_>,
169-
MaliciousFlags::default(),
169+
malicious_flags.clone(),
170170
deps.metrics_registry.clone(),
171171
replica_logger.clone(),
172172
fake_local_store_certified_time_reader,
173173
0,
174174
);
175175
let dkg = dkg::DkgImpl::new(
176176
deps.replica_config.node_id,
177-
consensus_crypto,
177+
Arc::clone(&consensus_crypto),
178178
deps.consensus_pool.read().unwrap().get_cache(),
179179
dkg_key_manager,
180180
deps.metrics_registry.clone(),
181181
replica_logger.clone(),
182182
);
183+
let ecdsa = ecdsa::EcdsaImpl::new(
184+
deps.replica_config.node_id,
185+
deps.consensus_pool.read().unwrap().get_block_cache(),
186+
consensus_crypto,
187+
deps.state_manager.clone(),
188+
deps.metrics_registry.clone(),
189+
replica_logger.clone(),
190+
malicious_flags,
191+
);
183192
let certifier = CertifierImpl::new(
184193
deps.replica_config.clone(),
185194
membership,
@@ -206,9 +215,11 @@ impl<'a> ConsensusRunner<'a> {
206215
modifier.unwrap_or_else(|| Box::new(|x| Box::new(x)))(consensus),
207216
consensus_gossip,
208217
dkg,
218+
ecdsa,
209219
Box::new(certifier),
210220
deps.consensus_pool.clone(),
211221
deps.dkg_pool.clone(),
222+
deps.ecdsa_pool.clone(),
212223
replica_logger,
213224
deps.metrics_registry.clone(),
214225
),
@@ -220,7 +231,7 @@ impl<'a> ConsensusRunner<'a> {
220231
/// Run until the given StopPredicate becomes true for all instances.
221232
/// Return true if it runs to completion according to StopPredicate.
222233
/// Otherwise return false, which indicates the network has stalled.
223-
pub fn run_until(&mut self, pred: StopPredicate<'a>) -> bool {
234+
pub fn run_until(&mut self, pred: StopPredicate) -> bool {
224235
info!(self.logger, "{}", &self.config);
225236
self.stop_predicate = pred;
226237
loop {

rs/consensus/tests/framework/types.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ use ic_artifact_pool::{
66
use ic_config::artifact_pool::ArtifactPoolConfig;
77
use ic_consensus::{
88
consensus::{ConsensusGossipImpl, ConsensusImpl},
9-
dkg,
9+
dkg, ecdsa,
1010
};
1111
use ic_https_outcalls_consensus::test_utils::FakeCanisterHttpPayloadBuilder;
1212
use ic_interfaces::{
1313
batch_payload::BatchPayloadBuilder,
1414
certification::ChangeSet,
1515
consensus_pool::ChangeSet as ConsensusChangeSet,
1616
ingress_manager::IngressSelector,
17-
messaging::{MessageRouting, XNetPayloadBuilder},
17+
messaging::XNetPayloadBuilder,
1818
p2p::consensus::{ChangeSetProducer, PriorityFnAndFilterProducer},
1919
self_validating_payload::SelfValidatingPayloadBuilder,
2020
time_source::TimeSource,
@@ -36,8 +36,8 @@ use ic_types::{
3636
artifact::{ArtifactKind, Priority, PriorityFn},
3737
artifact_kind::ConsensusArtifact,
3838
consensus::{
39-
certification::CertificationMessage, dkg::Message as DkgMessage, CatchUpPackage,
40-
ConsensusMessage,
39+
certification::CertificationMessage, dkg::Message as DkgMessage, ecdsa::EcdsaMessage,
40+
CatchUpPackage, ConsensusMessage,
4141
},
4242
replica_config::ReplicaConfig,
4343
time::{Time, UNIX_EPOCH},
@@ -112,6 +112,7 @@ pub enum InputMessage {
112112
Consensus(ConsensusMessage),
113113
Dkg(Box<DkgMessage>),
114114
Certification(CertificationMessage),
115+
Ecdsa(EcdsaMessage),
115116
}
116117

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

261262
pub(crate) struct PriorityFnState<Artifact: ArtifactKind> {
262263
priority_fn: PriorityFn<Artifact::Id, Artifact::Attribute>,
@@ -305,13 +306,15 @@ pub struct ConsensusDriver<'a> {
305306
Box<dyn ChangeSetProducer<ConsensusPoolImpl, ChangeSet = ConsensusChangeSet>>,
306307
pub(crate) consensus_gossip: ConsensusGossipImpl,
307308
pub(crate) dkg: dkg::DkgImpl,
309+
pub(crate) ecdsa: ecdsa::EcdsaImpl,
308310
pub(crate) certifier:
309311
Box<dyn ChangeSetProducer<CertificationPoolImpl, ChangeSet = ChangeSet> + 'a>,
310312
pub(crate) logger: ReplicaLogger,
311313
pub consensus_pool: Arc<RwLock<ConsensusPoolImpl>>,
312314
pub certification_pool: Arc<RwLock<CertificationPoolImpl>>,
313315
pub ingress_pool: RefCell<TestIngressPool>,
314316
pub dkg_pool: Arc<RwLock<dkg_pool::DkgPoolImpl>>,
317+
pub ecdsa_pool: Arc<RwLock<ecdsa_pool::EcdsaPoolImpl>>,
315318
pub(crate) consensus_priority: RefCell<PriorityFnState<ConsensusArtifact>>,
316319
}
317320

0 commit comments

Comments
 (0)