-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add validator helpers to cli #870
Changes from all commits
949e1a4
db3ed74
37ccd21
a2ef735
078218c
9a3e13d
6314187
bf7b9aa
6978756
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
use crate::{ | ||
chain_api::{ | ||
entropy::{ | ||
runtime_types::pallet_staking_extension::pallet::ServerInfo, staking_extension::events, | ||
}, | ||
get_api, get_rpc, | ||
}, | ||
change_endpoint, change_threshold_accounts, | ||
}; | ||
use entropy_testing_utils::substrate_context::test_context_stationary; | ||
use serial_test::serial; | ||
use sp_core::Pair; | ||
use sp_keyring::AccountKeyring; | ||
use subxt::utils::AccountId32; | ||
|
||
#[tokio::test] | ||
#[serial] | ||
async fn test_change_endpoint() { | ||
let one = AccountKeyring::AliceStash; | ||
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 result = change_endpoint(&api, &rpc, one.into(), "new_endpoint".to_string()).await.unwrap(); | ||
assert_eq!( | ||
format!("{:?}", result), | ||
format!( | ||
"{:?}", | ||
events::EndpointChanged( | ||
AccountId32(one.pair().public().0), | ||
"new_endpoint".as_bytes().to_vec() | ||
) | ||
) | ||
); | ||
} | ||
|
||
#[tokio::test] | ||
#[serial] | ||
async fn test_change_threhsold_accounts() { | ||
let one = AccountKeyring::AliceStash; | ||
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 x25519_public_key = [0u8; 32]; | ||
let result = change_threshold_accounts( | ||
&api, | ||
&rpc, | ||
one.into(), | ||
AccountId32(one.pair().public().0.into()).to_string(), | ||
hex::encode(x25519_public_key), | ||
) | ||
.await | ||
.unwrap(); | ||
assert_eq!( | ||
format!("{:?}", result), | ||
format!( | ||
"{:?}", | ||
events::ThresholdAccountChanged( | ||
AccountId32(one.pair().public().0), | ||
ServerInfo { | ||
tss_account: AccountId32(one.pair().public().0), | ||
x25519_public_key, | ||
endpoint: "127.0.0.1:3001".as_bytes().to_vec() | ||
} | ||
) | ||
) | ||
); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,12 +14,6 @@ | |
// along with this program. If not, see <https://www.gnu.org/licenses/>. | ||
|
||
//! Simple CLI to test registering, updating programs and signing | ||
use std::{ | ||
fmt::{self, Display}, | ||
fs, | ||
path::PathBuf, | ||
}; | ||
|
||
use anyhow::{anyhow, ensure}; | ||
use clap::{Parser, Subcommand}; | ||
use colored::Colorize; | ||
|
@@ -31,12 +25,18 @@ use entropy_client::{ | |
EntropyConfig, | ||
}, | ||
client::{ | ||
get_accounts, get_api, get_programs, get_rpc, register, sign, store_program, | ||
update_programs, KeyParams, KeyShare, KeyVisibility, VERIFYING_KEY_LENGTH, | ||
change_endpoint, change_threshold_accounts, get_accounts, get_api, get_programs, get_rpc, | ||
register, sign, store_program, update_programs, KeyParams, KeyShare, KeyVisibility, | ||
VERIFYING_KEY_LENGTH, | ||
}, | ||
}; | ||
use sp_core::{sr25519, DeriveJunction, Hasher, Pair}; | ||
use sp_runtime::traits::BlakeTwo256; | ||
use std::{ | ||
fmt::{self, Display}, | ||
fs, | ||
path::PathBuf, | ||
}; | ||
use subxt::{ | ||
backend::legacy::LegacyRpcMethods, | ||
utils::{AccountId32 as SubxtAccountId32, H256}, | ||
|
@@ -82,10 +82,10 @@ enum CliCommand { | |
/// interface. If no such file exists, it is assumed the program has no configuration | ||
/// interface. | ||
programs: Vec<String>, | ||
/// A name from which to generate a program modification keypair, eg: "Bob" | ||
/// This is used to send the register extrinsic and so it must be funded | ||
/// | ||
/// Optionally may be preceeded with "//" eg: "//Bob" | ||
/// 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..."" | ||
#[arg(short, long)] | ||
mnemonic_option: Option<String>, | ||
}, | ||
|
@@ -97,11 +97,7 @@ enum CliCommand { | |
message: String, | ||
/// Optional auxiliary data passed to the program, given as hex | ||
auxilary_data: Option<String>, | ||
/// A name from which to generate a keypair, eg: "Alice" | ||
/// This is only needed when using private mode. | ||
/// | ||
/// Optionally may be preceeded with "//", eg: "//Alice" | ||
#[arg(short, long)] | ||
/// The mnemonic to use for the call | ||
mnemonic_option: Option<String>, | ||
}, | ||
/// Update the program for a particular account | ||
|
@@ -120,9 +116,7 @@ enum CliCommand { | |
/// interface. If no such file exists, it is assumed the program has no configuration | ||
/// interface. | ||
programs: Vec<String>, | ||
/// A name from which to generate a program modification keypair, eg: "Bob" | ||
/// | ||
/// Optionally may be preceeded with "//", eg: "//Bob" | ||
/// The mnemonic to use for the call | ||
#[arg(short, long)] | ||
mnemonic_option: Option<String>, | ||
}, | ||
|
@@ -134,9 +128,25 @@ enum CliCommand { | |
config_interface_file: Option<PathBuf>, | ||
/// The path to a file containing the program aux interface (defaults to empty) | ||
aux_data_interface_file: Option<PathBuf>, | ||
/// A name from which to generate a keypair, eg: "Alice" | ||
/// | ||
/// Optionally may be preceeded with "//", eg: "//Alice" | ||
/// The mnemonic to use for the call | ||
#[arg(short, long)] | ||
mnemonic_option: Option<String>, | ||
}, | ||
/// Allows a validator to change their endpoint | ||
ChangeEndpoint { | ||
/// New endpoint to change to (ex. "127.0.0.1:3001") | ||
new_endpoint: String, | ||
/// The mnemonic for the validator stash account to use for the call, should be stash address | ||
#[arg(short, long)] | ||
mnemonic_option: Option<String>, | ||
}, | ||
/// Allows a validator to change their threshold accounts | ||
ChangeThresholdAccounts { | ||
/// New threshold account | ||
new_tss_account: String, | ||
/// New x25519 public key | ||
new_x25519_public_key: String, | ||
/// The mnemonic for the validator stash account to use for the call, should be stash address | ||
#[arg(short, long)] | ||
mnemonic_option: Option<String>, | ||
}, | ||
|
@@ -241,7 +251,7 @@ pub async fn run_command( | |
// If an account name is not provided, use the Alice key | ||
let user_keypair = <sr25519::Pair as Pair>::from_string(&mnemonic, None)?; | ||
|
||
println!("User account: {}", user_keypair.public()); | ||
println!("User account for current call: {}", user_keypair.public()); | ||
|
||
let auxilary_data = | ||
if let Some(data) = auxilary_data { Some(hex::decode(data)?) } else { None }; | ||
|
@@ -404,6 +414,45 @@ pub async fn run_command( | |
|
||
Ok("Got status".to_string()) | ||
}, | ||
CliCommand::ChangeEndpoint { new_endpoint, mnemonic_option } => { | ||
let mnemonic = if let Some(mnemonic_option) = mnemonic_option { | ||
mnemonic_option | ||
} else { | ||
passed_mnemonic.expect("No Mnemonic set") | ||
}; | ||
|
||
let user_keypair = <sr25519::Pair as Pair>::from_string(&mnemonic, None)?; | ||
println!("User account for current call: {}", user_keypair.public()); | ||
|
||
let result_event = change_endpoint(&api, &rpc, user_keypair, new_endpoint).await?; | ||
println!("Event result: {:?}", result_event); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd be a bit more specific with what we're printing here There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. well this one returns an event that is pretty descriptive and has the extra data needed |
||
Ok("Endpoint changed".to_string()) | ||
}, | ||
CliCommand::ChangeThresholdAccounts { | ||
new_tss_account, | ||
new_x25519_public_key, | ||
mnemonic_option, | ||
} => { | ||
let mnemonic = if let Some(mnemonic_option) = mnemonic_option { | ||
mnemonic_option | ||
} else { | ||
passed_mnemonic.expect("No Mnemonic set") | ||
}; | ||
let user_keypair = <sr25519::Pair as Pair>::from_string(&mnemonic, None)?; | ||
println!("User account for current call: {}", user_keypair.public()); | ||
|
||
let result_event = change_threshold_accounts( | ||
&api, | ||
&rpc, | ||
user_keypair, | ||
new_tss_account, | ||
new_x25519_public_key, | ||
) | ||
.await?; | ||
println!("Event result: {:?}", result_event); | ||
|
||
Ok("Threshold accounts changed".to_string()) | ||
}, | ||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I already said with the other ones, i think
--mnemonic-option
is not a good name for this argument. In the context of this CLI this a mandatory argument. If they don't give it the command will not work.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So we shouldn't even have this as an
Option
then, eh?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no it will work if the mnemonic is in the environment, a mnemonic is needed but it is not needed to be passed in
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah ok yeah you are right.