mep_vm/ext.rs
1// Copyright 2015-2020 Parity Technologies (UK) Ltd.
2// This file is part of Parity Ethereum.
3
4// Parity Ethereum 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 Ethereum 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 Ethereum. If not, see <http://www.gnu.org/licenses/>.
16
17//! Interface for Evm externalities.
18
19use std::sync::Arc;
20use ethereum_types::{U256, H256, Address};
21use bytes::Bytes;
22use action_type::ActionType;
23use env_info::EnvInfo;
24use schedule::Schedule;
25use return_data::ReturnData;
26use error::{Result, TrapKind};
27
28#[derive(Debug)]
29/// Result of externalities create function.
30pub enum ContractCreateResult {
31 /// Returned when creation was successfull.
32 /// Contains an address of newly created contract and gas left.
33 Created(Address, U256),
34 /// Returned when contract creation failed.
35 /// VM doesn't have to know the reason.
36 Failed,
37 /// Reverted with REVERT.
38 Reverted(U256, ReturnData),
39}
40
41#[derive(Debug)]
42/// Result of externalities call function.
43pub enum MessageCallResult {
44 /// Returned when message call was successfull.
45 /// Contains gas left and output data.
46 Success(U256, ReturnData),
47 /// Returned when message call failed.
48 /// VM doesn't have to know the reason.
49 Failed,
50 /// Returned when message call was reverted.
51 /// Contains gas left and output data.
52 Reverted(U256, ReturnData),
53}
54
55/// Specifies how an address is calculated for a new contract.
56#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
57pub enum CreateContractAddress {
58 /// Address is calculated from sender and nonce. pWASM `create` scheme.
59 FromSenderAndNonce,
60 /// Address is calculated from sender, salt and code hash. pWASM `create2` scheme and EIP-1014 CREATE2 scheme.
61 FromSenderSaltAndCodeHash(H256),
62 /// Address is calculated from code hash and sender. Used by pwasm create ext.
63 FromSenderAndCodeHash,
64}
65
66/// Externalities interface for EVMs
67pub trait Ext {
68 /// Returns the storage value for a given key if reversion happens on the current transaction.
69 fn initial_storage_at(&self, key: &H256) -> Result<H256>;
70
71 /// Returns a value for given key.
72 fn storage_at(&self, key: &H256) -> Result<H256>;
73
74 /// Stores a value for given key.
75 fn set_storage(&mut self, key: H256, value: H256) -> Result<()>;
76
77 /// Determine whether an account exists.
78 fn exists(&self, address: &Address) -> Result<bool>;
79
80 /// Determine whether an account exists and is not null (zero balance/nonce, no code).
81 fn exists_and_not_null(&self, address: &Address) -> Result<bool>;
82
83 /// Balance of the origin account.
84 fn origin_balance(&self) -> Result<U256>;
85
86 /// Returns address balance.
87 fn balance(&self, address: &Address) -> Result<U256>;
88
89 /// Returns the hash of one of the 256 most recent complete blocks.
90 fn blockhash(&mut self, number: &U256) -> H256;
91
92 /// Creates new contract.
93 ///
94 /// Returns gas_left and contract address if contract creation was successful.
95 fn create(
96 &mut self,
97 gas: &U256,
98 value: &U256,
99 code: &[u8],
100 parent_version: &U256,
101 address: CreateContractAddress,
102 trap: bool,
103 ) -> ::std::result::Result<ContractCreateResult, TrapKind>;
104
105 /// Message call.
106 ///
107 /// Returns Err, if we run out of gas.
108 /// Otherwise returns call_result which contains gas left
109 /// and true if subcall was successfull.
110 fn call(
111 &mut self,
112 gas: &U256,
113 sender_address: &Address,
114 receive_address: &Address,
115 value: Option<U256>,
116 data: &[u8],
117 code_address: &Address,
118 call_type: ActionType,
119 trap: bool
120 ) -> ::std::result::Result<MessageCallResult, TrapKind>;
121
122 /// Returns code at given address
123 fn extcode(&self, address: &Address) -> Result<Option<Arc<Bytes>>>;
124
125 /// Returns code hash at given address
126 fn extcodehash(&self, address: &Address) -> Result<Option<H256>>;
127
128 /// Returns code size at given address
129 fn extcodesize(&self, address: &Address) -> Result<Option<usize>>;
130
131 /// Creates log entry with given topics and data
132 fn log(&mut self, topics: Vec<H256>, data: &[u8]) -> Result<()>;
133
134 /// Should be called when transaction calls `RETURN` opcode.
135 /// Returns gas_left if cost of returning the data is not too high.
136 fn ret(self, gas: &U256, data: &ReturnData, apply_state: bool) -> Result<U256>;
137
138 /// Should be called when contract commits suicide.
139 /// Address to which funds should be refunded.
140 fn suicide(&mut self, refund_address: &Address) -> Result<()> ;
141
142 /// Returns schedule.
143 fn schedule(&self) -> &Schedule;
144
145 /// Returns environment info.
146 fn env_info(&self) -> &EnvInfo;
147
148 /// Returns the chain ID of the blockchain
149 fn chain_id(&self) -> u64;
150
151 /// Returns current depth of execution.
152 ///
153 /// If contract A calls contract B, and contract B calls C,
154 /// then A depth is 0, B is 1, C is 2 and so on.
155 fn depth(&self) -> usize;
156
157 /// Increments sstore refunds counter.
158 fn add_sstore_refund(&mut self, value: usize);
159
160 /// Decrements sstore refunds counter.
161 fn sub_sstore_refund(&mut self, value: usize);
162
163 /// Decide if any more operations should be traced. Passthrough for the VM trace.
164 fn trace_next_instruction(&mut self, _pc: usize, _instruction: u8, _current_gas: U256) -> bool { false }
165
166 /// Prepare to trace an operation. Passthrough for the VM trace.
167 /// For each call of `trace_prepare_execute` either `trace_failed` or `trace_executed` MUST be called.
168 fn trace_prepare_execute(&mut self, _pc: usize, _instruction: u8, _gas_cost: U256, _mem_written: Option<(usize, usize)>, _store_written: Option<(U256, U256)>) {}
169
170 /// Trace the execution failure of a single instruction.
171 fn trace_failed(&mut self) {}
172
173 /// Trace the finalised execution of a single instruction.
174 fn trace_executed(&mut self, _gas_used: U256, _stack_push: &[U256], _mem: &[u8]) {}
175
176 /// Check if running in static context.
177 fn is_static(&self) -> bool;
178}