Skip to content
Snippets Groups Projects
Verified Commit bf13092b authored by Pascal Engélibert's avatar Pascal Engélibert :bicyclist:
Browse files

feat: transfer & oneshot

parent 0a370bc7
No related branches found
No related tags found
No related merge requests found
This diff is collapsed.
......@@ -12,8 +12,8 @@ clap = { version = "3.0", features = ["derive"] }
env_logger = "0.9.0"
hex = "0.4.3"
logs = "0.5"
codec = { package = "parity-scale-codec", version = "2.3.1" }
codec = { package = "parity-scale-codec", version = "3.1.5" }
serde_json = "1.0.64"
sp-core = { git = "https://github.com/librelois/substrate.git", branch = "duniter-monthly-2022-02" }
subxt = { git = 'https://github.com/librelois/subxt.git', branch = 'duniter-monthly-2022-02' }
sp-core = { git = "https://github.com/duniter/substrate", branch = "duniter-substrate-v0.9.23" }
subxt = { git = 'https://github.com/duniter/subxt.git', branch = 'duniter-substrate-v0.9.23' }
tokio = { version = "1.15.0", features = ["macros"] }
No preview for this file type
......@@ -6,14 +6,35 @@ use sp_core::{
sr25519::Pair,
};
use subxt::sp_runtime::MultiAddress;
use subxt::{ClientBuilder, DefaultConfig, DefaultExtra, PairSigner};
use subxt::{
extrinsic::{BaseExtrinsicParams, BaseExtrinsicParamsBuilder},
ClientBuilder, DefaultConfig, PairSigner,
};
#[subxt::subxt(runtime_metadata_path = "res/metadata.scale")]
pub mod gdev_100 {}
pub mod gdev_300 {}
pub type Api = gdev_100::RuntimeApi<DefaultConfig, DefaultExtra<DefaultConfig>>;
pub type Api = gdev_300::RuntimeApi<DefaultConfig, BaseExtrinsicParams<DefaultConfig, Tip>>;
type Client = subxt::Client<DefaultConfig>;
#[derive(Copy, Clone, Debug, Default, Encode)]
pub struct Tip {
#[codec(compact)]
tip: u64,
}
impl Tip {
pub fn new(amount: u64) -> Self {
Tip { tip: amount }
}
}
impl From<u64> for Tip {
fn from(n: u64) -> Self {
Self::new(n)
}
}
#[derive(Parser, Debug)]
#[clap(author, version, about, long_about = None)]
struct Args {
......@@ -25,14 +46,35 @@ struct Args {
#[clap(short, long)]
secret: String,
/// Websocket RPC endpoint
#[clap(short, long, default_value = "ws://localhost:9945")]
#[clap(short, long, default_value = "ws://localhost:9944")]
url: String,
}
#[derive(Debug, clap::Subcommand)]
pub enum Subcommand {
CreateOneshot {
balance: u64,
dest: sp_core::crypto::AccountId32,
},
ConsumeOneshot {
dest: sp_core::crypto::AccountId32,
#[clap(long = "oneshot")]
dest_oneshot: bool,
},
ConsumeOneshotWithRemaining {
balance: u64,
dest: sp_core::crypto::AccountId32,
#[clap(long = "one")]
dest_oneshot: bool,
remaining_to: sp_core::crypto::AccountId32,
#[clap(long = "rem-one")]
remaining_to_oneshot: bool,
},
/// Generate a revocation document for the provided account
GenRevocDoc,
OneshotBalance {
account: sp_core::crypto::AccountId32,
},
#[clap(hide = true)]
Repart {
// Number of transactions per block to target
......@@ -43,6 +85,12 @@ pub enum Subcommand {
},
#[clap(hide = true)]
SpamRoll { actual_repart: usize },
Transfer {
balance: u64,
dest: sp_core::crypto::AccountId32,
#[clap(short = 'k')]
keep_alive: bool,
},
}
#[tokio::main(flavor = "current_thread")]
......@@ -53,7 +101,6 @@ async fn main() -> Result<()> {
let pair = Pair::from_string(&args.secret, None)
.map_err(|_| anyhow!("Invalid secret {}", args.secret))?;
//let mut signer = PairSigner::new(pair.clone());
let client: Client = ClientBuilder::new()
.set_url(&args.url)
......@@ -63,11 +110,91 @@ async fn main() -> Result<()> {
let api = client.clone().to_runtime_api::<Api>();
let account_id: sp_core::crypto::AccountId32 = pair.public().into();
let account = api.storage().system().account(account_id, None).await?;
let account = api.storage().system().account(&account_id, None).await?;
logs::info!("Account free balance: {}", account.data.free);
match args.subcommand {
Subcommand::CreateOneshot { balance, dest } => {
api.tx()
.oneshot_account()
.create_oneshot_account(dest.into(), balance)?
.sign_and_submit_then_watch(
&PairSigner::new(pair),
BaseExtrinsicParamsBuilder::new(),
)
.await?;
}
Subcommand::ConsumeOneshot { dest, dest_oneshot } => {
let number = api.storage().system().number(None).await?;
api.tx()
.oneshot_account()
.consume_oneshot_account(
number,
if dest_oneshot {
gdev_300::runtime_types::pallet_oneshot_account::types::Account::Oneshot(
dest.into(),
)
} else {
gdev_300::runtime_types::pallet_oneshot_account::types::Account::Normal(
dest.into(),
)
},
)?
.sign_and_submit_then_watch(
&PairSigner::new(pair),
BaseExtrinsicParamsBuilder::new(),
)
.await?;
}
Subcommand::ConsumeOneshotWithRemaining {
balance,
dest,
dest_oneshot,
remaining_to,
remaining_to_oneshot,
} => {
let number = api.storage().system().number(None).await?;
api.tx()
.oneshot_account()
.consume_oneshot_account_with_remaining(
number,
if dest_oneshot {
gdev_300::runtime_types::pallet_oneshot_account::types::Account::Oneshot(
dest.into(),
)
} else {
gdev_300::runtime_types::pallet_oneshot_account::types::Account::Normal(
dest.into(),
)
},
if remaining_to_oneshot {
gdev_300::runtime_types::pallet_oneshot_account::types::Account::Oneshot(
remaining_to.into(),
)
} else {
gdev_300::runtime_types::pallet_oneshot_account::types::Account::Normal(
remaining_to.into(),
)
},
balance,
)?
.sign_and_submit_then_watch(
&PairSigner::new(pair),
BaseExtrinsicParamsBuilder::new(),
)
.await?;
}
Subcommand::GenRevocDoc => gen_revoc_doc(&api, &pair).await?,
Subcommand::OneshotBalance { account } => {
logs::info!(
"{}",
api.storage()
.oneshot_account()
.oneshot_accounts(&account, None)
.await?
.unwrap_or(0)
);
}
Subcommand::Repart {
target,
actual_repart,
......@@ -85,8 +212,8 @@ async fn main() -> Result<()> {
/*let _ = api
.tx()
.balances()
.transfer(MultiAddress::Id(pair_i.public().into()), 501)
.sign_and_submit_then_watch(&signer)
.transfer(MultiAddress::Id(pair_i.public().into()), 501)?
.sign_and_submit_then_watch(&signer, BaseExtrinsicParamsBuilder::new())
.await?
.wait_for_in_block()
.await?;
......@@ -95,16 +222,14 @@ async fn main() -> Result<()> {
let pair_i_account = api
.storage()
.system()
.account(pair_i.public().into(), None)
.account(&pair_i.public().into(), None)
.await?;
logs::info!("account //{} balance: {}", i, pair_i_account.data.free);
}
}
Subcommand::SpamRoll { actual_repart } => {
let mut pairs = Vec::<(
PairSigner<DefaultConfig, DefaultExtra<DefaultConfig>, Pair>,
AccountId32,
)>::with_capacity(actual_repart);
let mut pairs =
Vec::<(PairSigner<DefaultConfig, Pair>, AccountId32)>::with_capacity(actual_repart);
for i in 0..actual_repart {
let pair_i = pair
.derive(std::iter::once(DeriveJunction::hard::<u32>(i as u32)), None)
......@@ -121,8 +246,8 @@ async fn main() -> Result<()> {
let watcher = api
.tx()
.balances()
.transfer(MultiAddress::Id(dest), 1)
.sign_and_submit_then_watch(&pairs[i].0)
.transfer(MultiAddress::Id(dest), 1)?
.sign_and_submit_then_watch(&pairs[i].0, BaseExtrinsicParamsBuilder::new())
.await?;
pairs[i].0.increment_nonce();
logs::info!("send 1 cent from //{} to //{}", i, i + 1);
......@@ -132,8 +257,11 @@ async fn main() -> Result<()> {
let watcher = api
.tx()
.balances()
.transfer(MultiAddress::Id(dest), 1)
.sign_and_submit_then_watch(&pairs[actual_repart - 1].0)
.transfer(MultiAddress::Id(dest), 1)?
.sign_and_submit_then_watch(
&pairs[actual_repart - 1].0,
BaseExtrinsicParamsBuilder::new(),
)
.await?;
pairs[actual_repart - 1].0.increment_nonce();
logs::info!("send 1 cent from //{} to //0", actual_repart - 1);
......@@ -145,6 +273,31 @@ async fn main() -> Result<()> {
}
}
}
Subcommand::Transfer {
balance,
dest,
keep_alive,
} => {
if keep_alive {
api.tx()
.balances()
.transfer(dest.into(), balance)?
.sign_and_submit_then_watch(
&PairSigner::new(pair),
BaseExtrinsicParamsBuilder::new(),
)
.await?;
} else {
api.tx()
.balances()
.transfer_keep_alive(dest.into(), balance)?
.sign_and_submit_then_watch(
&PairSigner::new(pair),
BaseExtrinsicParamsBuilder::new(),
)
.await?;
}
}
}
Ok(())
......@@ -152,7 +305,7 @@ async fn main() -> Result<()> {
async fn gen_revoc_doc(api: &Api, pair: &Pair) -> Result<()> {
let account_id: sp_core::crypto::AccountId32 = pair.public().into();
let genesis_hash = api.storage().system().block_hash(0, None).await?;
let genesis_hash = api.storage().system().block_hash(&0, None).await?;
let payload = (account_id, genesis_hash).encode();
let signature = pair.sign(&payload);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment