forked from iotaledger/wallet.rs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ping.rs
137 lines (125 loc) · 4.83 KB
/
ping.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// Copyright 2021 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0
//! cargo run --example ping --release
// In this example we will try to send transactions from multiple threads simultaneously to the first 1000 addresses of
// the second account (pong_account)
use std::env;
use dotenv::dotenv;
use iota_client::{
block::output::{
unlock_condition::{AddressUnlockCondition, UnlockCondition},
BasicOutputBuilder,
},
request_funds_from_faucet,
};
use iota_wallet::{
account_manager::AccountManager,
iota_client::constants::SHIMMER_COIN_TYPE,
secret::{mnemonic::MnemonicSecretManager, SecretManager},
ClientOptions, Result,
};
#[tokio::main]
async fn main() -> Result<()> {
// This example uses dotenv, which is not safe for use in production
dotenv().ok();
let client_options = ClientOptions::new()
.with_node(&env::var("NODE_URL").unwrap())?
.with_node_sync_disabled();
let secret_manager =
MnemonicSecretManager::try_from_mnemonic(&env::var("NON_SECURE_USE_OF_DEVELOPMENT_MNEMONIC").unwrap())?;
let manager = AccountManager::builder()
.with_secret_manager(SecretManager::Mnemonic(secret_manager))
.with_client_options(client_options)
.with_coin_type(SHIMMER_COIN_TYPE)
.with_storage_path("pingdb")
.finish()
.await?;
// Get account or create a new one
let account_alias = "ping";
let ping_account = match manager.get_account(account_alias.to_string()).await {
Ok(account) => account,
_ => {
// first we'll create an example account and store it
manager
.create_account()
.with_alias(account_alias.to_string())
.finish()
.await?
}
};
let account_alias = "pong";
let pong_account = match manager.get_account(account_alias.to_string()).await {
Ok(account) => account,
_ => {
// first we'll create an example account and store it
manager
.create_account()
.with_alias(account_alias.to_string())
.finish()
.await?
}
};
let amount_addresses = 5;
// generate addresses so we find all funds
if ping_account.addresses().await?.len() < amount_addresses {
ping_account
.generate_addresses((amount_addresses - ping_account.addresses().await?.len()) as u32, None)
.await?;
}
let balance = ping_account.sync(None).await?;
println!("Balance: {:?}", balance);
// generate addresses from the second account to which we will send funds
let pong_addresses = {
let mut addresses = pong_account.addresses().await?;
if addresses.len() < amount_addresses {
addresses = pong_account
.generate_addresses((amount_addresses - addresses.len()) as u32, None)
.await?
};
println!(
"{}",
request_funds_from_faucet(&env::var("FAUCET_URL").unwrap(), &addresses[0].address().to_bech32()).await?
);
addresses
};
for address_index in 0..1000 {
let mut threads = Vec::new();
for n in 1..4 {
let ping_account_ = ping_account.clone();
let pong_addresses_ = pong_addresses.clone();
threads.push(async move {
tokio::spawn(async move {
// send transaction
let outputs = vec![
// send one or two Mi for more different transactions
BasicOutputBuilder::new_with_amount(n * 1_000_000)?
.add_unlock_condition(UnlockCondition::Address(AddressUnlockCondition::new(
*pong_addresses_[address_index % amount_addresses].address().as_ref(),
)))
.finish_output(ping_account_.client().get_token_supply()?)?,
];
let tx = ping_account_.send(outputs, None).await?;
println!(
"Block from thread {} sent: {}/api/core/v2/blocks/{}",
n,
&env::var("NODE_URL").unwrap(),
tx.block_id.expect("no block created yet")
);
iota_wallet::Result::Ok(n)
})
.await
});
}
let results = futures::future::try_join_all(threads).await?;
for thread in results {
if let Err(e) = thread {
println!("{}", e);
}
}
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
}
// wait until user press enter so background tasks keep running
let mut input = String::new();
std::io::stdin().read_line(&mut input).unwrap();
Ok(())
}