mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 21:01:02 +00:00
CLI: Derive Account (#860)
* Move derive account. * Fix account derivation.
This commit is contained in:
committed by
Bastian Köcher
parent
da3f94d99f
commit
0d7291d729
@@ -0,0 +1,135 @@
|
|||||||
|
// Copyright 2019-2021 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity Bridges Common.
|
||||||
|
|
||||||
|
// Parity Bridges Common is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity Bridges Common 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 General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use crate::cli::AccountId;
|
||||||
|
use relay_substrate_client::Chain;
|
||||||
|
use structopt::{clap::arg_enum, StructOpt};
|
||||||
|
|
||||||
|
/// Given a source chain `AccountId`, derive the corresponding `AccountId` for the target chain.
|
||||||
|
///
|
||||||
|
/// The (derived) target chain `AccountId` is going to be used as dispatch origin of the call
|
||||||
|
/// that has been sent over the bridge.
|
||||||
|
/// This account can also be used to receive target-chain funds (or other form of ownership),
|
||||||
|
/// since messages sent over the bridge will be able to spend these.
|
||||||
|
#[derive(StructOpt)]
|
||||||
|
pub struct DeriveAccount {
|
||||||
|
/// A bridge instance to initalize.
|
||||||
|
#[structopt(possible_values = &DeriveAccountBridge::variants(), case_insensitive = true)]
|
||||||
|
bridge: DeriveAccountBridge,
|
||||||
|
/// Source-chain address to derive Target-chain address from.
|
||||||
|
account: AccountId,
|
||||||
|
}
|
||||||
|
|
||||||
|
arg_enum! {
|
||||||
|
#[derive(Debug)]
|
||||||
|
/// Bridge to derive account for.
|
||||||
|
pub enum DeriveAccountBridge {
|
||||||
|
MillauToRialto,
|
||||||
|
RialtoToMillau,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! select_bridge {
|
||||||
|
($bridge: expr, $generic: tt) => {
|
||||||
|
match $bridge {
|
||||||
|
DeriveAccountBridge::MillauToRialto => {
|
||||||
|
type Source = relay_millau_client::Millau;
|
||||||
|
type Target = relay_rialto_client::Rialto;
|
||||||
|
|
||||||
|
#[allow(unused_imports)] // the import is not used in `run`
|
||||||
|
use bp_millau::derive_account_from_rialto_id as derive_account;
|
||||||
|
|
||||||
|
$generic
|
||||||
|
}
|
||||||
|
DeriveAccountBridge::RialtoToMillau => {
|
||||||
|
type Source = relay_rialto_client::Rialto;
|
||||||
|
type Target = relay_millau_client::Millau;
|
||||||
|
|
||||||
|
#[allow(unused_imports)] // the import is not used in `run`.
|
||||||
|
use bp_rialto::derive_account_from_millau_id as derive_account;
|
||||||
|
|
||||||
|
$generic
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DeriveAccount {
|
||||||
|
/// Parse CLI arguments and derive account.
|
||||||
|
///
|
||||||
|
/// Returns both the Source account in correct SS58 format and the derived account.
|
||||||
|
fn derive_account(&self) -> (AccountId, AccountId) {
|
||||||
|
select_bridge!(self.bridge, {
|
||||||
|
let mut account = self.account.clone();
|
||||||
|
account.enforce_chain::<Source>();
|
||||||
|
let acc = bp_runtime::SourceAccount::Account(account.raw_id());
|
||||||
|
let id = derive_account(acc);
|
||||||
|
let derived_account = AccountId::from_raw::<Target>(id);
|
||||||
|
(account, derived_account)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Run the command.
|
||||||
|
pub async fn run(self) -> anyhow::Result<()> {
|
||||||
|
select_bridge!(self.bridge, {
|
||||||
|
let (account, derived_account) = self.derive_account();
|
||||||
|
println!("Source address:\n{} ({})", account, Source::NAME);
|
||||||
|
println!(
|
||||||
|
"->Corresponding (derived) address:\n{} ({})",
|
||||||
|
derived_account,
|
||||||
|
Target::NAME,
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
fn derive_account_cli(bridge: &str, account: &str) -> (AccountId, AccountId) {
|
||||||
|
DeriveAccount::from_iter(vec!["derive-account", bridge, account]).derive_account()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_derive_accounts_correctly() {
|
||||||
|
// given
|
||||||
|
let rialto = "5sauUXUfPjmwxSgmb3tZ5d6yx24eZX4wWJ2JtVUBaQqFbvEU";
|
||||||
|
let millau = "752paRyW1EGfq9YLTSSqcSJ5hqnBDidBmaftGhBo8fy6ypW9";
|
||||||
|
|
||||||
|
// when
|
||||||
|
let (rialto_parsed, rialto_derived) = derive_account_cli("RialtoToMillau", rialto);
|
||||||
|
let (millau_parsed, millau_derived) = derive_account_cli("MillauToRialto", millau);
|
||||||
|
let (millau2_parsed, millau2_derived) = derive_account_cli("MillauToRialto", rialto);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assert_eq!(format!("{}", rialto_parsed), rialto);
|
||||||
|
assert_eq!(format!("{}", millau_parsed), millau);
|
||||||
|
assert_eq!(format!("{}", millau2_parsed), millau);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
format!("{}", rialto_derived),
|
||||||
|
"73gLnUwrAdH4vMjbXCiNEpgyz1PLk9JxCaY4cKzvfSZT73KE"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
format!("{}", millau_derived),
|
||||||
|
"5rpTJqGv1BPAYy2sXzkPpc3Wx1ZpQtgfuBsrDpNV4HsXAmbi"
|
||||||
|
);
|
||||||
|
assert_eq!(millau_derived, millau2_derived);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,6 +25,7 @@ use frame_support::weights::Weight;
|
|||||||
use sp_runtime::app_crypto::Ss58Codec;
|
use sp_runtime::app_crypto::Ss58Codec;
|
||||||
use structopt::{clap::arg_enum, StructOpt};
|
use structopt::{clap::arg_enum, StructOpt};
|
||||||
|
|
||||||
|
mod derive_account;
|
||||||
mod init_bridge;
|
mod init_bridge;
|
||||||
mod relay_headers;
|
mod relay_headers;
|
||||||
mod relay_messages;
|
mod relay_messages;
|
||||||
@@ -71,7 +72,7 @@ pub enum Command {
|
|||||||
/// Estimate Delivery and Dispatch Fee required for message submission to messages pallet.
|
/// Estimate Delivery and Dispatch Fee required for message submission to messages pallet.
|
||||||
EstimateFee(EstimateFee),
|
EstimateFee(EstimateFee),
|
||||||
/// Given a source chain `AccountId`, derive the corresponding `AccountId` for the target chain.
|
/// Given a source chain `AccountId`, derive the corresponding `AccountId` for the target chain.
|
||||||
DeriveAccount(DeriveAccount),
|
DeriveAccount(derive_account::DeriveAccount),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Command {
|
impl Command {
|
||||||
@@ -159,28 +160,6 @@ impl EstimateFee {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given a source chain `AccountId`, derive the corresponding `AccountId` for the target chain.
|
|
||||||
///
|
|
||||||
/// The (derived) target chain `AccountId` is going to be used as dispatch origin of the call
|
|
||||||
/// that has been sent over the bridge.
|
|
||||||
/// This account can also be used to receive target-chain funds (or other form of ownership),
|
|
||||||
/// since messages sent over the bridge will be able to spend these.
|
|
||||||
#[derive(StructOpt)]
|
|
||||||
pub enum DeriveAccount {
|
|
||||||
#[structopt(flatten)]
|
|
||||||
RialtoMillau(rialto_millau::DeriveAccount),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DeriveAccount {
|
|
||||||
/// Run the command.
|
|
||||||
pub async fn run(self) -> anyhow::Result<()> {
|
|
||||||
match self {
|
|
||||||
Self::RialtoMillau(arg) => arg.run().await?,
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
arg_enum! {
|
arg_enum! {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
/// The origin to use when dispatching the message on the target chain.
|
/// The origin to use when dispatching the message on the target chain.
|
||||||
@@ -213,7 +192,7 @@ impl Balance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Generic account id with custom parser.
|
/// Generic account id with custom parser.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct AccountId {
|
pub struct AccountId {
|
||||||
account: sp_runtime::AccountId32,
|
account: sp_runtime::AccountId32,
|
||||||
ss58_format: sp_core::crypto::Ss58AddressFormat,
|
ss58_format: sp_core::crypto::Ss58AddressFormat,
|
||||||
|
|||||||
@@ -176,30 +176,6 @@ impl EstimateFee {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given a source chain `AccountId`, derive the corresponding `AccountId` for the target chain.
|
|
||||||
///
|
|
||||||
/// The (derived) target chain `AccountId` is going to be used as dispatch origin of the call
|
|
||||||
/// that has been sent over the bridge.
|
|
||||||
/// This account can also be used to receive target-chain funds (or other form of ownership),
|
|
||||||
/// since messages sent over the bridge will be able to spend these.
|
|
||||||
///
|
|
||||||
/// TODO [#855] Move to separate module.
|
|
||||||
#[derive(StructOpt)]
|
|
||||||
pub enum DeriveAccount {
|
|
||||||
/// Given Rialto AccountId, display corresponding Millau AccountId.
|
|
||||||
RialtoToMillau { account: AccountId },
|
|
||||||
/// Given Millau AccountId, display corresponding Rialto AccountId.
|
|
||||||
MillauToRialto { account: AccountId },
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DeriveAccount {
|
|
||||||
/// Run the command.
|
|
||||||
pub async fn run(self) -> anyhow::Result<()> {
|
|
||||||
super::run_derive_account(self).await.map_err(format_err)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn format_err(err: String) -> anyhow::Error {
|
fn format_err(err: String) -> anyhow::Error {
|
||||||
anyhow::anyhow!(err)
|
anyhow::anyhow!(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ pub type MillauClient = relay_substrate_client::Client<Millau>;
|
|||||||
pub type RialtoClient = relay_substrate_client::Client<Rialto>;
|
pub type RialtoClient = relay_substrate_client::Client<Rialto>;
|
||||||
|
|
||||||
use crate::cli::{
|
use crate::cli::{
|
||||||
AccountId, CliChain, ExplicitOrMaximal, HexBytes, Origins, SourceConnectionParams, SourceSigningParams,
|
CliChain, ExplicitOrMaximal, HexBytes, Origins, SourceConnectionParams, SourceSigningParams,
|
||||||
TargetConnectionParams, TargetSigningParams,
|
TargetConnectionParams, TargetSigningParams,
|
||||||
};
|
};
|
||||||
use codec::{Decode, Encode};
|
use codec::{Decode, Encode};
|
||||||
@@ -337,43 +337,6 @@ async fn run_estimate_fee(cmd: cli::EstimateFee) -> Result<(), String> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run_derive_account(cmd: cli::DeriveAccount) -> Result<(), String> {
|
|
||||||
match cmd {
|
|
||||||
cli::DeriveAccount::RialtoToMillau { mut account } => {
|
|
||||||
type Source = Rialto;
|
|
||||||
type Target = Millau;
|
|
||||||
|
|
||||||
account.enforce_chain::<Source>();
|
|
||||||
let acc = bp_runtime::SourceAccount::Account(account.raw_id());
|
|
||||||
let id = bp_millau::derive_account_from_rialto_id(acc);
|
|
||||||
let derived_account = AccountId::from_raw::<Target>(id);
|
|
||||||
println!("Source address:\n{} ({})", account, Source::NAME);
|
|
||||||
println!(
|
|
||||||
"->Corresponding (derived) address:\n{} ({})",
|
|
||||||
derived_account,
|
|
||||||
Target::NAME,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
cli::DeriveAccount::MillauToRialto { mut account } => {
|
|
||||||
type Source = Millau;
|
|
||||||
type Target = Rialto;
|
|
||||||
|
|
||||||
account.enforce_chain::<Source>();
|
|
||||||
let acc = bp_runtime::SourceAccount::Account(account.raw_id());
|
|
||||||
let id = bp_rialto::derive_account_from_millau_id(acc);
|
|
||||||
let derived_account = AccountId::from_raw::<Target>(id);
|
|
||||||
println!("Source address:\n{} ({})", account, Source::NAME);
|
|
||||||
println!(
|
|
||||||
"->Corresponding (derived) address:\n{} ({})",
|
|
||||||
derived_account,
|
|
||||||
Target::NAME,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn estimate_message_delivery_and_dispatch_fee<Fee: Decode, C: Chain, P: Encode>(
|
async fn estimate_message_delivery_and_dispatch_fee<Fee: Decode, C: Chain, P: Encode>(
|
||||||
client: &relay_substrate_client::Client<C>,
|
client: &relay_substrate_client::Client<C>,
|
||||||
estimate_fee_method: &str,
|
estimate_fee_method: &str,
|
||||||
@@ -864,25 +827,4 @@ mod tests {
|
|||||||
extra_bytes_in_transaction,
|
extra_bytes_in_transaction,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn should_reformat_addresses() {
|
|
||||||
// given
|
|
||||||
let mut rialto1: AccountId = "5sauUXUfPjmwxSgmb3tZ5d6yx24eZX4wWJ2JtVUBaQqFbvEU".parse().unwrap();
|
|
||||||
let mut millau1: AccountId = "752paRyW1EGfq9YLTSSqcSJ5hqnBDidBmaftGhBo8fy6ypW9".parse().unwrap();
|
|
||||||
|
|
||||||
// when
|
|
||||||
rialto1.enforce_chain::<Millau>();
|
|
||||||
millau1.enforce_chain::<Rialto>();
|
|
||||||
|
|
||||||
// then
|
|
||||||
assert_eq!(
|
|
||||||
&format!("{}", rialto1),
|
|
||||||
"752paRyW1EGfq9YLTSSqcSJ5hqnBDidBmaftGhBo8fy6ypW9"
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
&format!("{}", millau1),
|
|
||||||
"5sauUXUfPjmwxSgmb3tZ5d6yx24eZX4wWJ2JtVUBaQqFbvEU"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user