openethereum/ethcore/vm/src/ext.rs

155 lines
5.2 KiB
Rust
Raw Normal View History

// Copyright 2015-2017 Parity Technologies (UK) Ltd.
2016-02-05 13:40:41 +01:00
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// 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.
// Parity is distributed in the hope that it will be useful,
// 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
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
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;
2017-09-04 16:36:49 +02:00
use bigint::prelude::U256;
use bigint::hash::H256;
use util::*;
use bytes::Bytes;
use call_type::CallType;
use env_info::EnvInfo;
use schedule::Schedule;
use return_data::ReturnData;
use error::Result;
2016-01-06 13:00:14 +01:00
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.
Failed,
/// Reverted with REVERT.
Reverted(U256, ReturnData),
2016-01-16 20:11:12 +01:00
}
/// Result of externalities call function.
pub enum MessageCallResult {
/// Returned when message call was successfull.
/// 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.
Failed,
/// Returned when message call was reverted.
/// Contains gas left and output data.
Reverted(U256, ReturnData),
2016-01-16 20:11:12 +01:00
}
/// Specifies how an address is calculated for a new contract.
#[derive(Copy, Clone, PartialEq, Eq)]
pub enum CreateContractAddress {
/// Address is calculated from nonce and sender. Pre EIP-86 (Metropolis)
FromSenderAndNonce,
/// Address is calculated from code hash. Default since EIP-86
FromCodeHash,
/// Address is calculated from code hash and sender. Used by CREATE_P2SH instruction.
FromSenderAndCodeHash,
}
2016-01-20 16:52:22 +01:00
/// Externalities interface for EVMs
2016-01-09 00:51:09 +01:00
pub trait Ext {
2016-01-07 23:33:54 +01:00
/// Returns a value for given key.
fn storage_at(&self, key: &H256) -> Result<H256>;
2016-01-07 23:33:54 +01:00
/// Stores a value for given key.
fn set_storage(&mut self, key: H256, value: H256) -> Result<()>;
2016-01-16 20:11:12 +01:00
/// Determine whether an account exists.
fn exists(&self, address: &Address) -> Result<bool>;
2016-01-07 23:33:54 +01:00
/// Determine whether an account exists and is not null (zero balance/nonce, no code).
fn exists_and_not_null(&self, address: &Address) -> Result<bool>;
/// Balance of the origin account.
fn origin_balance(&self) -> Result<U256>;
2016-01-07 23:33:54 +01:00
/// Returns address balance.
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.
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
///
2016-01-14 21:21:46 +01:00
/// Returns gas_left and contract address if contract creation was succesfull.
fn create(&mut self, gas: &U256, value: &U256, code: &[u8], address: CreateContractAddress) -> ContractCreateResult;
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.
2016-03-18 10:14:19 +01:00
#[cfg_attr(feature="dev", allow(too_many_arguments))]
2016-02-29 22:21:15 +01:00
fn call(&mut self,
gas: &U256,
sender_address: &Address,
receive_address: &Address,
value: Option<U256>,
data: &[u8],
code_address: &Address,
output: &mut [u8],
call_type: CallType
) -> MessageCallResult;
2016-01-07 23:33:54 +01:00
/// Returns code at given address
fn extcode(&self, address: &Address) -> Result<Arc<Bytes>>;
2016-01-07 23:33:54 +01:00
/// Returns code size at given address
fn extcodesize(&self, address: &Address) -> Result<usize>;
2016-01-07 23:33:54 +01:00
/// Creates log entry with given topics and data
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.
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.
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
/// 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;
/// Increments sstore refunds count by 1.
fn inc_sstore_clears(&mut self);
/// Decide if any more operations should be traced. Passthrough for the VM trace.
fn trace_next_instruction(&mut self, _pc: usize, _instruction: u8) -> bool { false }
/// Prepare to trace an operation. Passthrough for the VM trace.
fn trace_prepare_execute(&mut self, _pc: usize, _instruction: u8, _gas_cost: U256) {}
/// Trace the finalised execution of a single instruction.
fn trace_executed(&mut self, _gas_used: U256, _stack_push: &[U256], _mem_diff: Option<(usize, &[u8])>, _store_diff: Option<(U256, U256)>) {}
/// Check if running in static context.
fn is_static(&self) -> bool;
2016-01-07 23:33:54 +01:00
}