diff --git a/src/engine.rs b/src/engine.rs index edc1cddf7..b89b86f9e 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -1,5 +1,7 @@ use std::collections::hash_map::*; use util::bytes::*; +use util::uint::*; +use util::rlp::*; use util::semantic_version::*; use util::error::*; use header::Header; @@ -30,6 +32,16 @@ pub trait Engine { /// Get the EVM schedule for fn evm_schedule(&self, env_info: &EnvInfo) -> EvmSchedule; + /// Some intrinsic operation parameters; by default they take their value from the `spec()`'s `engine_params`. + fn maximum_extra_data_size(&self, _env_info: &EnvInfo) -> usize { decode(&self.spec().engine_params.get("maximum_extra_data_size").unwrap()) } + fn account_start_nonce(&self, _env_info: &EnvInfo) -> U256 { decode(&self.spec().engine_params.get("account_start_nonce").unwrap()) } + // TODO: refactor in terms of `on_preseal_block` + fn block_reward(&self, _env_info: &EnvInfo) -> U256 { decode(&self.spec().engine_params.get("block_reward").unwrap()) } + + /// Block transformation functions, before and after the transactions. +// fn on_new_block(&self, _env_info: &EnvInfo, _block: &mut Block) -> Result<(), EthcoreError> {} +// fn on_preseal_block(&self, _env_info: &EnvInfo, _block: &mut Block) -> Result<(), EthcoreError> {} + /// Verify that `header` is valid. /// `parent` (the parent header) and `block` (the header's full block) may be provided for additional /// checks. Returns either a null `Ok` or a general error detailing the problem with import. @@ -42,8 +54,8 @@ pub trait Engine { /// Don't forget to call Super::populateFromParent when subclassing & overriding. fn populate_from_parent(&self, _header: &mut Header, _parent: &Header) -> Result<(), EthcoreError> { Ok(()) } - // TODO: buildin contract routing - this will require removing the built-in configuration reading logic from Spec - // into here and removing the Spec::builtins field. It's a big job. + // TODO: buildin contract routing - to do this properly, it will require removing the built-in configuration-reading logic + // from Spec into here and removing the Spec::builtins field. /* fn is_builtin(&self, a: Address) -> bool; fn cost_of_builtin(&self, a: Address, in: &[u8]) -> bignum; fn execute_builtin(&self, a: Address, in: &[u8], out: &mut [u8]); diff --git a/src/spec.rs b/src/spec.rs index 2b0eb9496..b62da9620 100644 --- a/src/spec.rs +++ b/src/spec.rs @@ -19,11 +19,9 @@ pub struct Spec { // What engine are we using for this? pub engine_name: String, - // Various parameters for the chain operation. - pub block_reward: U256, - pub maximum_extra_data_size: U256, - pub account_start_nonce: U256, - pub misc: HashMap, + // Parameters concerning operation of the specific engine we're using. + // Name -> RLP-encoded value + pub engine_params: HashMap, // Builtin-contracts are here for now but would like to abstract into Engine API eventually. pub builtins: HashMap, @@ -62,10 +60,6 @@ impl Spec { Ref::map(self.state_root_memo.borrow(), |x|x.as_ref().unwrap()) } - pub fn block_reward(&self) -> U256 { self.block_reward } - pub fn maximum_extra_data_size(&self) -> U256 { self.maximum_extra_data_size } - pub fn account_start_nonce(&self) -> U256 { self.account_start_nonce } - /// Compose the genesis block for this chain. pub fn genesis_block(&self) -> Bytes { // TODO @@ -78,10 +72,10 @@ impl Spec { pub fn olympic() -> Spec { Spec { engine_name: "Ethash".to_string(), - block_reward: finney() * U256::from(1500u64), - maximum_extra_data_size: U256::from(1024u64), - account_start_nonce: U256::from(0u64), - misc: vec![ + engine_params: vec![ + ("block_reward", encode(&(finney() * U256::from(1500u64)))), + ("maximum_extra_data_size", encode(&U256::from(1024u64))), + ("account_start_nonce", encode(&U256::from(0u64))), ("gas_limit_bounds_divisor", encode(&1024u64)), ("minimum_difficulty", encode(&131_072u64)), ("difficulty_bound_divisor", encode(&2048u64)), @@ -115,10 +109,10 @@ impl Spec { pub fn frontier() -> Spec { Spec { engine_name: "Ethash".to_string(), - block_reward: ether() * U256::from(5u64), - maximum_extra_data_size: U256::from(32u64), - account_start_nonce: U256::from(0u64), - misc: vec![ + engine_params: vec![ + ("block_reward", encode(&(ether() * U256::from(5u64)))), + ("maximum_extra_data_size", encode(&U256::from(32u64))), + ("account_start_nonce", encode(&U256::from(0u64))), ("gas_limit_bounds_divisor", encode(&1024u64)), ("minimum_difficulty", encode(&131_072u64)), ("difficulty_bound_divisor", encode(&2048u64)), @@ -152,10 +146,10 @@ impl Spec { pub fn morden() -> Spec { Spec { engine_name: "Ethash".to_string(), - block_reward: ether() * U256::from(5u64), - maximum_extra_data_size: U256::from(32u64), - account_start_nonce: U256::from(1u64) << 20, - misc: vec![ + engine_params: vec![ + ("block_reward", encode(&(ether() * U256::from(5u64)))), + ("maximum_extra_data_size", encode(&U256::from(32u64))), + ("account_start_nonce", encode(&(U256::from(1u64) << 20))), ("gas_limit_bounds_divisor", encode(&1024u64)), ("minimum_difficulty", encode(&131_072u64)), ("difficulty_bound_divisor", encode(&2048u64)),