Reformat the source code
This commit is contained in:
@@ -18,92 +18,95 @@
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use uint::Uint;
|
||||
use bytes::Bytes;
|
||||
use spec::builtin::BuiltinCompat;
|
||||
use uint::Uint;
|
||||
|
||||
/// Spec account.
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Account {
|
||||
/// Builtin contract.
|
||||
pub builtin: Option<BuiltinCompat>,
|
||||
/// Balance.
|
||||
pub balance: Option<Uint>,
|
||||
/// Nonce.
|
||||
pub nonce: Option<Uint>,
|
||||
/// Code.
|
||||
pub code: Option<Bytes>,
|
||||
/// Storage.
|
||||
pub storage: Option<BTreeMap<Uint, Uint>>,
|
||||
/// Constructor.
|
||||
pub constructor: Option<Bytes>,
|
||||
/// Builtin contract.
|
||||
pub builtin: Option<BuiltinCompat>,
|
||||
/// Balance.
|
||||
pub balance: Option<Uint>,
|
||||
/// Nonce.
|
||||
pub nonce: Option<Uint>,
|
||||
/// Code.
|
||||
pub code: Option<Bytes>,
|
||||
/// Storage.
|
||||
pub storage: Option<BTreeMap<Uint, Uint>>,
|
||||
/// Constructor.
|
||||
pub constructor: Option<Bytes>,
|
||||
}
|
||||
|
||||
impl Account {
|
||||
/// Returns true if account does not have nonce, balance, code and storage.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.balance.is_none() && self.nonce.is_none() && self.code.is_none() && self.storage.is_none()
|
||||
}
|
||||
/// Returns true if account does not have nonce, balance, code and storage.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.balance.is_none()
|
||||
&& self.nonce.is_none()
|
||||
&& self.code.is_none()
|
||||
&& self.storage.is_none()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::collections::BTreeMap;
|
||||
use serde_json;
|
||||
use spec::account::Account;
|
||||
use ethereum_types::U256;
|
||||
use uint::Uint;
|
||||
use bytes::Bytes;
|
||||
use bytes::Bytes;
|
||||
use ethereum_types::U256;
|
||||
use serde_json;
|
||||
use spec::account::Account;
|
||||
use std::collections::BTreeMap;
|
||||
use uint::Uint;
|
||||
|
||||
#[test]
|
||||
fn account_balance_missing_not_empty() {
|
||||
let s = r#"{
|
||||
#[test]
|
||||
fn account_balance_missing_not_empty() {
|
||||
let s = r#"{
|
||||
"nonce": "0",
|
||||
"code": "1234",
|
||||
"storage": { "0x7fffffffffffffff7fffffffffffffff": "0x1" }
|
||||
}"#;
|
||||
let deserialized: Account = serde_json::from_str(s).unwrap();
|
||||
assert!(!deserialized.is_empty());
|
||||
}
|
||||
let deserialized: Account = serde_json::from_str(s).unwrap();
|
||||
assert!(!deserialized.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn account_nonce_missing_not_empty() {
|
||||
let s = r#"{
|
||||
#[test]
|
||||
fn account_nonce_missing_not_empty() {
|
||||
let s = r#"{
|
||||
"balance": "1",
|
||||
"code": "1234",
|
||||
"storage": { "0x7fffffffffffffff7fffffffffffffff": "0x1" }
|
||||
}"#;
|
||||
let deserialized: Account = serde_json::from_str(s).unwrap();
|
||||
assert!(!deserialized.is_empty());
|
||||
}
|
||||
let deserialized: Account = serde_json::from_str(s).unwrap();
|
||||
assert!(!deserialized.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn account_code_missing_not_empty() {
|
||||
let s = r#"{
|
||||
#[test]
|
||||
fn account_code_missing_not_empty() {
|
||||
let s = r#"{
|
||||
"balance": "1",
|
||||
"nonce": "0",
|
||||
"storage": { "0x7fffffffffffffff7fffffffffffffff": "0x1" }
|
||||
}"#;
|
||||
let deserialized: Account = serde_json::from_str(s).unwrap();
|
||||
assert!(!deserialized.is_empty());
|
||||
}
|
||||
let deserialized: Account = serde_json::from_str(s).unwrap();
|
||||
assert!(!deserialized.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn account_storage_missing_not_empty() {
|
||||
let s = r#"{
|
||||
#[test]
|
||||
fn account_storage_missing_not_empty() {
|
||||
let s = r#"{
|
||||
"balance": "1",
|
||||
"nonce": "0",
|
||||
"code": "1234"
|
||||
}"#;
|
||||
let deserialized: Account = serde_json::from_str(s).unwrap();
|
||||
assert!(!deserialized.is_empty());
|
||||
}
|
||||
let deserialized: Account = serde_json::from_str(s).unwrap();
|
||||
assert!(!deserialized.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn account_empty() {
|
||||
let s = r#"{
|
||||
#[test]
|
||||
fn account_empty() {
|
||||
let s = r#"{
|
||||
"builtin": {
|
||||
"name": "ecrecover",
|
||||
"pricing": {
|
||||
@@ -114,13 +117,13 @@ mod tests {
|
||||
}
|
||||
}
|
||||
}"#;
|
||||
let deserialized: Account = serde_json::from_str(s).unwrap();
|
||||
assert!(deserialized.is_empty());
|
||||
}
|
||||
let deserialized: Account = serde_json::from_str(s).unwrap();
|
||||
assert!(deserialized.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn account_deserialization() {
|
||||
let s = r#"{
|
||||
#[test]
|
||||
fn account_deserialization() {
|
||||
let s = r#"{
|
||||
"balance": "1",
|
||||
"nonce": "0",
|
||||
"code": "1234",
|
||||
@@ -134,29 +137,32 @@ mod tests {
|
||||
}
|
||||
}
|
||||
}"#;
|
||||
let deserialized: Account = serde_json::from_str(s).unwrap();
|
||||
assert!(!deserialized.is_empty());
|
||||
assert_eq!(deserialized.balance.unwrap(), Uint(U256::from(1)));
|
||||
assert_eq!(deserialized.nonce.unwrap(), Uint(U256::from(0)));
|
||||
assert_eq!(deserialized.code.unwrap(), Bytes::new(vec![0x12, 0x34]));
|
||||
assert!(deserialized.builtin.is_some()); // Further tested in builtin.rs
|
||||
}
|
||||
let deserialized: Account = serde_json::from_str(s).unwrap();
|
||||
assert!(!deserialized.is_empty());
|
||||
assert_eq!(deserialized.balance.unwrap(), Uint(U256::from(1)));
|
||||
assert_eq!(deserialized.nonce.unwrap(), Uint(U256::from(0)));
|
||||
assert_eq!(deserialized.code.unwrap(), Bytes::new(vec![0x12, 0x34]));
|
||||
assert!(deserialized.builtin.is_some()); // Further tested in builtin.rs
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn account_storage_deserialization() {
|
||||
let s = r#"{
|
||||
#[test]
|
||||
fn account_storage_deserialization() {
|
||||
let s = r#"{
|
||||
"balance": "1",
|
||||
"nonce": "0",
|
||||
"code": "1234",
|
||||
"storage": { "0x7fffffffffffffff7fffffffffffffff": "0x1" }
|
||||
}"#;
|
||||
let deserialized: Account = serde_json::from_str(s).unwrap();
|
||||
assert!(!deserialized.is_empty());
|
||||
assert_eq!(deserialized.balance.unwrap(), Uint(U256::from(1)));
|
||||
assert_eq!(deserialized.nonce.unwrap(), Uint(U256::from(0)));
|
||||
assert_eq!(deserialized.code.unwrap(), Bytes::new(vec![0x12, 0x34]));
|
||||
let mut storage = BTreeMap::new();
|
||||
storage.insert(Uint(U256::from("7fffffffffffffff7fffffffffffffff")), Uint(U256::from(1)));
|
||||
assert_eq!(deserialized.storage.unwrap(), storage);
|
||||
}
|
||||
let deserialized: Account = serde_json::from_str(s).unwrap();
|
||||
assert!(!deserialized.is_empty());
|
||||
assert_eq!(deserialized.balance.unwrap(), Uint(U256::from(1)));
|
||||
assert_eq!(deserialized.nonce.unwrap(), Uint(U256::from(0)));
|
||||
assert_eq!(deserialized.code.unwrap(), Bytes::new(vec![0x12, 0x34]));
|
||||
let mut storage = BTreeMap::new();
|
||||
storage.insert(
|
||||
Uint(U256::from("7fffffffffffffff7fffffffffffffff")),
|
||||
Uint(U256::from(1)),
|
||||
);
|
||||
assert_eq!(deserialized.storage.unwrap(), storage);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,70 +16,69 @@
|
||||
|
||||
//! Authority params deserialization.
|
||||
|
||||
use super::ValidatorSet;
|
||||
use bytes::Bytes;
|
||||
use hash::Address;
|
||||
use uint::Uint;
|
||||
use bytes::Bytes;
|
||||
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.
|
||||
pub step_duration: Uint,
|
||||
/// Valid authorities
|
||||
pub validators: ValidatorSet,
|
||||
/// Starting step. Determined automatically if not specified.
|
||||
/// To be used for testing only.
|
||||
pub start_step: Option<Uint>,
|
||||
/// Block at which score validation should start.
|
||||
pub validate_score_transition: Option<Uint>,
|
||||
/// Block from which monotonic steps start.
|
||||
pub validate_step_transition: Option<Uint>,
|
||||
/// Whether transitions should be immediate.
|
||||
pub immediate_transitions: Option<bool>,
|
||||
/// Reward per block in wei.
|
||||
pub block_reward: Option<Uint>,
|
||||
/// Block at which the block reward contract should start being used.
|
||||
pub block_reward_contract_transition: Option<Uint>,
|
||||
/// Block reward contract address (setting the block reward contract
|
||||
/// overrides the static block reward definition).
|
||||
pub block_reward_contract_address: Option<Address>,
|
||||
/// Block reward code. This overrides the block reward contract address.
|
||||
pub block_reward_contract_code: Option<Bytes>,
|
||||
/// Block at which maximum uncle count should be considered.
|
||||
pub maximum_uncle_count_transition: Option<Uint>,
|
||||
/// Maximum number of accepted uncles.
|
||||
pub maximum_uncle_count: Option<Uint>,
|
||||
/// Block at which empty step messages should start.
|
||||
pub empty_steps_transition: Option<Uint>,
|
||||
/// Maximum number of accepted empty steps.
|
||||
pub maximum_empty_steps: Option<Uint>,
|
||||
/// Strict validation of empty steps transition block.
|
||||
pub strict_empty_steps_transition: Option<Uint>,
|
||||
/// Block duration, in seconds.
|
||||
pub step_duration: Uint,
|
||||
/// Valid authorities
|
||||
pub validators: ValidatorSet,
|
||||
/// Starting step. Determined automatically if not specified.
|
||||
/// To be used for testing only.
|
||||
pub start_step: Option<Uint>,
|
||||
/// Block at which score validation should start.
|
||||
pub validate_score_transition: Option<Uint>,
|
||||
/// Block from which monotonic steps start.
|
||||
pub validate_step_transition: Option<Uint>,
|
||||
/// Whether transitions should be immediate.
|
||||
pub immediate_transitions: Option<bool>,
|
||||
/// Reward per block in wei.
|
||||
pub block_reward: Option<Uint>,
|
||||
/// Block at which the block reward contract should start being used.
|
||||
pub block_reward_contract_transition: Option<Uint>,
|
||||
/// Block reward contract address (setting the block reward contract
|
||||
/// overrides the static block reward definition).
|
||||
pub block_reward_contract_address: Option<Address>,
|
||||
/// Block reward code. This overrides the block reward contract address.
|
||||
pub block_reward_contract_code: Option<Bytes>,
|
||||
/// Block at which maximum uncle count should be considered.
|
||||
pub maximum_uncle_count_transition: Option<Uint>,
|
||||
/// Maximum number of accepted uncles.
|
||||
pub maximum_uncle_count: Option<Uint>,
|
||||
/// Block at which empty step messages should start.
|
||||
pub empty_steps_transition: Option<Uint>,
|
||||
/// Maximum number of accepted empty steps.
|
||||
pub maximum_empty_steps: Option<Uint>,
|
||||
/// Strict validation of empty steps transition block.
|
||||
pub strict_empty_steps_transition: Option<Uint>,
|
||||
}
|
||||
|
||||
/// Authority engine deserialization.
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct AuthorityRound {
|
||||
/// Ethash params.
|
||||
pub params: AuthorityRoundParams,
|
||||
/// Ethash params.
|
||||
pub params: AuthorityRoundParams,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ethereum_types::{U256, H160};
|
||||
use uint::Uint;
|
||||
use serde_json;
|
||||
use hash::Address;
|
||||
use spec::validator_set::ValidatorSet;
|
||||
use spec::authority_round::AuthorityRound;
|
||||
use ethereum_types::{H160, U256};
|
||||
use hash::Address;
|
||||
use serde_json;
|
||||
use spec::{authority_round::AuthorityRound, validator_set::ValidatorSet};
|
||||
use uint::Uint;
|
||||
|
||||
#[test]
|
||||
fn authority_round_deserialization() {
|
||||
let s = r#"{
|
||||
#[test]
|
||||
fn authority_round_deserialization() {
|
||||
let s = r#"{
|
||||
"params": {
|
||||
"stepDuration": "0x02",
|
||||
"validators": {
|
||||
@@ -93,13 +92,23 @@ mod tests {
|
||||
}
|
||||
}"#;
|
||||
|
||||
let deserialized: AuthorityRound = serde_json::from_str(s).unwrap();
|
||||
assert_eq!(deserialized.params.step_duration, Uint(U256::from(0x02)));
|
||||
assert_eq!(deserialized.params.validators, ValidatorSet::List(vec![Address(H160::from("0xc6d9d2cd449a754c494264e1809c50e34d64562b"))]));
|
||||
assert_eq!(deserialized.params.start_step, Some(Uint(U256::from(24))));
|
||||
assert_eq!(deserialized.params.immediate_transitions, None);
|
||||
assert_eq!(deserialized.params.maximum_uncle_count_transition, Some(Uint(10_000_000.into())));
|
||||
assert_eq!(deserialized.params.maximum_uncle_count, Some(Uint(5.into())));
|
||||
|
||||
}
|
||||
let deserialized: AuthorityRound = serde_json::from_str(s).unwrap();
|
||||
assert_eq!(deserialized.params.step_duration, Uint(U256::from(0x02)));
|
||||
assert_eq!(
|
||||
deserialized.params.validators,
|
||||
ValidatorSet::List(vec![Address(H160::from(
|
||||
"0xc6d9d2cd449a754c494264e1809c50e34d64562b"
|
||||
))])
|
||||
);
|
||||
assert_eq!(deserialized.params.start_step, Some(Uint(U256::from(24))));
|
||||
assert_eq!(deserialized.params.immediate_transitions, None);
|
||||
assert_eq!(
|
||||
deserialized.params.maximum_uncle_count_transition,
|
||||
Some(Uint(10_000_000.into()))
|
||||
);
|
||||
assert_eq!(
|
||||
deserialized.params.maximum_uncle_count,
|
||||
Some(Uint(5.into()))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,40 +16,39 @@
|
||||
|
||||
//! Authority params deserialization.
|
||||
|
||||
use uint::Uint;
|
||||
use super::ValidatorSet;
|
||||
use uint::Uint;
|
||||
|
||||
/// Authority params deserialization.
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct BasicAuthorityParams {
|
||||
/// Block duration.
|
||||
pub duration_limit: Uint,
|
||||
/// Valid authorities
|
||||
pub validators: ValidatorSet,
|
||||
/// Block duration.
|
||||
pub duration_limit: Uint,
|
||||
/// Valid authorities
|
||||
pub validators: ValidatorSet,
|
||||
}
|
||||
|
||||
/// Authority engine deserialization.
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct BasicAuthority {
|
||||
/// Ethash params.
|
||||
pub params: BasicAuthorityParams,
|
||||
/// Ethash params.
|
||||
pub params: BasicAuthorityParams,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use serde_json;
|
||||
use uint::Uint;
|
||||
use ethereum_types::{U256, H160};
|
||||
use hash::Address;
|
||||
use spec::basic_authority::BasicAuthority;
|
||||
use spec::validator_set::ValidatorSet;
|
||||
use ethereum_types::{H160, U256};
|
||||
use hash::Address;
|
||||
use serde_json;
|
||||
use spec::{basic_authority::BasicAuthority, validator_set::ValidatorSet};
|
||||
use uint::Uint;
|
||||
|
||||
#[test]
|
||||
fn basic_authority_deserialization() {
|
||||
let s = r#"{
|
||||
#[test]
|
||||
fn basic_authority_deserialization() {
|
||||
let s = r#"{
|
||||
"params": {
|
||||
"durationLimit": "0x0d",
|
||||
"validators" : {
|
||||
@@ -58,10 +57,12 @@ mod tests {
|
||||
}
|
||||
}"#;
|
||||
|
||||
let deserialized: BasicAuthority = serde_json::from_str(s).unwrap();
|
||||
let deserialized: BasicAuthority = serde_json::from_str(s).unwrap();
|
||||
|
||||
assert_eq!(deserialized.params.duration_limit, Uint(U256::from(0x0d)));
|
||||
let vs = ValidatorSet::List(vec![Address(H160::from("0xc6d9d2cd449a754c494264e1809c50e34d64562b"))]);
|
||||
assert_eq!(deserialized.params.validators, vs);
|
||||
}
|
||||
assert_eq!(deserialized.params.duration_limit, Uint(U256::from(0x0d)));
|
||||
let vs = ValidatorSet::List(vec![Address(H160::from(
|
||||
"0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
||||
))]);
|
||||
assert_eq!(deserialized.params.validators, vs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,43 +16,43 @@
|
||||
|
||||
//! Spec builtin deserialization.
|
||||
|
||||
use uint::Uint;
|
||||
use std::collections::BTreeMap;
|
||||
use uint::Uint;
|
||||
|
||||
/// Linear pricing.
|
||||
#[derive(Debug, PartialEq, Deserialize, Clone)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Linear {
|
||||
/// Base price.
|
||||
pub base: u64,
|
||||
/// Price for word.
|
||||
pub word: u64,
|
||||
/// Base price.
|
||||
pub base: u64,
|
||||
/// Price for word.
|
||||
pub word: u64,
|
||||
}
|
||||
|
||||
/// Pricing for modular exponentiation.
|
||||
#[derive(Debug, PartialEq, Deserialize, Clone)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Modexp {
|
||||
/// Price divisor.
|
||||
pub divisor: u64,
|
||||
/// Price divisor.
|
||||
pub divisor: u64,
|
||||
}
|
||||
|
||||
/// Pricing for constant alt_bn128 operations (ECADD and ECMUL)
|
||||
#[derive(Debug, PartialEq, Deserialize, Clone)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct AltBn128ConstOperations {
|
||||
/// price
|
||||
pub price: u64,
|
||||
/// price
|
||||
pub price: u64,
|
||||
}
|
||||
|
||||
/// Pricing for alt_bn128_pairing.
|
||||
#[derive(Debug, PartialEq, Deserialize, Clone)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct AltBn128Pairing {
|
||||
/// Base price.
|
||||
pub base: u64,
|
||||
/// Price per point pair.
|
||||
pub pair: u64,
|
||||
/// Base price.
|
||||
pub base: u64,
|
||||
/// Price per point pair.
|
||||
pub pair: u64,
|
||||
}
|
||||
|
||||
/// Pricing variants.
|
||||
@@ -60,57 +60,66 @@ pub struct AltBn128Pairing {
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Pricing {
|
||||
/// Pricing for Blake2 compression function: each call costs the same amount per round.
|
||||
Blake2F {
|
||||
/// Price per round of Blake2 compression function.
|
||||
gas_per_round: u64,
|
||||
},
|
||||
/// Linear pricing.
|
||||
Linear(Linear),
|
||||
/// Pricing for modular exponentiation.
|
||||
Modexp(Modexp),
|
||||
/// Pricing for alt_bn128_pairing exponentiation.
|
||||
AltBn128Pairing(AltBn128Pairing),
|
||||
/// Pricing for constant alt_bn128 operations
|
||||
AltBn128ConstOperations(AltBn128ConstOperations),
|
||||
/// Pricing for Blake2 compression function: each call costs the same amount per round.
|
||||
Blake2F {
|
||||
/// Price per round of Blake2 compression function.
|
||||
gas_per_round: u64,
|
||||
},
|
||||
/// Linear pricing.
|
||||
Linear(Linear),
|
||||
/// Pricing for modular exponentiation.
|
||||
Modexp(Modexp),
|
||||
/// Pricing for alt_bn128_pairing exponentiation.
|
||||
AltBn128Pairing(AltBn128Pairing),
|
||||
/// Pricing for constant alt_bn128 operations
|
||||
AltBn128ConstOperations(AltBn128ConstOperations),
|
||||
}
|
||||
|
||||
/// Builtin compability layer
|
||||
#[derive(Debug, PartialEq, Deserialize, Clone)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct BuiltinCompat {
|
||||
/// Builtin name.
|
||||
name: String,
|
||||
/// Builtin pricing.
|
||||
pricing: PricingCompat,
|
||||
/// Activation block.
|
||||
activate_at: Option<Uint>,
|
||||
/// Builtin name.
|
||||
name: String,
|
||||
/// Builtin pricing.
|
||||
pricing: PricingCompat,
|
||||
/// Activation block.
|
||||
activate_at: Option<Uint>,
|
||||
}
|
||||
|
||||
/// Spec builtin.
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct Builtin {
|
||||
/// Builtin name.
|
||||
pub name: String,
|
||||
/// Builtin pricing.
|
||||
pub pricing: BTreeMap<u64, PricingAt>,
|
||||
/// Builtin name.
|
||||
pub name: String,
|
||||
/// Builtin pricing.
|
||||
pub pricing: BTreeMap<u64, PricingAt>,
|
||||
}
|
||||
|
||||
impl From<BuiltinCompat> for Builtin {
|
||||
fn from(legacy: BuiltinCompat) -> Self {
|
||||
let pricing = match legacy.pricing {
|
||||
PricingCompat::Single(pricing) => {
|
||||
let mut map = BTreeMap::new();
|
||||
let activate_at: u64 = legacy.activate_at.map_or(0, Into::into);
|
||||
map.insert(activate_at, PricingAt { info: None, price: pricing });
|
||||
map
|
||||
}
|
||||
PricingCompat::Multi(pricings) => {
|
||||
pricings.into_iter().map(|(a, p)| (a.into(), p)).collect()
|
||||
}
|
||||
};
|
||||
Self { name: legacy.name, pricing }
|
||||
}
|
||||
fn from(legacy: BuiltinCompat) -> Self {
|
||||
let pricing = match legacy.pricing {
|
||||
PricingCompat::Single(pricing) => {
|
||||
let mut map = BTreeMap::new();
|
||||
let activate_at: u64 = legacy.activate_at.map_or(0, Into::into);
|
||||
map.insert(
|
||||
activate_at,
|
||||
PricingAt {
|
||||
info: None,
|
||||
price: pricing,
|
||||
},
|
||||
);
|
||||
map
|
||||
}
|
||||
PricingCompat::Multi(pricings) => {
|
||||
pricings.into_iter().map(|(a, p)| (a.into(), p)).collect()
|
||||
}
|
||||
};
|
||||
Self {
|
||||
name: legacy.name,
|
||||
pricing,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Compability layer for different pricings
|
||||
@@ -119,48 +128,54 @@ impl From<BuiltinCompat> for Builtin {
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[serde(untagged)]
|
||||
enum PricingCompat {
|
||||
/// Single builtin
|
||||
Single(Pricing),
|
||||
/// Multiple builtins
|
||||
Multi(BTreeMap<Uint, PricingAt>),
|
||||
/// Single builtin
|
||||
Single(Pricing),
|
||||
/// Multiple builtins
|
||||
Multi(BTreeMap<Uint, PricingAt>),
|
||||
}
|
||||
|
||||
/// Price for a builtin, with the block number to activate it on
|
||||
#[derive(Debug, PartialEq, Deserialize, Clone)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct PricingAt {
|
||||
/// Description of the activation, e.g. "PunyPony HF, March 12, 2025".
|
||||
pub info: Option<String>,
|
||||
/// Builtin pricing.
|
||||
pub price: Pricing,
|
||||
/// Description of the activation, e.g. "PunyPony HF, March 12, 2025".
|
||||
pub info: Option<String>,
|
||||
/// Builtin pricing.
|
||||
pub price: Pricing,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use serde_json;
|
||||
use uint::Uint;
|
||||
use super::{Builtin, BuiltinCompat, BTreeMap, Pricing, PricingAt, Linear, Modexp, AltBn128ConstOperations};
|
||||
use macros::map;
|
||||
use super::{
|
||||
AltBn128ConstOperations, BTreeMap, Builtin, BuiltinCompat, Linear, Modexp, Pricing,
|
||||
PricingAt,
|
||||
};
|
||||
use macros::map;
|
||||
use serde_json;
|
||||
use uint::Uint;
|
||||
|
||||
#[test]
|
||||
fn builtin_deserialization() {
|
||||
let s = r#"{
|
||||
#[test]
|
||||
fn builtin_deserialization() {
|
||||
let s = r#"{
|
||||
"name": "ecrecover",
|
||||
"pricing": { "linear": { "base": 3000, "word": 0 } }
|
||||
}"#;
|
||||
let builtin: Builtin = serde_json::from_str::<BuiltinCompat>(s).unwrap().into();
|
||||
assert_eq!(builtin.name, "ecrecover");
|
||||
assert_eq!(builtin.pricing, map![
|
||||
0 => PricingAt {
|
||||
info: None,
|
||||
price: Pricing::Linear(Linear { base: 3000, word: 0 })
|
||||
}
|
||||
]);
|
||||
}
|
||||
let builtin: Builtin = serde_json::from_str::<BuiltinCompat>(s).unwrap().into();
|
||||
assert_eq!(builtin.name, "ecrecover");
|
||||
assert_eq!(
|
||||
builtin.pricing,
|
||||
map![
|
||||
0 => PricingAt {
|
||||
info: None,
|
||||
price: Pricing::Linear(Linear { base: 3000, word: 0 })
|
||||
}
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deserialize_multiple_pricings() {
|
||||
let s = r#"{
|
||||
#[test]
|
||||
fn deserialize_multiple_pricings() {
|
||||
let s = r#"{
|
||||
"name": "ecrecover",
|
||||
"pricing": {
|
||||
"0": {
|
||||
@@ -172,40 +187,46 @@ mod tests {
|
||||
}
|
||||
}
|
||||
}"#;
|
||||
let builtin: Builtin = serde_json::from_str::<BuiltinCompat>(s).unwrap().into();
|
||||
assert_eq!(builtin.name, "ecrecover");
|
||||
assert_eq!(builtin.pricing, map![
|
||||
0 => PricingAt {
|
||||
info: None,
|
||||
price: Pricing::Linear(Linear { base: 3000, word: 0 })
|
||||
},
|
||||
500 => PricingAt {
|
||||
info: Some(String::from("enable fake EIP at block 500")),
|
||||
price: Pricing::Linear(Linear { base: 10, word: 0 })
|
||||
}
|
||||
]);
|
||||
}
|
||||
let builtin: Builtin = serde_json::from_str::<BuiltinCompat>(s).unwrap().into();
|
||||
assert_eq!(builtin.name, "ecrecover");
|
||||
assert_eq!(
|
||||
builtin.pricing,
|
||||
map![
|
||||
0 => PricingAt {
|
||||
info: None,
|
||||
price: Pricing::Linear(Linear { base: 3000, word: 0 })
|
||||
},
|
||||
500 => PricingAt {
|
||||
info: Some(String::from("enable fake EIP at block 500")),
|
||||
price: Pricing::Linear(Linear { base: 10, word: 0 })
|
||||
}
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deserialization_blake2_f_builtin() {
|
||||
let s = r#"{
|
||||
#[test]
|
||||
fn deserialization_blake2_f_builtin() {
|
||||
let s = r#"{
|
||||
"name": "blake2_f",
|
||||
"activate_at": "0xffffff",
|
||||
"pricing": { "blake2_f": { "gas_per_round": 123 } }
|
||||
}"#;
|
||||
let builtin: Builtin = serde_json::from_str::<BuiltinCompat>(s).unwrap().into();
|
||||
assert_eq!(builtin.name, "blake2_f");
|
||||
assert_eq!(builtin.pricing, map![
|
||||
0xffffff => PricingAt {
|
||||
info: None,
|
||||
price: Pricing::Blake2F { gas_per_round: 123 }
|
||||
}
|
||||
]);
|
||||
}
|
||||
let builtin: Builtin = serde_json::from_str::<BuiltinCompat>(s).unwrap().into();
|
||||
assert_eq!(builtin.name, "blake2_f");
|
||||
assert_eq!(
|
||||
builtin.pricing,
|
||||
map![
|
||||
0xffffff => PricingAt {
|
||||
info: None,
|
||||
price: Pricing::Blake2F { gas_per_round: 123 }
|
||||
}
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deserialization_alt_bn128_const_operations() {
|
||||
let s = r#"{
|
||||
#[test]
|
||||
fn deserialization_alt_bn128_const_operations() {
|
||||
let s = r#"{
|
||||
"name": "alt_bn128_mul",
|
||||
"pricing": {
|
||||
"100500": {
|
||||
@@ -213,33 +234,39 @@ mod tests {
|
||||
}
|
||||
}
|
||||
}"#;
|
||||
let builtin: Builtin = serde_json::from_str::<BuiltinCompat>(s).unwrap().into();
|
||||
assert_eq!(builtin.name, "alt_bn128_mul");
|
||||
assert_eq!(builtin.pricing, map![
|
||||
100500 => PricingAt {
|
||||
info: None,
|
||||
price: Pricing::AltBn128ConstOperations(AltBn128ConstOperations {
|
||||
price: 123,
|
||||
}),
|
||||
}
|
||||
]);
|
||||
}
|
||||
let builtin: Builtin = serde_json::from_str::<BuiltinCompat>(s).unwrap().into();
|
||||
assert_eq!(builtin.name, "alt_bn128_mul");
|
||||
assert_eq!(
|
||||
builtin.pricing,
|
||||
map![
|
||||
100500 => PricingAt {
|
||||
info: None,
|
||||
price: Pricing::AltBn128ConstOperations(AltBn128ConstOperations {
|
||||
price: 123,
|
||||
}),
|
||||
}
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn activate_at() {
|
||||
let s = r#"{
|
||||
#[test]
|
||||
fn activate_at() {
|
||||
let s = r#"{
|
||||
"name": "late_start",
|
||||
"activate_at": 100000,
|
||||
"pricing": { "modexp": { "divisor": 5 } }
|
||||
}"#;
|
||||
|
||||
let builtin: Builtin = serde_json::from_str::<BuiltinCompat>(s).unwrap().into();
|
||||
assert_eq!(builtin.name, "late_start");
|
||||
assert_eq!(builtin.pricing, map![
|
||||
100_000 => PricingAt {
|
||||
info: None,
|
||||
price: Pricing::Modexp(Modexp { divisor: 5 })
|
||||
}
|
||||
]);
|
||||
}
|
||||
let builtin: Builtin = serde_json::from_str::<BuiltinCompat>(s).unwrap().into();
|
||||
assert_eq!(builtin.name, "late_start");
|
||||
assert_eq!(
|
||||
builtin.pricing,
|
||||
map![
|
||||
100_000 => PricingAt {
|
||||
info: None,
|
||||
price: Pricing::Modexp(Modexp { divisor: 5 })
|
||||
}
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,37 +21,37 @@ use std::num::NonZeroU64;
|
||||
/// Clique params deserialization.
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
pub struct CliqueParams {
|
||||
/// period as defined in EIP
|
||||
pub period: Option<u64>,
|
||||
/// epoch length as defined in EIP
|
||||
pub epoch: Option<NonZeroU64>
|
||||
/// period as defined in EIP
|
||||
pub period: Option<u64>,
|
||||
/// epoch length as defined in EIP
|
||||
pub epoch: Option<NonZeroU64>,
|
||||
}
|
||||
|
||||
/// Clique engine deserialization.
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
pub struct Clique {
|
||||
/// CliqueEngine params
|
||||
pub params: CliqueParams,
|
||||
/// CliqueEngine params
|
||||
pub params: CliqueParams,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use serde_json;
|
||||
use uint::Uint;
|
||||
use ethereum_types::U256;
|
||||
use super::*;
|
||||
use super::*;
|
||||
use ethereum_types::U256;
|
||||
use serde_json;
|
||||
use uint::Uint;
|
||||
|
||||
#[test]
|
||||
fn clique_deserialization() {
|
||||
let s = r#"{
|
||||
#[test]
|
||||
fn clique_deserialization() {
|
||||
let s = r#"{
|
||||
"params": {
|
||||
"period": 5,
|
||||
"epoch": 30000
|
||||
}
|
||||
}"#;
|
||||
|
||||
let deserialized: Clique = serde_json::from_str(s).unwrap();
|
||||
assert_eq!(deserialized.params.period, Some(5u64));
|
||||
assert_eq!(deserialized.params.epoch, NonZeroU64::new(30000));
|
||||
}
|
||||
let deserialized: Clique = serde_json::from_str(s).unwrap();
|
||||
assert_eq!(deserialized.params.period, Some(5u64));
|
||||
assert_eq!(deserialized.params.epoch, NonZeroU64::new(30000));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,36 +16,36 @@
|
||||
|
||||
//! Engine deserialization.
|
||||
|
||||
use super::{Ethash, BasicAuthority, AuthorityRound, NullEngine, InstantSeal, Clique};
|
||||
use super::{AuthorityRound, BasicAuthority, Clique, Ethash, InstantSeal, NullEngine};
|
||||
|
||||
/// Engine deserialization.
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum Engine {
|
||||
/// Null engine.
|
||||
Null(NullEngine),
|
||||
/// Instantly sealing engine.
|
||||
InstantSeal(Option<InstantSeal>),
|
||||
/// Ethash engine.
|
||||
#[serde(rename = "Ethash")]
|
||||
Ethash(Ethash),
|
||||
/// BasicAuthority engine.
|
||||
BasicAuthority(BasicAuthority),
|
||||
/// AuthorityRound engine.
|
||||
AuthorityRound(AuthorityRound),
|
||||
/// Clique engine.
|
||||
Clique(Clique)
|
||||
/// Null engine.
|
||||
Null(NullEngine),
|
||||
/// Instantly sealing engine.
|
||||
InstantSeal(Option<InstantSeal>),
|
||||
/// Ethash engine.
|
||||
#[serde(rename = "Ethash")]
|
||||
Ethash(Ethash),
|
||||
/// BasicAuthority engine.
|
||||
BasicAuthority(BasicAuthority),
|
||||
/// AuthorityRound engine.
|
||||
AuthorityRound(AuthorityRound),
|
||||
/// Clique engine.
|
||||
Clique(Clique),
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use serde_json;
|
||||
use spec::Engine;
|
||||
use serde_json;
|
||||
use spec::Engine;
|
||||
|
||||
#[test]
|
||||
fn engine_deserialization() {
|
||||
let s = r#"{
|
||||
#[test]
|
||||
fn engine_deserialization() {
|
||||
let s = r#"{
|
||||
"null": {
|
||||
"params": {
|
||||
"blockReward": "0x0d"
|
||||
@@ -53,33 +53,33 @@ mod tests {
|
||||
}
|
||||
}"#;
|
||||
|
||||
let deserialized: Engine = serde_json::from_str(s).unwrap();
|
||||
match deserialized {
|
||||
Engine::Null(_) => {}, // unit test in its own file.
|
||||
_ => panic!(),
|
||||
}
|
||||
let deserialized: Engine = serde_json::from_str(s).unwrap();
|
||||
match deserialized {
|
||||
Engine::Null(_) => {} // unit test in its own file.
|
||||
_ => panic!(),
|
||||
}
|
||||
|
||||
let s = r#"{
|
||||
let s = r#"{
|
||||
"instantSeal": {"params": {}}
|
||||
}"#;
|
||||
|
||||
let deserialized: Engine = serde_json::from_str(s).unwrap();
|
||||
match deserialized {
|
||||
Engine::InstantSeal(_) => {}, // instant seal is unit tested in its own file.
|
||||
_ => panic!(),
|
||||
};
|
||||
let deserialized: Engine = serde_json::from_str(s).unwrap();
|
||||
match deserialized {
|
||||
Engine::InstantSeal(_) => {} // instant seal is unit tested in its own file.
|
||||
_ => panic!(),
|
||||
};
|
||||
|
||||
let s = r#"{
|
||||
let s = r#"{
|
||||
"instantSeal": null
|
||||
}"#;
|
||||
|
||||
let deserialized: Engine = serde_json::from_str(s).unwrap();
|
||||
match deserialized {
|
||||
Engine::InstantSeal(_) => {}, // instant seal is unit tested in its own file.
|
||||
_ => panic!(),
|
||||
};
|
||||
let deserialized: Engine = serde_json::from_str(s).unwrap();
|
||||
match deserialized {
|
||||
Engine::InstantSeal(_) => {} // instant seal is unit tested in its own file.
|
||||
_ => panic!(),
|
||||
};
|
||||
|
||||
let s = r#"{
|
||||
let s = r#"{
|
||||
"Ethash": {
|
||||
"params": {
|
||||
"minimumDifficulty": "0x020000",
|
||||
@@ -93,13 +93,13 @@ mod tests {
|
||||
}
|
||||
}"#;
|
||||
|
||||
let deserialized: Engine = serde_json::from_str(s).unwrap();
|
||||
match deserialized {
|
||||
Engine::Ethash(_) => {}, // ethash is unit tested in its own file.
|
||||
_ => panic!(),
|
||||
};
|
||||
let deserialized: Engine = serde_json::from_str(s).unwrap();
|
||||
match deserialized {
|
||||
Engine::Ethash(_) => {} // ethash is unit tested in its own file.
|
||||
_ => panic!(),
|
||||
};
|
||||
|
||||
let s = r#"{
|
||||
let s = r#"{
|
||||
"basicAuthority": {
|
||||
"params": {
|
||||
"durationLimit": "0x0d",
|
||||
@@ -109,13 +109,13 @@ mod tests {
|
||||
}
|
||||
}
|
||||
}"#;
|
||||
let deserialized: Engine = serde_json::from_str(s).unwrap();
|
||||
match deserialized {
|
||||
Engine::BasicAuthority(_) => {}, // basicAuthority is unit tested in its own file.
|
||||
_ => panic!(),
|
||||
};
|
||||
let deserialized: Engine = serde_json::from_str(s).unwrap();
|
||||
match deserialized {
|
||||
Engine::BasicAuthority(_) => {} // basicAuthority is unit tested in its own file.
|
||||
_ => panic!(),
|
||||
};
|
||||
|
||||
let s = r#"{
|
||||
let s = r#"{
|
||||
"authorityRound": {
|
||||
"params": {
|
||||
"stepDuration": "0x02",
|
||||
@@ -127,13 +127,13 @@ mod tests {
|
||||
}
|
||||
}
|
||||
}"#;
|
||||
let deserialized: Engine = serde_json::from_str(s).unwrap();
|
||||
match deserialized {
|
||||
Engine::AuthorityRound(_) => {}, // AuthorityRound is unit tested in its own file.
|
||||
_ => panic!(),
|
||||
};
|
||||
let deserialized: Engine = serde_json::from_str(s).unwrap();
|
||||
match deserialized {
|
||||
Engine::AuthorityRound(_) => {} // AuthorityRound is unit tested in its own file.
|
||||
_ => panic!(),
|
||||
};
|
||||
|
||||
let s = r#"{
|
||||
let s = r#"{
|
||||
"clique": {
|
||||
"params": {
|
||||
"period": 15,
|
||||
@@ -141,10 +141,10 @@ mod tests {
|
||||
}
|
||||
}
|
||||
}"#;
|
||||
let deserialized: Engine = serde_json::from_str(s).unwrap();
|
||||
match deserialized {
|
||||
Engine::Clique(_) => {}, // Clique is unit tested in its own file.
|
||||
_ => panic!(),
|
||||
};
|
||||
}
|
||||
let deserialized: Engine = serde_json::from_str(s).unwrap();
|
||||
match deserialized {
|
||||
Engine::Clique(_) => {} // Clique is unit tested in its own file.
|
||||
_ => panic!(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,18 +16,18 @@
|
||||
|
||||
//! Ethash params deserialization.
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use uint::{self, Uint};
|
||||
use bytes::Bytes;
|
||||
use hash::Address;
|
||||
use std::collections::BTreeMap;
|
||||
use uint::{self, Uint};
|
||||
|
||||
/// Deserializable doppelganger of block rewards for EthashParams
|
||||
#[derive(Clone, Debug, PartialEq, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[serde(untagged)]
|
||||
pub enum BlockReward {
|
||||
Single(Uint),
|
||||
Multi(BTreeMap<Uint, Uint>),
|
||||
Single(Uint),
|
||||
Multi(BTreeMap<Uint, Uint>),
|
||||
}
|
||||
|
||||
/// Deserializable doppelganger of EthashParams.
|
||||
@@ -35,90 +35,90 @@ pub enum BlockReward {
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct EthashParams {
|
||||
/// See main EthashParams docs.
|
||||
#[serde(deserialize_with="uint::validate_non_zero")]
|
||||
pub minimum_difficulty: Uint,
|
||||
/// See main EthashParams docs.
|
||||
#[serde(deserialize_with="uint::validate_non_zero")]
|
||||
pub difficulty_bound_divisor: Uint,
|
||||
/// See main EthashParams docs.
|
||||
#[serde(default, deserialize_with="uint::validate_optional_non_zero")]
|
||||
pub difficulty_increment_divisor: Option<Uint>,
|
||||
/// See main EthashParams docs.
|
||||
#[serde(default, deserialize_with="uint::validate_optional_non_zero")]
|
||||
pub metropolis_difficulty_increment_divisor: Option<Uint>,
|
||||
/// See main EthashParams docs.
|
||||
pub duration_limit: Option<Uint>,
|
||||
/// See main EthashParams docs.
|
||||
#[serde(deserialize_with = "uint::validate_non_zero")]
|
||||
pub minimum_difficulty: Uint,
|
||||
/// See main EthashParams docs.
|
||||
#[serde(deserialize_with = "uint::validate_non_zero")]
|
||||
pub difficulty_bound_divisor: Uint,
|
||||
/// See main EthashParams docs.
|
||||
#[serde(default, deserialize_with = "uint::validate_optional_non_zero")]
|
||||
pub difficulty_increment_divisor: Option<Uint>,
|
||||
/// See main EthashParams docs.
|
||||
#[serde(default, deserialize_with = "uint::validate_optional_non_zero")]
|
||||
pub metropolis_difficulty_increment_divisor: Option<Uint>,
|
||||
/// See main EthashParams docs.
|
||||
pub duration_limit: Option<Uint>,
|
||||
|
||||
/// See main EthashParams docs.
|
||||
pub homestead_transition: Option<Uint>,
|
||||
/// Reward per block in wei.
|
||||
pub block_reward: Option<BlockReward>,
|
||||
/// Block at which the block reward contract should start being used.
|
||||
pub block_reward_contract_transition: Option<Uint>,
|
||||
/// Block reward contract address (setting the block reward contract
|
||||
/// overrides all other block reward parameters).
|
||||
pub block_reward_contract_address: Option<Address>,
|
||||
/// Block reward code. This overrides the block reward contract address.
|
||||
pub block_reward_contract_code: Option<Bytes>,
|
||||
/// See main EthashParams docs.
|
||||
pub homestead_transition: Option<Uint>,
|
||||
/// Reward per block in wei.
|
||||
pub block_reward: Option<BlockReward>,
|
||||
/// Block at which the block reward contract should start being used.
|
||||
pub block_reward_contract_transition: Option<Uint>,
|
||||
/// Block reward contract address (setting the block reward contract
|
||||
/// overrides all other block reward parameters).
|
||||
pub block_reward_contract_address: Option<Address>,
|
||||
/// Block reward code. This overrides the block reward contract address.
|
||||
pub block_reward_contract_code: Option<Bytes>,
|
||||
|
||||
/// See main EthashParams docs.
|
||||
pub dao_hardfork_transition: Option<Uint>,
|
||||
/// See main EthashParams docs.
|
||||
pub dao_hardfork_beneficiary: Option<Address>,
|
||||
/// See main EthashParams docs.
|
||||
pub dao_hardfork_accounts: Option<Vec<Address>>,
|
||||
/// See main EthashParams docs.
|
||||
pub dao_hardfork_transition: Option<Uint>,
|
||||
/// See main EthashParams docs.
|
||||
pub dao_hardfork_beneficiary: Option<Address>,
|
||||
/// See main EthashParams docs.
|
||||
pub dao_hardfork_accounts: Option<Vec<Address>>,
|
||||
|
||||
/// See main EthashParams docs.
|
||||
pub difficulty_hardfork_transition: Option<Uint>,
|
||||
/// See main EthashParams docs.
|
||||
#[serde(default, deserialize_with="uint::validate_optional_non_zero")]
|
||||
pub difficulty_hardfork_bound_divisor: Option<Uint>,
|
||||
/// See main EthashParams docs.
|
||||
pub bomb_defuse_transition: Option<Uint>,
|
||||
/// See main EthashParams docs.
|
||||
pub difficulty_hardfork_transition: Option<Uint>,
|
||||
/// See main EthashParams docs.
|
||||
#[serde(default, deserialize_with = "uint::validate_optional_non_zero")]
|
||||
pub difficulty_hardfork_bound_divisor: Option<Uint>,
|
||||
/// See main EthashParams docs.
|
||||
pub bomb_defuse_transition: Option<Uint>,
|
||||
|
||||
/// See main EthashParams docs.
|
||||
pub eip100b_transition: Option<Uint>,
|
||||
/// See main EthashParams docs.
|
||||
pub eip100b_transition: Option<Uint>,
|
||||
|
||||
/// See main EthashParams docs.
|
||||
pub ecip1010_pause_transition: Option<Uint>,
|
||||
/// See main EthashParams docs.
|
||||
pub ecip1010_continue_transition: Option<Uint>,
|
||||
/// See main EthashParams docs.
|
||||
pub ecip1010_pause_transition: Option<Uint>,
|
||||
/// See main EthashParams docs.
|
||||
pub ecip1010_continue_transition: Option<Uint>,
|
||||
|
||||
/// See main EthashParams docs.
|
||||
pub ecip1017_era_rounds: Option<Uint>,
|
||||
/// See main EthashParams docs.
|
||||
pub ecip1017_era_rounds: Option<Uint>,
|
||||
|
||||
/// Delays of difficulty bombs.
|
||||
pub difficulty_bomb_delays: Option<BTreeMap<Uint, Uint>>,
|
||||
/// Delays of difficulty bombs.
|
||||
pub difficulty_bomb_delays: Option<BTreeMap<Uint, Uint>>,
|
||||
|
||||
/// EXPIP-2 block height
|
||||
pub expip2_transition: Option<Uint>,
|
||||
/// EXPIP-2 duration limit
|
||||
pub expip2_duration_limit: Option<Uint>,
|
||||
/// Block to transition to progpow
|
||||
#[serde(rename="progpowTransition")]
|
||||
pub progpow_transition: Option<Uint>,
|
||||
/// EXPIP-2 block height
|
||||
pub expip2_transition: Option<Uint>,
|
||||
/// EXPIP-2 duration limit
|
||||
pub expip2_duration_limit: Option<Uint>,
|
||||
/// Block to transition to progpow
|
||||
#[serde(rename = "progpowTransition")]
|
||||
pub progpow_transition: Option<Uint>,
|
||||
}
|
||||
|
||||
/// Ethash engine deserialization.
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Ethash {
|
||||
/// Ethash params.
|
||||
pub params: EthashParams,
|
||||
/// Ethash params.
|
||||
pub params: EthashParams,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use serde_json;
|
||||
use uint::Uint;
|
||||
use ethereum_types::{H160, U256};
|
||||
use hash::Address;
|
||||
use spec::ethash::{Ethash, EthashParams, BlockReward};
|
||||
use ethereum_types::{H160, U256};
|
||||
use hash::Address;
|
||||
use serde_json;
|
||||
use spec::ethash::{BlockReward, Ethash, EthashParams};
|
||||
use uint::Uint;
|
||||
|
||||
#[test]
|
||||
fn ethash_deserialization() {
|
||||
let s = r#"{
|
||||
#[test]
|
||||
fn ethash_deserialization() {
|
||||
let s = r#"{
|
||||
"params": {
|
||||
"minimumDifficulty": "0x020000",
|
||||
"difficultyBoundDivisor": "0x0800",
|
||||
@@ -156,109 +156,117 @@ mod tests {
|
||||
}
|
||||
}"#;
|
||||
|
||||
let deserialized: Ethash = serde_json::from_str(s).unwrap();
|
||||
let deserialized: Ethash = serde_json::from_str(s).unwrap();
|
||||
|
||||
assert_eq!(deserialized, Ethash {
|
||||
params: EthashParams {
|
||||
minimum_difficulty: Uint(U256::from(0x020000)),
|
||||
difficulty_bound_divisor: Uint(U256::from(0x0800)),
|
||||
difficulty_increment_divisor: None,
|
||||
metropolis_difficulty_increment_divisor: None,
|
||||
duration_limit: Some(Uint(U256::from(0x0d))),
|
||||
homestead_transition: Some(Uint(U256::from(0x42))),
|
||||
block_reward: Some(BlockReward::Single(Uint(U256::from(0x100)))),
|
||||
block_reward_contract_address: None,
|
||||
block_reward_contract_code: None,
|
||||
block_reward_contract_transition: None,
|
||||
dao_hardfork_transition: Some(Uint(U256::from(0x08))),
|
||||
dao_hardfork_beneficiary: Some(Address(H160::from("0xabcabcabcabcabcabcabcabcabcabcabcabcabca"))),
|
||||
dao_hardfork_accounts: Some(vec![
|
||||
Address(H160::from("0x304a554a310c7e546dfe434669c62820b7d83490")),
|
||||
Address(H160::from("0x914d1b8b43e92723e64fd0a06f5bdb8dd9b10c79")),
|
||||
Address(H160::from("0xfe24cdd8648121a43a7c86d289be4dd2951ed49f")),
|
||||
Address(H160::from("0x17802f43a0137c506ba92291391a8a8f207f487d")),
|
||||
Address(H160::from("0xb136707642a4ea12fb4bae820f03d2562ebff487")),
|
||||
Address(H160::from("0xdbe9b615a3ae8709af8b93336ce9b477e4ac0940")),
|
||||
Address(H160::from("0xf14c14075d6c4ed84b86798af0956deef67365b5")),
|
||||
Address(H160::from("0xca544e5c4687d109611d0f8f928b53a25af72448")),
|
||||
Address(H160::from("0xaeeb8ff27288bdabc0fa5ebb731b6f409507516c")),
|
||||
Address(H160::from("0xcbb9d3703e651b0d496cdefb8b92c25aeb2171f7")),
|
||||
Address(H160::from("0xaccc230e8a6e5be9160b8cdf2864dd2a001c28b6")),
|
||||
Address(H160::from("0x2b3455ec7fedf16e646268bf88846bd7a2319bb2")),
|
||||
Address(H160::from("0x4613f3bca5c44ea06337a9e439fbc6d42e501d0a")),
|
||||
Address(H160::from("0xd343b217de44030afaa275f54d31a9317c7f441e")),
|
||||
Address(H160::from("0x84ef4b2357079cd7a7c69fd7a37cd0609a679106")),
|
||||
Address(H160::from("0xda2fef9e4a3230988ff17df2165440f37e8b1708")),
|
||||
Address(H160::from("0xf4c64518ea10f995918a454158c6b61407ea345c")),
|
||||
Address(H160::from("0x7602b46df5390e432ef1c307d4f2c9ff6d65cc97")),
|
||||
Address(H160::from("0xbb9bc244d798123fde783fcc1c72d3bb8c189413")),
|
||||
Address(H160::from("0x807640a13483f8ac783c557fcdf27be11ea4ac7a")),
|
||||
]),
|
||||
difficulty_hardfork_transition: Some(Uint(U256::from(0x59d9))),
|
||||
difficulty_hardfork_bound_divisor: Some(Uint(U256::from(0x0200))),
|
||||
bomb_defuse_transition: Some(Uint(U256::from(0x41))),
|
||||
eip100b_transition: Some(Uint(U256::from(0x42))),
|
||||
ecip1010_pause_transition: None,
|
||||
ecip1010_continue_transition: None,
|
||||
ecip1017_era_rounds: None,
|
||||
expip2_transition: None,
|
||||
expip2_duration_limit: None,
|
||||
progpow_transition: None,
|
||||
difficulty_bomb_delays: None,
|
||||
}
|
||||
});
|
||||
}
|
||||
assert_eq!(
|
||||
deserialized,
|
||||
Ethash {
|
||||
params: EthashParams {
|
||||
minimum_difficulty: Uint(U256::from(0x020000)),
|
||||
difficulty_bound_divisor: Uint(U256::from(0x0800)),
|
||||
difficulty_increment_divisor: None,
|
||||
metropolis_difficulty_increment_divisor: None,
|
||||
duration_limit: Some(Uint(U256::from(0x0d))),
|
||||
homestead_transition: Some(Uint(U256::from(0x42))),
|
||||
block_reward: Some(BlockReward::Single(Uint(U256::from(0x100)))),
|
||||
block_reward_contract_address: None,
|
||||
block_reward_contract_code: None,
|
||||
block_reward_contract_transition: None,
|
||||
dao_hardfork_transition: Some(Uint(U256::from(0x08))),
|
||||
dao_hardfork_beneficiary: Some(Address(H160::from(
|
||||
"0xabcabcabcabcabcabcabcabcabcabcabcabcabca"
|
||||
))),
|
||||
dao_hardfork_accounts: Some(vec![
|
||||
Address(H160::from("0x304a554a310c7e546dfe434669c62820b7d83490")),
|
||||
Address(H160::from("0x914d1b8b43e92723e64fd0a06f5bdb8dd9b10c79")),
|
||||
Address(H160::from("0xfe24cdd8648121a43a7c86d289be4dd2951ed49f")),
|
||||
Address(H160::from("0x17802f43a0137c506ba92291391a8a8f207f487d")),
|
||||
Address(H160::from("0xb136707642a4ea12fb4bae820f03d2562ebff487")),
|
||||
Address(H160::from("0xdbe9b615a3ae8709af8b93336ce9b477e4ac0940")),
|
||||
Address(H160::from("0xf14c14075d6c4ed84b86798af0956deef67365b5")),
|
||||
Address(H160::from("0xca544e5c4687d109611d0f8f928b53a25af72448")),
|
||||
Address(H160::from("0xaeeb8ff27288bdabc0fa5ebb731b6f409507516c")),
|
||||
Address(H160::from("0xcbb9d3703e651b0d496cdefb8b92c25aeb2171f7")),
|
||||
Address(H160::from("0xaccc230e8a6e5be9160b8cdf2864dd2a001c28b6")),
|
||||
Address(H160::from("0x2b3455ec7fedf16e646268bf88846bd7a2319bb2")),
|
||||
Address(H160::from("0x4613f3bca5c44ea06337a9e439fbc6d42e501d0a")),
|
||||
Address(H160::from("0xd343b217de44030afaa275f54d31a9317c7f441e")),
|
||||
Address(H160::from("0x84ef4b2357079cd7a7c69fd7a37cd0609a679106")),
|
||||
Address(H160::from("0xda2fef9e4a3230988ff17df2165440f37e8b1708")),
|
||||
Address(H160::from("0xf4c64518ea10f995918a454158c6b61407ea345c")),
|
||||
Address(H160::from("0x7602b46df5390e432ef1c307d4f2c9ff6d65cc97")),
|
||||
Address(H160::from("0xbb9bc244d798123fde783fcc1c72d3bb8c189413")),
|
||||
Address(H160::from("0x807640a13483f8ac783c557fcdf27be11ea4ac7a")),
|
||||
]),
|
||||
difficulty_hardfork_transition: Some(Uint(U256::from(0x59d9))),
|
||||
difficulty_hardfork_bound_divisor: Some(Uint(U256::from(0x0200))),
|
||||
bomb_defuse_transition: Some(Uint(U256::from(0x41))),
|
||||
eip100b_transition: Some(Uint(U256::from(0x42))),
|
||||
ecip1010_pause_transition: None,
|
||||
ecip1010_continue_transition: None,
|
||||
ecip1017_era_rounds: None,
|
||||
expip2_transition: None,
|
||||
expip2_duration_limit: None,
|
||||
progpow_transition: None,
|
||||
difficulty_bomb_delays: None,
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ethash_deserialization_missing_optionals() {
|
||||
let s = r#"{
|
||||
#[test]
|
||||
fn ethash_deserialization_missing_optionals() {
|
||||
let s = r#"{
|
||||
"params": {
|
||||
"difficultyBoundDivisor": "0x0800",
|
||||
"minimumDifficulty": "0x020000"
|
||||
}
|
||||
}"#;
|
||||
|
||||
let deserialized: Ethash = serde_json::from_str(s).unwrap();
|
||||
assert_eq!(deserialized, Ethash {
|
||||
params: EthashParams {
|
||||
minimum_difficulty: Uint(U256::from(0x020000)),
|
||||
difficulty_bound_divisor: Uint(U256::from(0x0800)),
|
||||
difficulty_increment_divisor: None,
|
||||
metropolis_difficulty_increment_divisor: None,
|
||||
duration_limit: None,
|
||||
homestead_transition: None,
|
||||
block_reward: None,
|
||||
block_reward_contract_address: None,
|
||||
block_reward_contract_code: None,
|
||||
block_reward_contract_transition: None,
|
||||
dao_hardfork_transition: None,
|
||||
dao_hardfork_beneficiary: None,
|
||||
dao_hardfork_accounts: None,
|
||||
difficulty_hardfork_transition: None,
|
||||
difficulty_hardfork_bound_divisor: None,
|
||||
bomb_defuse_transition: None,
|
||||
eip100b_transition: None,
|
||||
ecip1010_pause_transition: None,
|
||||
ecip1010_continue_transition: None,
|
||||
ecip1017_era_rounds: None,
|
||||
expip2_transition: None,
|
||||
expip2_duration_limit: None,
|
||||
progpow_transition: None,
|
||||
difficulty_bomb_delays: None,
|
||||
}
|
||||
});
|
||||
}
|
||||
let deserialized: Ethash = serde_json::from_str(s).unwrap();
|
||||
assert_eq!(
|
||||
deserialized,
|
||||
Ethash {
|
||||
params: EthashParams {
|
||||
minimum_difficulty: Uint(U256::from(0x020000)),
|
||||
difficulty_bound_divisor: Uint(U256::from(0x0800)),
|
||||
difficulty_increment_divisor: None,
|
||||
metropolis_difficulty_increment_divisor: None,
|
||||
duration_limit: None,
|
||||
homestead_transition: None,
|
||||
block_reward: None,
|
||||
block_reward_contract_address: None,
|
||||
block_reward_contract_code: None,
|
||||
block_reward_contract_transition: None,
|
||||
dao_hardfork_transition: None,
|
||||
dao_hardfork_beneficiary: None,
|
||||
dao_hardfork_accounts: None,
|
||||
difficulty_hardfork_transition: None,
|
||||
difficulty_hardfork_bound_divisor: None,
|
||||
bomb_defuse_transition: None,
|
||||
eip100b_transition: None,
|
||||
ecip1010_pause_transition: None,
|
||||
ecip1010_continue_transition: None,
|
||||
ecip1017_era_rounds: None,
|
||||
expip2_transition: None,
|
||||
expip2_duration_limit: None,
|
||||
progpow_transition: None,
|
||||
difficulty_bomb_delays: None,
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "a non-zero value")]
|
||||
fn test_zero_value_divisor() {
|
||||
let s = r#"{
|
||||
#[test]
|
||||
#[should_panic(expected = "a non-zero value")]
|
||||
fn test_zero_value_divisor() {
|
||||
let s = r#"{
|
||||
"params": {
|
||||
"difficultyBoundDivisor": "0x0",
|
||||
"minimumDifficulty": "0x020000"
|
||||
}
|
||||
}"#;
|
||||
|
||||
let _deserialized: Ethash = serde_json::from_str(s).unwrap();
|
||||
}
|
||||
let _deserialized: Ethash = serde_json::from_str(s).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,55 +16,54 @@
|
||||
|
||||
//! Spec genesis deserialization.
|
||||
|
||||
use uint::{Uint, self};
|
||||
use hash::{Address, H256};
|
||||
use bytes::Bytes;
|
||||
use hash::{Address, H256};
|
||||
use spec::Seal;
|
||||
use uint::{self, Uint};
|
||||
|
||||
/// Spec genesis.
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Genesis {
|
||||
/// Seal.
|
||||
pub seal: Seal,
|
||||
/// Difficulty.
|
||||
pub difficulty: Uint,
|
||||
/// Block author, defaults to 0.
|
||||
pub author: Option<Address>,
|
||||
/// Block timestamp, defaults to 0.
|
||||
pub timestamp: Option<Uint>,
|
||||
/// Parent hash, defaults to 0.
|
||||
pub parent_hash: Option<H256>,
|
||||
/// Gas limit.
|
||||
#[serde(deserialize_with="uint::validate_non_zero")]
|
||||
pub gas_limit: Uint,
|
||||
/// Transactions root.
|
||||
pub transactions_root: Option<H256>,
|
||||
/// Receipts root.
|
||||
pub receipts_root: Option<H256>,
|
||||
/// State root.
|
||||
pub state_root: Option<H256>,
|
||||
/// Gas used.
|
||||
pub gas_used: Option<Uint>,
|
||||
/// Extra data.
|
||||
pub extra_data: Option<Bytes>,
|
||||
/// Seal.
|
||||
pub seal: Seal,
|
||||
/// Difficulty.
|
||||
pub difficulty: Uint,
|
||||
/// Block author, defaults to 0.
|
||||
pub author: Option<Address>,
|
||||
/// Block timestamp, defaults to 0.
|
||||
pub timestamp: Option<Uint>,
|
||||
/// Parent hash, defaults to 0.
|
||||
pub parent_hash: Option<H256>,
|
||||
/// Gas limit.
|
||||
#[serde(deserialize_with = "uint::validate_non_zero")]
|
||||
pub gas_limit: Uint,
|
||||
/// Transactions root.
|
||||
pub transactions_root: Option<H256>,
|
||||
/// Receipts root.
|
||||
pub receipts_root: Option<H256>,
|
||||
/// State root.
|
||||
pub state_root: Option<H256>,
|
||||
/// Gas used.
|
||||
pub gas_used: Option<Uint>,
|
||||
/// Extra data.
|
||||
pub extra_data: Option<Bytes>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use serde_json;
|
||||
use bytes::Bytes;
|
||||
use uint::Uint;
|
||||
use ethereum_types::{U256, H160, H64 as Eth64, H256 as Eth256};
|
||||
use hash::{H64, H256, Address};
|
||||
use spec::genesis::Genesis;
|
||||
use spec::{Ethereum, Seal};
|
||||
use std::str::FromStr;
|
||||
use bytes::Bytes;
|
||||
use ethereum_types::{H160, H256 as Eth256, H64 as Eth64, U256};
|
||||
use hash::{Address, H256, H64};
|
||||
use serde_json;
|
||||
use spec::{genesis::Genesis, Ethereum, Seal};
|
||||
use std::str::FromStr;
|
||||
use uint::Uint;
|
||||
|
||||
#[test]
|
||||
fn genesis_deserialization() {
|
||||
let s = r#"{
|
||||
#[test]
|
||||
fn genesis_deserialization() {
|
||||
let s = r#"{
|
||||
"difficulty": "0x400000000",
|
||||
"seal": {
|
||||
"ethereum": {
|
||||
@@ -79,22 +78,38 @@ mod tests {
|
||||
"gasLimit": "0x1388",
|
||||
"stateRoot": "0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544"
|
||||
}"#;
|
||||
let deserialized: Genesis = serde_json::from_str(s).unwrap();
|
||||
assert_eq!(deserialized, Genesis {
|
||||
seal: Seal::Ethereum(Ethereum {
|
||||
nonce: H64(Eth64::from("0x00006d6f7264656e")),
|
||||
mix_hash: H256(Eth256::from("0x0000000000000000000000000000000000000000000000000000000000000000"))
|
||||
}),
|
||||
difficulty: Uint(U256::from(0x400000000u64)),
|
||||
author: Some(Address(H160::from("0x1000000000000000000000000000000000000001"))),
|
||||
timestamp: Some(Uint(U256::from(0x07))),
|
||||
parent_hash: Some(H256(Eth256::from("0x9000000000000000000000000000000000000000000000000000000000000000"))),
|
||||
gas_limit: Uint(U256::from(0x1388)),
|
||||
transactions_root: None,
|
||||
receipts_root: None,
|
||||
state_root: Some(H256(Eth256::from("0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544"))),
|
||||
gas_used: None,
|
||||
extra_data: Some(Bytes::from_str("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa").unwrap()),
|
||||
});
|
||||
}
|
||||
let deserialized: Genesis = serde_json::from_str(s).unwrap();
|
||||
assert_eq!(
|
||||
deserialized,
|
||||
Genesis {
|
||||
seal: Seal::Ethereum(Ethereum {
|
||||
nonce: H64(Eth64::from("0x00006d6f7264656e")),
|
||||
mix_hash: H256(Eth256::from(
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||
))
|
||||
}),
|
||||
difficulty: Uint(U256::from(0x400000000u64)),
|
||||
author: Some(Address(H160::from(
|
||||
"0x1000000000000000000000000000000000000001"
|
||||
))),
|
||||
timestamp: Some(Uint(U256::from(0x07))),
|
||||
parent_hash: Some(H256(Eth256::from(
|
||||
"0x9000000000000000000000000000000000000000000000000000000000000000"
|
||||
))),
|
||||
gas_limit: Uint(U256::from(0x1388)),
|
||||
transactions_root: None,
|
||||
receipts_root: None,
|
||||
state_root: Some(H256(Eth256::from(
|
||||
"0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544"
|
||||
))),
|
||||
gas_used: None,
|
||||
extra_data: Some(
|
||||
Bytes::from_str(
|
||||
"0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa"
|
||||
)
|
||||
.unwrap()
|
||||
),
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,26 +24,26 @@ use uint::Uint;
|
||||
#[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.
|
||||
pub header: String,
|
||||
/// Total difficulty including the block of `header`.
|
||||
pub total_difficulty: Uint,
|
||||
/// Ordered trie roots of blocks before and including `header`.
|
||||
#[serde(rename = "CHTs")]
|
||||
pub chts: Vec<H256>,
|
||||
/// Hexadecimal of the RLP encoding of the header of the block to start synchronization from.
|
||||
pub header: String,
|
||||
/// Total difficulty including the block of `header`.
|
||||
pub total_difficulty: Uint,
|
||||
/// Ordered trie roots of blocks before and including `header`.
|
||||
#[serde(rename = "CHTs")]
|
||||
pub chts: Vec<H256>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use serde_json;
|
||||
use uint::Uint;
|
||||
use ethereum_types::{U256, H256 as Eth256};
|
||||
use hash::H256;
|
||||
use spec::hardcoded_sync::HardcodedSync;
|
||||
use ethereum_types::{H256 as Eth256, U256};
|
||||
use hash::H256;
|
||||
use serde_json;
|
||||
use spec::hardcoded_sync::HardcodedSync;
|
||||
use uint::Uint;
|
||||
|
||||
#[test]
|
||||
fn hardcoded_sync_deserialization() {
|
||||
let s = r#"{
|
||||
#[test]
|
||||
fn hardcoded_sync_deserialization() {
|
||||
let s = r#"{
|
||||
"header": "f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23",
|
||||
"totalDifficulty": "0x400000000",
|
||||
"CHTs": [
|
||||
@@ -51,8 +51,8 @@ mod tests {
|
||||
"0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544"
|
||||
]
|
||||
}"#;
|
||||
let deserialized: HardcodedSync = serde_json::from_str(s).unwrap();
|
||||
assert_eq!(deserialized, HardcodedSync {
|
||||
let deserialized: HardcodedSync = serde_json::from_str(s).unwrap();
|
||||
assert_eq!(deserialized, HardcodedSync {
|
||||
header: String::from("f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23"),
|
||||
total_difficulty: Uint(U256::from(0x400000000u64)),
|
||||
chts: vec![
|
||||
@@ -60,5 +60,5 @@ mod tests {
|
||||
H256(Eth256::from("0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544")),
|
||||
]
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,15 +21,15 @@
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct InstantSealParams {
|
||||
/// Whether to enable millisecond timestamp.
|
||||
#[serde(default)]
|
||||
pub millisecond_timestamp: bool,
|
||||
/// Whether to enable millisecond timestamp.
|
||||
#[serde(default)]
|
||||
pub millisecond_timestamp: bool,
|
||||
}
|
||||
|
||||
/// Instant seal engine descriptor.
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct InstantSeal {
|
||||
/// Instant seal parameters.
|
||||
pub params: InstantSealParams,
|
||||
/// Instant seal parameters.
|
||||
pub params: InstantSealParams,
|
||||
}
|
||||
|
||||
@@ -17,35 +17,37 @@
|
||||
//! Spec deserialization.
|
||||
|
||||
pub mod account;
|
||||
pub mod builtin;
|
||||
pub mod genesis;
|
||||
pub mod params;
|
||||
pub mod spec;
|
||||
pub mod seal;
|
||||
pub mod engine;
|
||||
pub mod state;
|
||||
pub mod ethash;
|
||||
pub mod validator_set;
|
||||
pub mod basic_authority;
|
||||
pub mod authority_round;
|
||||
pub mod null_engine;
|
||||
pub mod instant_seal;
|
||||
pub mod hardcoded_sync;
|
||||
pub mod basic_authority;
|
||||
pub mod builtin;
|
||||
pub mod clique;
|
||||
pub mod engine;
|
||||
pub mod ethash;
|
||||
pub mod genesis;
|
||||
pub mod hardcoded_sync;
|
||||
pub mod instant_seal;
|
||||
pub mod null_engine;
|
||||
pub mod params;
|
||||
pub mod seal;
|
||||
pub mod spec;
|
||||
pub mod state;
|
||||
pub mod validator_set;
|
||||
|
||||
pub use self::account::Account;
|
||||
pub use self::builtin::{Builtin, Pricing, Linear};
|
||||
pub use self::genesis::Genesis;
|
||||
pub use self::params::Params;
|
||||
pub use self::spec::{Spec, ForkSpec};
|
||||
pub use self::seal::{Seal, Ethereum, AuthorityRoundSeal, TendermintSeal};
|
||||
pub use self::engine::Engine;
|
||||
pub use self::state::State;
|
||||
pub use self::ethash::{Ethash, EthashParams, BlockReward};
|
||||
pub use self::validator_set::ValidatorSet;
|
||||
pub use self::basic_authority::{BasicAuthority, BasicAuthorityParams};
|
||||
pub use self::authority_round::{AuthorityRound, AuthorityRoundParams};
|
||||
pub use self::clique::{Clique, CliqueParams};
|
||||
pub use self::null_engine::{NullEngine, NullEngineParams};
|
||||
pub use self::instant_seal::{InstantSeal, InstantSealParams};
|
||||
pub use self::hardcoded_sync::HardcodedSync;
|
||||
pub use self::{
|
||||
account::Account,
|
||||
authority_round::{AuthorityRound, AuthorityRoundParams},
|
||||
basic_authority::{BasicAuthority, BasicAuthorityParams},
|
||||
builtin::{Builtin, Linear, Pricing},
|
||||
clique::{Clique, CliqueParams},
|
||||
engine::Engine,
|
||||
ethash::{BlockReward, Ethash, EthashParams},
|
||||
genesis::Genesis,
|
||||
hardcoded_sync::HardcodedSync,
|
||||
instant_seal::{InstantSeal, InstantSealParams},
|
||||
null_engine::{NullEngine, NullEngineParams},
|
||||
params::Params,
|
||||
seal::{AuthorityRoundSeal, Ethereum, Seal, TendermintSeal},
|
||||
spec::{ForkSpec, Spec},
|
||||
state::State,
|
||||
validator_set::ValidatorSet,
|
||||
};
|
||||
|
||||
@@ -23,36 +23,39 @@ use uint::Uint;
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct NullEngineParams {
|
||||
/// Block reward.
|
||||
pub block_reward: Option<Uint>,
|
||||
/// Immediate finalization.
|
||||
pub immediate_finalization: Option<bool>
|
||||
/// Block reward.
|
||||
pub block_reward: Option<Uint>,
|
||||
/// Immediate finalization.
|
||||
pub immediate_finalization: Option<bool>,
|
||||
}
|
||||
|
||||
/// Null engine descriptor
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct NullEngine {
|
||||
/// Ethash params.
|
||||
pub params: NullEngineParams,
|
||||
/// Ethash params.
|
||||
pub params: NullEngineParams,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use serde_json;
|
||||
use uint::Uint;
|
||||
use ethereum_types::U256;
|
||||
use super::*;
|
||||
use super::*;
|
||||
use ethereum_types::U256;
|
||||
use serde_json;
|
||||
use uint::Uint;
|
||||
|
||||
#[test]
|
||||
fn null_engine_deserialization() {
|
||||
let s = r#"{
|
||||
#[test]
|
||||
fn null_engine_deserialization() {
|
||||
let s = r#"{
|
||||
"params": {
|
||||
"blockReward": "0x0d"
|
||||
}
|
||||
}"#;
|
||||
|
||||
let deserialized: NullEngine = serde_json::from_str(s).unwrap();
|
||||
assert_eq!(deserialized.params.block_reward, Some(Uint(U256::from(0x0d))));
|
||||
}
|
||||
let deserialized: NullEngine = serde_json::from_str(s).unwrap();
|
||||
assert_eq!(
|
||||
deserialized.params.block_reward,
|
||||
Some(Uint(U256::from(0x0d)))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,136 +16,136 @@
|
||||
|
||||
//! Spec params deserialization.
|
||||
|
||||
use uint::{self, Uint};
|
||||
use hash::{H256, Address};
|
||||
use bytes::Bytes;
|
||||
use hash::{Address, H256};
|
||||
use uint::{self, Uint};
|
||||
|
||||
/// Spec params.
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Params {
|
||||
/// Account start nonce, defaults to 0.
|
||||
pub account_start_nonce: Option<Uint>,
|
||||
/// Maximum size of extra data.
|
||||
pub maximum_extra_data_size: Uint,
|
||||
/// Minimum gas limit.
|
||||
pub min_gas_limit: Uint,
|
||||
/// Account start nonce, defaults to 0.
|
||||
pub account_start_nonce: Option<Uint>,
|
||||
/// Maximum size of extra data.
|
||||
pub maximum_extra_data_size: Uint,
|
||||
/// Minimum gas limit.
|
||||
pub min_gas_limit: Uint,
|
||||
|
||||
/// Network id.
|
||||
#[serde(rename = "networkID")]
|
||||
pub network_id: Uint,
|
||||
/// Chain id.
|
||||
#[serde(rename = "chainID")]
|
||||
pub chain_id: Option<Uint>,
|
||||
/// Network id.
|
||||
#[serde(rename = "networkID")]
|
||||
pub network_id: Uint,
|
||||
/// Chain id.
|
||||
#[serde(rename = "chainID")]
|
||||
pub chain_id: Option<Uint>,
|
||||
|
||||
/// Name of the main ("eth") subprotocol.
|
||||
pub subprotocol_name: Option<String>,
|
||||
/// Name of the main ("eth") subprotocol.
|
||||
pub subprotocol_name: Option<String>,
|
||||
|
||||
/// Option fork block number to check.
|
||||
pub fork_block: Option<Uint>,
|
||||
/// Expected fork block hash.
|
||||
#[serde(rename = "forkCanonHash")]
|
||||
pub fork_hash: Option<H256>,
|
||||
/// Option fork block number to check.
|
||||
pub fork_block: Option<Uint>,
|
||||
/// Expected fork block hash.
|
||||
#[serde(rename = "forkCanonHash")]
|
||||
pub fork_hash: Option<H256>,
|
||||
|
||||
/// See main EthashParams docs.
|
||||
pub eip150_transition: Option<Uint>,
|
||||
/// See main EthashParams docs.
|
||||
pub eip150_transition: Option<Uint>,
|
||||
|
||||
/// See main EthashParams docs.
|
||||
pub eip160_transition: Option<Uint>,
|
||||
/// See main EthashParams docs.
|
||||
pub eip160_transition: Option<Uint>,
|
||||
|
||||
/// See main EthashParams docs.
|
||||
pub eip161abc_transition: Option<Uint>,
|
||||
/// See main EthashParams docs.
|
||||
pub eip161d_transition: Option<Uint>,
|
||||
/// See main EthashParams docs.
|
||||
pub eip161abc_transition: Option<Uint>,
|
||||
/// See main EthashParams docs.
|
||||
pub eip161d_transition: Option<Uint>,
|
||||
|
||||
/// See `CommonParams` docs.
|
||||
pub eip98_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip155_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub validate_chain_id_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub validate_receipts_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip140_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip210_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip210_contract_address: Option<Address>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip210_contract_code: Option<Bytes>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip210_contract_gas: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip211_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip145_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip214_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip658_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip1052_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip1283_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip1283_disable_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip1283_reenable_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip1014_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip1706_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip1344_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip1884_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip2028_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub dust_protection_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub nonce_cap_increment: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub remove_dust_contracts : Option<bool>,
|
||||
/// See `CommonParams` docs.
|
||||
#[serde(deserialize_with="uint::validate_non_zero")]
|
||||
pub gas_limit_bound_divisor: Uint,
|
||||
/// See `CommonParams` docs.
|
||||
pub registrar: Option<Address>,
|
||||
/// Apply reward flag
|
||||
pub apply_reward: Option<bool>,
|
||||
/// Node permission contract address.
|
||||
pub node_permission_contract: Option<Address>,
|
||||
/// See main EthashParams docs.
|
||||
pub max_code_size: Option<Uint>,
|
||||
/// Maximum size of transaction RLP payload.
|
||||
pub max_transaction_size: Option<Uint>,
|
||||
/// See main EthashParams docs.
|
||||
pub max_code_size_transition: Option<Uint>,
|
||||
/// Transaction permission contract address.
|
||||
pub transaction_permission_contract: Option<Address>,
|
||||
/// Block at which the transaction permission contract should start being used.
|
||||
pub transaction_permission_contract_transition: Option<Uint>,
|
||||
/// Wasm activation block height, if not activated from start
|
||||
pub wasm_activation_transition: Option<Uint>,
|
||||
/// KIP4 activiation block height.
|
||||
pub kip4_transition: Option<Uint>,
|
||||
/// KIP6 activiation block height.
|
||||
pub kip6_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip98_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip155_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub validate_chain_id_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub validate_receipts_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip140_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip210_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip210_contract_address: Option<Address>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip210_contract_code: Option<Bytes>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip210_contract_gas: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip211_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip145_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip214_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip658_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip1052_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip1283_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip1283_disable_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip1283_reenable_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip1014_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip1706_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip1344_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip1884_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub eip2028_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub dust_protection_transition: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub nonce_cap_increment: Option<Uint>,
|
||||
/// See `CommonParams` docs.
|
||||
pub remove_dust_contracts: Option<bool>,
|
||||
/// See `CommonParams` docs.
|
||||
#[serde(deserialize_with = "uint::validate_non_zero")]
|
||||
pub gas_limit_bound_divisor: Uint,
|
||||
/// See `CommonParams` docs.
|
||||
pub registrar: Option<Address>,
|
||||
/// Apply reward flag
|
||||
pub apply_reward: Option<bool>,
|
||||
/// Node permission contract address.
|
||||
pub node_permission_contract: Option<Address>,
|
||||
/// See main EthashParams docs.
|
||||
pub max_code_size: Option<Uint>,
|
||||
/// Maximum size of transaction RLP payload.
|
||||
pub max_transaction_size: Option<Uint>,
|
||||
/// See main EthashParams docs.
|
||||
pub max_code_size_transition: Option<Uint>,
|
||||
/// Transaction permission contract address.
|
||||
pub transaction_permission_contract: Option<Address>,
|
||||
/// Block at which the transaction permission contract should start being used.
|
||||
pub transaction_permission_contract_transition: Option<Uint>,
|
||||
/// Wasm activation block height, if not activated from start
|
||||
pub wasm_activation_transition: Option<Uint>,
|
||||
/// KIP4 activiation block height.
|
||||
pub kip4_transition: Option<Uint>,
|
||||
/// KIP6 activiation block height.
|
||||
pub kip6_transition: Option<Uint>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use serde_json;
|
||||
use uint::Uint;
|
||||
use ethereum_types::U256;
|
||||
use spec::params::Params;
|
||||
use ethereum_types::U256;
|
||||
use serde_json;
|
||||
use spec::params::Params;
|
||||
use uint::Uint;
|
||||
|
||||
#[test]
|
||||
fn params_deserialization() {
|
||||
let s = r#"{
|
||||
#[test]
|
||||
fn params_deserialization() {
|
||||
let s = r#"{
|
||||
"maximumExtraDataSize": "0x20",
|
||||
"networkID" : "0x1",
|
||||
"chainID" : "0x15",
|
||||
@@ -157,22 +157,28 @@ mod tests {
|
||||
"wasmActivationTransition": "0x1010"
|
||||
}"#;
|
||||
|
||||
let deserialized: Params = serde_json::from_str(s).unwrap();
|
||||
assert_eq!(deserialized.maximum_extra_data_size, Uint(U256::from(0x20)));
|
||||
assert_eq!(deserialized.network_id, Uint(U256::from(0x1)));
|
||||
assert_eq!(deserialized.chain_id, Some(Uint(U256::from(0x15))));
|
||||
assert_eq!(deserialized.subprotocol_name, Some("exp".to_owned()));
|
||||
assert_eq!(deserialized.min_gas_limit, Uint(U256::from(0x1388)));
|
||||
assert_eq!(deserialized.account_start_nonce, Some(Uint(U256::from(0x01))));
|
||||
assert_eq!(deserialized.gas_limit_bound_divisor, Uint(U256::from(0x20)));
|
||||
assert_eq!(deserialized.max_code_size, Some(Uint(U256::from(0x1000))));
|
||||
assert_eq!(deserialized.wasm_activation_transition, Some(Uint(U256::from(0x1010))));
|
||||
}
|
||||
let deserialized: Params = serde_json::from_str(s).unwrap();
|
||||
assert_eq!(deserialized.maximum_extra_data_size, Uint(U256::from(0x20)));
|
||||
assert_eq!(deserialized.network_id, Uint(U256::from(0x1)));
|
||||
assert_eq!(deserialized.chain_id, Some(Uint(U256::from(0x15))));
|
||||
assert_eq!(deserialized.subprotocol_name, Some("exp".to_owned()));
|
||||
assert_eq!(deserialized.min_gas_limit, Uint(U256::from(0x1388)));
|
||||
assert_eq!(
|
||||
deserialized.account_start_nonce,
|
||||
Some(Uint(U256::from(0x01)))
|
||||
);
|
||||
assert_eq!(deserialized.gas_limit_bound_divisor, Uint(U256::from(0x20)));
|
||||
assert_eq!(deserialized.max_code_size, Some(Uint(U256::from(0x1000))));
|
||||
assert_eq!(
|
||||
deserialized.wasm_activation_transition,
|
||||
Some(Uint(U256::from(0x1010)))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "a non-zero value")]
|
||||
fn test_zero_value_divisor() {
|
||||
let s = r#"{
|
||||
#[test]
|
||||
#[should_panic(expected = "a non-zero value")]
|
||||
fn test_zero_value_divisor() {
|
||||
let s = r#"{
|
||||
"maximumExtraDataSize": "0x20",
|
||||
"networkID" : "0x1",
|
||||
"chainID" : "0x15",
|
||||
@@ -183,6 +189,6 @@ mod tests {
|
||||
"maxCodeSize": "0x1000"
|
||||
}"#;
|
||||
|
||||
let _deserialized: Params = serde_json::from_str(s).unwrap();
|
||||
}
|
||||
let _deserialized: Params = serde_json::from_str(s).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,41 +16,41 @@
|
||||
|
||||
//! Spec seal deserialization.
|
||||
|
||||
use bytes::Bytes;
|
||||
use hash::*;
|
||||
use uint::Uint;
|
||||
use bytes::Bytes;
|
||||
|
||||
/// Ethereum seal.
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Ethereum {
|
||||
/// Seal nonce.
|
||||
pub nonce: H64,
|
||||
/// Seal mix hash.
|
||||
pub mix_hash: H256,
|
||||
/// Seal nonce.
|
||||
pub nonce: H64,
|
||||
/// Seal mix hash.
|
||||
pub mix_hash: H256,
|
||||
}
|
||||
|
||||
/// AuthorityRound seal.
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct AuthorityRoundSeal {
|
||||
/// Seal step.
|
||||
pub step: Uint,
|
||||
/// Seal signature.
|
||||
pub signature: H520,
|
||||
/// Seal step.
|
||||
pub step: Uint,
|
||||
/// Seal signature.
|
||||
pub signature: H520,
|
||||
}
|
||||
|
||||
/// Tendermint seal.
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct TendermintSeal {
|
||||
/// Seal round.
|
||||
pub round: Uint,
|
||||
/// Proposal seal signature.
|
||||
pub proposal: H520,
|
||||
/// Proposal seal signature.
|
||||
pub precommits: Vec<H520>,
|
||||
/// Seal round.
|
||||
pub round: Uint,
|
||||
/// Proposal seal signature.
|
||||
pub proposal: H520,
|
||||
/// Proposal seal signature.
|
||||
pub precommits: Vec<H520>,
|
||||
}
|
||||
|
||||
/// Seal variants.
|
||||
@@ -58,28 +58,28 @@ pub struct TendermintSeal {
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum Seal {
|
||||
/// Ethereum seal.
|
||||
Ethereum(Ethereum),
|
||||
/// AuthorityRound seal.
|
||||
AuthorityRound(AuthorityRoundSeal),
|
||||
/// Tendermint seal.
|
||||
Tendermint(TendermintSeal),
|
||||
/// Generic seal.
|
||||
Generic(Bytes),
|
||||
/// Ethereum seal.
|
||||
Ethereum(Ethereum),
|
||||
/// AuthorityRound seal.
|
||||
AuthorityRound(AuthorityRoundSeal),
|
||||
/// Tendermint seal.
|
||||
Tendermint(TendermintSeal),
|
||||
/// Generic seal.
|
||||
Generic(Bytes),
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use serde_json;
|
||||
use hash::*;
|
||||
use bytes::Bytes;
|
||||
use uint::Uint;
|
||||
use ethereum_types::{U256, H64 as Eth64, H256 as Eth256, H520 as Eth520};
|
||||
use spec::{Ethereum, AuthorityRoundSeal, TendermintSeal, Seal};
|
||||
use bytes::Bytes;
|
||||
use ethereum_types::{H256 as Eth256, H520 as Eth520, H64 as Eth64, U256};
|
||||
use hash::*;
|
||||
use serde_json;
|
||||
use spec::{AuthorityRoundSeal, Ethereum, Seal, TendermintSeal};
|
||||
use uint::Uint;
|
||||
|
||||
#[test]
|
||||
fn seal_deserialization() {
|
||||
let s = r#"[{
|
||||
#[test]
|
||||
fn seal_deserialization() {
|
||||
let s = r#"[{
|
||||
"ethereum": {
|
||||
"nonce": "0x0000000000000042",
|
||||
"mixHash": "0x1000000000000000000000000000000000000000000000000000000000000001"
|
||||
@@ -101,31 +101,41 @@ mod tests {
|
||||
}
|
||||
}]"#;
|
||||
|
||||
let deserialized: Vec<Seal> = serde_json::from_str(s).unwrap();
|
||||
assert_eq!(deserialized.len(), 4);
|
||||
let deserialized: Vec<Seal> = serde_json::from_str(s).unwrap();
|
||||
assert_eq!(deserialized.len(), 4);
|
||||
|
||||
// [0]
|
||||
assert_eq!(deserialized[0], Seal::Ethereum(Ethereum {
|
||||
nonce: H64(Eth64::from("0x0000000000000042")),
|
||||
mix_hash: H256(Eth256::from("0x1000000000000000000000000000000000000000000000000000000000000001"))
|
||||
}));
|
||||
// [0]
|
||||
assert_eq!(
|
||||
deserialized[0],
|
||||
Seal::Ethereum(Ethereum {
|
||||
nonce: H64(Eth64::from("0x0000000000000042")),
|
||||
mix_hash: H256(Eth256::from(
|
||||
"0x1000000000000000000000000000000000000000000000000000000000000001"
|
||||
))
|
||||
})
|
||||
);
|
||||
|
||||
// [1]
|
||||
assert_eq!(deserialized[1], Seal::Generic(Bytes::new(vec![
|
||||
0xe0, 0x11, 0xbb, 0xe8, 0xdb, 0x4e, 0x34, 0x7b, 0x4e, 0x8c, 0x93, 0x7c, 0x1c, 0x83, 0x70, 0xe4,
|
||||
0xb5, 0xed, 0x33, 0xad, 0xb3, 0xdb, 0x69, 0xcb, 0xdb, 0x7a, 0x38, 0xe1, 0xe5, 0x0b, 0x1b, 0x82, 0xfa])));
|
||||
// [1]
|
||||
assert_eq!(
|
||||
deserialized[1],
|
||||
Seal::Generic(Bytes::new(vec![
|
||||
0xe0, 0x11, 0xbb, 0xe8, 0xdb, 0x4e, 0x34, 0x7b, 0x4e, 0x8c, 0x93, 0x7c, 0x1c, 0x83,
|
||||
0x70, 0xe4, 0xb5, 0xed, 0x33, 0xad, 0xb3, 0xdb, 0x69, 0xcb, 0xdb, 0x7a, 0x38, 0xe1,
|
||||
0xe5, 0x0b, 0x1b, 0x82, 0xfa
|
||||
]))
|
||||
);
|
||||
|
||||
// [2]
|
||||
assert_eq!(deserialized[2], Seal::AuthorityRound(AuthorityRoundSeal {
|
||||
// [2]
|
||||
assert_eq!(deserialized[2], Seal::AuthorityRound(AuthorityRoundSeal {
|
||||
step: Uint(U256::from(0x0)),
|
||||
signature: H520(Eth520::from("0x2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002"))
|
||||
}));
|
||||
|
||||
// [3]
|
||||
assert_eq!(deserialized[3], Seal::Tendermint(TendermintSeal {
|
||||
// [3]
|
||||
assert_eq!(deserialized[3], Seal::Tendermint(TendermintSeal {
|
||||
round: Uint(U256::from(0x3)),
|
||||
proposal: H520(Eth520::from("0x3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003")),
|
||||
precommits: vec![H520(Eth520::from("0x4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004"))]
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,26 +16,25 @@
|
||||
|
||||
//! Spec deserialization.
|
||||
|
||||
use serde_json::{self, Error};
|
||||
use spec::{Engine, Genesis, HardcodedSync, Params, State};
|
||||
use std::io::Read;
|
||||
use serde_json;
|
||||
use serde_json::Error;
|
||||
use spec::{Params, Genesis, Engine, State, HardcodedSync};
|
||||
|
||||
/// Fork spec definition
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Deserialize)]
|
||||
pub enum ForkSpec {
|
||||
EIP150,
|
||||
EIP158,
|
||||
Frontier,
|
||||
Homestead,
|
||||
Byzantium,
|
||||
Constantinople,
|
||||
ConstantinopleFix,
|
||||
Istanbul,
|
||||
EIP158ToByzantiumAt5,
|
||||
FrontierToHomesteadAt5,
|
||||
HomesteadToDaoAt5,
|
||||
HomesteadToEIP150At5,
|
||||
EIP150,
|
||||
EIP158,
|
||||
Frontier,
|
||||
Homestead,
|
||||
Byzantium,
|
||||
Constantinople,
|
||||
ConstantinopleFix,
|
||||
Istanbul,
|
||||
EIP158ToByzantiumAt5,
|
||||
FrontierToHomesteadAt5,
|
||||
HomesteadToDaoAt5,
|
||||
HomesteadToEIP150At5,
|
||||
}
|
||||
|
||||
/// Spec deserialization.
|
||||
@@ -43,39 +42,42 @@ pub enum ForkSpec {
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Spec {
|
||||
/// Spec name.
|
||||
pub name: String,
|
||||
/// Special fork name.
|
||||
pub data_dir: Option<String>,
|
||||
/// Engine.
|
||||
pub engine: Engine,
|
||||
/// Spec params.
|
||||
pub params: Params,
|
||||
/// Genesis header.
|
||||
pub genesis: Genesis,
|
||||
/// Genesis state.
|
||||
pub accounts: State,
|
||||
/// Boot nodes.
|
||||
pub nodes: Option<Vec<String>>,
|
||||
/// Hardcoded synchronization for the light client.
|
||||
pub hardcoded_sync: Option<HardcodedSync>,
|
||||
/// Spec name.
|
||||
pub name: String,
|
||||
/// Special fork name.
|
||||
pub data_dir: Option<String>,
|
||||
/// Engine.
|
||||
pub engine: Engine,
|
||||
/// Spec params.
|
||||
pub params: Params,
|
||||
/// Genesis header.
|
||||
pub genesis: Genesis,
|
||||
/// Genesis state.
|
||||
pub accounts: State,
|
||||
/// Boot nodes.
|
||||
pub nodes: Option<Vec<String>>,
|
||||
/// Hardcoded synchronization for the light client.
|
||||
pub hardcoded_sync: Option<HardcodedSync>,
|
||||
}
|
||||
|
||||
impl Spec {
|
||||
/// Loads test from json.
|
||||
pub fn load<R>(reader: R) -> Result<Self, Error> where R: Read {
|
||||
serde_json::from_reader(reader)
|
||||
}
|
||||
/// Loads test from json.
|
||||
pub fn load<R>(reader: R) -> Result<Self, Error>
|
||||
where
|
||||
R: Read,
|
||||
{
|
||||
serde_json::from_reader(reader)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use serde_json;
|
||||
use spec::spec::Spec;
|
||||
use serde_json;
|
||||
use spec::spec::Spec;
|
||||
|
||||
#[test]
|
||||
fn should_error_on_unknown_fields() {
|
||||
let s = r#"{
|
||||
#[test]
|
||||
fn should_error_on_unknown_fields() {
|
||||
let s = r#"{
|
||||
"name": "Morden",
|
||||
"dataDir": "morden",
|
||||
"engine": {
|
||||
@@ -134,13 +136,13 @@ mod tests {
|
||||
]
|
||||
}
|
||||
}"#;
|
||||
let result: Result<Spec, _> = serde_json::from_str(s);
|
||||
assert!(result.is_err());
|
||||
}
|
||||
let result: Result<Spec, _> = serde_json::from_str(s);
|
||||
assert!(result.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn spec_deserialization() {
|
||||
let s = r#"{
|
||||
#[test]
|
||||
fn spec_deserialization() {
|
||||
let s = r#"{
|
||||
"name": "Morden",
|
||||
"dataDir": "morden",
|
||||
"engine": {
|
||||
@@ -246,7 +248,7 @@ mod tests {
|
||||
]
|
||||
}
|
||||
}"#;
|
||||
let _deserialized: Spec = serde_json::from_str(s).unwrap();
|
||||
// TODO: validate all fields
|
||||
}
|
||||
let _deserialized: Spec = serde_json::from_str(s).unwrap();
|
||||
// TODO: validate all fields
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
|
||||
//! Blockchain test state deserializer.
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use hash::Address;
|
||||
use bytes::Bytes;
|
||||
use hash::Address;
|
||||
use spec::{Account, Builtin};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
/// Blockchain test state deserializer.
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
@@ -27,28 +27,28 @@ use spec::{Account, Builtin};
|
||||
pub struct State(BTreeMap<Address, Account>);
|
||||
|
||||
impl State {
|
||||
/// Returns all builtins.
|
||||
pub fn builtins(&self) -> BTreeMap<Address, Builtin> {
|
||||
self.0
|
||||
.iter()
|
||||
.filter_map(|(add, ref acc)| acc.builtin.clone().map(|b| (add.clone(), b.into())))
|
||||
.collect()
|
||||
}
|
||||
/// Returns all builtins.
|
||||
pub fn builtins(&self) -> BTreeMap<Address, Builtin> {
|
||||
self.0
|
||||
.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> {
|
||||
self.0
|
||||
.iter()
|
||||
.filter_map(|(add, ref acc)| acc.constructor.clone().map(|b| (add.clone(), b)))
|
||||
.collect()
|
||||
}
|
||||
/// Returns all constructors.
|
||||
pub fn constructors(&self) -> BTreeMap<Address, Bytes> {
|
||||
self.0
|
||||
.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;
|
||||
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()
|
||||
}
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.0.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,36 +16,36 @@
|
||||
|
||||
//! Validator set deserialization.
|
||||
|
||||
use hash::Address;
|
||||
use std::collections::BTreeMap;
|
||||
use uint::Uint;
|
||||
use hash::Address;
|
||||
|
||||
/// Different ways of specifying validators.
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum ValidatorSet {
|
||||
/// A simple list of authorities.
|
||||
List(Vec<Address>),
|
||||
/// Address of a contract that indicates the list of authorities.
|
||||
SafeContract(Address),
|
||||
/// Address of a contract that indicates the list of authorities and enables reporting of theor misbehaviour using transactions.
|
||||
Contract(Address),
|
||||
/// A map of starting blocks for each validator set.
|
||||
Multi(BTreeMap<Uint, ValidatorSet>),
|
||||
/// A simple list of authorities.
|
||||
List(Vec<Address>),
|
||||
/// Address of a contract that indicates the list of authorities.
|
||||
SafeContract(Address),
|
||||
/// Address of a contract that indicates the list of authorities and enables reporting of theor misbehaviour using transactions.
|
||||
Contract(Address),
|
||||
/// A map of starting blocks for each validator set.
|
||||
Multi(BTreeMap<Uint, ValidatorSet>),
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use serde_json;
|
||||
use uint::Uint;
|
||||
use ethereum_types::{H160, U256};
|
||||
use hash::Address;
|
||||
use spec::validator_set::ValidatorSet;
|
||||
use ethereum_types::{H160, U256};
|
||||
use hash::Address;
|
||||
use serde_json;
|
||||
use spec::validator_set::ValidatorSet;
|
||||
use uint::Uint;
|
||||
|
||||
#[test]
|
||||
fn validator_set_deserialization() {
|
||||
let s = r#"[{
|
||||
#[test]
|
||||
fn validator_set_deserialization() {
|
||||
let s = r#"[{
|
||||
"list": ["0xc6d9d2cd449a754c494264e1809c50e34d64562b"]
|
||||
}, {
|
||||
"safeContract": "0xc6d9d2cd449a754c494264e1809c50e34d64562b"
|
||||
@@ -59,20 +59,35 @@ mod tests {
|
||||
}
|
||||
}]"#;
|
||||
|
||||
let deserialized: Vec<ValidatorSet> = serde_json::from_str(s).unwrap();
|
||||
assert_eq!(deserialized.len(), 4);
|
||||
let deserialized: Vec<ValidatorSet> = serde_json::from_str(s).unwrap();
|
||||
assert_eq!(deserialized.len(), 4);
|
||||
|
||||
assert_eq!(deserialized[0], ValidatorSet::List(vec![Address(H160::from("0xc6d9d2cd449a754c494264e1809c50e34d64562b"))]));
|
||||
assert_eq!(deserialized[1], ValidatorSet::SafeContract(Address(H160::from("0xc6d9d2cd449a754c494264e1809c50e34d64562b"))));
|
||||
assert_eq!(deserialized[2], ValidatorSet::Contract(Address(H160::from("0xc6d9d2cd449a754c494264e1809c50e34d64562b"))));
|
||||
match deserialized[3] {
|
||||
ValidatorSet::Multi(ref map) => {
|
||||
assert_eq!(map.len(), 3);
|
||||
assert!(map.contains_key(&Uint(U256::from(0))));
|
||||
assert!(map.contains_key(&Uint(U256::from(10))));
|
||||
assert!(map.contains_key(&Uint(U256::from(20))));
|
||||
},
|
||||
_ => assert!(false),
|
||||
}
|
||||
}
|
||||
assert_eq!(
|
||||
deserialized[0],
|
||||
ValidatorSet::List(vec![Address(H160::from(
|
||||
"0xc6d9d2cd449a754c494264e1809c50e34d64562b"
|
||||
))])
|
||||
);
|
||||
assert_eq!(
|
||||
deserialized[1],
|
||||
ValidatorSet::SafeContract(Address(H160::from(
|
||||
"0xc6d9d2cd449a754c494264e1809c50e34d64562b"
|
||||
)))
|
||||
);
|
||||
assert_eq!(
|
||||
deserialized[2],
|
||||
ValidatorSet::Contract(Address(H160::from(
|
||||
"0xc6d9d2cd449a754c494264e1809c50e34d64562b"
|
||||
)))
|
||||
);
|
||||
match deserialized[3] {
|
||||
ValidatorSet::Multi(ref map) => {
|
||||
assert_eq!(map.len(), 3);
|
||||
assert!(map.contains_key(&Uint(U256::from(0))));
|
||||
assert!(map.contains_key(&Uint(U256::from(10))));
|
||||
assert!(map.contains_key(&Uint(U256::from(20))));
|
||||
}
|
||||
_ => assert!(false),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user