multiplexer_evm/
flow_builder.rs1use alloy_primitives::{Address, U256};
2
3use crate::opcodes::{
4 Call, ClearData, Create, DelegateCall, ExtCodeCopy, SetAddr, SetData, SetValue, SetCallback, SetFail, ClearFail,
5};
6
7enum Action {
9 ClearData(ClearData),
10 SetData(SetData),
11 SetAddr(SetAddr),
12 SetValue(SetValue),
13 ExtCodeCopy(ExtCodeCopy),
14 Call(Call),
15 Create(Create),
16 DelegateCall(DelegateCall),
17 SetFail(SetFail),
18 ClearFail(ClearFail),
19 SetCallback(SetCallback)
20}
21
22impl Action {
23 fn encode(&self) -> Vec<u8> {
24 match self {
25 Action::ClearData(cd) => cd.encode(),
26 Action::SetData(sd) => sd.encode(),
27 Action::SetAddr(sa) => sa.encode(),
28 Action::SetValue(sv) => sv.encode(),
29 Action::ExtCodeCopy(ecc) => ecc.encode(),
30 Action::Call(c) => c.encode(),
31 Action::Create(c) => c.encode(),
32 Action::DelegateCall(dc) => dc.encode(),
33 Action::SetFail(sf) => sf.encode(),
34 Action::ClearFail(cf) => cf.encode(),
35 Action::SetCallback(scb) => scb.encode(),
36 }
37 }
38}
39
40#[derive(Default)]
42pub struct FlowBuilder {
43 actions: Vec<Action>,
44}
45
46impl FlowBuilder {
47 pub fn empty() -> Self {
49 Self::default()
50 }
51
52 fn peephole_opt(&mut self) {
54 let mut ops_to_remove = Vec::new();
55 let mut last_value = U256::ZERO;
56 let mut last_target = Address::ZERO;
57 let mut last_data: Vec<u8> = Vec::new();
58 let mut last_fail = false;
59
60 for (idx, action) in self.actions.iter().enumerate() {
61 let to_remove = match action {
62 Action::SetFail(_) => {
63 if last_fail {
64 true
65 } else {
66 last_fail = true;
67 false
68 }
69 }
70 Action::ClearFail(_) => {
71 if last_fail {
72 last_fail = false;
73 false
74 } else {
75 true
76 }
77 }
78 Action::Call(_) => {
79 last_value = U256::ZERO;
80 false
81 }
82 Action::Create(Create { created_address }) => {
83 last_target = *created_address;
84 last_value = U256::ZERO;
85 false
86 }
87 Action::SetAddr(SetAddr { addr }) => {
88 let res = last_target == *addr;
89 last_target = *addr;
90 res
91 }
92 Action::SetValue(SetValue { value }) => {
93 let res = last_value == *value;
94 last_value = *value;
95 res
96 }
97 Action::ClearData(ClearData { size }) => {
98 let res = last_data.len() == *size as usize;
99 last_data = vec![0; *size as usize];
100 res
101 }
102 Action::SetData(SetData { offset, data }) => {
103 let offset_uz = *offset as usize;
104 let mut new_data = last_data.clone();
105 new_data.splice(offset_uz..offset_uz + data.len(), data.to_owned());
106 let res = last_data == new_data;
107 last_data = new_data;
108 res
109 }
110 _ => false,
111 };
112 if to_remove {
113 ops_to_remove.push(idx);
114 }
115 }
116
117 for idx in ops_to_remove.into_iter().rev() {
118 self.actions.remove(idx);
119 }
120 }
121
122 pub fn set_extcodecopy_op(&mut self, source: Address, data_offset: u16, code_offset: u16, size: u16) -> &mut Self {
124 self.actions.push(Action::ExtCodeCopy(ExtCodeCopy {
125 source,
126 data_offset,
127 code_offset,
128 size,
129 }));
130 self
131 }
132
133 pub fn set_addr_op(&mut self, addr: Address) -> &mut Self {
135 self.actions.push(Action::SetAddr(SetAddr { addr }));
136 self
137 }
138
139 pub fn set_value_op(&mut self, value: U256) -> &mut Self {
141 self.actions.push(Action::SetValue(SetValue { value }));
142 self
143 }
144
145 pub fn set_data_op(&mut self, offset: u16, data: &[u8]) -> &mut Self {
147 self.actions.push(Action::SetData(SetData {
148 offset,
149 data: data.to_owned(),
150 }));
151 self
152 }
153
154 pub fn set_cleardata_op(&mut self, size: u16) -> &mut Self {
156 self.actions.push(Action::ClearData(ClearData { size }));
157 self
158 }
159
160 pub fn call_op(&mut self) -> &mut Self {
162 self.actions.push(Action::Call(Call::new()));
163 self
164 }
165
166 pub fn create_op(&mut self, created_address: Address) -> &mut Self {
168 self.actions.push(Action::Create(Create { created_address }));
169 self
170 }
171
172 pub fn delegatecall_op(&mut self) -> &mut Self {
174 self.actions.push(Action::DelegateCall(DelegateCall::new()));
175 self
176 }
177
178 pub fn call(&mut self, target: Address, data: &[u8], value: U256) -> &mut Self {
180 assert!(data.len() < u16::MAX as usize, "datalen exceeds 0xffff");
181
182 self.set_addr_op(target)
183 .set_value_op(value)
184 .set_cleardata_op(data.len() as u16)
185 .set_data_op(0, data)
186 .call_op()
187 }
188
189 pub fn delegatecall(&mut self, target: Address, data: &[u8]) -> &mut Self {
191 self.set_addr_op(target)
192 .set_cleardata_op(data.len() as u16)
193 .set_data_op(0, data)
194 .delegatecall_op()
195 }
196
197 pub fn create(&mut self, created_address: Address, data: &[u8], value: U256) -> &mut Self {
199 self.set_value_op(value)
200 .set_cleardata_op(data.len() as u16)
201 .set_data_op(0, data)
202 .create_op(created_address)
203 }
204
205 pub fn set_callback(&mut self, callback_address: Address) -> &mut Self {
207 self.actions.push(Action::SetCallback(SetCallback::new(callback_address)));
208 self
209 }
210
211 pub fn set_fail(&mut self) -> &mut Self {
213 self.actions.push(Action::SetFail(SetFail::new()));
214 self
215 }
216
217 pub fn clear_fail(&mut self) -> &mut Self {
219 self.actions.push(Action::ClearFail(ClearFail::new()));
220 self
221 }
222
223 pub fn optimize(&mut self) -> &mut Self {
225 self.peephole_opt();
226 self
227 }
228
229 pub fn build_raw(&mut self) -> Vec<u8> {
231 let mut res = Vec::new();
232 for action in &self.actions {
233 res.extend(&action.encode());
234 }
235 res
236 }
237
238
239 pub fn build(&mut self) -> Vec<u8> {
241 let mut res = vec![0xc9, 0x4f, 0x55, 0x4d];
245 res.extend(self.build_raw());
246 res
247 }
248}