Implement JSON test suite (#11801)

This commit is contained in:
adria0.eth
2020-09-08 02:48:09 +02:00
committed by Artem Vorotnikov
parent 506cee52e8
commit c84d82580a
20 changed files with 777 additions and 600 deletions

View File

@@ -49,7 +49,7 @@ pub struct BlockChain {
/// Blocks.
pub blocks: Vec<Block>,
/// Post state.
pub post_state: State,
pub post_state: Option<State>,
/// Pre state.
#[serde(rename = "pre")]
pub pre_state: State,

View File

@@ -16,19 +16,62 @@
//! Blockchain test state deserializer.
use blockchain::account::Account;
use hash::Address;
use crate::{
bytes::Bytes,
hash::{Address, H256},
spec::{Account, Builtin},
};
use serde::Deserialize;
use std::collections::BTreeMap;
/// Blockchain test state deserializer.
#[derive(Debug, PartialEq, Deserialize, Clone)]
pub struct State(BTreeMap<Address, Account>);
#[derive(Clone, Debug, PartialEq, Deserialize)]
#[serde(untagged)]
pub enum HashOrMap {
/// When the `postState` is large, tests sometimes just include the state root of the last
/// successful block here.
Hash(H256),
/// The expected `postState` of a test
Map(BTreeMap<Address, Account>),
}
/// Blockchain state deserializer.
#[derive(Clone, Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct State(pub HashOrMap);
impl State {
/// Returns all builtins.
pub fn builtins(&self) -> BTreeMap<Address, Builtin> {
match &self.0 {
HashOrMap::Hash(_) => BTreeMap::default(),
HashOrMap::Map(map) => map
.iter()
.filter_map(|(add, ref acc)| acc.builtin.clone().map(|b| (add.clone(), b.into())))
.collect(),
}
}
/// Returns all constructors.
pub fn constructors(&self) -> BTreeMap<Address, Bytes> {
match &self.0 {
HashOrMap::Hash(_) => BTreeMap::default(),
HashOrMap::Map(map) => map
.iter()
.filter_map(|(add, ref acc)| acc.constructor.clone().map(|b| (add.clone(), b)))
.collect(),
}
}
}
impl IntoIterator for State {
type Item = <BTreeMap<Address, Account> as IntoIterator>::Item;
type IntoIter = <BTreeMap<Address, Account> as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
if let HashOrMap::Map(m) = self.0 {
m.into_iter()
} else {
BTreeMap::default().into_iter()
}
}
}

View File

@@ -23,7 +23,7 @@ use spec::builtin::BuiltinCompat;
use uint::Uint;
/// Spec account.
#[derive(Debug, PartialEq, Deserialize)]
#[derive(Clone, Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
#[serde(rename_all = "camelCase")]
pub struct Account {

View File

@@ -35,6 +35,7 @@ pub enum ForkSpec {
FrontierToHomesteadAt5,
HomesteadToDaoAt5,
HomesteadToEIP150At5,
ByzantiumToConstantinopleAt5,
}
/// Spec deserialization.

View File

@@ -18,7 +18,7 @@
use hash::H256;
use serde_json::{self, Error};
use std::{collections::BTreeMap, io::Read};
use std::{collections::BTreeMap, io::Read, path::PathBuf};
use uint::Uint;
/// Blockchain test header deserializer.
@@ -119,3 +119,123 @@ impl SkipStates {
}
}
}
/// Describes a github.com/ethereum/tests suite
#[derive(Debug, PartialEq, Deserialize)]
pub struct EthereumTestSuite {
/// Blockchain tests
pub chain: Vec<ChainTests>,
/// State tests
pub state: Vec<StateTests>,
/// Difficulty tests
pub difficulty: Vec<DifficultyTests>,
/// Executive tests
pub executive: Vec<ExecutiveTests>,
/// Transaction tests
pub transaction: Vec<TransactionTests>,
/// Trie tests
pub trie: Vec<TrieTests>,
}
/// Chain spec used in tests
#[derive(Debug, PartialEq, Deserialize)]
pub enum TestChainSpec {
/// Foundation
Foundation,
/// ByzantiumTest
ByzantiumTest,
/// FrontierTest
FrontierTest,
/// HomesteadTest
HomesteadTest,
}
/// Kind of trie used in test
#[derive(Debug, PartialEq, Deserialize)]
pub enum TestTrieSpec {
/// Generic
Generic,
/// Secure
Secure,
}
/// A set of blockchain tests
#[derive(Debug, PartialEq, Deserialize)]
pub struct ChainTests {
/// Path of the json tests
pub path: PathBuf,
/// Tests to skip
pub skip: Vec<ChainTestSkip>,
}
/// Tests to skip in chain tests
#[derive(Debug, PartialEq, Deserialize)]
pub struct ChainTestSkip {
/// Issue reference.
pub reference: String,
/// Test names to skip
pub names: Vec<String>,
/// Test paths to skip
pub paths: Vec<String>,
}
/// A set of state tests
#[derive(Debug, PartialEq, Deserialize)]
pub struct StateTests {
/// Path of the json tests
pub path: PathBuf,
/// Tests to skip
pub skip: Vec<StateTestSkip>,
}
/// State test to skip
#[derive(Debug, PartialEq, Deserialize)]
pub struct StateTestSkip {
/// Issue reference.
pub reference: String,
/// Paths to skip
pub paths: Vec<String>,
/// Test names to skip
pub names: BTreeMap<String, StateSkipSubStates1>,
}
/// State subtest to skip.
#[derive(Debug, PartialEq, Deserialize)]
pub struct StateSkipSubStates1 {
/// State test number of this item. Or '*' for all state.
pub subnumbers: Vec<String>,
/// Chain for this items.
pub chain: String,
}
/// A set of difficulty tests
#[derive(Debug, PartialEq, Deserialize)]
pub struct DifficultyTests {
/// Path of the json tests
pub path: Vec<PathBuf>,
/// Chain spec to use
pub chainspec: TestChainSpec,
}
/// A set of executive tests
#[derive(Debug, PartialEq, Deserialize)]
pub struct ExecutiveTests {
/// Path of the json tests
pub path: PathBuf,
}
/// A set of transaction tests
#[derive(Debug, PartialEq, Deserialize)]
pub struct TransactionTests {
/// Path of the json tests
pub path: PathBuf,
}
/// A set of trie tests
#[derive(Debug, PartialEq, Deserialize)]
pub struct TrieTests {
/// Path of the json tests
pub path: Vec<PathBuf>,
/// Trie spec to use
pub triespec: TestTrieSpec,
}