2019-01-07 11:33:07 +01:00
|
|
|
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
|
|
|
|
// This file is part of Parity Ethereum.
|
2016-02-05 13:40:41 +01:00
|
|
|
|
2019-01-07 11:33:07 +01:00
|
|
|
// Parity Ethereum is free software: you can redistribute it and/or modify
|
2016-02-05 13:40:41 +01:00
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
|
2019-01-07 11:33:07 +01:00
|
|
|
// Parity Ethereum is distributed in the hope that it will be useful,
|
2016-02-05 13:40:41 +01:00
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
|
|
|
|
// You should have received a copy of the GNU General Public License
|
2019-01-07 11:33:07 +01:00
|
|
|
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
2016-02-05 13:40:41 +01:00
|
|
|
|
2016-01-09 21:39:38 +01:00
|
|
|
//! Interface for Evm externalities.
|
2015-12-30 12:46:10 +01:00
|
|
|
|
2017-07-29 21:56:42 +02:00
|
|
|
use std::sync::Arc;
|
2018-01-10 13:35:18 +01:00
|
|
|
use ethereum_types::{U256, H256, Address};
|
2017-09-06 20:47:45 +02:00
|
|
|
use bytes::Bytes;
|
2020-01-13 11:10:24 +01:00
|
|
|
use action_type::ActionType;
|
2017-07-12 13:09:17 +02:00
|
|
|
use env_info::EnvInfo;
|
|
|
|
use schedule::Schedule;
|
2017-08-01 12:37:57 +02:00
|
|
|
use return_data::ReturnData;
|
2018-10-02 16:33:19 +02:00
|
|
|
use error::{Result, TrapKind};
|
2016-01-06 13:00:14 +01:00
|
|
|
|
2018-10-02 16:33:19 +02:00
|
|
|
#[derive(Debug)]
|
2016-01-16 20:11:12 +01:00
|
|
|
/// Result of externalities create function.
|
|
|
|
pub enum ContractCreateResult {
|
|
|
|
/// Returned when creation was successfull.
|
|
|
|
/// Contains an address of newly created contract and gas left.
|
|
|
|
Created(Address, U256),
|
|
|
|
/// Returned when contract creation failed.
|
|
|
|
/// VM doesn't have to know the reason.
|
2017-09-15 21:07:54 +02:00
|
|
|
Failed,
|
|
|
|
/// Reverted with REVERT.
|
|
|
|
Reverted(U256, ReturnData),
|
2016-01-16 20:11:12 +01:00
|
|
|
}
|
|
|
|
|
2018-10-02 16:33:19 +02:00
|
|
|
#[derive(Debug)]
|
2016-01-16 20:11:12 +01:00
|
|
|
/// Result of externalities call function.
|
|
|
|
pub enum MessageCallResult {
|
|
|
|
/// Returned when message call was successfull.
|
2017-06-06 17:47:12 +02:00
|
|
|
/// Contains gas left and output data.
|
|
|
|
Success(U256, ReturnData),
|
2016-01-16 20:11:12 +01:00
|
|
|
/// Returned when message call failed.
|
|
|
|
/// VM doesn't have to know the reason.
|
2017-09-15 21:07:54 +02:00
|
|
|
Failed,
|
|
|
|
/// Returned when message call was reverted.
|
|
|
|
/// Contains gas left and output data.
|
|
|
|
Reverted(U256, ReturnData),
|
2016-01-16 20:11:12 +01:00
|
|
|
}
|
|
|
|
|
2017-04-19 14:30:00 +02:00
|
|
|
/// Specifies how an address is calculated for a new contract.
|
2018-08-06 17:15:52 +02:00
|
|
|
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
|
2017-04-19 14:30:00 +02:00
|
|
|
pub enum CreateContractAddress {
|
2018-08-31 17:43:51 +02:00
|
|
|
/// Address is calculated from sender and nonce. pWASM `create` scheme.
|
2017-04-19 14:30:00 +02:00
|
|
|
FromSenderAndNonce,
|
2018-08-31 17:43:51 +02:00
|
|
|
/// Address is calculated from sender, salt and code hash. pWASM `create2` scheme and EIP-1014 CREATE2 scheme.
|
2018-08-01 13:17:04 +02:00
|
|
|
FromSenderSaltAndCodeHash(H256),
|
|
|
|
/// Address is calculated from code hash and sender. Used by pwasm create ext.
|
2017-04-19 14:30:00 +02:00
|
|
|
FromSenderAndCodeHash,
|
|
|
|
}
|
|
|
|
|
2016-01-20 16:52:22 +01:00
|
|
|
/// Externalities interface for EVMs
|
2016-01-09 00:51:09 +01:00
|
|
|
pub trait Ext {
|
2018-09-07 12:51:08 +02:00
|
|
|
/// Returns the storage value for a given key if reversion happens on the current transaction.
|
|
|
|
fn initial_storage_at(&self, key: &H256) -> Result<H256>;
|
|
|
|
|
2016-01-07 23:33:54 +01:00
|
|
|
/// Returns a value for given key.
|
2017-08-01 12:37:57 +02:00
|
|
|
fn storage_at(&self, key: &H256) -> Result<H256>;
|
2016-01-07 23:33:54 +01:00
|
|
|
|
|
|
|
/// Stores a value for given key.
|
2017-08-01 12:37:57 +02:00
|
|
|
fn set_storage(&mut self, key: H256, value: H256) -> Result<()>;
|
2016-01-16 20:11:12 +01:00
|
|
|
|
|
|
|
/// Determine whether an account exists.
|
2017-08-01 12:37:57 +02:00
|
|
|
fn exists(&self, address: &Address) -> Result<bool>;
|
2016-01-07 23:33:54 +01:00
|
|
|
|
2016-11-03 22:22:25 +01:00
|
|
|
/// Determine whether an account exists and is not null (zero balance/nonce, no code).
|
2017-08-01 12:37:57 +02:00
|
|
|
fn exists_and_not_null(&self, address: &Address) -> Result<bool>;
|
2016-11-03 22:22:25 +01:00
|
|
|
|
|
|
|
/// Balance of the origin account.
|
2017-08-01 12:37:57 +02:00
|
|
|
fn origin_balance(&self) -> Result<U256>;
|
2016-11-03 22:22:25 +01:00
|
|
|
|
2016-01-07 23:33:54 +01:00
|
|
|
/// Returns address balance.
|
2017-08-01 12:37:57 +02:00
|
|
|
fn balance(&self, address: &Address) -> Result<U256>;
|
2016-01-07 23:33:54 +01:00
|
|
|
|
|
|
|
/// Returns the hash of one of the 256 most recent complete blocks.
|
2017-05-30 11:52:33 +02:00
|
|
|
fn blockhash(&mut self, number: &U256) -> H256;
|
2016-01-07 23:33:54 +01:00
|
|
|
|
|
|
|
/// Creates new contract.
|
2016-02-29 22:21:15 +01:00
|
|
|
///
|
2019-08-29 13:19:55 +02:00
|
|
|
/// Returns gas_left and contract address if contract creation was successful.
|
2018-10-02 16:33:19 +02:00
|
|
|
fn create(
|
|
|
|
&mut self,
|
|
|
|
gas: &U256,
|
|
|
|
value: &U256,
|
|
|
|
code: &[u8],
|
2019-07-08 12:03:27 +02:00
|
|
|
parent_version: &U256,
|
2018-10-02 16:33:19 +02:00
|
|
|
address: CreateContractAddress,
|
|
|
|
trap: bool,
|
|
|
|
) -> ::std::result::Result<ContractCreateResult, TrapKind>;
|
2016-01-09 23:24:01 +01:00
|
|
|
|
|
|
|
/// Message call.
|
2016-02-29 22:21:15 +01:00
|
|
|
///
|
2016-01-14 21:21:46 +01:00
|
|
|
/// Returns Err, if we run out of gas.
|
2016-02-29 22:21:15 +01:00
|
|
|
/// Otherwise returns call_result which contains gas left
|
2016-01-14 19:52:40 +01:00
|
|
|
/// and true if subcall was successfull.
|
2018-10-02 16:33:19 +02:00
|
|
|
fn call(
|
|
|
|
&mut self,
|
2016-07-27 17:41:21 +02:00
|
|
|
gas: &U256,
|
|
|
|
sender_address: &Address,
|
|
|
|
receive_address: &Address,
|
|
|
|
value: Option<U256>,
|
|
|
|
data: &[u8],
|
|
|
|
code_address: &Address,
|
2020-01-13 11:10:24 +01:00
|
|
|
call_type: ActionType,
|
2018-10-02 16:33:19 +02:00
|
|
|
trap: bool
|
|
|
|
) -> ::std::result::Result<MessageCallResult, TrapKind>;
|
2016-01-07 23:33:54 +01:00
|
|
|
|
|
|
|
/// Returns code at given address
|
2018-07-31 07:27:57 +02:00
|
|
|
fn extcode(&self, address: &Address) -> Result<Option<Arc<Bytes>>>;
|
|
|
|
|
|
|
|
/// Returns code hash at given address
|
|
|
|
fn extcodehash(&self, address: &Address) -> Result<Option<H256>>;
|
2016-01-07 23:33:54 +01:00
|
|
|
|
2016-09-22 19:58:42 +02:00
|
|
|
/// Returns code size at given address
|
2018-07-31 07:27:57 +02:00
|
|
|
fn extcodesize(&self, address: &Address) -> Result<Option<usize>>;
|
2016-09-22 19:58:42 +02:00
|
|
|
|
2016-01-07 23:33:54 +01:00
|
|
|
/// Creates log entry with given topics and data
|
2017-08-01 12:37:57 +02:00
|
|
|
fn log(&mut self, topics: Vec<H256>, data: &[u8]) -> Result<()>;
|
2016-01-11 02:17:29 +01:00
|
|
|
|
|
|
|
/// Should be called when transaction calls `RETURN` opcode.
|
|
|
|
/// Returns gas_left if cost of returning the data is not too high.
|
2017-09-15 21:07:54 +02:00
|
|
|
fn ret(self, gas: &U256, data: &ReturnData, apply_state: bool) -> Result<U256>;
|
2016-01-11 02:17:29 +01:00
|
|
|
|
|
|
|
/// Should be called when contract commits suicide.
|
2016-01-13 16:16:21 +01:00
|
|
|
/// Address to which funds should be refunded.
|
2017-08-01 12:37:57 +02:00
|
|
|
fn suicide(&mut self, refund_address: &Address) -> Result<()> ;
|
2016-01-11 02:17:29 +01:00
|
|
|
|
|
|
|
/// Returns schedule.
|
2016-01-11 16:28:30 +01:00
|
|
|
fn schedule(&self) -> &Schedule;
|
2016-01-11 22:32:01 +01:00
|
|
|
|
|
|
|
/// Returns environment info.
|
|
|
|
fn env_info(&self) -> &EnvInfo;
|
2016-01-16 20:11:12 +01:00
|
|
|
|
2019-08-28 16:15:50 +02:00
|
|
|
/// Returns the chain ID of the blockchain
|
|
|
|
fn chain_id(&self) -> u64;
|
|
|
|
|
2016-01-16 20:11:12 +01:00
|
|
|
/// Returns current depth of execution.
|
2016-02-29 22:21:15 +01:00
|
|
|
///
|
2016-01-16 20:11:12 +01:00
|
|
|
/// If contract A calls contract B, and contract B calls C,
|
|
|
|
/// then A depth is 0, B is 1, C is 2 and so on.
|
|
|
|
fn depth(&self) -> usize;
|
|
|
|
|
2018-09-07 12:51:08 +02:00
|
|
|
/// Increments sstore refunds counter.
|
2018-10-15 11:09:55 +02:00
|
|
|
fn add_sstore_refund(&mut self, value: usize);
|
2018-09-07 12:51:08 +02:00
|
|
|
|
|
|
|
/// Decrements sstore refunds counter.
|
2018-10-15 11:09:55 +02:00
|
|
|
fn sub_sstore_refund(&mut self, value: usize);
|
2016-06-02 12:40:31 +02:00
|
|
|
|
2017-07-10 13:23:40 +02:00
|
|
|
/// Decide if any more operations should be traced. Passthrough for the VM trace.
|
2018-01-18 10:32:22 +01:00
|
|
|
fn trace_next_instruction(&mut self, _pc: usize, _instruction: u8, _current_gas: U256) -> bool { false }
|
2017-07-10 13:23:40 +02:00
|
|
|
|
2016-06-02 12:40:31 +02:00
|
|
|
/// Prepare to trace an operation. Passthrough for the VM trace.
|
2019-09-05 16:11:51 +02:00
|
|
|
/// For each call of `trace_prepare_execute` either `trace_failed` or `trace_executed` MUST be called.
|
2018-10-02 16:33:19 +02:00
|
|
|
fn trace_prepare_execute(&mut self, _pc: usize, _instruction: u8, _gas_cost: U256, _mem_written: Option<(usize, usize)>, _store_written: Option<(U256, U256)>) {}
|
2016-06-02 12:40:31 +02:00
|
|
|
|
2019-09-05 16:11:51 +02:00
|
|
|
/// Trace the execution failure of a single instruction.
|
|
|
|
fn trace_failed(&mut self) {}
|
|
|
|
|
2016-06-02 12:40:31 +02:00
|
|
|
/// Trace the finalised execution of a single instruction.
|
2018-10-02 16:33:19 +02:00
|
|
|
fn trace_executed(&mut self, _gas_used: U256, _stack_push: &[U256], _mem: &[u8]) {}
|
2017-09-15 21:07:54 +02:00
|
|
|
|
|
|
|
/// Check if running in static context.
|
|
|
|
fn is_static(&self) -> bool;
|
2016-01-07 23:33:54 +01:00
|
|
|
}
|