use ethjson module to load chain json tests
This commit is contained in:
parent
c837c3164a
commit
2face3f938
@ -16,18 +16,18 @@
|
||||
|
||||
use super::test_common::*;
|
||||
use client::{BlockChainClient, Client, ClientConfig};
|
||||
use pod_state::*;
|
||||
use block::Block;
|
||||
use ethereum;
|
||||
use tests::helpers::*;
|
||||
use devtools::*;
|
||||
use spec::Genesis;
|
||||
|
||||
pub fn json_chain_test(json_data: &[u8], era: ChainEra) -> Vec<String> {
|
||||
init_log();
|
||||
let json = Json::from_str(::std::str::from_utf8(json_data).unwrap()).expect("Json is invalid");
|
||||
let tests = ethjson::blockchain::Test.load(json_data).unwrap();
|
||||
let mut failed = Vec::new();
|
||||
|
||||
for (name, test) in json.as_object().unwrap() {
|
||||
for (name, blockchain) in tests.deref() {
|
||||
let mut fail = false;
|
||||
{
|
||||
let mut fail_unless = |cond: bool| if !cond && !fail {
|
||||
@ -39,37 +39,36 @@ pub fn json_chain_test(json_data: &[u8], era: ChainEra) -> Vec<String> {
|
||||
|
||||
flush!(" - {}...", name);
|
||||
|
||||
let blocks: Vec<(Bytes, bool)> = test["blocks"].as_array().unwrap().iter().map(|e| (xjson!(&e["rlp"]), e.find("blockHeader").is_some())).collect();
|
||||
let mut spec = match era {
|
||||
ChainEra::Frontier => ethereum::new_frontier_test(),
|
||||
ChainEra::Homestead => ethereum::new_homestead_test(),
|
||||
};
|
||||
let s = PodState::from_json(test.find("pre").unwrap());
|
||||
spec.set_genesis_state(s);
|
||||
spec.overwrite_genesis(test.find("genesisBlockHeader").unwrap());
|
||||
|
||||
let genesis = Genesis::from(blockchain.genesis());
|
||||
let state = From::from(blockchain.pre_state.clone());
|
||||
spec.set_genesis_state(state);
|
||||
spec.overwrite_genesis_params(genesis);
|
||||
assert!(spec.is_state_root_valid());
|
||||
let genesis_hash = spec.genesis_header().hash();
|
||||
assert_eq!(genesis_hash, H256::from_json(&test.find("genesisBlockHeader").unwrap()["hash"]));
|
||||
|
||||
let temp = RandomTempPath::new();
|
||||
{
|
||||
let client = Client::new(ClientConfig::default(), spec, temp.as_path(), IoChannel::disconnected()).unwrap();
|
||||
assert_eq!(client.chain_info().best_block_hash, genesis_hash);
|
||||
for (b, is_valid) in blocks.into_iter() {
|
||||
for b in &blockchain.blocks_rlp() {
|
||||
if Block::is_good(&b) {
|
||||
let _ = client.import_block(b.clone());
|
||||
client.flush_queue();
|
||||
client.import_verified_blocks(&IoChannel::disconnected());
|
||||
}
|
||||
client.flush_queue();
|
||||
let imported_ok = client.import_verified_blocks(&IoChannel::disconnected()) > 0;
|
||||
assert_eq!(imported_ok, is_valid);
|
||||
}
|
||||
fail_unless(client.chain_info().best_block_hash == H256::from_json(&test["lastblockhash"]));
|
||||
fail_unless(client.chain_info().best_block_hash == blockchain.best_block.clone().into());
|
||||
}
|
||||
}
|
||||
|
||||
if !fail {
|
||||
flushln!("ok");
|
||||
}
|
||||
}
|
||||
|
||||
println!("!!! {:?} tests from failed.", failed.len());
|
||||
failed
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ use pod_account::*;
|
||||
use ethjson;
|
||||
|
||||
/// State of all accounts in the system expressed in Plain Old Data.
|
||||
#[derive(Debug,Clone,PartialEq,Eq,Default)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Default)]
|
||||
pub struct PodState (BTreeMap<Address, PodAccount>);
|
||||
|
||||
impl PodState {
|
||||
|
@ -19,7 +19,6 @@
|
||||
use std::collections::BTreeMap;
|
||||
use uint::Uint;
|
||||
use bytes::Bytes;
|
||||
use hash::H256;
|
||||
|
||||
/// Blockchain test account deserializer.
|
||||
#[derive(Debug, PartialEq, Deserialize, Clone)]
|
||||
|
@ -24,11 +24,11 @@ use blockchain::transaction::Transaction;
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
pub struct Block {
|
||||
#[serde(rename="blockHeader")]
|
||||
header: Header,
|
||||
header: Option<Header>,
|
||||
rlp: Bytes,
|
||||
transactions: Vec<Transaction>,
|
||||
transactions: Option<Vec<Transaction>>,
|
||||
#[serde(rename="uncleHeaders")]
|
||||
uncles: Vec<Header>,
|
||||
uncles: Option<Vec<Header>>,
|
||||
}
|
||||
|
||||
impl Block {
|
||||
|
@ -17,6 +17,7 @@
|
||||
//! Blockchain deserialization.
|
||||
|
||||
use bytes::Bytes;
|
||||
use hash::H256;
|
||||
use blockchain::state::State;
|
||||
use blockchain::header::Header;
|
||||
use blockchain::block::Block;
|
||||
@ -30,7 +31,7 @@ pub struct BlockChain {
|
||||
pub genesis_block: Header,
|
||||
/// Genesis block rlp.
|
||||
#[serde(rename="genesisRLP")]
|
||||
pub genesis_rlp: Bytes,
|
||||
pub genesis_rlp: Option<Bytes>,
|
||||
/// Blocks.
|
||||
pub blocks: Vec<Block>,
|
||||
/// Post state.
|
||||
@ -39,14 +40,12 @@ pub struct BlockChain {
|
||||
/// Pre state.
|
||||
#[serde(rename="pre")]
|
||||
pub pre_state: State,
|
||||
/// Hash of best block.
|
||||
#[serde(rename="lastblockhash")]
|
||||
pub best_block: H256
|
||||
}
|
||||
|
||||
impl BlockChain {
|
||||
/// Returns genesis block rlp.
|
||||
pub fn genesis_rlp(&self) -> Vec<u8> {
|
||||
self.genesis_rlp.clone().into()
|
||||
}
|
||||
|
||||
/// Returns blocks rlp.
|
||||
pub fn blocks_rlp(&self) -> Vec<Vec<u8>> {
|
||||
self.blocks.iter().map(|block| block.rlp()).collect()
|
||||
|
@ -18,6 +18,9 @@
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use std::ops::Deref;
|
||||
use std::io::Read;
|
||||
use serde_json;
|
||||
use serde_json::Error;
|
||||
use blockchain::blockchain::BlockChain;
|
||||
|
||||
/// Blockchain test deserializer.
|
||||
@ -31,3 +34,10 @@ impl Deref for Test {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Test {
|
||||
/// Loads test from json.
|
||||
pub fn load<R>(reader: R) -> Result<Self, Error> where R: Read {
|
||||
serde_json::from_reader(reader)
|
||||
}
|
||||
}
|
||||
|
@ -46,12 +46,8 @@ impl Visitor for BytesVisitor {
|
||||
let v = match value.len() {
|
||||
0 => vec![],
|
||||
2 if value.starts_with("0x") => vec![],
|
||||
_ if value.starts_with("0x") => try!(FromHex::from_hex(&value[2..]).map_err(|_| {
|
||||
Error::custom(format!("Invalid hex value {}.", value).as_ref())
|
||||
})),
|
||||
_ => try!(FromHex::from_hex(value).map_err(|_| {
|
||||
Error::custom(format!("Invalid hex value {}.", value).as_ref())
|
||||
}))
|
||||
_ if value.starts_with("0x") => FromHex::from_hex(&value[2..]).unwrap_or(vec![]),
|
||||
_ => FromHex::from_hex(value).unwrap_or(vec![]),
|
||||
};
|
||||
Ok(Bytes(v))
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user