drt_sc_snippets/multi/
homogenous_tx_buffer.rs

1use drt_sc_scenario::{
2    drt_sc::{
3        tuple_util::NestedTupleFlatten,
4        types::{RHListExec, TxBaseWithEnv},
5    },
6    scenario::tx_to_step::{StepWithResponse, StepWrapper, TxToStep},
7    scenario_model::TxResponse,
8    ScenarioTxEnvData,
9};
10
11use crate::{Interactor, InteractorEnvExec, InteractorStep, StepBuffer};
12
13pub struct HomogenousTxBuffer<'w, Step, RH> {
14    env: InteractorEnvExec<'w>,
15    steps: Vec<StepWrapper<ScenarioTxEnvData, Step, RH>>,
16}
17
18impl Interactor {
19    /// Creates a buffer that can hold multiple transactions, and then execute them all at once.
20    ///
21    /// This buffer holds transactions of the same type (call/deploy) and with identical result handler types.
22    /// Therefore, after execution, all results will have the same type.
23    pub fn homogenous_call_buffer<Step, RH>(&mut self) -> HomogenousTxBuffer<'_, Step, RH> {
24        let data = self.new_env_data();
25        let env = InteractorEnvExec { world: self, data };
26        HomogenousTxBuffer {
27            env,
28            steps: Vec::new(),
29        }
30    }
31}
32
33impl<'w, Step, RH> HomogenousTxBuffer<'w, Step, RH>
34where
35    Step: InteractorStep + StepWithResponse,
36    RH: RHListExec<TxResponse, ScenarioTxEnvData>,
37    RH::ListReturns: NestedTupleFlatten,
38{
39    pub fn push_tx<Tx, F>(&mut self, f: F) -> &mut Self
40    where
41        Tx: TxToStep<ScenarioTxEnvData, RH, Step = Step>,
42        F: FnOnce(TxBaseWithEnv<ScenarioTxEnvData>) -> Tx,
43    {
44        let env = self.env.world.new_env_data();
45        let tx_base = TxBaseWithEnv::new_with_env(env);
46        let tx = f(tx_base);
47
48        self.steps.push(tx.tx_to_step());
49
50        self
51    }
52
53    pub async fn run(mut self) -> Vec<<RH::ListReturns as NestedTupleFlatten>::Unpacked> {
54        let mut step_buffer = StepBuffer::default();
55        for step in &mut self.steps {
56            step_buffer.refs.push(&mut step.step);
57        }
58        self.env.world.multi_sc_exec(step_buffer).await;
59
60        self.steps
61            .into_iter()
62            .map(|step| step.process_result())
63            .collect()
64    }
65}