Skip to content

Commit

Permalink
Remove chain logic from extrinsics crate (#1568)
Browse files Browse the repository at this point in the history
  • Loading branch information
smiasojed authored Apr 4, 2024
1 parent c9ffbe2 commit 20be25e
Show file tree
Hide file tree
Showing 17 changed files with 166 additions and 182 deletions.
20 changes: 8 additions & 12 deletions crates/cargo-contract/src/cmd/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ use std::{
},
str::FromStr,
};
use url::Url;

use super::{
config::SignerConfig,
Expand Down Expand Up @@ -102,9 +101,6 @@ pub struct CallCommand {
/// Export the call output in JSON format.
#[clap(long, conflicts_with = "verbose")]
output_json: bool,
/// The chain config to be used as part of the call.
#[clap(name = "config", long, default_value = "Polkadot")]
config: String,
}

impl CallCommand {
Expand All @@ -114,7 +110,11 @@ impl CallCommand {
}

pub async fn handle(&self) -> Result<(), ErrorVariant> {
call_with_config!(self, run, self.config.as_str())
call_with_config!(
self,
run,
self.extrinsic_cli_opts.chain_cli_opts.chain().config()
)
}

async fn run<C: Config + Environment + SignerConfig<C>>(
Expand All @@ -132,11 +132,8 @@ impl CallCommand {
.map_err(|e| anyhow::anyhow!("Failed to parse contract option: {}", e))?;
let signer = C::Signer::from_str(&self.extrinsic_cli_opts.suri)
.map_err(|_| anyhow::anyhow!("Failed to parse suri option"))?;
let token_metadata = if let Some(chain) = &self.extrinsic_cli_opts.chain {
TokenMetadata::query::<C>(&Url::parse(chain.end_point()).unwrap()).await?
} else {
TokenMetadata::query::<C>(&self.extrinsic_cli_opts.url).await?
};
let chain = self.extrinsic_cli_opts.chain_cli_opts.chain();
let token_metadata = TokenMetadata::query::<C>(&chain.url()).await?;
let storage_deposit_limit = self
.extrinsic_cli_opts
.storage_deposit_limit
Expand All @@ -151,8 +148,7 @@ impl CallCommand {
let extrinsic_opts = ExtrinsicOptsBuilder::new(signer)
.file(self.extrinsic_cli_opts.file.clone())
.manifest_path(self.extrinsic_cli_opts.manifest_path.clone())
.url(self.extrinsic_cli_opts.url.clone())
.chain(self.extrinsic_cli_opts.chain.clone())
.url(chain.url())
.storage_deposit_limit(storage_deposit_limit)
.verbosity(self.extrinsic_cli_opts.verbosity()?)
.done();
Expand Down
29 changes: 8 additions & 21 deletions crates/cargo-contract/src/cmd/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use super::{
basic_display_format_extended_contract_info,
display_all_contracts,
parse_account,
CLIChainOpts,
};
use anyhow::Result;
use contract_analyze::determine_language;
Expand All @@ -30,7 +31,6 @@ use contract_extrinsics::{
url_to_string,
ContractInfo,
ErrorVariant,
ProductionChain,
TrieId,
};
use ink_env::Environment;
Expand Down Expand Up @@ -67,17 +67,6 @@ pub struct InfoCommand {
required_unless_present = "all"
)]
contract: Option<String>,
/// Websockets url of a substrate node.
#[clap(
name = "url",
long,
value_parser,
default_value = "ws://localhost:9944"
)]
url: url::Url,
/// Name of a production chain to upload or instantiate the contract on.
#[clap(name = "chain", long, conflicts_with = "url")]
chain: Option<ProductionChain>,
/// Export the instantiate output in JSON format.
#[clap(name = "output-json", long)]
output_json: bool,
Expand All @@ -87,14 +76,14 @@ pub struct InfoCommand {
/// Display all contracts addresses
#[clap(name = "all", long)]
all: bool,
/// The chain config to be used as part of the call.
#[clap(name = "config", long, default_value = "Polkadot")]
config: String,
/// Arguments required for communtacting with a substrate node.
#[clap(flatten)]
chain_cli_opts: CLIChainOpts,
}

impl InfoCommand {
pub async fn handle(&self) -> Result<(), ErrorVariant> {
call_with_config!(self, run, self.config.as_str())
call_with_config!(self, run, self.chain_cli_opts.chain().config())
}

pub async fn run<C: Config + Environment>(&self) -> Result<(), ErrorVariant>
Expand All @@ -106,11 +95,9 @@ impl InfoCommand {
<<C as Config>::AccountId as FromStr>::Err:
Into<Box<(dyn std::error::Error)>> + Display,
{
let rpc_cli = if let Some(chain) = &self.chain {
RpcClient::from_url(chain.end_point()).await?
} else {
RpcClient::from_url(url_to_string(&self.url)).await?
};
let rpc_cli =
RpcClient::from_url(url_to_string(&self.chain_cli_opts.chain().url()))
.await?;
let client = OnlineClient::<C>::from_rpc_client(rpc_cli.clone()).await?;
let rpc = LegacyRpcMethods::<C>::new(rpc_cli.clone());

Expand Down
33 changes: 15 additions & 18 deletions crates/cargo-contract/src/cmd/instantiate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ use contract_build::{
Verbosity,
};
use contract_extrinsics::{
Chain,
Code,
DisplayEvents,
ExtrinsicOptsBuilder,
Expand Down Expand Up @@ -75,7 +74,6 @@ use subxt::{
},
Config,
};
use url::Url;

#[derive(Debug, clap::Args)]
pub struct InstantiateCommand {
Expand Down Expand Up @@ -106,9 +104,6 @@ pub struct InstantiateCommand {
/// Export the instantiate output in JSON format.
#[clap(long, conflicts_with = "verbose")]
output_json: bool,
/// The chain config to be used as part of the call.
#[clap(name = "config", long, default_value = "Polkadot")]
config: String,
}

/// Parse hex encoded bytes.
Expand All @@ -124,7 +119,11 @@ impl InstantiateCommand {
}

pub async fn handle(&self) -> Result<(), ErrorVariant> {
call_with_config!(self, run, self.config.as_str())
call_with_config!(
self,
run,
self.extrinsic_cli_opts.chain_cli_opts.chain().config()
)
}

async fn run<C: Config + Environment + SignerConfig<C>>(
Expand All @@ -142,11 +141,8 @@ impl InstantiateCommand {
{
let signer = C::Signer::from_str(&self.extrinsic_cli_opts.suri)
.map_err(|_| anyhow::anyhow!("Failed to parse suri option"))?;
let token_metadata = if let Some(chain) = &self.extrinsic_cli_opts.chain {
TokenMetadata::query::<C>(&Url::parse(chain.end_point()).unwrap()).await?
} else {
TokenMetadata::query::<C>(&self.extrinsic_cli_opts.url).await?
};
let chain = self.extrinsic_cli_opts.chain_cli_opts.chain();
let token_metadata = TokenMetadata::query::<C>(&chain.url()).await?;

let storage_deposit_limit = self
.extrinsic_cli_opts
Expand All @@ -162,8 +158,7 @@ impl InstantiateCommand {
let extrinsic_opts = ExtrinsicOptsBuilder::new(signer)
.file(self.extrinsic_cli_opts.file.clone())
.manifest_path(self.extrinsic_cli_opts.manifest_path.clone())
.url(self.extrinsic_cli_opts.url.clone())
.chain(self.extrinsic_cli_opts.chain.clone())
.url(chain.url())
.storage_deposit_limit(storage_deposit_limit)
.done();

Expand Down Expand Up @@ -204,11 +199,13 @@ impl InstantiateCommand {
}
}
} else {
if let Chain::Production(name) =
instantiate_exec.opts().chain_and_endpoint().0
{
if !instantiate_exec.opts().is_verifiable()? {
prompt_confirm_unverifiable_upload(&name)?
if let Some(chain) = chain.production() {
if !instantiate_exec
.opts()
.contract_artifacts()?
.is_verifiable()
{
prompt_confirm_unverifiable_upload(&chain.to_string())?
}
}
tracing::debug!("instantiate data {:?}", instantiate_exec.args().data());
Expand Down
77 changes: 65 additions & 12 deletions crates/cargo-contract/src/cmd/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
// along with cargo-contract. If not, see <http://www.gnu.org/licenses/>.

mod config;
mod prod_chains;

pub mod build;
pub mod call;
Expand All @@ -41,6 +42,7 @@ pub(crate) use self::{
InfoCommand,
},
instantiate::InstantiateCommand,
prod_chains::ProductionChain,
remove::RemoveCommand,
rpc::RpcCommand,
schema::{
Expand Down Expand Up @@ -72,7 +74,6 @@ pub(crate) use contract_extrinsics::ErrorVariant;
use contract_extrinsics::{
pallet_contracts_primitives::ContractResult,
BalanceVariant,
ProductionChain,
TokenMetadata,
};

Expand All @@ -98,14 +99,6 @@ pub struct CLIExtrinsicOpts {
/// Path to the `Cargo.toml` of the contract.
#[clap(long, value_parser)]
manifest_path: Option<PathBuf>,
/// Websockets url of a substrate node.
#[clap(
name = "url",
long,
value_parser,
default_value = "ws://localhost:9944"
)]
url: url::Url,
/// Secret key URI for the account deploying the contract.
///
/// e.g.
Expand All @@ -128,9 +121,9 @@ pub struct CLIExtrinsicOpts {
/// Before submitting a transaction, do not ask the user for confirmation.
#[clap(short('y'), long)]
skip_confirm: bool,
/// Name of a production chain to upload or instantiate the contract on.
#[clap(name = "chain", long, conflicts_with = "url")]
chain: Option<ProductionChain>,
/// Arguments required for communtacting with a substrate node.
#[clap(flatten)]
chain_cli_opts: CLIChainOpts,
}

impl CLIExtrinsicOpts {
Expand All @@ -140,6 +133,66 @@ impl CLIExtrinsicOpts {
}
}

/// Arguments required for communtacting with a substrate node.
#[derive(Clone, Debug, clap::Args)]
pub struct CLIChainOpts {
/// Websockets url of a substrate node.
#[clap(
name = "url",
long,
value_parser,
default_value = "ws://localhost:9944"
)]
url: url::Url,
/// Chain config to be used as part of the call.
#[clap(name = "config", long, default_value = "Polkadot")]
config: String,
/// Name of a production chain to be communicated with.
#[clap(name = "chain", long, conflicts_with_all = ["url", "config"])]
chain: Option<ProductionChain>,
}

impl CLIChainOpts {
pub fn chain(&self) -> Chain {
if let Some(chain) = &self.chain {
Chain::Production(chain.clone())
} else if let Some(prod) = ProductionChain::from_parts(&self.url, &self.config) {
Chain::Production(prod)
} else {
Chain::Custom(self.url.clone(), self.config.clone())
}
}
}

#[derive(Debug)]
pub enum Chain {
Production(ProductionChain),
Custom(url::Url, String),
}

impl Chain {
pub fn url(&self) -> url::Url {
match self {
Chain::Production(prod) => prod.url(),
Chain::Custom(url, _) => url.clone(),
}
}

pub fn config(&self) -> &str {
match self {
Chain::Production(prod) => prod.config(),
Chain::Custom(_, config) => config,
}
}

pub fn production(&self) -> Option<&ProductionChain> {
if let Chain::Production(prod) = self {
return Some(prod)
}
None
}
}

const STORAGE_DEPOSIT_KEY: &str = "Storage Total Deposit";
pub const MAX_KEY_COL_WIDTH: usize = STORAGE_DEPOSIT_KEY.len() + 1;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
//! This file simply contains the end points of the production chains
//! We hard-code these values to ensure that a user uploads a verifiable bundle
use contract_extrinsics::url_to_string;
use std::str::FromStr;
use url::Url;

/// This macro generates enums with the pre-defined production chains and their respective
/// endpoints.
Expand All @@ -26,27 +28,39 @@ use std::str::FromStr;
macro_rules! define_chains {
(
$(#[$($attrs:tt)*])*
pub enum $root:ident { $( $c:ident = $ep:tt ),* $(,)? }
pub enum $root:ident { $( $c:ident = ($ep:tt, $config:tt) ),* $(,)? }
) => {
$(#[$($attrs)*])*
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum $root { $($c),* }

impl $root {
/// Returns the endpoint URL of a chain.
pub fn end_point(&self) -> &str {
pub fn url(&self) -> url::Url {
match self {
$(
$root::$c => $ep
$root::$c => Url::parse($ep).expect("Incorrect Url format")
),*
}
}

/// Returns the chain type from the endpoint URL
pub fn chain_by_endpoint(ep: &str) -> Option<Self> {
match ep {
/// Returns the config of a chain.
pub fn config(&self) -> &str {
match self {
$(
$root::$c => $config
),*
}
}

/// Returns the production chain.
///
/// If the user specified the endpoint URL and config manually we'll attempt to
/// convert it into one of the pre-defined production chains.
pub fn from_parts(ep: &Url, config: &str) -> Option<Self> {
match (url_to_string(ep).as_str(), config) {
$(
$ep => Some($root::$c),
($ep, $config) => Some($root::$c),
)*
_ => None
}
Expand Down Expand Up @@ -80,9 +94,9 @@ macro_rules! define_chains {
define_chains! {
/// List of production chains where the contract can be deployed to.
pub enum ProductionChain {
AlephZero = "wss://ws.azero.dev:443",
Astar = "wss://rpc.astar.network:443",
Shiden = "wss://rpc.shiden.astar.network:443",
Krest = "wss://wss-krest.peaq.network"
AlephZero = ("wss://ws.azero.dev:443/", "Substrate"),
Astar = ("wss://rpc.astar.network:443/", "Polkadot"),
Shiden = ("wss://rpc.shiden.astar.network:443/", "Polkadot"),
Krest = ("wss://wss-krest.peaq.network:443/", "Polkadot")
}
}
Loading

0 comments on commit 20be25e

Please sign in to comment.