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;
33use cfx_types::{Address, CreateContractAddressType, Space, H256, U256};
34use std::sync::Arc;
35
36#[derive(Debug)]
37/// Result of externalities create function.
38pub enum ContractCreateResult {
39    /// Returned when creation was successful.
40    /// Contains an address of newly created contract and gas left.
41    Created(Address, U256),
42    /// Returned when contract creation failed.
43    /// Returns the reason so block trace can record it.
44    Failed(Error),
45    /// Reverted with REVERT.
46    Reverted(U256, ReturnData),
47}
48
49#[derive(Debug)]
50/// Result of externalities call function.
51pub enum MessageCallResult {
52    /// Returned when message call was successful.
53    /// Contains gas left and output data.
54    Success(U256, ReturnData),
55    /// Returned when message call failed.
56    /// Returns the reason so block trace can record it.
57    Failed(Error),
58    /// Returned when message call was reverted.
59    /// Contains gas left and output data.
60    Reverted(U256, ReturnData),
61}
62
63#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
64pub enum BlockHashSource {
65    /// Before CIP-133, block hash is read from `Env`, same as the Ethereum
66    Env,
67    /// After CIP-133, block hash is read from `State`
68    State,
69}
70
71/// Context for VMs
72pub trait Context {
73    /// Returns a value for given key.
74    fn storage_at(&self, key: &[u8]) -> Result<U256>;
75
76    /// Returns a value for given key.
77    fn origin_storage_at(&self, key: &[u8]) -> Result<Option<U256>>;
78
79    /// Stores a value for given key.
80    fn set_storage(&mut self, key: Vec<u8>, value: U256) -> Result<()>;
81
82    /// Returns a value for given key.
83    fn transient_storage_at(&self, key: &Vec<u8>) -> Result<U256>;
84
85    /// Stores a value for given key.
86    fn transient_set_storage(
87        &mut self, key: Vec<u8>, value: U256,
88    ) -> Result<()>;
89
90    /// Determine whether an account exists.
91    fn exists(&self, address: &Address) -> Result<bool>;
92
93    /// Determine whether an account exists and is not null (zero
94    /// balance/nonce, no code).
95    fn exists_and_not_null(&self, address: &Address) -> Result<bool>;
96
97    /// Balance of the origin account.
98    fn origin_balance(&self) -> Result<U256>;
99
100    /// Returns address balance.
101    fn balance(&self, address: &Address) -> Result<U256>;
102
103    /// Returns the hash of one of the 256 most recent complete blocks.
104    fn blockhash(&mut self, number: &U256) -> Result<H256>;
105
106    /// Creates new contract.
107    ///
108    /// Returns gas_left and contract address if contract creation was
109    /// succesfull.
110    fn create(
111        &mut self, gas: &U256, value: &U256, code: &[u8],
112        address: CreateContractAddressType,
113    ) -> DbResult<::std::result::Result<ContractCreateResult, TrapKind>>;
114
115    /// Message call.
116    ///
117    /// Returns Err, if we run out of gas.
118    /// Otherwise returns call_result which contains gas left
119    /// and true if subcall was successful.
120    fn call(
121        &mut self, gas: &U256, sender_address: &Address,
122        receive_address: &Address, value: Option<U256>, data: &[u8],
123        code_address: &Address, call_type: CallType,
124    ) -> DbResult<::std::result::Result<MessageCallResult, TrapKind>>;
125
126    /// Returns code at given address
127    fn extcode(&self, address: &Address) -> Result<Option<Arc<Bytes>>>;
128
129    /// Returns code hash at given address
130    fn extcodehash(&self, address: &Address) -> Result<H256>;
131
132    /// Returns code size at given address
133    fn extcodesize(&self, address: &Address) -> Result<usize>;
134
135    /// Creates log entry with given topics and data
136    fn log(&mut self, topics: Vec<H256>, data: &[u8]) -> Result<()>;
137
138    fn refund(&mut self, refund_gas: i64);
139
140    /// Should be called when transaction calls `RETURN` opcode.
141    /// Returns gas_left if cost of returning the data is not too high.
142    fn ret(
143        self, gas: &U256, data: &ReturnData, apply_state: bool,
144    ) -> Result<U256>;
145
146    /// Should be called when contract commits suicide.
147    /// Address to which funds should be refunded.
148    fn suicide(&mut self, refund_address: &Address) -> Result<()>;
149
150    /// Returns specification.
151    fn spec(&self) -> &Spec;
152
153    /// Returns environment.
154    fn env(&self) -> &Env;
155
156    /// Returns the chain ID of the blockchain
157    fn chain_id(&self) -> u64;
158
159    /// Returns the space of the blockchain
160    fn space(&self) -> Space;
161
162    /// Returns current depth of execution.
163    ///
164    /// If contract A calls contract B, and contract B calls C,
165    /// then A depth is 0, B is 1, C is 2 and so on.
166    fn depth(&self) -> usize;
167
168    fn is_warm_account(&self, account: Address) -> bool;
169
170    fn is_warm_storage_entry(&self, key: &H256) -> Result<bool>;
171
172    fn trace_step(&mut self, interpreter: &dyn InterpreterInfo) {
173        let _ = interpreter;
174    }
175
176    fn trace_step_end(&mut self, interpreter: &dyn InterpreterInfo) {
177        let _ = interpreter;
178    }
179
180    fn opcode_trace_enabled(&self) -> bool { false }
181
182    /// Check if running in static context.
183    fn is_static(&self) -> bool;
184
185    /// Check if running in static context or reentrancy context
186    fn is_static_or_reentrancy(&self) -> bool;
187
188    fn blockhash_source(&self) -> BlockHashSource;
189}