Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Deny unknown fields for chainspec #9972

Merged
merged 5 commits into from
Nov 27, 2018
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 2 additions & 12 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion chainspec/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,3 @@ authors = ["Marek Kotewicz <marek@parity.io>"]
[dependencies]
ethjson = { path = "../json" }
serde_json = "1.0"
serde_ignored = "0.0.4"
17 changes: 1 addition & 16 deletions chainspec/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,8 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.

extern crate serde_json;
extern crate serde_ignored;
extern crate ethjson;

use std::collections::BTreeSet;
use std::{fs, env, process};
use ethjson::spec::Spec;

Expand All @@ -41,24 +39,11 @@ fn main() {
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());
});
let spec: Result<Spec, _> = serde_json::from_reader(file);

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);
}
1 change: 1 addition & 0 deletions json/src/spec/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use spec::builtin::Builtin;

/// Spec account.
#[derive(Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Account {
/// Builtin contract.
pub builtin: Option<Builtin>,
Expand Down
2 changes: 2 additions & 0 deletions json/src/spec/authority_round.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use super::ValidatorSet;

/// Authority params deserialization.
#[derive(Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
#[serde(rename_all = "camelCase")]
pub struct AuthorityRoundParams {
/// Block duration, in seconds.
Expand Down Expand Up @@ -59,6 +60,7 @@ pub struct AuthorityRoundParams {

/// Authority engine deserialization.
#[derive(Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct AuthorityRound {
/// Ethash params.
pub params: AuthorityRoundParams,
Expand Down
2 changes: 2 additions & 0 deletions json/src/spec/basic_authority.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use super::ValidatorSet;

/// Authority params deserialization.
#[derive(Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
#[serde(rename_all = "camelCase")]
pub struct BasicAuthorityParams {
/// Block duration.
Expand All @@ -31,6 +32,7 @@ pub struct BasicAuthorityParams {

/// Authority engine deserialization.
#[derive(Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct BasicAuthority {
/// Ethash params.
pub params: BasicAuthorityParams,
Expand Down
5 changes: 5 additions & 0 deletions json/src/spec/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use uint::Uint;

/// Linear pricing.
#[derive(Debug, PartialEq, Deserialize, Clone)]
#[serde(deny_unknown_fields)]
pub struct Linear {
/// Base price.
pub base: usize,
Expand All @@ -29,13 +30,15 @@ pub struct Linear {

/// Pricing for modular exponentiation.
#[derive(Debug, PartialEq, Deserialize, Clone)]
#[serde(deny_unknown_fields)]
pub struct Modexp {
/// Price divisor.
pub divisor: usize,
}

/// Pricing for alt_bn128_pairing.
#[derive(Debug, PartialEq, Deserialize, Clone)]
#[serde(deny_unknown_fields)]
pub struct AltBn128Pairing {
/// Base price.
pub base: usize,
Expand All @@ -45,6 +48,7 @@ pub struct AltBn128Pairing {

/// Pricing variants.
#[derive(Debug, PartialEq, Deserialize, Clone)]
#[serde(deny_unknown_fields)]
#[serde(rename_all = "snake_case")]
pub enum Pricing {
/// Linear pricing.
Expand All @@ -57,6 +61,7 @@ pub enum Pricing {

/// Spec builtin.
#[derive(Debug, PartialEq, Deserialize, Clone)]
#[serde(deny_unknown_fields)]
pub struct Builtin {
/// Builtin name.
pub name: String,
Expand Down
2 changes: 1 addition & 1 deletion json/src/spec/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use super::{Ethash, BasicAuthority, AuthorityRound, Tendermint, NullEngine, Inst

/// Engine deserialization.
#[derive(Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
#[serde(rename_all = "camelCase")]
pub enum Engine {
/// Null engine.
Expand Down Expand Up @@ -85,7 +86,6 @@ mod tests {
"minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"homesteadTransition" : "0x",
"daoHardforkTransition": "0xffffffffffffffff",
"daoHardforkBeneficiary": "0x0000000000000000000000000000000000000000",
Expand Down
3 changes: 3 additions & 0 deletions json/src/spec/ethash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use hash::Address;

/// Deserializable doppelganger of block rewards for EthashParams
#[derive(Clone, Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
#[serde(untagged)]
pub enum BlockReward {
Single(Uint),
Expand All @@ -31,6 +32,7 @@ pub enum BlockReward {

/// Deserializable doppelganger of EthashParams.
#[derive(Clone, Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
#[serde(rename_all = "camelCase")]
pub struct EthashParams {
/// See main EthashParams docs.
Expand Down Expand Up @@ -97,6 +99,7 @@ pub struct EthashParams {

/// Ethash engine deserialization.
#[derive(Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct Ethash {
/// Ethash params.
pub params: EthashParams,
Expand Down
2 changes: 1 addition & 1 deletion json/src/spec/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use spec::Seal;

/// Spec genesis.
#[derive(Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
#[serde(rename_all = "camelCase")]
pub struct Genesis {
/// Seal.
Expand Down Expand Up @@ -64,7 +65,6 @@ mod tests {
#[test]
fn genesis_deserialization() {
let s = r#"{
"nonce": "0x0000000000000042",
"difficulty": "0x400000000",
"seal": {
"ethereum": {
Expand Down
1 change: 1 addition & 0 deletions json/src/spec/hardcoded_sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use uint::Uint;

/// Spec hardcoded sync.
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
#[serde(rename_all = "camelCase")]
pub struct HardcodedSync {
/// Hexadecimal of the RLP encoding of the header of the block to start synchronization from.
Expand Down
2 changes: 2 additions & 0 deletions json/src/spec/instant_seal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

/// Instant seal engine params deserialization.
#[derive(Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
#[serde(rename_all = "camelCase")]
pub struct InstantSealParams {
/// Whether to enable millisecond timestamp.
Expand All @@ -27,6 +28,7 @@ pub struct InstantSealParams {

/// Instant seal engine descriptor.
#[derive(Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct InstantSeal {
/// Instant seal parameters.
pub params: InstantSealParams,
Expand Down
2 changes: 2 additions & 0 deletions json/src/spec/null_engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use uint::Uint;

/// Authority params deserialization.
#[derive(Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
#[serde(rename_all = "camelCase")]
pub struct NullEngineParams {
/// Block reward.
Expand All @@ -28,6 +29,7 @@ pub struct NullEngineParams {

/// Null engine descriptor
#[derive(Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct NullEngine {
/// Ethash params.
pub params: NullEngineParams,
Expand Down
1 change: 1 addition & 0 deletions json/src/spec/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use bytes::Bytes;

/// Spec params.
#[derive(Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
#[serde(rename_all = "camelCase")]
pub struct Params {
/// Account start nonce, defaults to 0.
Expand Down
4 changes: 4 additions & 0 deletions json/src/spec/seal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use bytes::Bytes;

/// Ethereum seal.
#[derive(Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
#[serde(rename_all = "camelCase")]
pub struct Ethereum {
/// Seal nonce.
Expand All @@ -32,6 +33,7 @@ pub struct Ethereum {

/// AuthorityRound seal.
#[derive(Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct AuthorityRoundSeal {
/// Seal step.
pub step: Uint,
Expand All @@ -41,6 +43,7 @@ pub struct AuthorityRoundSeal {

/// Tendermint seal.
#[derive(Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct TendermintSeal {
/// Seal round.
pub round: Uint,
Expand All @@ -52,6 +55,7 @@ pub struct TendermintSeal {

/// Seal variants.
#[derive(Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
#[serde(rename_all = "camelCase")]
pub enum Seal {
/// Ethereum seal.
Expand Down
67 changes: 66 additions & 1 deletion json/src/spec/spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ pub enum ForkSpec {

/// Spec deserialization.
#[derive(Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
#[serde(rename_all = "camelCase")]
pub struct Spec {
/// Spec name.
Expand Down Expand Up @@ -70,6 +71,71 @@ mod tests {
use serde_json;
use spec::spec::Spec;

#[test]
fn should_error_on_unknown_fields() {
let s = r#"{
"name": "Morden",
"dataDir": "morden",
"engine": {
"Ethash": {
"params": {
"minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d",
"homesteadTransition" : "0x",
"daoHardforkTransition": "0xffffffffffffffff",
"daoHardforkBeneficiary": "0x0000000000000000000000000000000000000000",
"daoHardforkAccounts": []
}
}
},
"params": {
"accountStartNonce": "0x0100000",
"maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388",
"networkID" : "0x2",
"forkBlock": "0xffffffffffffffff",
"forkCanonHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"gasLimitBoundDivisor": "0x20",
"unknownField": "0x0"
},
"genesis": {
"seal": {
"ethereum": {
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"nonce": "0x00006d6f7264656e"
}
},
"difficulty": "0x20000",
"author": "0x0000000000000000000000000000000000000000",
"timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "0x",
"gasLimit": "0x2fefd8"
},
"nodes": [
"enode://b1217cbaa440e35ed471157123fe468e19e8b5ad5bedb4b1fdbcbdab6fb2f5ed3e95dd9c24a22a79fdb2352204cea207df27d92bfd21bfd41545e8b16f637499@104.44.138.37:30303"
],
"accounts": {
"0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
"0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
"0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
"0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
"102e61f5d8f9bc71d0ad4a084df4e65e05ce0e1c": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" }
},
"hardcodedSync": {
"header": "f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23",
"totalDifficulty": "0x400000000",
"CHTs": [
"0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa",
"0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544"
]
}
}"#;
let result: Result<Spec, _> = serde_json::from_str(s);
assert!(result.is_err());
}

#[test]
fn spec_deserialization() {
let s = r#"{
Expand All @@ -90,7 +156,6 @@ mod tests {
},
"params": {
"accountStartNonce": "0x0100000",
"homesteadTransition": "0x789b0",
"maximumExtraDataSize": "0x20",
"minGasLimit": "0x1388",
"networkID" : "0x2",
Expand Down
1 change: 1 addition & 0 deletions json/src/spec/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use spec::{Account, Builtin};

/// Blockchain test state deserializer.
#[derive(Debug, PartialEq, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct State(BTreeMap<Address, Account>);

impl State {
Expand Down
Loading