Chainspec validation (#6197)

* chainspec validation

* better error formatting for chainspec

* lint validate_chainspecs.sh

* quit takes &str instead of S: AsRef<str>

* push CI

* don't double check spec validity
This commit is contained in:
Marek Kotewicz 2017-08-02 12:50:36 +02:00 committed by Arkadiy Paronyan
parent 8de1e92b99
commit 0c7c34e609
10 changed files with 95 additions and 35 deletions

18
Cargo.lock generated
View File

@ -237,6 +237,15 @@ name = "cfg-if"
version = "0.1.0" version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "chainspec"
version = "0.1.0"
dependencies = [
"ethjson 0.1.0",
"serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "cid" name = "cid"
version = "0.2.2" version = "0.2.2"
@ -2592,6 +2601,14 @@ dependencies = [
"synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "serde_ignored"
version = "0.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.2" version = "1.0.2"
@ -3398,6 +3415,7 @@ dependencies = [
"checksum serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6a7c6b751a2e8d5df57a5ff71b5b4fc8aaee9ee28ff1341d640dd130bb5f4f7a" "checksum serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6a7c6b751a2e8d5df57a5ff71b5b4fc8aaee9ee28ff1341d640dd130bb5f4f7a"
"checksum serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "2f6ca58905ebd3c3b285a8a6d4f3ac92b92c0d7951d5649b1bdd212549c06639" "checksum serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "2f6ca58905ebd3c3b285a8a6d4f3ac92b92c0d7951d5649b1bdd212549c06639"
"checksum serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37aee4e0da52d801acfbc0cc219eb1eda7142112339726e427926a6f6ee65d3a" "checksum serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37aee4e0da52d801acfbc0cc219eb1eda7142112339726e427926a6f6ee65d3a"
"checksum serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "190e9765dcedb56be63b6e0993a006c7e3b071a016a304736e4a315dc01fb142"
"checksum serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "48b04779552e92037212c3615370f6bd57a40ebba7f20e554ff9f55e41a69a7b" "checksum serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "48b04779552e92037212c3615370f6bd57a40ebba7f20e554ff9f55e41a69a7b"
"checksum serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce0fd303af908732989354c6f02e05e2e6d597152870f2c6990efb0577137480" "checksum serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce0fd303af908732989354c6f02e05e2e6d597152870f2c6990efb0577137480"
"checksum sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc30b1e1e8c40c121ca33b86c23308a090d19974ef001b4bf6e61fd1a0fb095c" "checksum sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc30b1e1e8c40c121ca33b86c23308a090d19974ef001b4bf6e61fd1a0fb095c"

View File

@ -110,4 +110,4 @@ lto = false
panic = "abort" panic = "abort"
[workspace] [workspace]
members = ["ethstore/cli", "ethkey/cli", "evmbin", "whisper"] members = ["ethstore/cli", "ethkey/cli", "evmbin", "whisper", "chainspec"]

9
chainspec/Cargo.toml Normal file
View File

@ -0,0 +1,9 @@
[package]
name = "chainspec"
version = "0.1.0"
authors = ["debris <marek.kotewicz@gmail.com>"]
[dependencies]
ethjson = { path = "../json" }
serde_json = "1.0"
serde_ignored = "0.0.4"

48
chainspec/src/main.rs Normal file
View File

@ -0,0 +1,48 @@
extern crate serde_json;
extern crate serde_ignored;
extern crate ethjson;
use std::collections::BTreeSet;
use std::{fs, env, process};
use ethjson::spec::Spec;
fn quit(s: &str) -> ! {
println!("{}", s);
process::exit(1);
}
fn main() {
let mut args = env::args();
if args.len() != 2 {
quit("You need to specify chainspec.json\n\
\n\
./chainspec <chainspec.json>");
}
let path = args.nth(1).expect("args.len() == 2; qed");
let file = match fs::File::open(&path) {
Ok(file) => file,
Err(_) => quit(&format!("{} could not be opened", path)),
};
let mut unused = BTreeSet::new();
let mut deserializer = serde_json::Deserializer::from_reader(file);
let spec: Result<Spec, _> = serde_ignored::deserialize(&mut deserializer, |field| {
unused.insert(field.to_string());
});
if let Err(err) = spec {
quit(&format!("{} {}", path, err.to_string()));
}
if !unused.is_empty() {
let err = unused.into_iter()
.map(|field| format!("{} unexpected field `{}`", path, field))
.collect::<Vec<_>>()
.join("\n");
quit(&err);
}
println!("{} is valid", path);
}

View File

@ -11,7 +11,6 @@
"networkID" : "0x2" "networkID" : "0x2"
}, },
"genesis": { "genesis": {
"gasLimitBoundDivisor": "0x0400",
"seal": { "seal": {
"generic": "0x" "generic": "0x"
}, },

View File

@ -3,7 +3,6 @@
"engine": { "engine": {
"basicAuthority": { "basicAuthority": {
"params": { "params": {
"gasLimitBoundDivisor": "0x0400",
"durationLimit": "0x0d", "durationLimit": "0x0d",
"validators": { "validators": {
"safeContract": "0x0000000000000000000000000000000000000005" "safeContract": "0x0000000000000000000000000000000000000005"

View File

@ -134,23 +134,4 @@ mod tests {
let _ = frontier.engine; let _ = frontier.engine;
} }
#[test]
fn all_spec_files_valid() {
let tmp = ::std::env::temp_dir();
new_olympic(&tmp);
new_foundation(&tmp);
new_classic(&tmp);
new_expanse(&tmp);
new_kovan(&tmp);
new_ropsten(&tmp);
new_morden(&tmp);
new_frontier_test();
new_homestead_test();
new_eip150_test();
new_eip161_test();
new_transition_test();
new_mainnet_like();
new_metropolis_test();
}
} }

View File

@ -529,19 +529,6 @@ mod tests {
assert!(Spec::load(::std::env::temp_dir(), &[] as &[u8]).is_err()); assert!(Spec::load(::std::env::temp_dir(), &[] as &[u8]).is_err());
} }
#[test]
fn all_spec_files_valid() {
Spec::new_test();
Spec::new_null();
Spec::new_test_constructor();
Spec::new_instant();
Spec::new_test_round();
Spec::new_test_tendermint();
Spec::new_validator_safe_contract();
Spec::new_validator_contract();
Spec::new_validator_multi();
}
#[test] #[test]
fn test_chain() { fn test_chain() {
let test_spec = Spec::new_test(); let test_spec = Spec::new_test();

15
scripts/validate_chainspecs.sh Executable file
View File

@ -0,0 +1,15 @@
#!/bin/sh
ERR=0
cargo build --release -p chainspec
for spec in ethcore/res/*.json; do
if ! ./target/release/chainspec "$spec"; then ERR=1; fi
done
for spec in ethcore/res/ethereum/*.json; do
if ! ./target/release/chainspec "$spec"; then ERR=1; fi
done
exit $ERR

View File

@ -22,4 +22,8 @@ case $1 in
;; ;;
esac esac
set -e
./scripts/validate_chainspecs.sh
cargo test -j 8 $OPTIONS --features "$FEATURES" --all --exclude parity-ipfs-api --exclude evmjit $1 cargo test -j 8 $OPTIONS --features "$FEATURES" --all --exclude parity-ipfs-api --exclude evmjit $1