Skip to content
This repository was archived by the owner on Nov 6, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions ethcore/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ pub struct ExecutedBlock {
uncles: Vec<Header>,
receipts: Vec<Receipt>,
transactions_set: HashSet<H256>,
state: State,
state: State<StateDB>,
traces: Option<Vec<Vec<FlatTrace>>>,
}

Expand All @@ -106,7 +106,7 @@ pub struct BlockRefMut<'a> {
/// Transaction receipts.
pub receipts: &'a [Receipt],
/// State.
pub state: &'a mut State,
pub state: &'a mut State<StateDB>,
/// Traces.
pub traces: &'a Option<Vec<Vec<FlatTrace>>>,
}
Expand All @@ -122,14 +122,14 @@ pub struct BlockRef<'a> {
/// Transaction receipts.
pub receipts: &'a [Receipt],
/// State.
pub state: &'a State,
pub state: &'a State<StateDB>,
/// Traces.
pub traces: &'a Option<Vec<Vec<FlatTrace>>>,
}

impl ExecutedBlock {
/// Create a new block from the given `state`.
fn new(state: State, tracing: bool) -> ExecutedBlock {
fn new(state: State<StateDB>, tracing: bool) -> ExecutedBlock {
ExecutedBlock {
header: Default::default(),
transactions: Default::default(),
Expand Down Expand Up @@ -184,7 +184,7 @@ pub trait IsBlock {
fn header(&self) -> &Header { &self.block().header }

/// Get the final state associated with this object's block.
fn state(&self) -> &State { &self.block().state }
fn state(&self) -> &State<StateDB> { &self.block().state }

/// Get all information on transactions in this block.
fn transactions(&self) -> &[SignedTransaction] { &self.block().transactions }
Expand Down Expand Up @@ -228,7 +228,7 @@ pub struct ClosedBlock {
block: ExecutedBlock,
uncle_bytes: Bytes,
last_hashes: Arc<LastHashes>,
unclosed_state: State,
unclosed_state: State<StateDB>,
}

/// Just like `ClosedBlock` except that we can't reopen it and it's faster.
Expand Down
6 changes: 3 additions & 3 deletions ethcore/src/client/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -656,7 +656,7 @@ impl Client {
/// This will not fail if given BlockId::Latest.
/// Otherwise, this can fail (but may not) if the DB prunes state or the block
/// is unknown.
pub fn state_at(&self, id: BlockId) -> Option<State> {
pub fn state_at(&self, id: BlockId) -> Option<State<StateDB>> {
// fast path for latest state.
match id.clone() {
BlockId::Pending => return self.miner.pending_state().or_else(|| Some(self.state())),
Expand Down Expand Up @@ -686,7 +686,7 @@ impl Client {
///
/// This will not fail if given BlockId::Latest.
/// Otherwise, this can fail (but may not) if the DB prunes state.
pub fn state_at_beginning(&self, id: BlockId) -> Option<State> {
pub fn state_at_beginning(&self, id: BlockId) -> Option<State<StateDB>> {
// fast path for latest state.
match id {
BlockId::Pending => self.state_at(BlockId::Latest),
Expand All @@ -698,7 +698,7 @@ impl Client {
}

/// Get a copy of the best block's state.
pub fn state(&self) -> State {
pub fn state(&self) -> State<StateDB> {
let header = self.best_block_header();
State::from_existing(
self.state_db.lock().boxed_clone_canon(&header.hash()),
Expand Down
14 changes: 7 additions & 7 deletions ethcore/src/executive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
//! Transaction Execution environment.
use util::*;
use action_params::{ActionParams, ActionValue};
use state::{State, Substate, CleanupMode};
use state::{Backend as StateBackend, State, Substate, CleanupMode};
use engines::Engine;
use types::executed::CallType;
use env_info::EnvInfo;
Expand Down Expand Up @@ -56,17 +56,17 @@ pub struct TransactOptions {
}

/// Transaction executor.
pub struct Executive<'a> {
state: &'a mut State,
pub struct Executive<'a, B: 'a + StateBackend> {
state: &'a mut State<B>,
info: &'a EnvInfo,
engine: &'a Engine,
vm_factory: &'a Factory,
depth: usize,
}

impl<'a> Executive<'a> {
impl<'a, B: 'a + StateBackend> Executive<'a, B> {
/// Basic constructor.
pub fn new(state: &'a mut State, info: &'a EnvInfo, engine: &'a Engine, vm_factory: &'a Factory) -> Self {
pub fn new(state: &'a mut State<B>, info: &'a EnvInfo, engine: &'a Engine, vm_factory: &'a Factory) -> Self {
Executive {
state: state,
info: info,
Expand All @@ -77,7 +77,7 @@ impl<'a> Executive<'a> {
}

/// Populates executive from parent properties. Increments executive depth.
pub fn from_parent(state: &'a mut State, info: &'a EnvInfo, engine: &'a Engine, vm_factory: &'a Factory, parent_depth: usize) -> Self {
pub fn from_parent(state: &'a mut State<B>, info: &'a EnvInfo, engine: &'a Engine, vm_factory: &'a Factory, parent_depth: usize) -> Self {
Executive {
state: state,
info: info,
Expand All @@ -95,7 +95,7 @@ impl<'a> Executive<'a> {
output: OutputPolicy<'any, 'any>,
tracer: &'any mut T,
vm_tracer: &'any mut V
) -> Externalities<'any, T, V> where T: Tracer, V: VMTracer {
) -> Externalities<'any, T, V, B> where T: Tracer, V: VMTracer {
Externalities::new(self.state, self.info, self.engine, self.vm_factory, self.depth, origin_info, substate, output, tracer, vm_tracer)
}

Expand Down
22 changes: 14 additions & 8 deletions ethcore/src/externalities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
//! Transaction Execution environment.
use util::*;
use action_params::{ActionParams, ActionValue};
use state::{State, Substate};
use state::{Backend as StateBackend, State, Substate};
use engines::Engine;
use env_info::EnvInfo;
use executive::*;
Expand Down Expand Up @@ -57,8 +57,10 @@ impl OriginInfo {
}

/// Implementation of evm Externalities.
pub struct Externalities<'a, T, V> where T: 'a + Tracer, V: 'a + VMTracer {
state: &'a mut State,
pub struct Externalities<'a, T: 'a, V: 'a, B: 'a>
where T: Tracer, V: VMTracer, B: StateBackend
{
state: &'a mut State<B>,
env_info: &'a EnvInfo,
engine: &'a Engine,
vm_factory: &'a Factory,
Expand All @@ -71,10 +73,12 @@ pub struct Externalities<'a, T, V> where T: 'a + Tracer, V: 'a + VMTracer {
vm_tracer: &'a mut V,
}

impl<'a, T, V> Externalities<'a, T, V> where T: 'a + Tracer, V: 'a + VMTracer {
#[cfg_attr(feature="dev", allow(too_many_arguments))]
impl<'a, T: 'a, V: 'a, B: 'a> Externalities<'a, T, V, B>
where T: Tracer, V: VMTracer, B: StateBackend
{
/// Basic `Externalities` constructor.
pub fn new(state: &'a mut State,
#[cfg_attr(feature="dev", allow(too_many_arguments))]
pub fn new(state: &'a mut State<B>,
env_info: &'a EnvInfo,
engine: &'a Engine,
vm_factory: &'a Factory,
Expand All @@ -101,7 +105,9 @@ impl<'a, T, V> Externalities<'a, T, V> where T: 'a + Tracer, V: 'a + VMTracer {
}
}

impl<'a, T, V> Ext for Externalities<'a, T, V> where T: 'a + Tracer, V: 'a + VMTracer {
impl<'a, T: 'a, V: 'a, B: 'a> Ext for Externalities<'a, T, V, B>
where T: Tracer, V: VMTracer, B: StateBackend
{
fn storage_at(&self, key: &H256) -> H256 {
self.state.storage_at(&self.origin_info.address, key)
}
Expand Down Expand Up @@ -346,7 +352,7 @@ mod tests {
}

struct TestSetup {
state: GuardedTempResult<State>,
state: GuardedTempResult<State<::state_db::StateDB>>,
engine: Arc<Engine>,
sub_state: Substate,
env_info: EnvInfo
Expand Down
18 changes: 12 additions & 6 deletions ethcore/src/json_tests/executive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

use super::test_common::*;
use action_params::ActionParams;
use state::{State, Substate};
use state::{Backend as StateBackend, State, Substate};
use executive::*;
use engines::Engine;
use env_info::EnvInfo;
Expand Down Expand Up @@ -51,15 +51,19 @@ impl From<ethjson::vm::Call> for CallCreate {

/// Tiny wrapper around executive externalities.
/// Stores callcreates.
struct TestExt<'a, T, V> where T: 'a + Tracer, V: 'a + VMTracer {
ext: Externalities<'a, T, V>,
struct TestExt<'a, T: 'a, V: 'a, B: 'a>
where T: Tracer, V: VMTracer, B: StateBackend
{
ext: Externalities<'a, T, V, B>,
callcreates: Vec<CallCreate>,
contract_address: Address
}

impl<'a, T, V> TestExt<'a, T, V> where T: 'a + Tracer, V: 'a + VMTracer {
impl<'a, T: 'a, V: 'a, B: 'a> TestExt<'a, T, V, B>
where T: Tracer, V: VMTracer, B: StateBackend
{
fn new(
state: &'a mut State,
state: &'a mut State<B>,
info: &'a EnvInfo,
engine: &'a Engine,
vm_factory: &'a Factory,
Expand All @@ -79,7 +83,9 @@ impl<'a, T, V> TestExt<'a, T, V> where T: 'a + Tracer, V: 'a + VMTracer {
}
}

impl<'a, T, V> Ext for TestExt<'a, T, V> where T: Tracer, V: VMTracer {
impl<'a, T: 'a, V: 'a, B: 'a> Ext for TestExt<'a, T, V, B>
where T: Tracer, V: VMTracer, B: StateBackend
{
fn storage_at(&self, key: &H256) -> H256 {
self.ext.storage_at(key)
}
Expand Down
2 changes: 1 addition & 1 deletion ethcore/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,14 +139,14 @@ pub mod snapshot;
pub mod action_params;
pub mod db;
pub mod verification;
pub mod state;
#[macro_use] pub mod evm;

mod cache_manager;
mod blooms;
mod basic_types;
mod env_info;
mod pod_account;
mod state;
mod state_db;
mod account_db;
mod builtin;
Expand Down
2 changes: 1 addition & 1 deletion ethcore/src/miner/miner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ impl Miner {
}

/// Get `Some` `clone()` of the current pending block's state or `None` if we're not sealing.
pub fn pending_state(&self) -> Option<State> {
pub fn pending_state(&self) -> Option<State<::state_db::StateDB>> {
self.sealing_work.lock().queue.peek_last_ref().map(|b| b.block().fields().state.clone())
}

Expand Down
2 changes: 1 addition & 1 deletion ethcore/src/spec/spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use executive::Executive;
use trace::{NoopTracer, NoopVMTracer};
use action_params::{ActionValue, ActionParams};
use types::executed::CallType;
use state::{State, Substate};
use state::{Backend, State, Substate};
use env_info::EnvInfo;
use pod_state::*;
use account_db::*;
Expand Down
93 changes: 93 additions & 0 deletions ethcore/src/state/backend.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
// 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/>.

//! A minimal "state backend" trait: an abstraction over the sources of data
//! a blockchain state may draw upon.
//!
//! Currently assumes a very specific DB + cache structure, but
//! should become general over time to the point where not even a
//! merkle trie is strictly necessary.

use std::sync::Arc;

use state::Account;
use util::{Address, AsHashDB, HashDB, H256};

/// State backend. See module docs for more details.
pub trait Backend: Send {
/// Treat the backend as a read-only hashdb.
fn as_hashdb(&self) -> &HashDB;

/// Treat the backend as a writeable hashdb.
fn as_hashdb_mut(&mut self) -> &mut HashDB;

/// Add an account entry to the cache.
fn add_to_account_cache(&mut self, addr: Address, data: Option<Account>, modified: bool);

/// Add a global code cache entry. This doesn't need to worry about canonicality because
/// it simply maps hashes to raw code and will always be correct in the absence of
/// hash collisions.
fn cache_code(&self, hash: H256, code: Arc<Vec<u8>>);

/// Get basic copy of the cached account. Not required to include storage.
/// Returns 'None' if cache is disabled or if the account is not cached.
fn get_cached_account(&self, addr: &Address) -> Option<Option<Account>>;

/// Get value from a cached account.
/// `None` is passed to the closure if the account entry cached
/// is known not to exist.
/// `None` is returned if the entry is not cached.
fn get_cached<F, U>(&self, a: &Address, f: F) -> Option<U>
where F: FnOnce(Option<&mut Account>) -> U;

/// Get cached code based on hash.
fn get_cached_code(&self, hash: &H256) -> Option<Arc<Vec<u8>>>;

/// Note that an account with the given address is non-null.
fn note_non_null_account(&self, address: &Address);

/// Check whether an account is known to be empty. Returns true if known to be
/// empty, false otherwise.
fn is_known_null(&self, address: &Address) -> bool;
}

/// A raw backend which simply wraps a hashdb and does no caching.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct NoCache<T>(T);

impl<T> NoCache<T> {
/// Create a new `NoCache` backend.
pub fn new(inner: T) -> Self { NoCache(inner) }

/// Consume the backend, yielding the inner database.
pub fn into_inner(self) -> T { self.0 }
}

impl<T: AsHashDB + Send> Backend for NoCache<T> {
fn as_hashdb(&self) -> &HashDB { self.0.as_hashdb() }
fn as_hashdb_mut(&mut self) -> &mut HashDB { self.0.as_hashdb_mut() }
fn add_to_account_cache(&mut self, _addr: Address, _data: Option<Account>, _modified: bool) {}
fn cache_code(&self, _hash: H256, _code: Arc<Vec<u8>>) {}
fn get_cached_account(&self, _addr: &Address) -> Option<Option<Account>> { None }
fn get_cached<F, U>(&self, _a: &Address, _f: F) -> Option<U>
where F: FnOnce(Option<&mut Account>) -> U
{
None
}
fn get_cached_code(&self, _hash: &H256) -> Option<Arc<Vec<u8>>> { None }
fn note_non_null_account(&self, _address: &Address) {}
fn is_known_null(&self, _address: &Address) -> bool { false }
}
Loading