loading frontier genesis block

This commit is contained in:
debris 2015-12-12 15:52:37 +01:00
parent ada79ed62a
commit 5e215af5e2
5 changed files with 58 additions and 26 deletions

View File

@ -25,16 +25,3 @@ impl Account {
pub fn storage(&self) -> &HashMap<U256, U256> { &self.storage }
}
pub struct AccountMap {
accounts: HashMap<Address, Account>
}
impl AccountMap {
pub fn new(accounts: HashMap<Address, Account>) -> AccountMap {
AccountMap {
accounts: accounts
}
}
pub fn accounts(&self) -> &HashMap<Address, Account> { &self.accounts }
}

View File

@ -1,3 +1,4 @@
use std::collections::HashMap;
use util::hash::*;
use util::rlp::*;
use util::hashdb::*;
@ -8,25 +9,53 @@ use block::*;
use verifiedblock::*;
use importroute::*;
use account::*;
use genesis::*;
pub struct BlockChain {
genesis_block: Vec<u8>,
genesis_header: Vec<u8>,
genesis_hash: H256,
genesis_state: AccountMap
genesis_state: HashMap<Address, Account>
}
impl BlockChain {
pub fn new(genesis_block: Vec<u8>, genesis_state: AccountMap) -> BlockChain {
// consider creating `GenesisView` for genesis block RLP
let genesis_hash = BlockView::new(&genesis_block).parent_hash().sha3();
/// Create new instance of blockchain from given Genesis
///
/// ```rust
/// extern crate ethcore_util as util;
/// extern crate ethcore;
/// use std::str::FromStr;
/// use ethcore::genesis::*;
/// use ethcore::blockchain::*;
/// use util::hash::*;
///
/// fn main() {
/// let genesis = Genesis::new_frontier();
/// let bc = BlockChain::new(genesis);
/// let genesis_hash = "d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3";
/// assert_eq!(bc.genesis_hash(), &H256::from_str(genesis_hash).unwrap());
/// }
/// ```
pub fn new(genesis: Genesis) -> BlockChain {
let (genesis_block, genesis_state) = genesis.drain();
let (genesis_header, genesis_hash) = {
let rlp = Rlp::new(&genesis_block).at(0);
(rlp.raw().to_vec(), BlockView::new_from_rlp(rlp).sha3())
};
BlockChain {
genesis_block: genesis_block,
genesis_header: genesis_header,
genesis_hash: genesis_hash,
genesis_state: genesis_state
}
}
pub fn genesis_hash(&self) -> &H256 {
&self.genesis_hash
}
pub fn genesis_block(&self, db: &OverlayDB) -> Block {
let root = BlockView::new(&self.genesis_block).state_root();

View File

@ -15,6 +15,12 @@ impl<'a> BlockView<'a> {
}
}
pub fn new_from_rlp(rlp: Rlp<'a>) -> BlockView<'a> {
BlockView {
rlp: rlp
}
}
pub fn parent_hash(&self) -> H256 { self.rlp.val_at(0) }
pub fn uncles_hash(&self) -> H256 { self.rlp.val_at(1) }
pub fn coinbase(&self) -> Address { self.rlp.val_at(2) }
@ -33,7 +39,7 @@ impl<'a> BlockView<'a> {
impl<'a> sha3::Hashable for BlockView<'a> {
fn sha3(&self) -> H256 {
self.rlp.data().sha3()
self.rlp.raw().sha3()
}
}

View File

@ -3,6 +3,7 @@ use std::str::FromStr;
use std::collections::HashMap;
use rustc_serialize::base64::FromBase64;
use rustc_serialize::json::Json;
use rustc_serialize::hex::FromHex;
use flate2::read::GzDecoder;
use util::rlp::*;
use util::hash::*;
@ -24,7 +25,7 @@ fn base_to_json(source: &[u8]) -> Json {
pub struct Genesis {
block: Vec<u8>,
state: AccountMap
state: HashMap<Address, Account>
}
impl Genesis {
@ -45,7 +46,7 @@ impl Genesis {
let difficulty = U256::from_str(&json["difficulty"].as_string().unwrap()[2..]).unwrap();
let gas_limit = U256::from_str(&json["gasLimit"].as_string().unwrap()[2..]).unwrap();
let timestamp = U256::from_str(&json["timestamp"].as_string().unwrap()[2..]).unwrap();
let extra_data: Vec<u8> = From::from(&json["extraData"].as_string().unwrap()[2..]);
let extra_data: Vec<u8> = json["extraData"].as_string().unwrap()[2..].from_hex().unwrap();
let nonce = H64::from_str(&json["nonce"].as_string().unwrap()[2..]).unwrap();
let log_bloom = H2048::new();
@ -80,24 +81,32 @@ impl Genesis {
stream.append_raw(&empty_list, 1);
stream.append_raw(&empty_list, 1);
let mut map = HashMap::new();
let mut state = HashMap::new();
let accounts = json["alloc"].as_object().expect("Missing genesis state");
for (address, acc) in accounts.iter() {
let addr = Address::from_str(address).unwrap();
let o = acc.as_object().unwrap();
let balance = U256::from_dec_str(o["balance"].as_string().unwrap()).unwrap();
map.insert(addr, Account::new_with_balance(balance));
state.insert(addr, Account::new_with_balance(balance));
}
Genesis {
block: stream.out(),
state: AccountMap::new(map)
state: state
}
}
pub fn drain(self) -> (Vec<u8>, HashMap<Address, Account>) {
(self.block, self.state)
}
}
#[test]
fn test_genesis() {
let g = Genesis::new_default();
use blockheader::*;
let g = Genesis::new_frontier();
let view = BlockView::new_from_rlp(Rlp::new(&g.block).at(0));
let genesis_hash = H256::from_str("d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3").unwrap();
assert_eq!(view.sha3(), genesis_hash);
}

View File

@ -1,3 +1,4 @@
use std::collections::HashMap;
use util::hash::*;
use util::hashdb::*;
use util::memorydb::*;
@ -58,10 +59,10 @@ impl State {
/// Commit accounts to TrieDB. This is simplified version of
/// cpp-ethereum's dev::eth::commit.
pub fn insert_accounts(&mut self, map: &AccountMap) {
pub fn insert_accounts(&mut self, accounts: &HashMap<Address, Account>) {
let mut trie = TrieDB::new_existing(&mut self.db, &mut self.root);
for (address, account) in map.accounts().iter() {
for (address, account) in accounts.iter() {
let mut stream = RlpStream::new_list(4);
stream.append(account.nonce());
stream.append(account.balance());