Skip to content

Commit

Permalink
feat: Add faucet pallet to CLI
Browse files Browse the repository at this point in the history
  • Loading branch information
aidan46 committed Nov 19, 2024
1 parent c0750b8 commit a54b930
Show file tree
Hide file tree
Showing 7 changed files with 156 additions and 19 deletions.
69 changes: 69 additions & 0 deletions cli/polka-storage/storagext-cli/src/cmd/faucet.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use std::time::Duration;

use clap::Subcommand;
use storagext::{FaucetClientExt, PolkaStorageConfig};
use url::Url;

use crate::OutputFormat;

#[derive(Debug, Subcommand)]
#[command(name = "faucet", about = "CLI Client to the Faucet Pallet", version)]
pub(crate) enum FaucetCommand {
/// Drip funds into target account.
Drip {
/// Drip target's account ID.
account_id: <PolkaStorageConfig as subxt::Config>::AccountId,
},
}

impl FaucetCommand {
/// Run a `faucet` command.
///
/// Requires the target RPC address.
#[tracing::instrument(level = "info", skip(self, node_rpc), fields(node_rpc = node_rpc.as_str()))]
pub async fn run(
self,
node_rpc: Url,
n_retries: u32,
retry_interval: Duration,
output_format: OutputFormat,
wait_for_finalization: bool,
) -> Result<(), anyhow::Error> {
let client = storagext::Client::new(node_rpc, n_retries, retry_interval).await?;

match self {
FaucetCommand::Drip { account_id } => {
let submission_result = client.drip(account_id, wait_for_finalization).await?;

let Some(submission_result) = submission_result else {
// Didn't wait for finalization
return Ok(());
};

// This monstrosity first converts incoming events into a "generic" (subxt generated) event,
// and then we extract only the Market events. We could probably extract this into a proper
// iterator but the effort to improvement ratio seems low (for 2 pallets at least).
let submission_results = submission_result
.events
.iter()
.flat_map(|event| {
event.map(|details| details.as_root_event::<storagext::runtime::Event>())
})
.filter_map(|event| match event {
Ok(storagext::runtime::Event::Market(e)) => Some(Ok(e)),
Err(err) => Some(Err(err)),
_ => None,
});
for event in submission_results {
let event = event?;
let output = output_format.format(&event)?;
match output_format {
OutputFormat::Plain => println!("[{}] {}", submission_result.hash, output),
OutputFormat::Json => println!("{}", output),
}
}
Ok(())
}
}
}
}
1 change: 1 addition & 0 deletions cli/polka-storage/storagext-cli/src/cmd/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod faucet;
pub mod market;
pub mod proofs;
pub mod randomness;
Expand Down
16 changes: 14 additions & 2 deletions cli/polka-storage/storagext-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use std::{fmt::Debug, time::Duration};

use clap::{ArgGroup, Parser, Subcommand};
use cmd::{
market::MarketCommand, proofs::ProofsCommand, randomness::RandomnessCommand,
storage_provider::StorageProviderCommand, system::SystemCommand,
faucet::FaucetCommand, market::MarketCommand, proofs::ProofsCommand,
randomness::RandomnessCommand, storage_provider::StorageProviderCommand, system::SystemCommand,
};
use storagext::multipair::{DebugPair, MultiPairSigner};
use subxt::ext::sp_core::{
Expand Down Expand Up @@ -89,6 +89,8 @@ struct Cli {

#[derive(Debug, Subcommand)]
enum SubCommand {
#[command(subcommand)]
Faucet(FaucetCommand),
// Perform market operations.
#[command(subcommand)]
Market(MarketCommand),
Expand All @@ -114,6 +116,16 @@ impl SubCommand {
wait_for_finalization: bool,
) -> Result<(), anyhow::Error> {
match self {
SubCommand::Faucet(cmd) => {
cmd.run(
node_rpc,
n_retries,
retry_interval,
output_format,
wait_for_finalization,
)
.await?;
}
SubCommand::Market(cmd) => {
cmd.run(
node_rpc,
Expand Down
30 changes: 30 additions & 0 deletions cli/polka-storage/storagext/src/clients/faucet.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use std::future::Future;

use crate::{
runtime::{self, SubmissionResult},
PolkaStorageConfig,
};

/// Client to interact with the faucet pallet.
pub trait FaucetClientExt {
/// Drip funds into the provided account.
fn drip(
&self,
account_id: <PolkaStorageConfig as subxt::Config>::AccountId,
wait_for_finalization: bool,
) -> impl Future<Output = Result<Option<SubmissionResult<PolkaStorageConfig>>, subxt::Error>>;
}

impl FaucetClientExt for crate::runtime::client::Client {
async fn drip(
&self,
account_id: <PolkaStorageConfig as subxt::Config>::AccountId,
wait_for_finalization: bool,
) -> Result<Option<SubmissionResult<PolkaStorageConfig>>, subxt::Error> {
let payload = runtime::tx()
.faucet()
.drip(subxt::utils::AccountId32::from(account_id));

self.unsigned(&payload, wait_for_finalization).await
}
}
2 changes: 2 additions & 0 deletions cli/polka-storage/storagext/src/clients/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
mod faucet;
mod market;
mod proofs;
mod randomness;
mod storage_provider;
mod system;

pub use faucet::FaucetClientExt;
pub use market::MarketClientExt;
pub use proofs::ProofsClientExt;
pub use randomness::RandomnessClientExt;
Expand Down
5 changes: 4 additions & 1 deletion cli/polka-storage/storagext/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ pub mod types;
pub mod deser;

pub use crate::{
clients::{MarketClientExt, RandomnessClientExt, StorageProviderClientExt, SystemClientExt},
clients::{
FaucetClientExt, MarketClientExt, RandomnessClientExt, StorageProviderClientExt,
SystemClientExt,
},
runtime::{bounded_vec::IntoBoundedByteVec, client::Client},
};

Expand Down
52 changes: 36 additions & 16 deletions cli/polka-storage/storagext/src/runtime/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::time::Duration;

use codec::Encode;
use hex::ToHex;
use subxt::{blocks::Block, events::Events, OnlineClient};
use subxt::{blocks::Block, events::Events, utils::H256, OnlineClient};

use crate::PolkaStorageConfig;

Expand Down Expand Up @@ -67,6 +67,32 @@ impl Client {
}
}

pub(crate) async fn unsigned<Call>(
&self,
call: &Call,
wait_for_finalization: bool,
) -> Result<Option<SubmissionResult<PolkaStorageConfig>>, subxt::Error>
where
Call: subxt::tx::Payload,
{
if wait_for_finalization {
let submitted_extrinsic_hash = self.client.tx().create_unsigned(call)?.submit().await?;
self.traced_submission_with_finalization(submitted_extrinsic_hash)
.await
.map(Option::Some)
} else {
tracing::trace!("submitting unsigned extrinsic");
let extrinsic_hash = self.client.tx().create_unsigned(call)?.submit().await?;

tracing::trace!(
extrinsic_hash = extrinsic_hash.encode_hex::<String>(),
"waiting for finalization"
);

Ok(None)
}
}

/// Submit an extrinsic and wait for finalization, returning the block hash it was included in.
///
/// Equivalent to performing [`OnlineClient::sign_and_submit_then_watch_default`],
Expand All @@ -82,7 +108,12 @@ impl Client {
Keypair: subxt::tx::Signer<PolkaStorageConfig>,
{
if wait_for_finalization {
self.traced_submission_with_finalization(call, account_keypair)
let submitted_extrinsic_hash = self
.client
.tx()
.sign_and_submit_default(call, account_keypair)
.await?;
self.traced_submission_with_finalization(submitted_extrinsic_hash)
.await
.map(Option::Some)
} else {
Expand All @@ -101,25 +132,14 @@ impl Client {
}
}

pub(crate) async fn traced_submission_with_finalization<Call, Keypair>(
pub(crate) async fn traced_submission_with_finalization(
&self,
call: &Call,
account_keypair: &Keypair,
) -> Result<SubmissionResult<PolkaStorageConfig>, subxt::Error>
where
Call: subxt::tx::Payload,
Keypair: subxt::tx::Signer<PolkaStorageConfig>,
{
submitted_extrinsic_hash: H256,
) -> Result<SubmissionResult<PolkaStorageConfig>, subxt::Error> {
tracing::trace!("submitting extrinsic");

let mut finalized_block_stream = self.client.blocks().subscribe_finalized().await?;

let submitted_extrinsic_hash = self
.client
.tx()
.sign_and_submit_default(call, account_keypair)
.await?;

tracing::debug!(
extrinsic_hash = submitted_extrinsic_hash.encode_hex::<String>(),
"waiting for finalization"
Expand Down

0 comments on commit a54b930

Please sign in to comment.