revm_interpreter/instructions/
system.rs1use crate::{
2 gas,
3 interpreter::Interpreter,
4 interpreter_types::{
5 InputsTr, InterpreterTypes, LegacyBytecode, MemoryTr, ReturnData, RuntimeFlag, StackTr,
6 },
7 CallInput, InstructionResult,
8};
9use core::ptr;
10use primitives::{B256, KECCAK_EMPTY, U256};
11
12use crate::InstructionContext;
13
14pub fn keccak256<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
18 popn_top!([offset], top, context.interpreter);
19 let len = as_usize_or_fail!(context.interpreter, top);
20 gas_or_fail!(context.interpreter, gas::keccak256_cost(len));
21 let hash = if len == 0 {
22 KECCAK_EMPTY
23 } else {
24 let from = as_usize_or_fail!(context.interpreter, offset);
25 resize_memory!(context.interpreter, from, len);
26 primitives::keccak256(context.interpreter.memory.slice_len(from, len).as_ref())
27 };
28 *top = hash.into();
29}
30
31pub fn address<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
35 gas!(context.interpreter, gas::BASE);
36 push!(
37 context.interpreter,
38 context
39 .interpreter
40 .input
41 .target_address()
42 .into_word()
43 .into()
44 );
45}
46
47pub fn caller<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
51 gas!(context.interpreter, gas::BASE);
52 push!(
53 context.interpreter,
54 context
55 .interpreter
56 .input
57 .caller_address()
58 .into_word()
59 .into()
60 );
61}
62
63pub fn codesize<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
67 gas!(context.interpreter, gas::BASE);
68 push!(
69 context.interpreter,
70 U256::from(context.interpreter.bytecode.bytecode_len())
71 );
72}
73
74pub fn codecopy<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
78 popn!([memory_offset, code_offset, len], context.interpreter);
79 let len = as_usize_or_fail!(context.interpreter, len);
80 let Some(memory_offset) = memory_resize(context.interpreter, memory_offset, len) else {
81 return;
82 };
83 let code_offset = as_usize_saturated!(code_offset);
84
85 context.interpreter.memory.set_data(
87 memory_offset,
88 code_offset,
89 len,
90 context.interpreter.bytecode.bytecode_slice(),
91 );
92}
93
94pub fn calldataload<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
98 gas!(context.interpreter, gas::VERYLOW);
99 popn_top!([], offset_ptr, context.interpreter);
101 let mut word = B256::ZERO;
102 let offset = as_usize_saturated!(offset_ptr);
103 let input = context.interpreter.input.input();
104 let input_len = input.len();
105 if offset < input_len {
106 let count = 32.min(input_len - offset);
107
108 match context.interpreter.input.input() {
113 CallInput::Bytes(bytes) => {
114 unsafe {
115 ptr::copy_nonoverlapping(bytes.as_ptr().add(offset), word.as_mut_ptr(), count)
116 };
117 }
118 CallInput::SharedBuffer(range) => {
119 let input_slice = context.interpreter.memory.global_slice(range.clone());
120 unsafe {
121 ptr::copy_nonoverlapping(
122 input_slice.as_ptr().add(offset),
123 word.as_mut_ptr(),
124 count,
125 )
126 };
127 }
128 }
129 }
130 *offset_ptr = word.into();
131}
132
133pub fn calldatasize<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
137 gas!(context.interpreter, gas::BASE);
138 push!(
139 context.interpreter,
140 U256::from(context.interpreter.input.input().len())
141 );
142}
143
144pub fn callvalue<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
148 gas!(context.interpreter, gas::BASE);
149 push!(context.interpreter, context.interpreter.input.call_value());
150}
151
152pub fn calldatacopy<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
156 popn!([memory_offset, data_offset, len], context.interpreter);
157 let len = as_usize_or_fail!(context.interpreter, len);
158 let Some(memory_offset) = memory_resize(context.interpreter, memory_offset, len) else {
159 return;
160 };
161
162 let data_offset = as_usize_saturated!(data_offset);
163 match context.interpreter.input.input() {
164 CallInput::Bytes(bytes) => {
165 context
166 .interpreter
167 .memory
168 .set_data(memory_offset, data_offset, len, bytes.as_ref());
169 }
170 CallInput::SharedBuffer(range) => {
171 context.interpreter.memory.set_data_from_global(
172 memory_offset,
173 data_offset,
174 len,
175 range.clone(),
176 );
177 }
178 }
179}
180
181pub fn returndatasize<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
183 check!(context.interpreter, BYZANTIUM);
184 gas!(context.interpreter, gas::BASE);
185 push!(
186 context.interpreter,
187 U256::from(context.interpreter.return_data.buffer().len())
188 );
189}
190
191pub fn returndatacopy<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
193 check!(context.interpreter, BYZANTIUM);
194 popn!([memory_offset, offset, len], context.interpreter);
195
196 let len = as_usize_or_fail!(context.interpreter, len);
197 let data_offset = as_usize_saturated!(offset);
198
199 let data_end = data_offset.saturating_add(len);
201 if data_end > context.interpreter.return_data.buffer().len() {
202 context.interpreter.halt(InstructionResult::OutOfOffset);
203 return;
204 }
205
206 let Some(memory_offset) = memory_resize(context.interpreter, memory_offset, len) else {
207 return;
208 };
209
210 context.interpreter.memory.set_data(
212 memory_offset,
213 data_offset,
214 len,
215 context.interpreter.return_data.buffer(),
216 );
217}
218
219pub fn gas<WIRE: InterpreterTypes, H: ?Sized>(context: InstructionContext<'_, H, WIRE>) {
223 gas!(context.interpreter, gas::BASE);
224 push!(
225 context.interpreter,
226 U256::from(context.interpreter.gas.remaining())
227 );
228}
229
230pub fn memory_resize(
234 interpreter: &mut Interpreter<impl InterpreterTypes>,
235 memory_offset: U256,
236 len: usize,
237) -> Option<usize> {
238 gas_or_fail!(interpreter, gas::copy_cost_verylow(len), None);
240 if len == 0 {
241 return None;
242 }
243 let memory_offset = as_usize_or_fail_ret!(interpreter, memory_offset, None);
244 resize_memory!(interpreter, memory_offset, len, None);
245
246 Some(memory_offset)
247}