From 01b2b53b4cfa4fd8cfd8caf4fdbb84d65f20d7a6 Mon Sep 17 00:00:00 2001 From: Alistair Singh Date: Tue, 21 Jan 2025 00:34:52 +0200 Subject: [PATCH] Add register ether command to control tool (#1361) * command boilerplate * initial commit * asset metadata * comments * make parameters default * changed default symbol * add governance update 2025 --- control/preimage/src/commands.rs | 72 ++++++++++++++++++-- control/preimage/src/main.rs | 110 +++++++++++++++++++++++++------ 2 files changed, 155 insertions(+), 27 deletions(-) diff --git a/control/preimage/src/commands.rs b/control/preimage/src/commands.rs index 7bd2f2fc8a..2e8c81613d 100644 --- a/control/preimage/src/commands.rs +++ b/control/preimage/src/commands.rs @@ -1,7 +1,7 @@ use crate::helpers::calculate_delivery_fee; use crate::{ constants::*, Context, ForceCheckpointArgs, GatewayAddressArgs, GatewayOperatingModeEnum, - OperatingModeEnum, PricingParametersArgs, UpdateAssetArgs, UpgradeArgs, + OperatingModeEnum, PricingParametersArgs, RegisterEtherArgs, UpdateAssetArgs, UpgradeArgs, }; use alloy_primitives::{utils::format_units, U256}; use codec::Encode; @@ -31,9 +31,18 @@ use crate::bridge_hub_runtime::RuntimeCall as BridgeHubRuntimeCall; #[cfg(feature = "polkadot")] pub mod asset_hub_polkadot_types { pub use crate::asset_hub_runtime::runtime_types::staging_xcm::v4::{ - junction::Junction::AccountKey20, junction::Junction::GlobalConsensus, junction::NetworkId, - junctions::Junctions::X2, location::Location, + junction::Junction::AccountKey20, + junction::Junction::GlobalConsensus, + junction::NetworkId, + junctions::Junctions::{X1, X2}, + location::Location, }; + pub fn get_ether_id(chain_id: u64) -> Location { + return Location { + parents: 2, + interior: X1([GlobalConsensus(NetworkId::Ethereum { chain_id })]), + }; + } pub fn get_asset_id(chain_id: u64, key: [u8; 20]) -> Location { return Location { parents: 2, @@ -49,9 +58,17 @@ pub mod asset_hub_polkadot_types { pub mod asset_hub_paseo_types { pub use crate::asset_hub_runtime::runtime_types::staging_xcm::v3::multilocation::MultiLocation; pub use crate::asset_hub_runtime::runtime_types::xcm::v3::{ - junction::Junction::AccountKey20, junction::Junction::GlobalConsensus, junction::NetworkId, - junctions::Junctions::X2, + junction::Junction::AccountKey20, + junction::Junction::GlobalConsensus, + junction::NetworkId, + junctions::Junctions::{X1, X2}, }; + pub fn get_ether_id(chain_id: u64) -> MultiLocation { + return MultiLocation { + parents: 2, + interior: X1(GlobalConsensus(NetworkId::Ethereum { chain_id })), + }; + } pub fn get_asset_id(chain_id: u64, key: [u8; 20]) -> MultiLocation { return MultiLocation { parents: 2, @@ -66,9 +83,18 @@ pub mod asset_hub_paseo_types { #[cfg(feature = "westend")] pub mod asset_hub_westend_types { pub use crate::asset_hub_runtime::runtime_types::staging_xcm::v5::{ - junction::Junction::AccountKey20, junction::Junction::GlobalConsensus, junction::NetworkId, - junctions::Junctions::X2, location::Location, + junction::Junction::AccountKey20, + junction::Junction::GlobalConsensus, + junction::NetworkId, + junctions::Junctions::{X1, X2}, + location::Location, }; + pub fn get_ether_id(chain_id: u64) -> Location { + return Location { + parents: 2, + interior: X1([GlobalConsensus(NetworkId::Ethereum { chain_id })]), + }; + } pub fn get_asset_id(chain_id: u64, key: [u8; 20]) -> Location { return Location { parents: 2, @@ -309,3 +335,35 @@ pub fn force_set_metadata(params: &UpdateAssetArgs) -> AssetHubRuntimeCall { is_frozen: params.is_frozen, }) } + +pub fn register_ether(params: &RegisterEtherArgs) -> (AssetHubRuntimeCall, AssetHubRuntimeCall) { + use subxt::utils::AccountId32; + let chain_id = crate::bridge_hub_runtime::CHAIN_ID; + #[cfg(feature = "paseo")] + use asset_hub_paseo_types::*; + #[cfg(feature = "polkadot")] + use asset_hub_polkadot_types::*; + #[cfg(feature = "westend")] + use asset_hub_westend_types::*; + + let asset_id = get_ether_id(chain_id); + let owner = GlobalConsensusEthereumConvertsFor::<[u8; 32]>::from_chain_id(&chain_id); + + let force_register = + AssetHubRuntimeCall::ForeignAssets(pallet_assets::pallet::Call2::force_create { + id: asset_id.clone(), + min_balance: params.ether_min_balance, + is_sufficient: true, + owner: MultiAddress::::Id(owner.into()), + }); + let metadata = + AssetHubRuntimeCall::ForeignAssets(pallet_assets::pallet::Call2::force_set_metadata { + id: asset_id, + name: params.ether_name.as_bytes().to_vec(), + symbol: params.ether_symbol.as_bytes().to_vec(), + decimals: params.ether_decimals, + is_frozen: false, + }); + + return (force_register, metadata); +} diff --git a/control/preimage/src/main.rs b/control/preimage/src/main.rs index a70e24d12a..7b1333a52f 100644 --- a/control/preimage/src/main.rs +++ b/control/preimage/src/main.rs @@ -27,6 +27,11 @@ struct Cli { #[arg(long, value_enum, default_value_t=Format::Hex)] format: Format, + /// Wrap preimage in a sudo call + #[cfg(any(feature = "westend", feature = "paseo"))] + #[arg(long, default_value_t = false)] + sudo: bool, + #[command(flatten)] api_endpoints: ApiEndpoints, @@ -50,9 +55,14 @@ pub enum Command { ForceCheckpoint(ForceCheckpointArgs), /// Set the checkpoint for the beacon light client HaltBridge(HaltBridgeArgs), + /// Register Ether + RegisterEther(RegisterEtherArgs), /// Treasury proposal TreasuryProposal2024(TreasuryProposal2024Args), + /// Governance update 202501 + GovUpdate202501(GovUpdate202501Args), } + #[derive(Debug, Args)] pub struct InitializeArgs { #[command(flatten)] @@ -63,6 +73,8 @@ pub struct InitializeArgs { force_checkpoint: ForceCheckpointArgs, #[command(flatten)] gateway_address: GatewayAddressArgs, + #[command(flatten)] + register_ether: RegisterEtherArgs, } #[derive(Debug, Args)] @@ -210,6 +222,30 @@ pub struct TreasuryProposal2024Args { beneficiary: FixedBytes<32>, } +#[derive(Debug, Args)] +pub struct GovUpdate202501Args { + #[command(flatten)] + pricing_parameters: PricingParametersArgs, + #[command(flatten)] + register_ether: RegisterEtherArgs, +} + +#[derive(Debug, Args)] +pub struct RegisterEtherArgs { + /// The minimum balance of the Ether asset that users are allowed to hold + #[arg(long, value_name = "WEI", default_value_t = 1u128)] + ether_min_balance: u128, + /// The Ether asset display name + #[arg(long, value_name = "ASSET_DISPLAY_NAME", default_value_t = String::from("Ether"))] + ether_name: String, + /// The Ether asset symbol + #[arg(long, value_name = "ASSET_SYMBOL", default_value_t = String::from("ETH"))] + ether_symbol: String, + /// The Ether asset's number of decimal places + #[arg(long, value_name = "DECIMALS", default_value_t = 18u8)] + ether_decimals: u8, +} + #[derive(Debug, Args)] pub struct ApiEndpoints { #[arg(long, value_name = "URL")] @@ -312,7 +348,7 @@ async fn run() -> Result<(), Box> { Command::Initialize(params) => { let (set_pricing_parameters, set_ethereum_fee) = commands::pricing_parameters(&context, ¶ms.pricing_parameters).await?; - let call1 = send_xcm_bridge_hub( + let bridge_hub_call = send_xcm_bridge_hub( &context, vec![ commands::set_gateway_address(¶ms.gateway_address), @@ -324,29 +360,29 @@ async fn run() -> Result<(), Box> { ], ) .await?; - let call2 = - send_xcm_asset_hub(&context, vec![force_xcm_version(), set_ethereum_fee]).await?; - #[cfg(any(feature = "westend", feature = "paseo"))] - let final_call = sudo(Box::new(utility_force_batch(vec![call1, call2]))); - #[cfg(not(any(feature = "westend", feature = "paseo")))] - let final_call = utility_force_batch(vec![call1, call2]); - final_call + let (register_ether_call, set_ether_metadata_call) = + commands::register_ether(¶ms.register_ether); + let asset_hub_call = send_xcm_asset_hub( + &context, + vec![ + register_ether_call, + set_ether_metadata_call, + force_xcm_version(), + set_ethereum_fee, + ], + ) + .await?; + utility_force_batch(vec![bridge_hub_call, asset_hub_call]) } Command::UpdateAsset(params) => { - let call = send_xcm_asset_hub( + send_xcm_asset_hub( &context, vec![ commands::make_asset_sufficient(params), commands::force_set_metadata(params), ], ) - .await?; - - #[cfg(any(feature = "westend", feature = "paseo"))] - let final_call = sudo(Box::new(call)); - #[cfg(not(any(feature = "westend", feature = "paseo")))] - let final_call = call; - final_call + .await? } Command::GatewayOperatingMode(params) => { let call = commands::gateway_operating_mode(¶ms.gateway_operating_mode); @@ -359,9 +395,10 @@ async fn run() -> Result<(), Box> { Command::PricingParameters(params) => { let (set_pricing_parameters, set_ethereum_fee) = commands::pricing_parameters(&context, params).await?; - let call1 = send_xcm_bridge_hub(&context, vec![set_pricing_parameters]).await?; - let call2 = send_xcm_asset_hub(&context, vec![set_ethereum_fee]).await?; - utility_force_batch(vec![call1, call2]) + let bridge_hub_call = + send_xcm_bridge_hub(&context, vec![set_pricing_parameters]).await?; + let asset_hub_call = send_xcm_asset_hub(&context, vec![set_ethereum_fee]).await?; + utility_force_batch(vec![bridge_hub_call, asset_hub_call]) } Command::HaltBridge(params) => { let mut bh_calls = vec![]; @@ -409,10 +446,43 @@ async fn run() -> Result<(), Box> { utility_force_batch(vec![call1, call2]) } } + Command::RegisterEther(params) => { + let (register_ether_call, set_ether_metadata_call) = commands::register_ether(¶ms); + send_xcm_asset_hub(&context, vec![register_ether_call, set_ether_metadata_call]).await? + } Command::TreasuryProposal2024(params) => treasury_commands::treasury_proposal(¶ms), + Command::GovUpdate202501(GovUpdate202501Args { + pricing_parameters, + register_ether, + }) => { + let (set_pricing_parameters, set_ethereum_fee) = + commands::pricing_parameters(&context, pricing_parameters).await?; + + let bh_set_pricing_call = + send_xcm_bridge_hub(&context, vec![set_pricing_parameters]).await?; + + let ah_set_pricing_call = send_xcm_asset_hub(&context, vec![set_ethereum_fee]).await?; + + let (register_ether_call, set_ether_metadata_call) = + commands::register_ether(®ister_ether); + let ah_register_ether_call = + send_xcm_asset_hub(&context, vec![register_ether_call, set_ether_metadata_call]) + .await?; + + utility_force_batch(vec![ + bh_set_pricing_call, + ah_set_pricing_call, + ah_register_ether_call, + ]) + } }; - let preimage = call.encode(); + #[cfg(any(feature = "westend", feature = "paseo"))] + let final_call = if cli.sudo { sudo(Box::new(call)) } else { call }; + #[cfg(not(any(feature = "westend", feature = "paseo")))] + let final_call = call; + + let preimage = final_call.encode(); generate_chopsticks_script(&preimage, "chopsticks-execute-upgrade.js".into())?;