spec loading cleanup (#858)
* spec loading cleanup in progress * changed engine field in json spec * refactored engine params * polishing spec loading refactor * fixed compiling json tests * fixed compiling parity * removed warnings * removed commented out code * fixed failing test * bringing back removed TODO in spec.
This commit is contained in:
@@ -21,7 +21,7 @@ use hash::H256;
|
||||
use blockchain::state::State;
|
||||
use blockchain::header::Header;
|
||||
use blockchain::block::Block;
|
||||
use spec::Genesis;
|
||||
use spec::{Genesis, Seal, Ethereum};
|
||||
|
||||
/// Blockchain deserialization.
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
@@ -54,10 +54,10 @@ impl BlockChain {
|
||||
/// Returns spec compatible genesis struct.
|
||||
pub fn genesis(&self) -> Genesis {
|
||||
Genesis {
|
||||
nonce: Some(self.genesis_block.nonce.clone()),
|
||||
mix_hash: Some(self.genesis_block.mix_hash.clone()),
|
||||
seal_fields: None,
|
||||
seal_rlp: None,
|
||||
seal: Seal::Ethereum(Ethereum {
|
||||
nonce: self.genesis_block.nonce.clone(),
|
||||
mix_hash: self.genesis_block.mix_hash.clone(),
|
||||
}),
|
||||
difficulty: self.genesis_block.difficulty,
|
||||
author: self.genesis_block.author.clone(),
|
||||
timestamp: self.genesis_block.timestamp,
|
||||
|
||||
@@ -22,7 +22,7 @@ use blockchain::account::Account;
|
||||
|
||||
/// Blockchain test state deserializer.
|
||||
#[derive(Debug, PartialEq, Deserialize, Clone)]
|
||||
pub struct State(pub BTreeMap<Address, Account>);
|
||||
pub struct State(BTreeMap<Address, Account>);
|
||||
|
||||
impl IntoIterator for State {
|
||||
type Item = <BTreeMap<Address, Account> as IntoIterator>::Item;
|
||||
|
||||
@@ -22,9 +22,19 @@ use spec::builtin::Builtin;
|
||||
/// Spec account.
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
pub struct Account {
|
||||
builtin: Option<Builtin>,
|
||||
balance: Option<Uint>,
|
||||
nonce: Option<Uint>,
|
||||
/// Builtin contract.
|
||||
pub builtin: Option<Builtin>,
|
||||
/// Balance.
|
||||
pub balance: Option<Uint>,
|
||||
/// Nonce.
|
||||
pub nonce: Option<Uint>,
|
||||
}
|
||||
|
||||
impl Account {
|
||||
/// Returns true if account does not have nonce and balance.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.balance.is_none() && self.nonce.is_none()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -17,14 +17,16 @@
|
||||
//! Spec builtin deserialization.
|
||||
|
||||
/// Linear pricing.
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
#[derive(Debug, PartialEq, Deserialize, Clone)]
|
||||
pub struct Linear {
|
||||
base: u64,
|
||||
word: u64,
|
||||
/// Base price.
|
||||
pub base: usize,
|
||||
/// Price for word.
|
||||
pub word: usize,
|
||||
}
|
||||
|
||||
/// Pricing variants.
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
#[derive(Debug, PartialEq, Deserialize, Clone)]
|
||||
pub enum Pricing {
|
||||
/// Linear pricing.
|
||||
#[serde(rename="linear")]
|
||||
@@ -32,10 +34,12 @@ pub enum Pricing {
|
||||
}
|
||||
|
||||
/// Spec builtin.
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
#[derive(Debug, PartialEq, Deserialize, Clone)]
|
||||
pub struct Builtin {
|
||||
name: String,
|
||||
pricing: Pricing,
|
||||
/// Builtin name.
|
||||
pub name: String,
|
||||
/// Builtin pricing.
|
||||
pub pricing: Pricing,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
63
json/src/spec/engine.rs
Normal file
63
json/src/spec/engine.rs
Normal file
@@ -0,0 +1,63 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Engine deserialization.
|
||||
|
||||
use serde::{Deserializer, Error};
|
||||
use serde::de::Visitor;
|
||||
use spec::Ethash;
|
||||
|
||||
/// Engine deserialization.
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
pub enum Engine {
|
||||
/// Null engine.
|
||||
Null,
|
||||
/// Ethash engine.
|
||||
Ethash(Ethash),
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use serde_json;
|
||||
use spec::Engine;
|
||||
|
||||
#[test]
|
||||
fn engine_deserialization() {
|
||||
let s = r#"{
|
||||
"Null": null
|
||||
}"#;
|
||||
|
||||
let deserialized: Engine = serde_json::from_str(s).unwrap();
|
||||
assert_eq!(Engine::Null, deserialized);
|
||||
|
||||
let s = r#"{
|
||||
"Ethash": {
|
||||
"params": {
|
||||
"tieBreakingGas": false,
|
||||
"gasLimitBoundDivisor": "0x0400",
|
||||
"minimumDifficulty": "0x020000",
|
||||
"difficultyBoundDivisor": "0x0800",
|
||||
"durationLimit": "0x0d",
|
||||
"blockReward": "0x4563918244F40000",
|
||||
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b"
|
||||
}
|
||||
}
|
||||
}"#;
|
||||
|
||||
let _deserialized: Engine = serde_json::from_str(s).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
75
json/src/spec/ethash.rs
Normal file
75
json/src/spec/ethash.rs
Normal file
@@ -0,0 +1,75 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Ethash params deserialization.
|
||||
|
||||
use uint::Uint;
|
||||
use hash::Address;
|
||||
|
||||
/// Ethash params deserialization.
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
pub struct EthashParams {
|
||||
/// Tie breaking gas.
|
||||
#[serde(rename="tieBreakingGas")]
|
||||
pub tie_breaking_gas: bool,
|
||||
/// Gas limit divisor.
|
||||
#[serde(rename="gasLimitBoundDivisor")]
|
||||
pub gas_limit_bound_divisor: Uint,
|
||||
/// Minimum difficulty.
|
||||
#[serde(rename="minimumDifficulty")]
|
||||
pub minimum_difficulty: Uint,
|
||||
/// Difficulty bound divisor.
|
||||
#[serde(rename="difficultyBoundDivisor")]
|
||||
pub difficulty_bound_divisor: Uint,
|
||||
/// Block duration.
|
||||
#[serde(rename="durationLimit")]
|
||||
pub duration_limit: Uint,
|
||||
/// Block reward.
|
||||
#[serde(rename="blockReward")]
|
||||
pub block_reward: Uint,
|
||||
/// Namereg contract address.
|
||||
pub registrar: Address,
|
||||
}
|
||||
|
||||
/// Ethash engine deserialization.
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
pub struct Ethash {
|
||||
/// Ethash params.
|
||||
pub params: EthashParams,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use serde_json;
|
||||
use spec::ethash::Ethash;
|
||||
|
||||
#[test]
|
||||
fn ethash_deserialization() {
|
||||
let s = r#"{
|
||||
"params": {
|
||||
"tieBreakingGas": false,
|
||||
"gasLimitBoundDivisor": "0x0400",
|
||||
"minimumDifficulty": "0x020000",
|
||||
"difficultyBoundDivisor": "0x0800",
|
||||
"durationLimit": "0x0d",
|
||||
"blockReward": "0x4563918244F40000",
|
||||
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b"
|
||||
}
|
||||
}"#;
|
||||
|
||||
let _deserialized: Ethash = serde_json::from_str(s).unwrap();
|
||||
}
|
||||
}
|
||||
@@ -17,27 +17,15 @@
|
||||
//! Spec genesis deserialization.
|
||||
|
||||
use uint::Uint;
|
||||
use hash::{H64, Address, H256};
|
||||
use hash::{Address, H256};
|
||||
use bytes::Bytes;
|
||||
use spec::Seal;
|
||||
|
||||
/// Spec genesis.
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
pub struct Genesis {
|
||||
// old seal
|
||||
/// Seal nonce.
|
||||
pub nonce: Option<H64>,
|
||||
#[serde(rename="mixHash")]
|
||||
/// Seal mix hash.
|
||||
pub mix_hash: Option<H256>,
|
||||
|
||||
// new seal // TODO: consider moving it to a separate seal structure
|
||||
#[serde(rename="sealFields")]
|
||||
/// Number of seal fields.
|
||||
pub seal_fields: Option<usize>,
|
||||
#[serde(rename="sealRlp")]
|
||||
/// Seal rlp.
|
||||
pub seal_rlp: Option<Bytes>,
|
||||
|
||||
/// Seal.
|
||||
pub seal: Seal,
|
||||
/// Difficulty.
|
||||
pub difficulty: Uint,
|
||||
/// Block author.
|
||||
@@ -77,7 +65,12 @@ mod tests {
|
||||
let s = r#"{
|
||||
"nonce": "0x0000000000000042",
|
||||
"difficulty": "0x400000000",
|
||||
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"seal": {
|
||||
"ethereum": {
|
||||
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"nonce": "0x00006d6f7264656e"
|
||||
}
|
||||
},
|
||||
"author": "0x0000000000000000000000000000000000000000",
|
||||
"timestamp": "0x00",
|
||||
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
|
||||
@@ -21,9 +21,17 @@ 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 use self::account::Account;
|
||||
pub use self::builtin::Builtin;
|
||||
pub use self::builtin::{Builtin, Pricing, Linear};
|
||||
pub use self::genesis::Genesis;
|
||||
pub use self::params::Params;
|
||||
pub use self::spec::Spec;
|
||||
pub use self::seal::{Seal, Ethereum, Generic};
|
||||
pub use self::engine::Engine;
|
||||
pub use self::state::State;
|
||||
pub use self::ethash::{Ethash, EthashParams};
|
||||
|
||||
@@ -17,34 +17,25 @@
|
||||
//! Spec params deserialization.
|
||||
|
||||
use uint::Uint;
|
||||
use hash::Address;
|
||||
|
||||
/// Spec params.
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
pub struct Params {
|
||||
/// Account start nonce.
|
||||
#[serde(rename="accountStartNonce")]
|
||||
account_start_nonce: Uint,
|
||||
pub account_start_nonce: Uint,
|
||||
/// Homestead transition block number.
|
||||
#[serde(rename="frontierCompatibilityModeLimit")]
|
||||
frontier_compatibility_mode_limit: Uint,
|
||||
pub frontier_compatibility_mode_limit: Uint,
|
||||
/// Maximum size of extra data.
|
||||
#[serde(rename="maximumExtraDataSize")]
|
||||
maximum_extra_data_size: Uint,
|
||||
#[serde(rename="tieBreakingGas")]
|
||||
tie_breaking_gas: bool,
|
||||
#[serde(rename="minGasLimit")]
|
||||
min_gas_limit: Uint,
|
||||
#[serde(rename="gasLimitBoundDivisor")]
|
||||
gas_limit_bound_divisor: Uint,
|
||||
#[serde(rename="minimumDifficulty")]
|
||||
minimum_difficulty: Uint,
|
||||
#[serde(rename="difficultyBoundDivisor")]
|
||||
difficulty_bound_divisor: Uint,
|
||||
#[serde(rename="durationLimit")]
|
||||
duration_limit: Uint,
|
||||
#[serde(rename="blockReward")]
|
||||
block_reward: Uint,
|
||||
registrar: Address,
|
||||
pub maximum_extra_data_size: Uint,
|
||||
/// Network id.
|
||||
#[serde(rename="networkID")]
|
||||
network_id: Uint,
|
||||
pub network_id: Uint,
|
||||
/// Minimum gas limit.
|
||||
#[serde(rename="minGasLimit")]
|
||||
pub min_gas_limit: Uint,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -55,19 +46,13 @@ mod tests {
|
||||
#[test]
|
||||
fn params_deserialization() {
|
||||
let s = r#"{
|
||||
"accountStartNonce": "0x00",
|
||||
"frontierCompatibilityModeLimit": "0x118c30",
|
||||
"maximumExtraDataSize": "0x20",
|
||||
"tieBreakingGas": false,
|
||||
"networkID" : "0x1",
|
||||
"minGasLimit": "0x1388",
|
||||
"gasLimitBoundDivisor": "0x0400",
|
||||
"minimumDifficulty": "0x020000",
|
||||
"difficultyBoundDivisor": "0x0800",
|
||||
"durationLimit": "0x0d",
|
||||
"blockReward": "0x4563918244F40000",
|
||||
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
||||
"networkID" : "0x1"
|
||||
"accountStartNonce": "0x00"
|
||||
}"#;
|
||||
|
||||
let _deserialized: Params = serde_json::from_str(s).unwrap();
|
||||
// TODO: validate all fields
|
||||
}
|
||||
|
||||
73
json/src/spec/seal.rs
Normal file
73
json/src/spec/seal.rs
Normal file
@@ -0,0 +1,73 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Spec seal deserialization.
|
||||
|
||||
use hash::{H64, H256};
|
||||
use bytes::Bytes;
|
||||
|
||||
/// Ethereum seal.
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
pub struct Ethereum {
|
||||
/// Seal nonce.
|
||||
pub nonce: H64,
|
||||
/// Seal mix hash.
|
||||
#[serde(rename="mixHash")]
|
||||
pub mix_hash: H256,
|
||||
}
|
||||
|
||||
/// Generic seal.
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
pub struct Generic {
|
||||
/// Number of fields.
|
||||
pub fields: usize,
|
||||
/// Their rlp.
|
||||
pub rlp: Bytes,
|
||||
}
|
||||
|
||||
/// Seal variants.
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
pub enum Seal {
|
||||
/// Ethereum seal.
|
||||
#[serde(rename="ethereum")]
|
||||
Ethereum(Ethereum),
|
||||
/// Generic seal.
|
||||
#[serde(rename="generic")]
|
||||
Generic(Generic),
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use serde_json;
|
||||
use spec::Seal;
|
||||
|
||||
#[test]
|
||||
fn builtin_deserialization() {
|
||||
let s = r#"[{
|
||||
"ethereum": {
|
||||
"nonce": "0x0000000000000042",
|
||||
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||
}
|
||||
},{
|
||||
"generic": {
|
||||
"fields": 1,
|
||||
"rlp": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa"
|
||||
}
|
||||
}]"#;
|
||||
let _deserialized: Vec<Seal> = serde_json::from_str(s).unwrap();
|
||||
// TODO: validate all fields
|
||||
}
|
||||
}
|
||||
@@ -16,21 +16,33 @@
|
||||
|
||||
//! Spec deserialization.
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use hash::Address;
|
||||
use spec::account::Account;
|
||||
use spec::params::Params;
|
||||
use spec::genesis::Genesis;
|
||||
use std::io::Read;
|
||||
use serde_json;
|
||||
use serde_json::Error;
|
||||
use spec::{Params, Genesis, Engine, State};
|
||||
|
||||
/// Spec deserialization.
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
pub struct Spec {
|
||||
name: String,
|
||||
#[serde(rename="engineName")]
|
||||
engine_name: String, // TODO: consider making it an enum
|
||||
params: Params,
|
||||
genesis: Genesis,
|
||||
accounts: BTreeMap<Address, Account>,
|
||||
/// Spec name.
|
||||
pub name: 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>>,
|
||||
}
|
||||
|
||||
impl Spec {
|
||||
/// Loads test from json.
|
||||
pub fn load<R>(reader: R) -> Result<Self, Error> where R: Read {
|
||||
serde_json::from_reader(reader)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -42,25 +54,34 @@ mod tests {
|
||||
fn spec_deserialization() {
|
||||
let s = r#"{
|
||||
"name": "Morden",
|
||||
"engineName": "Ethash",
|
||||
"engine": {
|
||||
"Ethash": {
|
||||
"params": {
|
||||
"tieBreakingGas": false,
|
||||
"gasLimitBoundDivisor": "0x0400",
|
||||
"minimumDifficulty": "0x020000",
|
||||
"difficultyBoundDivisor": "0x0800",
|
||||
"durationLimit": "0x0d",
|
||||
"blockReward": "0x4563918244F40000",
|
||||
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b"
|
||||
}
|
||||
}
|
||||
},
|
||||
"params": {
|
||||
"accountStartNonce": "0x0100000",
|
||||
"frontierCompatibilityModeLimit": "0x789b0",
|
||||
"maximumExtraDataSize": "0x20",
|
||||
"tieBreakingGas": false,
|
||||
"minGasLimit": "0x1388",
|
||||
"gasLimitBoundDivisor": "0x0400",
|
||||
"minimumDifficulty": "0x020000",
|
||||
"difficultyBoundDivisor": "0x0800",
|
||||
"durationLimit": "0x0d",
|
||||
"blockReward": "0x4563918244F40000",
|
||||
"registrar": "",
|
||||
"networkID" : "0x2"
|
||||
},
|
||||
"genesis": {
|
||||
"nonce": "0x00006d6f7264656e",
|
||||
"seal": {
|
||||
"ethereum": {
|
||||
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"nonce": "0x00006d6f7264656e"
|
||||
}
|
||||
},
|
||||
"difficulty": "0x20000",
|
||||
"mixHash": "0x00000000000000000000000000000000000000647572616c65787365646c6578",
|
||||
"author": "0x0000000000000000000000000000000000000000",
|
||||
"timestamp": "0x00",
|
||||
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
|
||||
44
json/src/spec/state.rs
Normal file
44
json/src/spec/state.rs
Normal file
@@ -0,0 +1,44 @@
|
||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Blockchain test state deserializer.
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use hash::Address;
|
||||
use spec::{Account, Builtin};
|
||||
|
||||
/// Blockchain test state deserializer.
|
||||
#[derive(Debug, PartialEq, Deserialize)]
|
||||
pub struct State(BTreeMap<Address, Account>);
|
||||
|
||||
impl State {
|
||||
/// Returns all builtins.
|
||||
pub fn builtins(&self) -> BTreeMap<Address, Builtin> {
|
||||
self.0
|
||||
.iter()
|
||||
.filter_map(|ref pair| pair.1.builtin.clone().map(|b| (pair.0.clone(), b.clone())))
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoIterator for State {
|
||||
type Item = <BTreeMap<Address, Account> as IntoIterator>::Item;
|
||||
type IntoIter = <BTreeMap<Address, Account> as IntoIterator>::IntoIter;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.0.into_iter()
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,7 @@ use util::numbers::{U256, Uint as U};
|
||||
|
||||
/// Lenient uint json deserialization for test json files.
|
||||
#[derive(Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
|
||||
pub struct Uint(U256);
|
||||
pub struct Uint(pub U256);
|
||||
|
||||
impl Into<U256> for Uint {
|
||||
fn into(self) -> U256 {
|
||||
@@ -37,9 +37,15 @@ impl Into<u64> for Uint {
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<usize> for Uint {
|
||||
fn into(self) -> usize {
|
||||
// TODO: clean it after util conversions refactored.
|
||||
u64::from(self.0) as usize
|
||||
}
|
||||
}
|
||||
impl Into<u8> for Uint {
|
||||
fn into(self) -> u8 {
|
||||
<Uint as Into<u64>>::into(self) as u8
|
||||
u64::from(self.0) as u8
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,6 +61,10 @@ struct UintVisitor;
|
||||
impl Visitor for UintVisitor {
|
||||
type Value = Uint;
|
||||
|
||||
fn visit_u64<E>(&mut self, value: u64) -> Result<Self::Value, E> where E: Error {
|
||||
Ok(Uint(U256::from(value)))
|
||||
}
|
||||
|
||||
fn visit_str<E>(&mut self, value: &str) -> Result<Self::Value, E> where E: Error {
|
||||
let value = match value.len() {
|
||||
0 => U256::from(0),
|
||||
@@ -83,12 +93,13 @@ mod test {
|
||||
|
||||
#[test]
|
||||
fn uint_deserialization() {
|
||||
let s = r#"["0xa", "10", "", "0x"]"#;
|
||||
let s = r#"["0xa", "10", "", "0x", 0]"#;
|
||||
let deserialized: Vec<Uint> = serde_json::from_str(s).unwrap();
|
||||
assert_eq!(deserialized, vec![
|
||||
Uint(U256::from(10)),
|
||||
Uint(U256::from(10)),
|
||||
Uint(U256::from(0)),
|
||||
Uint(U256::from(0)),
|
||||
Uint(U256::from(0))
|
||||
]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user