revm_interpreter/instructions/contract/
call_helpers.rs

1use crate::{
2    gas,
3    interpreter::Interpreter,
4    primitives::{Bytes, Spec, SpecId::*, U256},
5    AccountLoad,
6};
7use core::{cmp::min, ops::Range};
8
9#[inline]
10pub fn get_memory_input_and_out_ranges(
11    interpreter: &mut Interpreter,
12) -> Option<(Bytes, Range<usize>)> {
13    pop_ret!(interpreter, in_offset, in_len, out_offset, out_len, None);
14
15    let in_range = resize_memory(interpreter, in_offset, in_len)?;
16
17    let mut input = Bytes::new();
18    if !in_range.is_empty() {
19        input = Bytes::copy_from_slice(interpreter.shared_memory.slice_range(in_range));
20    }
21
22    let ret_range = resize_memory(interpreter, out_offset, out_len)?;
23    Some((input, ret_range))
24}
25
26/// Resize memory and return range of memory.
27/// If `len` is 0 dont touch memory and return `usize::MAX` as offset and 0 as length.
28#[inline]
29pub fn resize_memory(
30    interpreter: &mut Interpreter,
31    offset: U256,
32    len: U256,
33) -> Option<Range<usize>> {
34    let len = as_usize_or_fail_ret!(interpreter, len, None);
35    let offset = if len != 0 {
36        let offset = as_usize_or_fail_ret!(interpreter, offset, None);
37        resize_memory!(interpreter, offset, len, None);
38        offset
39    } else {
40        usize::MAX //unrealistic value so we are sure it is not used
41    };
42    Some(offset..offset + len)
43}
44
45#[inline]
46pub fn calc_call_gas<SPEC: Spec>(
47    interpreter: &mut Interpreter,
48    account_load: AccountLoad,
49    has_transfer: bool,
50    local_gas_limit: u64,
51) -> Option<u64> {
52    let call_cost = gas::call_cost(SPEC::SPEC_ID, has_transfer, account_load);
53    gas!(interpreter, call_cost, None);
54
55    // EIP-150: Gas cost changes for IO-heavy operations
56    let gas_limit = if SPEC::enabled(TANGERINE) {
57        // take l64 part of gas_limit
58        min(
59            interpreter.gas().remaining_63_of_64_parts(),
60            local_gas_limit,
61        )
62    } else {
63        local_gas_limit
64    };
65
66    Some(gas_limit)
67}