diff --git a/CHANGELOG.md b/CHANGELOG.md index c587380e9..57ed829bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,10 @@ At the moment this project **does not** adhere to fields, `pallet_staking_extension::initial_signers`, `pallet_parameters::total_signers`, and `pallet_parameters::threshold`, which are used to set up the initial threshold signing configuration for the network. +- In [#1030](https://github.com/entropyxyz/entropy-core/pull/1030), the registration flow got + cleaned up. A lot of storage entries, events, and extrinsics were removed from the `Registry` + pallet. The genesis build config was also removed. Additionally, the `new/user/` HTTP endpoint in + the TSS was removed since it was no longer necessary. ### Added - Jumpstart network ([#918](https://github.com/entropyxyz/entropy-core/pull/918)) @@ -34,8 +38,9 @@ At the moment this project **does not** adhere to - Fix TSS `AccountId` keys in chainspec ([#993](https://github.com/entropyxyz/entropy-core/pull/993)) ### Removed -- Remove `prune_registration` extrinsic ([#1022](https://github.com/entropyxyz/entropy-core/pull/1022)) -- Remove `confirm_registered` extrinsic ([#1025](https://github.com/entropyxyz/entropy-core/pull/1025)) +- Remove `prune_registration` extrinsic ([#1022](https://github.com/entropyxyz/entropy-core/pull/1022)) +- Remove `confirm_registered` extrinsic ([#1025](https://github.com/entropyxyz/entropy-core/pull/1025)) +- Remove old registration flow ([#1030](https://github.com/entropyxyz/entropy-core/pull/1030)) ## [0.2.0](https://github.com/entropyxyz/entropy-core/compare/release/v0.1.0...release/v0.2.0) - 2024-07-11 diff --git a/crates/client/entropy_metadata.scale b/crates/client/entropy_metadata.scale index 815243d40..2c9faa9d0 100644 Binary files a/crates/client/entropy_metadata.scale and b/crates/client/entropy_metadata.scale differ diff --git a/crates/client/src/client.rs b/crates/client/src/client.rs index 172ac1f8b..5e1285e82 100644 --- a/crates/client/src/client.rs +++ b/crates/client/src/client.rs @@ -37,7 +37,7 @@ use crate::{ EntropyConfig, }, client::entropy::staking_extension::events::{EndpointChanged, ThresholdAccountChanged}, - substrate::{get_registered_details, query_chain, submit_transaction_with_pair}, + substrate::{get_registered_details, submit_transaction_with_pair}, user::{get_signers_from_chain, UserSignatureRequest}, Hasher, }; @@ -49,7 +49,6 @@ use futures::{future, stream::StreamExt}; use sp_core::{sr25519, Pair}; use subxt::{ backend::legacy::LegacyRpcMethods, - events::EventsClient, utils::{AccountId32 as SubxtAccountId32, H256}, Config, OnlineClient, }; @@ -76,27 +75,15 @@ pub async fn register( signature_request_keypair: sr25519::Pair, program_account: SubxtAccountId32, programs_data: BoundedVec, - on_chain: bool, ) -> Result<([u8; VERIFYING_KEY_LENGTH], RegisteredInfo), ClientError> { - let registration_event = if on_chain { - put_register_request_on_chain( - api, - rpc, - signature_request_keypair.clone(), - program_account, - programs_data, - ) - .await? - } else { - put_old_register_request_on_chain( - api, - rpc, - signature_request_keypair.clone(), - program_account, - programs_data, - ) - .await? - }; + let registration_event = put_register_request_on_chain( + api, + rpc, + signature_request_keypair.clone(), + program_account, + programs_data, + ) + .await?; let verifying_key = registration_event.1 .0; let registered_info = get_registered_details(api, rpc, verifying_key.clone()).await?; @@ -126,10 +113,7 @@ pub async fn sign( ) -> Result { let message_hash = Hasher::keccak(&message); - let registered_info = - get_registered_details(api, rpc, signature_verifying_key.to_vec()).await?; - let with_parent_key = registered_info.derivation_path.is_some(); - let validators_info = get_signers_from_chain(api, rpc, with_parent_key).await?; + let validators_info = get_signers_from_chain(api, rpc).await?; tracing::debug!("Validators info {:?}", validators_info); let block_number = rpc.chain_get_header(None).await?.ok_or(ClientError::BlockNumber)?.number; @@ -332,7 +316,7 @@ pub async fn put_register_request_on_chain( ) -> Result { tracing::debug!("Registering an account using on-chain flow."); - let registering_tx = entropy::tx().registry().register_on_chain(deployer, program_instances); + let registering_tx = entropy::tx().registry().register(deployer, program_instances); let registered_events = submit_transaction_with_pair(api, rpc, &signature_request_keypair, ®istering_tx, None) .await?; @@ -348,63 +332,6 @@ pub async fn put_register_request_on_chain( registered_event } -/// Submits a transaction registering an account on-chain using the old off-chain flow. -#[tracing::instrument( - skip_all, - fields( - user_account = ?signature_request_keypair.public(), - ) -)] -pub async fn put_old_register_request_on_chain( - api: &OnlineClient, - rpc: &LegacyRpcMethods, - signature_request_keypair: sr25519::Pair, - deployer: SubxtAccountId32, - program_instances: BoundedVec, -) -> Result { - tracing::debug!("Registering an account using old off-chain flow."); - - let registering_tx = entropy::tx().registry().register(deployer, program_instances); - submit_transaction_with_pair(api, rpc, &signature_request_keypair, ®istering_tx, None) - .await?; - - let account_id: SubxtAccountId32 = signature_request_keypair.public().into(); - - for _ in 0..50 { - let block_hash = rpc.chain_get_block_hash(None).await?; - let events = - EventsClient::new(api.clone()).at(block_hash.ok_or(ClientError::BlockHash)?).await?; - let registered_event = events.find::(); - for event in registered_event.flatten() { - // check if the event belongs to this user - if event.0 == account_id { - return Ok(event); - } - } - std::thread::sleep(std::time::Duration::from_millis(1000)); - } - - Err(ClientError::RegistrationTimeout) -} - -/// Check that the verfiying key from a new signature matches that in the from the -/// on-chain registration info for a given account -pub async fn check_verifying_key( - api: &OnlineClient, - rpc: &LegacyRpcMethods, - verifying_key: VerifyingKey, -) -> Result<(), ClientError> { - let verifying_key_serialized = verifying_key.to_encoded_point(true).as_bytes().to_vec(); - - // Get the verifying key associated with this account, if it exist return ok - let registered_query = - entropy::storage().registry().registered(BoundedVec(verifying_key_serialized)); - let query_registered_status = query_chain(api, rpc, registered_query, None).await; - query_registered_status?.ok_or(ClientError::NotRegistered)?; - - Ok(()) -} - /// Changes the endpoint of a validator pub async fn change_endpoint( api: &OnlineClient, diff --git a/crates/client/src/substrate.rs b/crates/client/src/substrate.rs index 519316f84..c8dfe4b41 100644 --- a/crates/client/src/substrate.rs +++ b/crates/client/src/substrate.rs @@ -119,25 +119,11 @@ pub async fn get_registered_details( ) -> Result { tracing::info!("Querying chain for registration info."); - let registered_info_query = - entropy::storage().registry().registered(BoundedVec(verifying_key.clone())); - let registered_result = query_chain(api, rpc, registered_info_query, None).await?; + let registered_info_query = entropy::storage().registry().registered(BoundedVec(verifying_key)); - let registration_info = if let Some(old_registration_info) = registered_result { - tracing::debug!("Found user in old `Registered` struct."); - - old_registration_info - } else { - // We failed with the old registration path, let's try the new one - tracing::warn!("Didn't find user in old `Registered` struct, trying new one."); - - let registered_info_query = - entropy::storage().registry().registered_on_chain(BoundedVec(verifying_key)); - - query_chain(api, rpc, registered_info_query, None) - .await? - .ok_or_else(|| SubstrateError::NotRegistered)? - }; + let registration_info = query_chain(api, rpc, registered_info_query, None) + .await? + .ok_or_else(|| SubstrateError::NotRegistered)?; Ok(registration_info) } diff --git a/crates/client/src/tests.rs b/crates/client/src/tests.rs index 68667b841..f04df75c1 100644 --- a/crates/client/src/tests.rs +++ b/crates/client/src/tests.rs @@ -147,14 +147,12 @@ async fn test_remove_program_reference_counter() { .unwrap(); // Register, using that program - let register_on_chain = true; let (verifying_key, _registered_info) = register( &api, &rpc, program_owner.clone(), AccountId32(program_owner.public().0), BoundedVec(vec![ProgramInstance { program_pointer, program_config: vec![] }]), - register_on_chain, ) .await .unwrap(); diff --git a/crates/client/src/user.rs b/crates/client/src/user.rs index 679bfc2b3..99dc1a67a 100644 --- a/crates/client/src/user.rs +++ b/crates/client/src/user.rs @@ -43,22 +43,11 @@ pub struct UserSignatureRequest { pub async fn get_signers_from_chain( api: &OnlineClient, rpc: &LegacyRpcMethods, - with_parent_key: bool, ) -> Result, SubgroupGetError> { - let mut validators = if with_parent_key { - let signer_query = entropy::storage().staking_extension().signers(); - query_chain(api, rpc, signer_query, None) - .await? - .ok_or_else(|| SubgroupGetError::ChainFetch("Get all validators error"))? - } else { - let all_validators_query = entropy::storage().session().validators(); - let mut validators = query_chain(api, rpc, all_validators_query, None) - .await? - .ok_or_else(|| SubgroupGetError::ChainFetch("Get all validators error"))?; - - validators.sort(); - validators - }; + let signer_query = entropy::storage().staking_extension().signers(); + let mut validators = query_chain(api, rpc, signer_query, None) + .await? + .ok_or_else(|| SubgroupGetError::ChainFetch("Get all validators error"))?; // TODO #898 For now we use a fix proportion of the number of validators as the threshold let threshold = (validators.len() as f32 * 0.75) as usize; diff --git a/crates/test-cli/src/lib.rs b/crates/test-cli/src/lib.rs index 78984891f..f29819fb5 100644 --- a/crates/test-cli/src/lib.rs +++ b/crates/test-cli/src/lib.rs @@ -80,9 +80,6 @@ enum CliCommand { /// If giving a mnemonic it must be enclosed in quotes, eg: "--mnemonic-option "alarm mutual concert..."" #[arg(short, long)] mnemonic_option: Option, - /// Indicates that a user wants to register using the fully on-chain registration flow. - #[arg(long)] - on_chain: bool, }, /// Ask the network to sign a given message Sign { @@ -186,7 +183,7 @@ pub async fn run_command( let rpc = get_rpc(&endpoint_addr).await?; match cli.command { - CliCommand::Register { mnemonic_option, programs, on_chain } => { + CliCommand::Register { mnemonic_option, programs } => { let mnemonic = if let Some(mnemonic_option) = mnemonic_option { mnemonic_option } else { @@ -211,7 +208,6 @@ pub async fn run_command( program_keypair.clone(), program_account, BoundedVec(programs_info), - on_chain, ) .await?; diff --git a/crates/threshold-signature-server/src/lib.rs b/crates/threshold-signature-server/src/lib.rs index 99e52da85..ea1ed07d9 100644 --- a/crates/threshold-signature-server/src/lib.rs +++ b/crates/threshold-signature-server/src/lib.rs @@ -72,14 +72,6 @@ //! //! ### For the blockchain node //! -//! #### `/user/new` - POST -//! -//! [crate::user::api::new_user()] -//! -//! Called by the off-chain worker (propagation pallet) during user registration. -//! This takes a parity scale encoded [entropy_shared::types::OcwMessageDkg] which tells us which -//! validators are in the registration group and will perform a DKG. -//! //! ### For other instances of the threshold server //! //! Takes a [UserRegistrationInfo] containing the users account ID and associated keyshare, wrapped @@ -176,7 +168,6 @@ impl AppState { pub fn app(app_state: AppState) -> Router { let mut routes = Router::new() .route("/generate_network_key", post(generate_network_key)) - .route("/user/new", post(new_user)) .route("/user/sign_tx", post(sign_tx)) .route("/signer/proactive_refresh", post(proactive_refresh)) .route("/validator/reshare", post(new_reshare)) diff --git a/crates/threshold-signature-server/src/signing_client/protocol_transport.rs b/crates/threshold-signature-server/src/signing_client/protocol_transport.rs index 635d8814d..992e777f2 100644 --- a/crates/threshold-signature-server/src/signing_client/protocol_transport.rs +++ b/crates/threshold-signature-server/src/signing_client/protocol_transport.rs @@ -170,8 +170,7 @@ async fn handle_initial_incoming_ws_message( }; { - // Check that the given public key matches the public key we got in the - // UserTransactionRequest or register transaction + // Check that the given public key is of the ones we are expecting for this protocol session let mut listeners = app_state .listener_state .listeners @@ -186,8 +185,7 @@ async fn handle_initial_incoming_ws_message( // Make the signing process fail, since one of the commitee has misbehaved listeners.remove(&msg.session_id); return Err(SubscribeErr::Decryption( - "Public key does not match that given in UserTransactionRequest or register \ - transaction" + "Public key does not match any of those expected for this protocol session" .to_string(), )); } diff --git a/crates/threshold-signature-server/src/user/api.rs b/crates/threshold-signature-server/src/user/api.rs index b410205f1..199259c55 100644 --- a/crates/threshold-signature-server/src/user/api.rs +++ b/crates/threshold-signature-server/src/user/api.rs @@ -61,10 +61,7 @@ use zeroize::Zeroize; use super::{ParsedUserInputPartyInfo, ProgramError, UserErr, UserInputPartyInfo}; use crate::{ - chain_api::{ - entropy::{self, runtime_types::pallet_registry::pallet::RegisteringDetails}, - get_api, get_rpc, EntropyConfig, - }, + chain_api::{entropy, get_api, get_rpc, EntropyConfig}, helpers::{ launch::LATEST_BLOCK_NUMBER_NEW_USER, signing::{do_signing, Hasher}, @@ -83,12 +80,6 @@ use crate::{ pub use entropy_client::user::{get_signers_from_chain, UserSignatureRequest}; pub const REQUEST_KEY_HEADER: &str = "REQUESTS"; -/// Used to differentiate different flows which perform distributed key generation. -enum DkgFlow { - Jumpstart, - Registration, -} - /// Type for validators to send user key's back and forth #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] #[derive(Debug, Clone, PartialEq)] @@ -197,8 +188,7 @@ pub async fn sign_tx( )?; } - let with_parent_key = user_details.derivation_path.is_some(); - let signers = get_signers_from_chain(&api, &rpc, with_parent_key).await?; + let signers = get_signers_from_chain(&api, &rpc).await?; // Use the validator info from chain as we can be sure it is in the correct order and the // details are correct @@ -220,12 +210,6 @@ pub async fn sign_tx( request_author, }; - // In the new registration flow we don't store the verifying key in the KVDB, so we only do this - // check if we're using the old registration flow - if user_details.derivation_path.is_none() { - let _has_key = check_for_key(&string_verifying_key, &app_state.kv_store).await?; - } - let derivation_path = if let Some(path) = user_details.derivation_path { let decoded_path = String::decode(&mut path.as_ref())?; let path = bip32::DerivationPath::from_str(&decoded_path)?; @@ -281,38 +265,10 @@ pub async fn generate_network_key( let data = OcwMessageDkg::decode(&mut encoded_data.as_ref())?; tracing::Span::current().record("block_number", data.block_number); - distributed_key_generation(app_state, data, DkgFlow::Jumpstart).await -} - -/// HTTP POST endpoint called by the off-chain worker (Propagation pallet) during user registration. -/// -/// The HTTP request takes a Parity SCALE encoded [OcwMessageDkg] which indicates which validators -/// are in the validator group. -/// -/// This will trigger the Distributed Key Generation (DKG) process. -#[tracing::instrument(skip_all, fields(block_number))] -pub async fn new_user( - State(app_state): State, - encoded_data: Bytes, -) -> Result { - let data = OcwMessageDkg::decode(&mut encoded_data.as_ref())?; - tracing::Span::current().record("block_number", data.block_number); - - distributed_key_generation(app_state, data, DkgFlow::Registration).await -} - -/// An internal helper which kicks off the distributed key generation (DKG) process. -/// -/// Since the jumpstart and registration flows are both doing DKG at the moment, we've split this -/// out. In the future though, only the jumpstart flow will require this. -async fn distributed_key_generation( - app_state: AppState, - data: OcwMessageDkg, - flow: DkgFlow, -) -> Result { if data.sig_request_accounts.is_empty() { return Ok(StatusCode::NO_CONTENT); } + let api = get_api(&app_state.configuration.endpoint).await?; let rpc = get_rpc(&app_state.configuration.endpoint).await?; let (signer, x25519_secret_key) = get_signer_and_x25519_secret(&app_state.kv_store).await?; @@ -330,7 +286,7 @@ async fn distributed_key_generation( return Ok(StatusCode::MISDIRECTED_REQUEST); } - validate_new_user(&data, &api, &rpc, &app_state.kv_store, flow).await?; + validate_jump_start(&data, &api, &rpc, &app_state.kv_store).await?; // Do the DKG protocol in another task, so we can already respond tokio::spawn(async move { @@ -346,7 +302,7 @@ async fn distributed_key_generation( /// Setup and execute DKG. /// -/// Called internally by the [new_user] function. +/// Called internally by the [generate_network_key] function. #[tracing::instrument( skip_all, fields(data), @@ -407,36 +363,6 @@ async fn setup_dkg( Ok(()) } -/// Returns details of a given registering user including key key visibility and X25519 public key. -#[tracing::instrument( - skip_all, - fields(who), - level = tracing::Level::DEBUG -)] -pub async fn get_registering_user_details( - api: &OnlineClient, - who: &::AccountId, - rpc: &LegacyRpcMethods, -) -> Result { - let registering_info_query = entropy::storage().registry().registering(who); - let register_info = query_chain(api, rpc, registering_info_query, None) - .await? - .ok_or_else(|| UserErr::ChainFetch("Register Onchain first"))?; - Ok(register_info) -} - -/// Returns `true` if the given account is in a "registering" state. -pub async fn is_registering( - api: &OnlineClient, - rpc: &LegacyRpcMethods, - who: &::AccountId, -) -> Result { - let registering_info_query = entropy::storage().registry().registering(who); - let register_info = query_chain(api, rpc, registering_info_query, None).await?; - - Ok(register_info.is_some()) -} - /// Confirms that the network wide distributed key generation process has taken place. pub async fn confirm_jump_start( api: &OnlineClient, @@ -463,14 +389,14 @@ pub async fn confirm_jump_start( Ok(()) } -/// Validates new user endpoint +/// Validates network jump start endpoint. +/// /// Checks the chain for validity of data and block number of data matches current block -async fn validate_new_user( +async fn validate_jump_start( chain_data: &OcwMessageDkg, api: &OnlineClient, rpc: &LegacyRpcMethods, kv_manager: &KvManager, - flow: DkgFlow, ) -> Result<(), UserErr> { let last_block_number_recorded = kv_manager.kv().get(LATEST_BLOCK_NUMBER_NEW_USER).await?; if u32::from_be_bytes( @@ -498,10 +424,7 @@ async fn validate_new_user( let chain_data_hash = hasher_chain_data.finalize(); let mut hasher_verifying_data = Blake2s256::new(); - let verifying_data_query = match flow { - DkgFlow::Jumpstart => entropy::storage().registry().jumpstart_dkg(chain_data.block_number), - DkgFlow::Registration => entropy::storage().registry().dkg(chain_data.block_number), - }; + let verifying_data_query = entropy::storage().registry().jumpstart_dkg(chain_data.block_number); let verifying_data = query_chain(api, rpc, verifying_data_query, None).await?; hasher_verifying_data.update(verifying_data.encode()); @@ -510,9 +433,11 @@ async fn validate_new_user( if verifying_data_hash != chain_data_hash { return Err(UserErr::InvalidData); } + kv_manager.kv().delete(LATEST_BLOCK_NUMBER_NEW_USER).await?; let reservation = kv_manager.kv().reserve_key(LATEST_BLOCK_NUMBER_NEW_USER.to_string()).await?; kv_manager.kv().put(reservation, chain_data.block_number.to_be_bytes().to_vec()).await?; + Ok(()) } diff --git a/crates/threshold-signature-server/src/user/tests.rs b/crates/threshold-signature-server/src/user/tests.rs index b44720db9..59d41f3d8 100644 --- a/crates/threshold-signature-server/src/user/tests.rs +++ b/crates/threshold-signature-server/src/user/tests.rs @@ -19,7 +19,8 @@ use bip39::{Language, Mnemonic}; use blake3::hash; use entropy_client::substrate::get_registered_details; use entropy_client::{ - client::{sign, store_program, update_programs}, + client as test_client, + client::{sign, update_programs}, user::get_signers_from_chain, }; use entropy_kvdb::{ @@ -126,7 +127,6 @@ use crate::{ user::compute_hash, validator::get_signer_and_x25519_secret_from_mnemonic, }, - new_user, r#unsafe::api::UnsafeQuery, signing_client::ListenerState, user::{ @@ -159,24 +159,34 @@ async fn test_get_signer_does_not_throw_err() { clean_tests(); } -#[ignore] #[tokio::test] #[serial] -async fn test_sign_tx_no_chain() { +async fn test_signature_requests_fail_on_different_conditions() { initialize_test_logger().await; clean_tests(); - let one = AccountKeyring::Dave; + let one = AccountKeyring::One; let two = AccountKeyring::Two; - 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(); - let program_hash = store_program( + let add_parent_key_to_kvdb = true; + let (_validator_ips, _validator_ids) = spawn_testing_validators(add_parent_key_to_kvdb).await; + + // Here we need to use `--chain=integration-tests` and force authoring otherwise we won't be + // able to get our chain in the right state to be jump started. + let force_authoring = true; + let substrate_context = test_node_process_testing_state(force_authoring).await; + let entropy_api = get_api(&substrate_context.ws_url).await.unwrap(); + let rpc = get_rpc(&substrate_context.ws_url).await.unwrap(); + + // We first need to jump start the network and grab the resulting network wide verifying key + // for later + jump_start_network(&entropy_api, &rpc).await; + + // We need to store a program in order to be able to register succesfully + let program_hash = test_client::store_program( &entropy_api, &rpc, - &two.pair(), + &two.pair(), // This is our program deployer TEST_PROGRAM_WASM_BYTECODE.to_owned(), vec![], vec![], @@ -185,76 +195,40 @@ async fn test_sign_tx_no_chain() { .await .unwrap(); - let message_hash = Hasher::keccak(PREIMAGE_SHOULD_SUCCEED); - let signature_request_account = subxtAccountId32(one.pair().public().0); - let session_id = SessionId::Sign(SigningSessionInfo { - signature_verifying_key: DAVE_VERIFYING_KEY.to_vec(), - message_hash, - request_author: signature_request_account.clone(), - }); - - let with_parent_key = false; - let (validators_info, mut generic_msg, validator_ips_and_keys) = - get_sign_tx_data(&entropy_api, &rpc, hex::encode(PREIMAGE_SHOULD_SUCCEED), with_parent_key) - .await; - - generic_msg.block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number; - // test points to no program - let test_no_program = - submit_transaction_requests(validator_ips_and_keys.clone(), generic_msg.clone(), one).await; - - for res in test_no_program { - assert_eq!(res.unwrap().text().await.unwrap(), "No program pointer defined for account"); - } - update_programs( + let (verifying_key, _registered_info) = test_client::register( &entropy_api, &rpc, - DAVE_VERIFYING_KEY, - &one.pair(), - OtherBoundedVec(vec![ - OtherProgramInstance { program_pointer: program_hash, program_config: vec![] }, - OtherProgramInstance { program_pointer: program_hash, program_config: vec![] }, - ]), + one.clone().into(), // This is our program modification account + subxtAccountId32(two.public().0), // This is our signature request account + BoundedVec(vec![ProgramInstance { program_pointer: program_hash, program_config: vec![] }]), ) .await .unwrap(); - generic_msg.block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number; - let test_user_res = - submit_transaction_requests(validator_ips_and_keys.clone(), generic_msg.clone(), one).await; - - let verifying_key = decode_verifying_key(&DAVE_VERIFYING_KEY).unwrap(); - verify_signature(test_user_res, message_hash, &verifying_key, &validators_info).await; - let mock_client = reqwest::Client::new(); - // check request limiter increases - let unsafe_get = - UnsafeQuery::new(request_limit_key(hex::encode(DAVE_VERIFYING_KEY.to_vec())), vec![]) - .to_json(); + // Test: We check that an account with a program succeeds in submiting a signature request + let (validators_info, mut signature_request, validator_ips_and_keys) = + get_sign_tx_data(&entropy_api, &rpc, hex::encode(PREIMAGE_SHOULD_SUCCEED)).await; - let get_response = mock_client - .post(format!("http://{}/unsafe/get", validators_info[0].ip_address)) - .header("Content-Type", "application/json") - .body(unsafe_get.clone()) - .send() - .await - .unwrap(); - let serialized_request_amount = get_response.text().await.unwrap(); + // The account we registered does have a program pointer, so this should succeed + signature_request.block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number; + signature_request.signature_verifying_key = verifying_key.to_vec(); - let request_info: RequestLimitStorage = - RequestLimitStorage::decode(&mut serialized_request_amount.as_ref()).unwrap(); - assert_eq!(request_info.request_amount, 1); + let test_user_res = + submit_transaction_requests(validator_ips_and_keys.clone(), signature_request.clone(), one) + .await; - generic_msg.block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number; - generic_msg.validators_info = generic_msg.validators_info.into_iter().rev().collect::>(); - let test_user_res_order = - submit_transaction_requests(validator_ips_and_keys.clone(), generic_msg.clone(), one).await; + let message_hash = Hasher::keccak(PREIMAGE_SHOULD_SUCCEED); + let decoded_verifying_key = + decode_verifying_key(verifying_key.as_slice().try_into().unwrap()).unwrap(); + verify_signature(test_user_res, message_hash, &decoded_verifying_key, &validators_info).await; - verify_signature(test_user_res_order, message_hash, &verifying_key, &validators_info).await; + // Test: A user that is not registered is not able to send a signature request - generic_msg.block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number; - generic_msg.signature_verifying_key = DEFAULT_VERIFYING_KEY_NOT_REGISTERED.to_vec(); + signature_request.block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number; + signature_request.signature_verifying_key = DEFAULT_VERIFYING_KEY_NOT_REGISTERED.to_vec(); let test_user_res_not_registered = - submit_transaction_requests(validator_ips_and_keys.clone(), generic_msg.clone(), two).await; + submit_transaction_requests(validator_ips_and_keys.clone(), signature_request.clone(), two) + .await; for res in test_user_res_not_registered { assert_eq!( @@ -263,66 +237,16 @@ async fn test_sign_tx_no_chain() { ); } - // Test attempting to connect over ws by someone who is not in the signing group - let validator_ip_and_key = validator_ips_and_keys[0].clone(); - let connection_attempt_handle = tokio::spawn(async move { - // Wait for the "user" to submit the signing request - tokio::time::sleep(Duration::from_millis(500)).await; - let ws_endpoint = format!("ws://{}/ws", validator_ip_and_key.0); - let (ws_stream, _response) = connect_async(ws_endpoint).await.unwrap(); - - let ferdie_pair = AccountKeyring::Ferdie.pair(); - - // create a SubscribeMessage from a party who is not in the signing commitee - let subscribe_message_vec = - bincode::serialize(&SubscribeMessage::new(session_id, &ferdie_pair).unwrap()).unwrap(); - - // Attempt a noise handshake including the subscribe message in the payload - let mut encrypted_connection = noise_handshake_initiator( - ws_stream, - &FERDIE_X25519_SECRET_KEY.into(), - validator_ip_and_key.1, - subscribe_message_vec, - ) - .await - .unwrap(); - - // Check the response as to whether they accepted our SubscribeMessage - let response_message = encrypted_connection.recv().await.unwrap(); - let subscribe_response: Result<(), String> = - bincode::deserialize(&response_message).unwrap(); - - assert_eq!(Err("NoListener(\"no listener\")".to_string()), subscribe_response); - // The stream should not continue to send messages - // returns true if this part of the test passes - encrypted_connection.recv().await.is_err() - }); - - generic_msg.block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number; - generic_msg.signature_verifying_key = DAVE_VERIFYING_KEY.to_vec().to_vec(); - let test_user_bad_connection_res = submit_transaction_requests( - vec![validator_ips_and_keys[1].clone()], - generic_msg.clone(), - one, - ) - .await; - - for res in test_user_bad_connection_res { - assert_eq!( - res.unwrap().text().await.unwrap(), - "{\"Err\":\"Timed out waiting for remote party\"}" - ); - } - - assert!(connection_attempt_handle.await.unwrap()); + // Test: Signature requests fail if no auxiliary data is set - // Now, test a signature request that should fail // The test program is written to fail when `auxilary_data` is `None` - generic_msg.auxilary_data = None; - generic_msg.block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number; + signature_request.block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number; + signature_request.signature_verifying_key = verifying_key.to_vec(); + signature_request.auxilary_data = None; let test_user_failed_programs_res = - submit_transaction_requests(validator_ips_and_keys.clone(), generic_msg.clone(), one).await; + submit_transaction_requests(validator_ips_and_keys.clone(), signature_request.clone(), one) + .await; for res in test_user_failed_programs_res { assert_eq!( @@ -331,37 +255,63 @@ async fn test_sign_tx_no_chain() { ); } - // The test program is written to fail when `auxilary_data` is `None` but only on the second program - generic_msg.auxilary_data = Some(vec![Some(hex::encode(AUXILARY_DATA_SHOULD_SUCCEED))]); - generic_msg.block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number; + // The test program is written to fail when `auxilary_data` is `None` but only on the second + // program + update_programs( + &entropy_api, + &rpc, + verifying_key.as_slice().try_into().unwrap(), + &two.pair(), + OtherBoundedVec(vec![ + OtherProgramInstance { program_pointer: program_hash, program_config: vec![] }, + OtherProgramInstance { program_pointer: program_hash, program_config: vec![] }, + ]), + ) + .await + .unwrap(); + + signature_request.block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number; + signature_request.signature_verifying_key = verifying_key.to_vec(); + signature_request.auxilary_data = Some(vec![Some(hex::encode(AUXILARY_DATA_SHOULD_SUCCEED))]); let test_user_failed_aux_data = - submit_transaction_requests(validator_ips_and_keys.clone(), generic_msg.clone(), one).await; + submit_transaction_requests(validator_ips_and_keys.clone(), signature_request.clone(), one) + .await; for res in test_user_failed_aux_data { assert_eq!(res.unwrap().text().await.unwrap(), "Auxilary data is mismatched"); } - generic_msg.block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number; - generic_msg.hash = HashingAlgorithm::Custom(3); + // Test: Signature requests fails if a user provides an invalid hashing algorithm option + + signature_request.block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number; + signature_request.signature_verifying_key = verifying_key.to_vec(); + signature_request.hash = HashingAlgorithm::Custom(3); + let test_user_custom_hash_out_of_bounds = - submit_transaction_requests(validator_ips_and_keys.clone(), generic_msg.clone(), two).await; + submit_transaction_requests(validator_ips_and_keys.clone(), signature_request.clone(), two) + .await; for res in test_user_custom_hash_out_of_bounds { assert_eq!(res.unwrap().text().await.unwrap(), "Custom hash choice out of bounds"); } - generic_msg.block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number; - generic_msg.signature_verifying_key = NETWORK_PARENT_KEY.as_bytes().to_vec(); + // Test: Signature requests fails if a the network parent key is used + + signature_request.block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number; + signature_request.signature_verifying_key = NETWORK_PARENT_KEY.as_bytes().to_vec(); + let test_user_sign_with_parent_key = submit_transaction_requests( vec![validator_ips_and_keys[1].clone()], - generic_msg.clone(), + signature_request.clone(), one, ) .await; + for res in test_user_sign_with_parent_key { assert_eq!(res.unwrap().text().await.unwrap(), "No signing from parent key"); } + clean_tests(); } @@ -389,14 +339,8 @@ async fn signature_request_with_derived_account_works() { // for later jump_start_network(&entropy_api, &rpc).await; - let jump_start_progress_query = entropy::storage().staking_extension().jump_start_progress(); - let jump_start_progress = - query_chain(&entropy_api, &rpc, jump_start_progress_query, None).await.unwrap().unwrap(); - - let network_verifying_key = jump_start_progress.verifying_key.unwrap().0; - // We need to store a program in order to be able to register succesfully - let program_hash = store_program( + let program_hash = test_client::store_program( &entropy_api, &rpc, &bob.pair(), // This is our program deployer @@ -408,67 +352,21 @@ async fn signature_request_with_derived_account_works() { .await .unwrap(); - let registration_request = put_new_register_request_on_chain( + let (verifying_key, _registered_info) = test_client::register( &entropy_api, &rpc, - &alice, // This is our signature request account - charlie.to_account_id().into(), // This is our program modification account + charlie.clone().into(), // This is our program modification account + subxtAccountId32(alice.public().0), // This is our signature request account BoundedVec(vec![ProgramInstance { program_pointer: program_hash, program_config: vec![] }]), ) - .await; - - assert!( - matches!(registration_request, Ok(_)), - "We expect our registration request to succeed." - ); - - let entropy::registry::events::AccountRegistered( - _actual_signature_request_account, - actual_verifying_key, - ) = registration_request.unwrap(); - - // This is slightly more convenient to work with later one - let actual_verifying_key = actual_verifying_key.0; - - // Next we want to check that the info that's on-chain is what we actually expect - let registered_info = - get_registered_details(&entropy_api, &rpc, actual_verifying_key.to_vec()).await; - - assert!( - matches!(registered_info, Ok(_)), - "We expect that the verifying key we got back matches registration entry in storage." - ); - - assert_eq!( - registered_info.unwrap().program_modification_account, - charlie.to_account_id().into() - ); - - // Next, let's check that the child verifying key matches - let network_verifying_key = - SynedrionVerifyingKey::try_from(network_verifying_key.as_slice()).unwrap(); - - // We hardcode the derivation path here since we know that there's only been one registration - // request (ours). - let derivation_path = "m/0/0".parse().unwrap(); - let expected_verifying_key = - network_verifying_key.derive_verifying_key_bip32(&derivation_path).unwrap(); - let expected_verifying_key = expected_verifying_key.to_encoded_point(true).as_bytes().to_vec(); - - assert_eq!( - expected_verifying_key, actual_verifying_key, - "The derived child key doesn't match our registered verifying key." - ); - - // Now that we've set up and registered a user, we can proceed with testing the signing flow + .await + .unwrap(); - let with_parent_key = true; let (validators_info, mut signature_request, validator_ips_and_keys) = - get_sign_tx_data(&entropy_api, &rpc, hex::encode(PREIMAGE_SHOULD_SUCCEED), with_parent_key) - .await; + get_sign_tx_data(&entropy_api, &rpc, hex::encode(PREIMAGE_SHOULD_SUCCEED)).await; // We'll use the actual verifying key we registered for the signature request - signature_request.signature_verifying_key = actual_verifying_key.to_vec(); + signature_request.signature_verifying_key = verifying_key.to_vec(); signature_request.block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number; let signature_request_responses = submit_transaction_requests( @@ -489,31 +387,35 @@ async fn signature_request_with_derived_account_works() { clean_tests(); } -#[ignore] #[tokio::test] #[serial] -async fn test_sign_tx_no_chain_fail() { +async fn test_signing_fails_if_wrong_participants_are_used() { initialize_test_logger().await; clean_tests(); let one = AccountKeyring::Dave; - 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(); + let add_parent_key = true; + let (_validator_ips, _validator_ids) = spawn_testing_validators(add_parent_key).await; + + let force_authoring = true; + let substrate_context = test_node_process_testing_state(force_authoring).await; + + let entropy_api = get_api(&substrate_context.ws_url).await.unwrap(); + let rpc = get_rpc(&substrate_context.ws_url).await.unwrap(); + + jump_start_network(&entropy_api, &rpc).await; + let mock_client = reqwest::Client::new(); - let with_parent_key = false; - let (validators_info, mut generic_msg, validator_ips_and_keys) = - get_sign_tx_data(&entropy_api, &rpc, hex::encode(PREIMAGE_SHOULD_SUCCEED), with_parent_key) - .await; + let (_validators_info, signature_request, _validator_ips_and_keys) = + get_sign_tx_data(&entropy_api, &rpc, hex::encode(PREIMAGE_SHOULD_SUCCEED)).await; // fails verification tests // wrong key for wrong validator let failed_signed_message = EncryptedSignedMessage::new( &one.pair(), - serde_json::to_vec(&generic_msg.clone()).unwrap(), + serde_json::to_vec(&signature_request.clone()).unwrap(), &X25519_PUBLIC_KEYS[1], &[], ) @@ -534,7 +436,7 @@ async fn test_sign_tx_no_chain_fail() { let sig: [u8; 64] = [0; 64]; let user_input_bad = EncryptedSignedMessage::new_with_given_signature( &one.pair(), - serde_json::to_vec(&generic_msg.clone()).unwrap(), + serde_json::to_vec(&signature_request.clone()).unwrap(), &X25519_PUBLIC_KEYS[0], &[], sr25519::Signature::from_raw(sig), @@ -555,14 +457,33 @@ async fn test_sign_tx_no_chain_fail() { "Encryption or signing error: Cannot verify signature" ); - let request_limit_query = entropy::storage().parameters().request_limit(); - let request_limit = - query_chain(&entropy_api, &rpc, request_limit_query, None).await.unwrap().unwrap(); + clean_tests(); +} + +#[tokio::test] +#[serial] +async fn test_request_limit_are_updated_during_signing() { + initialize_test_logger().await; + clean_tests(); + + let one = AccountKeyring::One; + let two = AccountKeyring::Two; - let program_hash = store_program( + let add_parent_key = true; + let (_validator_ips, _validator_ids) = spawn_testing_validators(add_parent_key).await; + + let force_authoring = true; + let substrate_context = test_node_process_testing_state(force_authoring).await; + + let entropy_api = get_api(&substrate_context.ws_url).await.unwrap(); + let rpc = get_rpc(&substrate_context.ws_url).await.unwrap(); + + jump_start_network(&entropy_api, &rpc).await; + + let program_hash = test_client::store_program( &entropy_api, &rpc, - &one.pair(), + &two.pair(), // This is our program deployer TEST_PROGRAM_WASM_BYTECODE.to_owned(), vec![], vec![], @@ -570,26 +491,68 @@ async fn test_sign_tx_no_chain_fail() { ) .await .unwrap(); - update_programs( + + let (verifying_key, _registered_info) = test_client::register( &entropy_api, &rpc, - DAVE_VERIFYING_KEY, - &one.pair(), - OtherBoundedVec(vec![ - OtherProgramInstance { program_pointer: program_hash, program_config: vec![] }, - OtherProgramInstance { program_pointer: program_hash, program_config: vec![] }, - ]), + one.clone().into(), // This is our program modification account + subxtAccountId32(two.public().0), // This is our signature request account + BoundedVec(vec![ProgramInstance { program_pointer: program_hash, program_config: vec![] }]), ) .await .unwrap(); - // test request limit reached - // gets current blocknumber, potential race condition run to block + 1 + // Test: We check that the rate limiter changes as expected when signature requests are sent + + // First we need to get a signature request to populate the KVDB for our verifying key + let (validators_info, mut signature_request, validator_ips_and_keys) = + get_sign_tx_data(&entropy_api, &rpc, hex::encode(PREIMAGE_SHOULD_SUCCEED)).await; + + signature_request.block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number; + signature_request.signature_verifying_key = verifying_key.to_vec(); + + let test_user_res = + submit_transaction_requests(validator_ips_and_keys.clone(), signature_request.clone(), one) + .await; + + let message_hash = Hasher::keccak(PREIMAGE_SHOULD_SUCCEED); + let decoded_verifying_key = + decode_verifying_key(verifying_key.as_slice().try_into().unwrap()).unwrap(); + verify_signature(test_user_res, message_hash, &decoded_verifying_key, &validators_info).await; + + // Next we check request limiter increases + let mock_client = reqwest::Client::new(); + + let unsafe_get = + UnsafeQuery::new(request_limit_key(hex::encode(verifying_key.clone().to_vec())), vec![]) + .to_json(); + + let get_response = mock_client + .post(format!("http://{}/unsafe/get", validators_info[0].ip_address)) + .header("Content-Type", "application/json") + .body(unsafe_get.clone()) + .send() + .await + .unwrap(); + let serialized_request_amount = get_response.text().await.unwrap(); + + let request_info: RequestLimitStorage = + RequestLimitStorage::decode(&mut serialized_request_amount.as_ref()).unwrap(); + assert_eq!(request_info.request_amount, 1); + + // Test: If we send too many requests though, we'll be blocked from signing + + let request_limit_query = entropy::storage().parameters().request_limit(); + let request_limit = + query_chain(&entropy_api, &rpc, request_limit_query, None).await.unwrap().unwrap(); + + // Gets current block number, potential race condition run to block + 1 // to reset block and give us 6 seconds to hit rate limit let block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number; run_to_block(&rpc, block_number + 1).await; + let unsafe_put = UnsafeQuery::new( - request_limit_key(hex::encode(DAVE_VERIFYING_KEY.to_vec())), + request_limit_key(hex::encode(verifying_key.to_vec())), RequestLimitStorage { request_amount: request_limit + 1, block_number: block_number + 1 } .encode(), ) @@ -605,36 +568,45 @@ async fn test_sign_tx_no_chain_fail() { .unwrap(); } - generic_msg.block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number; + signature_request.block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number; + signature_request.signature_verifying_key = verifying_key.to_vec(); + let test_user_failed_request_limit = - submit_transaction_requests(validator_ips_and_keys.clone(), generic_msg.clone(), one).await; + submit_transaction_requests(validator_ips_and_keys.clone(), signature_request.clone(), one) + .await; for res in test_user_failed_request_limit { assert_eq!(res.unwrap().text().await.unwrap(), "Too many requests - wait a block"); } + clean_tests(); } -#[ignore] #[tokio::test] #[serial] -async fn test_program_with_config() { +async fn test_fails_to_sign_if_non_signing_group_participants_are_used() { initialize_test_logger().await; clean_tests(); - let one = AccountKeyring::Dave; + let one = AccountKeyring::One; let two = AccountKeyring::Two; - 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(); + let add_parent_key = true; + let (_validator_ips, _validator_ids) = spawn_testing_validators(add_parent_key).await; + + let force_authoring = true; + let substrate_context = test_node_process_testing_state(force_authoring).await; + + let entropy_api = get_api(&substrate_context.ws_url).await.unwrap(); + let rpc = get_rpc(&substrate_context.ws_url).await.unwrap(); - let program_hash = store_program( + jump_start_network(&entropy_api, &rpc).await; + + let program_hash = test_client::store_program( &entropy_api, &rpc, - &two.pair(), - TEST_BASIC_TRANSACTION.to_owned(), + &two.pair(), // This is our program deployer + TEST_PROGRAM_WASM_BYTECODE.to_owned(), vec![], vec![], vec![], @@ -642,69 +614,110 @@ async fn test_program_with_config() { .await .unwrap(); - // this message is an ethereum tx rlp encoded with a proper allow listed address - let message = "0xef01808094772b9a9e8aa1c9db861c6611a82d251db4fac990019243726561746564204f6e20456e74726f7079018080"; - - let message_hash = Hasher::keccak(message.as_bytes()); - - let with_parent_key = false; - let (validators_info, mut generic_msg, validator_ips_and_keys) = - get_sign_tx_data(&entropy_api, &rpc, hex::encode(message), with_parent_key).await; - - let config = r#" - { - "allowlisted_addresses": [ - "772b9a9e8aa1c9db861c6611a82d251db4fac990" - ] - } - "# - .as_bytes(); - - update_programs( + let (verifying_key, _registered_info) = test_client::register( &entropy_api, &rpc, - DAVE_VERIFYING_KEY, - &one.pair(), - OtherBoundedVec(vec![ - OtherProgramInstance { program_pointer: program_hash, program_config: config.to_vec() }, - OtherProgramInstance { program_pointer: program_hash, program_config: config.to_vec() }, - ]), + one.clone().into(), // This is our program modification account + subxtAccountId32(two.public().0), // This is our signature request account + BoundedVec(vec![ProgramInstance { program_pointer: program_hash, program_config: vec![] }]), ) .await .unwrap(); - generic_msg.block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number; - let test_user_res = - submit_transaction_requests(validator_ips_and_keys.clone(), generic_msg.clone(), one).await; + let (_validators_info, mut signature_request, validator_ips_and_keys) = + get_sign_tx_data(&entropy_api, &rpc, hex::encode(PREIMAGE_SHOULD_SUCCEED)).await; + + let message_hash = Hasher::keccak(PREIMAGE_SHOULD_SUCCEED); + let signature_request_account = subxtAccountId32(one.pair().public().0); + let session_id = SessionId::Sign(SigningSessionInfo { + signature_verifying_key: verifying_key.to_vec(), + message_hash, + request_author: signature_request_account.clone(), + }); + + // Test attempting to connect over ws by someone who is not in the signing group + let validator_ip_and_key = validator_ips_and_keys[0].clone(); + let connection_attempt_handle = tokio::spawn(async move { + // Wait for the "user" to submit the signing request + tokio::time::sleep(Duration::from_millis(500)).await; + let ws_endpoint = format!("ws://{}/ws", validator_ip_and_key.0); + let (ws_stream, _response) = connect_async(ws_endpoint).await.unwrap(); + + let ferdie_pair = AccountKeyring::Ferdie.pair(); + + // create a SubscribeMessage from a party who is not in the signing commitee + let subscribe_message_vec = + bincode::serialize(&SubscribeMessage::new(session_id, &ferdie_pair).unwrap()).unwrap(); + + // Attempt a noise handshake including the subscribe message in the payload + let mut encrypted_connection = noise_handshake_initiator( + ws_stream, + &FERDIE_X25519_SECRET_KEY.into(), + validator_ip_and_key.1, + subscribe_message_vec, + ) + .await + .unwrap(); + + // Check the response as to whether they accepted our SubscribeMessage + let response_message = encrypted_connection.recv().await.unwrap(); + let subscribe_response: Result<(), String> = + bincode::deserialize(&response_message).unwrap(); + + assert_eq!(Err("Decryption(\"Public key does not match any of those expected for this protocol session\")".to_string()), subscribe_response); + + // The stream should not continue to send messages + // returns true if this part of the test passes + encrypted_connection.recv().await.is_err() + }); + + signature_request.block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number; + signature_request.signature_verifying_key = verifying_key.to_vec(); + + let test_user_bad_connection_res = submit_transaction_requests( + vec![validator_ips_and_keys[0].clone()], + signature_request.clone(), + one, + ) + .await; + + for res in test_user_bad_connection_res { + assert_eq!( + res.unwrap().text().await.unwrap(), + "{\"Err\":\"Oneshot timeout error: channel closed\"}" + ); + } + + assert!(connection_attempt_handle.await.unwrap()); - let verifying_key = decode_verifying_key(&DAVE_VERIFYING_KEY).unwrap(); - verify_signature(test_user_res, message_hash, &verifying_key, &validators_info).await; clean_tests(); } -#[ignore] #[tokio::test] #[serial] -async fn test_store_share() { +async fn test_program_with_config() { initialize_test_logger().await; clean_tests(); - let alice = AccountKeyring::Alice; - let alice_program = AccountKeyring::Charlie; - let program_manager = AccountKeyring::Dave; + let one = AccountKeyring::One; + let two = AccountKeyring::Two; - let cxt = test_context_stationary().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(); + let add_parent_key = true; + let (_validator_ips, _validator_ids) = spawn_testing_validators(add_parent_key).await; - let client = reqwest::Client::new(); + let force_authoring = true; + let substrate_context = test_node_process_testing_state(force_authoring).await; - let program_hash = store_program( - &api, + let entropy_api = get_api(&substrate_context.ws_url).await.unwrap(); + let rpc = get_rpc(&substrate_context.ws_url).await.unwrap(); + + jump_start_network(&entropy_api, &rpc).await; + + let program_hash = test_client::store_program( + &entropy_api, &rpc, - &program_manager.pair(), - TEST_PROGRAM_WASM_BYTECODE.to_owned(), + &two.pair(), + TEST_BASIC_TRANSACTION.to_owned(), vec![], vec![], vec![], @@ -712,146 +725,59 @@ async fn test_store_share() { .await .unwrap(); - let mut block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number + 1; - - let validators_info = vec![ - entropy_shared::ValidatorInfo { - ip_address: b"127.0.0.1:3001".to_vec(), - x25519_public_key: X25519_PUBLIC_KEYS[0], - tss_account: TSS_ACCOUNTS[0].clone().encode(), - }, - entropy_shared::ValidatorInfo { - ip_address: b"127.0.0.1:3002".to_vec(), - x25519_public_key: X25519_PUBLIC_KEYS[1], - tss_account: TSS_ACCOUNTS[1].clone().encode(), - }, - entropy_shared::ValidatorInfo { - ip_address: b"127.0.0.1:3003".to_vec(), - x25519_public_key: X25519_PUBLIC_KEYS[2], - tss_account: TSS_ACCOUNTS[2].clone().encode(), - }, - ]; - let mut onchain_user_request = OcwMessageDkg { - sig_request_accounts: vec![alice.public().encode()], - block_number, - validators_info, - }; - - put_register_request_on_chain( - &api, + let (verifying_key, _registered_info) = test_client::register( + &entropy_api, &rpc, - &alice, - alice_program.to_account_id().into(), + one.clone().into(), // This is our program modification account + subxtAccountId32(two.public().0), // This is our signature request account BoundedVec(vec![ProgramInstance { program_pointer: program_hash, program_config: vec![] }]), ) - .await; - - run_to_block(&rpc, block_number + 1).await; - - let response_results = join_all( - vec![3002, 3003] - .iter() - .map(|port| { - client - .post(format!("http://127.0.0.1:{}/user/new", port)) - .body(onchain_user_request.clone().encode()) - .send() - }) - .collect::>(), - ) - .await; - - for response_result in response_results { - assert_eq!(response_result.unwrap().text().await.unwrap(), ""); - } + .await + .unwrap(); - let mut new_verifying_key = vec![]; - // wait for registered event check that key exists in kvdb - for _ in 0..65 { - std::thread::sleep(std::time::Duration::from_millis(1000)); - let block_hash = rpc.chain_get_block_hash(None).await.unwrap(); - let events = EventsClient::new(api.clone()).at(block_hash.unwrap()).await.unwrap(); - let registered_event = events.find::(); - for event in registered_event.flatten() { - let registered_query = entropy::storage().registry().registered(&event.1); - let query_registered_status = - query_chain(&api, &rpc, registered_query, block_hash).await; - if query_registered_status.unwrap().is_some() { - if event.0 == alice.to_account_id().into() { - new_verifying_key = event.1 .0; - break; - } - } + // This message is an ethereum tx rlp encoded with a proper allow listed address + let message = "0xef01808094772b9a9e8aa1c9db861c6611a82d251db4fac990019243726561746564204f6e20456e74726f7079018080"; + let config = r#" + { + "allowlisted_addresses": [ + "772b9a9e8aa1c9db861c6611a82d251db4fac990" + ] } - } - // Check that the timeout was not reached - assert!(new_verifying_key.len() > 0); - - let response_key = unsafe_get(&client, hex::encode(&new_verifying_key), 3001).await; - // check to make sure keyshare is correct - let key_share: Option = - entropy_kvdb::kv_manager::helpers::deserialize(&response_key); - assert_eq!(key_share.is_some(), true); - - // fails repeated data - let response_repeated_data = client - .post("http://127.0.0.1:3001/user/new") - .body(onchain_user_request.clone().encode()) - .send() - .await - .unwrap(); - - assert_eq!(response_repeated_data.status(), StatusCode::INTERNAL_SERVER_ERROR); - assert_eq!(response_repeated_data.text().await.unwrap(), "Data is repeated"); - - run_to_block(&rpc, block_number + 3).await; - onchain_user_request.block_number = block_number + 1; - // fails stale data - let response_stale = client - .post("http://127.0.0.1:3001/user/new") - .body(onchain_user_request.clone().encode()) - .send() - .await - .unwrap(); - - assert_eq!(response_stale.status(), StatusCode::INTERNAL_SERVER_ERROR); - assert_eq!(response_stale.text().await.unwrap(), "Data is stale"); + "# + .as_bytes(); - block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number + 1; - put_register_request_on_chain( - &api, + // We update the program to use the new config + update_programs( + &entropy_api, &rpc, - &alice_program, - alice_program.to_account_id().into(), - BoundedVec(vec![ProgramInstance { program_pointer: program_hash, program_config: vec![] }]), + verifying_key.as_slice().try_into().unwrap(), + &two.pair(), + OtherBoundedVec(vec![ + OtherProgramInstance { program_pointer: program_hash, program_config: config.to_vec() }, + OtherProgramInstance { program_pointer: program_hash, program_config: config.to_vec() }, + ]), ) - .await; - onchain_user_request.block_number = block_number; - run_to_block(&rpc, block_number + 1).await; + .await + .unwrap(); - // fails not verified data - let response_not_verified = client - .post("http://127.0.0.1:3001/user/new") - .body(onchain_user_request.clone().encode()) - .send() - .await - .unwrap(); + // Now we'll send off a signature request using the new program + let (validators_info, mut signature_request, validator_ips_and_keys) = + get_sign_tx_data(&entropy_api, &rpc, hex::encode(message)).await; - assert_eq!(response_not_verified.status(), StatusCode::INTERNAL_SERVER_ERROR); - assert_eq!(response_not_verified.text().await.unwrap(), "Data is not verifiable"); + // We'll use the actual verifying key we registered for the signature request + signature_request.signature_verifying_key = verifying_key.to_vec(); + signature_request.block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number; - onchain_user_request.validators_info[0].tss_account = TSS_ACCOUNTS[1].clone().encode(); - // fails not in validator group data - let response_not_validator = client - .post("http://127.0.0.1:3001/user/new") - .body(onchain_user_request.clone().encode()) - .send() - .await - .unwrap(); + // Here we check that the signature request was indeed completed successfully + let signature_request_responses = + submit_transaction_requests(validator_ips_and_keys.clone(), signature_request.clone(), one) + .await; - assert_eq!(response_not_validator.status(), StatusCode::MISDIRECTED_REQUEST); + let message_hash = Hasher::keccak(message.as_bytes()); + let verifying_key = decode_verifying_key(verifying_key.as_slice().try_into().unwrap()).unwrap(); + verify_signature(signature_request_responses, message_hash, &verifying_key, &validators_info) + .await; - // TODO check if key is in other subgroup member clean_tests(); } @@ -947,23 +873,8 @@ async fn test_jumpstart_network() { clean_tests(); } -pub async fn put_register_request_on_chain( - api: &OnlineClient, - rpc: &LegacyRpcMethods, - sig_req_keyring: &Sr25519Keyring, - program_modification_account: subxtAccountId32, - program_instances: BoundedVec, -) { - let sig_req_account = - PairSigner::::new(sig_req_keyring.pair()); - - let registering_tx = - entropy::tx().registry().register(program_modification_account, program_instances); - submit_transaction(api, rpc, &sig_req_account, ®istering_tx, None).await.unwrap(); -} - /// Registers an account on-chain using the new registration flow. -pub async fn put_new_register_request_on_chain( +pub async fn put_register_request_on_chain( api: &OnlineClient, rpc: &LegacyRpcMethods, signature_request_account: &Sr25519Keyring, @@ -975,7 +886,7 @@ pub async fn put_new_register_request_on_chain( PairSigner::::new(signature_request_account.pair()); let registering_tx = - entropy::tx().registry().register_on_chain(program_modification_account, program_instances); + entropy::tx().registry().register(program_modification_account, program_instances); let events = submit_transaction(api, rpc, &signature_request_account, ®istering_tx, None).await?; @@ -1010,7 +921,7 @@ async fn test_compute_hash() { let rpc = get_rpc(&substrate_context.node_proc.ws_url).await.unwrap(); let mut runtime = Runtime::default(); - let program_hash = store_program( + let program_hash = test_client::store_program( &api, &rpc, &one.pair(), @@ -1081,23 +992,28 @@ pub async fn verify_signature( } } -#[ignore] #[tokio::test] #[serial] async fn test_fail_infinite_program() { initialize_test_logger().await; clean_tests(); - let one = AccountKeyring::Dave; + let one = AccountKeyring::One; let two = AccountKeyring::Two; - 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(); + let add_parent_key = true; + let (_validator_ips, _validator_ids) = spawn_testing_validators(add_parent_key).await; - let program_hash = store_program( - &entropy_api, + let force_authoring = true; + let substrate_context = test_node_process_testing_state(force_authoring).await; + + let api = get_api(&substrate_context.ws_url).await.unwrap(); + let rpc = get_rpc(&substrate_context.ws_url).await.unwrap(); + + jump_start_network(&api, &rpc).await; + + let program_hash = test_client::store_program( + &api, &rpc, &two.pair(), TEST_INFINITE_LOOP_BYTECODE.to_owned(), @@ -1108,64 +1024,39 @@ async fn test_fail_infinite_program() { .await .unwrap(); - update_programs( - &entropy_api, + let (verifying_key, _registered_info) = test_client::register( + &api, &rpc, - DAVE_VERIFYING_KEY, - &one.pair(), - OtherBoundedVec(vec![OtherProgramInstance { - program_pointer: program_hash, - program_config: vec![], - }]), + one.clone().into(), // This is our program modification account + subxtAccountId32(two.public().0), // This is our signature request account + BoundedVec(vec![ProgramInstance { program_pointer: program_hash, program_config: vec![] }]), ) .await .unwrap(); - let validators_info = vec![ - ValidatorInfo { - ip_address: "localhost:3001".to_string(), - x25519_public_key: X25519_PUBLIC_KEYS[0], - tss_account: TSS_ACCOUNTS[0].clone(), - }, - ValidatorInfo { - ip_address: "127.0.0.1:3002".to_string(), - x25519_public_key: X25519_PUBLIC_KEYS[1], - tss_account: TSS_ACCOUNTS[1].clone(), - }, - ]; - - let mut generic_msg = UserSignatureRequest { - message: hex::encode(PREIMAGE_SHOULD_SUCCEED), - auxilary_data: Some(vec![ - Some(hex::encode(AUXILARY_DATA_SHOULD_SUCCEED)), - Some(hex::encode(AUXILARY_DATA_SHOULD_SUCCEED)), - ]), - validators_info, - block_number: rpc.chain_get_header(None).await.unwrap().unwrap().number, - hash: HashingAlgorithm::Keccak, - signature_verifying_key: DAVE_VERIFYING_KEY.to_vec(), - }; - - let validator_ips_and_keys = vec![ - (validator_ips[0].clone(), X25519_PUBLIC_KEYS[0]), - (validator_ips[1].clone(), X25519_PUBLIC_KEYS[1]), - ]; + // Now we'll send off a signature request using the new program + let (_validators_info, mut signature_request, validator_ips_and_keys) = + get_sign_tx_data(&api, &rpc, hex::encode(PREIMAGE_SHOULD_SUCCEED)).await; - generic_msg.block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number; + // We'll use the actual verifying key we registered for the signature request + signature_request.signature_verifying_key = verifying_key.to_vec(); + signature_request.block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number; let test_infinite_loop = - submit_transaction_requests(validator_ips_and_keys.clone(), generic_msg.clone(), one).await; + submit_transaction_requests(validator_ips_and_keys.clone(), signature_request.clone(), one) + .await; + for res in test_infinite_loop { assert_eq!(res.unwrap().text().await.unwrap(), "Runtime error: OutOfFuel"); } } -#[ignore] #[tokio::test] #[serial] async fn test_device_key_proxy() { initialize_test_logger().await; clean_tests(); + /// JSON-deserializable struct that will be used to derive the program-JSON interface. /// Note how this uses JSON-native types only. #[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize, JsonSchema)] @@ -1175,6 +1066,7 @@ async fn test_device_key_proxy() { pub sr25519_public_keys: Option>, pub ed25519_public_keys: Option>, } + /// JSON representation of the auxiliary data #[cfg_attr(feature = "std", derive(schemars::JsonSchema))] #[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] @@ -1189,12 +1081,46 @@ async fn test_device_key_proxy() { pub context: String, } - let one = AccountKeyring::Dave; + let one = AccountKeyring::One; + let two = AccountKeyring::Two; + + let add_parent_key_to_kvdb = true; + let (_validator_ips, _validator_ids) = spawn_testing_validators(add_parent_key_to_kvdb).await; + + // Here we need to use `--chain=integration-tests` and force authoring otherwise we won't be + // able to get our chain in the right state to be jump started. + let force_authoring = true; + let substrate_context = test_node_process_testing_state(force_authoring).await; + let entropy_api = get_api(&substrate_context.ws_url).await.unwrap(); + let rpc = get_rpc(&substrate_context.ws_url).await.unwrap(); + + // We first need to jump start the network and grab the resulting network wide verifying key + // for later + jump_start_network(&entropy_api, &rpc).await; + + // We need to store a program in order to be able to register succesfully + let program_hash = test_client::store_program( + &entropy_api, + &rpc, + &two.pair(), // This is our program deployer + TEST_PROGRAM_WASM_BYTECODE.to_owned(), + vec![], + vec![], + vec![], + ) + .await + .unwrap(); + + let (verifying_key, _registered_info) = test_client::register( + &entropy_api, + &rpc, + one.clone().into(), // This is our program modification account + subxtAccountId32(two.public().0), // This is our signature request account + BoundedVec(vec![ProgramInstance { program_pointer: program_hash, program_config: vec![] }]), + ) + .await + .unwrap(); - 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(); let keypair = Sr25519Keypair::generate(); let public_key = BASE64_STANDARD.encode(keypair.public); @@ -1203,6 +1129,7 @@ async fn test_device_key_proxy() { sr25519_public_keys: Some(vec![public_key.clone()]), ed25519_public_keys: None, }; + // check to make sure config data stored properly let program_query = entropy::storage().programs().programs(*DEVICE_KEY_HASH); let program_data = query_chain(&entropy_api, &rpc, program_query, None).await.unwrap().unwrap(); @@ -1219,11 +1146,12 @@ async fn test_device_key_proxy() { program_data.auxiliary_data_schema, "aux data interface recoverable through schemers" ); + update_programs( &entropy_api, &rpc, - DAVE_VERIFYING_KEY, - &one.pair(), + verifying_key.as_slice().try_into().unwrap(), + &two.pair(), OtherBoundedVec(vec![OtherProgramInstance { program_pointer: *DEVICE_KEY_HASH, program_config: serde_json::to_vec(&device_key_user_config).unwrap(), @@ -1232,11 +1160,8 @@ async fn test_device_key_proxy() { .await .unwrap(); - let with_parent_key = false; - let validators_info = - get_signers_from_chain(&entropy_api, &rpc, with_parent_key).await.unwrap(); + // We now set up the auxilary data for our program let context = signing_context(b""); - let sr25519_signature: Sr25519Signature = keypair.sign(context.bytes(PREIMAGE_SHOULD_SUCCEED)); let aux_data_json_sr25519 = AuxData { @@ -1245,30 +1170,27 @@ async fn test_device_key_proxy() { signature: BASE64_STANDARD.encode(sr25519_signature.to_bytes()), context: "".to_string(), }; - let mut generic_msg = UserSignatureRequest { - message: hex::encode(PREIMAGE_SHOULD_SUCCEED), - auxilary_data: Some(vec![Some(hex::encode( - &serde_json::to_string(&aux_data_json_sr25519.clone()).unwrap(), - ))]), - validators_info: validators_info.clone(), - block_number: rpc.chain_get_header(None).await.unwrap().unwrap().number, - hash: HashingAlgorithm::Keccak, - signature_verifying_key: DAVE_VERIFYING_KEY.to_vec(), - }; - let validator_ips_and_keys: Vec<_> = validators_info - .iter() - .map(|validator_info| { - (validator_info.ip_address.clone(), validator_info.x25519_public_key.clone()) - }) - .collect(); + let auxilary_data = Some(vec![Some(hex::encode( + &serde_json::to_string(&aux_data_json_sr25519.clone()).unwrap(), + ))]); + + // Now we'll send off a signature request using the new program with auxilary data + let (validators_info, mut signature_request, validator_ips_and_keys) = + get_sign_tx_data(&entropy_api, &rpc, hex::encode(PREIMAGE_SHOULD_SUCCEED)).await; + + // We'll use the actual verifying key we registered for the signature request + signature_request.signature_verifying_key = verifying_key.to_vec(); + signature_request.block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number; + signature_request.auxilary_data = auxilary_data; - generic_msg.block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number; - let message_hash = Hasher::keccak(PREIMAGE_SHOULD_SUCCEED); let test_user_res = - submit_transaction_requests(validator_ips_and_keys.clone(), generic_msg.clone(), one).await; + submit_transaction_requests(validator_ips_and_keys.clone(), signature_request.clone(), one) + .await; + + let message_hash = Hasher::keccak(PREIMAGE_SHOULD_SUCCEED); + let verifying_key = decode_verifying_key(verifying_key.as_slice().try_into().unwrap()).unwrap(); - let verifying_key = decode_verifying_key(&DAVE_VERIFYING_KEY).unwrap(); verify_signature(test_user_res, message_hash, &verifying_key, &validators_info).await; } @@ -1330,7 +1252,7 @@ async fn test_faucet() { .await .unwrap(); - let program_hash = store_program( + let program_hash = test_client::store_program( &entropy_api, &rpc, &two.pair(), @@ -1392,7 +1314,7 @@ async fn test_faucet() { let partial = entropy_api.tx().create_partial_signed_offline(&balance_transfer_tx, tx_params).unwrap(); - let mut generic_msg = UserSignatureRequest { + let mut signature_request = UserSignatureRequest { message: hex::encode(partial.signer_payload()), auxilary_data: Some(vec![Some(hex::encode( &serde_json::to_string(&aux_data.clone()).unwrap(), @@ -1408,9 +1330,10 @@ async fn test_faucet() { (validator_ips[1].clone(), X25519_PUBLIC_KEYS[1]), ]; - generic_msg.block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number; + signature_request.block_number = rpc.chain_get_header(None).await.unwrap().unwrap().number; let test_user_res = - submit_transaction_requests(validator_ips_and_keys.clone(), generic_msg.clone(), one).await; + submit_transaction_requests(validator_ips_and_keys.clone(), signature_request.clone(), one) + .await; let mut decoded_sig: Vec = vec![]; for res in test_user_res { let chunk = res.unwrap().chunk().await.unwrap().unwrap(); @@ -1492,7 +1415,7 @@ async fn test_new_registration_flow() { let network_verifying_key = jump_start_progress.verifying_key.unwrap().0; // We need to store a program in order to be able to register succesfully - let program_hash = store_program( + let program_hash = test_client::store_program( &entropy_api, &rpc, &bob.pair(), // This is our program deployer @@ -1504,7 +1427,7 @@ async fn test_new_registration_flow() { .await .unwrap(); - let registration_request = put_new_register_request_on_chain( + let registration_request = put_register_request_on_chain( &entropy_api, &rpc, &alice, // This is our signature request account @@ -1660,11 +1583,10 @@ pub async fn get_sign_tx_data( api: &OnlineClient, rpc: &LegacyRpcMethods, message: String, - with_parent_key: bool, ) -> (Vec, UserSignatureRequest, Vec<(String, [u8; 32])>) { - let validators_info = get_signers_from_chain(api, rpc, with_parent_key).await.unwrap(); + let validators_info = get_signers_from_chain(api, rpc).await.unwrap(); - let generic_msg = UserSignatureRequest { + let signature_request = UserSignatureRequest { message, auxilary_data: Some(vec![ Some(hex::encode(AUXILARY_DATA_SHOULD_SUCCEED)), @@ -1679,7 +1601,7 @@ pub async fn get_sign_tx_data( let validator_ips_and_keys = validators_info.iter().map(|v| (v.ip_address.clone(), v.x25519_public_key)).collect(); - (validators_info, generic_msg, validator_ips_and_keys) + (validators_info, signature_request, validator_ips_and_keys) } /// Mock jump starting the network diff --git a/crates/threshold-signature-server/tests/register_and_sign.rs b/crates/threshold-signature-server/tests/register_and_sign.rs index 454ff701e..839bd41d9 100644 --- a/crates/threshold-signature-server/tests/register_and_sign.rs +++ b/crates/threshold-signature-server/tests/register_and_sign.rs @@ -68,14 +68,12 @@ async fn integration_test_register_and_sign() { .unwrap(); // Register, using that program - let register_on_chain = true; let (verifying_key, _registered_info) = test_client::register( &api, &rpc, account_owner.clone(), AccountId32(account_owner.public().0), BoundedVec(vec![ProgramInstance { program_pointer, program_config: vec![] }]), - register_on_chain, ) .await .unwrap(); diff --git a/crates/threshold-signature-server/tests/sign.rs b/crates/threshold-signature-server/tests/sign.rs deleted file mode 100644 index 733d028fe..000000000 --- a/crates/threshold-signature-server/tests/sign.rs +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (C) 2023 Entropy Cryptography Inc. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -use entropy_client::{ - chain_api::{ - entropy::runtime_types::bounded_collections::bounded_vec::BoundedVec, - entropy::runtime_types::pallet_registry::pallet::ProgramInstance, get_api, get_rpc, - }, - client as test_client, Hasher, -}; -use entropy_kvdb::clean_tests; -use entropy_shared::EVE_VERIFYING_KEY; -use entropy_testing_utils::{ - constants::{ - AUXILARY_DATA_SHOULD_SUCCEED, PREIMAGE_SHOULD_SUCCEED, TEST_PROGRAM_WASM_BYTECODE, - }, - spawn_testing_validators, - substrate_context::test_context_stationary, -}; -use serial_test::serial; -use sp_keyring::AccountKeyring; -use synedrion::k256::ecdsa::VerifyingKey; - -#[ignore] -#[tokio::test] -#[serial] -async fn integration_test_sign_public() { - clean_tests(); - let eve = AccountKeyring::Eve; - let request_author = AccountKeyring::One; - - 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(); - - let program_pointer = test_client::store_program( - &api, - &rpc, - &eve.pair(), - TEST_PROGRAM_WASM_BYTECODE.to_owned(), - vec![], - vec![], - vec![], - ) - .await - .unwrap(); - - test_client::update_programs( - &api, - &rpc, - EVE_VERIFYING_KEY, - &eve.pair(), - BoundedVec(vec![ProgramInstance { program_pointer, program_config: vec![] }]), - ) - .await - .unwrap(); - - let message_should_succeed_hash = Hasher::keccak(PREIMAGE_SHOULD_SUCCEED); - - let recoverable_signature = test_client::sign( - &api, - &rpc, - request_author.pair(), - EVE_VERIFYING_KEY, - PREIMAGE_SHOULD_SUCCEED.to_vec(), - Some(AUXILARY_DATA_SHOULD_SUCCEED.to_vec()), - ) - .await - .unwrap(); - - let recovery_key_from_sig = VerifyingKey::recover_from_prehash( - &message_should_succeed_hash, - &recoverable_signature.signature, - recoverable_signature.recovery_id, - ) - .unwrap(); - assert_eq!( - EVE_VERIFYING_KEY.to_vec(), - recovery_key_from_sig.to_encoded_point(true).to_bytes().to_vec() - ); -} diff --git a/crates/threshold-signature-server/tests/sign_eth_tx.rs b/crates/threshold-signature-server/tests/sign_eth_tx.rs index 92bd7c473..00279dad4 100644 --- a/crates/threshold-signature-server/tests/sign_eth_tx.rs +++ b/crates/threshold-signature-server/tests/sign_eth_tx.rs @@ -17,16 +17,15 @@ use entropy_client::{ chain_api::{ entropy::runtime_types::bounded_collections::bounded_vec::BoundedVec, entropy::runtime_types::pallet_registry::pallet::ProgramInstance, get_api, get_rpc, + EntropyConfig, }, client as test_client, Hasher, }; use entropy_kvdb::clean_tests; use entropy_protocol::{decode_verifying_key, RecoverableSignature}; -use entropy_shared::EVE_VERIFYING_KEY; use entropy_testing_utils::{ constants::{AUXILARY_DATA_SHOULD_SUCCEED, TEST_PROGRAM_WASM_BYTECODE}, - spawn_testing_validators, - substrate_context::test_context_stationary, + jump_start_network, spawn_testing_validators, test_node_process_testing_state, }; use ethers_core::{ abi::ethabi::ethereum_types::{H160, H256}, @@ -37,27 +36,39 @@ use ethers_core::{ }, }; use serial_test::serial; +use sp_core::{sr25519, Pair}; use sp_keyring::AccountKeyring; +use subxt::{tx::PairSigner, utils::AccountId32}; use synedrion::k256::ecdsa::VerifyingKey; const GOERLI_CHAIN_ID: u64 = 5; -#[ignore] #[tokio::test] #[serial] async fn integration_test_sign_eth_tx() { clean_tests(); - let pre_registered_user = AccountKeyring::Eve; + let account_owner = AccountKeyring::Ferdie.pair(); + let signature_request_author = AccountKeyring::One; - 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(); + let add_parent_key = true; + let (_validator_ips, _validator_ids) = spawn_testing_validators(add_parent_key).await; + let force_authoring = true; + let substrate_context = test_node_process_testing_state(force_authoring).await; + + let api = get_api(&substrate_context.ws_url).await.unwrap(); + let rpc = get_rpc(&substrate_context.ws_url).await.unwrap(); + + // Jumpstart the network + let alice = AccountKeyring::Alice; + let signer = PairSigner::::new(alice.clone().into()); + jump_start_network(&api, &rpc, &signer).await; + + // Store a program let program_pointer = test_client::store_program( &api, &rpc, - &pre_registered_user.pair(), + &account_owner, TEST_PROGRAM_WASM_BYTECODE.to_owned(), vec![], vec![], @@ -66,30 +77,28 @@ async fn integration_test_sign_eth_tx() { .await .unwrap(); - test_client::update_programs( + // Register, using that program + let (verifying_key, _registered_info) = test_client::register( &api, &rpc, - EVE_VERIFYING_KEY, - &pre_registered_user.pair(), + account_owner.clone(), + AccountId32(account_owner.public().0), BoundedVec(vec![ProgramInstance { program_pointer, program_config: vec![] }]), ) .await .unwrap(); - // Get the public key to use in the 'from' field - let verifying_key = decode_verifying_key(&EVE_VERIFYING_KEY).unwrap(); - - let transaction_request = create_unsigned_eth_tx(verifying_key); + let eth_verifying_key = decode_verifying_key(&verifying_key).unwrap(); + let transaction_request = create_unsigned_eth_tx(eth_verifying_key); let message = transaction_request.rlp_unsigned().to_vec(); - let message_hash = Hasher::keccak(&message); let recoverable_signature = test_client::sign( &api, &rpc, - pre_registered_user.pair(), - EVE_VERIFYING_KEY, + signature_request_author.pair(), + verifying_key, message, Some(AUXILARY_DATA_SHOULD_SUCCEED.to_vec()), ) @@ -102,14 +111,14 @@ async fn integration_test_sign_eth_tx() { recoverable_signature.recovery_id, ) .unwrap(); - assert_eq!(verifying_key, recovery_key_from_sig); + assert_eq!(eth_verifying_key, recovery_key_from_sig); let ethers_signature = recoverable_signature_to_ethers_signature(recoverable_signature); // Check the signature let recovered_eth_address = ethers_signature.recover(RecoveryMessage::Hash(H256(message_hash))).unwrap(); - assert_eq!(recovered_eth_address, public_key_to_address(&verifying_key)); + assert_eq!(recovered_eth_address, public_key_to_address(ð_verifying_key)); let signed_transaction_bytes = transaction_request.rlp_signed(ðers_signature); let rlp = Rlp::new(&signed_transaction_bytes); @@ -123,7 +132,7 @@ async fn integration_test_sign_eth_tx() { // Verify the signed Transaction let recovered_eth_address = transaction.recover_from().unwrap(); - assert_eq!(recovered_eth_address, public_key_to_address(&verifying_key)); + assert_eq!(recovered_eth_address, public_key_to_address(ð_verifying_key)); } /// Convert a k256 Signature and RecoveryId to an ethers Signature diff --git a/node/cli/src/chain_spec/dev.rs b/node/cli/src/chain_spec/dev.rs index 44e29e38b..6a8fa3cd6 100644 --- a/node/cli/src/chain_spec/dev.rs +++ b/node/cli/src/chain_spec/dev.rs @@ -19,14 +19,14 @@ use crate::endowed_accounts::endowed_accounts_dev; use entropy_runtime::{ constants::currency::*, wasm_binary_unwrap, AttestationConfig, AuthorityDiscoveryConfig, BabeConfig, BalancesConfig, ElectionsConfig, GrandpaConfig, ImOnlineConfig, IndicesConfig, - MaxNominations, ParametersConfig, ProgramsConfig, RegistryConfig, SessionConfig, StakerStatus, - StakingConfig, StakingExtensionConfig, SudoConfig, TechnicalCommitteeConfig, + MaxNominations, ParametersConfig, ProgramsConfig, SessionConfig, StakerStatus, StakingConfig, + StakingExtensionConfig, SudoConfig, TechnicalCommitteeConfig, }; use entropy_runtime::{AccountId, Balance}; use entropy_shared::{ - X25519PublicKey as TssX25519PublicKey, DAVE_VERIFYING_KEY, DEVICE_KEY_AUX_DATA_TYPE, - DEVICE_KEY_CONFIG_TYPE, DEVICE_KEY_HASH, DEVICE_KEY_PROXY, EVE_VERIFYING_KEY, - FERDIE_VERIFYING_KEY, INITIAL_MAX_INSTRUCTIONS_PER_PROGRAM, SIGNER_THRESHOLD, TOTAL_SIGNERS, + X25519PublicKey as TssX25519PublicKey, DEVICE_KEY_AUX_DATA_TYPE, DEVICE_KEY_CONFIG_TYPE, + DEVICE_KEY_HASH, DEVICE_KEY_PROXY, INITIAL_MAX_INSTRUCTIONS_PER_PROGRAM, SIGNER_THRESHOLD, + TOTAL_SIGNERS, }; use grandpa_primitives::AuthorityId as GrandpaId; use itertools::Itertools; @@ -35,7 +35,7 @@ use sc_service::ChainType; use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; use sp_consensus_babe::AuthorityId as BabeId; use sp_core::{sr25519, ByteArray}; -use sp_runtime::{BoundedVec, Perbill}; +use sp_runtime::Perbill; pub fn devnet_three_node_initial_tss_servers( ) -> Vec<(sp_runtime::AccountId32, TssX25519PublicKey, String)> { @@ -303,22 +303,6 @@ pub fn development_genesis_config( "imOnline": ImOnlineConfig { keys: vec![] }, "authorityDiscovery": AuthorityDiscoveryConfig { keys: vec![], ..Default::default() }, "grandpa": GrandpaConfig { authorities: vec![], ..Default::default() }, - "registry": RegistryConfig { - registered_accounts: vec![ - ( - get_account_id_from_seed::("Dave"), - BoundedVec::try_from(DAVE_VERIFYING_KEY.to_vec()).unwrap(), - ), - ( - get_account_id_from_seed::("Eve"), - BoundedVec::try_from(EVE_VERIFYING_KEY.to_vec()).unwrap(), - ), - ( - get_account_id_from_seed::("Ferdie"), - BoundedVec::try_from(FERDIE_VERIFYING_KEY.to_vec()).unwrap(), - ), - ], - }, "parameters": ParametersConfig { request_limit: 20, max_instructions_per_programs: INITIAL_MAX_INSTRUCTIONS_PER_PROGRAM, diff --git a/node/cli/src/chain_spec/integration_tests.rs b/node/cli/src/chain_spec/integration_tests.rs index a7d9b9fbe..c5dd75816 100644 --- a/node/cli/src/chain_spec/integration_tests.rs +++ b/node/cli/src/chain_spec/integration_tests.rs @@ -19,14 +19,14 @@ use crate::endowed_accounts::endowed_accounts_dev; use entropy_runtime::{ constants::currency::*, wasm_binary_unwrap, AttestationConfig, AuthorityDiscoveryConfig, BabeConfig, BalancesConfig, ElectionsConfig, GrandpaConfig, ImOnlineConfig, IndicesConfig, - MaxNominations, ParametersConfig, ProgramsConfig, RegistryConfig, SessionConfig, StakerStatus, - StakingConfig, StakingExtensionConfig, SudoConfig, TechnicalCommitteeConfig, + MaxNominations, ParametersConfig, ProgramsConfig, SessionConfig, StakerStatus, StakingConfig, + StakingExtensionConfig, SudoConfig, TechnicalCommitteeConfig, }; use entropy_runtime::{AccountId, Balance}; use entropy_shared::{ DAVE_VERIFYING_KEY, DEVICE_KEY_AUX_DATA_TYPE, DEVICE_KEY_CONFIG_TYPE, DEVICE_KEY_HASH, - DEVICE_KEY_PROXY, EVE_VERIFYING_KEY, FERDIE_VERIFYING_KEY, - INITIAL_MAX_INSTRUCTIONS_PER_PROGRAM, SIGNER_THRESHOLD, TOTAL_SIGNERS, + DEVICE_KEY_PROXY, EVE_VERIFYING_KEY, INITIAL_MAX_INSTRUCTIONS_PER_PROGRAM, SIGNER_THRESHOLD, + TOTAL_SIGNERS, }; use grandpa_primitives::AuthorityId as GrandpaId; use itertools::Itertools; @@ -35,7 +35,7 @@ use sc_service::ChainType; use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; use sp_consensus_babe::AuthorityId as BabeId; use sp_core::{sr25519, ByteArray}; -use sp_runtime::{BoundedVec, Perbill}; +use sp_runtime::Perbill; /// The configuration used for the Threshold Signature Scheme server integration tests. /// @@ -242,22 +242,6 @@ pub fn integration_tests_genesis_config( "imOnline": ImOnlineConfig { keys: vec![] }, "authorityDiscovery": AuthorityDiscoveryConfig { keys: vec![], ..Default::default() }, "grandpa": GrandpaConfig { authorities: vec![], ..Default::default() }, - "registry": RegistryConfig { - registered_accounts: vec![ - ( - get_account_id_from_seed::("Dave"), - BoundedVec::try_from(DAVE_VERIFYING_KEY.to_vec()).unwrap(), - ), - ( - get_account_id_from_seed::("Eve"), - BoundedVec::try_from(EVE_VERIFYING_KEY.to_vec()).unwrap(), - ), - ( - get_account_id_from_seed::("Ferdie"), - BoundedVec::try_from(FERDIE_VERIFYING_KEY.to_vec()).unwrap(), - ), - ], - }, "parameters": ParametersConfig { request_limit: 20, max_instructions_per_programs: INITIAL_MAX_INSTRUCTIONS_PER_PROGRAM, diff --git a/node/cli/src/service.rs b/node/cli/src/service.rs index 0dbb6a88e..ac481472a 100644 --- a/node/cli/src/service.rs +++ b/node/cli/src/service.rs @@ -357,11 +357,6 @@ pub fn new_full_base( b"propagation", &format!("{}/generate_network_key", endpoint).into_bytes(), ); - offchain_db.local_storage_set( - sp_core::offchain::StorageKind::PERSISTENT, - b"registration", - &format!("{}/user/new", endpoint).into_bytes(), - ); offchain_db.local_storage_set( sp_core::offchain::StorageKind::PERSISTENT, b"refresh", diff --git a/pallets/propagation/src/lib.rs b/pallets/propagation/src/lib.rs index 7d110665a..630aa4396 100644 --- a/pallets/propagation/src/lib.rs +++ b/pallets/propagation/src/lib.rs @@ -69,14 +69,12 @@ pub mod pallet { fn offchain_worker(block_number: BlockNumberFor) { let _ = Self::post_dkg(block_number); let _ = Self::post_reshare(block_number); - let _ = Self::post_user_registration(block_number); - let _ = Self::post_attestation_request(block_number); let _ = Self::post_proactive_refresh(block_number); + let _ = Self::post_attestation_request(block_number); let _ = Self::post_rotate_keyshare(block_number); } - fn on_initialize(block_number: BlockNumberFor) -> Weight { - pallet_registry::Dkg::::remove(block_number.saturating_sub(2u32.into())); + fn on_initialize(_block_number: BlockNumberFor) -> Weight { pallet_staking_extension::ProactiveRefresh::::take(); ::WeightInfo::on_initialize() } @@ -169,64 +167,6 @@ pub mod pallet { Ok(()) } - /// Submits a distributed key generation request to register a set of users to the threshold - /// servers. - pub fn post_user_registration(block_number: BlockNumberFor) -> Result<(), http::Error> { - let messages = - pallet_registry::Pallet::::dkg(block_number.saturating_sub(1u32.into())); - - 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"registration") - .unwrap_or_else(|| b"http://localhost:3001/user/new".to_vec()); - let url = str::from_utf8(&from_local).unwrap_or("http://localhost:3001/user/new"); - - log::warn!("propagation::post::messages: {:?}", &messages); - let converted_block_number: u32 = - BlockNumberFor::::try_into(block_number).unwrap_or_default(); - let servers_info = - pallet_registry::Pallet::::get_validators_info().unwrap_or_default(); - let validators_info = servers_info - .iter() - .map(|server_info| ValidatorInfo { - x25519_public_key: server_info.x25519_public_key, - ip_address: server_info.endpoint.clone(), - tss_account: server_info.tss_account.encode(), - }) - .collect::>(); - // the data is serialized / encoded to Vec by parity-scale-codec::encode() - let req_body = OcwMessageDkg { - // subtract 1 from blocknumber since the request is from the last block - block_number: converted_block_number.saturating_sub(1), - sig_request_accounts: messages, - validators_info, - }; - - log::warn!("propagation::post::req_body: {:?}", &[req_body.encode()]); - // We construct the request - // important: the header->Content-Type must be added and match that of the receiving - // party!! - let pending = http::Request::post(url, vec![req_body.encode()]) - .deadline(deadline) - .send() - .map_err(|_| http::Error::IoError)?; - - // We await response, same as in fn get() - let response = - pending.try_wait(deadline).map_err(|_| http::Error::DeadlineReached)??; - - // check response code - if response.code != 200 { - log::warn!("Unexpected status code: {}", response.code); - return Err(http::Error::Unknown); - } - let _res_body = response.body().collect::>(); - - Self::deposit_event(Event::DkgMessagePassed(req_body)); - - Ok(()) - } - /// 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(); diff --git a/pallets/propagation/src/tests.rs b/pallets/propagation/src/tests.rs index eae4e59a3..05172236c 100644 --- a/pallets/propagation/src/tests.rs +++ b/pallets/propagation/src/tests.rs @@ -17,9 +17,7 @@ use std::sync::Arc; use codec::Encode; use entropy_shared::ValidatorInfo; -use frame_support::{assert_ok, traits::OnInitialize, BoundedVec}; -use pallet_programs::ProgramInfo; -use pallet_registry::ProgramInstance; +use frame_support::traits::OnInitialize; use pallet_staking_extension::{RefreshInfo, ReshareInfo}; use sp_core::offchain::{testing, OffchainDbExt, OffchainWorkerExt, TransactionPoolExt}; use sp_io::TestExternalities; @@ -45,21 +43,6 @@ fn knows_how_to_mock_several_http_calls() { ..Default::default() }); - state.expect_request(testing::PendingRequest { - method: "POST".into(), - uri: "http://localhost:3001/generate_network_key".into(), - sent: true, - response: Some([].to_vec()), - body: [ - 3, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 10, 32, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, - 11, 32, 4, 0, 0, 0, 0, 0, 0, 0, - ] - .to_vec(), - ..Default::default() - }); - state.expect_request(testing::PendingRequest { method: "POST".into(), uri: "http://localhost:3001/signer/proactive_refresh".into(), @@ -94,35 +77,6 @@ fn knows_how_to_mock_several_http_calls() { t.execute_with(|| { Propagation::post_dkg(1).unwrap(); - System::set_block_number(3); - pallet_programs::Programs::::insert( - ::Hash::default(), - ProgramInfo { - bytecode: vec![], - configuration_schema: vec![], - auxiliary_data_schema: vec![], - oracle_data_pointer: vec![], - deployer: 1, - ref_counter: 0, - }, - ); - - let programs_info = BoundedVec::try_from(vec![ProgramInstance { - program_pointer: ::Hash::default(), - program_config: vec![], - }]) - .unwrap(); - assert_ok!(Registry::register(RuntimeOrigin::signed(1), 2, programs_info.clone(),)); - assert_ok!(Registry::register(RuntimeOrigin::signed(2), 3, programs_info,)); - - // full send - Propagation::post_dkg(4).unwrap(); - - // test pruning - assert_eq!(Registry::dkg(3).len(), 2); - Propagation::on_initialize(5); - assert_eq!(Registry::dkg(3).len(), 0); - Propagation::post_proactive_refresh(6).unwrap(); let ocw_message = RefreshInfo { validators_info: vec![ValidatorInfo { diff --git a/pallets/registry/src/benchmarking.rs b/pallets/registry/src/benchmarking.rs index c520e8172..492009951 100644 --- a/pallets/registry/src/benchmarking.rs +++ b/pallets/registry/src/benchmarking.rs @@ -142,30 +142,6 @@ benchmarks! { register { let p in 1 .. T::MaxProgramHashes::get(); - let program = vec![0u8]; - let configuration_schema = vec![1u8]; - let auxiliary_data_schema = vec![2u8]; - let oracle_data_pointer = vec![3u8]; - let program_hash = T::Hashing::hash(&program); - let programs_info = BoundedVec::try_from(vec![ProgramInstance { - program_pointer: program_hash, - program_config: vec![], - }; p as usize]) - .unwrap(); - - let program_modification_account: T::AccountId = whitelisted_caller(); - Programs::::insert(program_hash, ProgramInfo {bytecode: program, configuration_schema, auxiliary_data_schema, oracle_data_pointer, deployer: program_modification_account.clone(), ref_counter: 0}); - let sig_req_account: T::AccountId = whitelisted_caller(); - let balance = ::Currency::minimum_balance() * 100u32.into(); - let _ = ::Currency::make_free_balance_be(&sig_req_account, balance); - }: _(RawOrigin::Signed(sig_req_account.clone()), program_modification_account, programs_info) - verify { - assert_last_event::(Event::SignalRegister(sig_req_account.clone()).into()); - assert!(Registering::::contains_key(sig_req_account)); - } - - register_on_chain { - let p in 1 .. T::MaxProgramHashes::get(); let program_modification_account: T::AccountId = whitelisted_caller(); let signature_request_account: T::AccountId = whitelisted_caller(); @@ -225,7 +201,7 @@ benchmarks! { // We substract one from the count since this gets incremented after a succesful registration, // and we're interested in the account we just registered. - let count = >::count() - 1; + let count = >::count() - 1; let derivation_path = bip32::DerivationPath::from_str(&scale_info::prelude::format!("m/0/{}", count)).unwrap(); @@ -247,7 +223,7 @@ benchmarks! { ).into(), ); - assert!(RegisteredOnChain::::contains_key(expected_verifying_key)); + assert!(Registered::::contains_key(expected_verifying_key)); } change_program_instance { diff --git a/pallets/registry/src/lib.rs b/pallets/registry/src/lib.rs index 99371e7d1..c22f42231 100644 --- a/pallets/registry/src/lib.rs +++ b/pallets/registry/src/lib.rs @@ -52,7 +52,7 @@ pub mod weights; #[frame_support::pallet] pub mod pallet { - use entropy_shared::{MAX_SIGNERS, NETWORK_PARENT_KEY, VERIFICATION_KEY_LENGTH}; + use entropy_shared::{MAX_SIGNERS, NETWORK_PARENT_KEY}; use frame_support::{ dispatch::DispatchResultWithPostInfo, pallet_prelude::*, traits::ConstU32, }; @@ -120,41 +120,10 @@ pub mod pallet { pub version_number: u8, } - #[pallet::genesis_config] - #[derive(frame_support::DefaultNoBound)] - pub struct GenesisConfig { - #[allow(clippy::type_complexity)] - pub registered_accounts: Vec<(T::AccountId, VerifyingKey)>, - } - - #[pallet::genesis_build] - impl BuildGenesisConfig for GenesisConfig { - fn build(&self) { - for (account_id, verifying_key) in &self.registered_accounts { - assert!(verifying_key.len() as u32 == VERIFICATION_KEY_LENGTH); - - Registered::::insert( - verifying_key.clone(), - RegisteredInfo { - programs_data: BoundedVec::default(), - program_modification_account: account_id.clone(), - derivation_path: None, - version_number: T::KeyVersionNumber::get(), - }, - ); - } - } - } - #[pallet::pallet] #[pallet::without_storage_info] pub struct Pallet(_); - #[pallet::storage] - #[pallet::getter(fn registering)] - pub type Registering = - StorageMap<_, Blake2_128Concat, T::AccountId, RegisteringDetails, OptionQuery>; - /// Used for triggering a network wide distributed key generation request via an offchain /// worker. #[pallet::storage] @@ -162,26 +131,14 @@ pub mod pallet { pub type JumpstartDkg = StorageMap<_, Blake2_128Concat, BlockNumberFor, Vec>, ValueQuery>; - /// Used to store requests and trigger distributed key generation for users via an offchain - /// worker. - #[pallet::storage] - #[pallet::getter(fn dkg)] - pub type Dkg = - StorageMap<_, Blake2_128Concat, BlockNumberFor, Vec>, ValueQuery>; - - #[pallet::storage] - #[pallet::getter(fn registered)] - pub type Registered = - StorageMap<_, Blake2_128Concat, VerifyingKey, RegisteredInfo, OptionQuery>; - /// An item tracking all the users registered on the Entropy network. /// /// Notice that the registration state does not depend on any Substrate account being /// registered, but rather a _verifying key_, which represents the user beyond the scope of the /// Entropy network itself (e.g it can be an account on Bitcoin or Ethereum). #[pallet::storage] - #[pallet::getter(fn registered_on_chain)] - pub type RegisteredOnChain = + #[pallet::getter(fn registered)] + pub type Registered = CountedStorageMap<_, Blake2_128Concat, VerifyingKey, RegisteredInfo, OptionQuery>; /// Mapping of program_modification accounts to verifying keys they can control @@ -206,41 +163,24 @@ pub mod pallet { FinishedNetworkJumpStart(), /// The network has had a jump start confirmation. [who, confirmation_count] JumpStartConfirmation(T::ValidatorId, u8), - /// An account has signaled to be registered. [signature request account] - SignalRegister(T::AccountId), - /// An account has been registered. [who, verifying_key] - RecievedConfirmation(T::AccountId, VerifyingKey), /// An account has been registered. \[who, verifying_key] AccountRegistered(T::AccountId, VerifyingKey), - /// An account registration has failed - FailedRegistration(T::AccountId), - /// An account cancelled their registration - RegistrationCancelled(T::AccountId), /// An account hash changed their program info [who, new_program_instance] ProgramInfoChanged(T::AccountId, BoundedVec, T::MaxProgramHashes>), /// An account has changed their program modification account [old, new, verifying_key] ProgramModificationAccountChanged(T::AccountId, T::AccountId, VerifyingKey), - /// An account has been registered. [who, block_number, failures] - ConfirmedDone(T::AccountId, BlockNumberFor, Vec), } // Errors inform users that something went wrong. #[pallet::error] pub enum Error { - AlreadySubmitted, NoThresholdKey, - NotRegistering, NotRegistered, AlreadyConfirmed, IpAddressError, - NoSyncedValidators, - MaxProgramLengthExceeded, - NoVerifyingKey, NotAuthorized, - ProgramDoesNotExist, NoProgramSet, TooManyModifiableKeys, - MismatchedVerifyingKeyLength, MismatchedVerifyingKey, NotValidator, JumpStartProgressNotReady, @@ -383,9 +323,8 @@ pub mod pallet { /// /// The caller provides an initial program pointer. /// - /// Note that a user needs to be confirmed by validators through the - /// [`Self::confirm_register`] extrinsic before they can be considered as registered on the - /// network. + /// Note: Substrate origins are allowed to register as many accounts as they wish. Each + /// registration request will produce a different verifying key. #[pallet::call_index(2)] #[pallet::weight({ ::WeightInfo::register(::MaxProgramHashes::get()) @@ -395,18 +334,19 @@ pub mod pallet { program_modification_account: T::AccountId, programs_data: BoundedVec, T::MaxProgramHashes>, ) -> DispatchResultWithPostInfo { - let sig_req_account = ensure_signed(origin)?; + use core::str::FromStr; + use synedrion::{ecdsa::VerifyingKey as SynedrionVerifyingKey, DeriveChildKey}; + + let signature_request_account = ensure_signed(origin)?; ensure!( - sig_req_account.encode() != NETWORK_PARENT_KEY.encode(), + signature_request_account.encode() != NETWORK_PARENT_KEY.encode(), Error::::NoRegisteringFromParentKey ); - ensure!( - !Registering::::contains_key(&sig_req_account), - Error::::AlreadySubmitted - ); - ensure!(!programs_data.is_empty(), Error::::NoProgramSet); - let block_number = >::block_number(); + + let num_programs = programs_data.len(); + ensure!(num_programs != 0, Error::::NoProgramSet); + // Change program ref counter for program_instance in &programs_data { pallet_programs::Programs::::try_mutate( @@ -422,25 +362,61 @@ pub mod pallet { )?; } - Dkg::::try_mutate(block_number, |messages| -> Result<_, DispatchError> { - messages.push(sig_req_account.encode()); - Ok(()) - })?; + let network_verifying_key = + if let Some(key) = >::get().verifying_key { + SynedrionVerifyingKey::try_from(key.as_slice()) + .expect("The network verifying key must be valid.") + } else { + return Err(Error::::JumpStartNotCompleted.into()); + }; - // Put account into a registering state - Registering::::insert( - &sig_req_account, - RegisteringDetails:: { - program_modification_account, - confirmations: vec![], - programs_data: programs_data.clone(), - verifying_key: None, + // TODO (#984): For a `CountedStorageMap` there is the possibility that the counter + // can decrease as storage entries are removed from the map. In our case we don't ever + // remove entries from the `Registered` map so the counter should never + // decrease. If it does we will end up with the same verifying key for different + // accounts, which would be bad. + // + // For a V1 of this flow it's fine, but we'll need to think about a better solution + // down the line. + let count = Registered::::count(); + let inner_path = scale_info::prelude::format!("m/0/{}", count); + let path = bip32::DerivationPath::from_str(&inner_path) + .map_err(|_| Error::::InvalidBip32DerivationPath)?; + let child_verifying_key = network_verifying_key + .derive_verifying_key_bip32(&path) + .map_err(|_| Error::::Bip32AccountDerivationFailed)?; + + let child_verifying_key = BoundedVec::try_from( + child_verifying_key.to_encoded_point(true).as_bytes().to_vec(), + ) + .expect("Synedrion must have returned a valid verifying key."); + + Registered::::insert( + child_verifying_key.clone(), + RegisteredInfo { + programs_data, + program_modification_account: program_modification_account.clone(), + derivation_path: Some(inner_path.encode()), version_number: T::KeyVersionNumber::get(), }, ); - Self::deposit_event(Event::SignalRegister(sig_req_account)); - Ok(Some(::WeightInfo::register(programs_data.len() as u32)).into()) + ModifiableKeys::::try_mutate( + program_modification_account, + |verifying_keys| -> Result<(), DispatchError> { + verifying_keys + .try_push(child_verifying_key.clone()) + .map_err(|_| Error::::TooManyModifiableKeys)?; + Ok(()) + }, + )?; + + Self::deposit_event(Event::AccountRegistered( + signature_request_account, + child_verifying_key, + )); + + Ok(Some(::WeightInfo::register(num_programs as u32)).into()) } /// Allows a user's program modification account to change their program pointer @@ -475,7 +451,7 @@ pub mod pallet { let mut old_programs_length = 0; let programs_data = - RegisteredOnChain::::try_mutate(&verifying_key, |maybe_registered_details| { + Registered::::try_mutate(&verifying_key, |maybe_registered_details| { if let Some(registered_details) = maybe_registered_details { ensure!( who == registered_details.program_modification_account, @@ -522,7 +498,7 @@ pub mod pallet { ) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; - RegisteredOnChain::::try_mutate(&verifying_key, |maybe_registered_details| { + Registered::::try_mutate(&verifying_key, |maybe_registered_details| { if let Some(registered_details) = maybe_registered_details { ensure!( who == registered_details.program_modification_account, @@ -568,106 +544,6 @@ pub mod pallet { )) .into()) } - - /// Allows a user to signal that they want to register an account with the Entropy network. - /// - /// The caller provides an initial program pointer. - /// - /// Note: Substrate origins are allowed to register as many accounts as they wish. Each - /// registration request will produce a different verifying key. - #[pallet::call_index(5)] - #[pallet::weight({ - ::WeightInfo::register_on_chain(::MaxProgramHashes::get()) - })] - pub fn register_on_chain( - origin: OriginFor, - program_modification_account: T::AccountId, - programs_data: BoundedVec, T::MaxProgramHashes>, - ) -> DispatchResultWithPostInfo { - use core::str::FromStr; - use synedrion::{ecdsa::VerifyingKey as SynedrionVerifyingKey, DeriveChildKey}; - - let signature_request_account = ensure_signed(origin)?; - - ensure!( - signature_request_account.encode() != NETWORK_PARENT_KEY.encode(), - Error::::NoRegisteringFromParentKey - ); - - let num_programs = programs_data.len(); - ensure!(num_programs != 0, Error::::NoProgramSet); - - // Change program ref counter - for program_instance in &programs_data { - pallet_programs::Programs::::try_mutate( - program_instance.program_pointer, - |maybe_program_info| { - if let Some(program_info) = maybe_program_info { - program_info.ref_counter = program_info.ref_counter.saturating_add(1); - Ok(()) - } else { - Err(Error::::NoProgramSet) - } - }, - )?; - } - - let network_verifying_key = - if let Some(key) = >::get().verifying_key { - SynedrionVerifyingKey::try_from(key.as_slice()) - .expect("The network verifying key must be valid.") - } else { - return Err(Error::::JumpStartNotCompleted.into()); - }; - - // TODO (#984): For a `CountedStorageMap` there is the possibility that the counter - // can decrease as storage entries are removed from the map. In our case we don't ever - // remove entries from the `RegisteredOnChain` map so the counter should never - // decrease. If it does we will end up with the same verifying key for different - // accounts, which would be bad. - // - // For a V1 of this flow it's fine, but we'll need to think about a better solution - // down the line. - let count = RegisteredOnChain::::count(); - let inner_path = scale_info::prelude::format!("m/0/{}", count); - let path = bip32::DerivationPath::from_str(&inner_path) - .map_err(|_| Error::::InvalidBip32DerivationPath)?; - let child_verifying_key = network_verifying_key - .derive_verifying_key_bip32(&path) - .map_err(|_| Error::::Bip32AccountDerivationFailed)?; - - let child_verifying_key = BoundedVec::try_from( - child_verifying_key.to_encoded_point(true).as_bytes().to_vec(), - ) - .expect("Synedrion must have returned a valid verifying key."); - - RegisteredOnChain::::insert( - child_verifying_key.clone(), - RegisteredInfo { - programs_data, - program_modification_account: program_modification_account.clone(), - derivation_path: Some(inner_path.encode()), - version_number: T::KeyVersionNumber::get(), - }, - ); - - ModifiableKeys::::try_mutate( - program_modification_account, - |verifying_keys| -> Result<(), DispatchError> { - verifying_keys - .try_push(child_verifying_key.clone()) - .map_err(|_| Error::::TooManyModifiableKeys)?; - Ok(()) - }, - )?; - - Self::deposit_event(Event::AccountRegistered( - signature_request_account, - child_verifying_key, - )); - - Ok(Some(::WeightInfo::register(num_programs as u32)).into()) - } } impl Pallet { diff --git a/pallets/registry/src/tests.rs b/pallets/registry/src/tests.rs index 951475348..77a6517bb 100644 --- a/pallets/registry/src/tests.rs +++ b/pallets/registry/src/tests.rs @@ -24,7 +24,7 @@ use pallet_staking_extension::{JumpStartDetails, JumpStartProgress, JumpStartSta use sp_runtime::traits::Hash; use crate as pallet_registry; -use crate::{mock::*, Error, ModifiableKeys, ProgramInstance, RegisteredInfo, RegisteredOnChain}; +use crate::{mock::*, Error, ModifiableKeys, ProgramInstance, Registered, RegisteredInfo}; const NULL_ARR: [u8; 32] = [0; 32]; @@ -69,7 +69,7 @@ fn it_tests_get_validators_info() { } #[test] -fn it_registers_a_user_on_chain() { +fn it_registers_a_user() { new_test_ext().execute_with(|| { use synedrion::{ecdsa::VerifyingKey as SynedrionVerifyingKey, DeriveChildKey}; @@ -87,11 +87,7 @@ fn it_registers_a_user_on_chain() { }); // Test: Run through registration - assert_ok!(Registry::register_on_chain( - RuntimeOrigin::signed(alice), - bob, - programs_info.clone(), - )); + assert_ok!(Registry::register(RuntimeOrigin::signed(alice), bob, programs_info.clone(),)); // Validate: Our expected verifying key is registered correctly let network_verifying_key = @@ -104,7 +100,7 @@ fn it_registers_a_user_on_chain() { BoundedVec::try_from(expected_verifying_key.to_encoded_point(true).as_bytes().to_vec()) .unwrap(); - let registered_info = Registry::registered_on_chain(expected_verifying_key.clone()); + let registered_info = Registry::registered(expected_verifying_key.clone()); assert!(registered_info.is_some()); assert_eq!(registered_info.unwrap().program_modification_account, bob); }); @@ -129,11 +125,7 @@ fn it_increases_program_reference_count_on_register() { }); // Test: Run through registration - assert_ok!(Registry::register_on_chain( - RuntimeOrigin::signed(alice), - bob, - programs_info.clone(), - )); + assert_ok!(Registry::register(RuntimeOrigin::signed(alice), bob, programs_info.clone(),)); // Validate: We expect that the program reference count has gone up assert_eq!( @@ -164,17 +156,9 @@ fn it_registers_different_users_with_the_same_sig_req_account() { // Test: Run through registration twice using the same signature request account. We should // get different verifying keys. - assert_ok!(Registry::register_on_chain( - RuntimeOrigin::signed(alice), - bob, - programs_info.clone(), - )); + assert_ok!(Registry::register(RuntimeOrigin::signed(alice), bob, programs_info.clone(),)); - assert_ok!(Registry::register_on_chain( - RuntimeOrigin::signed(alice), - bob, - programs_info.clone(), - )); + assert_ok!(Registry::register(RuntimeOrigin::signed(alice), bob, programs_info.clone(),)); // Validate: We expect two different verifying keys to be registered let network_verifying_key = @@ -199,8 +183,8 @@ fn it_registers_different_users_with_the_same_sig_req_account() { // Knowing that the two keys are indeed different, we still expect both registration // requests to have succeeded. assert!(first_expected_verifying_key != second_expected_verifying_key); - assert!(Registry::registered_on_chain(first_expected_verifying_key).is_some()); - assert!(Registry::registered_on_chain(second_expected_verifying_key).is_some()); + assert!(Registry::registered(first_expected_verifying_key).is_some()); + assert!(Registry::registered(second_expected_verifying_key).is_some()); }); } @@ -214,7 +198,7 @@ fn it_fails_registration_if_no_program_is_set() { // Test: Run through registration, this should fail assert_noop!( - Registry::register_on_chain(RuntimeOrigin::signed(alice), bob, programs_info,), + Registry::register(RuntimeOrigin::signed(alice), bob, programs_info,), Error::::NoProgramSet ); }) @@ -236,7 +220,7 @@ fn it_fails_registration_if_an_empty_program_is_set() { // Test: Run through registration, this should fail assert_noop!( - Registry::register_on_chain(RuntimeOrigin::signed(alice), bob, programs_info,), + Registry::register(RuntimeOrigin::signed(alice), bob, programs_info,), Error::::NoProgramSet ); }) @@ -260,7 +244,7 @@ fn it_fails_registration_if_no_jump_start_has_happened() { // Test: Run through registration, this should fail assert_noop!( - Registry::register_on_chain(RuntimeOrigin::signed(alice), bob, programs_info,), + Registry::register(RuntimeOrigin::signed(alice), bob, programs_info,), Error::::JumpStartNotCompleted ); }) @@ -294,7 +278,7 @@ fn it_fails_registration_with_too_many_modifiable_keys() { // Test: Run through registration, this should fail assert_noop!( - Registry::register_on_chain(RuntimeOrigin::signed(alice), bob, programs_info,), + Registry::register(RuntimeOrigin::signed(alice), bob, programs_info,), Error::::TooManyModifiableKeys ); }) @@ -481,11 +465,8 @@ fn it_changes_a_program_instance() { version_number: 1, }; - RegisteredOnChain::::insert(expected_verifying_key.clone(), ®istered_info); - assert_eq!( - Registry::registered_on_chain(expected_verifying_key.clone()).unwrap(), - registered_info - ); + Registered::::insert(expected_verifying_key.clone(), ®istered_info); + assert_eq!(Registry::registered(expected_verifying_key.clone()).unwrap(), registered_info); assert_ok!(Registry::change_program_instance( RuntimeOrigin::signed(2), @@ -494,10 +475,7 @@ fn it_changes_a_program_instance() { )); registered_info.programs_data = new_programs_info; - assert_eq!( - Registry::registered_on_chain(expected_verifying_key.clone()).unwrap(), - registered_info - ); + assert_eq!(Registry::registered(expected_verifying_key.clone()).unwrap(), registered_info); assert_eq!( pallet_programs::Programs::::get(program_hash).unwrap().ref_counter, 0, @@ -552,11 +530,8 @@ fn it_changes_a_program_mod_account() { version_number: 1, }; - RegisteredOnChain::::insert(expected_verifying_key.clone(), ®istered_info); - assert_eq!( - Registry::registered_on_chain(expected_verifying_key.clone()).unwrap(), - registered_info - ); + Registered::::insert(expected_verifying_key.clone(), ®istered_info); + assert_eq!(Registry::registered(expected_verifying_key.clone()).unwrap(), registered_info); // Idk why this state could happen but still test to make sure it fails with a noop if ModifiableKeys not set assert_noop!( @@ -588,7 +563,7 @@ fn it_changes_a_program_mod_account() { registered_info.program_modification_account = 3; assert_eq!( - Registry::registered_on_chain(expected_verifying_key.clone()).unwrap(), + Registry::registered(expected_verifying_key.clone()).unwrap(), registered_info, "account 3 now in registered info" ); @@ -605,36 +580,3 @@ fn it_changes_a_program_mod_account() { ); }) } - -#[test] -fn it_fails_on_non_matching_verifying_keys() { - new_test_ext().execute_with(|| { - let empty_program = vec![]; - let program_hash = ::Hashing::hash(&empty_program); - let programs_info = BoundedVec::try_from(vec![ProgramInstance { - program_pointer: program_hash, - program_config: vec![], - }]) - .unwrap(); - - pallet_programs::Programs::::insert( - program_hash, - ProgramInfo { - bytecode: empty_program.clone(), - configuration_schema: empty_program.clone(), - auxiliary_data_schema: empty_program.clone(), - oracle_data_pointer: empty_program.clone(), - deployer: 1, - ref_counter: 0, - }, - ); - - assert_ok!(Registry::register(RuntimeOrigin::signed(1), 2, programs_info.clone(),)); - - // error if they try to submit another request, even with a different program key - assert_noop!( - Registry::register(RuntimeOrigin::signed(1), 2, programs_info), - Error::::AlreadySubmitted - ); - }); -} diff --git a/pallets/registry/src/weights.rs b/pallets/registry/src/weights.rs index 6584f4075..a9862b35e 100644 --- a/pallets/registry/src/weights.rs +++ b/pallets/registry/src/weights.rs @@ -51,8 +51,7 @@ use core::marker::PhantomData; /// Weight functions needed for pallet_registry. pub trait WeightInfo { - fn register(p: u32) -> Weight; - fn register_on_chain(_p: u32) -> Weight; + fn register(_p: u32) -> Weight; fn jump_start_network() -> Weight; fn confirm_jump_start_done(c: u32, ) -> Weight; fn confirm_jump_start_confirm(c: u32, ) -> Weight; @@ -111,39 +110,18 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Registry::Registered` (r:1 w:0) - /// Proof: `Registry::Registered` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Registry::Registering` (r:1 w:1) - /// Proof: `Registry::Registering` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Programs::Programs` (r:1 w:1) - /// Proof: `Programs::Programs` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Registry::Dkg` (r:1 w:1) - /// Proof: `Registry::Dkg` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// The range of component `p` is `[1, 5]`. - fn register(p: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `401` - // Estimated: `3866` - // Minimum execution time: 21_000_000 picoseconds. - Weight::from_parts(19_100_000, 0) - .saturating_add(Weight::from_parts(0, 3866)) - // Standard Error: 134_629 - .saturating_add(Weight::from_parts(2_000_000, 0).saturating_mul(p.into())) - .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(3)) - } /// Storage: `Programs::Programs` (r:1 w:1) /// Proof: `Programs::Programs` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Registry::JumpStartProgress` (r:1 w:0) /// Proof: `Registry::JumpStartProgress` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Registry::CounterForRegisteredOnChain` (r:1 w:1) - /// Proof: `Registry::CounterForRegisteredOnChain` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Registry::RegisteredOnChain` (r:1 w:1) - /// Proof: `Registry::RegisteredOnChain` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Registry::CounterForRegistered` (r:1 w:1) + /// Proof: `Registry::CounterForRegistered` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Registry::Registered` (r:1 w:1) + /// Proof: `Registry::Registered` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Registry::ModifiableKeys` (r:1 w:1) /// Proof: `Registry::ModifiableKeys` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `p` is `[1, 5]`. - fn register_on_chain(_p: u32, ) -> Weight { + fn register(_p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `563` // Estimated: `4028` @@ -239,39 +217,18 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(3)) .saturating_add(RocksDbWeight::get().writes(1)) } - /// Storage: `Registry::Registered` (r:1 w:0) - /// Proof: `Registry::Registered` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Registry::Registering` (r:1 w:1) - /// Proof: `Registry::Registering` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Programs::Programs` (r:1 w:1) - /// Proof: `Programs::Programs` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Registry::Dkg` (r:1 w:1) - /// Proof: `Registry::Dkg` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// The range of component `p` is `[1, 5]`. - fn register(p: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `401` - // Estimated: `3866` - // Minimum execution time: 21_000_000 picoseconds. - Weight::from_parts(19_100_000, 0) - .saturating_add(Weight::from_parts(0, 3866)) - // Standard Error: 134_629 - .saturating_add(Weight::from_parts(2_000_000, 0).saturating_mul(p.into())) - .saturating_add(RocksDbWeight::get().reads(4)) - .saturating_add(RocksDbWeight::get().writes(3)) - } /// Storage: `Programs::Programs` (r:1 w:1) /// Proof: `Programs::Programs` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Registry::JumpStartProgress` (r:1 w:0) /// Proof: `Registry::JumpStartProgress` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Registry::CounterForRegisteredOnChain` (r:1 w:1) - /// Proof: `Registry::CounterForRegisteredOnChain` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Registry::RegisteredOnChain` (r:1 w:1) - /// Proof: `Registry::RegisteredOnChain` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Registry::CounterForRegistered` (r:1 w:1) + /// Proof: `Registry::CounterForRegistered` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Registry::Registered` (r:1 w:1) + /// Proof: `Registry::Registered` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Registry::ModifiableKeys` (r:1 w:1) /// Proof: `Registry::ModifiableKeys` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `p` is `[1, 5]`. - fn register_on_chain(_p: u32, ) -> Weight { + fn register(_p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `563` // Estimated: `4028` diff --git a/runtime/src/weights/pallet_registry.rs b/runtime/src/weights/pallet_registry.rs index 720a5c5a9..bae0793a0 100644 --- a/runtime/src/weights/pallet_registry.rs +++ b/runtime/src/weights/pallet_registry.rs @@ -97,37 +97,18 @@ impl pallet_registry::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Registry::Registering` (r:1 w:1) - /// Proof: `Registry::Registering` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Programs::Programs` (r:1 w:1) - /// Proof: `Programs::Programs` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Registry::Dkg` (r:1 w:1) - /// Proof: `Registry::Dkg` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// The range of component `p` is `[1, 5]`. - fn register(p: u32, ) -> Weight { - // Proof Size summary in bytes: - // Measured: `393` - // Estimated: `3858` - // Minimum execution time: 20_000_000 picoseconds. - Weight::from_parts(18_500_000, 0) - .saturating_add(Weight::from_parts(0, 3858)) - // Standard Error: 362_284 - .saturating_add(Weight::from_parts(2_500_000, 0).saturating_mul(p.into())) - .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(3)) - } /// Storage: `Programs::Programs` (r:1 w:1) /// Proof: `Programs::Programs` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Registry::JumpStartProgress` (r:1 w:0) /// Proof: `Registry::JumpStartProgress` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) - /// Storage: `Registry::CounterForRegisteredOnChain` (r:1 w:1) - /// Proof: `Registry::CounterForRegisteredOnChain` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Registry::RegisteredOnChain` (r:1 w:1) - /// Proof: `Registry::RegisteredOnChain` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// Storage: `Registry::CounterForRegistered` (r:1 w:1) + /// Proof: `Registry::CounterForRegistered` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `Registry::Registered` (r:1 w:1) + /// Proof: `Registry::Registered` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Registry::ModifiableKeys` (r:1 w:1) /// Proof: `Registry::ModifiableKeys` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `p` is `[1, 5]`. - fn register_on_chain(_p: u32, ) -> Weight { + fn register(_p: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `563` // Estimated: `4028`