2016-12-11 19:30:54 +01:00
// Copyright 2015, 2016 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-02-02 15:29:53 +01:00
//! Parameters for a block chain.
2016-10-24 18:35:25 +02:00
use util ::* ;
use builtin ::Builtin ;
2016-11-16 11:29:54 +01:00
use engines ::{ Engine , NullEngine , InstantSeal , BasicAuthority , AuthorityRound , Tendermint } ;
2016-12-23 18:44:39 +01:00
use factory ::Factories ;
use executive ::Executive ;
use trace ::{ NoopTracer , NoopVMTracer } ;
use action_params ::{ ActionValue , ActionParams } ;
use types ::executed ::CallType ;
use state ::{ State , Substate } ;
use env_info ::EnvInfo ;
2016-01-25 18:56:36 +01:00
use pod_state ::* ;
2016-02-05 01:49:06 +01:00
use account_db ::* ;
2016-10-24 18:35:25 +02:00
use header ::{ BlockNumber , Header } ;
2016-09-27 18:02:11 +02:00
use state_db ::StateDB ;
2016-04-09 19:20:35 +02:00
use super ::genesis ::Genesis ;
use super ::seal ::Generic as GenericSeal ;
2016-03-17 15:15:10 +01:00
use ethereum ;
2016-04-09 19:20:35 +02:00
use ethjson ;
2016-09-01 14:29:59 +02:00
use rlp ::{ Rlp , RlpStream , View , Stream } ;
2016-04-09 19:20:35 +02:00
/// Parameters common to all engines.
2016-12-05 16:20:32 +01:00
#[ derive(Debug, PartialEq, Clone, Default) ]
2016-04-09 19:20:35 +02:00
pub struct CommonParams {
/// Account start nonce.
pub account_start_nonce : U256 ,
/// Maximum size of extra data.
pub maximum_extra_data_size : usize ,
/// Network id.
2016-12-04 19:48:26 +01:00
pub network_id : u64 ,
2016-12-22 13:10:58 +01:00
/// Chain id.
pub chain_id : u64 ,
2016-09-28 14:21:59 +02:00
/// Main subprotocol name.
pub subprotocol_name : String ,
2016-04-09 19:20:35 +02:00
/// Minimum gas limit.
pub min_gas_limit : U256 ,
2016-07-27 21:38:22 +02:00
/// Fork block to check.
pub fork_block : Option < ( BlockNumber , H256 ) > ,
2015-12-23 12:53:34 +01:00
}
2016-04-09 19:20:35 +02:00
impl From < ethjson ::spec ::Params > for CommonParams {
fn from ( p : ethjson ::spec ::Params ) -> Self {
CommonParams {
2016-12-22 07:06:40 +01:00
account_start_nonce : p . account_start_nonce . map_or_else ( U256 ::zero , Into ::into ) ,
2016-04-09 19:20:35 +02:00
maximum_extra_data_size : p . maximum_extra_data_size . into ( ) ,
network_id : p . network_id . into ( ) ,
2016-12-22 13:10:58 +01:00
chain_id : if let Some ( n ) = p . chain_id { n . into ( ) } else { p . network_id . into ( ) } ,
2016-09-28 14:21:59 +02:00
subprotocol_name : p . subprotocol_name . unwrap_or_else ( | | " eth " . to_owned ( ) ) ,
2016-04-09 19:20:35 +02:00
min_gas_limit : p . min_gas_limit . into ( ) ,
2016-07-27 21:38:22 +02:00
fork_block : if let ( Some ( n ) , Some ( h ) ) = ( p . fork_block , p . fork_hash ) { Some ( ( n . into ( ) , h . into ( ) ) ) } else { None } ,
2016-04-09 19:20:35 +02:00
}
}
2015-12-21 22:08:42 +01:00
}
2015-12-20 21:45:43 +01:00
/// Parameters for a block chain; includes both those intrinsic to the design of the
/// chain and those to be interpreted by the active chain engine.
pub struct Spec {
2016-02-03 13:20:32 +01:00
/// User friendly spec name
2016-01-14 22:38:49 +01:00
pub name : String ,
2016-02-03 13:20:32 +01:00
/// What engine are we using for this?
2016-08-05 17:00:46 +02:00
pub engine : Arc < Engine > ,
2016-12-12 23:21:44 +01:00
/// Name of the subdir inside the main data dir to use for chain data and settings.
2016-12-12 16:51:07 +01:00
pub data_dir : String ,
2015-12-20 21:45:43 +01:00
2016-01-23 23:53:20 +01:00
/// Known nodes on the network in enode format.
pub nodes : Vec < String > ,
2015-12-20 21:45:43 +01:00
2016-04-09 19:20:35 +02:00
/// Parameters common to all engines.
pub params : CommonParams ,
2015-12-20 21:45:43 +01:00
2016-02-03 13:20:32 +01:00
/// The genesis block's parent hash field.
2015-12-20 21:45:43 +01:00
pub parent_hash : H256 ,
2016-02-03 13:20:32 +01:00
/// The genesis block's author field.
2015-12-20 21:45:43 +01:00
pub author : Address ,
2016-02-03 13:20:32 +01:00
/// The genesis block's difficulty field.
2015-12-20 21:45:43 +01:00
pub difficulty : U256 ,
2016-02-03 13:20:32 +01:00
/// The genesis block's gas limit field.
2015-12-20 21:45:43 +01:00
pub gas_limit : U256 ,
2016-02-03 13:20:32 +01:00
/// The genesis block's gas used field.
2015-12-20 21:45:43 +01:00
pub gas_used : U256 ,
2016-02-03 13:20:32 +01:00
/// The genesis block's timestamp field.
2016-01-10 22:55:07 +01:00
pub timestamp : u64 ,
2016-01-28 22:06:25 +01:00
/// Transactions root of the genesis block. Should be SHA3_NULL_RLP.
pub transactions_root : H256 ,
/// Receipts root of the genesis block. Should be SHA3_NULL_RLP.
pub receipts_root : H256 ,
2016-02-03 13:20:32 +01:00
/// The genesis block's extra data field.
2015-12-20 21:45:43 +01:00
pub extra_data : Bytes ,
2016-02-03 13:20:32 +01:00
/// Each seal field, expressed as RLP, concatenated.
2015-12-20 21:45:43 +01:00
pub seal_rlp : Bytes ,
2016-12-23 18:44:39 +01:00
/// Contract constructors to be executed on genesis.
constructors : Vec < ( Address , Bytes ) > ,
/// May be prepopulated if we know this in advance.
2016-01-11 11:51:31 +01:00
state_root_memo : RwLock < Option < H256 > > ,
2016-02-03 13:20:32 +01:00
2016-12-23 18:44:39 +01:00
/// Genesis state as plain old data.
2016-02-03 13:20:32 +01:00
genesis_state : PodState ,
2015-12-20 21:45:43 +01:00
}
2016-04-09 19:20:35 +02:00
impl From < ethjson ::spec ::Spec > for Spec {
fn from ( s : ethjson ::spec ::Spec ) -> Self {
let builtins = s . accounts . builtins ( ) . into_iter ( ) . map ( | p | ( p . 0. into ( ) , From ::from ( p . 1 ) ) ) . collect ( ) ;
let g = Genesis ::from ( s . genesis ) ;
2016-12-14 12:50:32 +01:00
let GenericSeal ( seal_rlp ) = g . seal . into ( ) ;
2016-04-09 19:20:35 +02:00
let params = CommonParams ::from ( s . params ) ;
Spec {
2016-12-12 16:51:07 +01:00
name : s . name . clone ( ) . into ( ) ,
2016-04-09 19:20:35 +02:00
params : params . clone ( ) ,
engine : Spec ::engine ( s . engine , params , builtins ) ,
2016-12-12 16:51:07 +01:00
data_dir : s . data_dir . unwrap_or ( s . name ) . into ( ) ,
2016-04-09 19:20:35 +02:00
nodes : s . nodes . unwrap_or_else ( Vec ::new ) ,
parent_hash : g . parent_hash ,
transactions_root : g . transactions_root ,
receipts_root : g . receipts_root ,
author : g . author ,
difficulty : g . difficulty ,
gas_limit : g . gas_limit ,
gas_used : g . gas_used ,
timestamp : g . timestamp ,
extra_data : g . extra_data ,
2016-12-14 12:50:32 +01:00
seal_rlp : seal_rlp ,
2016-12-23 18:44:39 +01:00
constructors : s . accounts . constructors ( ) . into_iter ( ) . map ( | ( a , c ) | ( a . into ( ) , c . into ( ) ) ) . collect ( ) ,
2016-04-09 19:20:35 +02:00
state_root_memo : RwLock ::new ( g . state_root ) ,
2016-07-25 10:20:22 +02:00
genesis_state : From ::from ( s . accounts ) ,
2016-04-09 19:20:35 +02:00
}
}
}
2016-11-11 17:37:44 +01:00
macro_rules ! load_bundled {
( $e :expr ) = > {
2016-11-14 15:29:33 +01:00
Spec ::load ( include_bytes! ( concat! ( " ../../res/ " , $e , " .json " ) ) as & [ u8 ] ) . expect ( concat! ( " Chain spec " , $e , " is invalid. " ) )
2016-11-11 17:37:44 +01:00
} ;
}
2015-12-20 21:45:43 +01:00
impl Spec {
2016-08-05 17:00:46 +02:00
/// Convert engine spec into a arc'd Engine of the right underlying type.
2016-04-09 19:20:35 +02:00
/// TODO avoid this hard-coded nastiness - use dynamic-linked plugin framework instead.
2016-08-05 17:00:46 +02:00
fn engine ( engine_spec : ethjson ::spec ::Engine , params : CommonParams , builtins : BTreeMap < Address , Builtin > ) -> Arc < Engine > {
2016-04-09 19:20:35 +02:00
match engine_spec {
2016-08-05 17:00:46 +02:00
ethjson ::spec ::Engine ::Null = > Arc ::new ( NullEngine ::new ( params , builtins ) ) ,
ethjson ::spec ::Engine ::InstantSeal = > Arc ::new ( InstantSeal ::new ( params , builtins ) ) ,
ethjson ::spec ::Engine ::Ethash ( ethash ) = > Arc ::new ( ethereum ::Ethash ::new ( params , From ::from ( ethash . params ) , builtins ) ) ,
ethjson ::spec ::Engine ::BasicAuthority ( basic_authority ) = > Arc ::new ( BasicAuthority ::new ( params , From ::from ( basic_authority . params ) , builtins ) ) ,
2016-11-16 11:29:54 +01:00
ethjson ::spec ::Engine ::AuthorityRound ( authority_round ) = > AuthorityRound ::new ( params , From ::from ( authority_round . params ) , builtins ) . expect ( " Failed to start AuthorityRound consensus engine. " ) ,
2016-11-15 11:21:18 +01:00
ethjson ::spec ::Engine ::Tendermint ( tendermint ) = > Tendermint ::new ( params , From ::from ( tendermint . params ) , builtins ) . expect ( " Failed to start the Tendermint consensus engine. " ) ,
2015-12-20 21:45:43 +01:00
}
}
2016-01-05 00:11:16 +01:00
/// Return the state root for the genesis state, memoising accordingly.
2016-01-11 11:51:31 +01:00
pub fn state_root ( & self ) -> H256 {
2016-07-13 19:59:59 +02:00
if self . state_root_memo . read ( ) . is_none ( ) {
* self . state_root_memo . write ( ) = Some ( self . genesis_state . root ( ) ) ;
2015-12-20 21:45:43 +01:00
}
2016-10-20 23:41:15 +02:00
self . state_root_memo . read ( ) . as_ref ( ) . cloned ( )
. expect ( " state root memo ensured to be set at this point; qed " )
2015-12-20 21:45:43 +01:00
}
2016-01-23 23:53:20 +01:00
/// Get the known knodes of the network in enode format.
2016-07-12 10:28:35 +02:00
pub fn nodes ( & self ) -> & [ String ] { & self . nodes }
2016-01-23 23:53:20 +01:00
2016-02-24 21:23:58 +01:00
/// Get the configured Network ID.
2016-12-04 19:48:26 +01:00
pub fn network_id ( & self ) -> u64 { self . params . network_id }
2016-02-24 21:23:58 +01:00
2016-11-13 13:58:42 +01:00
/// Get the configured subprotocol name.
2016-09-28 14:21:59 +02:00
pub fn subprotocol_name ( & self ) -> String { self . params . subprotocol_name . clone ( ) }
2016-07-27 21:38:22 +02:00
/// Get the configured network fork block.
pub fn fork_block ( & self ) -> Option < ( BlockNumber , H256 ) > { self . params . fork_block }
2016-02-03 13:20:32 +01:00
/// Get the header of the genesis block.
2016-01-09 12:30:41 +01:00
pub fn genesis_header ( & self ) -> Header {
2016-08-29 11:35:24 +02:00
let mut header : Header = Default ::default ( ) ;
header . set_parent_hash ( self . parent_hash . clone ( ) ) ;
header . set_timestamp ( self . timestamp ) ;
header . set_number ( 0 ) ;
header . set_author ( self . author . clone ( ) ) ;
header . set_transactions_root ( self . transactions_root . clone ( ) ) ;
header . set_uncles_hash ( RlpStream ::new_list ( 0 ) . out ( ) . sha3 ( ) ) ;
header . set_extra_data ( self . extra_data . clone ( ) ) ;
2016-09-28 14:21:59 +02:00
header . set_state_root ( self . state_root ( ) ) ;
2016-08-29 11:35:24 +02:00
header . set_receipts_root ( self . receipts_root . clone ( ) ) ;
header . set_log_bloom ( H2048 ::new ( ) . clone ( ) ) ;
header . set_gas_used ( self . gas_used . clone ( ) ) ;
header . set_gas_limit ( self . gas_limit . clone ( ) ) ;
header . set_difficulty ( self . difficulty . clone ( ) ) ;
header . set_seal ( {
2016-12-05 15:07:31 +01:00
let r = Rlp ::new ( & self . seal_rlp ) ;
r . iter ( ) . map ( | f | f . as_raw ( ) . to_vec ( ) ) . collect ( )
2016-08-29 11:35:24 +02:00
} ) ;
2016-09-28 14:21:59 +02:00
trace! ( target : " spec " , " Header hash is {} " , header . hash ( ) ) ;
2016-09-16 23:03:26 +02:00
header
2016-01-06 15:57:17 +01:00
}
/// Compose the genesis block for this chain.
pub fn genesis_block ( & self ) -> Bytes {
let empty_list = RlpStream ::new_list ( 0 ) . out ( ) ;
let header = self . genesis_header ( ) ;
2015-12-21 22:08:42 +01:00
let mut ret = RlpStream ::new_list ( 3 ) ;
ret . append ( & header ) ;
ret . append_raw ( & empty_list , 1 ) ;
ret . append_raw ( & empty_list , 1 ) ;
ret . out ( )
2015-12-20 21:45:43 +01:00
}
2016-01-25 18:56:36 +01:00
2016-03-17 15:15:10 +01:00
/// Overwrite the genesis components.
pub fn overwrite_genesis_params ( & mut self , g : Genesis ) {
2016-12-14 12:50:32 +01:00
let GenericSeal ( seal_rlp ) = g . seal . into ( ) ;
2016-03-17 15:15:10 +01:00
self . parent_hash = g . parent_hash ;
self . transactions_root = g . transactions_root ;
self . receipts_root = g . receipts_root ;
self . author = g . author ;
self . difficulty = g . difficulty ;
self . gas_limit = g . gas_limit ;
self . gas_used = g . gas_used ;
self . timestamp = g . timestamp ;
self . extra_data = g . extra_data ;
2016-12-14 12:50:32 +01:00
self . seal_rlp = seal_rlp ;
2016-03-17 15:15:10 +01:00
self . state_root_memo = RwLock ::new ( g . state_root ) ;
}
2016-01-25 23:24:51 +01:00
/// Alter the value of the genesis state.
pub fn set_genesis_state ( & mut self , s : PodState ) {
self . genesis_state = s ;
2016-07-13 19:59:59 +02:00
* self . state_root_memo . write ( ) = None ;
2016-01-25 23:24:51 +01:00
}
/// Returns `false` if the memoized state root is invalid. `true` otherwise.
pub fn is_state_root_valid ( & self ) -> bool {
2016-07-13 19:59:59 +02:00
self . state_root_memo . read ( ) . clone ( ) . map_or ( true , | sr | sr = = self . genesis_state . root ( ) )
2016-01-25 23:24:51 +01:00
}
2016-01-04 22:47:45 +01:00
2016-01-09 12:30:41 +01:00
/// Ensure that the given state DB has the trie nodes in for the genesis state.
2016-12-23 18:44:39 +01:00
pub fn ensure_db_good ( & self , mut db : StateDB , factories : & Factories ) -> Result < StateDB , Box < TrieError > > {
if db . as_hashdb ( ) . contains ( & self . state_root ( ) ) {
return Ok ( db )
}
trace! ( target : " spec " , " ensure_db_good: Fresh database? Cannot find state root {} " , self . state_root ( ) ) ;
let mut root = H256 ::new ( ) ;
{
let mut t = factories . trie . create ( db . as_hashdb_mut ( ) , & mut root ) ;
for ( address , account ) in self . genesis_state . get ( ) . iter ( ) {
2016-12-27 12:53:56 +01:00
t . insert ( & * * address , & account . rlp ( ) ) ? ;
2016-12-23 18:44:39 +01:00
}
}
trace! ( target : " spec " , " ensure_db_good: Populated sec trie; root is {} " , root ) ;
for ( address , account ) in self . genesis_state . get ( ) . iter ( ) {
db . note_non_null_account ( address ) ;
account . insert_additional ( & mut AccountDBMut ::new ( db . as_hashdb_mut ( ) , address ) , & factories . trie ) ;
}
2016-09-28 14:21:59 +02:00
2016-12-23 18:44:39 +01:00
// Execute contract constructors.
let env_info = EnvInfo {
number : 0 ,
author : self . author ,
timestamp : self . timestamp ,
difficulty : self . difficulty ,
last_hashes : Default ::default ( ) ,
gas_used : U256 ::zero ( ) ,
gas_limit : U256 ::max_value ( ) ,
} ;
let from = Address ::default ( ) ;
let start_nonce = self . engine . account_start_nonce ( ) ;
let mut state = State ::from_existing ( db , root , start_nonce , factories . clone ( ) ) ? ;
// Mutate the state with each constructor.
for & ( ref address , ref constructor ) in self . constructors . iter ( ) {
trace! ( target : " spec " , " ensure_db_good: Creating a contract at {}. " , address ) ;
let params = ActionParams {
code_address : address . clone ( ) ,
code_hash : constructor . sha3 ( ) ,
address : address . clone ( ) ,
sender : from . clone ( ) ,
origin : from . clone ( ) ,
gas : U256 ::max_value ( ) ,
gas_price : Default ::default ( ) ,
value : ActionValue ::Transfer ( Default ::default ( ) ) ,
code : Some ( Arc ::new ( constructor . clone ( ) ) ) ,
data : None ,
call_type : CallType ::None ,
} ;
let mut substate = Substate ::new ( ) ;
2016-01-14 22:38:49 +01:00
{
2016-12-23 18:44:39 +01:00
let mut exec = Executive ::new ( & mut state , & env_info , self . engine . as_ref ( ) , & factories . vm ) ;
if let Err ( e ) = exec . create ( params , & mut substate , & mut NoopTracer , & mut NoopVMTracer ) {
warn! ( target : " spec " , " Genesis constructor execution at {} failed: {}. " , address , e ) ;
2016-01-14 22:38:49 +01:00
}
2016-01-09 12:30:41 +01:00
}
2016-12-23 18:44:39 +01:00
if let Err ( e ) = state . commit ( ) {
warn! ( target : " spec " , " Genesis constructor trie commit at {} failed: {}. " , address , e ) ;
2016-01-26 15:00:22 +01:00
}
2016-12-23 18:44:39 +01:00
}
let ( root , db ) = state . drop ( ) ;
* self . state_root_memo . write ( ) = Some ( root ) ;
Ok ( db )
2016-01-09 12:30:41 +01:00
}
2016-04-09 19:20:35 +02:00
/// Loads spec from json file.
2016-09-05 17:41:34 +02:00
pub fn load < R > ( reader : R ) -> Result < Self , String > where R : Read {
match ethjson ::spec ::Spec ::load ( reader ) {
Ok ( spec ) = > Ok ( spec . into ( ) ) ,
_ = > Err ( " Spec json is invalid " . into ( ) ) ,
}
2016-01-08 16:24:14 +01:00
}
2016-05-03 17:23:53 +02:00
/// Create a new Spec which conforms to the Frontier-era Morden chain except that it's a NullEngine consensus.
2016-11-11 17:37:44 +01:00
pub fn new_test ( ) -> Spec { load_bundled! ( " null_morden " ) }
2016-06-16 12:44:08 +02:00
/// Create a new Spec which is a NullEngine consensus with a premine of address whose secret is sha3('').
2016-11-11 17:37:44 +01:00
pub fn new_null ( ) -> Spec { load_bundled! ( " null " ) }
2016-09-13 12:52:14 +02:00
2016-12-23 18:44:39 +01:00
/// Create a new Spec which constructs a contract at address 5 with storage at 0 equal to 1.
pub fn new_test_constructor ( ) -> Spec { load_bundled! ( " constructor " ) }
2016-09-13 12:52:14 +02:00
/// Create a new Spec with InstantSeal consensus which does internal sealing (not requiring work).
2016-11-11 18:27:20 +01:00
pub fn new_instant ( ) -> Spec { load_bundled! ( " instant_seal " ) }
2016-09-14 11:17:39 +02:00
/// Create a new Spec with AuthorityRound consensus which does internal sealing (not requiring work).
2017-01-10 12:23:59 +01:00
/// Accounts with secrets "0".sha3() and "1".sha3() are the validators.
2016-11-14 19:04:44 +01:00
pub fn new_test_round ( ) -> Self { load_bundled! ( " authority_round " ) }
2016-11-16 11:29:54 +01:00
2017-01-10 12:23:59 +01:00
/// Create a new Spec with BasicAuthority which uses a contract at address 5 to determine the current validators.
/// Accounts with secrets "0".sha3() and "1".sha3() are initially the validators.
/// Second validator can be removed with "0xf94e18670000000000000000000000000000000000000000000000000000000000000001" and added back in using "0x4d238c8e00000000000000000000000082a978b3f5962a5b0957d9ee9eef472ee55b42f1".
pub fn new_validator_contract ( ) -> Self { load_bundled! ( " validator_contract " ) }
2016-09-29 17:57:52 +02:00
/// Create a new Spec with Tendermint consensus which does internal sealing (not requiring work).
2016-10-05 15:31:31 +02:00
/// Account "0".sha3() and "1".sha3() are a authorities.
2016-11-15 11:26:37 +01:00
pub fn new_test_tendermint ( ) -> Self { load_bundled! ( " tendermint " ) }
2015-12-20 21:45:43 +01:00
}
2016-01-06 16:00:42 +01:00
#[ cfg(test) ]
2016-01-06 15:57:17 +01:00
mod tests {
2016-12-23 18:44:39 +01:00
use util ::* ;
2016-01-06 15:57:17 +01:00
use views ::* ;
2016-12-23 18:44:39 +01:00
use tests ::helpers ::get_temp_state_db ;
use state ::State ;
2016-01-06 15:57:17 +01:00
use super ::* ;
2016-09-05 17:41:34 +02:00
// https://github.com/ethcore/parity/issues/1840
#[ test ]
fn test_load_empty ( ) {
2016-09-16 23:03:26 +02:00
assert! ( Spec ::load ( & [ ] as & [ u8 ] ) . is_err ( ) ) ;
2016-09-05 17:41:34 +02:00
}
2016-01-07 19:10:29 +01:00
#[ test ]
2016-01-09 18:20:31 +01:00
fn test_chain ( ) {
let test_spec = Spec ::new_test ( ) ;
2016-01-08 16:24:14 +01:00
2016-01-11 11:51:31 +01:00
assert_eq! ( test_spec . state_root ( ) , H256 ::from_str ( " f3f4696bbf3b3b07775128eb7a3763279a394e382130f27c21e70233e04946a9 " ) . unwrap ( ) ) ;
2016-01-09 18:20:31 +01:00
let genesis = test_spec . genesis_block ( ) ;
2016-01-09 17:15:55 +01:00
assert_eq! ( BlockView ::new ( & genesis ) . header_view ( ) . sha3 ( ) , H256 ::from_str ( " 0cd786a2425d16f152c658316c423e6ce1181e15c3295826d7c9904cba9ce303 " ) . unwrap ( ) ) ;
2016-01-07 19:10:29 +01:00
}
2016-12-23 18:44:39 +01:00
#[ test ]
fn genesis_constructor ( ) {
let spec = Spec ::new_test_constructor ( ) ;
let mut db_result = get_temp_state_db ( ) ;
let db = spec . ensure_db_good ( db_result . take ( ) , & Default ::default ( ) ) . unwrap ( ) ;
let state = State ::from_existing ( db . boxed_clone ( ) , spec . state_root ( ) , spec . engine . account_start_nonce ( ) , Default ::default ( ) ) . unwrap ( ) ;
let expected = H256 ::from_str ( " 0000000000000000000000000000000000000000000000000000000000000001 " ) . unwrap ( ) ;
assert_eq! ( state . storage_at ( & Address ::from_str ( " 0000000000000000000000000000000000000005 " ) . unwrap ( ) , & H256 ::zero ( ) ) , expected ) ;
}
2016-01-09 10:26:31 +01:00
}