From b15f009caadf649a6c29a69d3a69e12d916bc02f Mon Sep 17 00:00:00 2001 From: Hernando Castano Date: Wed, 17 Jul 2024 15:07:13 -0400 Subject: [PATCH 01/11] Use `/generate_network_key` endpoint instead of `/user/new` when jumpstarting These flows are going to be different since the user registration flow shouldn't involve any DKG going forward. --- crates/client/entropy_metadata.scale | Bin 205050 -> 205344 bytes crates/threshold-signature-server/src/lib.rs | 1 + .../src/user/api.rs | 13 +++- .../src/user/tests.rs | 2 +- node/cli/src/service.rs | 2 +- pallets/propagation/src/lib.rs | 58 ++++++++++++++++++ pallets/registry/src/lib.rs | 17 +++-- 7 files changed, 85 insertions(+), 8 deletions(-) diff --git a/crates/client/entropy_metadata.scale b/crates/client/entropy_metadata.scale index ba7b2915bc6e9500ba0edd3f2a9ed380ec103679..5b41ba1bf5a4df0550d21c9a47025e42ad651d70 100644 GIT binary patch delta 353 zcmZ9Gu}T9$6h)n73y~CJAr=<5uuw>0B_bjU0a4HtS+vb$=4E$?JG0rDF~lZ?g@0gL zKfx}wkl&E4{D&YZoUD!5J>GrizVrRjc$+ugzpCk6u`Raoyr^Cl6`L)p=yI3sOwX6m z_T=!|=Y@5=bgeyk^|EAldkhu46xAy_}>CY903%U cK>Pw04h%$VX8{2O0ubE+1ONcHiv0qXBwFAb)c^nh diff --git a/crates/threshold-signature-server/src/lib.rs b/crates/threshold-signature-server/src/lib.rs index ab5d9c648..3350e0749 100644 --- a/crates/threshold-signature-server/src/lib.rs +++ b/crates/threshold-signature-server/src/lib.rs @@ -172,6 +172,7 @@ impl AppState { pub fn app(app_state: AppState) -> Router { let mut routes = Router::new() + .route("/generate_network_key", post(generate_network_key)) .route("/user/sign_tx", post(sign_tx)) .route("/user/new", post(new_user)) .route("/signer/proactive_refresh", post(proactive_refresh)) diff --git a/crates/threshold-signature-server/src/user/api.rs b/crates/threshold-signature-server/src/user/api.rs index 85ca987e4..5aff2b951 100644 --- a/crates/threshold-signature-server/src/user/api.rs +++ b/crates/threshold-signature-server/src/user/api.rs @@ -235,7 +235,7 @@ pub async fn sign_tx( /// /// This will trigger the Distributed Key Generation (DKG) process. #[tracing::instrument(skip_all, fields(block_number))] -pub async fn new_user( +pub async fn generate_network_key( State(app_state): State, encoded_data: Bytes, ) -> Result { @@ -275,6 +275,14 @@ pub async fn new_user( Ok(StatusCode::OK) } +#[tracing::instrument(skip_all, fields(block_number))] +pub async fn new_user( + State(_app_state): State, + _encoded_data: Bytes, +) -> Result { + todo!() +} + /// Setup and execute DKG. /// /// Called internally by the [new_user] function. @@ -308,6 +316,7 @@ async fn setup_dkg( data.block_number, ) .await?; + let verifying_key = key_share.verifying_key().to_encoded_point(true).as_bytes().to_vec(); let string_verifying_key = if sig_request_account == NETWORK_PARENT_KEY.encode() { hex::encode(NETWORK_PARENT_KEY) @@ -428,7 +437,7 @@ pub async fn validate_new_user( let chain_data_hash = hasher_chain_data.finalize(); let mut hasher_verifying_data = Blake2s256::new(); - let verifying_data_query = entropy::storage().registry().dkg(chain_data.block_number); + let verifying_data_query = entropy::storage().registry().jumpstart_dkg(chain_data.block_number); let verifying_data = query_chain(api, rpc, verifying_data_query, None).await?; hasher_verifying_data.update(verifying_data.encode()); diff --git a/crates/threshold-signature-server/src/user/tests.rs b/crates/threshold-signature-server/src/user/tests.rs index e2febcf5f..2911d19e6 100644 --- a/crates/threshold-signature-server/src/user/tests.rs +++ b/crates/threshold-signature-server/src/user/tests.rs @@ -771,7 +771,7 @@ async fn test_jumpstart_network() { .iter() .map(|port| { client - .post(format!("http://127.0.0.1:{}/user/new", port)) + .post(format!("http://127.0.0.1:{}/generate_network_key", port)) .body(onchain_user_request.clone().encode()) .send() }) diff --git a/node/cli/src/service.rs b/node/cli/src/service.rs index e9cb4b0ef..447219140 100644 --- a/node/cli/src/service.rs +++ b/node/cli/src/service.rs @@ -355,7 +355,7 @@ pub fn new_full_base( offchain_db.local_storage_set( sp_core::offchain::StorageKind::PERSISTENT, b"propagation", - &format!("{}/user/new", endpoint).into_bytes(), + &format!("{}/generate_network_key", endpoint).into_bytes(), ); offchain_db.local_storage_set( sp_core::offchain::StorageKind::PERSISTENT, diff --git a/pallets/propagation/src/lib.rs b/pallets/propagation/src/lib.rs index f60dd566e..5176852ab 100644 --- a/pallets/propagation/src/lib.rs +++ b/pallets/propagation/src/lib.rs @@ -83,6 +83,64 @@ pub mod pallet { impl Pallet { pub fn post_dkg(block_number: BlockNumberFor) -> Result<(), http::Error> { + let messages = pallet_registry::Pallet::::jumpstart_dkg( + block_number.saturating_sub(1u32.into()), + ); + + let deadline = sp_io::offchain::timestamp().add(Duration::from_millis(2_000)); + let kind = sp_core::offchain::StorageKind::PERSISTENT; + let from_local = sp_io::offchain::local_storage_get(kind, b"propagation") + .unwrap_or_else(|| b"http://localhost:3001/generate_network_key".to_vec()); + let url = + str::from_utf8(&from_local).unwrap_or("http://localhost:3001/generate_network_key"); + + log::warn!("propagation::post::messages: {:?}", &messages); + let converted_block_number: u32 = + BlockNumberFor::::try_into(block_number).unwrap_or_default(); + let servers_info = + pallet_registry::Pallet::::get_validators_info().unwrap_or_default(); + let validators_info = servers_info + .iter() + .map(|server_info| ValidatorInfo { + x25519_public_key: server_info.x25519_public_key, + ip_address: server_info.endpoint.clone(), + tss_account: server_info.tss_account.encode(), + }) + .collect::>(); + // the data is serialized / encoded to Vec by parity-scale-codec::encode() + let req_body = OcwMessageDkg { + // subtract 1 from blocknumber since the request is from the last block + block_number: converted_block_number.saturating_sub(1), + sig_request_accounts: messages, + validators_info, + }; + + log::warn!("propagation::post::req_body: {:?}", &[req_body.encode()]); + // We construct the request + // important: the header->Content-Type must be added and match that of the receiving + // party!! + let pending = http::Request::post(url, vec![req_body.encode()]) + .deadline(deadline) + .send() + .map_err(|_| http::Error::IoError)?; + + // We await response, same as in fn get() + let response = + pending.try_wait(deadline).map_err(|_| http::Error::DeadlineReached)??; + + // check response code + if response.code != 200 { + log::warn!("Unexpected status code: {}", response.code); + return Err(http::Error::Unknown); + } + let _res_body = response.body().collect::>(); + + Self::deposit_event(Event::DkgMessagePassed(req_body)); + + Ok(()) + } + + pub fn post_user_registration(block_number: BlockNumberFor) -> Result<(), http::Error> { let messages = pallet_registry::Pallet::::dkg(block_number.saturating_sub(1u32.into())); diff --git a/pallets/registry/src/lib.rs b/pallets/registry/src/lib.rs index afcc3904b..7ef665dc5 100644 --- a/pallets/registry/src/lib.rs +++ b/pallets/registry/src/lib.rs @@ -180,6 +180,11 @@ pub mod pallet { pub type Registering = StorageMap<_, Blake2_128Concat, T::AccountId, RegisteringDetails, OptionQuery>; + #[pallet::storage] + #[pallet::getter(fn jumpstart_dkg)] + pub type JumpstartDkg = + StorageMap<_, Blake2_128Concat, BlockNumberFor, Vec>, ValueQuery>; + #[pallet::storage] #[pallet::getter(fn dkg)] pub type Dkg = @@ -284,11 +289,15 @@ pub mod pallet { }, _ => return Err(Error::::JumpStartProgressNotReady.into()), }; + // TODO (#923): Add checks for network state. - Dkg::::try_mutate(current_block_number, |messages| -> Result<_, DispatchError> { - messages.push(NETWORK_PARENT_KEY.encode()); - Ok(()) - })?; + JumpstartDkg::::try_mutate( + current_block_number, + |messages| -> Result<_, DispatchError> { + messages.push(NETWORK_PARENT_KEY.encode()); + Ok(()) + }, + )?; JumpStartProgress::::put(JumpStartDetails { jump_start_status: JumpStartStatus::InProgress(converted_block_number), confirmations: vec![], From 7f6ad287353ceab538784515459b5404e60e3162 Mon Sep 17 00:00:00 2001 From: Hernando Castano Date: Thu, 18 Jul 2024 16:34:08 -0400 Subject: [PATCH 02/11] Make implementation for jumpstart and user registration endpoints the same --- .../src/user/api.rs | 40 ++++++++++++++----- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/crates/threshold-signature-server/src/user/api.rs b/crates/threshold-signature-server/src/user/api.rs index 5aff2b951..5e3a9488e 100644 --- a/crates/threshold-signature-server/src/user/api.rs +++ b/crates/threshold-signature-server/src/user/api.rs @@ -228,7 +228,8 @@ pub async fn sign_tx( Ok((StatusCode::OK, Body::from_stream(response_rx))) } -/// HTTP POST endpoint called by the off-chain worker (propagation pallet) during user registration. +/// HTTP POST endpoint called by the off-chain worker (Propagation pallet) during the network +/// jumpstart. /// /// The HTTP request takes a Parity SCALE encoded [OcwMessageDkg] which indicates which validators /// are in the validator group. @@ -242,12 +243,41 @@ pub async fn generate_network_key( let data = OcwMessageDkg::decode(&mut encoded_data.as_ref())?; tracing::Span::current().record("block_number", data.block_number); + Ok(distributed_key_generation(app_state, data).await?) +} + +/// HTTP POST endpoint called by the off-chain worker (Propagation pallet) during user registration. +/// +/// The HTTP request takes a Parity SCALE encoded [OcwMessageDkg] which indicates which validators +/// are in the validator group. +/// +/// This will trigger the Distributed Key Generation (DKG) process. +#[tracing::instrument(skip_all, fields(block_number))] +pub async fn new_user( + State(app_state): State, + encoded_data: Bytes, +) -> Result { + let data = OcwMessageDkg::decode(&mut encoded_data.as_ref())?; + tracing::Span::current().record("block_number", data.block_number); + + Ok(distributed_key_generation(app_state, data).await?) +} + +/// An internal helper which kicks off the distributed key generation (DKG) process. +/// +/// Since the jumpstart and registration flows are both doing DKG at the moment, we've split this +/// out. In the future though, only the jumpstart flow will require this. +async fn distributed_key_generation( + app_state: AppState, + data: OcwMessageDkg, +) -> Result { if data.sig_request_accounts.is_empty() { return Ok(StatusCode::NO_CONTENT); } let api = get_api(&app_state.configuration.endpoint).await?; let rpc = get_rpc(&app_state.configuration.endpoint).await?; let (signer, x25519_secret_key) = get_signer_and_x25519_secret(&app_state.kv_store).await?; + let in_registration_group = check_in_registration_group(&data.validators_info, signer.account_id()); @@ -275,14 +305,6 @@ pub async fn generate_network_key( Ok(StatusCode::OK) } -#[tracing::instrument(skip_all, fields(block_number))] -pub async fn new_user( - State(_app_state): State, - _encoded_data: Bytes, -) -> Result { - todo!() -} - /// Setup and execute DKG. /// /// Called internally by the [new_user] function. From e17a91be124b775bce9a9ae2394ad1bf5d3349a3 Mon Sep 17 00:00:00 2001 From: Hernando Castano Date: Thu, 18 Jul 2024 16:34:55 -0400 Subject: [PATCH 03/11] Change offchain worker local storage entry for registration --- node/cli/src/service.rs | 5 +++++ pallets/propagation/src/lib.rs | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/node/cli/src/service.rs b/node/cli/src/service.rs index 447219140..a26bb59c0 100644 --- a/node/cli/src/service.rs +++ b/node/cli/src/service.rs @@ -357,6 +357,11 @@ pub fn new_full_base( b"propagation", &format!("{}/generate_network_key", endpoint).into_bytes(), ); + offchain_db.local_storage_set( + sp_core::offchain::StorageKind::PERSISTENT, + b"registration", + &format!("{}/user/new", endpoint).into_bytes(), + ); offchain_db.local_storage_set( sp_core::offchain::StorageKind::PERSISTENT, b"refresh", diff --git a/pallets/propagation/src/lib.rs b/pallets/propagation/src/lib.rs index 5176852ab..572c4cf09 100644 --- a/pallets/propagation/src/lib.rs +++ b/pallets/propagation/src/lib.rs @@ -146,7 +146,7 @@ pub mod pallet { let deadline = sp_io::offchain::timestamp().add(Duration::from_millis(2_000)); let kind = sp_core::offchain::StorageKind::PERSISTENT; - let from_local = sp_io::offchain::local_storage_get(kind, b"propagation") + let from_local = sp_io::offchain::local_storage_get(kind, b"registration") .unwrap_or_else(|| b"http://localhost:3001/user/new".to_vec()); let url = str::from_utf8(&from_local).unwrap_or("http://localhost:3001/user/new"); From f9f323ab716f286ec8a7456d28f02d78be9d46d3 Mon Sep 17 00:00:00 2001 From: Hernando Castano Date: Thu, 18 Jul 2024 16:35:13 -0400 Subject: [PATCH 04/11] Small cleanups --- crates/threshold-signature-server/src/lib.rs | 2 +- pallets/registry/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/threshold-signature-server/src/lib.rs b/crates/threshold-signature-server/src/lib.rs index 3350e0749..0c06f9693 100644 --- a/crates/threshold-signature-server/src/lib.rs +++ b/crates/threshold-signature-server/src/lib.rs @@ -173,8 +173,8 @@ impl AppState { pub fn app(app_state: AppState) -> Router { let mut routes = Router::new() .route("/generate_network_key", post(generate_network_key)) - .route("/user/sign_tx", post(sign_tx)) .route("/user/new", post(new_user)) + .route("/user/sign_tx", post(sign_tx)) .route("/signer/proactive_refresh", post(proactive_refresh)) .route("/healthz", get(healthz)) .route("/version", get(get_version)) diff --git a/pallets/registry/src/lib.rs b/pallets/registry/src/lib.rs index 7ef665dc5..ae926cfdf 100644 --- a/pallets/registry/src/lib.rs +++ b/pallets/registry/src/lib.rs @@ -382,7 +382,7 @@ pub mod pallet { /// network. #[pallet::call_index(2)] #[pallet::weight({ - ::WeightInfo::register( ::MaxProgramHashes::get()) + ::WeightInfo::register(::MaxProgramHashes::get()) })] pub fn register( origin: OriginFor, From 92b198b853b8808ea23e7812b515a163603ad845 Mon Sep 17 00:00:00 2001 From: Hernando Castano Date: Thu, 18 Jul 2024 16:59:15 -0400 Subject: [PATCH 05/11] Add the registration flow to offchain worker hook --- pallets/propagation/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/pallets/propagation/src/lib.rs b/pallets/propagation/src/lib.rs index 572c4cf09..19cc00e7c 100644 --- a/pallets/propagation/src/lib.rs +++ b/pallets/propagation/src/lib.rs @@ -56,6 +56,7 @@ pub mod pallet { impl Hooks> for Pallet { fn offchain_worker(block_number: BlockNumberFor) { let _ = Self::post_dkg(block_number); + let _ = Self::post_user_registration(block_number); let _ = Self::post_proactive_refresh(block_number); } From 29b709d4baf94a384fc93913042a34a2c992e30d Mon Sep 17 00:00:00 2001 From: Hernando Castano Date: Thu, 18 Jul 2024 17:20:41 -0400 Subject: [PATCH 06/11] Add different codepath when validating user data --- .../src/user/api.rs | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/crates/threshold-signature-server/src/user/api.rs b/crates/threshold-signature-server/src/user/api.rs index 5e3a9488e..65b0ad566 100644 --- a/crates/threshold-signature-server/src/user/api.rs +++ b/crates/threshold-signature-server/src/user/api.rs @@ -82,6 +82,12 @@ use crate::{ pub use entropy_client::user::{get_signers_from_chain, UserSignatureRequest}; pub const REQUEST_KEY_HEADER: &str = "REQUESTS"; +/// Used to differentiate different flows which perform distributed key generation. +enum DkgFlow { + Jumpstart, + Registration, +} + /// Type for validators to send user key's back and forth #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] #[derive(Debug, Clone, PartialEq)] @@ -243,7 +249,7 @@ pub async fn generate_network_key( let data = OcwMessageDkg::decode(&mut encoded_data.as_ref())?; tracing::Span::current().record("block_number", data.block_number); - Ok(distributed_key_generation(app_state, data).await?) + Ok(distributed_key_generation(app_state, data, DkgFlow::Jumpstart).await?) } /// HTTP POST endpoint called by the off-chain worker (Propagation pallet) during user registration. @@ -260,7 +266,7 @@ pub async fn new_user( let data = OcwMessageDkg::decode(&mut encoded_data.as_ref())?; tracing::Span::current().record("block_number", data.block_number); - Ok(distributed_key_generation(app_state, data).await?) + Ok(distributed_key_generation(app_state, data, DkgFlow::Registration).await?) } /// An internal helper which kicks off the distributed key generation (DKG) process. @@ -270,6 +276,7 @@ pub async fn new_user( async fn distributed_key_generation( app_state: AppState, data: OcwMessageDkg, + flow: DkgFlow, ) -> Result { if data.sig_request_accounts.is_empty() { return Ok(StatusCode::NO_CONTENT); @@ -291,7 +298,7 @@ async fn distributed_key_generation( return Ok(StatusCode::MISDIRECTED_REQUEST); } - validate_new_user(&data, &api, &rpc, &app_state.kv_store).await?; + validate_new_user(&data, &api, &rpc, &app_state.kv_store, flow).await?; // Do the DKG protocol in another task, so we can already respond tokio::spawn(async move { @@ -427,11 +434,12 @@ pub async fn confirm_registered( /// Validates new user endpoint /// Checks the chain for validity of data and block number of data matches current block -pub async fn validate_new_user( +async fn validate_new_user( chain_data: &OcwMessageDkg, api: &OnlineClient, rpc: &LegacyRpcMethods, kv_manager: &KvManager, + flow: DkgFlow, ) -> Result<(), UserErr> { let last_block_number_recorded = kv_manager.kv().get(LATEST_BLOCK_NUMBER_NEW_USER).await?; if u32::from_be_bytes( @@ -459,7 +467,11 @@ pub async fn validate_new_user( let chain_data_hash = hasher_chain_data.finalize(); let mut hasher_verifying_data = Blake2s256::new(); - let verifying_data_query = entropy::storage().registry().jumpstart_dkg(chain_data.block_number); + let verifying_data_query = match flow { + DkgFlow::Jumpstart => entropy::storage().registry().jumpstart_dkg(chain_data.block_number), + DkgFlow::Registration => entropy::storage().registry().dkg(chain_data.block_number), + }; + let verifying_data = query_chain(api, rpc, verifying_data_query, None).await?; hasher_verifying_data.update(verifying_data.encode()); From aacc5b766fe902873d93a941a2d342a71768a3fe Mon Sep 17 00:00:00 2001 From: Hernando Castano Date: Thu, 18 Jul 2024 17:24:34 -0400 Subject: [PATCH 07/11] Appease Clippy --- crates/threshold-signature-server/src/user/api.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/threshold-signature-server/src/user/api.rs b/crates/threshold-signature-server/src/user/api.rs index 65b0ad566..ae17834fb 100644 --- a/crates/threshold-signature-server/src/user/api.rs +++ b/crates/threshold-signature-server/src/user/api.rs @@ -249,7 +249,7 @@ pub async fn generate_network_key( let data = OcwMessageDkg::decode(&mut encoded_data.as_ref())?; tracing::Span::current().record("block_number", data.block_number); - Ok(distributed_key_generation(app_state, data, DkgFlow::Jumpstart).await?) + distributed_key_generation(app_state, data, DkgFlow::Jumpstart).await } /// HTTP POST endpoint called by the off-chain worker (Propagation pallet) during user registration. @@ -266,7 +266,7 @@ pub async fn new_user( let data = OcwMessageDkg::decode(&mut encoded_data.as_ref())?; tracing::Span::current().record("block_number", data.block_number); - Ok(distributed_key_generation(app_state, data, DkgFlow::Registration).await?) + distributed_key_generation(app_state, data, DkgFlow::Registration).await } /// An internal helper which kicks off the distributed key generation (DKG) process. From 6c8725ea068eee5bae3aa81c9d7196a40eb438ad Mon Sep 17 00:00:00 2001 From: Hernando Castano Date: Thu, 18 Jul 2024 17:29:41 -0400 Subject: [PATCH 08/11] Add `CHANGELOG` entry --- CHANGELOG.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f14b580f..0de5a8a25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,16 +9,17 @@ At the moment this project **does not** adhere to ## [Unreleased](https://github.com/entropyxyz/entropy-core/compare/release/v0.2.0...master) -### Added -- Jumpstart network ([#918](https://github.com/entropyxyz/entropy-core/pull/918)) -- Add Signer groups and rotation ([#938](https://github.com/entropyxyz/entropy-core/pull/938)) - ### Breaking Changes - In [#938](https://github.com/entropyxyz/entropy-core/pull/938), the chainspec got a couple of new fields, `pallet_staking_extension::initial_signers`, `pallet_parameters::total_signers`, and `pallet_parameters::threshold`, which are used to set up the initial threshold signing configuration for the network. +### Added +- Jumpstart network ([#918](https://github.com/entropyxyz/entropy-core/pull/918)) +- Add Signer groups and rotation ([#938](https://github.com/entropyxyz/entropy-core/pull/938)) +- Split jumpstart and register flows ([#952](https://github.com/entropyxyz/entropy-core/pull/952)) + ## [0.2.0](https://github.com/entropyxyz/entropy-core/compare/release/v0.1.0...release/v0.2.0) - 2024-07-11 ### Breaking Changes From 63796e78dc93e3631a46154f4b09ef15a3b4a0a9 Mon Sep 17 00:00:00 2001 From: Hernando Castano Date: Fri, 19 Jul 2024 12:37:15 -0400 Subject: [PATCH 09/11] Fix OCW HTTP test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tbh don't know what the right values for this are, and we should really be encoding the data stucture instead of hardcoding it, but 🤷 --- pallets/propagation/src/tests.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/pallets/propagation/src/tests.rs b/pallets/propagation/src/tests.rs index 0bbcfa039..0f0bffa5f 100644 --- a/pallets/propagation/src/tests.rs +++ b/pallets/propagation/src/tests.rs @@ -32,7 +32,7 @@ fn knows_how_to_mock_several_http_calls() { let mut t = offchain_worker_env(|state| { state.expect_request(testing::PendingRequest { method: "POST".into(), - uri: "http://localhost:3001/user/new".into(), + uri: "http://localhost:3001/generate_network_key".into(), sent: true, response: Some([].to_vec()), body: [ @@ -44,21 +44,22 @@ fn knows_how_to_mock_several_http_calls() { .to_vec(), ..Default::default() }); + state.expect_request(testing::PendingRequest { method: "POST".into(), - uri: "http://localhost:3001/user/new".into(), + uri: "http://localhost:3001/generate_network_key".into(), sent: true, response: Some([].to_vec()), body: [ - 3, 0, 0, 0, 8, 32, 1, 0, 0, 0, 0, 0, 0, 0, 32, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 10, 32, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 11, 32, 4, 0, 0, 0, 0, 0, 0, - 0, + 3, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 10, 32, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, + 11, 32, 4, 0, 0, 0, 0, 0, 0, 0, ] .to_vec(), ..Default::default() }); + state.expect_request(testing::PendingRequest { method: "POST".into(), uri: "http://localhost:3001/signer/proactive_refresh".into(), @@ -97,8 +98,10 @@ fn knows_how_to_mock_several_http_calls() { .unwrap(); assert_ok!(Registry::register(RuntimeOrigin::signed(1), 2, programs_info.clone(),)); assert_ok!(Registry::register(RuntimeOrigin::signed(2), 3, programs_info,)); + // full send Propagation::post_dkg(4).unwrap(); + // test pruning assert_eq!(Registry::dkg(3).len(), 2); Propagation::on_initialize(5); From 0c7ab9860ea8eca3aadc6888bef2b1b15f06c95b Mon Sep 17 00:00:00 2001 From: Hernando Castano Date: Fri, 19 Jul 2024 12:43:06 -0400 Subject: [PATCH 10/11] Add some docs --- pallets/propagation/src/lib.rs | 5 +++++ pallets/registry/src/lib.rs | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/pallets/propagation/src/lib.rs b/pallets/propagation/src/lib.rs index 19cc00e7c..31260c546 100644 --- a/pallets/propagation/src/lib.rs +++ b/pallets/propagation/src/lib.rs @@ -83,6 +83,8 @@ pub mod pallet { impl Pallet {} impl Pallet { + /// Submits a distributed key generation request to jumpstart the network to the threshold + /// servers. pub fn post_dkg(block_number: BlockNumberFor) -> Result<(), http::Error> { let messages = pallet_registry::Pallet::::jumpstart_dkg( block_number.saturating_sub(1u32.into()), @@ -141,6 +143,8 @@ pub mod pallet { Ok(()) } + /// Submits a distributed key generation request to register a set of users to the threshold + /// servers. pub fn post_user_registration(block_number: BlockNumberFor) -> Result<(), http::Error> { let messages = pallet_registry::Pallet::::dkg(block_number.saturating_sub(1u32.into())); @@ -197,6 +201,7 @@ pub mod pallet { Ok(()) } + /// Submits a request to perform a proactive refresh to the threshold servers. pub fn post_proactive_refresh(block_number: BlockNumberFor) -> Result<(), http::Error> { let refresh_info = pallet_staking_extension::Pallet::::proactive_refresh(); if refresh_info.validators_info.is_empty() { diff --git a/pallets/registry/src/lib.rs b/pallets/registry/src/lib.rs index ae926cfdf..3e702d5ce 100644 --- a/pallets/registry/src/lib.rs +++ b/pallets/registry/src/lib.rs @@ -180,11 +180,15 @@ pub mod pallet { pub type Registering = StorageMap<_, Blake2_128Concat, T::AccountId, RegisteringDetails, OptionQuery>; + /// Used for triggering a network wide distributed key generation request via an offchain + /// worker. #[pallet::storage] #[pallet::getter(fn jumpstart_dkg)] pub type JumpstartDkg = StorageMap<_, Blake2_128Concat, BlockNumberFor, Vec>, ValueQuery>; + /// Used to store requests and trigger distributed key generation for users via an offchain + /// worker. #[pallet::storage] #[pallet::getter(fn dkg)] pub type Dkg = From 422362c080a0931007c0ba41f72be30a9c2e9f7c Mon Sep 17 00:00:00 2001 From: Hernando Castano Date: Fri, 19 Jul 2024 13:17:39 -0400 Subject: [PATCH 11/11] Use correct DKG call in jumpstart test --- pallets/registry/src/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/registry/src/tests.rs b/pallets/registry/src/tests.rs index 7be263f81..631d6279e 100644 --- a/pallets/registry/src/tests.rs +++ b/pallets/registry/src/tests.rs @@ -96,7 +96,7 @@ fn it_jumps_the_network() { ); assert_ok!(Registry::jump_start_network(RuntimeOrigin::signed(1))); assert_eq!( - Registry::dkg(0), + Registry::jumpstart_dkg(0), vec![NETWORK_PARENT_KEY.encode()], "ensures a dkg message for the jump start network is prepped" );