From acbaed59c0b7134b581f78ba235aab0a8091cb2b Mon Sep 17 00:00:00 2001 From: Jannis R Date: Thu, 10 Nov 2016 17:26:45 +0100 Subject: [PATCH 01/31] CopyToClipboard: clear timeout on unmount --- js/src/ui/CopyToClipboard/copyToClipboard.js | 21 ++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/js/src/ui/CopyToClipboard/copyToClipboard.js b/js/src/ui/CopyToClipboard/copyToClipboard.js index 3351f2e40..a49da6adc 100644 --- a/js/src/ui/CopyToClipboard/copyToClipboard.js +++ b/js/src/ui/CopyToClipboard/copyToClipboard.js @@ -39,9 +39,17 @@ export default class CopyToClipboard extends Component { }; state = { - copied: false + copied: false, + timeout: null }; + componentWillUnmount () { + const { timeoutId } = this.state; + if (timeoutId) { + window.clearTimeout(timeoutId); + } + } + render () { const { data, label, size } = this.props; const { copied } = this.state; @@ -65,11 +73,12 @@ export default class CopyToClipboard extends Component { onCopy = () => { const { cooldown, onCopy } = this.props; - this.setState({ copied: true }); - setTimeout(() => { - this.setState({ copied: false }); - }, cooldown); - + this.setState({ + copied: true, + timeout: setTimeout(() => { + this.setState({ copied: false, timeout: null }); + }, cooldown) + }); onCopy(); } } From 87c39f066c373c747e848d1499551994eea35831 Mon Sep 17 00:00:00 2001 From: Jannis R Date: Thu, 10 Nov 2016 17:27:04 +0100 Subject: [PATCH 02/31] Form/Input: use CopyToClipboard --- js/src/ui/Form/Input/input.css | 4 --- js/src/ui/Form/Input/input.js | 62 +++------------------------------- 2 files changed, 5 insertions(+), 61 deletions(-) diff --git a/js/src/ui/Form/Input/input.css b/js/src/ui/Form/Input/input.css index 62c2e39b2..bc7cfb840 100644 --- a/js/src/ui/Form/Input/input.css +++ b/js/src/ui/Form/Input/input.css @@ -24,8 +24,4 @@ .copy { margin-right: 0.5em; - - svg { - transition: all .5s ease-in-out; - } } diff --git a/js/src/ui/Form/Input/input.js b/js/src/ui/Form/Input/input.js index 24a0a8089..27c270834 100644 --- a/js/src/ui/Form/Input/input.js +++ b/js/src/ui/Form/Input/input.js @@ -15,11 +15,9 @@ // along with Parity. If not, see . import React, { Component, PropTypes } from 'react'; +import { TextField } from 'material-ui'; -import CopyToClipboard from 'react-copy-to-clipboard'; -import CopyIcon from 'material-ui/svg-icons/content/content-copy'; -import { TextField, IconButton } from 'material-ui'; -import { lightWhite, fullWhite } from 'material-ui/styles/colors'; +import CopyToClipboard from '../../CopyToClipboard'; import styles from './input.css'; @@ -77,9 +75,7 @@ export default class Input extends Component { } state = { - value: this.props.value || '', - timeoutId: null, - copied: false + value: this.props.value || '' } componentWillReceiveProps (newProps) { @@ -88,14 +84,6 @@ export default class Input extends Component { } } - componentWillUnmount () { - const { timeoutId } = this.state; - - if (timeoutId) { - window.clearTimeout(timeoutId); - } - } - render () { const { value } = this.state; const { children, className, hideUnderline, disabled, error, label, hint, multiLine, rows, type } = this.props; @@ -151,7 +139,7 @@ export default class Input extends Component { renderCopyButton () { const { allowCopy, hideUnderline, label, hint, floatCopy } = this.props; - const { copied, value } = this.state; + const { value } = this.state; if (!allowCopy) { return null; @@ -165,8 +153,6 @@ export default class Input extends Component { ? allowCopy : value; - const scale = copied ? 'scale(1.15)' : 'scale(1)'; - if (hideUnderline && !label) { style.marginBottom = 2; } else if (label && !hint) { @@ -184,49 +170,11 @@ export default class Input extends Component { return (
- - - - - +
); } - handleCopy = () => { - if (this.state.timeoutId) { - window.clearTimeout(this.state.timeoutId); - } - - this.setState({ copied: true }, () => { - const timeoutId = window.setTimeout(() => { - this.setState({ copied: false }); - }, 500); - - this.setState({ timeoutId }); - }); - } - onChange = (event, value) => { this.setValue(value); From e9b69bceab88355d459ab7d0c396ceb20848f795 Mon Sep 17 00:00:00 2001 From: Jannis R Date: Thu, 10 Nov 2016 18:09:54 +0100 Subject: [PATCH 03/31] Account Header: use CopyToClipboard --- js/src/views/Account/Header/header.css | 4 +- js/src/views/Account/Header/header.js | 58 ++------------------------ 2 files changed, 6 insertions(+), 56 deletions(-) diff --git a/js/src/views/Account/Header/header.css b/js/src/views/Account/Header/header.css index ff3f985c3..74390face 100644 --- a/js/src/views/Account/Header/header.css +++ b/js/src/views/Account/Header/header.css @@ -43,6 +43,6 @@ } .address { - white-space: nowrap; - font-family: monospace; + display: inline-block; + margin-left: .5em; } diff --git a/js/src/views/Account/Header/header.js b/js/src/views/Account/Header/header.js index d4b01cf56..66f0a36b9 100644 --- a/js/src/views/Account/Header/header.js +++ b/js/src/views/Account/Header/header.js @@ -15,13 +15,9 @@ // along with Parity. If not, see . import React, { Component, PropTypes } from 'react'; -import CopyToClipboard from 'react-copy-to-clipboard'; -import IconButton from 'material-ui/IconButton'; -import Snackbar from 'material-ui/Snackbar'; -import CopyIcon from 'material-ui/svg-icons/content/content-copy'; -import { lightWhite, fullWhite, darkBlack } from 'material-ui/styles/colors'; import { Balance, Container, ContainerTitle, IdentityIcon, IdentityName, Tags } from '../../../ui'; +import CopyToClipboard from '../../../ui/CopyToClipboard'; import styles from './header.css'; @@ -37,8 +33,7 @@ export default class Header extends Component { } state = { - name: null, - addressCopied: false + name: null } componentWillMount () { @@ -51,7 +46,6 @@ export default class Header extends Component { render () { const { account, balance } = this.props; - const { addressCopied } = this.state; const { address, meta, uuid } = account; if (!account) { @@ -64,50 +58,14 @@ export default class Header extends Component { return (
- - - Address - { address } - copied to clipboard - - } - autoHideDuration={ 4000 } - onRequestClose={ this.handleCopyAddressClose } - bodyStyle={ { - backgroundColor: darkBlack - } } - /> -
} />
- - - - - - { address } + +
{ address }
{ uuidText }
@@ -157,14 +115,6 @@ export default class Header extends Component { }); } - handleCopyAddress = () => { - this.setState({ addressCopied: true }); - } - - handleCopyAddressClose = () => { - this.setState({ addressCopied: false }); - } - setName () { const { account } = this.props; From 522b7108f94b44e898c3869c1d035ffc57b1b287 Mon Sep 17 00:00:00 2001 From: Jannis R Date: Thu, 10 Nov 2016 18:47:17 +0100 Subject: [PATCH 04/31] CopyToClipboard: show SnackBar --- js/src/ui/CopyToClipboard/copyToClipboard.css | 20 +++++++++++ js/src/ui/CopyToClipboard/copyToClipboard.js | 34 +++++++++++++------ 2 files changed, 44 insertions(+), 10 deletions(-) create mode 100644 js/src/ui/CopyToClipboard/copyToClipboard.css diff --git a/js/src/ui/CopyToClipboard/copyToClipboard.css b/js/src/ui/CopyToClipboard/copyToClipboard.css new file mode 100644 index 000000000..acf2bb204 --- /dev/null +++ b/js/src/ui/CopyToClipboard/copyToClipboard.css @@ -0,0 +1,20 @@ +/* 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 . +*/ + +.data { + font-family: monospace; +} diff --git a/js/src/ui/CopyToClipboard/copyToClipboard.js b/js/src/ui/CopyToClipboard/copyToClipboard.js index a49da6adc..c78038617 100644 --- a/js/src/ui/CopyToClipboard/copyToClipboard.js +++ b/js/src/ui/CopyToClipboard/copyToClipboard.js @@ -16,11 +16,15 @@ import React, { Component, PropTypes } from 'react'; import { IconButton } from 'material-ui'; +import Snackbar from 'material-ui/Snackbar'; import Clipboard from 'react-copy-to-clipboard'; import CopyIcon from 'material-ui/svg-icons/content/content-copy'; import Theme from '../Theme'; +import { darkBlack } from 'material-ui/styles/colors'; const { textColor, disabledTextColor } = Theme.flatButton; +import styles from './copyToClipboard.css'; + export default class CopyToClipboard extends Component { static propTypes = { data: PropTypes.string.isRequired, @@ -56,16 +60,26 @@ export default class CopyToClipboard extends Component { return ( - - - +
+ copied { data } to clipboard
+ } + autoHideDuration={ 2000 } + bodyStyle={ { backgroundColor: darkBlack } } + /> + + + +
); } From ed135bb9dc5638a3e33ed4d1961b7cb5ce6afa51 Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Fri, 11 Nov 2016 17:18:31 +0100 Subject: [PATCH 05/31] fetch known code from the database during restoration previously it kept all seen code in memory, leading to high memory usage by the end of state restoration --- ethcore/src/snapshot/account.rs | 20 +++++--------- ethcore/src/snapshot/mod.rs | 47 +++++++++++++++++++++++---------- 2 files changed, 40 insertions(+), 27 deletions(-) diff --git a/ethcore/src/snapshot/account.rs b/ethcore/src/snapshot/account.rs index 38a4028e1..4db023017 100644 --- a/ethcore/src/snapshot/account.rs +++ b/ethcore/src/snapshot/account.rs @@ -19,11 +19,11 @@ use account_db::{AccountDB, AccountDBMut}; use snapshot::Error; -use util::{U256, FixedHash, H256, Bytes, HashDB, DBValue, SHA3_EMPTY, SHA3_NULL_RLP}; +use util::{U256, FixedHash, H256, Bytes, HashDB, SHA3_EMPTY, SHA3_NULL_RLP}; use util::trie::{TrieDB, Trie}; use rlp::{Rlp, RlpStream, Stream, UntrustedRlp, View}; -use std::collections::{HashMap, HashSet}; +use std::collections::HashSet; // An empty account -- these are replaced with RLP null data for a space optimization. const ACC_EMPTY: Account = Account { @@ -150,7 +150,6 @@ impl Account { pub fn from_fat_rlp( acct_db: &mut AccountDBMut, rlp: UntrustedRlp, - code_map: &HashMap, ) -> Result<(Self, Option), Error> { use util::{TrieDBMut, TrieMut}; @@ -177,9 +176,6 @@ impl Account { } CodeState::Hash => { let code_hash = try!(rlp.val_at(3)); - if let Some(code) = code_map.get(&code_hash) { - acct_db.emplace(code_hash.clone(), DBValue::from_slice(code)); - } (code_hash, None) } @@ -250,7 +246,7 @@ mod tests { let fat_rlp = account.to_fat_rlp(&AccountDB::new(db.as_hashdb(), &addr), &mut Default::default()).unwrap(); let fat_rlp = UntrustedRlp::new(&fat_rlp); - assert_eq!(Account::from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &addr), fat_rlp, &Default::default()).unwrap().0, account); + assert_eq!(Account::from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &addr), fat_rlp).unwrap().0, account); } #[test] @@ -275,7 +271,7 @@ mod tests { let fat_rlp = account.to_fat_rlp(&AccountDB::new(db.as_hashdb(), &addr), &mut Default::default()).unwrap(); let fat_rlp = UntrustedRlp::new(&fat_rlp); - assert_eq!(Account::from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &addr), fat_rlp, &Default::default()).unwrap().0, account); + assert_eq!(Account::from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &addr), fat_rlp).unwrap().0, account); } #[test] @@ -318,12 +314,11 @@ mod tests { let fat_rlp1 = UntrustedRlp::new(&fat_rlp1); let fat_rlp2 = UntrustedRlp::new(&fat_rlp2); - let code_map = HashMap::new(); - let (acc, maybe_code) = Account::from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &addr2), fat_rlp2, &code_map).unwrap(); + let (acc, maybe_code) = Account::from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &addr2), fat_rlp2).unwrap(); assert!(maybe_code.is_none()); assert_eq!(acc, account2); - let (acc, maybe_code) = Account::from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &addr1), fat_rlp1, &code_map).unwrap(); + let (acc, maybe_code) = Account::from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &addr1), fat_rlp1).unwrap(); assert_eq!(maybe_code, Some(b"this is definitely code".to_vec())); assert_eq!(acc, account1); } @@ -332,9 +327,8 @@ mod tests { fn encoding_empty_acc() { let mut db = get_temp_state_db(); let mut used_code = HashSet::new(); - let code_map = HashMap::new(); assert_eq!(ACC_EMPTY.to_fat_rlp(&AccountDB::new(db.as_hashdb(), &Address::default()), &mut used_code).unwrap(), ::rlp::NULL_RLP.to_vec()); - assert_eq!(Account::from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &Address::default()), UntrustedRlp::new(&::rlp::NULL_RLP), &code_map).unwrap(), (ACC_EMPTY, None)); + assert_eq!(Account::from_fat_rlp(&mut AccountDBMut::new(db.as_hashdb_mut(), &Address::default()), UntrustedRlp::new(&::rlp::NULL_RLP)).unwrap(), (ACC_EMPTY, None)); } } diff --git a/ethcore/src/snapshot/mod.rs b/ethcore/src/snapshot/mod.rs index 22c44ba3b..325ce94a8 100644 --- a/ethcore/src/snapshot/mod.rs +++ b/ethcore/src/snapshot/mod.rs @@ -389,7 +389,7 @@ pub fn chunk_state<'a>(db: &HashDB, root: &H256, writer: &Mutex, state_root: H256, - code_map: HashMap, // maps code hashes to code itself. + known_code: HashMap, // code hashes mapped to first account with this code. missing_code: HashMap>, // maps code hashes to lists of accounts missing that code. bloom: Bloom, } @@ -400,7 +400,7 @@ impl StateRebuilder { StateRebuilder { db: journaldb::new(db.clone(), pruning, ::db::COL_STATE), state_root: SHA3_NULL_RLP, - code_map: HashMap::new(), + known_code: HashMap::new(), missing_code: HashMap::new(), bloom: StateDB::load_bloom(&*db), } @@ -419,24 +419,26 @@ impl StateRebuilder { let chunk_size = account_fat_rlps.len() / ::num_cpus::get() + 1; // new code contained within this chunk. - let mut chunk_code = HashMap::new(); + let mut chunk_code = Vec::new(); for (account_chunk, out_pairs_chunk) in account_fat_rlps.chunks(chunk_size).zip(pairs.chunks_mut(chunk_size)) { - let code_map = &self.code_map; - let status = try!(rebuild_accounts(self.db.as_hashdb_mut(), account_chunk, out_pairs_chunk, code_map)); + let status = try!(rebuild_accounts(self.db.as_hashdb_mut(), account_chunk, out_pairs_chunk, &self.known_code)); chunk_code.extend(status.new_code); + + // update missing code. for (addr_hash, code_hash) in status.missing_code { self.missing_code.entry(code_hash).or_insert_with(Vec::new).push(addr_hash); } } + // patch up all missing code. must be done after collecting all new missing code entries. - for (code_hash, code) in chunk_code { + for (code_hash, code, first_with) in chunk_code { for addr_hash in self.missing_code.remove(&code_hash).unwrap_or_else(Vec::new) { let mut db = AccountDBMut::from_hash(self.db.as_hashdb_mut(), addr_hash); db.emplace(code_hash, DBValue::from_slice(&code)); } - self.code_map.insert(code_hash, code); + self.known_code.insert(code_hash, first_with); } let backing = self.db.backing().clone(); @@ -482,7 +484,8 @@ impl StateRebuilder { #[derive(Default)] struct RebuiltStatus { - new_code: Vec<(H256, Bytes)>, // new code that's become available. + // new code that's become available. (code_hash, code, addr_hash) + new_code: Vec<(H256, Bytes, H256)>, missing_code: Vec<(H256, H256)>, // accounts that are missing code. } @@ -492,7 +495,7 @@ fn rebuild_accounts( db: &mut HashDB, account_chunk: &[&[u8]], out_chunk: &mut [(H256, Bytes)], - code_map: &HashMap + known_code: &HashMap, ) -> Result { let mut status = RebuiltStatus::default(); @@ -503,17 +506,33 @@ fn rebuild_accounts( let fat_rlp = try!(account_rlp.at(1)); let thin_rlp = { - let mut acct_db = AccountDBMut::from_hash(db, hash); // fill out the storage trie and code while decoding. - let (acc, maybe_code) = try!(Account::from_fat_rlp(&mut acct_db, fat_rlp, code_map)); + let (acc, maybe_code) = { + let mut acct_db = AccountDBMut::from_hash(db, hash); + try!(Account::from_fat_rlp(&mut acct_db, fat_rlp)) + }; let code_hash = acc.code_hash().clone(); match maybe_code { - Some(code) => status.new_code.push((code_hash, code)), + // new inline code + Some(code) => status.new_code.push((code_hash, code, hash)), None => { - if code_hash != ::util::SHA3_EMPTY && !code_map.contains_key(&code_hash) { - status.missing_code.push((hash, code_hash)); + if code_hash != ::util::SHA3_EMPTY { + // see if this code has already been included inline + match known_code.get(&code_hash) { + Some(&first_with) => { + // if so, load it from the database. + let code = try!(AccountDB::from_hash(db, first_with) + .get(&code_hash) + .ok_or_else(|| Error::MissingCode(vec![first_with]))); + + // and write it again under a different mangled key + AccountDBMut::from_hash(db, hash).emplace(code_hash, code); + } + // if not, queue it up to be filled later + None => status.missing_code.push((hash, code_hash)), + } } } } From a7ad75d851a82e224a8050db2faa1ff0f2643837 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 11 Nov 2016 17:32:54 +0100 Subject: [PATCH 06/31] whitespace [ci:skip] --- ethcore/src/snapshot/mod.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ethcore/src/snapshot/mod.rs b/ethcore/src/snapshot/mod.rs index 325ce94a8..9cdbff433 100644 --- a/ethcore/src/snapshot/mod.rs +++ b/ethcore/src/snapshot/mod.rs @@ -496,8 +496,7 @@ fn rebuild_accounts( account_chunk: &[&[u8]], out_chunk: &mut [(H256, Bytes)], known_code: &HashMap, -) -> Result -{ +) -> Result { let mut status = RebuiltStatus::default(); for (account_pair, out) in account_chunk.into_iter().zip(out_chunk) { let account_rlp = UntrustedRlp::new(account_pair); From a719b91b635b1a419f78352eb50b57e34d349136 Mon Sep 17 00:00:00 2001 From: keorn Date: Fri, 11 Nov 2016 16:37:44 +0000 Subject: [PATCH 07/31] move spec constructors to spec --- ethcore/res/{ethereum => }/expanse.json | 0 ethcore/src/ethereum/ethash.rs | 38 +++++++++--------- ethcore/src/ethereum/mod.rs | 47 ++--------------------- ethcore/src/miner/mod.rs | 4 +- ethcore/src/spec/spec.rs | 51 ++++++++++++++++++++----- ethcore/src/tests/client.rs | 3 +- ethcore/src/tests/helpers.rs | 3 +- 7 files changed, 69 insertions(+), 77 deletions(-) rename ethcore/res/{ethereum => }/expanse.json (100%) diff --git a/ethcore/res/ethereum/expanse.json b/ethcore/res/expanse.json similarity index 100% rename from ethcore/res/ethereum/expanse.json rename to ethcore/res/expanse.json diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index 6436e3531..2c7187b09 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -423,13 +423,13 @@ mod tests { use env_info::EnvInfo; use error::{BlockError, Error}; use header::Header; - use super::super::{new_morden, new_homestead_test}; + use spec::Spec; use super::{Ethash, EthashParams}; use rlp; #[test] fn on_close_block() { - let spec = new_morden(); + let spec = Spec::new_ethereum_morden(); let engine = &*spec.engine; let genesis_header = spec.genesis_header(); let mut db_result = get_temp_state_db(); @@ -443,7 +443,7 @@ mod tests { #[test] fn on_close_block_with_uncle() { - let spec = new_morden(); + let spec = Spec::new_ethereum_morden(); let engine = &*spec.engine; let genesis_header = spec.genesis_header(); let mut db_result = get_temp_state_db(); @@ -463,14 +463,14 @@ mod tests { #[test] fn has_valid_metadata() { - let engine = new_morden().engine; + let engine = Spec::new_ethereum_morden().engine; assert!(!engine.name().is_empty()); assert!(engine.version().major >= 1); } #[test] fn can_return_schedule() { - let engine = new_morden().engine; + let engine = Spec::new_ethereum_morden().engine; let schedule = engine.schedule(&EnvInfo { number: 10000000, author: 0.into(), @@ -498,8 +498,8 @@ mod tests { #[test] fn can_do_seal_verification_fail() { - let engine = new_morden().engine; - //let engine = Ethash::new_test(new_morden()); + let engine = Spec::new_ethereum_morden().engine; + //let engine = Ethash::new_test(Spec::new_ethereum_morden()); let header: Header = Header::default(); let verify_result = engine.verify_block_basic(&header, None); @@ -513,7 +513,7 @@ mod tests { #[test] fn can_do_difficulty_verification_fail() { - let engine = new_morden().engine; + let engine = Spec::new_ethereum_morden().engine; let mut header: Header = Header::default(); header.set_seal(vec![rlp::encode(&H256::zero()).to_vec(), rlp::encode(&H64::zero()).to_vec()]); @@ -528,7 +528,7 @@ mod tests { #[test] fn can_do_proof_of_work_verification_fail() { - let engine = new_morden().engine; + let engine = Spec::new_ethereum_morden().engine; let mut header: Header = Header::default(); header.set_seal(vec![rlp::encode(&H256::zero()).to_vec(), rlp::encode(&H64::zero()).to_vec()]); header.set_difficulty(U256::from_str("ffffffffffffffffffffffffffffffffffffffffffffaaaaaaaaaaaaaaaaaaaa").unwrap()); @@ -544,7 +544,7 @@ mod tests { #[test] fn can_do_seal_unordered_verification_fail() { - let engine = new_morden().engine; + let engine = Spec::new_ethereum_morden().engine; let header: Header = Header::default(); let verify_result = engine.verify_block_unordered(&header, None); @@ -558,7 +558,7 @@ mod tests { #[test] fn can_do_seal256_verification_fail() { - let engine = new_morden().engine; + let engine = Spec::new_ethereum_morden().engine; let mut header: Header = Header::default(); header.set_seal(vec![rlp::encode(&H256::zero()).to_vec(), rlp::encode(&H64::zero()).to_vec()]); let verify_result = engine.verify_block_unordered(&header, None); @@ -572,7 +572,7 @@ mod tests { #[test] fn can_do_proof_of_work_unordered_verification_fail() { - let engine = new_morden().engine; + let engine = Spec::new_ethereum_morden().engine; let mut header: Header = Header::default(); header.set_seal(vec![rlp::encode(&H256::from("b251bd2e0283d0658f2cadfdc8ca619b5de94eca5742725e2e757dd13ed7503d")).to_vec(), rlp::encode(&H64::zero()).to_vec()]); header.set_difficulty(U256::from_str("ffffffffffffffffffffffffffffffffffffffffffffaaaaaaaaaaaaaaaaaaaa").unwrap()); @@ -588,7 +588,7 @@ mod tests { #[test] fn can_verify_block_family_genesis_fail() { - let engine = new_morden().engine; + let engine = Spec::new_ethereum_morden().engine; let header: Header = Header::default(); let parent_header: Header = Header::default(); @@ -603,7 +603,7 @@ mod tests { #[test] fn can_verify_block_family_difficulty_fail() { - let engine = new_morden().engine; + let engine = Spec::new_ethereum_morden().engine; let mut header: Header = Header::default(); header.set_number(2); let mut parent_header: Header = Header::default(); @@ -620,7 +620,7 @@ mod tests { #[test] fn can_verify_block_family_gas_fail() { - let engine = new_morden().engine; + let engine = Spec::new_ethereum_morden().engine; let mut header: Header = Header::default(); header.set_number(2); header.set_difficulty(U256::from_str("0000000000000000000000000000000000000000000000000000000000020000").unwrap()); @@ -648,7 +648,7 @@ mod tests { #[test] fn difficulty_frontier() { - let spec = new_homestead_test(); + let spec = Spec::new_ethereum_homestead_test(); let ethparams = get_default_ethash_params(); let ethash = Ethash::new(spec.params, ethparams, BTreeMap::new()); @@ -666,7 +666,7 @@ mod tests { #[test] fn difficulty_homestead() { - let spec = new_homestead_test(); + let spec = Spec::new_ethereum_homestead_test(); let ethparams = get_default_ethash_params(); let ethash = Ethash::new(spec.params, ethparams, BTreeMap::new()); @@ -684,7 +684,7 @@ mod tests { #[test] fn difficulty_classic_bomb_delay() { - let spec = new_homestead_test(); + let spec = Spec::new_ethereum_homestead_test(); let ethparams = EthashParams { ecip1010_pause_transition: 3000000, ..get_default_ethash_params() @@ -717,7 +717,7 @@ mod tests { #[test] fn test_difficulty_bomb_continue() { - let spec = new_homestead_test(); + let spec = Spec::new_ethereum_homestead_test(); let ethparams = EthashParams { ecip1010_pause_transition: 3000000, ecip1010_continue_transition: 5000000, diff --git a/ethcore/src/ethereum/mod.rs b/ethcore/src/ethereum/mod.rs index 253a12372..3df130a8d 100644 --- a/ethcore/src/ethereum/mod.rs +++ b/ethcore/src/ethereum/mod.rs @@ -27,56 +27,17 @@ pub mod denominations; pub use self::ethash::{Ethash}; pub use self::denominations::*; -use super::spec::*; - -fn load(b: &[u8]) -> Spec { - Spec::load(b).expect("chain spec is invalid") -} - -/// Create a new Olympic chain spec. -pub fn new_olympic() -> Spec { load(include_bytes!("../../res/ethereum/olympic.json")) } - -/// Create a new Frontier mainnet chain spec. -pub fn new_frontier() -> Spec { load(include_bytes!("../../res/ethereum/frontier.json")) } - -/// Create a new Frontier mainnet chain spec without the DAO hardfork. -pub fn new_classic() -> Spec { load(include_bytes!("../../res/ethereum/classic.json")) } - -/// Create a new Frontier mainnet chain spec without the DAO hardfork. -pub fn new_expanse() -> Spec { load(include_bytes!("../../res/ethereum/expanse.json")) } - -/// Create a new Frontier chain spec as though it never changes to Homestead. -pub fn new_frontier_test() -> Spec { load(include_bytes!("../../res/ethereum/frontier_test.json")) } - -/// Create a new Homestead chain spec as though it never changed from Frontier. -pub fn new_homestead_test() -> Spec { load(include_bytes!("../../res/ethereum/homestead_test.json")) } - -/// Create a new Homestead-EIP150 chain spec as though it never changed from Homestead/Frontier. -pub fn new_eip150_test() -> Spec { load(include_bytes!("../../res/ethereum/eip150_test.json")) } - -/// Create a new Homestead-EIP150 chain spec as though it never changed from Homestead/Frontier. -pub fn new_eip161_test() -> Spec { load(include_bytes!("../../res/ethereum/eip161_test.json")) } - -/// Create a new Frontier/Homestead/DAO chain spec with transition points at #5 and #8. -pub fn new_transition_test() -> Spec { load(include_bytes!("../../res/ethereum/transition_test.json")) } - -/// Create a new Frontier main net chain spec without genesis accounts. -pub fn new_mainnet_like() -> Spec { load(include_bytes!("../../res/ethereum/frontier_like_test.json")) } - -/// Create a new Morden chain spec. -pub fn new_morden() -> Spec { load(include_bytes!("../../res/ethereum/morden.json")) } - #[cfg(test)] mod tests { use util::*; use state::*; - use super::*; use tests::helpers::*; + use spec::Spec; use views::BlockView; #[test] fn ensure_db_good() { - let spec = new_morden(); + let spec = Spec::new_ethereum_morden(); let engine = &spec.engine; let genesis_header = spec.genesis_header(); let mut db_result = get_temp_state_db(); @@ -93,7 +54,7 @@ mod tests { #[test] fn morden() { - let morden = new_morden(); + let morden = Spec::new_ethereum_morden(); assert_eq!(morden.state_root(), "f3f4696bbf3b3b07775128eb7a3763279a394e382130f27c21e70233e04946a9".into()); let genesis = morden.genesis_block(); @@ -104,7 +65,7 @@ mod tests { #[test] fn frontier() { - let frontier = new_frontier(); + let frontier = Spec::new_ethereum_frontier(); assert_eq!(frontier.state_root(), "d7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544".into()); let genesis = frontier.genesis_block(); diff --git a/ethcore/src/miner/mod.rs b/ethcore/src/miner/mod.rs index da93dc0b7..a553daffc 100644 --- a/ethcore/src/miner/mod.rs +++ b/ethcore/src/miner/mod.rs @@ -27,12 +27,12 @@ //! extern crate ethcore_util as util; //! extern crate ethcore; //! use std::env; -//! use ethcore::ethereum; +//! use spec::Spec; //! use ethcore::client::{Client, ClientConfig}; //! use ethcore::miner::{Miner, MinerService}; //! //! fn main() { -//! let miner: Miner = Miner::with_spec(ðereum::new_frontier()); +//! let miner: Miner = Miner::with_spec(&Spec::new_ethereum_frontier()); //! // get status //! assert_eq!(miner.status().transactions_in_pending_queue, 0); //! diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index 2babfb708..786b264ab 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -135,6 +135,12 @@ impl From for Spec { } } +macro_rules! load_bundled { + ($e:expr) => { + Spec::load(include_bytes!(concat!("../../res/", $e, ".json")) as &[u8]).expect("Chain spec is invalid") + }; +} + impl Spec { /// Convert engine spec into a arc'd Engine of the right underlying type. /// TODO avoid this hard-coded nastiness - use dynamic-linked plugin framework instead. @@ -267,19 +273,46 @@ impl Spec { } /// Create a new Spec which conforms to the Frontier-era Morden chain except that it's a NullEngine consensus. - pub fn new_test() -> Self { - Spec::load(include_bytes!("../../res/null_morden.json") as &[u8]).expect("null_morden.json is invalid") - } + pub fn new_test() -> Spec { load_bundled!("null_morden") } /// Create a new Spec which is a NullEngine consensus with a premine of address whose secret is sha3(''). - pub fn new_null() -> Self { - Spec::load(include_bytes!("../../res/null.json") as &[u8]).expect("null.json is invalid") - } + pub fn new_null() -> Spec { load_bundled!("null") } /// Create a new Spec with InstantSeal consensus which does internal sealing (not requiring work). - pub fn new_test_instant() -> Self { - Spec::load(include_bytes!("../../res/instant_seal.json") as &[u8]).expect("instant_seal.json is invalid") - } + pub fn new_test_instant() -> Spec { load_bundled!("instant_seal") } + + /// Create a new Olympic chain spec. + pub fn new_ethereum_olympic() -> Spec { load_bundled!("ethereum/olympic") } + + /// Create a new Frontier mainnet chain spec. + pub fn new_ethereum_frontier() -> Spec { load_bundled!("ethereum/frontier") } + + /// Create a new Frontier mainnet chain spec without the DAO hardfork. + pub fn new_ethereum_classic() -> Spec { load_bundled!("ethereum/classic") } + + /// Create a new Frontier mainnet chain spec without the DAO hardfork. + pub fn new_expanse() -> Spec { load_bundled!("expanse") } + + /// Create a new Frontier chain spec as though it never changes to Homestead. + pub fn new_ethereum_frontier_test() -> Spec { load_bundled!("ethereum/frontier_test") } + + /// Create a new Homestead chain spec as though it never changed from Frontier. + pub fn new_ethereum_homestead_test() -> Spec { load_bundled!("ethereum/homestead_test") } + + /// Create a new Homestead-EIP150 chain spec as though it never changed from Homestead/Frontier. + pub fn new_ethereum_eip150_test() -> Spec { load_bundled!("ethereum/eip150_test") } + + /// Create a new Homestead-EIP150 chain spec as though it never changed from Homestead/Frontier. + pub fn new_ethereum_eip161_test() -> Spec { load_bundled!("ethereum/eip161_test") } + + /// Create a new Frontier/Homestead/DAO chain spec with transition points at #5 and #8. + pub fn new_ethereum_transition_test() -> Spec { load_bundled!("ethereum/transition_test") } + + /// Create a new Frontier main net chain spec without genesis accounts. + pub fn new_ethereum_mainnet_like() -> Spec { load_bundled!("ethereum/frontier_like_test") } + + /// Create a new Morden chain spec. + pub fn new_ethereum_morden() -> Spec { load_bundled!("ethereum/morden") } } #[cfg(test)] diff --git a/ethcore/src/tests/client.rs b/ethcore/src/tests/client.rs index 99b251d66..e6fba0b0a 100644 --- a/ethcore/src/tests/client.rs +++ b/ethcore/src/tests/client.rs @@ -17,7 +17,6 @@ use io::IoChannel; use client::{BlockChainClient, MiningBlockChainClient, Client, ClientConfig, BlockID}; use state::CleanupMode; -use ethereum; use block::IsBlock; use tests::helpers::*; use types::filter::Filter; @@ -50,7 +49,7 @@ fn imports_from_empty() { #[test] fn should_return_registrar() { let dir = RandomTempPath::new(); - let spec = ethereum::new_morden(); + let spec = Spec::new_ethereum_morden(); let db_config = DatabaseConfig::with_columns(::db::NUM_COLUMNS); let client = Client::new( diff --git a/ethcore/src/tests/helpers.rs b/ethcore/src/tests/helpers.rs index 96d5f8366..a6a06608a 100644 --- a/ethcore/src/tests/helpers.rs +++ b/ethcore/src/tests/helpers.rs @@ -27,7 +27,6 @@ use state::*; use evm::Schedule; use engines::Engine; use env_info::EnvInfo; -use ethereum; use ethereum::ethash::EthashParams; use devtools::*; use miner::Miner; @@ -53,7 +52,7 @@ pub struct TestEngine { impl TestEngine { pub fn new(max_depth: usize) -> TestEngine { TestEngine { - engine: ethereum::new_frontier_test().engine, + engine: Spec::new_ethereum_frontier_test().engine, max_depth: max_depth, } } From beaa014543dc7f8010a45634d1ea479e4e7e1c66 Mon Sep 17 00:00:00 2001 From: keorn Date: Fri, 11 Nov 2016 16:59:22 +0000 Subject: [PATCH 08/31] tix doc test --- ethcore/src/miner/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethcore/src/miner/mod.rs b/ethcore/src/miner/mod.rs index a553daffc..fc306c3de 100644 --- a/ethcore/src/miner/mod.rs +++ b/ethcore/src/miner/mod.rs @@ -27,7 +27,7 @@ //! extern crate ethcore_util as util; //! extern crate ethcore; //! use std::env; -//! use spec::Spec; +//! use ethcore::spec::Spec; //! use ethcore::client::{Client, ClientConfig}; //! use ethcore::miner::{Miner, MinerService}; //! From 225d0b02e7d82925450dee260d720b71789582e7 Mon Sep 17 00:00:00 2001 From: keorn Date: Fri, 11 Nov 2016 17:10:47 +0000 Subject: [PATCH 09/31] update parity module --- parity/params.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/parity/params.rs b/parity/params.rs index 5a81fba7f..783c4564a 100644 --- a/parity/params.rs +++ b/parity/params.rs @@ -19,7 +19,6 @@ use std::time::Duration; use util::{Address, U256, version_data}; use util::journaldb::Algorithm; use ethcore::spec::Spec; -use ethcore::ethereum; use ethcore::client::Mode; use ethcore::miner::{GasPricer, GasPriceCalibratorOptions}; use user_defaults::UserDefaults; @@ -59,11 +58,11 @@ impl str::FromStr for SpecType { impl SpecType { pub fn spec(&self) -> Result { match *self { - SpecType::Mainnet => Ok(ethereum::new_frontier()), - SpecType::Testnet => Ok(ethereum::new_morden()), - SpecType::Olympic => Ok(ethereum::new_olympic()), - SpecType::Classic => Ok(ethereum::new_classic()), - SpecType::Expanse => Ok(ethereum::new_expanse()), + SpecType::Mainnet => Ok(Spec::new_ethereum_frontier()), + SpecType::Testnet => Ok(Spec::new_ethereum_morden()), + SpecType::Olympic => Ok(Spec::new_ethereum_olympic()), + SpecType::Classic => Ok(Spec::new_ethereum_classic()), + SpecType::Expanse => Ok(Spec::new_expanse()), SpecType::Custom(ref filename) => { let file = try!(fs::File::open(filename).map_err(|_| "Could not load specification file.")); Spec::load(file) From 87c668ba9cbdc7521a98f4df72a58f525970a242 Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Fri, 11 Nov 2016 18:24:12 +0100 Subject: [PATCH 10/31] test previous code fetch --- ethcore/src/snapshot/account.rs | 2 +- ethcore/src/snapshot/tests/state.rs | 54 +++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/ethcore/src/snapshot/account.rs b/ethcore/src/snapshot/account.rs index 4db023017..327979ce3 100644 --- a/ethcore/src/snapshot/account.rs +++ b/ethcore/src/snapshot/account.rs @@ -225,7 +225,7 @@ mod tests { use util::{Address, FixedHash, H256, HashDB, DBValue}; use rlp::{UntrustedRlp, View}; - use std::collections::{HashSet, HashMap}; + use std::collections::HashSet; use super::{ACC_EMPTY, Account}; diff --git a/ethcore/src/snapshot/tests/state.rs b/ethcore/src/snapshot/tests/state.rs index e1d4df5f9..5257903d5 100644 --- a/ethcore/src/snapshot/tests/state.rs +++ b/ethcore/src/snapshot/tests/state.rs @@ -17,6 +17,7 @@ //! State snapshotting tests. use snapshot::{chunk_state, Progress, StateRebuilder}; +use snapshot::account::Account; use snapshot::io::{PackedReader, PackedWriter, SnapshotReader, SnapshotWriter}; use super::helpers::{compare_dbs, StateProducer}; @@ -28,6 +29,8 @@ use util::memorydb::MemoryDB; use util::Mutex; use devtools::RandomTempPath; +use util::sha3::SHA3_NULL_RLP; + use std::sync::Arc; #[test] @@ -82,3 +85,54 @@ fn snap_and_restore() { compare_dbs(&old_db, new_db.as_hashdb()); } + +#[test] +fn get_code_from_prev_chunk() { + use std::collections::HashSet; + use rlp::{RlpStream, Stream}; + use util::{HashDB, H256, FixedHash, U256, Hashable}; + + use account_db::{AccountDBMut, AccountDB}; + + let code = b"this is definitely code"; + let mut used_code = HashSet::new(); + let mut acc_stream = RlpStream::new_list(4); + acc_stream.append(&U256::default()) + .append(&U256::default()) + .append(&SHA3_NULL_RLP) + .append(&code.sha3()); + + let (h1, h2) = (H256::random(), H256::random()); + + // two accounts with the same code, one per chunk. + // first one will have code inlined, + // second will just have its hash. + let thin_rlp = acc_stream.out(); + let acc1 = Account::from_thin_rlp(&thin_rlp); + let acc2 = Account::from_thin_rlp(&thin_rlp); + + let mut make_chunk = |acc: Account, hash| { + let mut db = MemoryDB::new(); + AccountDBMut::from_hash(&mut db, hash).insert(&code[..]); + + let fat_rlp = acc.to_fat_rlp(&AccountDB::from_hash(&db, hash), &mut used_code).unwrap(); + + let mut stream = RlpStream::new_list(1); + stream.begin_list(2).append(&hash).append_raw(&fat_rlp, 1); + stream.out() + }; + + let chunk1 = make_chunk(acc1, h1); + let chunk2 = make_chunk(acc2, h2); + + let db_path = RandomTempPath::create_dir(); + let db_cfg = DatabaseConfig::with_columns(::db::NUM_COLUMNS); + let new_db = Arc::new(Database::open(&db_cfg, &db_path.to_string_lossy()).unwrap()); + + let mut rebuilder = StateRebuilder::new(new_db, Algorithm::Archive); + + rebuilder.feed(&chunk1).unwrap(); + rebuilder.feed(&chunk2).unwrap(); + + rebuilder.check_missing().unwrap(); +} \ No newline at end of file From e63b7e51fb6e02b14420c80e6a2a797d59d74ec4 Mon Sep 17 00:00:00 2001 From: keorn Date: Fri, 11 Nov 2016 17:26:41 +0000 Subject: [PATCH 11/31] update instant_seal schedule --- ethcore/src/engines/instant_seal.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ethcore/src/engines/instant_seal.rs b/ethcore/src/engines/instant_seal.rs index acead19b4..75fae4d81 100644 --- a/ethcore/src/engines/instant_seal.rs +++ b/ethcore/src/engines/instant_seal.rs @@ -55,7 +55,7 @@ impl Engine for InstantSeal { } fn schedule(&self, _env_info: &EnvInfo) -> Schedule { - Schedule::new_homestead() + Schedule::new_post_eip150(false, false, false) } fn is_sealer(&self, _author: &Address) -> Option { Some(true) } @@ -79,7 +79,7 @@ mod tests { let tap = AccountProvider::transient_provider(); let addr = tap.insert_account("".sha3(), "").unwrap(); - let spec = Spec::new_test_instant(); + let spec = Spec::new_instant(); let engine = &*spec.engine; let genesis_header = spec.genesis_header(); let mut db_result = get_temp_state_db(); @@ -95,7 +95,7 @@ mod tests { #[test] fn instant_cant_verify() { - let engine = Spec::new_test_instant().engine; + let engine = Spec::new_instant().engine; let mut header: Header = Header::default(); assert!(engine.verify_block_basic(&header, None).is_ok()); From 53258cca6cbeca1ef0e78b8418674b53d8953a1a Mon Sep 17 00:00:00 2001 From: keorn Date: Fri, 11 Nov 2016 17:27:20 +0000 Subject: [PATCH 12/31] add new dev spec --- ethcore/src/miner/miner.rs | 2 +- ethcore/src/spec/spec.rs | 2 +- parity/params.rs | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index 19a2b9a10..af4677cf3 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -1251,7 +1251,7 @@ mod tests { #[test] fn internal_seals_without_work() { - let miner = Miner::with_spec(&Spec::new_test_instant()); + let miner = Miner::with_spec(&Spec::new_instant()); let c = generate_dummy_client(2); let client = c.reference().as_ref(); diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index 786b264ab..d8b2f72fc 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -279,7 +279,7 @@ impl Spec { pub fn new_null() -> Spec { load_bundled!("null") } /// Create a new Spec with InstantSeal consensus which does internal sealing (not requiring work). - pub fn new_test_instant() -> Spec { load_bundled!("instant_seal") } + pub fn new_instant() -> Spec { load_bundled!("instant_seal") } /// Create a new Olympic chain spec. pub fn new_ethereum_olympic() -> Spec { load_bundled!("ethereum/olympic") } diff --git a/parity/params.rs b/parity/params.rs index 783c4564a..0a24cc7dd 100644 --- a/parity/params.rs +++ b/parity/params.rs @@ -30,6 +30,7 @@ pub enum SpecType { Olympic, Classic, Expanse, + Dev, Custom(String), } @@ -49,6 +50,7 @@ impl str::FromStr for SpecType { "morden" | "testnet" => SpecType::Testnet, "olympic" => SpecType::Olympic, "expanse" => SpecType::Expanse, + "dev" => SpecType::Dev, other => SpecType::Custom(other.into()), }; Ok(spec) @@ -63,6 +65,7 @@ impl SpecType { SpecType::Olympic => Ok(Spec::new_ethereum_olympic()), SpecType::Classic => Ok(Spec::new_ethereum_classic()), SpecType::Expanse => Ok(Spec::new_expanse()), + SpecType::Dev => Ok(Spec::new_instant()), SpecType::Custom(ref filename) => { let file = try!(fs::File::open(filename).map_err(|_| "Could not load specification file.")); Spec::load(file) From 4a653942696a2115e8679c1b4ec6a62df8ff29eb Mon Sep 17 00:00:00 2001 From: keorn Date: Fri, 11 Nov 2016 18:38:44 +0000 Subject: [PATCH 13/31] change instant spec, update doc --- ethcore/res/instant_seal.json | 2 +- parity/cli/usage.txt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ethcore/res/instant_seal.json b/ethcore/res/instant_seal.json index b7c29a01f..eefe7431b 100644 --- a/ethcore/res/instant_seal.json +++ b/ethcore/res/instant_seal.json @@ -28,6 +28,6 @@ "0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, - "102e61f5d8f9bc71d0ad4a084df4e65e05ce0e1c": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" } + "0x00a329c0648769a73afac7f9381e08fb43dbea72": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" } } } diff --git a/parity/cli/usage.txt b/parity/cli/usage.txt index ba27c4902..89603d311 100644 --- a/parity/cli/usage.txt +++ b/parity/cli/usage.txt @@ -32,8 +32,8 @@ Operating Options: (default: {flag_mode_alarm}). --chain CHAIN Specify the blockchain type. CHAIN may be either a JSON chain specification file or olympic, frontier, - homestead, mainnet, morden, classic, expanse or - testnet (default: {flag_chain}). + homestead, mainnet, morden, classic, expanse, + testnet or dev (default: {flag_chain}). -d --db-path PATH Specify the database & configuration directory path (default: {flag_db_path}). --keys-path PATH Specify the path for JSON key files to be found From cc39b245990dacfa0eeded56971a52ec44bb9778 Mon Sep 17 00:00:00 2001 From: keorn Date: Fri, 11 Nov 2016 18:41:04 +0000 Subject: [PATCH 14/31] update chain name --- ethcore/res/instant_seal.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethcore/res/instant_seal.json b/ethcore/res/instant_seal.json index eefe7431b..2d5b38659 100644 --- a/ethcore/res/instant_seal.json +++ b/ethcore/res/instant_seal.json @@ -1,5 +1,5 @@ { - "name": "TestInstantSeal", + "name": "DevelopmentChain", "engine": { "InstantSeal": null }, From ea9c479fffcb904f4d2e75524f503bd5150e8b70 Mon Sep 17 00:00:00 2001 From: keorn Date: Fri, 11 Nov 2016 18:57:57 +0000 Subject: [PATCH 15/31] update json_tests --- ethcore/src/json_tests/chain.rs | 12 ++++++------ ethcore/src/json_tests/state.rs | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/ethcore/src/json_tests/chain.rs b/ethcore/src/json_tests/chain.rs index b50241199..1146004b3 100644 --- a/ethcore/src/json_tests/chain.rs +++ b/ethcore/src/json_tests/chain.rs @@ -17,7 +17,7 @@ use super::test_common::*; use client::{BlockChainClient, Client, ClientConfig}; use block::Block; -use ethereum; +use spec::Spec; use tests::helpers::*; use devtools::*; use spec::Genesis; @@ -46,11 +46,11 @@ pub fn json_chain_test(json_data: &[u8], era: ChainEra) -> Vec { let genesis = Genesis::from(blockchain.genesis()); let state = From::from(blockchain.pre_state.clone()); let mut spec = match era { - ChainEra::Frontier => ethereum::new_frontier_test(), - ChainEra::Homestead => ethereum::new_homestead_test(), - ChainEra::Eip150 => ethereum::new_eip150_test(), - ChainEra::Eip161 => ethereum::new_eip161_test(), - ChainEra::TransitionTest => ethereum::new_transition_test(), + ChainEra::Frontier => Spec::new_ethereum_frontier_test(), + ChainEra::Homestead => Spec::new_ethereum_homestead_test(), + ChainEra::Eip150 => Spec::new_ethereum_eip150_test(), + ChainEra::Eip161 => Spec::new_ethereum_eip161_test(), + ChainEra::TransitionTest => Spec::new_ethereum_transition_test(), }; spec.set_genesis_state(state); spec.overwrite_genesis_params(genesis); diff --git a/ethcore/src/json_tests/state.rs b/ethcore/src/json_tests/state.rs index bf84d50ee..712b47feb 100644 --- a/ethcore/src/json_tests/state.rs +++ b/ethcore/src/json_tests/state.rs @@ -18,7 +18,7 @@ use super::test_common::*; use tests::helpers::*; use pod_state::{self, PodState}; use log_entry::LogEntry; -use ethereum; +use spec::Spec; use ethjson; pub fn json_chain_test(json_data: &[u8], era: ChainEra) -> Vec { @@ -26,11 +26,11 @@ pub fn json_chain_test(json_data: &[u8], era: ChainEra) -> Vec { let tests = ethjson::state::Test::load(json_data).unwrap(); let mut failed = Vec::new(); let engine = match era { - ChainEra::Frontier => ethereum::new_mainnet_like().engine, - ChainEra::Homestead => ethereum::new_homestead_test().engine, - ChainEra::Eip150 => ethereum::new_eip150_test().engine, - ChainEra::Eip161 => ethereum::new_eip161_test().engine, - ChainEra::TransitionTest => ethereum::new_transition_test().engine, + ChainEra::Frontier => Spec::new_ethereum_mainnet_like().engine, + ChainEra::Homestead => Spec::new_ethereum_homestead_test().engine, + ChainEra::Eip150 => Spec::new_ethereum_eip150_test().engine, + ChainEra::Eip161 => Spec::new_ethereum_eip161_test().engine, + ChainEra::TransitionTest => Spec::new_ethereum_transition_test().engine, }; for (name, test) in tests.into_iter() { From aa296c3c0dee7323b86be3c6b56da70e1ee10e5f Mon Sep 17 00:00:00 2001 From: keorn Date: Fri, 11 Nov 2016 19:12:32 +0000 Subject: [PATCH 16/31] update rpc tests --- rpc/src/v1/tests/eth.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/rpc/src/v1/tests/eth.rs b/rpc/src/v1/tests/eth.rs index 2f5131f32..38597343e 100644 --- a/rpc/src/v1/tests/eth.rs +++ b/rpc/src/v1/tests/eth.rs @@ -23,7 +23,6 @@ use ethcore::ids::BlockID; use ethcore::spec::{Genesis, Spec}; use ethcore::block::Block; use ethcore::views::BlockView; -use ethcore::ethereum; use ethcore::miner::{MinerOptions, Banning, GasPricer, MinerService, ExternalMiner, Miner, PendingSet, PrioritizationStrategy, GasLimit}; use ethcore::account_provider::AccountProvider; use devtools::RandomTempPath; @@ -79,7 +78,7 @@ fn snapshot_service() -> Arc { fn make_spec(chain: &BlockChain) -> Spec { let genesis = Genesis::from(chain.genesis()); - let mut spec = ethereum::new_frontier_test(); + let mut spec = Spec::new_ethereum_frontier_test(); let state = chain.pre_state.clone().into(); spec.set_genesis_state(state); spec.overwrite_genesis_params(genesis); From 2d4b4cf5c90706a510fad8a4c24e62754afced88 Mon Sep 17 00:00:00 2001 From: keorn Date: Mon, 14 Nov 2016 10:04:34 +0000 Subject: [PATCH 17/31] revert moves to Spec --- ethcore/res/{ => ethereum}/expanse.json | 0 ethcore/src/ethereum/ethash.rs | 38 ++++++++++---------- ethcore/src/ethereum/mod.rs | 47 ++++++++++++++++++++++--- ethcore/src/json_tests/chain.rs | 12 +++---- ethcore/src/json_tests/state.rs | 12 +++---- ethcore/src/miner/mod.rs | 4 +-- ethcore/src/spec/spec.rs | 33 ----------------- ethcore/src/tests/client.rs | 3 +- ethcore/src/tests/helpers.rs | 3 +- parity/params.rs | 11 +++--- rpc/src/v1/tests/eth.rs | 3 +- 11 files changed, 88 insertions(+), 78 deletions(-) rename ethcore/res/{ => ethereum}/expanse.json (100%) diff --git a/ethcore/res/expanse.json b/ethcore/res/ethereum/expanse.json similarity index 100% rename from ethcore/res/expanse.json rename to ethcore/res/ethereum/expanse.json diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index 2c7187b09..6436e3531 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -423,13 +423,13 @@ mod tests { use env_info::EnvInfo; use error::{BlockError, Error}; use header::Header; - use spec::Spec; + use super::super::{new_morden, new_homestead_test}; use super::{Ethash, EthashParams}; use rlp; #[test] fn on_close_block() { - let spec = Spec::new_ethereum_morden(); + let spec = new_morden(); let engine = &*spec.engine; let genesis_header = spec.genesis_header(); let mut db_result = get_temp_state_db(); @@ -443,7 +443,7 @@ mod tests { #[test] fn on_close_block_with_uncle() { - let spec = Spec::new_ethereum_morden(); + let spec = new_morden(); let engine = &*spec.engine; let genesis_header = spec.genesis_header(); let mut db_result = get_temp_state_db(); @@ -463,14 +463,14 @@ mod tests { #[test] fn has_valid_metadata() { - let engine = Spec::new_ethereum_morden().engine; + let engine = new_morden().engine; assert!(!engine.name().is_empty()); assert!(engine.version().major >= 1); } #[test] fn can_return_schedule() { - let engine = Spec::new_ethereum_morden().engine; + let engine = new_morden().engine; let schedule = engine.schedule(&EnvInfo { number: 10000000, author: 0.into(), @@ -498,8 +498,8 @@ mod tests { #[test] fn can_do_seal_verification_fail() { - let engine = Spec::new_ethereum_morden().engine; - //let engine = Ethash::new_test(Spec::new_ethereum_morden()); + let engine = new_morden().engine; + //let engine = Ethash::new_test(new_morden()); let header: Header = Header::default(); let verify_result = engine.verify_block_basic(&header, None); @@ -513,7 +513,7 @@ mod tests { #[test] fn can_do_difficulty_verification_fail() { - let engine = Spec::new_ethereum_morden().engine; + let engine = new_morden().engine; let mut header: Header = Header::default(); header.set_seal(vec![rlp::encode(&H256::zero()).to_vec(), rlp::encode(&H64::zero()).to_vec()]); @@ -528,7 +528,7 @@ mod tests { #[test] fn can_do_proof_of_work_verification_fail() { - let engine = Spec::new_ethereum_morden().engine; + let engine = new_morden().engine; let mut header: Header = Header::default(); header.set_seal(vec![rlp::encode(&H256::zero()).to_vec(), rlp::encode(&H64::zero()).to_vec()]); header.set_difficulty(U256::from_str("ffffffffffffffffffffffffffffffffffffffffffffaaaaaaaaaaaaaaaaaaaa").unwrap()); @@ -544,7 +544,7 @@ mod tests { #[test] fn can_do_seal_unordered_verification_fail() { - let engine = Spec::new_ethereum_morden().engine; + let engine = new_morden().engine; let header: Header = Header::default(); let verify_result = engine.verify_block_unordered(&header, None); @@ -558,7 +558,7 @@ mod tests { #[test] fn can_do_seal256_verification_fail() { - let engine = Spec::new_ethereum_morden().engine; + let engine = new_morden().engine; let mut header: Header = Header::default(); header.set_seal(vec![rlp::encode(&H256::zero()).to_vec(), rlp::encode(&H64::zero()).to_vec()]); let verify_result = engine.verify_block_unordered(&header, None); @@ -572,7 +572,7 @@ mod tests { #[test] fn can_do_proof_of_work_unordered_verification_fail() { - let engine = Spec::new_ethereum_morden().engine; + let engine = new_morden().engine; let mut header: Header = Header::default(); header.set_seal(vec![rlp::encode(&H256::from("b251bd2e0283d0658f2cadfdc8ca619b5de94eca5742725e2e757dd13ed7503d")).to_vec(), rlp::encode(&H64::zero()).to_vec()]); header.set_difficulty(U256::from_str("ffffffffffffffffffffffffffffffffffffffffffffaaaaaaaaaaaaaaaaaaaa").unwrap()); @@ -588,7 +588,7 @@ mod tests { #[test] fn can_verify_block_family_genesis_fail() { - let engine = Spec::new_ethereum_morden().engine; + let engine = new_morden().engine; let header: Header = Header::default(); let parent_header: Header = Header::default(); @@ -603,7 +603,7 @@ mod tests { #[test] fn can_verify_block_family_difficulty_fail() { - let engine = Spec::new_ethereum_morden().engine; + let engine = new_morden().engine; let mut header: Header = Header::default(); header.set_number(2); let mut parent_header: Header = Header::default(); @@ -620,7 +620,7 @@ mod tests { #[test] fn can_verify_block_family_gas_fail() { - let engine = Spec::new_ethereum_morden().engine; + let engine = new_morden().engine; let mut header: Header = Header::default(); header.set_number(2); header.set_difficulty(U256::from_str("0000000000000000000000000000000000000000000000000000000000020000").unwrap()); @@ -648,7 +648,7 @@ mod tests { #[test] fn difficulty_frontier() { - let spec = Spec::new_ethereum_homestead_test(); + let spec = new_homestead_test(); let ethparams = get_default_ethash_params(); let ethash = Ethash::new(spec.params, ethparams, BTreeMap::new()); @@ -666,7 +666,7 @@ mod tests { #[test] fn difficulty_homestead() { - let spec = Spec::new_ethereum_homestead_test(); + let spec = new_homestead_test(); let ethparams = get_default_ethash_params(); let ethash = Ethash::new(spec.params, ethparams, BTreeMap::new()); @@ -684,7 +684,7 @@ mod tests { #[test] fn difficulty_classic_bomb_delay() { - let spec = Spec::new_ethereum_homestead_test(); + let spec = new_homestead_test(); let ethparams = EthashParams { ecip1010_pause_transition: 3000000, ..get_default_ethash_params() @@ -717,7 +717,7 @@ mod tests { #[test] fn test_difficulty_bomb_continue() { - let spec = Spec::new_ethereum_homestead_test(); + let spec = new_homestead_test(); let ethparams = EthashParams { ecip1010_pause_transition: 3000000, ecip1010_continue_transition: 5000000, diff --git a/ethcore/src/ethereum/mod.rs b/ethcore/src/ethereum/mod.rs index 3df130a8d..253a12372 100644 --- a/ethcore/src/ethereum/mod.rs +++ b/ethcore/src/ethereum/mod.rs @@ -27,17 +27,56 @@ pub mod denominations; pub use self::ethash::{Ethash}; pub use self::denominations::*; +use super::spec::*; + +fn load(b: &[u8]) -> Spec { + Spec::load(b).expect("chain spec is invalid") +} + +/// Create a new Olympic chain spec. +pub fn new_olympic() -> Spec { load(include_bytes!("../../res/ethereum/olympic.json")) } + +/// Create a new Frontier mainnet chain spec. +pub fn new_frontier() -> Spec { load(include_bytes!("../../res/ethereum/frontier.json")) } + +/// Create a new Frontier mainnet chain spec without the DAO hardfork. +pub fn new_classic() -> Spec { load(include_bytes!("../../res/ethereum/classic.json")) } + +/// Create a new Frontier mainnet chain spec without the DAO hardfork. +pub fn new_expanse() -> Spec { load(include_bytes!("../../res/ethereum/expanse.json")) } + +/// Create a new Frontier chain spec as though it never changes to Homestead. +pub fn new_frontier_test() -> Spec { load(include_bytes!("../../res/ethereum/frontier_test.json")) } + +/// Create a new Homestead chain spec as though it never changed from Frontier. +pub fn new_homestead_test() -> Spec { load(include_bytes!("../../res/ethereum/homestead_test.json")) } + +/// Create a new Homestead-EIP150 chain spec as though it never changed from Homestead/Frontier. +pub fn new_eip150_test() -> Spec { load(include_bytes!("../../res/ethereum/eip150_test.json")) } + +/// Create a new Homestead-EIP150 chain spec as though it never changed from Homestead/Frontier. +pub fn new_eip161_test() -> Spec { load(include_bytes!("../../res/ethereum/eip161_test.json")) } + +/// Create a new Frontier/Homestead/DAO chain spec with transition points at #5 and #8. +pub fn new_transition_test() -> Spec { load(include_bytes!("../../res/ethereum/transition_test.json")) } + +/// Create a new Frontier main net chain spec without genesis accounts. +pub fn new_mainnet_like() -> Spec { load(include_bytes!("../../res/ethereum/frontier_like_test.json")) } + +/// Create a new Morden chain spec. +pub fn new_morden() -> Spec { load(include_bytes!("../../res/ethereum/morden.json")) } + #[cfg(test)] mod tests { use util::*; use state::*; + use super::*; use tests::helpers::*; - use spec::Spec; use views::BlockView; #[test] fn ensure_db_good() { - let spec = Spec::new_ethereum_morden(); + let spec = new_morden(); let engine = &spec.engine; let genesis_header = spec.genesis_header(); let mut db_result = get_temp_state_db(); @@ -54,7 +93,7 @@ mod tests { #[test] fn morden() { - let morden = Spec::new_ethereum_morden(); + let morden = new_morden(); assert_eq!(morden.state_root(), "f3f4696bbf3b3b07775128eb7a3763279a394e382130f27c21e70233e04946a9".into()); let genesis = morden.genesis_block(); @@ -65,7 +104,7 @@ mod tests { #[test] fn frontier() { - let frontier = Spec::new_ethereum_frontier(); + let frontier = new_frontier(); assert_eq!(frontier.state_root(), "d7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544".into()); let genesis = frontier.genesis_block(); diff --git a/ethcore/src/json_tests/chain.rs b/ethcore/src/json_tests/chain.rs index 1146004b3..b50241199 100644 --- a/ethcore/src/json_tests/chain.rs +++ b/ethcore/src/json_tests/chain.rs @@ -17,7 +17,7 @@ use super::test_common::*; use client::{BlockChainClient, Client, ClientConfig}; use block::Block; -use spec::Spec; +use ethereum; use tests::helpers::*; use devtools::*; use spec::Genesis; @@ -46,11 +46,11 @@ pub fn json_chain_test(json_data: &[u8], era: ChainEra) -> Vec { let genesis = Genesis::from(blockchain.genesis()); let state = From::from(blockchain.pre_state.clone()); let mut spec = match era { - ChainEra::Frontier => Spec::new_ethereum_frontier_test(), - ChainEra::Homestead => Spec::new_ethereum_homestead_test(), - ChainEra::Eip150 => Spec::new_ethereum_eip150_test(), - ChainEra::Eip161 => Spec::new_ethereum_eip161_test(), - ChainEra::TransitionTest => Spec::new_ethereum_transition_test(), + ChainEra::Frontier => ethereum::new_frontier_test(), + ChainEra::Homestead => ethereum::new_homestead_test(), + ChainEra::Eip150 => ethereum::new_eip150_test(), + ChainEra::Eip161 => ethereum::new_eip161_test(), + ChainEra::TransitionTest => ethereum::new_transition_test(), }; spec.set_genesis_state(state); spec.overwrite_genesis_params(genesis); diff --git a/ethcore/src/json_tests/state.rs b/ethcore/src/json_tests/state.rs index 712b47feb..bf84d50ee 100644 --- a/ethcore/src/json_tests/state.rs +++ b/ethcore/src/json_tests/state.rs @@ -18,7 +18,7 @@ use super::test_common::*; use tests::helpers::*; use pod_state::{self, PodState}; use log_entry::LogEntry; -use spec::Spec; +use ethereum; use ethjson; pub fn json_chain_test(json_data: &[u8], era: ChainEra) -> Vec { @@ -26,11 +26,11 @@ pub fn json_chain_test(json_data: &[u8], era: ChainEra) -> Vec { let tests = ethjson::state::Test::load(json_data).unwrap(); let mut failed = Vec::new(); let engine = match era { - ChainEra::Frontier => Spec::new_ethereum_mainnet_like().engine, - ChainEra::Homestead => Spec::new_ethereum_homestead_test().engine, - ChainEra::Eip150 => Spec::new_ethereum_eip150_test().engine, - ChainEra::Eip161 => Spec::new_ethereum_eip161_test().engine, - ChainEra::TransitionTest => Spec::new_ethereum_transition_test().engine, + ChainEra::Frontier => ethereum::new_mainnet_like().engine, + ChainEra::Homestead => ethereum::new_homestead_test().engine, + ChainEra::Eip150 => ethereum::new_eip150_test().engine, + ChainEra::Eip161 => ethereum::new_eip161_test().engine, + ChainEra::TransitionTest => ethereum::new_transition_test().engine, }; for (name, test) in tests.into_iter() { diff --git a/ethcore/src/miner/mod.rs b/ethcore/src/miner/mod.rs index fc306c3de..da93dc0b7 100644 --- a/ethcore/src/miner/mod.rs +++ b/ethcore/src/miner/mod.rs @@ -27,12 +27,12 @@ //! extern crate ethcore_util as util; //! extern crate ethcore; //! use std::env; -//! use ethcore::spec::Spec; +//! use ethcore::ethereum; //! use ethcore::client::{Client, ClientConfig}; //! use ethcore::miner::{Miner, MinerService}; //! //! fn main() { -//! let miner: Miner = Miner::with_spec(&Spec::new_ethereum_frontier()); +//! let miner: Miner = Miner::with_spec(ðereum::new_frontier()); //! // get status //! assert_eq!(miner.status().transactions_in_pending_queue, 0); //! diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index d8b2f72fc..22eb13850 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -280,39 +280,6 @@ impl Spec { /// Create a new Spec with InstantSeal consensus which does internal sealing (not requiring work). pub fn new_instant() -> Spec { load_bundled!("instant_seal") } - - /// Create a new Olympic chain spec. - pub fn new_ethereum_olympic() -> Spec { load_bundled!("ethereum/olympic") } - - /// Create a new Frontier mainnet chain spec. - pub fn new_ethereum_frontier() -> Spec { load_bundled!("ethereum/frontier") } - - /// Create a new Frontier mainnet chain spec without the DAO hardfork. - pub fn new_ethereum_classic() -> Spec { load_bundled!("ethereum/classic") } - - /// Create a new Frontier mainnet chain spec without the DAO hardfork. - pub fn new_expanse() -> Spec { load_bundled!("expanse") } - - /// Create a new Frontier chain spec as though it never changes to Homestead. - pub fn new_ethereum_frontier_test() -> Spec { load_bundled!("ethereum/frontier_test") } - - /// Create a new Homestead chain spec as though it never changed from Frontier. - pub fn new_ethereum_homestead_test() -> Spec { load_bundled!("ethereum/homestead_test") } - - /// Create a new Homestead-EIP150 chain spec as though it never changed from Homestead/Frontier. - pub fn new_ethereum_eip150_test() -> Spec { load_bundled!("ethereum/eip150_test") } - - /// Create a new Homestead-EIP150 chain spec as though it never changed from Homestead/Frontier. - pub fn new_ethereum_eip161_test() -> Spec { load_bundled!("ethereum/eip161_test") } - - /// Create a new Frontier/Homestead/DAO chain spec with transition points at #5 and #8. - pub fn new_ethereum_transition_test() -> Spec { load_bundled!("ethereum/transition_test") } - - /// Create a new Frontier main net chain spec without genesis accounts. - pub fn new_ethereum_mainnet_like() -> Spec { load_bundled!("ethereum/frontier_like_test") } - - /// Create a new Morden chain spec. - pub fn new_ethereum_morden() -> Spec { load_bundled!("ethereum/morden") } } #[cfg(test)] diff --git a/ethcore/src/tests/client.rs b/ethcore/src/tests/client.rs index e6fba0b0a..99b251d66 100644 --- a/ethcore/src/tests/client.rs +++ b/ethcore/src/tests/client.rs @@ -17,6 +17,7 @@ use io::IoChannel; use client::{BlockChainClient, MiningBlockChainClient, Client, ClientConfig, BlockID}; use state::CleanupMode; +use ethereum; use block::IsBlock; use tests::helpers::*; use types::filter::Filter; @@ -49,7 +50,7 @@ fn imports_from_empty() { #[test] fn should_return_registrar() { let dir = RandomTempPath::new(); - let spec = Spec::new_ethereum_morden(); + let spec = ethereum::new_morden(); let db_config = DatabaseConfig::with_columns(::db::NUM_COLUMNS); let client = Client::new( diff --git a/ethcore/src/tests/helpers.rs b/ethcore/src/tests/helpers.rs index a6a06608a..96d5f8366 100644 --- a/ethcore/src/tests/helpers.rs +++ b/ethcore/src/tests/helpers.rs @@ -27,6 +27,7 @@ use state::*; use evm::Schedule; use engines::Engine; use env_info::EnvInfo; +use ethereum; use ethereum::ethash::EthashParams; use devtools::*; use miner::Miner; @@ -52,7 +53,7 @@ pub struct TestEngine { impl TestEngine { pub fn new(max_depth: usize) -> TestEngine { TestEngine { - engine: Spec::new_ethereum_frontier_test().engine, + engine: ethereum::new_frontier_test().engine, max_depth: max_depth, } } diff --git a/parity/params.rs b/parity/params.rs index 0a24cc7dd..54e08da32 100644 --- a/parity/params.rs +++ b/parity/params.rs @@ -19,6 +19,7 @@ use std::time::Duration; use util::{Address, U256, version_data}; use util::journaldb::Algorithm; use ethcore::spec::Spec; +use ethcore::ethereum; use ethcore::client::Mode; use ethcore::miner::{GasPricer, GasPriceCalibratorOptions}; use user_defaults::UserDefaults; @@ -60,11 +61,11 @@ impl str::FromStr for SpecType { impl SpecType { pub fn spec(&self) -> Result { match *self { - SpecType::Mainnet => Ok(Spec::new_ethereum_frontier()), - SpecType::Testnet => Ok(Spec::new_ethereum_morden()), - SpecType::Olympic => Ok(Spec::new_ethereum_olympic()), - SpecType::Classic => Ok(Spec::new_ethereum_classic()), - SpecType::Expanse => Ok(Spec::new_expanse()), + SpecType::Mainnet => Ok(ethereum::new_frontier()), + SpecType::Testnet => Ok(ethereum::new_morden()), + SpecType::Olympic => Ok(ethereum::new_olympic()), + SpecType::Classic => Ok(ethereum::new_classic()), + SpecType::Expanse => Ok(ethereum::new_expanse()), SpecType::Dev => Ok(Spec::new_instant()), SpecType::Custom(ref filename) => { let file = try!(fs::File::open(filename).map_err(|_| "Could not load specification file.")); diff --git a/rpc/src/v1/tests/eth.rs b/rpc/src/v1/tests/eth.rs index 38597343e..2f5131f32 100644 --- a/rpc/src/v1/tests/eth.rs +++ b/rpc/src/v1/tests/eth.rs @@ -23,6 +23,7 @@ use ethcore::ids::BlockID; use ethcore::spec::{Genesis, Spec}; use ethcore::block::Block; use ethcore::views::BlockView; +use ethcore::ethereum; use ethcore::miner::{MinerOptions, Banning, GasPricer, MinerService, ExternalMiner, Miner, PendingSet, PrioritizationStrategy, GasLimit}; use ethcore::account_provider::AccountProvider; use devtools::RandomTempPath; @@ -78,7 +79,7 @@ fn snapshot_service() -> Arc { fn make_spec(chain: &BlockChain) -> Spec { let genesis = Genesis::from(chain.genesis()); - let mut spec = Spec::new_ethereum_frontier_test(); + let mut spec = ethereum::new_frontier_test(); let state = chain.pre_state.clone().into(); spec.set_genesis_state(state); spec.overwrite_genesis_params(genesis); From e9e947583091f0fd64b747ec25fc7fa71d2d9572 Mon Sep 17 00:00:00 2001 From: Jannis R Date: Mon, 14 Nov 2016 11:39:36 +0100 Subject: [PATCH 18/31] CopyToClipboard: remove tooltip --- js/src/ui/CopyToClipboard/copyToClipboard.css | 4 ++++ js/src/ui/CopyToClipboard/copyToClipboard.js | 9 ++------- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/js/src/ui/CopyToClipboard/copyToClipboard.css b/js/src/ui/CopyToClipboard/copyToClipboard.css index acf2bb204..0c511ba45 100644 --- a/js/src/ui/CopyToClipboard/copyToClipboard.css +++ b/js/src/ui/CopyToClipboard/copyToClipboard.css @@ -15,6 +15,10 @@ /* along with Parity. If not, see . */ +.wrapper { + display: inline-block; +} + .data { font-family: monospace; } diff --git a/js/src/ui/CopyToClipboard/copyToClipboard.js b/js/src/ui/CopyToClipboard/copyToClipboard.js index c78038617..568520b09 100644 --- a/js/src/ui/CopyToClipboard/copyToClipboard.js +++ b/js/src/ui/CopyToClipboard/copyToClipboard.js @@ -28,7 +28,6 @@ import styles from './copyToClipboard.css'; export default class CopyToClipboard extends Component { static propTypes = { data: PropTypes.string.isRequired, - label: PropTypes.string, onCopy: PropTypes.func, size: PropTypes.number, // in px cooldown: PropTypes.number // in ms @@ -36,7 +35,6 @@ export default class CopyToClipboard extends Component { static defaultProps = { className: '', - label: 'copy to clipboard', onCopy: () => {}, size: 16, cooldown: 1000 @@ -55,12 +53,12 @@ export default class CopyToClipboard extends Component { } render () { - const { data, label, size } = this.props; + const { data, size } = this.props; const { copied } = this.state; return ( -
+
From d02afc0e409b769ab487f7cc411edb62a8d00bf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Mon, 14 Nov 2016 13:21:08 +0100 Subject: [PATCH 19/31] Beta -> Stable --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 80bf9ba10..6f3fd9933 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,7 +17,7 @@ matrix: include: - rust: stable env: RUN_TESTS="true" TEST_OPTIONS="--no-release" - - rust: beta + - rust: stable env: RUN_COVERAGE="true" - rust: stable env: RUN_DOCS="true" From 48b2252029c62c9f1617badabefb611536d5bc2a Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Mon, 14 Nov 2016 15:16:57 +0100 Subject: [PATCH 20/31] Swap from base to decimals --- .../tokenreg/Actions/Register/register.js | 10 +++++----- js/src/dapps/tokenreg/Actions/actions.js | 3 ++- js/src/dapps/tokenreg/Inputs/validation.js | 18 ++++++++++++++++++ js/src/dapps/tokenreg/Tokens/Token/token.js | 4 ++-- 4 files changed, 27 insertions(+), 8 deletions(-) diff --git a/js/src/dapps/tokenreg/Actions/Register/register.js b/js/src/dapps/tokenreg/Actions/Register/register.js index 8ae042494..a008ce84f 100644 --- a/js/src/dapps/tokenreg/Actions/Register/register.js +++ b/js/src/dapps/tokenreg/Actions/Register/register.js @@ -21,7 +21,7 @@ import { Dialog, FlatButton } from 'material-ui'; import AccountSelector from '../../Accounts/AccountSelector'; import InputText from '../../Inputs/Text'; -import { TOKEN_ADDRESS_TYPE, TLA_TYPE, UINT_TYPE, STRING_TYPE } from '../../Inputs/validation'; +import { TOKEN_ADDRESS_TYPE, TLA_TYPE, DECIMAL_TYPE, STRING_TYPE } from '../../Inputs/validation'; import styles from '../actions.css'; @@ -41,11 +41,11 @@ const initState = { floatingLabelText: 'Token TLA', hintText: 'The token short name (3 characters)' }, - base: { + decimals: { ...defaultField, - type: UINT_TYPE, - floatingLabelText: 'Token Base', - hintText: 'The token precision' + type: DECIMAL_TYPE, + floatingLabelText: 'Token Decimals', + hintText: 'The number of decimals (0-18)' }, name: { ...defaultField, diff --git a/js/src/dapps/tokenreg/Actions/actions.js b/js/src/dapps/tokenreg/Actions/actions.js index 0f3390ea4..1c6703f77 100644 --- a/js/src/dapps/tokenreg/Actions/actions.js +++ b/js/src/dapps/tokenreg/Actions/actions.js @@ -47,7 +47,8 @@ export const registerToken = (tokenData) => (dispatch, getState) => { const contractInstance = state.status.contract.instance; const fee = state.status.contract.fee; - const { address, base, name, tla } = tokenData; + const { address, decimals, name, tla } = tokenData; + const base = Math.pow(10, decimals); dispatch(setRegisterSending(true)); diff --git a/js/src/dapps/tokenreg/Inputs/validation.js b/js/src/dapps/tokenreg/Inputs/validation.js index 38eba5ef1..fd394b4ec 100644 --- a/js/src/dapps/tokenreg/Inputs/validation.js +++ b/js/src/dapps/tokenreg/Inputs/validation.js @@ -32,6 +32,7 @@ export const SIMPLE_TOKEN_ADDRESS_TYPE = 'SIMPLE_TOKEN_ADDRESS_TYPE'; export const TLA_TYPE = 'TLA_TYPE'; export const SIMPLE_TLA_TYPE = 'SIMPLE_TLA_TYPE'; export const UINT_TYPE = 'UINT_TYPE'; +export const DECIMAL_TYPE = 'DECIMAL_TYPE'; export const STRING_TYPE = 'STRING_TYPE'; export const HEX_TYPE = 'HEX_TYPE'; export const URL_TYPE = 'URL_TYPE'; @@ -39,6 +40,7 @@ export const URL_TYPE = 'URL_TYPE'; export const ERRORS = { invalidTLA: 'The TLA should be 3 characters long', invalidUint: 'Please enter a non-negative integer', + invalidDecimal: 'Please enter a value between 0 and 18', invalidString: 'Please enter at least a character', invalidAccount: 'Please select an account to transact with', invalidRecipient: 'Please select an account to send to', @@ -152,6 +154,21 @@ const validateUint = (uint) => { }; }; +const validateDecimal = (decimal) => { + if (!/^\d+$/.test(decimal) || parseInt(decimal) < 0 || parseInt(decimal) > 18) { + return { + error: ERRORS.invalidDecimal, + valid: false + }; + } + + return { + value: parseInt(decimal), + error: null, + valid: true + }; +}; + const validateString = (string) => { if (string.toString().length === 0) { return { @@ -204,6 +221,7 @@ export const validate = (value, type, contract) => { if (type === TLA_TYPE) return validateTLA(value, contract); if (type === SIMPLE_TLA_TYPE) return validateTLA(value, contract, true); if (type === UINT_TYPE) return validateUint(value); + if (type === DECIMAL_TYPE) return validateDecimal(value); if (type === STRING_TYPE) return validateString(value); if (type === HEX_TYPE) return validateHex(value); if (type === URL_TYPE) return validateURL(value); diff --git a/js/src/dapps/tokenreg/Tokens/Token/token.js b/js/src/dapps/tokenreg/Tokens/Token/token.js index 34550ef48..660b21b97 100644 --- a/js/src/dapps/tokenreg/Tokens/Token/token.js +++ b/js/src/dapps/tokenreg/Tokens/Token/token.js @@ -152,8 +152,8 @@ export default class Token extends Component { if (!base || base < 0) return null; return ( + value={ Math.log10(base).toString() } + label='Decimals' /> ); } From 0b5a9a6e60b02b69ee83d056294159316dab92b6 Mon Sep 17 00:00:00 2001 From: keorn Date: Mon, 14 Nov 2016 14:29:33 +0000 Subject: [PATCH 21/31] nicer bundled spec message --- ethcore/src/spec/spec.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index 695483611..de1b7db42 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -137,7 +137,7 @@ impl From for Spec { macro_rules! load_bundled { ($e:expr) => { - Spec::load(include_bytes!(concat!("../../res/", $e, ".json")) as &[u8]).expect("Chain spec is invalid") + Spec::load(include_bytes!(concat!("../../res/", $e, ".json")) as &[u8]).expect(concat!("Chain spec ", $e, " is invalid.")) }; } From ecb89d3670fffc932bdeb6867b9d55e8243dcafb Mon Sep 17 00:00:00 2001 From: Nicolas Gotchac Date: Mon, 14 Nov 2016 15:35:25 +0100 Subject: [PATCH 22/31] Scrollable Accounts list // Tab;Enter;Keydown for first input #3396 --- .../basiccoin/AddressSelect/addressSelect.css | 4 +++ js/src/ui/Form/AutoComplete/autocomplete.js | 27 +++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/js/src/dapps/basiccoin/AddressSelect/addressSelect.css b/js/src/dapps/basiccoin/AddressSelect/addressSelect.css index ddfd334e8..818906708 100644 --- a/js/src/dapps/basiccoin/AddressSelect/addressSelect.css +++ b/js/src/dapps/basiccoin/AddressSelect/addressSelect.css @@ -21,3 +21,7 @@ .iconMenu option { padding-left: 30px; } + +.menu { + display: none; +} diff --git a/js/src/ui/Form/AutoComplete/autocomplete.js b/js/src/ui/Form/AutoComplete/autocomplete.js index b0958da31..89cc5ee16 100644 --- a/js/src/ui/Form/AutoComplete/autocomplete.js +++ b/js/src/ui/Form/AutoComplete/autocomplete.js @@ -15,6 +15,7 @@ // along with Parity. If not, see . import React, { Component, PropTypes } from 'react'; +import keycode from 'keycode'; import { MenuItem, AutoComplete as MUIAutoComplete } from 'material-ui'; import { PopoverAnimationVertical } from 'material-ui/Popover'; @@ -67,6 +68,9 @@ export default class AutoComplete extends Component { fullWidth floatingLabelFixed dataSource={ this.getDataSource() } + menuProps={ { maxHeight: 400 } } + ref='muiAutocomplete' + onKeyDown={ this.onKeyDown } /> ); } @@ -91,6 +95,29 @@ export default class AutoComplete extends Component { })); } + onKeyDown = (event) => { + const { muiAutocomplete } = this.refs; + + switch (keycode(event)) { + case 'down': + const { menu } = muiAutocomplete.refs; + menu.handleKeyDown(event); + break; + + case 'enter': + case 'tab': + event.preventDefault(); + event.stopPropagation(); + event.which = 'useless'; + + const e = new CustomEvent('down'); + e.which = 40; + + muiAutocomplete.handleKeyDown(e); + break; + } + } + onChange = (item, idx) => { if (idx === -1) { return; From d66cc0907dc96376d1ad3b302e2f090524550571 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Mon, 14 Nov 2016 16:10:04 +0100 Subject: [PATCH 23/31] Bump ws-rs --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 95be811e2..420af2655 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1926,7 +1926,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "ws" version = "0.5.3" -source = "git+https://github.com/ethcore/ws-rs.git?branch=mio-upstream-stable#0cd6c5e3e9d5e61a37d53eb8dcbad523dcc69314" +source = "git+https://github.com/ethcore/ws-rs.git?branch=mio-upstream-stable#f5c0b35d660244d1b7500693c8cc28277ce1d418" dependencies = [ "bytes 0.4.0-dev (git+https://github.com/carllerche/bytes)", "httparse 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", From 89f83b8cd7974df78f5b1734a03192a879b1aad2 Mon Sep 17 00:00:00 2001 From: Nicolas Gotchac Date: Mon, 14 Nov 2016 16:11:00 +0100 Subject: [PATCH 24/31] Fixes #3397 : fake blur handled --- js/src/ui/Form/AutoComplete/autocomplete.js | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/js/src/ui/Form/AutoComplete/autocomplete.js b/js/src/ui/Form/AutoComplete/autocomplete.js index 89cc5ee16..ada1176b6 100644 --- a/js/src/ui/Form/AutoComplete/autocomplete.js +++ b/js/src/ui/Form/AutoComplete/autocomplete.js @@ -41,7 +41,8 @@ export default class AutoComplete extends Component { state = { lastChangedValue: undefined, entry: null, - open: false + open: false, + fakeBlur: false } render () { @@ -102,6 +103,7 @@ export default class AutoComplete extends Component { case 'down': const { menu } = muiAutocomplete.refs; menu.handleKeyDown(event); + this.setState({ fakeBlur: true }); break; case 'enter': @@ -135,17 +137,22 @@ export default class AutoComplete extends Component { this.setState({ entry, open: false }); } - onBlur = () => { + onBlur = (event) => { const { onUpdateInput } = this.props; - // TODO: Handle blur gracefully where we use onUpdateInput (currently replaces input + // TODO: Handle blur gracefully where we use onUpdateInput (currently replaces // input where text is allowed with the last selected value from the dropdown) if (!onUpdateInput) { window.setTimeout(() => { - const { entry } = this.state; + const { entry, fakeBlur } = this.state; + + if (fakeBlur) { + this.setState({ fakeBlur: false }); + return; + } this.handleOnChange(entry); - }, 100); + }, 200); } } From c061eae64b88ab60b4f526cee918afce33445fbd Mon Sep 17 00:00:00 2001 From: GitLab Build Bot Date: Mon, 14 Nov 2016 15:46:21 +0000 Subject: [PATCH 25/31] [ci skip] js-precompiled 20161114-154454 --- Cargo.lock | 2 +- js/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f2e3b0690..0a7c27813 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1249,7 +1249,7 @@ dependencies = [ [[package]] name = "parity-ui-precompiled" version = "1.4.0" -source = "git+https://github.com/ethcore/js-precompiled.git#7bf550e482ef274480d1fd7e1ceb2efddd747dbd" +source = "git+https://github.com/ethcore/js-precompiled.git#1628fe95dd21b87f35a72f06c452b814876e3877" dependencies = [ "parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/js/package.json b/js/package.json index 1e2da7d5b..a68826c9a 100644 --- a/js/package.json +++ b/js/package.json @@ -1,6 +1,6 @@ { "name": "parity.js", - "version": "0.2.38", + "version": "0.2.39", "main": "release/index.js", "jsnext:main": "src/index.js", "author": "Parity Team ", From 5127b997ebbb370d61faaf0db95401ee460d0eeb Mon Sep 17 00:00:00 2001 From: GitLab Build Bot Date: Mon, 14 Nov 2016 15:54:09 +0000 Subject: [PATCH 26/31] [ci skip] js-precompiled 20161114-155241 --- Cargo.lock | 2 +- js/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0a7c27813..487a8a40a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1249,7 +1249,7 @@ dependencies = [ [[package]] name = "parity-ui-precompiled" version = "1.4.0" -source = "git+https://github.com/ethcore/js-precompiled.git#1628fe95dd21b87f35a72f06c452b814876e3877" +source = "git+https://github.com/ethcore/js-precompiled.git#1c7339e275e82608a0380824f675a666de0b9e83" dependencies = [ "parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/js/package.json b/js/package.json index a68826c9a..6f3893bbb 100644 --- a/js/package.json +++ b/js/package.json @@ -1,6 +1,6 @@ { "name": "parity.js", - "version": "0.2.39", + "version": "0.2.40", "main": "release/index.js", "jsnext:main": "src/index.js", "author": "Parity Team ", From 134622ea3ade5b2fa6bbb55735948d111561ca9e Mon Sep 17 00:00:00 2001 From: Nicolas Gotchac Date: Mon, 14 Nov 2016 18:34:05 +0100 Subject: [PATCH 27/31] Adds error handler in Importer // Import AddressBook #2885 --- js/src/ui/Actionbar/Import/import.js | 34 +++++++++++-- js/src/ui/IdentityName/identityName.js | 12 +++-- js/src/views/Accounts/Summary/summary.js | 56 +++++++++++++++++---- js/src/views/Addresses/addresses.js | 64 +++++++++++++++++++++++- 4 files changed, 146 insertions(+), 20 deletions(-) diff --git a/js/src/ui/Actionbar/Import/import.js b/js/src/ui/Actionbar/Import/import.js index 776e5bb08..081fe1a17 100644 --- a/js/src/ui/Actionbar/Import/import.js +++ b/js/src/ui/Actionbar/Import/import.js @@ -29,6 +29,8 @@ const initialState = { show: false, validate: false, validationBody: null, + error: false, + errorText: '', content: '' }; @@ -65,7 +67,7 @@ export default class ActionbarImport extends Component { renderModal () { const { title, renderValidation } = this.props; - const { show, step } = this.state; + const { show, step, error } = this.state; if (!show) { return null; @@ -73,7 +75,7 @@ export default class ActionbarImport extends Component { const hasSteps = typeof renderValidation === 'function'; - const steps = hasSteps ? [ 'select a file', 'validate' ] : null; + const steps = hasSteps ? [ 'select a file', error ? 'error' : 'validate' ] : null; return ( ); + if (error) { + return [ cancelBtn ]; + } + if (validate) { const confirmBtn = (
+ ); + } if (validate) { return this.renderValidation(); @@ -169,10 +183,20 @@ export default class ActionbarImport extends Component { return this.onCloseModal(); } + const validationBody = renderValidation(content); + + if (validationBody && validationBody.error) { + return this.setState({ + step: 1, + error: true, + errorText: validationBody.error + }); + } + this.setState({ step: 1, validate: true, - validationBody: renderValidation(content), + validationBody, content }); }; diff --git a/js/src/ui/IdentityName/identityName.js b/js/src/ui/IdentityName/identityName.js index 6b6c75be2..f19e2bb2e 100644 --- a/js/src/ui/IdentityName/identityName.js +++ b/js/src/ui/IdentityName/identityName.js @@ -28,11 +28,12 @@ class IdentityName extends Component { tokens: PropTypes.object, empty: PropTypes.bool, shorten: PropTypes.bool, - unknown: PropTypes.bool + unknown: PropTypes.bool, + name: PropTypes.string } render () { - const { address, accountsInfo, tokens, empty, shorten, unknown, className } = this.props; + const { address, accountsInfo, tokens, empty, name, shorten, unknown, className } = this.props; const account = accountsInfo[address] || tokens[address]; const hasAccount = account && (!account.meta || !account.meta.deleted); @@ -43,13 +44,14 @@ class IdentityName extends Component { const addressFallback = shorten ? this.formatHash(address) : address; const fallback = unknown ? defaultName : addressFallback; const isUuid = hasAccount && account.name === account.uuid; - const name = hasAccount && !isUuid + const displayName = (name && name.toUpperCase().trim()) || + (hasAccount && !isUuid ? account.name.toUpperCase().trim() - : fallback; + : fallback); return ( - { name && name.length ? name : fallback } + { displayName && displayName.length ? displayName : fallback } ); } diff --git a/js/src/views/Accounts/Summary/summary.js b/js/src/views/Accounts/Summary/summary.js index 51bb81215..5a96f64ff 100644 --- a/js/src/views/Accounts/Summary/summary.js +++ b/js/src/views/Accounts/Summary/summary.js @@ -22,22 +22,28 @@ import { Balance, Container, ContainerTitle, IdentityIcon, IdentityName, Tags, I export default class Summary extends Component { static contextTypes = { api: React.PropTypes.object - } + }; static propTypes = { account: PropTypes.object.isRequired, - balance: PropTypes.object.isRequired, + balance: PropTypes.object, link: PropTypes.string, + name: PropTypes.string, + noLink: PropTypes.bool, children: PropTypes.node, handleAddSearchToken: PropTypes.func - } + }; + + static defaultProps = { + noLink: false + }; state = { name: 'Unnamed' - } + }; render () { - const { account, balance, children, link, handleAddSearchToken } = this.props; + const { account, children, handleAddSearchToken } = this.props; const { tags } = account.meta; if (!account) { @@ -45,7 +51,6 @@ export default class Summary extends Component { } const { address } = account; - const viewLink = `/${link || 'account'}/${address}`; const addressComponent = ( { } } + title={ this.renderLink() } byline={ addressComponent } /> - + + { this.renderBalance() } { children } ); } + + renderLink () { + const { link, noLink, account, name } = this.props; + + const { address } = account; + const viewLink = `/${link || 'account'}/${address}`; + + const content = ( + + ); + + if (noLink) { + return content; + } + + return ( + + { content } + + ); + } + + renderBalance () { + const { balance } = this.props; + + if (!balance) { + return null; + } + + return ( + + ); + } } diff --git a/js/src/views/Addresses/addresses.js b/js/src/views/Addresses/addresses.js index 13c512713..0347f8fa2 100644 --- a/js/src/views/Addresses/addresses.js +++ b/js/src/views/Addresses/addresses.js @@ -21,8 +21,9 @@ import ContentAdd from 'material-ui/svg-icons/content/add'; import { uniq } from 'lodash'; import List from '../Accounts/List'; +import Summary from '../Accounts/Summary'; import { AddAddress } from '../../modals'; -import { Actionbar, ActionbarExport, ActionbarSearch, ActionbarSort, Button, Page } from '../../ui'; +import { Actionbar, ActionbarExport, ActionbarImport, ActionbarSearch, ActionbarSort, Button, Page } from '../../ui'; import styles from './addresses.css'; @@ -107,6 +108,12 @@ class Addresses extends Component { content={ contacts } filename='addressbook.json' />, + , + this.renderSearchButton(), this.renderSortButton() ]; @@ -134,6 +141,61 @@ class Addresses extends Component { ); } + renderValidation = (content) => { + let addresses; + + try { + addresses = JSON.parse(content); + } catch (e) { + return { + error: 'The provided file is invalid...' + }; + } + + const body = Object.values(addresses).map((address, index) => ( + + )); + + return ( +
+ { body } +
+ ); + } + + onImport = (content) => { + try { + const addresses = JSON.parse(content); + + Object.values(addresses).forEach((account) => { + this.onAddAccount(account); + }); + } catch (e) { + console.error('onImport', content, e); + } + } + + onAddAccount = (account) => { + const { api } = this.context; + const { address, name, meta } = account; + + Promise.all([ + api.parity.setAccountName(address, name), + api.parity.setAccountMeta(address, { + ...meta, + timestamp: Date.now(), + deleted: false + }) + ]).catch((error) => { + console.error('onAddAccount', error); + }); + } + onAddSearchToken = (token) => { const { searchTokens } = this.state; const newSearchTokens = uniq([].concat(searchTokens, token)); From 3bfa56c72a9890b97eb55e91be85a9388b122b34 Mon Sep 17 00:00:00 2001 From: GitLab Build Bot Date: Mon, 14 Nov 2016 17:48:20 +0000 Subject: [PATCH 28/31] [ci skip] js-precompiled 20161114-174654 --- Cargo.lock | 2 +- js/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 487a8a40a..7a20e3dee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1249,7 +1249,7 @@ dependencies = [ [[package]] name = "parity-ui-precompiled" version = "1.4.0" -source = "git+https://github.com/ethcore/js-precompiled.git#1c7339e275e82608a0380824f675a666de0b9e83" +source = "git+https://github.com/ethcore/js-precompiled.git#610876fb2bb01705b81de14dd7e04d6a3cdf80ab" dependencies = [ "parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/js/package.json b/js/package.json index 6f3893bbb..6022072ea 100644 --- a/js/package.json +++ b/js/package.json @@ -1,6 +1,6 @@ { "name": "parity.js", - "version": "0.2.40", + "version": "0.2.41", "main": "release/index.js", "jsnext:main": "src/index.js", "author": "Parity Team ", From 09ec0c1f2f62c2e0c26710b0af4d73dc5191a23c Mon Sep 17 00:00:00 2001 From: Nicolas Gotchac Date: Mon, 14 Nov 2016 20:26:21 +0100 Subject: [PATCH 29/31] More robust import #2885 --- js/src/views/Addresses/addresses.js | 45 ++++++++++++++++------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/js/src/views/Addresses/addresses.js b/js/src/views/Addresses/addresses.js index 0347f8fa2..8b5fc0818 100644 --- a/js/src/views/Addresses/addresses.js +++ b/js/src/views/Addresses/addresses.js @@ -142,30 +142,35 @@ class Addresses extends Component { } renderValidation = (content) => { - let addresses; + const error = { + error: 'The provided file is invalid...' + }; try { - addresses = JSON.parse(content); - } catch (e) { - return { - error: 'The provided file is invalid...' - }; - } + const addresses = JSON.parse(content); - const body = Object.values(addresses).map((address, index) => ( - - )); + if (!addresses || Object.keys(addresses).length === 0) { + return error; + } - return ( -
- { body } -
- ); + const body = Object + .values(addresses) + .filter((account) => account && account.address) + .map((account, index) => ( + + )); + + return ( +
+ { body } +
+ ); + } catch (e) { return error; } } onImport = (content) => { From 85fdcc7bf30d1047b1a6095bd76ee0477e2f676e Mon Sep 17 00:00:00 2001 From: "Denis S. Soldatov aka General-Beck" Date: Mon, 14 Nov 2016 23:45:58 +0400 Subject: [PATCH 30/31] Update gitlab-ci remove -Zorbit=off switch to rust 1.13 --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 591807e24..1d152114c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -326,7 +326,7 @@ windows: - set INCLUDE=C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Include;C:\vs2015\VC\include;C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt - set LIB=C:\vs2015\VC\lib;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x64 - set RUST_BACKTRACE=1 - - set RUSTFLAGS=%RUSTFLAGS% -Zorbit=off + - set RUSTFLAGS=%RUSTFLAGS% - rustup default stable-x86_64-pc-windows-msvc - cargo build --release %CARGOFLAGS% - curl -sL --url "https://github.com/ethcore/win-build/raw/master/SimpleFC.dll" -o nsis\SimpleFC.dll From c4885a14237dfc3ac31ab333dcc9c83dd202a032 Mon Sep 17 00:00:00 2001 From: GitLab Build Bot Date: Mon, 14 Nov 2016 20:11:54 +0000 Subject: [PATCH 31/31] [ci skip] js-precompiled 20161114-201022 --- Cargo.lock | 2 +- js/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7a20e3dee..2e6196014 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1249,7 +1249,7 @@ dependencies = [ [[package]] name = "parity-ui-precompiled" version = "1.4.0" -source = "git+https://github.com/ethcore/js-precompiled.git#610876fb2bb01705b81de14dd7e04d6a3cdf80ab" +source = "git+https://github.com/ethcore/js-precompiled.git#5555504896f109c2930838999b8915f44ee5ed27" dependencies = [ "parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/js/package.json b/js/package.json index 6022072ea..b0a543344 100644 --- a/js/package.json +++ b/js/package.json @@ -1,6 +1,6 @@ { "name": "parity.js", - "version": "0.2.41", + "version": "0.2.42", "main": "release/index.js", "jsnext:main": "src/index.js", "author": "Parity Team ",