signet_evm/orders/
inspector.rs1use crate::{FramedFilleds, FramedOrders};
2use alloy::{
3 primitives::{map::HashSet, Address, Log, U256},
4 sol_types::SolEvent,
5};
6use signet_types::{constants::SignetSystemConstants, AggregateFills, AggregateOrders};
7use signet_zenith::RollupOrders;
8use trevm::{
9 helpers::Ctx,
10 revm::{
11 interpreter::{
12 CallInputs, CallOutcome, CreateInputs, CreateOutcome, Interpreter, InterpreterTypes,
13 },
14 Database, Inspector,
15 },
16};
17
18#[derive(Debug, Clone, PartialEq, Eq)]
37pub struct OrderDetector {
38 contracts: HashSet<Address>,
40
41 fills_only: bool,
43
44 chain_id: u64,
46
47 orders: FramedOrders,
49
50 filleds: FramedFilleds,
52}
53
54impl OrderDetector {
55 pub fn new(contracts: HashSet<Address>, chain_id: u64, fills_only: bool) -> Self {
58 Self {
59 contracts,
60 chain_id,
61 fills_only,
62 orders: Default::default(),
63 filleds: Default::default(),
64 }
65 }
66
67 pub fn for_rollup(constants: SignetSystemConstants) -> OrderDetector {
70 Self::new(
71 std::iter::once(constants.rollup().orders()).collect(),
72 constants.ru_chain_id(),
73 false,
74 )
75 }
76
77 pub fn for_host(constants: SignetSystemConstants) -> OrderDetector {
80 Self::new(
81 std::iter::once(constants.host().orders()).collect(),
82 constants.host_chain_id(),
83 true,
84 )
85 }
86
87 pub fn is_contract(&self, address: Address) -> bool {
89 self.contracts.contains(&address)
90 }
91
92 pub const fn chain_id(&self) -> u64 {
94 self.chain_id
95 }
96
97 pub fn take(&mut self) -> (FramedOrders, FramedFilleds) {
99 (std::mem::take(&mut self.orders), std::mem::take(&mut self.filleds))
100 }
101
102 pub fn take_aggregates(&mut self) -> (AggregateFills, AggregateOrders) {
105 let (orders, filleds) = self.take();
106 (filleds.aggregate(self.chain_id()), orders.aggregate())
107 }
108
109 pub fn into_parts(self) -> (FramedOrders, FramedFilleds) {
111 (self.orders, self.filleds)
112 }
113
114 pub const fn orders(&self) -> &FramedOrders {
116 &self.orders
117 }
118
119 pub const fn filleds(&self) -> &FramedFilleds {
121 &self.filleds
122 }
123}
124
125impl<Db, Int> Inspector<Ctx<Db>, Int> for OrderDetector
126where
127 Db: Database,
128 Int: InterpreterTypes,
129{
130 fn log(&mut self, _interp: &mut Interpreter<Int>, _context: &mut Ctx<Db>, log: Log) {
131 if !self.is_contract(log.address) {
133 return;
134 }
135
136 if let Ok(Log { data, .. }) = RollupOrders::Filled::decode_log(&log) {
138 self.filleds.add(data);
139 return;
140 }
141
142 if self.fills_only {
144 return;
145 }
146
147 if let Ok(Log { data, .. }) = RollupOrders::Order::decode_log(&log) {
149 if self.fills_only {
150 return;
151 }
152 self.orders.add(data);
153 }
154 }
155
156 fn call(&mut self, _context: &mut Ctx<Db>, _inputs: &mut CallInputs) -> Option<CallOutcome> {
157 self.orders.enter_frame();
158 None
159 }
160
161 fn call_end(
162 &mut self,
163 _context: &mut Ctx<Db>,
164 _inputs: &CallInputs,
165 outcome: &mut CallOutcome,
166 ) {
167 if outcome.result.is_ok() {
168 self.orders.exit_frame();
169 } else {
170 self.orders.revert_frame();
171 }
172 }
173
174 fn create(
175 &mut self,
176 _context: &mut Ctx<Db>,
177 _inputs: &mut CreateInputs,
178 ) -> Option<CreateOutcome> {
179 self.orders.enter_frame();
180 None
181 }
182
183 fn create_end(
184 &mut self,
185 _context: &mut Ctx<Db>,
186 _inputs: &CreateInputs,
187 outcome: &mut CreateOutcome,
188 ) {
189 if outcome.result.is_ok() {
190 self.orders.exit_frame();
191 } else {
192 self.orders.revert_frame();
193 }
194 }
195
196 fn selfdestruct(&mut self, _contract: Address, _target: Address, _value: U256) {
197 self.orders.exit_frame();
198 }
199}