use alloy_primitives::{Address, Bytes, Log, U256};
use revm::context::result::ExecutionResult;
use crate::cache::TxConfig;
#[derive(Clone, Debug)]
pub struct BundleTx {
pub from: Address,
pub to: Address,
pub calldata: Bytes,
pub tx: TxConfig,
}
impl BundleTx {
pub fn new(from: Address, to: Address, calldata: Bytes) -> Self {
Self {
from,
to,
calldata,
tx: TxConfig::default(),
}
}
pub fn with_config(from: Address, to: Address, calldata: Bytes, tx: TxConfig) -> Self {
Self {
from,
to,
calldata,
tx,
}
}
}
#[derive(Clone, Debug, Default)]
pub enum RevertPolicy {
#[default]
Atomic,
AllowReverts(Vec<usize>),
}
#[derive(Clone, Debug, Default)]
pub struct BundleOptions {
pub revert_policy: RevertPolicy,
pub commit: bool,
}
#[derive(Clone, Debug)]
pub struct TxOutcome {
pub result: ExecutionResult,
pub gas_used: u64,
pub reverted: bool,
pub logs: Vec<Log>,
}
#[derive(Clone, Debug)]
pub struct BundleResult {
pub per_tx: Vec<TxOutcome>,
pub coinbase_payment: U256,
pub gas_used: u64,
pub successful_tx_gas: u64,
pub reverted_tx_gas: u64,
pub succeeded: bool,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn revert_policy_defaults_to_atomic() {
assert!(matches!(RevertPolicy::default(), RevertPolicy::Atomic));
}
#[test]
fn bundle_options_default_is_evaluate_only_atomic() {
let opts = BundleOptions::default();
assert!(matches!(opts.revert_policy, RevertPolicy::Atomic));
assert!(!opts.commit, "default must not persist");
}
#[test]
fn bundle_tx_new_uses_default_tx_config() {
let from = Address::repeat_byte(0x01);
let to = Address::repeat_byte(0x02);
let tx = BundleTx::new(from, to, Bytes::from(vec![0xaa]));
assert_eq!(tx.from, from);
assert_eq!(tx.to, to);
assert_eq!(tx.calldata, Bytes::from(vec![0xaa]));
assert_eq!(tx.tx.value, U256::ZERO);
assert!(tx.tx.gas_price.is_none());
assert!(tx.tx.access_list.is_none());
}
#[test]
fn bundle_tx_with_config_carries_value_and_gas_price() {
let tx = BundleTx::with_config(
Address::ZERO,
Address::ZERO,
Bytes::new(),
TxConfig {
value: U256::from(42u64),
gas_price: Some(7),
..Default::default()
},
);
assert_eq!(tx.tx.value, U256::from(42u64));
assert_eq!(tx.tx.gas_price, Some(7));
}
}