Integrate Executive into State.
This commit is contained in:
parent
7650dead6d
commit
0004ed8960
@ -3,7 +3,9 @@ use util::hash::*;
|
|||||||
use util::uint::*;
|
use util::uint::*;
|
||||||
use util::bytes::*;
|
use util::bytes::*;
|
||||||
|
|
||||||
/// Evm input params. Everything else should be specified in Externalities.
|
// TODO: should be a trait, possible to avoid cloning everything from a Transaction(/View).
|
||||||
|
|
||||||
|
/// Action (call/create) input params. Everything else should be specified in Externalities.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct ActionParams {
|
pub struct ActionParams {
|
||||||
/// Address of currently executed code.
|
/// Address of currently executed code.
|
||||||
|
@ -170,12 +170,12 @@ impl<'x, 'y> OpenBlock<'x, 'y> {
|
|||||||
pub fn push_transaction(&mut self, t: Transaction, h: Option<H256>) -> Result<&Receipt, Error> {
|
pub fn push_transaction(&mut self, t: Transaction, h: Option<H256>) -> Result<&Receipt, Error> {
|
||||||
let env_info = self.env_info();
|
let env_info = self.env_info();
|
||||||
match self.block.state.apply(&env_info, self.engine, &t) {
|
match self.block.state.apply(&env_info, self.engine, &t) {
|
||||||
Ok(x) => {
|
Ok(receipt) => {
|
||||||
self.block.archive_set.insert(h.unwrap_or_else(||t.hash()));
|
self.block.archive_set.insert(h.unwrap_or_else(||t.hash()));
|
||||||
self.block.archive.push(Entry { transaction: t, receipt: x.receipt });
|
self.block.archive.push(Entry { transaction: t, receipt: receipt });
|
||||||
Ok(&self.block.archive.last().unwrap().receipt)
|
Ok(&self.block.archive.last().unwrap().receipt)
|
||||||
}
|
}
|
||||||
Err(x) => Err(x)
|
Err(x) => Err(From::from(x))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
24
src/error.rs
24
src/error.rs
@ -16,6 +16,23 @@ pub struct OutOfBounds<T: fmt::Debug> {
|
|||||||
pub found: T,
|
pub found: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Result of executing the transaction.
|
||||||
|
#[derive(PartialEq, Debug)]
|
||||||
|
pub enum ExecutionError {
|
||||||
|
/// Returned when block (gas_used + gas) > gas_limit.
|
||||||
|
///
|
||||||
|
/// If gas =< gas_limit, upstream may try to execute the transaction
|
||||||
|
/// in next block.
|
||||||
|
BlockGasLimitReached { gas_limit: U256, gas_used: U256, gas: U256 },
|
||||||
|
/// Returned when transaction nonce does not match state nonce.
|
||||||
|
InvalidNonce { expected: U256, is: U256 },
|
||||||
|
/// Returned when cost of transaction (value + gas_price * gas) exceeds
|
||||||
|
/// current sender balance.
|
||||||
|
NotEnoughCash { required: U256, is: U256 },
|
||||||
|
/// Returned when internal evm error occurs.
|
||||||
|
Internal
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum BlockError {
|
pub enum BlockError {
|
||||||
TooManyUncles(OutOfBounds<usize>),
|
TooManyUncles(OutOfBounds<usize>),
|
||||||
@ -65,6 +82,7 @@ pub enum Error {
|
|||||||
Util(UtilError),
|
Util(UtilError),
|
||||||
Block(BlockError),
|
Block(BlockError),
|
||||||
UnknownEngineName(String),
|
UnknownEngineName(String),
|
||||||
|
Execution(ExecutionError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<BlockError> for Error {
|
impl From<BlockError> for Error {
|
||||||
@ -73,6 +91,12 @@ impl From<BlockError> for Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<ExecutionError> for Error {
|
||||||
|
fn from(err: ExecutionError) -> Error {
|
||||||
|
Error::Execution(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: uncomment below once https://github.com/rust-lang/rust/issues/27336 sorted.
|
// TODO: uncomment below once https://github.com/rust-lang/rust/issues/27336 sorted.
|
||||||
/*#![feature(concat_idents)]
|
/*#![feature(concat_idents)]
|
||||||
macro_rules! assimilate {
|
macro_rules! assimilate {
|
||||||
|
@ -55,26 +55,10 @@ pub struct Executed {
|
|||||||
/// where `tn` is current transaction.
|
/// where `tn` is current transaction.
|
||||||
pub cumulative_gas_used: U256,
|
pub cumulative_gas_used: U256,
|
||||||
/// Vector of logs generated by transaction.
|
/// Vector of logs generated by transaction.
|
||||||
pub logs: Vec<LogEntry>
|
pub logs: Vec<LogEntry>,
|
||||||
}
|
|
||||||
|
|
||||||
/// Result of executing the transaction.
|
/// Execution ended running out of gas.
|
||||||
#[derive(PartialEq, Debug)]
|
pub out_of_gas: bool,
|
||||||
pub enum ExecutionError {
|
|
||||||
/// Returned when block (gas_used + gas) > gas_limit.
|
|
||||||
///
|
|
||||||
/// If gas =< gas_limit, upstream may try to execute the transaction
|
|
||||||
/// in next block.
|
|
||||||
BlockGasLimitReached { gas_limit: U256, gas_used: U256, gas: U256 },
|
|
||||||
/// Returned when transaction nonce does not match state nonce.
|
|
||||||
InvalidNonce { expected: U256, is: U256 },
|
|
||||||
/// Returned when cost of transaction (value + gas_price * gas) exceeds
|
|
||||||
/// current sender balance.
|
|
||||||
NotEnoughCash { required: U256, is: U256 },
|
|
||||||
/// Returned when transaction execution runs out of gas.
|
|
||||||
OutOfGas,
|
|
||||||
/// Returned when internal evm error occurs.
|
|
||||||
Internal
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type ExecutionResult = Result<Executed, ExecutionError>;
|
pub type ExecutionResult = Result<Executed, ExecutionError>;
|
||||||
@ -228,7 +212,14 @@ impl<'a> Executive<'a> {
|
|||||||
Err(evm::Error::Internal) => Err(ExecutionError::Internal),
|
Err(evm::Error::Internal) => Err(ExecutionError::Internal),
|
||||||
Err(evm::Error::OutOfGas) => {
|
Err(evm::Error::OutOfGas) => {
|
||||||
*self.state = backup;
|
*self.state = backup;
|
||||||
Err(ExecutionError::OutOfGas)
|
Ok(Executed {
|
||||||
|
gas: t.gas,
|
||||||
|
gas_used: t.gas,
|
||||||
|
refunded: U256::zero(),
|
||||||
|
cumulative_gas_used: self.info.gas_used + t.gas,
|
||||||
|
logs: vec![],
|
||||||
|
out_of_gas: true,
|
||||||
|
})
|
||||||
},
|
},
|
||||||
Ok(gas_left) => {
|
Ok(gas_left) => {
|
||||||
let schedule = self.engine.schedule(self.info);
|
let schedule = self.engine.schedule(self.info);
|
||||||
@ -259,7 +250,8 @@ impl<'a> Executive<'a> {
|
|||||||
gas_used: gas_used,
|
gas_used: gas_used,
|
||||||
refunded: refund,
|
refunded: refund,
|
||||||
cumulative_gas_used: self.info.gas_used + gas_used,
|
cumulative_gas_used: self.info.gas_used + gas_used,
|
||||||
logs: substate.logs
|
logs: substate.logs,
|
||||||
|
out_of_gas: false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -499,6 +491,8 @@ mod tests {
|
|||||||
assert_eq!(state.storage_at(&address, &H256::new()), H256::from(&U256::from(0xf9u64)));
|
assert_eq!(state.storage_at(&address, &H256::new()), H256::from(&U256::from(0xf9u64)));
|
||||||
assert_eq!(state.balance(&sender), U256::from(0xf9));
|
assert_eq!(state.balance(&sender), U256::from(0xf9));
|
||||||
assert_eq!(state.balance(&address), U256::from(0x7));
|
assert_eq!(state.balance(&address), U256::from(0x7));
|
||||||
|
|
||||||
|
// TODO: just test state root.
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -10,6 +10,17 @@ pub struct Receipt {
|
|||||||
pub logs: Vec<LogEntry>,
|
pub logs: Vec<LogEntry>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Receipt {
|
||||||
|
pub fn new(state_root: H256, gas_used: U256, logs: Vec<LogEntry>) -> Receipt {
|
||||||
|
Receipt {
|
||||||
|
state_root: state_root,
|
||||||
|
gas_used: gas_used,
|
||||||
|
log_bloom: logs.iter().fold(LogBloom::new(), |mut b, l| { b |= &l.bloom(); b }),
|
||||||
|
logs: logs,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl RlpStandard for Receipt {
|
impl RlpStandard for Receipt {
|
||||||
fn rlp_append(&self, s: &mut RlpStream) {
|
fn rlp_append(&self, s: &mut RlpStream) {
|
||||||
s.append_list(4);
|
s.append_list(4);
|
||||||
|
13
src/state.rs
13
src/state.rs
@ -1,13 +1,8 @@
|
|||||||
use common::*;
|
use common::*;
|
||||||
use engine::Engine;
|
use engine::Engine;
|
||||||
//use executive::Executive;
|
use executive::Executive;
|
||||||
|
|
||||||
/// Information concerning the result of the `State::apply` operation.
|
pub type ApplyResult = Result<Receipt, ExecutionError>;
|
||||||
pub struct ApplyInfo {
|
|
||||||
pub receipt: Receipt,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type ApplyResult = Result<ApplyInfo, Error>;
|
|
||||||
|
|
||||||
/// Representation of the entire state of all accounts in the system.
|
/// Representation of the entire state of all accounts in the system.
|
||||||
pub struct State {
|
pub struct State {
|
||||||
@ -136,7 +131,9 @@ impl State {
|
|||||||
/// Execute a given transaction.
|
/// Execute a given transaction.
|
||||||
/// This will change the state accordingly.
|
/// This will change the state accordingly.
|
||||||
pub fn apply(&mut self, env_info: &EnvInfo, engine: &Engine, t: &Transaction) -> ApplyResult {
|
pub fn apply(&mut self, env_info: &EnvInfo, engine: &Engine, t: &Transaction) -> ApplyResult {
|
||||||
unimplemented!();
|
let e = try!(Executive::new(self, env_info, engine).transact(t));
|
||||||
|
self.commit();
|
||||||
|
Ok(Receipt::new(self.root().clone(), e.gas_used, e.logs))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert into a JSON representation.
|
/// Convert into a JSON representation.
|
||||||
|
Loading…
Reference in New Issue
Block a user