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::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)]
|
||||
pub struct ActionParams {
|
||||
/// 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> {
|
||||
let env_info = self.env_info();
|
||||
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.push(Entry { transaction: t, receipt: x.receipt });
|
||||
self.block.archive.push(Entry { transaction: t, receipt: 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,
|
||||
}
|
||||
|
||||
/// 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)]
|
||||
pub enum BlockError {
|
||||
TooManyUncles(OutOfBounds<usize>),
|
||||
@ -65,6 +82,7 @@ pub enum Error {
|
||||
Util(UtilError),
|
||||
Block(BlockError),
|
||||
UnknownEngineName(String),
|
||||
Execution(ExecutionError),
|
||||
}
|
||||
|
||||
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.
|
||||
/*#![feature(concat_idents)]
|
||||
macro_rules! assimilate {
|
||||
|
@ -55,26 +55,10 @@ pub struct Executed {
|
||||
/// where `tn` is current transaction.
|
||||
pub cumulative_gas_used: U256,
|
||||
/// Vector of logs generated by transaction.
|
||||
pub logs: Vec<LogEntry>
|
||||
}
|
||||
pub logs: Vec<LogEntry>,
|
||||
|
||||
/// 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 transaction execution runs out of gas.
|
||||
OutOfGas,
|
||||
/// Returned when internal evm error occurs.
|
||||
Internal
|
||||
/// Execution ended running out of gas.
|
||||
pub out_of_gas: bool,
|
||||
}
|
||||
|
||||
pub type ExecutionResult = Result<Executed, ExecutionError>;
|
||||
@ -228,7 +212,14 @@ impl<'a> Executive<'a> {
|
||||
Err(evm::Error::Internal) => Err(ExecutionError::Internal),
|
||||
Err(evm::Error::OutOfGas) => {
|
||||
*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) => {
|
||||
let schedule = self.engine.schedule(self.info);
|
||||
@ -259,7 +250,8 @@ impl<'a> Executive<'a> {
|
||||
gas_used: gas_used,
|
||||
refunded: refund,
|
||||
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.balance(&sender), U256::from(0xf9));
|
||||
assert_eq!(state.balance(&address), U256::from(0x7));
|
||||
|
||||
// TODO: just test state root.
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -10,6 +10,17 @@ pub struct Receipt {
|
||||
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 {
|
||||
fn rlp_append(&self, s: &mut RlpStream) {
|
||||
s.append_list(4);
|
||||
|
13
src/state.rs
13
src/state.rs
@ -1,13 +1,8 @@
|
||||
use common::*;
|
||||
use engine::Engine;
|
||||
//use executive::Executive;
|
||||
use executive::Executive;
|
||||
|
||||
/// Information concerning the result of the `State::apply` operation.
|
||||
pub struct ApplyInfo {
|
||||
pub receipt: Receipt,
|
||||
}
|
||||
|
||||
pub type ApplyResult = Result<ApplyInfo, Error>;
|
||||
pub type ApplyResult = Result<Receipt, ExecutionError>;
|
||||
|
||||
/// Representation of the entire state of all accounts in the system.
|
||||
pub struct State {
|
||||
@ -136,7 +131,9 @@ impl State {
|
||||
/// Execute a given transaction.
|
||||
/// This will change the state accordingly.
|
||||
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.
|
||||
|
Loading…
Reference in New Issue
Block a user