verbs_rs/agent/
singleton_agent.rs

1//! Implementation of [AgentSet] for a single agent
2
3use crate::agent::traits::{Agent, AgentSet, RecordedAgent, RecordedAgentSet};
4use crate::contract::Transaction;
5use crate::env::{Env, Validator};
6use crate::DB;
7use alloy_primitives::Address;
8use rand::RngCore;
9use std::mem;
10
11/// Implementation of agent set for a single agent
12///
13/// Convenience implementation of the [AgentSet] trait
14/// for a set containing a single agent
15///
16/// # Examples
17///
18/// ```
19/// use rand::RngCore;
20/// use alloy_primitives::Address;
21/// use verbs_rs::{DB, env::{Env, Validator}};
22/// use verbs_rs::agent::{Agent, RecordedAgent, SingletonAgent, AgentSet};
23/// use verbs_rs::contract::Transaction;
24///
25/// struct DummyAgent{}
26///
27/// impl Agent for DummyAgent {
28///     fn update<D: DB, V: Validator, R: RngCore>(
29///         &mut self, rng: &mut R, network: &mut Env<D, V>
30///     ) -> Vec<Transaction> {
31///         Vec::default()
32///     }
33///
34///     fn get_address(&self) -> Address {
35///         Address::ZERO
36///     }
37/// }
38///
39/// impl RecordedAgent<bool> for DummyAgent {
40///     fn record<D: DB, V: Validator>(&mut self, _env: &mut Env<D, V>) -> bool {
41///         true
42///     }
43/// }
44///
45/// let singleton_agent = SingletonAgent::<bool, DummyAgent>::from(
46///     DummyAgent{}
47/// );
48///
49/// let addresses = singleton_agent.get_addresses();
50/// ```
51pub struct SingletonAgent<R, A: Agent + RecordedAgent<R>> {
52    /// Single agent in this set
53    agent: A,
54    /// Records of agent state over the course of the simulation.
55    records: Vec<R>,
56}
57
58impl<R, A: Agent + RecordedAgent<R>> SingletonAgent<R, A> {
59    /// Initialise an from an existing agents.
60    ///
61    /// # Arguments
62    ///
63    /// * `agent` - Agent controlled by the agent-set
64    ///
65    pub fn from(agent: A) -> Self {
66        SingletonAgent {
67            agent,
68            records: Vec::<R>::new(),
69        }
70    }
71    /// Get the recorded history of the agent.
72    pub fn get_records(&self) -> &Vec<R> {
73        &self.records
74    }
75
76    /// Take ownership of recorded data of the agent.
77    pub fn take_records(&mut self) -> Vec<R> {
78        mem::take(&mut self.records)
79    }
80}
81
82/// Implementations of agent updates and recording.
83impl<R: 'static, A: Agent + RecordedAgent<R> + 'static> AgentSet for SingletonAgent<R, A> {
84    /// Call the agent and optionally return EVM call
85    ///
86    /// This is called during the simulation, updating the state of
87    /// the agents, and collecting any submitted transactions into
88    /// a single vector.
89    ///
90    /// # Arguments
91    ///
92    /// * `rng` - Random generator
93    /// * `network` - Protocol deployment(s)
94    ///
95    fn call<D: DB, V: Validator, RG: RngCore>(
96        &mut self,
97        rng: &mut RG,
98        env: &mut Env<D, V>,
99    ) -> Vec<Transaction> {
100        self.agent.update(rng, env)
101    }
102    /// Record the current state of the agent
103    fn record<D: DB, V: Validator>(&mut self, env: &mut Env<D, V>) {
104        self.records.push(self.agent.record(env));
105    }
106    /// Get the address of the agent as a vector
107    fn get_addresses(&self) -> Vec<Address> {
108        vec![self.agent.get_address()]
109    }
110}
111
112impl<R, A: Agent + RecordedAgent<R>> RecordedAgentSet<R> for SingletonAgent<R, A> {
113    fn take_records(&mut self) -> Vec<Vec<R>> {
114        let x = mem::take(&mut self.records);
115        x.into_iter().map(|y| vec![y]).collect()
116    }
117}