cfx_vm_types/
context.rs

1// Copyright 2015-2018 Parity Technologies (UK) Ltd.
2// This file is part of Parity.
3
4// Parity is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// Parity is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with Parity.  If not, see <http://www.gnu.org/licenses/>.
16
17// Copyright 2019 Conflux Foundation. All rights reserved.
18// Conflux is free software and distributed under GNU General Public License.
19// See http://www.gnu.org/licenses/
20
21//! Interface for Evm externalities.
22
23use super::{
24    call_create_type::CallType,
25    env::Env,
26    error::{Result, TrapKind},
27    return_data::ReturnData,
28    spec::Spec,
29    Error, InterpreterInfo,
30};
31use cfx_bytes::Bytes;
32use cfx_db_errors::statedb::Result as DbResult;
33pub use cfx_types::{
34    cal_contract_address as contract_address,
35    CreateContractAddressType as CreateContractAddress,
36};
37use cfx_types::{Address, Space, H256, U256};
38use std::sync::Arc;
39
40#[derive(Debug)]
41/// Result of externalities create function.
42pub enum ContractCreateResult {
43    /// Returned when creation was successful.
44    /// Contains an address of newly created contract and gas left.
45    Created(Address, U256),
46    /// Returned when contract creation failed.
47    /// Returns the reason so block trace can record it.
48    Failed(Error),
49    /// Reverted with REVERT.
50    Reverted(U256, ReturnData),
51}
52
53#[derive(Debug)]
54/// Result of externalities call function.
55pub enum MessageCallResult {
56    /// Returned when message call was successful.
57    /// Contains gas left and output data.
58    Success(U256, ReturnData),
59    /// Returned when message call failed.
60    /// Returns the reason so block trace can record it.
61    Failed(Error),
62    /// Returned when message call was reverted.
63    /// Contains gas left and output data.
64    Reverted(U256, ReturnData),
65}
66
67#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
68pub enum BlockHashSource {
69    /// Before CIP-133, block hash is read from `Env`, same as the Ethereum
70    Env,
71    /// After CIP-133, block hash is read from `State`
72    State,
73}
74
75/// Context for VMs
76pub trait Context {
77    /// Returns a value for given key.
78    fn storage_at(&self, key: &[u8]) -> Result<U256>;
79
80    /// Returns a value for given key.
81    fn origin_storage_at(&self, key: &[u8]) -> Result<Option<U256>>;
82
83    /// Stores a value for given key.
84    fn set_storage(&mut self, key: Vec<u8>, value: U256) -> Result<()>;
85
86    /// Returns a value for given key.
87    fn transient_storage_at(&self, key: &Vec<u8>) -> Result<U256>;
88
89    /// Stores a value for given key.
90    fn transient_set_storage(
91        &mut self, key: Vec<u8>, value: U256,
92    ) -> Result<()>;
93
94    /// Determine whether an account exists.
95    fn exists(&self, address: &Address) -> Result<bool>;
96
97    /// Determine whether an account exists and is not null (zero
98    /// balance/nonce, no code).
99    fn exists_and_not_null(&self, address: &Address) -> Result<bool>;
100
101    /// Balance of the origin account.
102    fn origin_balance(&self) -> Result<U256>;
103
104    /// Returns address balance.
105    fn balance(&self, address: &Address) -> Result<U256>;
106
107    /// Returns the hash of one of the 256 most recent complete blocks.
108    fn blockhash(&mut self, number: &U256) -> Result<H256>;
109
110    /// Creates new contract.
111    ///
112    /// Returns gas_left and contract address if contract creation was
113    /// succesfull.
114    fn create(
115        &mut self, gas: &U256, value: &U256, code: &[u8],
116        address: CreateContractAddress,
117    ) -> DbResult<::std::result::Result<ContractCreateResult, TrapKind>>;
118
119    /// Message call.
120    ///
121    /// Returns Err, if we run out of gas.
122    /// Otherwise returns call_result which contains gas left
123    /// and true if subcall was successful.
124    fn call(
125        &mut self, gas: &U256, sender_address: &Address,
126        receive_address: &Address, value: Option<U256>, data: &[u8],
127        code_address: &Address, call_type: CallType,
128    ) -> DbResult<::std::result::Result<MessageCallResult, TrapKind>>;
129
130    /// Returns code at given address
131    fn extcode(&self, address: &Address) -> Result<Option<Arc<Bytes>>>;
132
133    /// Returns code hash at given address
134    fn extcodehash(&self, address: &Address) -> Result<H256>;
135
136    /// Returns code size at given address
137    fn extcodesize(&self, address: &Address) -> Result<usize>;
138
139    /// Creates log entry with given topics and data
140    fn log(&mut self, topics: Vec<H256>, data: &[u8]) -> Result<()>;
141
142    fn refund(&mut self, refund_gas: i64);
143
144    /// Should be called when transaction calls `RETURN` opcode.
145    /// Returns gas_left if cost of returning the data is not too high.
146    fn ret(
147        self, gas: &U256, data: &ReturnData, apply_state: bool,
148    ) -> Result<U256>;
149
150    /// Should be called when contract commits suicide.
151    /// Address to which funds should be refunded.
152    fn suicide(&mut self, refund_address: &Address) -> Result<()>;
153
154    /// Returns specification.
155    fn spec(&self) -> &Spec;
156
157    /// Returns environment.
158    fn env(&self) -> &Env;
159
160    /// Returns the chain ID of the blockchain
161    fn chain_id(&self) -> u64;
162
163    /// Returns the space of the blockchain
164    fn space(&self) -> Space;
165
166    /// Returns current depth of execution.
167    ///
168    /// If contract A calls contract B, and contract B calls C,
169    /// then A depth is 0, B is 1, C is 2 and so on.
170    fn depth(&self) -> usize;
171
172    fn is_warm_account(&self, account: Address) -> bool;
173
174    fn is_warm_storage_entry(&self, key: &H256) -> Result<bool>;
175
176    fn trace_step(&mut self, interpreter: &dyn InterpreterInfo) {
177        let _ = interpreter;
178    }
179
180    fn trace_step_end(&mut self, interpreter: &dyn InterpreterInfo) {
181        let _ = interpreter;
182    }
183
184    fn opcode_trace_enabled(&self) -> bool { false }
185
186    /// Check if running in static context.
187    fn is_static(&self) -> bool;
188
189    /// Check if running in static context or reentrancy context
190    fn is_static_or_reentrancy(&self) -> bool;
191
192    fn blockhash_source(&self) -> BlockHashSource;
193}