Skip to content

Commit

Permalink
Merge pull request #72 from flashbots/feature/dynamic-eoas-in-create-…
Browse files Browse the repository at this point in the history
…steps

support from_pool in create steps
  • Loading branch information
zeroXbrock authored Jan 7, 2025
2 parents d73f14e + 7dbe69f commit f47bf5f
Show file tree
Hide file tree
Showing 10 changed files with 249 additions and 140 deletions.
26 changes: 16 additions & 10 deletions crates/cli/src/commands/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ use contender_testfile::TestConfig;
use std::str::FromStr;

use crate::util::{
check_private_keys_fns, find_insufficient_balance_addrs, fund_accounts, get_setup_pools,
get_signers_with_defaults,
check_private_keys_fns, find_insufficient_balance_addrs, fund_accounts, get_create_pools,
get_setup_pools, get_signers_with_defaults,
};

pub async fn setup(
Expand All @@ -38,11 +38,15 @@ pub async fn setup(
.iter()
.map(|key| PrivateKeySigner::from_str(key).expect("invalid private key"))
.collect::<Vec<PrivateKeySigner>>();
let default_signers = get_signers_with_defaults(private_keys);

let user_signers_with_defaults = get_signers_with_defaults(private_keys);

check_private_keys_fns(
&testconfig.setup.to_owned().unwrap_or_default(),
&default_signers,
&user_signers_with_defaults,
);

// ensure user-provided accounts have sufficient balance
let broke_accounts = find_insufficient_balance_addrs(
&user_signers.iter().map(|s| s.address()).collect::<Vec<_>>(),
min_balance,
Expand All @@ -53,11 +57,14 @@ pub async fn setup(
panic!("Insufficient balance in provided user account(s)");
}

let mut agents = AgentStore::new();
let from_pools = get_setup_pools(&testconfig);
// collect all signers
let mut all_signers = vec![];
all_signers.extend_from_slice(&user_signers);

// load agents from setup and create pools
let mut from_pools = get_setup_pools(&testconfig);
from_pools.extend(get_create_pools(&testconfig));
let mut agents = AgentStore::new();
for from_pool in &from_pools {
if agents.has_agent(from_pool) {
continue;
Expand All @@ -69,11 +76,11 @@ pub async fn setup(
}

fund_accounts(
&all_signers,
&user_signers_with_defaults[0],
&rpc_client,
&eth_client,
min_balance,
&all_signers,
&default_signers[0],
)
.await?;

Expand All @@ -83,14 +90,13 @@ pub async fn setup(
url,
None,
seed,
&default_signers,
&user_signers_with_defaults,
agents,
)
.await?;

scenario.deploy_contracts().await?;
scenario.run_setup().await?;
// TODO: catch failures and prompt user to retry specific steps

Ok(())
}
7 changes: 3 additions & 4 deletions crates/cli/src/commands/spam.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,7 @@ pub async fn spam(
let mut agents = AgentStore::new();
let signers_per_period = args
.txs_per_block
.unwrap_or(args.txs_per_second.unwrap_or(spam.len()))
/ spam.len();
.unwrap_or(args.txs_per_second.unwrap_or(spam.len()));

let mut all_signers = vec![];
all_signers.extend_from_slice(&user_signers);
Expand All @@ -78,11 +77,11 @@ pub async fn spam(
check_private_keys(&testconfig, &all_signers);

fund_accounts(
&all_signers,
&user_signers[0],
&rpc_client,
&eth_client,
min_balance,
&all_signers,
&user_signers[0],
)
.await?;

Expand Down
3 changes: 2 additions & 1 deletion crates/cli/src/default_scenarios/runconfig.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ impl From<BuiltinScenarioConfig> for TestConfig {
create: Some(vec![CreateDefinition {
name: "SpamMe".to_owned(),
bytecode: bytecode::SPAM_ME.to_owned(),
from: sender.to_string(),
from: Some(sender.to_string()),
from_pool: None,
}]),
setup: None,
spam: Some(spam_txs),
Expand Down
41 changes: 25 additions & 16 deletions crates/cli/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ pub const DEFAULT_PRV_KEYS: [&str; 10] = [
"0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6",
];

pub fn get_create_pools(testconfig: &TestConfig) -> Vec<String> {
testconfig
.create
.to_owned()
.unwrap_or_default()
.into_iter()
.filter_map(|s| s.from_pool)
.collect()
}

pub fn get_setup_pools(testconfig: &TestConfig) -> Vec<String> {
testconfig
.setup
Expand Down Expand Up @@ -67,6 +77,9 @@ pub fn get_spam_pools(testconfig: &TestConfig) -> Vec<String> {
}
}

// filter out non-unique pools
from_pools.sort();
from_pools.dedup();
from_pools
}

Expand Down Expand Up @@ -140,29 +153,29 @@ async fn is_balance_sufficient(
}

pub async fn fund_accounts(
accounts: &[PrivateKeySigner],
fund_with: &PrivateKeySigner,
rpc_client: &AnyProvider,
eth_client: &EthProvider,
min_balance: U256,
all_signers: &[PrivateKeySigner],
admin_signer: &PrivateKeySigner,
) -> Result<(), Box<dyn std::error::Error>> {
let insufficient_balance_addrs = find_insufficient_balance_addrs(
&all_signers.iter().map(|s| s.address()).collect::<Vec<_>>(),
&accounts.iter().map(|s| s.address()).collect::<Vec<_>>(),
min_balance,
rpc_client,
)
.await?;

let mut pending_fund_txs = vec![];
let admin_nonce = rpc_client
.get_transaction_count(admin_signer.address())
.get_transaction_count(fund_with.address())
.await?;
for (idx, address) in insufficient_balance_addrs.iter().enumerate() {
if !is_balance_sufficient(&admin_signer.address(), min_balance, rpc_client).await? {
if !is_balance_sufficient(&fund_with.address(), min_balance, rpc_client).await? {
// panic early if admin account runs out of funds
return Err(format!(
"Admin account {} has insufficient balance to fund this account.",
admin_signer.address()
fund_with.address()
)
.into());
}
Expand All @@ -178,7 +191,7 @@ pub async fn fund_accounts(
let fund_amount = min_balance;
pending_fund_txs.push(
fund_account(
admin_signer,
fund_with,
*address,
fund_amount,
eth_client,
Expand All @@ -197,7 +210,7 @@ pub async fn fund_accounts(
}

pub async fn fund_account(
admin_signer: &PrivateKeySigner,
sender: &PrivateKeySigner,
recipient: Address,
amount: U256,
rpc_client: &EthProvider,
Expand All @@ -206,18 +219,14 @@ pub async fn fund_account(
println!(
"funding account {} with user account {}",
recipient,
admin_signer.address()
sender.address()
);

let gas_price = rpc_client.get_gas_price().await?;
let nonce = nonce.unwrap_or(
rpc_client
.get_transaction_count(admin_signer.address())
.await?,
);
let nonce = nonce.unwrap_or(rpc_client.get_transaction_count(sender.address()).await?);
let chain_id = rpc_client.get_chain_id().await?;
let tx_req = TransactionRequest {
from: Some(admin_signer.address()),
from: Some(sender.address()),
to: Some(alloy::primitives::TxKind::Call(recipient)),
value: Some(amount),
gas: Some(21000),
Expand All @@ -226,7 +235,7 @@ pub async fn fund_account(
chain_id: Some(chain_id),
..Default::default()
};
let eth_wallet = EthereumWallet::from(admin_signer.to_owned());
let eth_wallet = EthereumWallet::from(sender.to_owned());
let tx = tx_req.build(&eth_wallet).await?;
let res = rpc_client.send_tx_envelope(tx).await?;

Expand Down
Loading

0 comments on commit f47bf5f

Please sign in to comment.