From 314f6be467a2d3fa5b58f7723d27e1554b6d32bb Mon Sep 17 00:00:00 2001 From: Hernando Castano Date: Wed, 14 Aug 2024 16:43:19 -0400 Subject: [PATCH] Add `network-jumpstart` command to `entropy-test-cli` (#1004) * Add `network-jumpstart` subcommand to `entropy-test-cli` This PR adds a way to trigger a network jumpstart from the test CLI. This is useful for ensuring the network is in the correct state before registering using the new registration flow. * Add `CHANGELOG` entry * Add 45 second timeout when checking for jumpstarts --- CHANGELOG.md | 1 + crates/client/Cargo.toml | 2 +- crates/client/src/client.rs | 40 +++++++++++++++++++++++++++++++++++++ crates/client/src/errors.rs | 2 ++ crates/test-cli/src/lib.rs | 29 +++++++++++++++++++++++++-- 5 files changed, 71 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 76bbd0b2a..6b1d5542b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ At the moment this project **does not** adhere to - Set inital signers ([#971](https://github.com/entropyxyz/entropy-core/pull/971)) - Add parent key threshold dynamically ([#974](https://github.com/entropyxyz/entropy-core/pull/974)) - TSS attestation endpoint ([#1001](https://github.com/entropyxyz/entropy-core/pull/1001)) +- Add `network-jumpstart` command to `entropy-test-cli` ([#1004](https://github.com/entropyxyz/entropy-core/pull/1004)) ### Changed - Fix TSS `AccountId` keys in chainspec ([#993](https://github.com/entropyxyz/entropy-core/pull/993)) diff --git a/crates/client/Cargo.toml b/crates/client/Cargo.toml index 8f2755ca4..62fea585e 100644 --- a/crates/client/Cargo.toml +++ b/crates/client/Cargo.toml @@ -33,7 +33,7 @@ anyhow ="1.0.86" # Only for the browser js-sys={ version="0.3.70", optional=true } -tokio ="1.39" +tokio ={ version="1.39", features=["time"] } [dev-dependencies] serial_test ="3.1.1" diff --git a/crates/client/src/client.rs b/crates/client/src/client.rs index 4fc87744c..c0559d8b7 100644 --- a/crates/client/src/client.rs +++ b/crates/client/src/client.rs @@ -360,3 +360,43 @@ pub async fn change_threshold_accounts( .ok_or(anyhow!("Error with transaction"))?; Ok(result_event) } + +/// Trigger a network wide distributed key generation (DKG) event. +/// +/// Fails if the network has already been jumpstarted. +pub async fn jumpstart_network( + api: &OnlineClient, + rpc: &LegacyRpcMethods, + signer: sr25519::Pair, +) -> Result<(), ClientError> { + // We split the implementation out into an inner function so that we can more easily pass a + // single future to the `timeout` + tokio::time::timeout(std::time::Duration::from_secs(45), jumpstart_inner(api, rpc, signer)) + .await + .map_err(|_| ClientError::JumpstartTimeout)? +} + +async fn jumpstart_inner( + api: &OnlineClient, + rpc: &LegacyRpcMethods, + signer: sr25519::Pair, +) -> Result<(), ClientError> { + // In this case we don't care too much about the result because we're more interested in the + // `FinishedNetworkJumpStart` event, which happens later on. + let jump_start_request = entropy::tx().registry().jump_start_network(); + let _result = + submit_transaction_with_pair(api, rpc, &signer, &jump_start_request, None).await?; + + let mut blocks_sub = api.blocks().subscribe_finalized().await?; + + while let Some(block) = blocks_sub.next().await { + let block = block?; + let events = block.events().await?; + + if events.has::()? { + break; + } + } + + Ok(()) +} diff --git a/crates/client/src/errors.rs b/crates/client/src/errors.rs index 86e1000e9..012bf2d87 100644 --- a/crates/client/src/errors.rs +++ b/crates/client/src/errors.rs @@ -66,6 +66,8 @@ pub enum ClientError { Subxt(#[from] subxt::Error), #[error("Timed out waiting for register confirmation")] RegistrationTimeout, + #[error("Timed out waiting for jumpstart confirmation")] + JumpstartTimeout, #[error("Cannot get subgroup: {0}")] SubgroupGet(#[from] SubgroupGetError), #[error("JSON: {0}")] diff --git a/crates/test-cli/src/lib.rs b/crates/test-cli/src/lib.rs index 2f36ee1de..6af8292da 100644 --- a/crates/test-cli/src/lib.rs +++ b/crates/test-cli/src/lib.rs @@ -26,7 +26,7 @@ use entropy_client::{ }, client::{ change_endpoint, change_threshold_accounts, get_accounts, get_api, get_programs, get_rpc, - register, sign, store_program, update_programs, VERIFYING_KEY_LENGTH, + jumpstart_network, register, sign, store_program, update_programs, VERIFYING_KEY_LENGTH, }, }; use sp_core::{sr25519, Hasher, Pair}; @@ -76,7 +76,7 @@ enum CliCommand { /// A name or mnemonic from which to derive a program modification keypair. /// This is used to send the register extrinsic so it must be funded /// If giving a name it must be preceded with "//", eg: "--mnemonic-option //Alice" - /// If giving a mnemonic it must be enclosed in quotes, eg: "--mnemonic-option "alarm mutual concert..."" + /// If giving a mnemonic it must be enclosed in quotes, eg: "--mnemonic-option "alarm mutual concert..."" #[arg(short, long)] mnemonic_option: Option, }, @@ -143,6 +143,17 @@ enum CliCommand { }, /// Display a list of registered Entropy accounts Status, + /// Triggers the network wide distributed key generation process. + /// + /// A fully jumpstarted network is required for the on-chain registration flow to work + /// correctly. + /// + /// Note: Any account may trigger the jumpstart process. + JumpstartNetwork { + /// The mnemonic for the signer which will trigger the jumpstart process. + #[arg(short, long)] + mnemonic_option: Option, + }, } pub async fn run_command( @@ -392,6 +403,20 @@ pub async fn run_command( Ok("Threshold accounts changed".to_string()) }, + CliCommand::JumpstartNetwork { mnemonic_option } => { + let mnemonic = if let Some(mnemonic_option) = mnemonic_option { + mnemonic_option + } else { + passed_mnemonic.unwrap_or("//Alice".to_string()) + }; + + let signer = ::from_string(&mnemonic, None)?; + println!("Account being used for jumpstart: {}", signer.public()); + + jumpstart_network(&api, &rpc, signer).await?; + + Ok("Succesfully jumpstarted network.".to_string()) + }, } }