revm_interpreter/interpreter_action/
eof_create_inputs.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
use crate::primitives::{Address, Bytes, Eof, TxEnv, U256};

/// EOF create can be called from two places:
/// * EOFCREATE opcode
/// * Creation transaction.
///
/// Creation transaction uses initdata and packs EOF and initdata inside it.
/// This eof bytecode needs to be validated.
///
/// Opcode creation uses already validated EOF bytecode, and input from Interpreter memory.
/// Address is already known and is passed as an argument.
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum EOFCreateKind {
    Tx {
        initdata: Bytes,
    },
    Opcode {
        initcode: Eof,
        input: Bytes,
        created_address: Address,
    },
}

impl EOFCreateKind {
    /// Returns created address
    pub fn created_address(&self) -> Option<&Address> {
        match self {
            EOFCreateKind::Opcode {
                created_address, ..
            } => Some(created_address),
            EOFCreateKind::Tx { .. } => None,
        }
    }
}

impl Default for EOFCreateKind {
    fn default() -> Self {
        EOFCreateKind::Opcode {
            initcode: Eof::default(),
            input: Bytes::default(),
            created_address: Address::default(),
        }
    }
}

/// Inputs for EOF create call.
#[derive(Debug, Default, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct EOFCreateInputs {
    /// Caller of Eof Craate
    pub caller: Address,
    /// Values of ether transferred
    pub value: U256,
    /// Gas limit for the create call.
    pub gas_limit: u64,
    /// EOF Create kind
    pub kind: EOFCreateKind,
}

impl EOFCreateInputs {
    /// Create new EOF crate input from transaction that has concatenated eof init code and calldata.
    ///
    /// Legacy transaction still have optional nonce so we need to obtain it.
    pub fn new(caller: Address, value: U256, gas_limit: u64, kind: EOFCreateKind) -> Self {
        //let (eof_init_code, input) = Eof::decode_dangling(tx.data.clone())?;
        EOFCreateInputs {
            caller,
            value,
            gas_limit,
            kind,
        }
    }

    /// Creates new EOFCreateInputs from transaction.
    pub fn new_tx(tx: &TxEnv, gas_limit: u64) -> Self {
        EOFCreateInputs::new(
            tx.caller,
            tx.value,
            gas_limit,
            EOFCreateKind::Tx {
                initdata: tx.data.clone(),
            },
        )
    }

    /// Returns a new instance of EOFCreateInput.
    pub fn new_opcode(
        caller: Address,
        created_address: Address,
        value: U256,
        eof_init_code: Eof,
        gas_limit: u64,
        input: Bytes,
    ) -> EOFCreateInputs {
        EOFCreateInputs::new(
            caller,
            value,
            gas_limit,
            EOFCreateKind::Opcode {
                initcode: eof_init_code,
                input,
                created_address,
            },
        )
    }
}