From 24de58869928f413c384d73fe485518236e141c7 Mon Sep 17 00:00:00 2001 From: Jesse Abramowitz Date: Wed, 17 Jul 2024 14:26:27 -0400 Subject: [PATCH 01/25] Add keyshare trigger --- pallets/propagation/src/lib.rs | 39 ++++++++++++++++++++++++++++++++++ pallets/staking/src/lib.rs | 8 +++++++ 2 files changed, 47 insertions(+) diff --git a/pallets/propagation/src/lib.rs b/pallets/propagation/src/lib.rs index f60dd566e..808145806 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_reshare(block_number); let _ = Self::post_proactive_refresh(block_number); } @@ -138,6 +139,44 @@ pub mod pallet { Ok(()) } + pub fn post_reshare(block_number: BlockNumberFor) -> Result<(), http::Error> { + let reshare_block_number = pallet_staking_extension::Pallet::::reshare_block(); + if reshare_block_number != block_number { + return Ok(()); + } + + 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"reshare") + .unwrap_or_else(|| b"http://localhost:3001/validator/reshare".to_vec()); + let url = str::from_utf8(&from_local) + .unwrap_or("http://localhost:3001/validator/reshare"); + + // 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!["0x"]) + .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::ProactiveRefreshMessagePassed(req_body)); + + Ok(()) + } + + 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/staking/src/lib.rs b/pallets/staking/src/lib.rs index 85f3073a9..e9f8d0b59 100644 --- a/pallets/staking/src/lib.rs +++ b/pallets/staking/src/lib.rs @@ -170,6 +170,11 @@ pub mod pallet { #[pallet::getter(fn next_signers)] pub type NextSigners = StorageValue<_, Vec, ValueQuery>; + /// The next time a reshare should happen + #[pallet::storage] + #[pallet::getter(fn reshare_block)] + pub type ReshareBlock = StorageValue<_, BlockNumberFor, ValueQuery>; + /// A type used to simplify the genesis configuration definition. pub type ThresholdServersConfig = ( ::ValidatorId, @@ -437,6 +442,9 @@ pub mod pallet { current_signers.remove(0); current_signers.push(next_signer_up.clone()); NextSigners::::put(current_signers); + // trigger reshare at next block + let current_block_number = >::block_number(); + ReshareBlock::::put(current_block_number + sp_runtime::traits::One::one()); // for next PR // tell signers to do new key rotation with new signer group (dkg) From 25f2ba1f61380cdd085e90214d73f633e7b07506 Mon Sep 17 00:00:00 2001 From: Jesse Abramowitz Date: Wed, 17 Jul 2024 14:41:08 -0400 Subject: [PATCH 02/25] tests --- pallets/propagation/src/lib.rs | 5 ++--- pallets/propagation/src/tests.rs | 14 ++++++++++++++ pallets/staking/src/mock.rs | 4 +--- pallets/staking/src/tests.rs | 10 ++++++---- 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/pallets/propagation/src/lib.rs b/pallets/propagation/src/lib.rs index 808145806..e9ed1e894 100644 --- a/pallets/propagation/src/lib.rs +++ b/pallets/propagation/src/lib.rs @@ -149,8 +149,8 @@ pub mod pallet { let kind = sp_core::offchain::StorageKind::PERSISTENT; let from_local = sp_io::offchain::local_storage_get(kind, b"reshare") .unwrap_or_else(|| b"http://localhost:3001/validator/reshare".to_vec()); - let url = str::from_utf8(&from_local) - .unwrap_or("http://localhost:3001/validator/reshare"); + let url = + str::from_utf8(&from_local).unwrap_or("http://localhost:3001/validator/reshare"); // We construct the request // important: the header->Content-Type must be added and match that of the receiving @@ -175,7 +175,6 @@ pub mod pallet { Ok(()) } - pub fn post_proactive_refresh(block_number: BlockNumberFor) -> Result<(), http::Error> { let refresh_info = pallet_staking_extension::Pallet::::proactive_refresh(); diff --git a/pallets/propagation/src/tests.rs b/pallets/propagation/src/tests.rs index 0bbcfa039..43396e894 100644 --- a/pallets/propagation/src/tests.rs +++ b/pallets/propagation/src/tests.rs @@ -72,6 +72,14 @@ fn knows_how_to_mock_several_http_calls() { .to_vec(), ..Default::default() }); + state.expect_request(testing::PendingRequest { + method: "POST".into(), + uri: "http://localhost:3001/validator/reshare".into(), + sent: true, + response: Some([].to_vec()), + body: [48, 120].to_vec(), + ..Default::default() + }); }); t.execute_with(|| { @@ -117,6 +125,12 @@ fn knows_how_to_mock_several_http_calls() { Propagation::post_proactive_refresh(6).unwrap(); Propagation::on_initialize(6); assert_eq!(Staking::proactive_refresh(), RefreshInfo::default()); + + // doesn't trigger no reshare block + Propagation::post_reshare(7).unwrap(); + pallet_staking_extension::ReshareBlock::::put(7); + // now triggers + Propagation::post_reshare(7).unwrap(); }) } diff --git a/pallets/staking/src/mock.rs b/pallets/staking/src/mock.rs index 9b95b9263..ad34160d7 100644 --- a/pallets/staking/src/mock.rs +++ b/pallets/staking/src/mock.rs @@ -360,9 +360,7 @@ impl pallet_session::historical::Config for Test { thread_local! { pub static LAST_RANDOM: RefCell> = RefCell::new(None); } -fn set_last_random(output: H256, known_since: u64) { - LAST_RANDOM.with(|p| *p.borrow_mut() = Some((output, known_since))) -} + pub struct TestPastRandomness; impl Randomness for TestPastRandomness { fn random(_subject: &[u8]) -> (H256, u64) { diff --git a/pallets/staking/src/tests.rs b/pallets/staking/src/tests.rs index 68259366a..429e672d3 100644 --- a/pallets/staking/src/tests.rs +++ b/pallets/staking/src/tests.rs @@ -331,16 +331,18 @@ fn it_tests_new_session_handler() { // no next signers at start assert_eq!(Staking::next_signers().len(), 0); - - Staking::new_session_handler(&vec![1u64, 2u64, 3u64]); + assert_eq!(Staking::reshare_block(), 0, "Check reshare block start at zero"); + System::set_block_number(100); + let _ = Staking::new_session_handler(&vec![1u64, 2u64, 3u64]); // takes signers original (5,6) pops off first 5, adds (fake randomness in mock so adds 1) assert_eq!(Staking::next_signers(), vec![6u64, 1u64]); + assert_eq!(Staking::reshare_block(), 101, "Check reshare block start at 100 + 1"); - Staking::new_session_handler(&vec![6u64, 5u64, 3u64]); + let _ = Staking::new_session_handler(&vec![6u64, 5u64, 3u64]); // takes 3 and leaves 5 and 6 since already in signer group assert_eq!(Staking::next_signers(), vec![6u64, 3u64]); - Staking::new_session_handler(&vec![1u64]); + let _ = Staking::new_session_handler(&vec![1u64]); // does nothing as not enough validators assert_eq!(Staking::next_signers(), vec![6u64, 3u64]); }); From f8e462d71a0519708bf68b91e88cc4064a0fd640 Mon Sep 17 00:00:00 2001 From: Jesse Abramowitz Date: Wed, 17 Jul 2024 20:23:18 -0400 Subject: [PATCH 03/25] add parent key veryifying key onchain --- crates/client/entropy_metadata.scale | Bin 205050 -> 205210 bytes crates/threshold-signature-server/src/lib.rs | 2 + .../src/validator/api.rs | 46 +++++++++++++++++- pallets/registry/src/benchmarking.rs | 8 ++- pallets/registry/src/lib.rs | 17 ++++++- pallets/registry/src/tests.rs | 46 ++++++++++++++---- pallets/staking/src/lib.rs | 1 - 7 files changed, 105 insertions(+), 15 deletions(-) diff --git a/crates/client/entropy_metadata.scale b/crates/client/entropy_metadata.scale index ba7b2915bc6e9500ba0edd3f2a9ed380ec103679..07035fcd33611c23a848f974a9a115c7fc17ae83 100644 GIT binary patch delta 208 zcmex$kZ0Cmo`x-qZf=Y$)1%!P6}Nl1G1kmymb5j)(6^bCr6pAzQOLI~bG7<|4QuDUQG&0SuX5wMk{^Ji5 GlL`Rafk)H; delta 137 zcmV;40CxYH!wmYt41lx&Mn<=0Mge}G0SK4n;zJ0Z6yj<^d!D zEHF-QbXH+(X=Gt^Z*l+*0AxyaZE#a`VRCd(a&KpHWpi^*Z*)>+VPts#50^mb0T}@h rms;on9RU%Sz<2>8x0~nz)RX}jw{U#|P6W66fdZR*0SLF4{Q?3cOawEw diff --git a/crates/threshold-signature-server/src/lib.rs b/crates/threshold-signature-server/src/lib.rs index ab5d9c648..92a601dbd 100644 --- a/crates/threshold-signature-server/src/lib.rs +++ b/crates/threshold-signature-server/src/lib.rs @@ -155,6 +155,7 @@ use crate::{ r#unsafe::api::{delete, put, remove_keys, unsafe_get}, signing_client::{api::*, ListenerState}, user::api::*, + validator::api::new_reshare, }; #[derive(Clone)] @@ -175,6 +176,7 @@ pub fn app(app_state: AppState) -> Router { .route("/user/sign_tx", post(sign_tx)) .route("/user/new", post(new_user)) .route("/signer/proactive_refresh", post(proactive_refresh)) + .route("/validator/reshare", post(new_reshare)) .route("/healthz", get(healthz)) .route("/version", get(get_version)) .route("/hashes", get(hashes)) diff --git a/crates/threshold-signature-server/src/validator/api.rs b/crates/threshold-signature-server/src/validator/api.rs index b8234e8a0..b2e06fcf8 100644 --- a/crates/threshold-signature-server/src/validator/api.rs +++ b/crates/threshold-signature-server/src/validator/api.rs @@ -16,14 +16,58 @@ use crate::{ chain_api::{ entropy::{self}, - EntropyConfig, + get_api, get_rpc, EntropyConfig, }, helpers::{launch::FORBIDDEN_KEYS, substrate::query_chain}, validator::errors::ValidatorErr, + AppState, +}; +use axum::{ + body::{Body, Bytes}, + extract::State, + http::StatusCode, + response::IntoResponse, + routing::{get, post}, + Json, Router, }; use std::str::FromStr; use subxt::{backend::legacy::LegacyRpcMethods, utils::AccountId32, OnlineClient}; +/// 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)] +pub async fn new_reshare( + State(app_state): State, + encoded_data: Bytes, +) -> Result { + // get block number from encoded data + 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 + // .map_err(|e| ProtocolErr::UserError(e.to_string()))?; + // need a network verifying key + // let new_key_share = do_proactive_refresh( + // &validators_info, + // &signer, + // &x25519_secret_key, + // &app_state.listener_state, + // encoded_key, + // deserialized_old_key, + // block_number, + // ) + // .await?; + // validate message came from chain (check reshare block # against current block number) + // get next signers see if I am one + // If so do reshare call confirm_reshare (delete key when done) + // If not terminate + Ok(StatusCode::OK) +} + /// Validation for if an account can cover tx fees for a tx pub async fn check_balance_for_fees( api: &OnlineClient, diff --git a/pallets/registry/src/benchmarking.rs b/pallets/registry/src/benchmarking.rs index 5e800cbc5..12eaf5b36 100644 --- a/pallets/registry/src/benchmarking.rs +++ b/pallets/registry/src/benchmarking.rs @@ -82,6 +82,7 @@ benchmarks! { let c in 0 .. SIGNING_PARTY_SIZE as u32; let sig_req_account: T::AccountId = whitelisted_caller(); let validator_account: T::AccountId = whitelisted_caller(); + let expected_verifying_key = BoundedVec::default(); let mut accounts = vec![]; for i in 0..SIGNING_PARTY_SIZE { @@ -98,12 +99,13 @@ benchmarks! { >::put(JumpStartDetails { jump_start_status: JumpStartStatus::InProgress(0), confirmations: vec![validators[0].clone()], + verifying_key: None }); let balance = ::Currency::minimum_balance() * 100u32.into(); let _ = ::Currency::make_free_balance_be(&accounts[1], balance); - }: confirm_jump_start(RawOrigin::Signed(accounts[1].clone())) + }: confirm_jump_start(RawOrigin::Signed(accounts[1].clone()), expected_verifying_key) verify { assert_last_event::(Event::::FinishedNetworkJumpStart().into()); } @@ -113,6 +115,7 @@ benchmarks! { let sig_req_account: T::AccountId = whitelisted_caller(); let validator_account: T::AccountId = whitelisted_caller(); let threshold_account: T::AccountId = whitelisted_caller(); + let expected_verifying_key = BoundedVec::default(); // add validators and a registering user for i in 0..SIGNING_PARTY_SIZE { @@ -123,12 +126,13 @@ benchmarks! { >::put(JumpStartDetails { jump_start_status: JumpStartStatus::InProgress(0), confirmations: vec![], + verifying_key: None }); let balance = ::Currency::minimum_balance() * 100u32.into(); let _ = ::Currency::make_free_balance_be(&threshold_account, balance); - }: confirm_jump_start(RawOrigin::Signed(threshold_account.clone())) + }: confirm_jump_start(RawOrigin::Signed(threshold_account.clone()), expected_verifying_key) verify { let validator_stash = pallet_staking_extension::Pallet::::threshold_to_stash(&threshold_account).unwrap(); diff --git a/pallets/registry/src/lib.rs b/pallets/registry/src/lib.rs index afcc3904b..2138106b5 100644 --- a/pallets/registry/src/lib.rs +++ b/pallets/registry/src/lib.rs @@ -134,6 +134,7 @@ pub mod pallet { pub struct JumpStartDetails { pub jump_start_status: JumpStartStatus, pub confirmations: Vec, + pub verifying_key: Option, } #[pallet::genesis_config] @@ -252,6 +253,7 @@ pub mod pallet { NoProgramSet, TooManyModifiableKeys, MismatchedVerifyingKeyLength, + MismatchedVerifyingKey, NotValidator, JumpStartProgressNotReady, JumpStartNotInProgress, @@ -292,6 +294,7 @@ pub mod pallet { JumpStartProgress::::put(JumpStartDetails { jump_start_status: JumpStartStatus::InProgress(converted_block_number), confirmations: vec![], + verifying_key: None, }); Self::deposit_event(Event::StartedNetworkJumpStart()); Ok(()) @@ -303,7 +306,10 @@ pub mod pallet { ::WeightInfo::confirm_jump_start_confirm(SIGNING_PARTY_SIZE as u32) .max(::WeightInfo::confirm_jump_start_done(SIGNING_PARTY_SIZE as u32)) })] - pub fn confirm_jump_start(origin: OriginFor) -> DispatchResultWithPostInfo { + pub fn confirm_jump_start( + origin: OriginFor, + verifying_key: VerifyingKey, + ) -> DispatchResultWithPostInfo { // check is validator let ts_server_account = ensure_signed(origin)?; @@ -314,6 +320,14 @@ pub mod pallet { ensure!(validators.contains(&validator_stash), Error::::NotValidator); let mut jump_start_info = JumpStartProgress::::get(); + if jump_start_info.verifying_key.is_some() { + ensure!( + jump_start_info.verifying_key == Some(verifying_key.clone()), + Error::::MismatchedVerifyingKey + ); + } else { + jump_start_info.verifying_key = Some(verifying_key.clone()); + } // check in progress ensure!( @@ -337,6 +351,7 @@ pub mod pallet { JumpStartProgress::::put(JumpStartDetails { jump_start_status: JumpStartStatus::Done, confirmations: vec![], + verifying_key: Some(verifying_key), }); Self::deposit_event(Event::FinishedNetworkJumpStart()); diff --git a/pallets/registry/src/tests.rs b/pallets/registry/src/tests.rs index 7be263f81..0baec6ceb 100644 --- a/pallets/registry/src/tests.rs +++ b/pallets/registry/src/tests.rs @@ -91,7 +91,11 @@ fn it_jumps_the_network() { new_test_ext().execute_with(|| { assert_eq!( Registry::jump_start_progress(), - JumpStartDetails { jump_start_status: JumpStartStatus::Ready, confirmations: vec![] }, + JumpStartDetails { + jump_start_status: JumpStartStatus::Ready, + confirmations: vec![], + verifying_key: None + }, "Checks default status of jump start detail" ); assert_ok!(Registry::jump_start_network(RuntimeOrigin::signed(1))); @@ -105,6 +109,7 @@ fn it_jumps_the_network() { JumpStartDetails { jump_start_status: JumpStartStatus::InProgress(0), confirmations: vec![], + verifying_key: None }, "Checks that jump start is in progress" ); @@ -121,7 +126,8 @@ fn it_jumps_the_network() { Registry::jump_start_progress(), JumpStartDetails { jump_start_status: JumpStartStatus::InProgress(100), - confirmations: vec![] + confirmations: vec![], + verifying_key: None }, "ensures jump start is called again if too many blocks passed" ); @@ -131,44 +137,64 @@ fn it_jumps_the_network() { #[test] fn it_tests_jump_start_result() { new_test_ext().execute_with(|| { + let expected_verifying_key = BoundedVec::default(); + assert_noop!( - Registry::confirm_jump_start(RuntimeOrigin::signed(1)), + Registry::confirm_jump_start(RuntimeOrigin::signed(1), expected_verifying_key.clone()), Error::::NoThresholdKey ); pallet_staking_extension::ThresholdToStash::::insert(1, 1); pallet_staking_extension::ThresholdToStash::::insert(7, 7); assert_noop!( - Registry::confirm_jump_start(RuntimeOrigin::signed(7)), + Registry::confirm_jump_start(RuntimeOrigin::signed(7), expected_verifying_key.clone()), Error::::NotValidator ); assert_noop!( - Registry::confirm_jump_start(RuntimeOrigin::signed(1)), + Registry::confirm_jump_start(RuntimeOrigin::signed(1), expected_verifying_key.clone()), Error::::JumpStartNotInProgress ); // trigger jump start assert_ok!(Registry::jump_start_network(RuntimeOrigin::signed(1))); - assert_ok!(Registry::confirm_jump_start(RuntimeOrigin::signed(1))); + assert_ok!(Registry::confirm_jump_start( + RuntimeOrigin::signed(1), + expected_verifying_key.clone() + )); assert_eq!( Registry::jump_start_progress(), JumpStartDetails { jump_start_status: JumpStartStatus::InProgress(0), - confirmations: vec![1] + confirmations: vec![1], + verifying_key: Some(expected_verifying_key.clone()) }, "Jump start recieves a confirmation" ); assert_noop!( - Registry::confirm_jump_start(RuntimeOrigin::signed(1)), + Registry::confirm_jump_start(RuntimeOrigin::signed(1), expected_verifying_key.clone()), Error::::AlreadyConfirmed ); + let bad_verifying_key = + BoundedVec::try_from(vec![0; VERIFICATION_KEY_LENGTH as usize]).unwrap(); + assert_noop!( + Registry::confirm_jump_start(RuntimeOrigin::signed(1), bad_verifying_key.clone()), + Error::::MismatchedVerifyingKey + ); + pallet_staking_extension::ThresholdToStash::::insert(2, 2); - assert_ok!(Registry::confirm_jump_start(RuntimeOrigin::signed(2))); + assert_ok!(Registry::confirm_jump_start( + RuntimeOrigin::signed(2), + expected_verifying_key.clone() + )); assert_eq!( Registry::jump_start_progress(), - JumpStartDetails { jump_start_status: JumpStartStatus::Done, confirmations: vec![] }, + JumpStartDetails { + jump_start_status: JumpStartStatus::Done, + confirmations: vec![], + verifying_key: Some(expected_verifying_key) + }, "Jump start in done status after all confirmations" ); }); diff --git a/pallets/staking/src/lib.rs b/pallets/staking/src/lib.rs index e9f8d0b59..247b919c1 100644 --- a/pallets/staking/src/lib.rs +++ b/pallets/staking/src/lib.rs @@ -447,7 +447,6 @@ pub mod pallet { ReshareBlock::::put(current_block_number + sp_runtime::traits::One::one()); // for next PR - // tell signers to do new key rotation with new signer group (dkg) // confirm action has taken place Ok(()) From 3ee66148a39a59d65bafdd275e800126f783f1d9 Mon Sep 17 00:00:00 2001 From: Jesse Abramowitz Date: Thu, 18 Jul 2024 13:40:06 -0400 Subject: [PATCH 04/25] add next signer to chain --- crates/shared/src/types.rs | 8 +++ .../src/helpers/substrate.rs | 39 +++++++++++ .../src/user/api.rs | 4 +- .../src/validator/api.rs | 69 +++++++++++++++---- .../src/validator/tests.rs | 47 +++++++++++-- pallets/propagation/src/lib.rs | 14 ++-- pallets/propagation/src/tests.rs | 9 ++- pallets/staking/src/lib.rs | 15 +++- pallets/staking/src/tests.rs | 15 +++- 9 files changed, 186 insertions(+), 34 deletions(-) diff --git a/crates/shared/src/types.rs b/crates/shared/src/types.rs index ecec165e1..2e1de3292 100644 --- a/crates/shared/src/types.rs +++ b/crates/shared/src/types.rs @@ -50,6 +50,14 @@ pub struct OcwMessageDkg { pub validators_info: Vec, } +/// Offchain worker message for initiating a dkg +#[cfg(not(feature = "wasm"))] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +#[derive(Clone, Encode, Decode, Debug, Eq, PartialEq, TypeInfo)] +pub struct OcwMessageReshare { + pub new_signer: Vec, +} + /// Offchain worker message for initiating a proactive refresh #[cfg(not(feature = "wasm"))] #[derive( diff --git a/crates/threshold-signature-server/src/helpers/substrate.rs b/crates/threshold-signature-server/src/helpers/substrate.rs index 9cb99b308..d2dbcb763 100644 --- a/crates/threshold-signature-server/src/helpers/substrate.rs +++ b/crates/threshold-signature-server/src/helpers/substrate.rs @@ -28,6 +28,7 @@ use crate::{ user::UserErr, }; pub use entropy_client::substrate::{query_chain, submit_transaction}; +use entropy_shared::user::ValidatorInfo; use subxt::{backend::legacy::LegacyRpcMethods, utils::AccountId32, Config, OnlineClient}; /// Given a threshold server's account ID, return its corresponding stash (validator) address. @@ -72,3 +73,41 @@ pub async fn get_registered_details( .ok_or_else(|| UserErr::ChainFetch("Not Registering error: Register Onchain first"))?; Ok(result) } + +pub async fn get_validators_info( + api: &OnlineClient, + rpc: &LegacyRpcMethods, + validators: Vec, +) -> Result, UserErr> { + let mut handles = Vec::new(); + let block_hash = rpc.chain_get_block_hash(None).await?; + for validator in validators { + let handle: tokio::task::JoinHandle> = tokio::task::spawn({ + let api = api.clone(); + let rpc = rpc.clone(); + + async move { + let threshold_address_query = + entropy::storage().staking_extension().threshold_servers(validator); + let server_info = query_chain(&api, &rpc, threshold_address_query, block_hash) + .await + .unwrap() + .unwrap(); + // .ok_or_else(|| { + // SubgroupGetError::ChainFetch("threshold_servers query error") + // })?; + Ok(ValidatorInfo { + x25519_public_key: server_info.x25519_public_key, + ip_address: std::str::from_utf8(&server_info.endpoint).unwrap().to_string(), + tss_account: server_info.tss_account, + }) + } + }); + handles.push(handle); + } + let mut all_signers: Vec = vec![]; + for handle in handles { + all_signers.push(handle.await.unwrap().unwrap()); + } + Ok(all_signers) +} diff --git a/crates/threshold-signature-server/src/user/api.rs b/crates/threshold-signature-server/src/user/api.rs index 85ca987e4..8f1a6d512 100644 --- a/crates/threshold-signature-server/src/user/api.rs +++ b/crates/threshold-signature-server/src/user/api.rs @@ -381,7 +381,9 @@ pub async fn confirm_registered( // TODO: Understand this better, potentially use sign_and_submit_default // or other method under sign_and_* if who.encode() == NETWORK_PARENT_KEY.encode() { - let jump_start_request = entropy::tx().registry().confirm_jump_start(); + let jump_start_request = entropy::tx().registry().confirm_jump_start( + entropy::runtime_types::bounded_collections::bounded_vec::BoundedVec(verifying_key), + ); submit_transaction(api, rpc, signer, &jump_start_request, Some(nonce)).await?; } else { let confirm_register_request = entropy::tx().registry().confirm_register( diff --git a/crates/threshold-signature-server/src/validator/api.rs b/crates/threshold-signature-server/src/validator/api.rs index b2e06fcf8..8b3bb5331 100644 --- a/crates/threshold-signature-server/src/validator/api.rs +++ b/crates/threshold-signature-server/src/validator/api.rs @@ -18,7 +18,11 @@ use crate::{ entropy::{self}, get_api, get_rpc, EntropyConfig, }, - helpers::{launch::FORBIDDEN_KEYS, substrate::query_chain}, + get_signer_and_x25519_secret, + helpers::{ + launch::FORBIDDEN_KEYS, + substrate::{get_validators_info, query_chain}, + }, validator::errors::ValidatorErr, AppState, }; @@ -30,6 +34,8 @@ use axum::{ routing::{get, post}, Json, Router, }; +use entropy_shared::OcwMessageReshare; +use parity_scale_codec::Decode; use std::str::FromStr; use subxt::{backend::legacy::LegacyRpcMethods, utils::AccountId32, OnlineClient}; @@ -44,23 +50,58 @@ pub async fn new_reshare( State(app_state): State, encoded_data: Bytes, ) -> Result { + let data = OcwMessageReshare::decode(&mut encoded_data.as_ref()).unwrap(); + // get block number from encoded data 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 - // .map_err(|e| ProtocolErr::UserError(e.to_string()))?; + + let signers_query = entropy::storage().staking_extension().signers(); + let signers = query_chain(&api, &rpc, signers_query, None) + .await? + .ok_or_else(|| ValidatorErr::ChainFetch("Max instructions per program error"))?; + + let next_signers_query = entropy::storage().staking_extension().signers(); + let next_signers = query_chain(&api, &rpc, next_signers_query, None) + .await? + .ok_or_else(|| ValidatorErr::ChainFetch("Max instructions per program error"))?; + + let validators_info = get_validators_info(&api, &rpc, next_signers).await.unwrap(); + dbg!(validators_info); + let (signer, x25519_secret_key) = + get_signer_and_x25519_secret(&app_state.kv_store).await.unwrap(); + // .map_err(|e| ProtocolErr::UserError(e.to_string()))?; + // let verifying_key_query = entropy::storage().registry().jump_start_progress(); + // let verifying_key = + // query_chain(&api, &rpc, verifying_key_query, None).await?.unwrap().verifying_key; + + // let is_in_current_signer = validators_info + // .iter() + // .any(|validator_info| validator_info.tss_account == validator_address.0.to_vec()); + // .ok_or_else(|| ValidatorErr::ChainFetch("Max instructions per program error"))?; + // dbg!(verifying_key); + // get old key if have it + // let old_holder = None; + // let new_holder = None; + // need a network verifying key - // let new_key_share = do_proactive_refresh( - // &validators_info, - // &signer, - // &x25519_secret_key, - // &app_state.listener_state, - // encoded_key, - // deserialized_old_key, - // block_number, - // ) - // .await?; + // let inputs = KeyResharingInputs { + // old_holder: Some(OldHolder { key_share: old_key }), + // new_holder: Some(NewHolder { + // verifying_key, + // old_threshold: party_ids.len(), + // old_holders: party_ids.clone(), + // }), + // new_holders: party_ids.clone(), + // new_threshold: threshold, + // }; + // let session = + // make_key_resharing_session(&mut OsRng, &session_id_hash, pair, &party_ids, &inputs) + // .map_err(ProtocolExecutionErr::SessionCreation)?; + + // let new_key_share = execute_protocol_generic(chans, session, session_id_hash).await?.0; + + // new_key_share.ok_or(ProtocolExecutionErr::NoOutputFromReshareProtocol) // validate message came from chain (check reshare block # against current block number) // get next signers see if I am one // If so do reshare call confirm_reshare (delete key when done) diff --git a/crates/threshold-signature-server/src/validator/tests.rs b/crates/threshold-signature-server/src/validator/tests.rs index 6f2090642..c251b2637 100644 --- a/crates/threshold-signature-server/src/validator/tests.rs +++ b/crates/threshold-signature-server/src/validator/tests.rs @@ -12,18 +12,53 @@ // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -use entropy_shared::MIN_BALANCE; -use entropy_testing_utils::{ - constants::{ALICE_STASH_ADDRESS, RANDOM_ACCOUNT}, - substrate_context::testing_context, -}; - use super::api::{check_balance_for_fees, check_forbidden_key}; use crate::{ chain_api::{get_api, get_rpc}, helpers::{launch::FORBIDDEN_KEYS, tests::initialize_test_logger}, validator::errors::ValidatorErr, }; +use parity_scale_codec::Encode; +use entropy_kvdb::clean_tests; +use entropy_shared::{OcwMessageReshare, MIN_BALANCE}; +use entropy_testing_utils::{ + constants::{ALICE_STASH_ADDRESS, RANDOM_ACCOUNT}, + spawn_testing_validators, + substrate_context::testing_context, + test_context_stationary, +}; +use serial_test::serial; +use sp_keyring::AccountKeyring; + +#[tokio::test] +#[serial] +async fn test_reshare() { + initialize_test_logger().await; + clean_tests(); + + let alice = AccountKeyring::Alice; + let alice_program = AccountKeyring::Charlie; + let program_manager = AccountKeyring::Dave; + + let cxt = test_context_stationary().await; + let (_validator_ips, _validator_ids) = spawn_testing_validators().await; + let api = get_api(&cxt.node_proc.ws_url).await.unwrap(); + let rpc = get_rpc(&cxt.node_proc.ws_url).await.unwrap(); + + let client = reqwest::Client::new(); + + let mut onchain_reshare_request = + OcwMessageReshare { new_signer: alice.public().encode() }; + + // fails repeated data + let _ = client + .post("http://127.0.0.1:3001/validator/reshare") + .body(onchain_reshare_request.clone().encode()) + .send() + .await + .unwrap(); + clean_tests(); +} #[tokio::test] #[should_panic = "Account does not exist, add balance"] diff --git a/pallets/propagation/src/lib.rs b/pallets/propagation/src/lib.rs index e9ed1e894..f4bbb007b 100644 --- a/pallets/propagation/src/lib.rs +++ b/pallets/propagation/src/lib.rs @@ -30,7 +30,9 @@ mod tests; #[frame_support::pallet] pub mod pallet { use codec::Encode; - use entropy_shared::{OcwMessageDkg, OcwMessageProactiveRefresh, ValidatorInfo}; + use entropy_shared::{ + OcwMessageDkg, OcwMessageProactiveRefresh, OcwMessageReshare, ValidatorInfo, + }; use frame_support::{pallet_prelude::*, sp_runtime::traits::Saturating}; use frame_system::pallet_prelude::*; use sp_runtime::{ @@ -140,8 +142,8 @@ pub mod pallet { } pub fn post_reshare(block_number: BlockNumberFor) -> Result<(), http::Error> { - let reshare_block_number = pallet_staking_extension::Pallet::::reshare_block(); - if reshare_block_number != block_number { + let reshare_data = pallet_staking_extension::Pallet::::reshare_data(); + if reshare_data.block_number != block_number { return Ok(()); } @@ -152,10 +154,14 @@ pub mod pallet { let url = str::from_utf8(&from_local).unwrap_or("http://localhost:3001/validator/reshare"); + let req_body = OcwMessageReshare { new_signer: reshare_data.new_signer }; + + log::warn!("propagation::post::req_body reshare: {:?}", &[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!["0x"]) + let pending = http::Request::post(url, vec![req_body.encode()]) .deadline(deadline) .send() .map_err(|_| http::Error::IoError)?; diff --git a/pallets/propagation/src/tests.rs b/pallets/propagation/src/tests.rs index 43396e894..d0ecb7c34 100644 --- a/pallets/propagation/src/tests.rs +++ b/pallets/propagation/src/tests.rs @@ -20,7 +20,7 @@ use entropy_shared::ValidatorInfo; use frame_support::{assert_ok, traits::OnInitialize, BoundedVec}; use pallet_programs::ProgramInfo; use pallet_registry::ProgramInstance; -use pallet_staking_extension::RefreshInfo; +use pallet_staking_extension::{RefreshInfo, ResharehInfo}; use sp_core::offchain::{testing, OffchainDbExt, OffchainWorkerExt, TransactionPoolExt}; use sp_io::TestExternalities; use sp_keystore::{testing::MemoryKeystore, KeystoreExt}; @@ -77,7 +77,7 @@ fn knows_how_to_mock_several_http_calls() { uri: "http://localhost:3001/validator/reshare".into(), sent: true, response: Some([].to_vec()), - body: [48, 120].to_vec(), + body: [32, 1, 0, 0, 0, 0, 0, 0, 0].to_vec(), ..Default::default() }); }); @@ -128,7 +128,10 @@ fn knows_how_to_mock_several_http_calls() { // doesn't trigger no reshare block Propagation::post_reshare(7).unwrap(); - pallet_staking_extension::ReshareBlock::::put(7); + pallet_staking_extension::ReshareData::::put(ResharehInfo { + block_number: 7, + new_signer: 1u64.encode(), + }); // now triggers Propagation::post_reshare(7).unwrap(); }) diff --git a/pallets/staking/src/lib.rs b/pallets/staking/src/lib.rs index 247b919c1..d04c1d5aa 100644 --- a/pallets/staking/src/lib.rs +++ b/pallets/staking/src/lib.rs @@ -114,6 +114,11 @@ pub mod pallet { pub proactive_refresh_keys: Vec>, } + #[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, Default)] + pub struct ResharehInfo { + pub new_signer: Vec, + pub block_number: BlockNumber, + } #[pallet::pallet] #[pallet::without_storage_info] pub struct Pallet(_); @@ -172,8 +177,8 @@ pub mod pallet { /// The next time a reshare should happen #[pallet::storage] - #[pallet::getter(fn reshare_block)] - pub type ReshareBlock = StorageValue<_, BlockNumberFor, ValueQuery>; + #[pallet::getter(fn reshare_data)] + pub type ReshareData = StorageValue<_, ResharehInfo>, ValueQuery>; /// A type used to simplify the genesis configuration definition. pub type ThresholdServersConfig = ( @@ -444,7 +449,11 @@ pub mod pallet { NextSigners::::put(current_signers); // trigger reshare at next block let current_block_number = >::block_number(); - ReshareBlock::::put(current_block_number + sp_runtime::traits::One::one()); + let reshare_info = ResharehInfo { + block_number: current_block_number + sp_runtime::traits::One::one(), + new_signer: next_signer_up.encode(), + }; + ReshareData::::put(reshare_info); // for next PR // confirm action has taken place diff --git a/pallets/staking/src/tests.rs b/pallets/staking/src/tests.rs index 429e672d3..42b7ed7f1 100644 --- a/pallets/staking/src/tests.rs +++ b/pallets/staking/src/tests.rs @@ -14,10 +14,10 @@ // along with this program. If not, see . use crate::{mock::*, tests::RuntimeEvent, Error, IsValidatorSynced, ServerInfo, ThresholdToStash}; +use codec::Encode; use frame_support::{assert_noop, assert_ok}; use frame_system::{EventRecord, Phase}; use pallet_session::SessionManager; - const NULL_ARR: [u8; 32] = [0; 32]; #[test] @@ -331,12 +331,21 @@ fn it_tests_new_session_handler() { // no next signers at start assert_eq!(Staking::next_signers().len(), 0); - assert_eq!(Staking::reshare_block(), 0, "Check reshare block start at zero"); + assert_eq!(Staking::reshare_data().block_number, 0, "Check reshare block start at zero"); System::set_block_number(100); let _ = Staking::new_session_handler(&vec![1u64, 2u64, 3u64]); // takes signers original (5,6) pops off first 5, adds (fake randomness in mock so adds 1) assert_eq!(Staking::next_signers(), vec![6u64, 1u64]); - assert_eq!(Staking::reshare_block(), 101, "Check reshare block start at 100 + 1"); + assert_eq!( + Staking::reshare_data().block_number, + 101, + "Check reshare block start at 100 + 1" + ); + assert_eq!( + Staking::reshare_data().new_signer, + 1u64.encode(), + "Check reshare next signer up is 1" + ); let _ = Staking::new_session_handler(&vec![6u64, 5u64, 3u64]); // takes 3 and leaves 5 and 6 since already in signer group From ca6968b08be159d7ad77f72d20752efba7c59a6a Mon Sep 17 00:00:00 2001 From: Jesse Abramowitz Date: Thu, 18 Jul 2024 14:39:50 -0400 Subject: [PATCH 05/25] get party ids --- .../src/validator/api.rs | 42 +++++++++++-------- .../src/validator/tests.rs | 5 +-- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/crates/threshold-signature-server/src/validator/api.rs b/crates/threshold-signature-server/src/validator/api.rs index 8b3bb5331..3c5c1e583 100644 --- a/crates/threshold-signature-server/src/validator/api.rs +++ b/crates/threshold-signature-server/src/validator/api.rs @@ -22,6 +22,7 @@ use crate::{ helpers::{ launch::FORBIDDEN_KEYS, substrate::{get_validators_info, query_chain}, + user::check_in_registration_group, }, validator::errors::ValidatorErr, AppState, @@ -34,10 +35,13 @@ use axum::{ routing::{get, post}, Json, Router, }; +pub use entropy_protocol::{errors::ProtocolExecutionErr, KeyParams, PartyId}; use entropy_shared::OcwMessageReshare; use parity_scale_codec::Decode; +use rand_core::OsRng; use std::str::FromStr; use subxt::{backend::legacy::LegacyRpcMethods, utils::AccountId32, OnlineClient}; +use synedrion::{make_key_resharing_session, KeyResharingInputs, NewHolder, OldHolder}; /// HTTP POST endpoint called by the off-chain worker (propagation pallet) during user registration. /// @@ -67,7 +71,6 @@ pub async fn new_reshare( .ok_or_else(|| ValidatorErr::ChainFetch("Max instructions per program error"))?; let validators_info = get_validators_info(&api, &rpc, next_signers).await.unwrap(); - dbg!(validators_info); let (signer, x25519_secret_key) = get_signer_and_x25519_secret(&app_state.kv_store).await.unwrap(); // .map_err(|e| ProtocolErr::UserError(e.to_string()))?; @@ -75,26 +78,29 @@ pub async fn new_reshare( // let verifying_key = // query_chain(&api, &rpc, verifying_key_query, None).await?.unwrap().verifying_key; - // let is_in_current_signer = validators_info - // .iter() - // .any(|validator_info| validator_info.tss_account == validator_address.0.to_vec()); - // .ok_or_else(|| ValidatorErr::ChainFetch("Max instructions per program error"))?; + let is_proper_signer = &validators_info + .iter() + .any(|validator_info| validator_info.tss_account == *signer.account_id()); + dbg!(is_proper_signer); + if !is_proper_signer { + return Ok(StatusCode::MISDIRECTED_REQUEST); + } // dbg!(verifying_key); // get old key if have it - // let old_holder = None; - // let new_holder = None; - + let old_holder: Option> = None; + // get new holder data + let new_holder: Option> = None; + let mut party_ids: Vec = + validators_info.iter().cloned().map(|x| PartyId::new(x.tss_account)).collect(); + party_ids.sort(); // need a network verifying key - // let inputs = KeyResharingInputs { - // old_holder: Some(OldHolder { key_share: old_key }), - // new_holder: Some(NewHolder { - // verifying_key, - // old_threshold: party_ids.len(), - // old_holders: party_ids.clone(), - // }), - // new_holders: party_ids.clone(), - // new_threshold: threshold, - // }; + let inputs = KeyResharingInputs { + old_holder, + new_holder, + // todo get from chain + new_holders: party_ids.clone(), + new_threshold: 2, + }; // let session = // make_key_resharing_session(&mut OsRng, &session_id_hash, pair, &party_ids, &inputs) // .map_err(ProtocolExecutionErr::SessionCreation)?; diff --git a/crates/threshold-signature-server/src/validator/tests.rs b/crates/threshold-signature-server/src/validator/tests.rs index c251b2637..de9541cab 100644 --- a/crates/threshold-signature-server/src/validator/tests.rs +++ b/crates/threshold-signature-server/src/validator/tests.rs @@ -18,7 +18,6 @@ use crate::{ helpers::{launch::FORBIDDEN_KEYS, tests::initialize_test_logger}, validator::errors::ValidatorErr, }; -use parity_scale_codec::Encode; use entropy_kvdb::clean_tests; use entropy_shared::{OcwMessageReshare, MIN_BALANCE}; use entropy_testing_utils::{ @@ -27,6 +26,7 @@ use entropy_testing_utils::{ substrate_context::testing_context, test_context_stationary, }; +use parity_scale_codec::Encode; use serial_test::serial; use sp_keyring::AccountKeyring; @@ -47,8 +47,7 @@ async fn test_reshare() { let client = reqwest::Client::new(); - let mut onchain_reshare_request = - OcwMessageReshare { new_signer: alice.public().encode() }; + let mut onchain_reshare_request = OcwMessageReshare { new_signer: alice.public().encode() }; // fails repeated data let _ = client From b137a55de9382554b873843b970003be74e88509 Mon Sep 17 00:00:00 2001 From: Jesse Abramowitz Date: Thu, 18 Jul 2024 17:17:54 -0400 Subject: [PATCH 06/25] get session info --- crates/protocol/tests/protocol.rs | 4 ++- crates/shared/src/types.rs | 1 + .../src/validator/api.rs | 34 +++++++++++++------ .../src/validator/tests.rs | 4 ++- pallets/propagation/src/lib.rs | 8 ++++- 5 files changed, 38 insertions(+), 13 deletions(-) diff --git a/crates/protocol/tests/protocol.rs b/crates/protocol/tests/protocol.rs index 36365c2d5..f3611706d 100644 --- a/crates/protocol/tests/protocol.rs +++ b/crates/protocol/tests/protocol.rs @@ -17,7 +17,9 @@ //! to the number of cpus available. Note that these should be run in release mode to get a realistic //! idea of how long things take in production. -use entropy_protocol::{KeyParams, PartyId, SessionId, SigningSessionInfo, ValidatorInfo}; +use entropy_protocol::{ + KeyParams, PartyId, SessionId, SessionId, SigningSessionInfo, ValidatorInfo, +}; use futures::future; use rand_core::OsRng; use serial_test::serial; diff --git a/crates/shared/src/types.rs b/crates/shared/src/types.rs index 2e1de3292..9ed3696a6 100644 --- a/crates/shared/src/types.rs +++ b/crates/shared/src/types.rs @@ -56,6 +56,7 @@ pub struct OcwMessageDkg { #[derive(Clone, Encode, Decode, Debug, Eq, PartialEq, TypeInfo)] pub struct OcwMessageReshare { pub new_signer: Vec, + pub block_number: BlockNumber, } /// Offchain worker message for initiating a proactive refresh diff --git a/crates/threshold-signature-server/src/validator/api.rs b/crates/threshold-signature-server/src/validator/api.rs index 3c5c1e583..1678f0182 100644 --- a/crates/threshold-signature-server/src/validator/api.rs +++ b/crates/threshold-signature-server/src/validator/api.rs @@ -35,7 +35,10 @@ use axum::{ routing::{get, post}, Json, Router, }; -pub use entropy_protocol::{errors::ProtocolExecutionErr, KeyParams, PartyId}; +pub use entropy_protocol::{ + decode_verifying_key, errors::ProtocolExecutionErr, execute_protocol::PairWrapper, KeyParams, + PartyId, SessionId, +}; use entropy_shared::OcwMessageReshare; use parity_scale_codec::Decode; use rand_core::OsRng; @@ -74,9 +77,11 @@ pub async fn new_reshare( let (signer, x25519_secret_key) = get_signer_and_x25519_secret(&app_state.kv_store).await.unwrap(); // .map_err(|e| ProtocolErr::UserError(e.to_string()))?; - // let verifying_key_query = entropy::storage().registry().jump_start_progress(); - // let verifying_key = - // query_chain(&api, &rpc, verifying_key_query, None).await?.unwrap().verifying_key; + let verifying_key_query = entropy::storage().registry().jump_start_progress(); + let verifying_key = + query_chain(&api, &rpc, verifying_key_query, None).await?.unwrap().verifying_key.unwrap().0; + let decoded_verifying_key = + decode_verifying_key(&verifying_key.clone().try_into().unwrap()).unwrap(); let is_proper_signer = &validators_info .iter() @@ -88,22 +93,31 @@ pub async fn new_reshare( // dbg!(verifying_key); // get old key if have it let old_holder: Option> = None; - // get new holder data - let new_holder: Option> = None; let mut party_ids: Vec = validators_info.iter().cloned().map(|x| PartyId::new(x.tss_account)).collect(); party_ids.sort(); + let new_holder = NewHolder { + verifying_key: decoded_verifying_key, + old_threshold: party_ids.len(), + old_holders: party_ids.clone(), + }; // need a network verifying key let inputs = KeyResharingInputs { old_holder, - new_holder, + new_holder: Some(new_holder), // todo get from chain new_holders: party_ids.clone(), new_threshold: 2, }; - // let session = - // make_key_resharing_session(&mut OsRng, &session_id_hash, pair, &party_ids, &inputs) - // .map_err(ProtocolExecutionErr::SessionCreation)?; + // TODO rename to Reshare + let session_id = SessionId::ProactiveRefresh { verifying_key, block_number: data.block_number }; + let session_id_hash = session_id.blake2(None).unwrap(); + let pair = PairWrapper(signer.signer().clone()); + + let session = + make_key_resharing_session(&mut OsRng, &session_id_hash, pair, &party_ids, &inputs) + .unwrap(); + // .map_err(ProtocolExecutionErr::SessionCreation)?; // let new_key_share = execute_protocol_generic(chans, session, session_id_hash).await?.0; diff --git a/crates/threshold-signature-server/src/validator/tests.rs b/crates/threshold-signature-server/src/validator/tests.rs index de9541cab..85f68b8c1 100644 --- a/crates/threshold-signature-server/src/validator/tests.rs +++ b/crates/threshold-signature-server/src/validator/tests.rs @@ -46,8 +46,10 @@ async fn test_reshare() { let rpc = get_rpc(&cxt.node_proc.ws_url).await.unwrap(); let client = reqwest::Client::new(); + let block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number + 1; - let mut onchain_reshare_request = OcwMessageReshare { new_signer: alice.public().encode() }; + let mut onchain_reshare_request = + OcwMessageReshare { new_signer: alice.public().encode(), block_number }; // fails repeated data let _ = client diff --git a/pallets/propagation/src/lib.rs b/pallets/propagation/src/lib.rs index f4bbb007b..78ae3e0df 100644 --- a/pallets/propagation/src/lib.rs +++ b/pallets/propagation/src/lib.rs @@ -153,8 +153,14 @@ pub mod pallet { .unwrap_or_else(|| b"http://localhost:3001/validator/reshare".to_vec()); let url = str::from_utf8(&from_local).unwrap_or("http://localhost:3001/validator/reshare"); + let converted_block_number: u32 = + BlockNumberFor::::try_into(block_number).unwrap_or_default(); - let req_body = OcwMessageReshare { new_signer: reshare_data.new_signer }; + let req_body = OcwMessageReshare { + new_signer: reshare_data.new_signer, + // subtract 1 from blocknumber since the request is from the last block + block_number: converted_block_number.saturating_sub(1), + }; log::warn!("propagation::post::req_body reshare: {:?}", &[req_body.encode()]); From 87e2390bd61761fcc7036404c3ea18180e411869 Mon Sep 17 00:00:00 2001 From: Jesse Abramowitz Date: Fri, 19 Jul 2024 11:45:34 -0400 Subject: [PATCH 07/25] execute reshare protocol --- crates/protocol/src/execute_protocol.rs | 2 +- .../src/validator/api.rs | 60 ++++++++++++++++--- 2 files changed, 54 insertions(+), 8 deletions(-) diff --git a/crates/protocol/src/execute_protocol.rs b/crates/protocol/src/execute_protocol.rs index a03f7c262..f0a376f6a 100644 --- a/crates/protocol/src/execute_protocol.rs +++ b/crates/protocol/src/execute_protocol.rs @@ -67,7 +67,7 @@ impl RandomizedPrehashSigner for PairWrapper { } } -async fn execute_protocol_generic>( +pub async fn execute_protocol_generic>( mut chans: Channels, session: Session, session_id_hash: [u8; 32], diff --git a/crates/threshold-signature-server/src/validator/api.rs b/crates/threshold-signature-server/src/validator/api.rs index 1678f0182..ef29f6654 100644 --- a/crates/threshold-signature-server/src/validator/api.rs +++ b/crates/threshold-signature-server/src/validator/api.rs @@ -24,6 +24,10 @@ use crate::{ substrate::{get_validators_info, query_chain}, user::check_in_registration_group, }, + signing_client::{ + protocol_transport::{handle_socket, open_protocol_connections}, + ListenerState, ProtocolErr, + }, validator::errors::ValidatorErr, AppState, }; @@ -36,15 +40,19 @@ use axum::{ Json, Router, }; pub use entropy_protocol::{ - decode_verifying_key, errors::ProtocolExecutionErr, execute_protocol::PairWrapper, KeyParams, - PartyId, SessionId, + decode_verifying_key, + errors::ProtocolExecutionErr, + execute_protocol::{execute_protocol_generic, Channels, PairWrapper}, + KeyParams, Listener, PartyId, SessionId, ValidatorInfo, }; -use entropy_shared::OcwMessageReshare; +use entropy_shared::{OcwMessageReshare, SETUP_TIMEOUT_SECONDS}; use parity_scale_codec::Decode; use rand_core::OsRng; -use std::str::FromStr; +use sp_core::Pair; +use std::{str::FromStr, time::Duration}; use subxt::{backend::legacy::LegacyRpcMethods, utils::AccountId32, OnlineClient}; use synedrion::{make_key_resharing_session, KeyResharingInputs, NewHolder, OldHolder}; +use tokio::time::timeout; /// HTTP POST endpoint called by the off-chain worker (propagation pallet) during user registration. /// @@ -111,21 +119,59 @@ pub async fn new_reshare( }; // TODO rename to Reshare let session_id = SessionId::ProactiveRefresh { verifying_key, block_number: data.block_number }; + let account_id = AccountId32(signer.signer().public().0); let session_id_hash = session_id.blake2(None).unwrap(); let pair = PairWrapper(signer.signer().clone()); + let mut converted_validator_info = vec![]; + let mut tss_accounts = vec![]; + for validator_info in validators_info { + let validator_info = ValidatorInfo { + x25519_public_key: validator_info.x25519_public_key, + ip_address: validator_info.ip_address, + tss_account: validator_info.tss_account.clone(), + }; + converted_validator_info.push(validator_info.clone()); + tss_accounts.push(validator_info.tss_account.clone()); + } + + let (rx_ready, rx_from_others, listener) = + Listener::new(converted_validator_info.clone(), &account_id); + app_state.listener_state + .listeners + .lock() + .unwrap() + // .map_err(|_| ProtocolErr::SessionError("Error getting lock".to_string()))? + .insert(session_id.clone(), listener); + + open_protocol_connections( + &converted_validator_info, + &session_id, + signer.signer(), + &app_state.listener_state, + &x25519_secret_key, + ) + .await + .unwrap(); + + let channels = { + let ready = timeout(Duration::from_secs(SETUP_TIMEOUT_SECONDS), rx_ready).await.unwrap(); + let broadcast_out = ready.unwrap().unwrap(); + Channels(broadcast_out, rx_from_others) + }; + let session = make_key_resharing_session(&mut OsRng, &session_id_hash, pair, &party_ids, &inputs) .unwrap(); // .map_err(ProtocolExecutionErr::SessionCreation)?; - // let new_key_share = execute_protocol_generic(chans, session, session_id_hash).await?.0; + let new_key_share = + execute_protocol_generic(channels, session, session_id_hash).await.unwrap().0.unwrap(); + // new_key_share.ok_or(ProtocolExecutionErr::NoOutputFromReshareProtocol) // new_key_share.ok_or(ProtocolExecutionErr::NoOutputFromReshareProtocol) // validate message came from chain (check reshare block # against current block number) - // get next signers see if I am one // If so do reshare call confirm_reshare (delete key when done) - // If not terminate Ok(StatusCode::OK) } From 9e6db22997fb84bf9e0f919364096d18ce18adc8 Mon Sep 17 00:00:00 2001 From: Jesse Abramowitz Date: Fri, 19 Jul 2024 15:57:36 -0400 Subject: [PATCH 08/25] prepare refresh tests --- .../src/helpers/tests.rs | 20 ++++---- .../src/helpers/validator.rs | 4 +- .../src/signing_client/tests.rs | 2 +- .../src/user/tests.rs | 16 +++---- .../src/validator/api.rs | 4 +- .../src/validator/tests.rs | 46 +++++++++++++++++-- .../threshold-signature-server/tests/sign.rs | 2 +- .../tests/sign_eth_tx.rs | 2 +- 8 files changed, 68 insertions(+), 28 deletions(-) diff --git a/crates/threshold-signature-server/src/helpers/tests.rs b/crates/threshold-signature-server/src/helpers/tests.rs index 8f7a9e3be..afb73ac06 100644 --- a/crates/threshold-signature-server/src/helpers/tests.rs +++ b/crates/threshold-signature-server/src/helpers/tests.rs @@ -39,7 +39,8 @@ use crate::{ use axum::{routing::IntoMakeService, Router}; use entropy_kvdb::{encrypted_sled::PasswordMethod, get_db_path, kv_manager::KvManager}; use entropy_protocol::PartyId; -use entropy_shared::{DAVE_VERIFYING_KEY, EVE_VERIFYING_KEY}; +use entropy_shared::{DAVE_VERIFYING_KEY, EVE_VERIFYING_KEY, NETWORK_PARENT_KEY}; +use parity_scale_codec::Encode; use std::time::Duration; use subxt::{ backend::legacy::LegacyRpcMethods, ext::sp_core::sr25519, tx::PairSigner, @@ -118,7 +119,7 @@ pub async fn create_clients( } /// Spawn 3 TSS nodes with pre-stored keyshares -pub async fn spawn_testing_validators() -> (Vec, Vec) { +pub async fn spawn_testing_validators(add_parent_key: bool) -> (Vec, Vec) { // spawn threshold servers let ports = [3001i64, 3002, 3003]; @@ -143,9 +144,9 @@ pub async fn spawn_testing_validators() -> (Vec, Vec) { let ids = vec![alice_id, bob_id, charlie_id]; - put_keyshares_in_db("alice", alice_kv).await; - put_keyshares_in_db("bob", bob_kv).await; - put_keyshares_in_db("charlie", charlie_kv).await; + put_keyshares_in_db("alice", alice_kv, add_parent_key).await; + put_keyshares_in_db("bob", bob_kv, add_parent_key).await; + put_keyshares_in_db("charlie", charlie_kv, add_parent_key).await; let listener_alice = tokio::net::TcpListener::bind(format!("0.0.0.0:{}", ports[0])) .await @@ -175,9 +176,12 @@ pub async fn spawn_testing_validators() -> (Vec, Vec) { } /// Add the pre-generated test keyshares to a kvdb -async fn put_keyshares_in_db(holder_name: &str, kvdb: KvManager) { - let user_names_and_verifying_keys = [("eve", EVE_VERIFYING_KEY), ("dave", DAVE_VERIFYING_KEY)]; - +async fn put_keyshares_in_db(holder_name: &str, kvdb: KvManager, add_parent_key: bool) { + let mut user_names_and_verifying_keys = + vec![("eve", EVE_VERIFYING_KEY.to_vec()), ("dave", DAVE_VERIFYING_KEY.to_vec())]; + if add_parent_key { + user_names_and_verifying_keys.push(("eve", NETWORK_PARENT_KEY.encode())) + } for (user_name, user_verifying_key) in user_names_and_verifying_keys { let keyshare_bytes = { let project_root = diff --git a/crates/threshold-signature-server/src/helpers/validator.rs b/crates/threshold-signature-server/src/helpers/validator.rs index 6b80ad2b0..f35919f02 100644 --- a/crates/threshold-signature-server/src/helpers/validator.rs +++ b/crates/threshold-signature-server/src/helpers/validator.rs @@ -61,14 +61,14 @@ async fn get_hkdf(kv: &KvManager) -> Result, UserErr> { } /// Given a mnemonic, setup hkdf -fn get_hkdf_from_mnemonic(mnemonic: &str) -> Result, UserErr> { +pub fn get_hkdf_from_mnemonic(mnemonic: &str) -> Result, UserErr> { let mnemonic = Mnemonic::parse_in_normalized(Language::English, mnemonic) .map_err(|e| UserErr::Mnemonic(e.to_string()))?; Ok(Hkdf::::new(None, &mnemonic.to_seed(""))) } /// Derive signing keypair -fn get_signer_from_hkdf( +pub fn get_signer_from_hkdf( hkdf: &Hkdf, ) -> Result, UserErr> { let mut sr25519_seed = [0u8; 32]; diff --git a/crates/threshold-signature-server/src/signing_client/tests.rs b/crates/threshold-signature-server/src/signing_client/tests.rs index 2bdba0861..b4a9ee4ff 100644 --- a/crates/threshold-signature-server/src/signing_client/tests.rs +++ b/crates/threshold-signature-server/src/signing_client/tests.rs @@ -45,7 +45,7 @@ async fn test_proactive_refresh() { clean_tests(); let _cxt = test_node_process_testing_state(false).await; - let (validator_ips, _ids) = spawn_testing_validators().await; + let (validator_ips, _ids) = spawn_testing_validators(false).await; let client = reqwest::Client::new(); diff --git a/crates/threshold-signature-server/src/user/tests.rs b/crates/threshold-signature-server/src/user/tests.rs index e2febcf5f..f8fd905be 100644 --- a/crates/threshold-signature-server/src/user/tests.rs +++ b/crates/threshold-signature-server/src/user/tests.rs @@ -167,7 +167,7 @@ async fn test_sign_tx_no_chain() { let one = AccountKeyring::Dave; let two = AccountKeyring::Two; - let (_validator_ips, _validator_ids) = spawn_testing_validators().await; + let (_validator_ips, _validator_ids) = spawn_testing_validators(false).await; let substrate_context = test_context_stationary().await; let entropy_api = get_api(&substrate_context.node_proc.ws_url).await.unwrap(); let rpc = get_rpc(&substrate_context.node_proc.ws_url).await.unwrap(); @@ -369,7 +369,7 @@ async fn test_sign_tx_no_chain_fail() { let one = AccountKeyring::Dave; - let (_validator_ips, _validator_ids) = spawn_testing_validators().await; + let (_validator_ips, _validator_ids) = spawn_testing_validators(false).await; let substrate_context = test_context_stationary().await; let entropy_api = get_api(&substrate_context.node_proc.ws_url).await.unwrap(); let rpc = get_rpc(&substrate_context.node_proc.ws_url).await.unwrap(); @@ -493,7 +493,7 @@ async fn test_program_with_config() { let one = AccountKeyring::Dave; let two = AccountKeyring::Two; - let (_validator_ips, _validator_ids) = spawn_testing_validators().await; + let (_validator_ips, _validator_ids) = spawn_testing_validators(false).await; let substrate_context = test_context_stationary().await; let entropy_api = get_api(&substrate_context.node_proc.ws_url).await.unwrap(); let rpc = get_rpc(&substrate_context.node_proc.ws_url).await.unwrap(); @@ -559,7 +559,7 @@ async fn test_store_share() { let program_manager = AccountKeyring::Dave; let cxt = test_context_stationary().await; - let (_validator_ips, _validator_ids) = spawn_testing_validators().await; + let (_validator_ips, _validator_ids) = spawn_testing_validators(false).await; let api = get_api(&cxt.node_proc.ws_url).await.unwrap(); let rpc = get_rpc(&cxt.node_proc.ws_url).await.unwrap(); @@ -730,7 +730,7 @@ async fn test_jumpstart_network() { let alice = AccountKeyring::Alice; let cxt = test_context_stationary().await; - let (_validator_ips, _validator_ids) = spawn_testing_validators().await; + let (_validator_ips, _validator_ids) = spawn_testing_validators(false).await; let api = get_api(&cxt.node_proc.ws_url).await.unwrap(); let rpc = get_rpc(&cxt.node_proc.ws_url).await.unwrap(); @@ -921,7 +921,7 @@ async fn test_fail_infinite_program() { let one = AccountKeyring::Dave; let two = AccountKeyring::Two; - let (validator_ips, _validator_ids) = spawn_testing_validators().await; + let (validator_ips, _validator_ids) = spawn_testing_validators(false).await; let substrate_context = test_context_stationary().await; let entropy_api = get_api(&substrate_context.node_proc.ws_url).await.unwrap(); let rpc = get_rpc(&substrate_context.node_proc.ws_url).await.unwrap(); @@ -1020,7 +1020,7 @@ async fn test_device_key_proxy() { let one = AccountKeyring::Dave; - let (_validator_ips, _validator_ids) = spawn_testing_validators().await; + let (_validator_ips, _validator_ids) = spawn_testing_validators(false).await; let substrate_context = test_context_stationary().await; let entropy_api = get_api(&substrate_context.node_proc.ws_url).await.unwrap(); let rpc = get_rpc(&substrate_context.node_proc.ws_url).await.unwrap(); @@ -1128,7 +1128,7 @@ async fn test_faucet() { let two = AccountKeyring::Eve; let alice = AccountKeyring::Alice; - let (validator_ips, _validator_ids) = spawn_testing_validators().await; + let (validator_ips, _validator_ids) = spawn_testing_validators(false).await; let substrate_context = test_node_process_testing_state(true).await; let entropy_api = get_api(&substrate_context.ws_url).await.unwrap(); let rpc = get_rpc(&substrate_context.ws_url).await.unwrap(); diff --git a/crates/threshold-signature-server/src/validator/api.rs b/crates/threshold-signature-server/src/validator/api.rs index ef29f6654..ab19a42f0 100644 --- a/crates/threshold-signature-server/src/validator/api.rs +++ b/crates/threshold-signature-server/src/validator/api.rs @@ -74,12 +74,12 @@ pub async fn new_reshare( let signers_query = entropy::storage().staking_extension().signers(); let signers = query_chain(&api, &rpc, signers_query, None) .await? - .ok_or_else(|| ValidatorErr::ChainFetch("Max instructions per program error"))?; + .ok_or_else(|| ValidatorErr::ChainFetch("Error getting signers"))?; let next_signers_query = entropy::storage().staking_extension().signers(); let next_signers = query_chain(&api, &rpc, next_signers_query, None) .await? - .ok_or_else(|| ValidatorErr::ChainFetch("Max instructions per program error"))?; + .ok_or_else(|| ValidatorErr::ChainFetch("Error getting next signers"))?; let validators_info = get_validators_info(&api, &rpc, next_signers).await.unwrap(); let (signer, x25519_secret_key) = diff --git a/crates/threshold-signature-server/src/validator/tests.rs b/crates/threshold-signature-server/src/validator/tests.rs index 85f68b8c1..b65c13745 100644 --- a/crates/threshold-signature-server/src/validator/tests.rs +++ b/crates/threshold-signature-server/src/validator/tests.rs @@ -14,12 +14,21 @@ // along with this program. If not, see . use super::api::{check_balance_for_fees, check_forbidden_key}; use crate::{ - chain_api::{get_api, get_rpc}, - helpers::{launch::FORBIDDEN_KEYS, tests::initialize_test_logger}, + chain_api::{ + entropy::{self, runtime_types::bounded_collections::bounded_vec}, + get_api, get_rpc, EntropyConfig, + }, + helpers::{ + launch::{development_mnemonic, ValidatorName, FORBIDDEN_KEYS}, + substrate::submit_transaction, + tests::initialize_test_logger, + validator::{get_hkdf_from_mnemonic, get_signer_from_hkdf}, + }, + r#unsafe::api::UnsafeQuery, validator::errors::ValidatorErr, }; use entropy_kvdb::clean_tests; -use entropy_shared::{OcwMessageReshare, MIN_BALANCE}; +use entropy_shared::{OcwMessageReshare, EVE_VERIFYING_KEY, MIN_BALANCE}; use entropy_testing_utils::{ constants::{ALICE_STASH_ADDRESS, RANDOM_ACCOUNT}, spawn_testing_validators, @@ -29,6 +38,9 @@ use entropy_testing_utils::{ use parity_scale_codec::Encode; use serial_test::serial; use sp_keyring::AccountKeyring; +use subxt::{ + backend::legacy::LegacyRpcMethods, ext::sp_core::sr25519, tx::PairSigner, OnlineClient, +}; #[tokio::test] #[serial] @@ -41,7 +53,7 @@ async fn test_reshare() { let program_manager = AccountKeyring::Dave; let cxt = test_context_stationary().await; - let (_validator_ips, _validator_ids) = spawn_testing_validators().await; + let (_validator_ips, _validator_ids) = spawn_testing_validators(true).await; let api = get_api(&cxt.node_proc.ws_url).await.unwrap(); let rpc = get_rpc(&cxt.node_proc.ws_url).await.unwrap(); @@ -50,7 +62,7 @@ async fn test_reshare() { let mut onchain_reshare_request = OcwMessageReshare { new_signer: alice.public().encode(), block_number }; - + setup_for_reshare(&api, &rpc).await; // fails repeated data let _ = client .post("http://127.0.0.1:3001/validator/reshare") @@ -61,6 +73,30 @@ async fn test_reshare() { clean_tests(); } +async fn setup_for_reshare( + api: &OnlineClient, + rpc: &LegacyRpcMethods, +) { + let client = reqwest::Client::new(); + let alice = AccountKeyring::Alice; + let signer = PairSigner::::new(alice.clone().into()); + + let jump_start_request = entropy::tx().registry().jump_start_network(); + let _result = submit_transaction(api, rpc, &signer, &jump_start_request, None).await.unwrap(); + + let validators_names = vec![ValidatorName::Alice, ValidatorName::Bob]; + for validator_name in validators_names { + let mnemonic = development_mnemonic(&Some(validator_name)); + let hkdf = get_hkdf_from_mnemonic(&mnemonic.to_string()).unwrap(); + let tss_signer = get_signer_from_hkdf(&hkdf).unwrap(); + + let jump_start_confirm_request = entropy::tx() + .registry() + .confirm_jump_start(bounded_vec::BoundedVec(EVE_VERIFYING_KEY.to_vec())); + + submit_transaction(api, rpc, &tss_signer, &jump_start_confirm_request, None).await.unwrap(); + } +} #[tokio::test] #[should_panic = "Account does not exist, add balance"] async fn test_check_balance_for_fees() { diff --git a/crates/threshold-signature-server/tests/sign.rs b/crates/threshold-signature-server/tests/sign.rs index 8acc5295d..9ad3cd48b 100644 --- a/crates/threshold-signature-server/tests/sign.rs +++ b/crates/threshold-signature-server/tests/sign.rs @@ -40,7 +40,7 @@ async fn integration_test_sign_public() { let eve = AccountKeyring::Eve; let request_author = AccountKeyring::One; - let (_validator_ips, _validator_ids) = spawn_testing_validators().await; + let (_validator_ips, _validator_ids) = spawn_testing_validators(false).await; let substrate_context = test_context_stationary().await; let api = get_api(&substrate_context.node_proc.ws_url).await.unwrap(); diff --git a/crates/threshold-signature-server/tests/sign_eth_tx.rs b/crates/threshold-signature-server/tests/sign_eth_tx.rs index 8991bb953..c957f5148 100644 --- a/crates/threshold-signature-server/tests/sign_eth_tx.rs +++ b/crates/threshold-signature-server/tests/sign_eth_tx.rs @@ -48,7 +48,7 @@ async fn integration_test_sign_eth_tx() { clean_tests(); let pre_registered_user = AccountKeyring::Eve; - let (_validator_ips, _validator_ids) = spawn_testing_validators().await; + let (_validator_ips, _validator_ids) = spawn_testing_validators(false).await; let substrate_context = test_context_stationary().await; let api = get_api(&substrate_context.node_proc.ws_url).await.unwrap(); let rpc = get_rpc(&substrate_context.node_proc.ws_url).await.unwrap(); From eba2a82344df5bc8a060f6b15fdeacba4782c8c5 Mon Sep 17 00:00:00 2001 From: Jesse Abramowitz Date: Fri, 19 Jul 2024 17:07:48 -0400 Subject: [PATCH 09/25] proactive refresh test --- .../src/helpers/tests.rs | 6 ++--- .../src/validator/api.rs | 27 +++++++++++++------ .../src/validator/tests.rs | 25 ++++++++++++----- 3 files changed, 41 insertions(+), 17 deletions(-) diff --git a/crates/threshold-signature-server/src/helpers/tests.rs b/crates/threshold-signature-server/src/helpers/tests.rs index afb73ac06..c34cf69c9 100644 --- a/crates/threshold-signature-server/src/helpers/tests.rs +++ b/crates/threshold-signature-server/src/helpers/tests.rs @@ -178,9 +178,9 @@ pub async fn spawn_testing_validators(add_parent_key: bool) -> (Vec, Vec /// Add the pre-generated test keyshares to a kvdb async fn put_keyshares_in_db(holder_name: &str, kvdb: KvManager, add_parent_key: bool) { let mut user_names_and_verifying_keys = - vec![("eve", EVE_VERIFYING_KEY.to_vec()), ("dave", DAVE_VERIFYING_KEY.to_vec())]; + vec![("eve", hex::encode(EVE_VERIFYING_KEY)), ("dave", hex::encode(DAVE_VERIFYING_KEY))]; if add_parent_key { - user_names_and_verifying_keys.push(("eve", NETWORK_PARENT_KEY.encode())) + user_names_and_verifying_keys.push(("eve", hex::encode(NETWORK_PARENT_KEY))) } for (user_name, user_verifying_key) in user_names_and_verifying_keys { let keyshare_bytes = { @@ -192,7 +192,7 @@ async fn put_keyshares_in_db(holder_name: &str, kvdb: KvManager, add_parent_key: )); std::fs::read(file_path).unwrap() }; - let reservation = kvdb.kv().reserve_key(hex::encode(user_verifying_key)).await.unwrap(); + let reservation = kvdb.kv().reserve_key(user_verifying_key).await.unwrap(); kvdb.kv().put(reservation, keyshare_bytes).await.unwrap(); } } diff --git a/crates/threshold-signature-server/src/validator/api.rs b/crates/threshold-signature-server/src/validator/api.rs index ab19a42f0..8eacab83e 100644 --- a/crates/threshold-signature-server/src/validator/api.rs +++ b/crates/threshold-signature-server/src/validator/api.rs @@ -21,7 +21,7 @@ use crate::{ get_signer_and_x25519_secret, helpers::{ launch::FORBIDDEN_KEYS, - substrate::{get_validators_info, query_chain}, + substrate::{get_stash_address, get_validators_info, query_chain}, user::check_in_registration_group, }, signing_client::{ @@ -39,14 +39,15 @@ use axum::{ routing::{get, post}, Json, Router, }; +use entropy_kvdb::kv_manager::helpers::serialize as key_serialize; pub use entropy_protocol::{ decode_verifying_key, errors::ProtocolExecutionErr, execute_protocol::{execute_protocol_generic, Channels, PairWrapper}, - KeyParams, Listener, PartyId, SessionId, ValidatorInfo, + KeyParams, KeyShareWithAuxInfo, Listener, PartyId, SessionId, ValidatorInfo, }; -use entropy_shared::{OcwMessageReshare, SETUP_TIMEOUT_SECONDS}; -use parity_scale_codec::Decode; +use entropy_shared::{OcwMessageReshare, NETWORK_PARENT_KEY, SETUP_TIMEOUT_SECONDS}; +use parity_scale_codec::{Decode, Encode}; use rand_core::OsRng; use sp_core::Pair; use std::{str::FromStr, time::Duration}; @@ -94,13 +95,22 @@ pub async fn new_reshare( let is_proper_signer = &validators_info .iter() .any(|validator_info| validator_info.tss_account == *signer.account_id()); - dbg!(is_proper_signer); + if !is_proper_signer { return Ok(StatusCode::MISDIRECTED_REQUEST); } - // dbg!(verifying_key); // get old key if have it - let old_holder: Option> = None; + let my_stash_address = get_stash_address(&api, &rpc, &signer.account_id()).await.unwrap(); + let old_holder: Option> = + if data.new_signer == my_stash_address.encode() { + None + } else { + let kvdb_result = + app_state.kv_store.kv().get(&hex::encode(NETWORK_PARENT_KEY)).await.unwrap(); + let key_share: KeyShareWithAuxInfo = + entropy_kvdb::kv_manager::helpers::deserialize(&kvdb_result).unwrap(); + Some(OldHolder { key_share: key_share.0 }) + }; let mut party_ids: Vec = validators_info.iter().cloned().map(|x| PartyId::new(x.tss_account)).collect(); party_ids.sort(); @@ -168,7 +178,8 @@ pub async fn new_reshare( let new_key_share = execute_protocol_generic(channels, session, session_id_hash).await.unwrap().0.unwrap(); // new_key_share.ok_or(ProtocolExecutionErr::NoOutputFromReshareProtocol) - + let serialized_key_share = key_serialize(&new_key_share).unwrap(); + // .map_err(|_| ProtocolErr::KvSerialize("Kv Serialize Error".to_string()))?; // new_key_share.ok_or(ProtocolExecutionErr::NoOutputFromReshareProtocol) // validate message came from chain (check reshare block # against current block number) // If so do reshare call confirm_reshare (delete key when done) diff --git a/crates/threshold-signature-server/src/validator/tests.rs b/crates/threshold-signature-server/src/validator/tests.rs index b65c13745..2552db5f9 100644 --- a/crates/threshold-signature-server/src/validator/tests.rs +++ b/crates/threshold-signature-server/src/validator/tests.rs @@ -35,6 +35,10 @@ use entropy_testing_utils::{ substrate_context::testing_context, test_context_stationary, }; +use futures::{ + future::{self, join_all}, + join, Future, SinkExt, StreamExt, +}; use parity_scale_codec::Encode; use serial_test::serial; use sp_keyring::AccountKeyring; @@ -64,12 +68,21 @@ async fn test_reshare() { OcwMessageReshare { new_signer: alice.public().encode(), block_number }; setup_for_reshare(&api, &rpc).await; // fails repeated data - let _ = client - .post("http://127.0.0.1:3001/validator/reshare") - .body(onchain_reshare_request.clone().encode()) - .send() - .await - .unwrap(); + let response_results = join_all( + vec![3001, 3002, 3003] + .iter() + .map(|port| { + client + .post(format!("http://127.0.0.1:{}/validator/reshare", port)) + .body(onchain_reshare_request.clone().encode()) + .send() + }) + .collect::>(), + ) + .await; + for response_result in response_results { + assert_eq!(response_result.unwrap().text().await.unwrap(), ""); + } clean_tests(); } From bff3238c2886ad0bfb44249b6eee047c66be1c29 Mon Sep 17 00:00:00 2001 From: Jesse Abramowitz Date: Mon, 22 Jul 2024 10:39:31 -0400 Subject: [PATCH 10/25] add more info from chain --- .../src/validator/api.rs | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/crates/threshold-signature-server/src/validator/api.rs b/crates/threshold-signature-server/src/validator/api.rs index 8eacab83e..b449b7c55 100644 --- a/crates/threshold-signature-server/src/validator/api.rs +++ b/crates/threshold-signature-server/src/validator/api.rs @@ -67,8 +67,8 @@ pub async fn new_reshare( encoded_data: Bytes, ) -> Result { let data = OcwMessageReshare::decode(&mut encoded_data.as_ref()).unwrap(); + // TODO: validate message came from chain (check reshare block # against current block number) - // get block number from encoded data let api = get_api(&app_state.configuration.endpoint).await?; let rpc = get_rpc(&app_state.configuration.endpoint).await?; @@ -114,18 +114,30 @@ pub async fn new_reshare( let mut party_ids: Vec = validators_info.iter().cloned().map(|x| PartyId::new(x.tss_account)).collect(); party_ids.sort(); + + let old_holders_info = get_validators_info(&api, &rpc, signers).await.unwrap(); + let mut old_holders: Vec = + old_holders_info.iter().cloned().map(|x| PartyId::new(x.tss_account)).collect(); + old_holders.sort(); + dbg!(party_ids.clone()); + dbg!(old_holders.clone()); let new_holder = NewHolder { verifying_key: decoded_verifying_key, + // TODO: get from chain old_threshold: party_ids.len(), - old_holders: party_ids.clone(), + old_holders, }; - // need a network verifying key + let key_info_query = entropy::storage().parameters().signers_info(); + let threshold = query_chain(&api, &rpc, key_info_query, None) + .await? + .ok_or_else(|| ValidatorErr::ChainFetch("Failed to get signers info"))? + .threshold; + let inputs = KeyResharingInputs { old_holder, new_holder: Some(new_holder), - // todo get from chain new_holders: party_ids.clone(), - new_threshold: 2, + new_threshold: threshold as usize, }; // TODO rename to Reshare let session_id = SessionId::ProactiveRefresh { verifying_key, block_number: data.block_number }; @@ -181,7 +193,6 @@ pub async fn new_reshare( let serialized_key_share = key_serialize(&new_key_share).unwrap(); // .map_err(|_| ProtocolErr::KvSerialize("Kv Serialize Error".to_string()))?; // new_key_share.ok_or(ProtocolExecutionErr::NoOutputFromReshareProtocol) - // validate message came from chain (check reshare block # against current block number) // If so do reshare call confirm_reshare (delete key when done) Ok(StatusCode::OK) } From 7ff8ba9c5a87675e12270b4f6fda9f90d1e89b30 Mon Sep 17 00:00:00 2001 From: Jesse Abramowitz Date: Mon, 22 Jul 2024 11:50:04 -0400 Subject: [PATCH 11/25] error handling --- crates/protocol/src/lib.rs | 4 +- crates/protocol/tests/helpers/mod.rs | 6 +- crates/protocol/tests/protocol.rs | 4 +- .../src/signing_client/api.rs | 2 +- .../src/validator/api.rs | 80 +++++++++++-------- .../src/validator/errors.rs | 35 +++++++- 6 files changed, 89 insertions(+), 42 deletions(-) diff --git a/crates/protocol/src/lib.rs b/crates/protocol/src/lib.rs index 79443ea59..2b1b77ab7 100644 --- a/crates/protocol/src/lib.rs +++ b/crates/protocol/src/lib.rs @@ -160,7 +160,7 @@ pub enum SessionId { /// A distributed key generation protocol session for registering Dkg { user: AccountId32, block_number: u32 }, /// A proactive refresh session - ProactiveRefresh { verifying_key: Vec, block_number: u32 }, + Reshare { verifying_key: Vec, block_number: u32 }, /// A signing session Sign(SigningSessionInfo), } @@ -185,7 +185,7 @@ impl Hash for SessionId { user.0.hash(state); block_number.hash(state); }, - SessionId::ProactiveRefresh { verifying_key, block_number } => { + SessionId::Reshare { verifying_key, block_number } => { verifying_key.hash(state); block_number.hash(state); }, diff --git a/crates/protocol/tests/helpers/mod.rs b/crates/protocol/tests/helpers/mod.rs index 972bac0f2..627d1c912 100644 --- a/crates/protocol/tests/helpers/mod.rs +++ b/crates/protocol/tests/helpers/mod.rs @@ -55,7 +55,7 @@ struct ServerState { #[derive(Clone)] pub enum ProtocolOutput { Sign(RecoverableSignature), - ProactiveRefresh(ThresholdKeyShare), + Reshare(ThresholdKeyShare), Dkg(KeyShareWithAuxInfo), } @@ -130,7 +130,7 @@ pub async fn server( let (signature, recovery_id) = rsig.to_backend(); Ok(ProtocolOutput::Sign(RecoverableSignature { signature, recovery_id })) }, - SessionId::ProactiveRefresh { .. } => { + SessionId::Reshare { .. } => { let new_keyshare = execute_proactive_refresh( session_id, channels, @@ -139,7 +139,7 @@ pub async fn server( threshold_keyshare.unwrap(), ) .await?; - Ok(ProtocolOutput::ProactiveRefresh(new_keyshare)) + Ok(ProtocolOutput::Reshare(new_keyshare)) }, SessionId::Dkg { .. } => { let keyshare_and_aux_info = diff --git a/crates/protocol/tests/protocol.rs b/crates/protocol/tests/protocol.rs index f3611706d..b0041e949 100644 --- a/crates/protocol/tests/protocol.rs +++ b/crates/protocol/tests/protocol.rs @@ -114,7 +114,7 @@ async fn test_refresh_with_parties(num_parties: usize) { let keyshares = KeyShare::::new_centralized(&mut OsRng, &ids, None); let verifying_key = keyshares[0].verifying_key(); - let session_id = SessionId::ProactiveRefresh { + let session_id = SessionId::Reshare { verifying_key: verifying_key.to_encoded_point(true).as_bytes().to_vec(), block_number: 0, }; @@ -131,7 +131,7 @@ async fn test_refresh_with_parties(num_parties: usize) { .collect(); let threshold = parties.len(); let mut outputs = test_protocol_with_parties(parties, session_id, threshold).await; - if let ProtocolOutput::ProactiveRefresh(keyshare) = outputs.pop().unwrap() { + if let ProtocolOutput::Reshare(keyshare) = outputs.pop().unwrap() { assert!(keyshare.verifying_key() == verifying_key); } else { panic!("Unexpected protocol output"); diff --git a/crates/threshold-signature-server/src/signing_client/api.rs b/crates/threshold-signature-server/src/signing_client/api.rs index c30ba7f64..8c3858ef6 100644 --- a/crates/threshold-signature-server/src/signing_client/api.rs +++ b/crates/threshold-signature-server/src/signing_client/api.rs @@ -157,7 +157,7 @@ pub async fn do_proactive_refresh( tracing::debug!("Preparing to perform proactive refresh"); tracing::debug!("Signing with {:?}", &signer.signer().public()); - let session_id = SessionId::ProactiveRefresh { verifying_key, block_number }; + let session_id = SessionId::Reshare { verifying_key, block_number }; let account_id = SubxtAccountId32(signer.signer().public().0); let mut converted_validator_info = vec![]; let mut tss_accounts = vec![]; diff --git a/crates/threshold-signature-server/src/validator/api.rs b/crates/threshold-signature-server/src/validator/api.rs index b449b7c55..6ef27bbe3 100644 --- a/crates/threshold-signature-server/src/validator/api.rs +++ b/crates/threshold-signature-server/src/validator/api.rs @@ -66,8 +66,8 @@ pub async fn new_reshare( State(app_state): State, encoded_data: Bytes, ) -> Result { - let data = OcwMessageReshare::decode(&mut encoded_data.as_ref()).unwrap(); - // TODO: validate message came from chain (check reshare block # against current block number) + let data = OcwMessageReshare::decode(&mut encoded_data.as_ref())?; + // TODO: validate message came from chain (check reshare block # against current block number) see #941 let api = get_api(&app_state.configuration.endpoint).await?; let rpc = get_rpc(&app_state.configuration.endpoint).await?; @@ -82,15 +82,28 @@ pub async fn new_reshare( .await? .ok_or_else(|| ValidatorErr::ChainFetch("Error getting next signers"))?; - let validators_info = get_validators_info(&api, &rpc, next_signers).await.unwrap(); - let (signer, x25519_secret_key) = - get_signer_and_x25519_secret(&app_state.kv_store).await.unwrap(); - // .map_err(|e| ProtocolErr::UserError(e.to_string()))?; + let validators_info = get_validators_info(&api, &rpc, next_signers) + .await + .map_err(|e| ValidatorErr::UserError(e.to_string()))?; + let (signer, x25519_secret_key) = get_signer_and_x25519_secret(&app_state.kv_store) + .await + .map_err(|e| ValidatorErr::UserError(e.to_string()))?; + let verifying_key_query = entropy::storage().registry().jump_start_progress(); - let verifying_key = - query_chain(&api, &rpc, verifying_key_query, None).await?.unwrap().verifying_key.unwrap().0; - let decoded_verifying_key = - decode_verifying_key(&verifying_key.clone().try_into().unwrap()).unwrap(); + let verifying_key = query_chain(&api, &rpc, verifying_key_query, None) + .await? + .ok_or_else(|| ValidatorErr::ChainFetch("Parent verifying key error"))? + .verifying_key + .ok_or_else(|| ValidatorErr::OptionUnwrapError("Failed to get verifying key".to_string()))? + .0; + + let decoded_verifying_key = decode_verifying_key( + &verifying_key + .clone() + .try_into() + .map_err(|_| ValidatorErr::Conversion("Verifying key conversion"))?, + ) + .map_err(|e| ValidatorErr::VerifyingKeyError(e.to_string()))?; let is_proper_signer = &validators_info .iter() @@ -100,7 +113,9 @@ pub async fn new_reshare( return Ok(StatusCode::MISDIRECTED_REQUEST); } // get old key if have it - let my_stash_address = get_stash_address(&api, &rpc, &signer.account_id()).await.unwrap(); + let my_stash_address = get_stash_address(&api, &rpc, &signer.account_id()) + .await + .map_err(|e| ValidatorErr::UserError(e.to_string()))?; let old_holder: Option> = if data.new_signer == my_stash_address.encode() { None @@ -123,7 +138,7 @@ pub async fn new_reshare( dbg!(old_holders.clone()); let new_holder = NewHolder { verifying_key: decoded_verifying_key, - // TODO: get from chain + // TODO: get from chain see #941 old_threshold: party_ids.len(), old_holders, }; @@ -139,8 +154,8 @@ pub async fn new_reshare( new_holders: party_ids.clone(), new_threshold: threshold as usize, }; - // TODO rename to Reshare - let session_id = SessionId::ProactiveRefresh { verifying_key, block_number: data.block_number }; + + let session_id = SessionId::Reshare { verifying_key, block_number: data.block_number }; let account_id = AccountId32(signer.signer().public().0); let session_id_hash = session_id.blake2(None).unwrap(); let pair = PairWrapper(signer.signer().clone()); @@ -159,12 +174,12 @@ pub async fn new_reshare( let (rx_ready, rx_from_others, listener) = Listener::new(converted_validator_info.clone(), &account_id); - app_state.listener_state - .listeners - .lock() - .unwrap() - // .map_err(|_| ProtocolErr::SessionError("Error getting lock".to_string()))? - .insert(session_id.clone(), listener); + app_state + .listener_state + .listeners + .lock() + .map_err(|_| ValidatorErr::SessionError("Error getting lock".to_string()))? + .insert(session_id.clone(), listener); open_protocol_connections( &converted_validator_info, @@ -173,27 +188,26 @@ pub async fn new_reshare( &app_state.listener_state, &x25519_secret_key, ) - .await - .unwrap(); + .await?; let channels = { let ready = timeout(Duration::from_secs(SETUP_TIMEOUT_SECONDS), rx_ready).await.unwrap(); - let broadcast_out = ready.unwrap().unwrap(); + let broadcast_out = ready??; Channels(broadcast_out, rx_from_others) }; let session = make_key_resharing_session(&mut OsRng, &session_id_hash, pair, &party_ids, &inputs) - .unwrap(); - // .map_err(ProtocolExecutionErr::SessionCreation)?; - - let new_key_share = - execute_protocol_generic(channels, session, session_id_hash).await.unwrap().0.unwrap(); - // new_key_share.ok_or(ProtocolExecutionErr::NoOutputFromReshareProtocol) - let serialized_key_share = key_serialize(&new_key_share).unwrap(); - // .map_err(|_| ProtocolErr::KvSerialize("Kv Serialize Error".to_string()))?; - // new_key_share.ok_or(ProtocolExecutionErr::NoOutputFromReshareProtocol) - // If so do reshare call confirm_reshare (delete key when done) + .map_err(ProtocolExecutionErr::SessionCreation)?; + + let new_key_share = execute_protocol_generic(channels, session, session_id_hash) + .await + .map_err(|_| ValidatorErr::ProtocolError("Error executing protocol".to_string()))? + .0 + .ok_or(ValidatorErr::NoOutputFromReshareProtocol)?; + let serialized_key_share = key_serialize(&new_key_share) + .map_err(|_| ProtocolErr::KvSerialize("Kv Serialize Error".to_string()))?; + // TODO: do reshare call confirm_reshare (delete key when done) see #941 Ok(StatusCode::OK) } diff --git a/crates/threshold-signature-server/src/validator/errors.rs b/crates/threshold-signature-server/src/validator/errors.rs index bb1b075a8..5614fc1d1 100644 --- a/crates/threshold-signature-server/src/validator/errors.rs +++ b/crates/threshold-signature-server/src/validator/errors.rs @@ -15,12 +15,15 @@ use std::string::FromUtf8Error; +use crate::signing_client::ProtocolErr; use axum::{ http::StatusCode, response::{IntoResponse, Response}, }; -use entropy_protocol::sign_and_encrypt::EncryptedSignedMessageErr; +use entropy_protocol::{errors::ProtocolExecutionErr, sign_and_encrypt::EncryptedSignedMessageErr}; +use synedrion::sessions; use thiserror::Error; +use tokio::sync::oneshot::error::RecvError; #[derive(Debug, Error)] pub enum ValidatorErr { @@ -52,6 +55,36 @@ pub enum ValidatorErr { Authentication, #[error("Substrate: {0}")] SubstrateClient(#[from] entropy_client::substrate::SubstrateError), + #[error("Codec decoding error: {0}")] + CodecError(#[from] parity_scale_codec::Error), + #[error("User Error: {0}")] + UserError(String), + #[error("Option Unwrap error: {0}")] + OptionUnwrapError(String), + #[error("Vec Conversion Error: {0}")] + Conversion(&'static str), + #[error("Verifying key Error: {0}")] + VerifyingKeyError(String), + #[error("Session Error: {0}")] + SessionError(String), + #[error("Protocol Execution Error {0}")] + ProtocolExecution(#[from] ProtocolExecutionErr), + #[error("Listener: {0}")] + Listener(#[from] entropy_protocol::errors::ListenerErr), + #[error("Reshare protocol error: {0}")] + SigningClientError(#[from] ProtocolErr), + #[error("Timed out waiting for remote party")] + Timeout(#[from] tokio::time::error::Elapsed), + #[error("Oneshot timeout error: {0}")] + OneshotTimeout(#[from] RecvError), + #[error("Synedrion session creation error: {0}")] + SessionCreation(sessions::LocalError), + #[error("No output from reshare protocol")] + NoOutputFromReshareProtocol, + #[error("Protocol Error: {0}")] + ProtocolError(String), + #[error("Kv Fatal error")] + KvSerialize(String), } impl IntoResponse for ValidatorErr { From 9d23d85f786f8229a4f983e0d1d4e44d46b42b04 Mon Sep 17 00:00:00 2001 From: Jesse Abramowitz Date: Mon, 22 Jul 2024 11:54:30 -0400 Subject: [PATCH 12/25] clean --- .../src/helpers/tests.rs | 1 - .../src/validator/api.rs | 17 +++-------------- .../src/validator/tests.rs | 11 ++--------- 3 files changed, 5 insertions(+), 24 deletions(-) diff --git a/crates/threshold-signature-server/src/helpers/tests.rs b/crates/threshold-signature-server/src/helpers/tests.rs index c34cf69c9..79226ee35 100644 --- a/crates/threshold-signature-server/src/helpers/tests.rs +++ b/crates/threshold-signature-server/src/helpers/tests.rs @@ -40,7 +40,6 @@ use axum::{routing::IntoMakeService, Router}; use entropy_kvdb::{encrypted_sled::PasswordMethod, get_db_path, kv_manager::KvManager}; use entropy_protocol::PartyId; use entropy_shared::{DAVE_VERIFYING_KEY, EVE_VERIFYING_KEY, NETWORK_PARENT_KEY}; -use parity_scale_codec::Encode; use std::time::Duration; use subxt::{ backend::legacy::LegacyRpcMethods, ext::sp_core::sr25519, tx::PairSigner, diff --git a/crates/threshold-signature-server/src/validator/api.rs b/crates/threshold-signature-server/src/validator/api.rs index 6ef27bbe3..958077ce7 100644 --- a/crates/threshold-signature-server/src/validator/api.rs +++ b/crates/threshold-signature-server/src/validator/api.rs @@ -22,23 +22,12 @@ use crate::{ helpers::{ launch::FORBIDDEN_KEYS, substrate::{get_stash_address, get_validators_info, query_chain}, - user::check_in_registration_group, - }, - signing_client::{ - protocol_transport::{handle_socket, open_protocol_connections}, - ListenerState, ProtocolErr, }, + signing_client::{protocol_transport::open_protocol_connections, ProtocolErr}, validator::errors::ValidatorErr, AppState, }; -use axum::{ - body::{Body, Bytes}, - extract::State, - http::StatusCode, - response::IntoResponse, - routing::{get, post}, - Json, Router, -}; +use axum::{body::Bytes, extract::State, http::StatusCode}; use entropy_kvdb::kv_manager::helpers::serialize as key_serialize; pub use entropy_protocol::{ decode_verifying_key, @@ -205,7 +194,7 @@ pub async fn new_reshare( .map_err(|_| ValidatorErr::ProtocolError("Error executing protocol".to_string()))? .0 .ok_or(ValidatorErr::NoOutputFromReshareProtocol)?; - let serialized_key_share = key_serialize(&new_key_share) + let _serialized_key_share = key_serialize(&new_key_share) .map_err(|_| ProtocolErr::KvSerialize("Kv Serialize Error".to_string()))?; // TODO: do reshare call confirm_reshare (delete key when done) see #941 Ok(StatusCode::OK) diff --git a/crates/threshold-signature-server/src/validator/tests.rs b/crates/threshold-signature-server/src/validator/tests.rs index 2552db5f9..f35c3c0c1 100644 --- a/crates/threshold-signature-server/src/validator/tests.rs +++ b/crates/threshold-signature-server/src/validator/tests.rs @@ -24,7 +24,6 @@ use crate::{ tests::initialize_test_logger, validator::{get_hkdf_from_mnemonic, get_signer_from_hkdf}, }, - r#unsafe::api::UnsafeQuery, validator::errors::ValidatorErr, }; use entropy_kvdb::clean_tests; @@ -35,10 +34,7 @@ use entropy_testing_utils::{ substrate_context::testing_context, test_context_stationary, }; -use futures::{ - future::{self, join_all}, - join, Future, SinkExt, StreamExt, -}; +use futures::future::join_all; use parity_scale_codec::Encode; use serial_test::serial; use sp_keyring::AccountKeyring; @@ -53,8 +49,6 @@ async fn test_reshare() { clean_tests(); let alice = AccountKeyring::Alice; - let alice_program = AccountKeyring::Charlie; - let program_manager = AccountKeyring::Dave; let cxt = test_context_stationary().await; let (_validator_ips, _validator_ids) = spawn_testing_validators(true).await; @@ -64,7 +58,7 @@ async fn test_reshare() { let client = reqwest::Client::new(); let block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number + 1; - let mut onchain_reshare_request = + let onchain_reshare_request = OcwMessageReshare { new_signer: alice.public().encode(), block_number }; setup_for_reshare(&api, &rpc).await; // fails repeated data @@ -90,7 +84,6 @@ async fn setup_for_reshare( api: &OnlineClient, rpc: &LegacyRpcMethods, ) { - let client = reqwest::Client::new(); let alice = AccountKeyring::Alice; let signer = PairSigner::::new(alice.clone().into()); From c3fa56499615042126b95f26843f0bea9979363c Mon Sep 17 00:00:00 2001 From: Jesse Abramowitz Date: Mon, 22 Jul 2024 14:39:49 -0400 Subject: [PATCH 13/25] clean --- crates/shared/src/types.rs | 2 +- .../src/helpers/substrate.rs | 16 ++++++++-------- .../src/validator/api.rs | 9 ++++----- .../src/validator/tests.rs | 2 +- node/cli/src/service.rs | 5 +++++ pallets/propagation/src/lib.rs | 8 ++++++-- 6 files changed, 25 insertions(+), 17 deletions(-) diff --git a/crates/shared/src/types.rs b/crates/shared/src/types.rs index 9ed3696a6..bc001d85a 100644 --- a/crates/shared/src/types.rs +++ b/crates/shared/src/types.rs @@ -50,7 +50,7 @@ pub struct OcwMessageDkg { pub validators_info: Vec, } -/// Offchain worker message for initiating a dkg +/// Offchain worker message for initiating a refresh #[cfg(not(feature = "wasm"))] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] #[derive(Clone, Encode, Decode, Debug, Eq, PartialEq, TypeInfo)] diff --git a/crates/threshold-signature-server/src/helpers/substrate.rs b/crates/threshold-signature-server/src/helpers/substrate.rs index d2dbcb763..5b036275c 100644 --- a/crates/threshold-signature-server/src/helpers/substrate.rs +++ b/crates/threshold-signature-server/src/helpers/substrate.rs @@ -74,6 +74,7 @@ pub async fn get_registered_details( Ok(result) } +/// Takes Stash keys and returns validator info from chain pub async fn get_validators_info( api: &OnlineClient, rpc: &LegacyRpcMethods, @@ -82,7 +83,7 @@ pub async fn get_validators_info( let mut handles = Vec::new(); let block_hash = rpc.chain_get_block_hash(None).await?; for validator in validators { - let handle: tokio::task::JoinHandle> = tokio::task::spawn({ + let handle: tokio::task::JoinHandle> = tokio::task::spawn({ let api = api.clone(); let rpc = rpc.clone(); @@ -90,15 +91,14 @@ pub async fn get_validators_info( let threshold_address_query = entropy::storage().staking_extension().threshold_servers(validator); let server_info = query_chain(&api, &rpc, threshold_address_query, block_hash) - .await - .unwrap() - .unwrap(); - // .ok_or_else(|| { - // SubgroupGetError::ChainFetch("threshold_servers query error") - // })?; + .await? + .ok_or_else(|| { + UserErr::OptionUnwrapError("Failed to unwrap validator info".to_string()) + })?; + Ok(ValidatorInfo { x25519_public_key: server_info.x25519_public_key, - ip_address: std::str::from_utf8(&server_info.endpoint).unwrap().to_string(), + ip_address: std::str::from_utf8(&server_info.endpoint)?.to_string(), tss_account: server_info.tss_account, }) } diff --git a/crates/threshold-signature-server/src/validator/api.rs b/crates/threshold-signature-server/src/validator/api.rs index 958077ce7..565d86f13 100644 --- a/crates/threshold-signature-server/src/validator/api.rs +++ b/crates/threshold-signature-server/src/validator/api.rs @@ -44,12 +44,11 @@ use subxt::{backend::legacy::LegacyRpcMethods, utils::AccountId32, OnlineClient} use synedrion::{make_key_resharing_session, KeyResharingInputs, NewHolder, OldHolder}; use tokio::time::timeout; -/// 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 network reshare. /// -/// The HTTP request takes a Parity SCALE encoded [OcwMessageDkg] which indicates which validators -/// are in the validator group. +/// The HTTP request takes a Parity SCALE encoded [OcwMessageReshare] which indicates which validator is joining /// -/// This will trigger the Distributed Key Generation (DKG) process. +/// This will trigger the key reshare process. #[tracing::instrument(skip_all)] pub async fn new_reshare( State(app_state): State, @@ -102,7 +101,7 @@ pub async fn new_reshare( return Ok(StatusCode::MISDIRECTED_REQUEST); } // get old key if have it - let my_stash_address = get_stash_address(&api, &rpc, &signer.account_id()) + let my_stash_address = get_stash_address(&api, &rpc, signer.account_id()) .await .map_err(|e| ValidatorErr::UserError(e.to_string()))?; let old_holder: Option> = diff --git a/crates/threshold-signature-server/src/validator/tests.rs b/crates/threshold-signature-server/src/validator/tests.rs index f35c3c0c1..384d052df 100644 --- a/crates/threshold-signature-server/src/validator/tests.rs +++ b/crates/threshold-signature-server/src/validator/tests.rs @@ -61,7 +61,7 @@ async fn test_reshare() { let onchain_reshare_request = OcwMessageReshare { new_signer: alice.public().encode(), block_number }; setup_for_reshare(&api, &rpc).await; - // fails repeated data + let response_results = join_all( vec![3001, 3002, 3003] .iter() diff --git a/node/cli/src/service.rs b/node/cli/src/service.rs index e9cb4b0ef..ad8091a7b 100644 --- a/node/cli/src/service.rs +++ b/node/cli/src/service.rs @@ -362,6 +362,11 @@ pub fn new_full_base( b"refresh", &format!("{}/signer/proactive_refresh", endpoint).into_bytes(), ); + offchain_db.local_storage_set( + sp_core::offchain::StorageKind::PERSISTENT, + b"reshare_validators", + &format!("{}/validator/reshare", endpoint).into_bytes(), + ); log::info!("Threshold Signing Sever (TSS) location changed to {}", endpoint); } } diff --git a/pallets/propagation/src/lib.rs b/pallets/propagation/src/lib.rs index 78ae3e0df..751c995f6 100644 --- a/pallets/propagation/src/lib.rs +++ b/pallets/propagation/src/lib.rs @@ -79,6 +79,10 @@ pub mod pallet { /// Proactive Refresh Message passed to validators /// parameters. [OcwMessageProactiveRefresh] ProactiveRefreshMessagePassed(OcwMessageProactiveRefresh), + + /// Proactive Refresh Message passed to validators + /// parameters. [OcwMessageReshare] + KeyReshareMessagePassed(OcwMessageReshare), } #[pallet::call] @@ -149,7 +153,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"reshare") + let from_local = sp_io::offchain::local_storage_get(kind, b"reshare_validators") .unwrap_or_else(|| b"http://localhost:3001/validator/reshare".to_vec()); let url = str::from_utf8(&from_local).unwrap_or("http://localhost:3001/validator/reshare"); @@ -183,7 +187,7 @@ pub mod pallet { } let _res_body = response.body().collect::>(); - // Self::deposit_event(Event::ProactiveRefreshMessagePassed(req_body)); + Self::deposit_event(Event::KeyReshareMessagePassed(req_body)); Ok(()) } From f11f95c8a08f665d7381ead475736d574d459c5a Mon Sep 17 00:00:00 2001 From: Jesse Abramowitz Date: Mon, 22 Jul 2024 14:41:33 -0400 Subject: [PATCH 14/25] metadata --- crates/client/entropy_metadata.scale | Bin 205210 -> 205556 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/crates/client/entropy_metadata.scale b/crates/client/entropy_metadata.scale index 07035fcd33611c23a848f974a9a115c7fc17ae83..1dc12746e0b910bf948bb159e4dfbca4402ca707 100644 GIT binary patch delta 13493 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 P6e+LA?akRcY|{S$dfXks delta 13439 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 Date: Mon, 22 Jul 2024 19:05:46 -0400 Subject: [PATCH 15/25] fix --- crates/protocol/tests/protocol.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/crates/protocol/tests/protocol.rs b/crates/protocol/tests/protocol.rs index 3604ae65e..a2e287203 100644 --- a/crates/protocol/tests/protocol.rs +++ b/crates/protocol/tests/protocol.rs @@ -17,9 +17,7 @@ //! to the number of cpus available. Note that these should be run in release mode to get a realistic //! idea of how long things take in production. -use entropy_protocol::{ - KeyParams, PartyId, SessionId, SessionId, SigningSessionInfo, ValidatorInfo, -}; +use entropy_protocol::{KeyParams, PartyId, SessionId, SigningSessionInfo, ValidatorInfo}; use futures::future; use rand_core::OsRng; use serial_test::serial; From 41508bf6110b66ce4451357aac6f4b7b2bf42d87 Mon Sep 17 00:00:00 2001 From: Jesse Abramowitz Date: Mon, 22 Jul 2024 21:42:53 -0400 Subject: [PATCH 16/25] fix test --- pallets/propagation/src/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/propagation/src/tests.rs b/pallets/propagation/src/tests.rs index abab45515..587698859 100644 --- a/pallets/propagation/src/tests.rs +++ b/pallets/propagation/src/tests.rs @@ -78,7 +78,7 @@ fn knows_how_to_mock_several_http_calls() { uri: "http://localhost:3001/validator/reshare".into(), sent: true, response: Some([].to_vec()), - body: [32, 1, 0, 0, 0, 0, 0, 0, 0].to_vec(), + body: [32, 1, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0].to_vec(), ..Default::default() }); }); From 21ada128417cc3fbb9a6751f30b1a33d6f6d6b1a Mon Sep 17 00:00:00 2001 From: Jesse Abramowitz Date: Thu, 25 Jul 2024 18:47:40 -0400 Subject: [PATCH 17/25] clean --- crates/shared/src/types.rs | 1 + crates/threshold-signature-server/src/helpers/validator.rs | 2 +- crates/threshold-signature-server/src/validator/tests.rs | 7 +++---- pallets/propagation/src/lib.rs | 2 ++ 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/crates/shared/src/types.rs b/crates/shared/src/types.rs index bc001d85a..9f860d031 100644 --- a/crates/shared/src/types.rs +++ b/crates/shared/src/types.rs @@ -55,6 +55,7 @@ pub struct OcwMessageDkg { #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] #[derive(Clone, Encode, Decode, Debug, Eq, PartialEq, TypeInfo)] pub struct OcwMessageReshare { + // Stash address of new signer pub new_signer: Vec, pub block_number: BlockNumber, } diff --git a/crates/threshold-signature-server/src/helpers/validator.rs b/crates/threshold-signature-server/src/helpers/validator.rs index f35919f02..b571e0181 100644 --- a/crates/threshold-signature-server/src/helpers/validator.rs +++ b/crates/threshold-signature-server/src/helpers/validator.rs @@ -61,7 +61,7 @@ async fn get_hkdf(kv: &KvManager) -> Result, UserErr> { } /// Given a mnemonic, setup hkdf -pub fn get_hkdf_from_mnemonic(mnemonic: &str) -> Result, UserErr> { +fn get_hkdf_from_mnemonic(mnemonic: &str) -> Result, UserErr> { let mnemonic = Mnemonic::parse_in_normalized(Language::English, mnemonic) .map_err(|e| UserErr::Mnemonic(e.to_string()))?; Ok(Hkdf::::new(None, &mnemonic.to_seed(""))) diff --git a/crates/threshold-signature-server/src/validator/tests.rs b/crates/threshold-signature-server/src/validator/tests.rs index 384d052df..cc4bb3efd 100644 --- a/crates/threshold-signature-server/src/validator/tests.rs +++ b/crates/threshold-signature-server/src/validator/tests.rs @@ -22,7 +22,7 @@ use crate::{ launch::{development_mnemonic, ValidatorName, FORBIDDEN_KEYS}, substrate::submit_transaction, tests::initialize_test_logger, - validator::{get_hkdf_from_mnemonic, get_signer_from_hkdf}, + validator::get_signer_and_x25519_secret_from_mnemonic, }, validator::errors::ValidatorErr, }; @@ -93,9 +93,8 @@ async fn setup_for_reshare( let validators_names = vec![ValidatorName::Alice, ValidatorName::Bob]; for validator_name in validators_names { let mnemonic = development_mnemonic(&Some(validator_name)); - let hkdf = get_hkdf_from_mnemonic(&mnemonic.to_string()).unwrap(); - let tss_signer = get_signer_from_hkdf(&hkdf).unwrap(); - + let (tss_signer, _static_secret) = + get_signer_and_x25519_secret_from_mnemonic(&mnemonic.to_string()).unwrap(); let jump_start_confirm_request = entropy::tx() .registry() .confirm_jump_start(bounded_vec::BoundedVec(EVE_VERIFYING_KEY.to_vec())); diff --git a/pallets/propagation/src/lib.rs b/pallets/propagation/src/lib.rs index 1d6e04633..99062ca39 100644 --- a/pallets/propagation/src/lib.rs +++ b/pallets/propagation/src/lib.rs @@ -208,6 +208,7 @@ pub mod pallet { Ok(()) } + /// Submits a request to do a key refresh on the signers parent key. pub fn post_reshare(block_number: BlockNumberFor) -> Result<(), http::Error> { let reshare_data = pallet_staking_extension::Pallet::::reshare_data(); if reshare_data.block_number != block_number { @@ -255,6 +256,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() { From 4a1d93669f81a2426481bc391ff5b0b44579da8d Mon Sep 17 00:00:00 2001 From: JesseAbram <33698952+JesseAbram@users.noreply.github.com> Date: Thu, 25 Jul 2024 15:48:09 -0700 Subject: [PATCH 18/25] Apply suggestions from code review Co-authored-by: peg --- pallets/staking/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pallets/staking/src/lib.rs b/pallets/staking/src/lib.rs index d04c1d5aa..e810674ee 100644 --- a/pallets/staking/src/lib.rs +++ b/pallets/staking/src/lib.rs @@ -115,7 +115,7 @@ pub mod pallet { } #[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, Default)] - pub struct ResharehInfo { + pub struct ReshareInfo { pub new_signer: Vec, pub block_number: BlockNumber, } @@ -178,7 +178,7 @@ pub mod pallet { /// The next time a reshare should happen #[pallet::storage] #[pallet::getter(fn reshare_data)] - pub type ReshareData = StorageValue<_, ResharehInfo>, ValueQuery>; + pub type ReshareData = StorageValue<_, ReshareInfo>, ValueQuery>; /// A type used to simplify the genesis configuration definition. pub type ThresholdServersConfig = ( From de3822a892c6f20558ed7aefc64b5fd78cc3e929 Mon Sep 17 00:00:00 2001 From: Jesse Abramowitz Date: Thu, 25 Jul 2024 18:56:40 -0400 Subject: [PATCH 19/25] clean --- .../src/validator/api.rs | 14 ++++++++------ .../src/validator/errors.rs | 2 ++ pallets/staking/src/lib.rs | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/crates/threshold-signature-server/src/validator/api.rs b/crates/threshold-signature-server/src/validator/api.rs index a3a15fa12..e7e6738b5 100644 --- a/crates/threshold-signature-server/src/validator/api.rs +++ b/crates/threshold-signature-server/src/validator/api.rs @@ -111,16 +111,18 @@ pub async fn new_reshare( if data.new_signer == my_stash_address.encode() { None } else { - let kvdb_result = - app_state.kv_store.kv().get(&hex::encode(NETWORK_PARENT_KEY)).await.unwrap(); + let kvdb_result = app_state.kv_store.kv().get(&hex::encode(NETWORK_PARENT_KEY)).await?; let key_share: KeyShareWithAuxInfo = - entropy_kvdb::kv_manager::helpers::deserialize(&kvdb_result).unwrap(); + entropy_kvdb::kv_manager::helpers::deserialize(&kvdb_result) + .ok_or_else(|| ValidatorErr::KvDeserialize("Failed to load KeyShare".into()))?; Some(OldHolder { key_share: key_share.0 }) }; let party_ids: BTreeSet = validators_info.iter().cloned().map(|x| PartyId::new(x.tss_account)).collect(); - let old_holders_info = get_validators_info(&api, &rpc, signers).await.unwrap(); + let old_holders_info = get_validators_info(&api, &rpc, signers) + .await + .map_err(|e| ValidatorErr::UserError(e.to_string()))?; let old_holders: BTreeSet = old_holders_info.iter().cloned().map(|x| PartyId::new(x.tss_account)).collect(); @@ -145,7 +147,7 @@ pub async fn new_reshare( let session_id = SessionId::Reshare { verifying_key, block_number: data.block_number }; let account_id = AccountId32(signer.signer().public().0); - let session_id_hash = session_id.blake2(None).unwrap(); + let session_id_hash = session_id.blake2(None)?; let pair = PairWrapper(signer.signer().clone()); let mut converted_validator_info = vec![]; @@ -179,7 +181,7 @@ pub async fn new_reshare( .await?; let channels = { - let ready = timeout(Duration::from_secs(SETUP_TIMEOUT_SECONDS), rx_ready).await.unwrap(); + let ready = timeout(Duration::from_secs(SETUP_TIMEOUT_SECONDS), rx_ready).await?; let broadcast_out = ready??; Channels(broadcast_out, rx_from_others) }; diff --git a/crates/threshold-signature-server/src/validator/errors.rs b/crates/threshold-signature-server/src/validator/errors.rs index 5614fc1d1..6b8c7dae6 100644 --- a/crates/threshold-signature-server/src/validator/errors.rs +++ b/crates/threshold-signature-server/src/validator/errors.rs @@ -85,6 +85,8 @@ pub enum ValidatorErr { ProtocolError(String), #[error("Kv Fatal error")] KvSerialize(String), + #[error("Kv Deserialization Error: {0}")] + KvDeserialize(String), } impl IntoResponse for ValidatorErr { diff --git a/pallets/staking/src/lib.rs b/pallets/staking/src/lib.rs index e810674ee..8496a3b31 100644 --- a/pallets/staking/src/lib.rs +++ b/pallets/staking/src/lib.rs @@ -449,7 +449,7 @@ pub mod pallet { NextSigners::::put(current_signers); // trigger reshare at next block let current_block_number = >::block_number(); - let reshare_info = ResharehInfo { + let reshare_info = ReshareInfo { block_number: current_block_number + sp_runtime::traits::One::one(), new_signer: next_signer_up.encode(), }; From eb547e0aab03e77567954ba18eeb26f8455a7afd Mon Sep 17 00:00:00 2001 From: Jesse Abramowitz Date: Fri, 26 Jul 2024 10:18:34 -0400 Subject: [PATCH 20/25] update time to 0.3.36 --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1c02c4c79..9d6444099 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14096,9 +14096,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.34" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", @@ -14119,9 +14119,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ "num-conv", "time-core", From c1dd59dcde6bb8c8a94b0a8e84bc73865067e5c5 Mon Sep 17 00:00:00 2001 From: Jesse Abramowitz Date: Fri, 26 Jul 2024 10:28:48 -0400 Subject: [PATCH 21/25] lint fix --- crates/threshold-signature-server/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/threshold-signature-server/src/lib.rs b/crates/threshold-signature-server/src/lib.rs index 3f663e8ee..67dfb086c 100644 --- a/crates/threshold-signature-server/src/lib.rs +++ b/crates/threshold-signature-server/src/lib.rs @@ -86,10 +86,10 @@ //! in a [crate::validation::SignedMessage]. //! //! - [`/ws`](crate::signing_client::api::ws_handler()) - Websocket server for signing and DKG protocol -//! messages. This is opened by other threshold servers when the signing procotol is initiated. +//! messages. This is opened by other threshold servers when the signing procotol is initiated. //! //! - [`/validator/sync_kvdb`](crate::validator::api::sync_kvdb()) - POST - Called by another -//! threshold server when joining to get the key-shares from a member of their sub-group. +//! threshold server when joining to get the key-shares from a member of their sub-group. //! //! Takes a list of users account IDs for which shares are requested, wrapped in a //! [crate::validation::SignedMessage]. @@ -119,7 +119,7 @@ //! //! - Axum server - Includes global state and mutex locked IPs //! - [kvdb](entropy_kvdb) - Encrypted key-value database for storing key-shares and other data, build using -//! [sled](https://docs.rs/sled) +//! [sled](https://docs.rs/sled) #![doc(html_logo_url = "https://entropy.xyz/assets/logo_02.png")] pub use entropy_client::chain_api; pub(crate) mod health; From 0af6df267fcb81b631ae982df36d01e093992215 Mon Sep 17 00:00:00 2001 From: Jesse Abramowitz Date: Fri, 26 Jul 2024 10:41:23 -0400 Subject: [PATCH 22/25] lint --- runtime/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 53104c22a..ad26f4020 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -1384,8 +1384,8 @@ impl pallet_transaction_storage::Config for Runtime { parameter_types! { pub const BagThresholds: &'static [u64] = &voter_bags::THRESHOLDS; } -type VoterBagsListInstance = pallet_bags_list::Instance1; -impl pallet_bags_list::Config for Runtime { + +impl pallet_bags_list::Config for Runtime { type BagThresholds = BagThresholds; type RuntimeEvent = RuntimeEvent; type Score = VoteWeight; From b2129bf05c0e51ed121cc8e39b2607d3be5cdbab Mon Sep 17 00:00:00 2001 From: Jesse Abramowitz Date: Fri, 26 Jul 2024 10:59:08 -0400 Subject: [PATCH 23/25] lint --- node/cli/src/chain_spec/testnet.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/cli/src/chain_spec/testnet.rs b/node/cli/src/chain_spec/testnet.rs index 9824db2d4..c304a555d 100644 --- a/node/cli/src/chain_spec/testnet.rs +++ b/node/cli/src/chain_spec/testnet.rs @@ -202,7 +202,7 @@ pub fn testnet_local_initial_tss_servers() -> Vec<(TssAccountId, TssX25519Public /// However, this can be done by: /// - First, spinning up the machines you expect to be running at genesis /// - Then, running each TSS server with the `--setup-only` flag to get the `TssAccountId` and -/// `TssX25519PublicKey` +/// `TssX25519PublicKey` /// - Finally, writing all that information back here, and generating the chainspec from that. /// /// Note that if the KVDB of the TSS is deleted at any point during this process you will end up From 912b5961ec7584d1ea443d108f2b5989452528a1 Mon Sep 17 00:00:00 2001 From: Jesse Abramowitz Date: Fri, 26 Jul 2024 11:21:11 -0400 Subject: [PATCH 24/25] fix --- pallets/propagation/src/tests.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pallets/propagation/src/tests.rs b/pallets/propagation/src/tests.rs index 587698859..b3e411e11 100644 --- a/pallets/propagation/src/tests.rs +++ b/pallets/propagation/src/tests.rs @@ -20,7 +20,7 @@ use entropy_shared::ValidatorInfo; use frame_support::{assert_ok, traits::OnInitialize, BoundedVec}; use pallet_programs::ProgramInfo; use pallet_registry::ProgramInstance; -use pallet_staking_extension::{RefreshInfo, ResharehInfo}; +use pallet_staking_extension::{RefreshInfo, ReshareInfo}; use sp_core::offchain::{testing, OffchainDbExt, OffchainWorkerExt, TransactionPoolExt}; use sp_io::TestExternalities; use sp_keystore::{testing::MemoryKeystore, KeystoreExt}; @@ -131,7 +131,7 @@ fn knows_how_to_mock_several_http_calls() { // doesn't trigger no reshare block Propagation::post_reshare(7).unwrap(); - pallet_staking_extension::ReshareData::::put(ResharehInfo { + pallet_staking_extension::ReshareData::::put(ReshareInfo { block_number: 7, new_signer: 1u64.encode(), }); From d83f191993fc7333cfa9256c4ed2e0a19f1a9d8f Mon Sep 17 00:00:00 2001 From: Jesse Abramowitz Date: Fri, 26 Jul 2024 12:03:39 -0400 Subject: [PATCH 25/25] update metadata --- crates/client/entropy_metadata.scale | Bin 205775 -> 205774 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/crates/client/entropy_metadata.scale b/crates/client/entropy_metadata.scale index c89192baed094b337d94177421f2666252327413..9748b94ce140124336e156818ddb48b26d1c9399 100644 GIT binary patch delta 30 mcmX?qoafweo`x-qLX{jkL8-+ViAAaH(v^(cr7M}XtO5YP*9*x2 delta 31 ncmX?ioag*;o`x-qLY15bL8-+ViAAXy?NXJD+odX*wyXjG%%BW3