From 52f37e1e07c4604f1fa4bb99fb9b47cdbb7bada7 Mon Sep 17 00:00:00 2001 From: Anthony Graignic <anthony.graignic@uca.fr> Date: Thu, 11 Jan 2024 10:47:35 +0100 Subject: [PATCH] Update sending tx from csv file Rename to send for clarity Add rpc call to ots_accounts --- src/main.rs | 83 ++++++++++++++++++++++++++++------------------------- 1 file changed, 44 insertions(+), 39 deletions(-) diff --git a/src/main.rs b/src/main.rs index a6597be..60631a5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,9 @@ use ecomobicoin_jsonrpc::types::{Behavior, Block}; use ethereum_types::U64; -use ethers::{prelude::*, signers::coins_bip39::English}; +use ethers::{prelude::{*, rand::Rng}, signers::coins_bip39::English}; use futures::executor::block_on; use testnet_injector::utils::miner::get_miner_behavior; -use std::{process, time::Duration, ops::Div}; +use std::{process, time::Duration}; use testnet_injector::{ utils::{mobility_data::*, txbx}, }; @@ -28,8 +28,8 @@ enum Commands { Send(SendParams), /// Simulate behaviors from csv dataset and send them to the node SimulateBxFromCsv(SimulateBxFromCsv), - /// Simulate transactions from derived accounts from csv dataset and send them to the node - SimulateTxFromCsv(SimulateTxFromCsv), + /// Send transactions from derived accounts from csv dataset + SendTxFromCsv(SendTxFromCsv), /// Mine a block Mine(MineParams), } @@ -58,13 +58,13 @@ struct SimulateBxFromCsv { chain_id: Option<u64> } #[derive(Args)] -struct SimulateTxFromCsv { +struct SendTxFromCsv { /// Path to CSV file file: String, /// Block time in seconds, will send 1 tx every block block_time: u64, - /// Send tx to random addresses - random_addr: Option<bool>, + /// Send tx to unknown addresses + unknown_addr: Option<bool>, // Node RPC URL rpc_url: Option<String>, // Chain ID @@ -265,8 +265,8 @@ async fn main() -> Result<(), anyhow::Error> { block_on(handle).unwrap(); } }, - Some(Commands::SimulateTxFromCsv(params)) => { - info!("Simulating tx from {:?} every {:?} secs",params.file.clone(), params.block_time.clone()); + Some(Commands::SendTxFromCsv(params)) => { + info!("Sending tx from {:?} every {:?} secs with unknown address={:?}", params.file, params.block_time, params.unknown_addr); // Override env vars if specified in CLI if params.rpc_url.clone().is_some(){ rpc_url = params.rpc_url.clone().unwrap(); @@ -283,13 +283,7 @@ async fn main() -> Result<(), anyhow::Error> { let mobility_records = generate_behaviors_from_records(records.clone()); - let dataset_max_relative_time = mobility_records - .iter() - .max_by(|x, y| x.relative_start_time.cmp(&y.relative_start_time)) - .unwrap() - .relative_start_time; - - let is_addr_random = params.random_addr.unwrap_or(false); + let is_addr_unknown = params.unknown_addr.unwrap_or(false); let block_time = if params.block_time > 0 { params.block_time } else { @@ -297,10 +291,8 @@ async fn main() -> Result<(), anyhow::Error> { }; info!( - "Simulation of {:?} records every {:?} secs with random addr {:?}", - mobility_records.len(), - block_time, - is_addr_random + "Simulation of {:?} records", + mobility_records.len() ); // ---------------- @@ -322,46 +314,59 @@ async fn main() -> Result<(), anyhow::Error> { // Wallet is derived from mnemomic with user_id to ensure each user have the same wallet for the simulation. let mnemonic = std::env::var("MNEMONIC").unwrap_or("abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about".to_string()); + let user_id = simulation_behavior.mobility_record.user_id as u32; let wallet = MnemonicBuilder::<English>::default() .phrase(PathOrString::String(mnemonic.clone())) - .index(simulation_behavior.mobility_record.user_id as u32) + .index(user_id) .unwrap() .build() .unwrap() .with_chain_id(chain_id); - // Get random addr - //TODO call rpc - let to_addr = if is_addr_random{ Address::random()} else { - Address::zero() - }; + let signer = SignerMiddleware::new(provider.clone(), wallet.clone()); + let addr = signer.clone().address(); + let nonce_manager = signer.nonce_manager(addr); - let from_balance = provider.get_balance(wallet.address(),None).await.unwrap(); + // List of active accounts from node + let accounts = provider.request::<[Behavior;0], Vec<(Address, U256)>>("ots_getAccountWithBalance", []).await.unwrap(); - if from_balance.is_zero() { - warn!("Attempted to send a tx from an empty account {:?}, user_id {:?}", wallet.address(),simulation_behavior.mobility_record.user_id); + let to_addr = if is_addr_unknown { + Address::random() } else { - // Temporary value - let value = from_balance.div(2) + 1 ; + let mut rng = rand::thread_rng(); + let rnd = rng.gen_range(0..accounts.len()); + accounts[rnd].0 + }; + + let from_balance = provider.get_balance(wallet.address(),None).await.unwrap(); + // Temporary value close to min + let tx_value= U256::from(210000); + + if from_balance.gt(&tx_value) { + let tx = TransactionRequest::new() + .to(to_addr) + .value(tx_value) + .chain_id(chain_id); + info!( "Sending tx from: {:?} (user_id: {:?}),to {:?} value {:?} ", - wallet.address(), - simulation_behavior.mobility_record.user_id, + addr, + user_id, to_addr, - value + tx_value ); - - let client = SignerMiddleware::new(provider.clone(), wallet.clone()); - - let tx_hash = txbx::send_transaction(client.clone(), chain_id, to_addr, value).await; + + let tx_hash = nonce_manager.send_transaction(tx, None).await; info!("Sent tx {:?}", tx_hash); + } else { + warn!("Didn't send tx for {:?}, balance too low ({:?}<210000)", addr, from_balance); } } })) } - info!("Scheduling done, waiting for bx & tx threads..."); + info!("Scheduling done, waiting for tx threads..."); // Wait for all of them to complete. for handle in handles { -- GitLab