From 529a7fc33c61a88298a63fc205585538b219f4f5 Mon Sep 17 00:00:00 2001 From: keorn Date: Mon, 5 Dec 2016 17:08:16 +0000 Subject: [PATCH 01/56] add password and AccountProvider --- ethcore/src/engines/authority_round.rs | 46 +++++++++++------------ ethcore/src/engines/basic_authority.rs | 13 +++++-- ethcore/src/engines/instant_seal.rs | 12 ++---- ethcore/src/engines/mod.rs | 14 +++++-- ethcore/src/miner/miner.rs | 43 ++++++++++++++------- ethcore/src/miner/mod.rs | 3 ++ parity/run.rs | 5 ++- rpc/src/v1/impls/parity_set.rs | 6 +++ rpc/src/v1/tests/eth.rs | 1 + rpc/src/v1/tests/helpers/miner_service.rs | 10 +++++ rpc/src/v1/tests/helpers/sync_provider.rs | 2 +- rpc/src/v1/tests/mocked/parity_set.rs | 17 +++++++++ rpc/src/v1/traits/parity_set.rs | 4 ++ 13 files changed, 119 insertions(+), 57 deletions(-) diff --git a/ethcore/src/engines/authority_round.rs b/ethcore/src/engines/authority_round.rs index f28a06117..646c107e0 100644 --- a/ethcore/src/engines/authority_round.rs +++ b/ethcore/src/engines/authority_round.rs @@ -21,13 +21,15 @@ use std::sync::Weak; use std::time::{UNIX_EPOCH, Duration}; use util::*; use ethkey::{verify_address, Signature}; -use rlp::{Rlp, UntrustedRlp, View, encode}; +use rlp::{UntrustedRlp, View, encode}; use account_provider::AccountProvider; use block::*; use spec::CommonParams; use engines::Engine; use header::Header; use error::{Error, BlockError}; +use blockchain::extras::BlockDetails; +use views::HeaderView; use evm::Schedule; use ethjson; use io::{IoContext, IoHandler, TimerToken, IoService, IoChannel}; @@ -35,8 +37,6 @@ use service::ClientIoMessage; use transaction::SignedTransaction; use env_info::EnvInfo; use builtin::Builtin; -use blockchain::extras::BlockDetails; -use views::HeaderView; /// `AuthorityRound` params. #[derive(Debug, PartialEq)] @@ -72,6 +72,7 @@ pub struct AuthorityRound { message_channel: Mutex>>, step: AtomicUsize, proposed: AtomicBool, + account_provider: Mutex>>, } fn header_step(header: &Header) -> Result { @@ -104,7 +105,8 @@ impl AuthorityRound { transition_service: try!(IoService::::start()), message_channel: Mutex::new(None), step: AtomicUsize::new(initial_step), - proposed: AtomicBool::new(false) + proposed: AtomicBool::new(false), + account_provider: Mutex::new(None), }); let handler = TransitionHandler { engine: Arc::downgrade(&engine) }; try!(engine.transition_service.register_handler(Arc::new(handler))); @@ -196,7 +198,6 @@ impl Engine for AuthorityRound { } fn populate_from_parent(&self, header: &mut Header, parent: &Header, gas_floor_target: U256, _gas_ceil_target: U256) { - header.set_difficulty(parent.difficulty().clone()); header.set_gas_limit({ let gas_limit = parent.gas_limit().clone(); let bound_divisor = self.our_params.gas_limit_bound_divisor; @@ -221,12 +222,12 @@ impl Engine for AuthorityRound { /// /// This operation is synchronous and may (quite reasonably) not be available, in which `false` will /// be returned. - fn generate_seal(&self, block: &ExecutedBlock, accounts: Option<&AccountProvider>) -> Option> { + fn generate_seal(&self, block: &ExecutedBlock) -> Option> { if self.proposed.load(AtomicOrdering::SeqCst) { return None; } let header = block.header(); let step = self.step(); if self.is_step_proposer(step, header.author()) { - if let Some(ap) = accounts { + if let Some(ref ap) = *self.account_provider.lock() { // Account should be permanently unlocked, otherwise sealing will fail. if let Ok(signature) = ap.sign(*header.author(), None, header.bare_hash()) { trace!(target: "poa", "generate_seal: Issuing a block for step {}.", step); @@ -303,22 +304,16 @@ impl Engine for AuthorityRound { t.sender().map(|_|()) // Perform EC recovery and cache sender } - fn register_message_channel(&self, message_channel: IoChannel) { - let mut guard = self.message_channel.lock(); - *guard = Some(message_channel); + fn is_new_best_block(&self, _best_total_difficulty: U256, best_header: HeaderView, _parent_details: &BlockDetails, new_header: &HeaderView) -> bool { + new_header.number() > best_header.number() } - fn is_new_best_block(&self, _best_total_difficulty: U256, best_header: HeaderView, _parent_details: &BlockDetails, new_header: &HeaderView) -> bool { - let new_number = new_header.number(); - let best_number = best_header.number(); - if new_number != best_number { - new_number > best_number - } else { - // Take the oldest step at given height. - let new_step: usize = Rlp::new(&new_header.seal()[0]).as_val(); - let best_step: usize = Rlp::new(&best_header.seal()[0]).as_val(); - new_step < best_step - } + fn register_message_channel(&self, message_channel: IoChannel) { + *self.message_channel.lock() = Some(message_channel); + } + + fn register_account_provider(&self, account_provider: Arc) { + *self.account_provider.lock() = Some(account_provider); } } @@ -393,6 +388,7 @@ mod tests { let spec = Spec::new_test_round(); let engine = &*spec.engine; + engine.register_account_provider(Arc::new(tap)); let genesis_header = spec.genesis_header(); let mut db1 = get_temp_state_db().take(); spec.ensure_db_good(&mut db1, &TrieFactory::new(TrieSpec::Secure)).unwrap(); @@ -404,16 +400,16 @@ mod tests { let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes, addr2, (3141562.into(), 31415620.into()), vec![]).unwrap(); let b2 = b2.close_and_lock(); - if let Some(seal) = engine.generate_seal(b1.block(), Some(&tap)) { + if let Some(seal) = engine.generate_seal(b1.block()) { assert!(b1.clone().try_seal(engine, seal).is_ok()); // Second proposal is forbidden. - assert!(engine.generate_seal(b1.block(), Some(&tap)).is_none()); + assert!(engine.generate_seal(b1.block()).is_none()); } - if let Some(seal) = engine.generate_seal(b2.block(), Some(&tap)) { + if let Some(seal) = engine.generate_seal(b2.block()) { assert!(b2.clone().try_seal(engine, seal).is_ok()); // Second proposal is forbidden. - assert!(engine.generate_seal(b2.block(), Some(&tap)).is_none()); + assert!(engine.generate_seal(b2.block()).is_none()); } } diff --git a/ethcore/src/engines/basic_authority.rs b/ethcore/src/engines/basic_authority.rs index fb2f9bde6..0b9040a11 100644 --- a/ethcore/src/engines/basic_authority.rs +++ b/ethcore/src/engines/basic_authority.rs @@ -58,6 +58,7 @@ pub struct BasicAuthority { params: CommonParams, our_params: BasicAuthorityParams, builtins: BTreeMap, + account_provider: Mutex>>, } impl BasicAuthority { @@ -67,6 +68,7 @@ impl BasicAuthority { params: params, our_params: our_params, builtins: builtins, + account_provider: Mutex::new(None) } } } @@ -113,8 +115,8 @@ impl Engine for BasicAuthority { /// /// This operation is synchronous and may (quite reasonably) not be available, in which `false` will /// be returned. - fn generate_seal(&self, block: &ExecutedBlock, accounts: Option<&AccountProvider>) -> Option> { - if let Some(ap) = accounts { + fn generate_seal(&self, block: &ExecutedBlock) -> Option> { + if let Some(ref ap) = *self.account_provider.lock() { let header = block.header(); let message = header.bare_hash(); // account should be pernamently unlocked, otherwise sealing will fail @@ -179,6 +181,10 @@ impl Engine for BasicAuthority { fn verify_transaction(&self, t: &SignedTransaction, _header: &Header) -> Result<(), Error> { t.sender().map(|_|()) // Perform EC recovery and cache sender } + + fn register_account_provider(&self, ap: Arc) { + *self.account_provider.lock() = Some(ap); + } } #[cfg(test)] @@ -254,6 +260,7 @@ mod tests { let spec = new_test_authority(); let engine = &*spec.engine; + engine.register_account_provider(Arc::new(tap)); let genesis_header = spec.genesis_header(); let mut db_result = get_temp_state_db(); let mut db = db_result.take(); @@ -261,7 +268,7 @@ mod tests { let last_hashes = Arc::new(vec![genesis_header.hash()]); let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, addr, (3141562.into(), 31415620.into()), vec![]).unwrap(); let b = b.close_and_lock(); - let seal = engine.generate_seal(b.block(), Some(&tap)).unwrap(); + let seal = engine.generate_seal(b.block()).unwrap(); assert!(b.try_seal(engine, seal).is_ok()); } diff --git a/ethcore/src/engines/instant_seal.rs b/ethcore/src/engines/instant_seal.rs index f50f7344b..83335fb03 100644 --- a/ethcore/src/engines/instant_seal.rs +++ b/ethcore/src/engines/instant_seal.rs @@ -23,7 +23,6 @@ use spec::CommonParams; use evm::Schedule; use block::ExecutedBlock; use util::Bytes; -use account_provider::AccountProvider; /// An engine which does not provide any consensus mechanism, just seals blocks internally. pub struct InstantSeal { @@ -60,7 +59,7 @@ impl Engine for InstantSeal { fn is_sealer(&self, _author: &Address) -> Option { Some(true) } - fn generate_seal(&self, _block: &ExecutedBlock, _accounts: Option<&AccountProvider>) -> Option> { + fn generate_seal(&self, _block: &ExecutedBlock) -> Option> { Some(Vec::new()) } } @@ -70,16 +69,12 @@ mod tests { use util::*; use util::trie::TrieSpec; use tests::helpers::*; - use account_provider::AccountProvider; use spec::Spec; use header::Header; use block::*; #[test] fn instant_can_seal() { - let tap = AccountProvider::transient_provider(); - let addr = tap.insert_account("".sha3(), "").unwrap(); - let spec = Spec::new_instant(); let engine = &*spec.engine; let genesis_header = spec.genesis_header(); @@ -87,10 +82,9 @@ mod tests { let mut db = db_result.take(); spec.ensure_db_good(&mut db, &TrieFactory::new(TrieSpec::Secure)).unwrap(); let last_hashes = Arc::new(vec![genesis_header.hash()]); - let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, addr, (3141562.into(), 31415620.into()), vec![]).unwrap(); + let b = OpenBlock::new(engine, Default::default(), false, db, &genesis_header, last_hashes, Address::default(), (3141562.into(), 31415620.into()), vec![]).unwrap(); let b = b.close_and_lock(); - // Seal with empty AccountProvider. - let seal = engine.generate_seal(b.block(), Some(&tap)).unwrap(); + let seal = engine.generate_seal(b.block()).unwrap(); assert!(b.try_seal(engine, seal).is_ok()); } diff --git a/ethcore/src/engines/mod.rs b/ethcore/src/engines/mod.rs index 163901edc..0401ba667 100644 --- a/ethcore/src/engines/mod.rs +++ b/ethcore/src/engines/mod.rs @@ -94,7 +94,7 @@ pub trait Engine : Sync + Send { /// /// This operation is synchronous and may (quite reasonably) not be available, in which None will /// be returned. - fn generate_seal(&self, _block: &ExecutedBlock, _accounts: Option<&AccountProvider>) -> Option> { None } + fn generate_seal(&self, _block: &ExecutedBlock) -> Option> { None } /// Phase 1 quick block verification. Only does checks that are cheap. `block` (the header's full block) /// may be provided for additional checks. Returns either a null `Ok` or a general error detailing the problem with import. @@ -147,11 +147,17 @@ pub trait Engine : Sync + Send { self.builtins().get(a).expect("attempted to execute nonexistent builtin").execute(input, output); } - /// Add a channel for communication with Client which can be used for sealing. - fn register_message_channel(&self, _message_channel: IoChannel) {} - /// Check if new block should be chosen as the one in chain. fn is_new_best_block(&self, best_total_difficulty: U256, _best_header: HeaderView, parent_details: &BlockDetails, new_header: &HeaderView) -> bool { ethash::is_new_best_block(best_total_difficulty, parent_details, new_header) } + + /// Register an account which signs consensus messages. + fn set_signer(&self, _address: Address, _password: String) {} + + /// Add a channel for communication with Client which can be used for sealing. + fn register_message_channel(&self, _message_channel: IoChannel) {} + + /// Add an account provider useful for Engines that sign stuff. + fn register_account_provider(&self, _account_provider: Arc) {} } diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index a543e608d..4b38a7e07 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -19,7 +19,7 @@ use std::time::{Instant, Duration}; use util::*; use util::using_queue::{UsingQueue, GetAction}; -use account_provider::AccountProvider; +use account_provider::{AccountProvider, Error as AccountError}; use views::{BlockView, HeaderView}; use header::Header; use state::{State, CleanupMode}; @@ -464,15 +464,12 @@ impl Miner { /// Attempts to perform internal sealing (one that does not require work) to return Ok(sealed), /// Err(Some(block)) returns for unsuccesful sealing while Err(None) indicates misspecified engine. fn seal_block_internally(&self, block: ClosedBlock) -> Result> { - trace!(target: "miner", "seal_block_internally: block has transaction - attempting internal seal."); - let s = self.engine.generate_seal(block.block(), match self.accounts { - Some(ref x) => Some(&**x), - None => None, - }); + trace!(target: "miner", "seal_block_internally: attempting internal seal."); + let s = self.engine.generate_seal(block.block()); if let Some(seal) = s { trace!(target: "miner", "seal_block_internally: managed internal seal. importing..."); - block.lock().try_seal(&*self.engine, seal).or_else(|_| { - warn!("prepare_sealing: ERROR: try_seal failed when given internally generated seal. WTF?"); + block.lock().try_seal(&*self.engine, seal).or_else(|(e, _)| { + warn!("prepare_sealing: ERROR: try_seal failed when given internally generated seal: {}", e); Err(None) }) } else { @@ -485,7 +482,7 @@ impl Miner { fn seal_and_import_block_internally(&self, chain: &MiningBlockChainClient, block: ClosedBlock) -> bool { if !block.transactions().is_empty() || self.forced_sealing() { if let Ok(sealed) = self.seal_block_internally(block) { - if chain.import_block(sealed.rlp_bytes()).is_ok() { + if chain.import_sealed_block(sealed).is_ok() { trace!(target: "miner", "import_block_internally: imported internally sealed block"); return true } @@ -740,6 +737,19 @@ impl MinerService for Miner { *self.author.write() = author; } + fn set_consensus_signer(&self, address: Address, password: String) -> Result<(), AccountError> { + if self.seals_internally { + if let Some(ref ap) = self.accounts { + try!(ap.sign(address.clone(), Some(password.clone()), Default::default())); + } + let mut sealing_work = self.sealing_work.lock(); + sealing_work.enabled = self.engine.is_sealer(&address).unwrap_or(false); + *self.author.write() = address; + self.engine.set_signer(address, password); + } + Ok(()) + } + fn set_extra_data(&self, extra_data: Bytes) { *self.extra_data.write() = extra_data; } @@ -1020,6 +1030,11 @@ impl MinerService for Miner { let (block, original_work_hash) = self.prepare_block(chain); if self.seals_internally { trace!(target: "miner", "update_sealing: engine indicates internal sealing"); + { + let mut sealing_work = self.sealing_work.lock(); + sealing_work.queue.push(block.clone()); + sealing_work.queue.use_last_ref(); + } self.seal_and_import_block_internally(chain, block); } else { trace!(target: "miner", "update_sealing: engine does not seal internally, preparing work"); @@ -1042,7 +1057,7 @@ impl MinerService for Miner { ret.map(f) } - fn submit_seal(&self, chain: &MiningBlockChainClient, pow_hash: H256, seal: Vec) -> Result<(), Error> { + fn submit_seal(&self, chain: &MiningBlockChainClient, block_hash: H256, seal: Vec) -> Result<(), Error> { let result = if let Some(b) = self.sealing_work.lock().queue.get_used_if( if self.options.enable_resubmission { @@ -1050,22 +1065,22 @@ impl MinerService for Miner { } else { GetAction::Take }, - |b| &b.hash() == &pow_hash + |b| &b.hash() == &block_hash ) { - trace!(target: "miner", "Sealing block {}={}={} with seal {:?}", pow_hash, b.hash(), b.header().bare_hash(), seal); + trace!(target: "miner", "Submitted block {}={}={} with seal {:?}", block_hash, b.hash(), b.header().bare_hash(), seal); b.lock().try_seal(&*self.engine, seal).or_else(|(e, _)| { warn!(target: "miner", "Mined solution rejected: {}", e); Err(Error::PowInvalid) }) } else { - warn!(target: "miner", "Mined solution rejected: Block unknown or out of date."); + warn!(target: "miner", "Submitted solution rejected: Block unknown or out of date."); Err(Error::PowHashInvalid) }; result.and_then(|sealed| { let n = sealed.header().number(); let h = sealed.header().hash(); try!(chain.import_sealed_block(sealed)); - info!(target: "miner", "Mined block imported OK. #{}: {}", Colour::White.bold().paint(format!("{}", n)), Colour::White.bold().paint(h.hex())); + info!(target: "miner", "Submitted block imported OK. #{}: {}", Colour::White.bold().paint(format!("{}", n)), Colour::White.bold().paint(h.hex())); Ok(()) }) } diff --git a/ethcore/src/miner/mod.rs b/ethcore/src/miner/mod.rs index 1fb2244fd..26cefb295 100644 --- a/ethcore/src/miner/mod.rs +++ b/ethcore/src/miner/mod.rs @@ -76,6 +76,9 @@ pub trait MinerService : Send + Sync { /// Set the author that we will seal blocks as. fn set_author(&self, author: Address); + /// Set info necessary to sign consensus messages. + fn set_consensus_signer(&self, address: Address, password: String) -> Result<(), ::account_provider::Error>; + /// Get the extra_data that we will seal blocks with. fn extra_data(&self) -> Bytes; diff --git a/parity/run.rs b/parity/run.rs index f977c450c..2509d1347 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -70,7 +70,7 @@ pub struct RunCmd { pub http_conf: HttpConfiguration, pub ipc_conf: IpcConfiguration, pub net_conf: NetworkConfiguration, - pub network_id: Option, + pub network_id: Option, pub warp_sync: bool, pub acc_conf: AccountsConfig, pub gas_pricer: GasPricerConfig, @@ -208,6 +208,9 @@ pub fn execute(cmd: RunCmd, logger: Arc) -> Result<(), String> { // prepare account provider let account_provider = Arc::new(try!(prepare_account_provider(&cmd.dirs, cmd.acc_conf))); + // let the Engine access the accounts + spec.engine.register_account_provider(account_provider.clone()); + // create miner let miner = Miner::new(cmd.miner_options, cmd.gas_pricer.into(), &spec, Some(account_provider.clone())); miner.set_author(cmd.miner_extras.author); diff --git a/rpc/src/v1/impls/parity_set.rs b/rpc/src/v1/impls/parity_set.rs index 47634d518..e28f9a573 100644 --- a/rpc/src/v1/impls/parity_set.rs +++ b/rpc/src/v1/impls/parity_set.rs @@ -116,6 +116,12 @@ impl ParitySet for ParitySetClient where Ok(true) } + fn set_consensus_signer(&self, address: H160, password: String) -> Result { + try!(self.active()); + try!(take_weak!(self.miner).set_consensus_signer(address.into(), password).map_err(Into::into).map_err(errors::from_password_error)); + Ok(true) + } + fn set_transactions_limit(&self, limit: usize) -> Result { try!(self.active()); diff --git a/rpc/src/v1/tests/eth.rs b/rpc/src/v1/tests/eth.rs index 7894fa111..3aa83fec9 100644 --- a/rpc/src/v1/tests/eth.rs +++ b/rpc/src/v1/tests/eth.rs @@ -116,6 +116,7 @@ impl EthTester { fn from_spec(spec: Spec) -> Self { let dir = RandomTempPath::new(); let account_provider = account_provider(); + spec.engine.register_account_provider(account_provider.clone()); let miner_service = miner_service(&spec, account_provider.clone()); let snapshot_service = snapshot_service(); diff --git a/rpc/src/v1/tests/helpers/miner_service.rs b/rpc/src/v1/tests/helpers/miner_service.rs index ad55faa7b..6037cdd4a 100644 --- a/rpc/src/v1/tests/helpers/miner_service.rs +++ b/rpc/src/v1/tests/helpers/miner_service.rs @@ -25,6 +25,7 @@ use ethcore::header::BlockNumber; use ethcore::transaction::SignedTransaction; use ethcore::receipt::{Receipt, RichReceipt}; use ethcore::miner::{MinerService, MinerStatus, TransactionImportResult, LocalTransactionStatus}; +use ethcore::account_provider::Error as AccountError; /// Test miner service. pub struct TestMinerService { @@ -40,6 +41,8 @@ pub struct TestMinerService { pub pending_receipts: Mutex>, /// Last nonces. pub last_nonces: RwLock>, + /// Password held by Engine. + pub password: RwLock, min_gas_price: RwLock, gas_range_target: RwLock<(U256, U256)>, @@ -61,6 +64,7 @@ impl Default for TestMinerService { min_gas_price: RwLock::new(U256::from(20_000_000)), gas_range_target: RwLock::new((U256::from(12345), U256::from(54321))), author: RwLock::new(Address::zero()), + password: RwLock::new(String::new()), extra_data: RwLock::new(vec![1, 2, 3, 4]), limit: RwLock::new(1024), tx_gas_limit: RwLock::new(!U256::zero()), @@ -83,6 +87,12 @@ impl MinerService for TestMinerService { *self.author.write() = author; } + fn set_consensus_signer(&self, address: Address, password: String) -> Result<(), AccountError> { + *self.author.write() = address; + *self.password.write() = password; + Ok(()) + } + fn set_extra_data(&self, extra_data: Bytes) { *self.extra_data.write() = extra_data; } diff --git a/rpc/src/v1/tests/helpers/sync_provider.rs b/rpc/src/v1/tests/helpers/sync_provider.rs index 24be33417..8800d926a 100644 --- a/rpc/src/v1/tests/helpers/sync_provider.rs +++ b/rpc/src/v1/tests/helpers/sync_provider.rs @@ -23,7 +23,7 @@ use ethsync::{SyncProvider, SyncStatus, SyncState, PeerInfo, TransactionStats}; /// TestSyncProvider config. pub struct Config { /// Protocol version. - pub network_id: usize, + pub network_id: u64, /// Number of peers. pub num_peers: usize, } diff --git a/rpc/src/v1/tests/mocked/parity_set.rs b/rpc/src/v1/tests/mocked/parity_set.rs index 01f33e251..fdf3f2d0f 100644 --- a/rpc/src/v1/tests/mocked/parity_set.rs +++ b/rpc/src/v1/tests/mocked/parity_set.rs @@ -106,6 +106,23 @@ fn rpc_parity_set_author() { assert_eq!(miner.author(), Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap()); } +#[test] +fn rpc_parity_set_consensus_signer() { + let miner = miner_service(); + let client = client_service(); + let network = network_service(); + let io = IoHandler::new(); + io.add_delegate(parity_set_client(&client, &miner, &network).to_delegate()); + + let request = r#"{"jsonrpc": "2.0", "method": "parity_setConsensusSigner", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681", "password"], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#; + + assert_eq!(io.handle_request_sync(request), Some(response.to_owned())); + assert_eq!(miner.author(), Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap()); + assert_eq!(*miner.password.read(), "password".to_string()); +} + + #[test] fn rpc_parity_set_transactions_limit() { let miner = miner_service(); diff --git a/rpc/src/v1/traits/parity_set.rs b/rpc/src/v1/traits/parity_set.rs index c83eff022..e196a7d21 100644 --- a/rpc/src/v1/traits/parity_set.rs +++ b/rpc/src/v1/traits/parity_set.rs @@ -44,6 +44,10 @@ build_rpc_trait! { #[rpc(name = "parity_setAuthor")] fn set_author(&self, H160) -> Result; + /// Sets account for signing consensus messages. + #[rpc(name = "parity_setConsensusSigner")] + fn set_consensus_signer(&self, H160, String) -> Result; + /// Sets the limits for transaction queue. #[rpc(name = "parity_setTransactionsLimit")] fn set_transactions_limit(&self, usize) -> Result; From 01bf483b63152b3e5fb1a5cf4ea8285a033cfc6b Mon Sep 17 00:00:00 2001 From: keorn Date: Mon, 5 Dec 2016 17:29:47 +0000 Subject: [PATCH 02/56] remove unnecessary impls --- ethcore/src/engines/authority_round.rs | 4 ---- ethcore/src/engines/basic_authority.rs | 5 ----- ethcore/src/miner/miner.rs | 5 ----- 3 files changed, 14 deletions(-) diff --git a/ethcore/src/engines/authority_round.rs b/ethcore/src/engines/authority_round.rs index 646c107e0..02993fe83 100644 --- a/ethcore/src/engines/authority_round.rs +++ b/ethcore/src/engines/authority_round.rs @@ -209,10 +209,6 @@ impl Engine for AuthorityRound { }); } - /// Apply the block reward on finalisation of the block. - /// This assumes that all uncles are valid uncles (i.e. of at least one generation before the current). - fn on_close_block(&self, _block: &mut ExecutedBlock) {} - fn is_sealer(&self, author: &Address) -> Option { let p = &self.our_params; Some(p.authorities.contains(author)) diff --git a/ethcore/src/engines/basic_authority.rs b/ethcore/src/engines/basic_authority.rs index 0b9040a11..264a2d55a 100644 --- a/ethcore/src/engines/basic_authority.rs +++ b/ethcore/src/engines/basic_authority.rs @@ -100,13 +100,8 @@ impl Engine for BasicAuthority { max(gas_floor_target, gas_limit - gas_limit / bound_divisor + 1.into()) } }); -// info!("ethash: populate_from_parent #{}: difficulty={} and gas_limit={}", header.number, header.difficulty, header.gas_limit); } - /// Apply the block reward on finalisation of the block. - /// This assumes that all uncles are valid uncles (i.e. of at least one generation before the current). - fn on_close_block(&self, _block: &mut ExecutedBlock) {} - fn is_sealer(&self, author: &Address) -> Option { Some(self.our_params.authorities.contains(author)) } diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index 4b38a7e07..3b4223c68 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -1030,11 +1030,6 @@ impl MinerService for Miner { let (block, original_work_hash) = self.prepare_block(chain); if self.seals_internally { trace!(target: "miner", "update_sealing: engine indicates internal sealing"); - { - let mut sealing_work = self.sealing_work.lock(); - sealing_work.queue.push(block.clone()); - sealing_work.queue.use_last_ref(); - } self.seal_and_import_block_internally(chain, block); } else { trace!(target: "miner", "update_sealing: engine does not seal internally, preparing work"); From 5e7c21ad4aa613038d30715fc5b55f02e50a904b Mon Sep 17 00:00:00 2001 From: keorn Date: Mon, 5 Dec 2016 19:23:03 +0000 Subject: [PATCH 03/56] add a cli flag --- parity/cli/config.full.toml | 1 + parity/cli/config.toml | 1 + parity/cli/mod.rs | 5 +++++ parity/cli/usage.txt | 4 ++++ parity/configuration.rs | 5 +++++ parity/helpers.rs | 4 ++-- parity/params.rs | 2 ++ parity/run.rs | 14 +++++++++----- 8 files changed, 29 insertions(+), 7 deletions(-) diff --git a/parity/cli/config.full.toml b/parity/cli/config.full.toml index fcd9a9712..e2e4aeb5a 100644 --- a/parity/cli/config.full.toml +++ b/parity/cli/config.full.toml @@ -61,6 +61,7 @@ pass = "test_pass" [mining] author = "0xdeadbeefcafe0000000000000000000000000001" +consensus_signer = "0xdeadbeefcafe0000000000000000000000000001" force_sealing = true reseal_on_txs = "all" reseal_min_period = 4000 diff --git a/parity/cli/config.toml b/parity/cli/config.toml index c9bd563a8..b84c10b22 100644 --- a/parity/cli/config.toml +++ b/parity/cli/config.toml @@ -40,6 +40,7 @@ pass = "password" [mining] author = "0xdeadbeefcafe0000000000000000000000000001" +consensus_signer = "0xdeadbeefcafe0000000000000000000000000001" force_sealing = true reseal_on_txs = "all" reseal_min_period = 4000 diff --git a/parity/cli/mod.rs b/parity/cli/mod.rs index 7fcdd2209..8939b22e1 100644 --- a/parity/cli/mod.rs +++ b/parity/cli/mod.rs @@ -178,6 +178,8 @@ usage! { // -- Sealing/Mining Options flag_author: Option = None, or |c: &Config| otry!(c.mining).author.clone().map(Some), + flag_engine_signer: Option = None, + or |c: &Config| otry!(c.mining).consensus_signer.clone().map(Some), flag_force_sealing: bool = false, or |c: &Config| otry!(c.mining).force_sealing.clone(), flag_reseal_on_txs: String = "own", @@ -367,6 +369,7 @@ struct Dapps { #[derive(Default, Debug, PartialEq, RustcDecodable)] struct Mining { author: Option, + consensus_signer: Option, force_sealing: Option, reseal_on_txs: Option, reseal_min_period: Option, @@ -569,6 +572,7 @@ mod tests { // -- Sealing/Mining Options flag_author: Some("0xdeadbeefcafe0000000000000000000000000001".into()), + flag_engine_signer: Some("0xdeadbeefcafe0000000000000000000000000001".into()), flag_force_sealing: true, flag_reseal_on_txs: "all".into(), flag_reseal_min_period: 4000u64, @@ -738,6 +742,7 @@ mod tests { }), mining: Some(Mining { author: Some("0xdeadbeefcafe0000000000000000000000000001".into()), + consensus_signer: Some("0xdeadbeefcafe0000000000000000000000000001".into()), force_sealing: Some(true), reseal_on_txs: Some("all".into()), reseal_min_period: Some(4000), diff --git a/parity/cli/usage.txt b/parity/cli/usage.txt index b67af6110..2829f4fe1 100644 --- a/parity/cli/usage.txt +++ b/parity/cli/usage.txt @@ -149,6 +149,10 @@ Sealing/Mining Options: for sending block rewards from sealed blocks. NOTE: MINING WILL NOT WORK WITHOUT THIS OPTION. (default: {flag_author:?}) + --engine-signer ADDRESS Specify the address which should be used to + sign consensus messages and issue blocks. + Relevant only to non-PoW chains. + (default: {flag_engine_signer:?}) --force-sealing Force the node to author new blocks as if it were always sealing/mining. (default: {flag_force_sealing}) diff --git a/parity/configuration.rs b/parity/configuration.rs index 37c699521..0ba084673 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -300,6 +300,7 @@ impl Configuration { gas_floor_target: try!(to_u256(&self.args.flag_gas_floor_target)), gas_ceil_target: try!(to_u256(&self.args.flag_gas_cap)), transactions_limit: self.args.flag_tx_queue_size, + consensus_signer: try!(self.consensus_signer()), }; Ok(extras) @@ -309,6 +310,10 @@ impl Configuration { to_address(self.args.flag_etherbase.clone().or(self.args.flag_author.clone())) } + fn consensus_signer(&self) -> Result { + to_address(self.args.flag_engine_signer.clone()) + } + fn format(&self) -> Result, String> { match self.args.flag_format { Some(ref f) => Ok(Some(try!(f.parse()))), diff --git a/parity/helpers.rs b/parity/helpers.rs index ab0dafddd..654270b64 100644 --- a/parity/helpers.rs +++ b/parity/helpers.rs @@ -300,14 +300,14 @@ pub fn password_prompt() -> Result { /// Read a password from password file. pub fn password_from_file(path: String) -> Result { - let passwords = try!(passwords_from_files(vec![path])); + let passwords = try!(passwords_from_files(&[path])); // use only first password from the file passwords.get(0).map(String::to_owned) .ok_or_else(|| "Password file seems to be empty.".to_owned()) } /// Reads passwords from files. Treats each line as a separate password. -pub fn passwords_from_files(files: Vec) -> Result, String> { +pub fn passwords_from_files(files: &[String]) -> Result, String> { let passwords = files.iter().map(|filename| { let file = try!(File::open(filename).map_err(|_| format!("{} Unable to read password file. Ensure it exists and permissions are correct.", filename))); let reader = BufReader::new(&file); diff --git a/parity/params.rs b/parity/params.rs index 3ce07e889..97a5e7b08 100644 --- a/parity/params.rs +++ b/parity/params.rs @@ -204,6 +204,7 @@ pub struct MinerExtras { pub gas_floor_target: U256, pub gas_ceil_target: U256, pub transactions_limit: usize, + pub consensus_signer: Address, } impl Default for MinerExtras { @@ -214,6 +215,7 @@ impl Default for MinerExtras { gas_floor_target: U256::from(4_700_000), gas_ceil_target: U256::from(6_283_184), transactions_limit: 1024, + consensus_signer: Default::default(), } } } diff --git a/parity/run.rs b/parity/run.rs index 2509d1347..332f296c1 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -205,8 +205,10 @@ pub fn execute(cmd: RunCmd, logger: Arc) -> Result<(), String> { sync_config.warp_sync = cmd.warp_sync; sync_config.download_old_blocks = cmd.download_old_blocks; + let passwords = try!(passwords_from_files(&cmd.acc_conf.password_files)); + // prepare account provider - let account_provider = Arc::new(try!(prepare_account_provider(&cmd.dirs, cmd.acc_conf))); + let account_provider = Arc::new(try!(prepare_account_provider(&cmd.dirs, cmd.acc_conf, &passwords))); // let the Engine access the accounts spec.engine.register_account_provider(account_provider.clone()); @@ -218,6 +220,10 @@ pub fn execute(cmd: RunCmd, logger: Arc) -> Result<(), String> { miner.set_gas_ceil_target(cmd.miner_extras.gas_ceil_target); miner.set_extra_data(cmd.miner_extras.extra_data); miner.set_transactions_limit(cmd.miner_extras.transactions_limit); + let consensus_signer = cmd.miner_extras.consensus_signer; + if passwords.into_iter().any(|p| miner.set_consensus_signer(consensus_signer, p).is_ok()) { + return Err(format!("No password found for the consensus signer {}. Make sure valid password is present in files passed using `--password`.", cmd.miner_extras.consensus_signer)); + } // create client config let client_config = to_client_config( @@ -424,19 +430,17 @@ fn daemonize(_pid_file: String) -> Result<(), String> { Err("daemon is no supported on windows".into()) } -fn prepare_account_provider(dirs: &Directories, cfg: AccountsConfig) -> Result { +fn prepare_account_provider(dirs: &Directories, cfg: AccountsConfig, passwords: &[String]) -> Result { use ethcore::ethstore::EthStore; use ethcore::ethstore::dir::DiskDirectory; - let passwords = try!(passwords_from_files(cfg.password_files)); - let dir = Box::new(try!(DiskDirectory::create(dirs.keys.clone()).map_err(|e| format!("Could not open keys directory: {}", e)))); let account_service = AccountProvider::new(Box::new( try!(EthStore::open_with_iterations(dir, cfg.iterations).map_err(|e| format!("Could not open keys directory: {}", e))) )); for a in cfg.unlocked_accounts { - if passwords.iter().find(|p| account_service.unlock_account_permanently(a, (*p).clone()).is_ok()).is_none() { + if passwords.iter().any(|p| account_service.unlock_account_permanently(a, (*p).clone()).is_ok()) { return Err(format!("No password found to unlock account {}. Make sure valid password is present in files passed using `--password`.", a)); } } From 46dd2543e5b104a58bd4dd2aae32c1c4158aae62 Mon Sep 17 00:00:00 2001 From: keorn Date: Mon, 5 Dec 2016 19:27:24 +0000 Subject: [PATCH 04/56] rename rpc to match cli --- rpc/src/v1/tests/mocked/parity_set.rs | 2 +- rpc/src/v1/traits/parity_set.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rpc/src/v1/tests/mocked/parity_set.rs b/rpc/src/v1/tests/mocked/parity_set.rs index fdf3f2d0f..5c249f08b 100644 --- a/rpc/src/v1/tests/mocked/parity_set.rs +++ b/rpc/src/v1/tests/mocked/parity_set.rs @@ -114,7 +114,7 @@ fn rpc_parity_set_consensus_signer() { let io = IoHandler::new(); io.add_delegate(parity_set_client(&client, &miner, &network).to_delegate()); - let request = r#"{"jsonrpc": "2.0", "method": "parity_setConsensusSigner", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681", "password"], "id": 1}"#; + let request = r#"{"jsonrpc": "2.0", "method": "parity_setEngineSigner", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681", "password"], "id": 1}"#; let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#; assert_eq!(io.handle_request_sync(request), Some(response.to_owned())); diff --git a/rpc/src/v1/traits/parity_set.rs b/rpc/src/v1/traits/parity_set.rs index e196a7d21..c41a88033 100644 --- a/rpc/src/v1/traits/parity_set.rs +++ b/rpc/src/v1/traits/parity_set.rs @@ -45,7 +45,7 @@ build_rpc_trait! { fn set_author(&self, H160) -> Result; /// Sets account for signing consensus messages. - #[rpc(name = "parity_setConsensusSigner")] + #[rpc(name = "parity_setEngineSigner")] fn set_consensus_signer(&self, H160, String) -> Result; /// Sets the limits for transaction queue. From 0a2ec319ac5be557493de6df53f381c09fde6108 Mon Sep 17 00:00:00 2001 From: keorn Date: Mon, 5 Dec 2016 21:31:38 +0000 Subject: [PATCH 05/56] rename to engine_signer --- ethcore/src/miner/miner.rs | 2 +- ethcore/src/miner/mod.rs | 2 +- parity/cli/config.full.toml | 2 +- parity/cli/config.toml | 2 +- parity/cli/mod.rs | 6 +++--- parity/configuration.rs | 4 ++-- parity/params.rs | 4 ++-- parity/run.rs | 6 +++--- rpc/src/v1/impls/parity_set.rs | 4 ++-- rpc/src/v1/tests/helpers/miner_service.rs | 2 +- rpc/src/v1/tests/mocked/parity_set.rs | 2 +- rpc/src/v1/traits/parity_set.rs | 2 +- 12 files changed, 19 insertions(+), 19 deletions(-) diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index 3b4223c68..8d1f55567 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -737,7 +737,7 @@ impl MinerService for Miner { *self.author.write() = author; } - fn set_consensus_signer(&self, address: Address, password: String) -> Result<(), AccountError> { + fn set_engine_signer(&self, address: Address, password: String) -> Result<(), AccountError> { if self.seals_internally { if let Some(ref ap) = self.accounts { try!(ap.sign(address.clone(), Some(password.clone()), Default::default())); diff --git a/ethcore/src/miner/mod.rs b/ethcore/src/miner/mod.rs index 26cefb295..8c466581b 100644 --- a/ethcore/src/miner/mod.rs +++ b/ethcore/src/miner/mod.rs @@ -77,7 +77,7 @@ pub trait MinerService : Send + Sync { fn set_author(&self, author: Address); /// Set info necessary to sign consensus messages. - fn set_consensus_signer(&self, address: Address, password: String) -> Result<(), ::account_provider::Error>; + fn set_engine_signer(&self, address: Address, password: String) -> Result<(), ::account_provider::Error>; /// Get the extra_data that we will seal blocks with. fn extra_data(&self) -> Bytes; diff --git a/parity/cli/config.full.toml b/parity/cli/config.full.toml index e2e4aeb5a..4f3e4fa07 100644 --- a/parity/cli/config.full.toml +++ b/parity/cli/config.full.toml @@ -61,7 +61,7 @@ pass = "test_pass" [mining] author = "0xdeadbeefcafe0000000000000000000000000001" -consensus_signer = "0xdeadbeefcafe0000000000000000000000000001" +engine_signer = "0xdeadbeefcafe0000000000000000000000000001" force_sealing = true reseal_on_txs = "all" reseal_min_period = 4000 diff --git a/parity/cli/config.toml b/parity/cli/config.toml index b84c10b22..34bab5b46 100644 --- a/parity/cli/config.toml +++ b/parity/cli/config.toml @@ -40,7 +40,7 @@ pass = "password" [mining] author = "0xdeadbeefcafe0000000000000000000000000001" -consensus_signer = "0xdeadbeefcafe0000000000000000000000000001" +engine_signer = "0xdeadbeefcafe0000000000000000000000000001" force_sealing = true reseal_on_txs = "all" reseal_min_period = 4000 diff --git a/parity/cli/mod.rs b/parity/cli/mod.rs index 8939b22e1..1f6a266b3 100644 --- a/parity/cli/mod.rs +++ b/parity/cli/mod.rs @@ -179,7 +179,7 @@ usage! { flag_author: Option = None, or |c: &Config| otry!(c.mining).author.clone().map(Some), flag_engine_signer: Option = None, - or |c: &Config| otry!(c.mining).consensus_signer.clone().map(Some), + or |c: &Config| otry!(c.mining).engine_signer.clone().map(Some), flag_force_sealing: bool = false, or |c: &Config| otry!(c.mining).force_sealing.clone(), flag_reseal_on_txs: String = "own", @@ -369,7 +369,7 @@ struct Dapps { #[derive(Default, Debug, PartialEq, RustcDecodable)] struct Mining { author: Option, - consensus_signer: Option, + engine_signer: Option, force_sealing: Option, reseal_on_txs: Option, reseal_min_period: Option, @@ -742,7 +742,7 @@ mod tests { }), mining: Some(Mining { author: Some("0xdeadbeefcafe0000000000000000000000000001".into()), - consensus_signer: Some("0xdeadbeefcafe0000000000000000000000000001".into()), + engine_signer: Some("0xdeadbeefcafe0000000000000000000000000001".into()), force_sealing: Some(true), reseal_on_txs: Some("all".into()), reseal_min_period: Some(4000), diff --git a/parity/configuration.rs b/parity/configuration.rs index 0ba084673..bcca3aa58 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -300,7 +300,7 @@ impl Configuration { gas_floor_target: try!(to_u256(&self.args.flag_gas_floor_target)), gas_ceil_target: try!(to_u256(&self.args.flag_gas_cap)), transactions_limit: self.args.flag_tx_queue_size, - consensus_signer: try!(self.consensus_signer()), + engine_signer: try!(self.engine_signer()), }; Ok(extras) @@ -310,7 +310,7 @@ impl Configuration { to_address(self.args.flag_etherbase.clone().or(self.args.flag_author.clone())) } - fn consensus_signer(&self) -> Result { + fn engine_signer(&self) -> Result { to_address(self.args.flag_engine_signer.clone()) } diff --git a/parity/params.rs b/parity/params.rs index 97a5e7b08..25ddc8814 100644 --- a/parity/params.rs +++ b/parity/params.rs @@ -204,7 +204,7 @@ pub struct MinerExtras { pub gas_floor_target: U256, pub gas_ceil_target: U256, pub transactions_limit: usize, - pub consensus_signer: Address, + pub engine_signer: Address, } impl Default for MinerExtras { @@ -215,7 +215,7 @@ impl Default for MinerExtras { gas_floor_target: U256::from(4_700_000), gas_ceil_target: U256::from(6_283_184), transactions_limit: 1024, - consensus_signer: Default::default(), + engine_signer: Default::default(), } } } diff --git a/parity/run.rs b/parity/run.rs index 332f296c1..774dd6271 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -220,9 +220,9 @@ pub fn execute(cmd: RunCmd, logger: Arc) -> Result<(), String> { miner.set_gas_ceil_target(cmd.miner_extras.gas_ceil_target); miner.set_extra_data(cmd.miner_extras.extra_data); miner.set_transactions_limit(cmd.miner_extras.transactions_limit); - let consensus_signer = cmd.miner_extras.consensus_signer; - if passwords.into_iter().any(|p| miner.set_consensus_signer(consensus_signer, p).is_ok()) { - return Err(format!("No password found for the consensus signer {}. Make sure valid password is present in files passed using `--password`.", cmd.miner_extras.consensus_signer)); + let engine_signer = cmd.miner_extras.engine_signer; + if passwords.into_iter().any(|p| miner.set_engine_signer(engine_signer, p).is_ok()) { + return Err(format!("No password found for the consensus signer {}. Make sure valid password is present in files passed using `--password`.", cmd.miner_extras.engine_signer)); } // create client config diff --git a/rpc/src/v1/impls/parity_set.rs b/rpc/src/v1/impls/parity_set.rs index e28f9a573..92de99a1f 100644 --- a/rpc/src/v1/impls/parity_set.rs +++ b/rpc/src/v1/impls/parity_set.rs @@ -116,9 +116,9 @@ impl ParitySet for ParitySetClient where Ok(true) } - fn set_consensus_signer(&self, address: H160, password: String) -> Result { + fn set_engine_signer(&self, address: H160, password: String) -> Result { try!(self.active()); - try!(take_weak!(self.miner).set_consensus_signer(address.into(), password).map_err(Into::into).map_err(errors::from_password_error)); + try!(take_weak!(self.miner).set_engine_signer(address.into(), password).map_err(Into::into).map_err(errors::from_password_error)); Ok(true) } diff --git a/rpc/src/v1/tests/helpers/miner_service.rs b/rpc/src/v1/tests/helpers/miner_service.rs index 6037cdd4a..39fba8406 100644 --- a/rpc/src/v1/tests/helpers/miner_service.rs +++ b/rpc/src/v1/tests/helpers/miner_service.rs @@ -87,7 +87,7 @@ impl MinerService for TestMinerService { *self.author.write() = author; } - fn set_consensus_signer(&self, address: Address, password: String) -> Result<(), AccountError> { + fn set_engine_signer(&self, address: Address, password: String) -> Result<(), AccountError> { *self.author.write() = address; *self.password.write() = password; Ok(()) diff --git a/rpc/src/v1/tests/mocked/parity_set.rs b/rpc/src/v1/tests/mocked/parity_set.rs index 5c249f08b..55f155693 100644 --- a/rpc/src/v1/tests/mocked/parity_set.rs +++ b/rpc/src/v1/tests/mocked/parity_set.rs @@ -107,7 +107,7 @@ fn rpc_parity_set_author() { } #[test] -fn rpc_parity_set_consensus_signer() { +fn rpc_parity_set_engine_signer() { let miner = miner_service(); let client = client_service(); let network = network_service(); diff --git a/rpc/src/v1/traits/parity_set.rs b/rpc/src/v1/traits/parity_set.rs index c41a88033..c40abd01f 100644 --- a/rpc/src/v1/traits/parity_set.rs +++ b/rpc/src/v1/traits/parity_set.rs @@ -46,7 +46,7 @@ build_rpc_trait! { /// Sets account for signing consensus messages. #[rpc(name = "parity_setEngineSigner")] - fn set_consensus_signer(&self, H160, String) -> Result; + fn set_engine_signer(&self, H160, String) -> Result; /// Sets the limits for transaction queue. #[rpc(name = "parity_setTransactionsLimit")] From b089aa7a6b47d955a0d66503c98f239b6eb3dc62 Mon Sep 17 00:00:00 2001 From: keorn Date: Tue, 6 Dec 2016 08:38:41 +0000 Subject: [PATCH 06/56] fix password loading --- parity/run.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/parity/run.rs b/parity/run.rs index 774dd6271..cd2392ae6 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -221,7 +221,7 @@ pub fn execute(cmd: RunCmd, logger: Arc) -> Result<(), String> { miner.set_extra_data(cmd.miner_extras.extra_data); miner.set_transactions_limit(cmd.miner_extras.transactions_limit); let engine_signer = cmd.miner_extras.engine_signer; - if passwords.into_iter().any(|p| miner.set_engine_signer(engine_signer, p).is_ok()) { + if !passwords.into_iter().any(|p| miner.set_engine_signer(engine_signer, p).is_ok()) { return Err(format!("No password found for the consensus signer {}. Make sure valid password is present in files passed using `--password`.", cmd.miner_extras.engine_signer)); } @@ -440,7 +440,7 @@ fn prepare_account_provider(dirs: &Directories, cfg: AccountsConfig, passwords: )); for a in cfg.unlocked_accounts { - if passwords.iter().any(|p| account_service.unlock_account_permanently(a, (*p).clone()).is_ok()) { + if !passwords.iter().any(|p| account_service.unlock_account_permanently(a, (*p).clone()).is_ok()) { return Err(format!("No password found to unlock account {}. Make sure valid password is present in files passed using `--password`.", a)); } } From 71a96588b0c48436af549efa3cf891a67e79512a Mon Sep 17 00:00:00 2001 From: keorn Date: Wed, 7 Dec 2016 10:34:06 +0100 Subject: [PATCH 07/56] add the methods to engines --- ethcore/src/engines/authority_round.rs | 13 ++++++++++--- ethcore/src/engines/basic_authority.rs | 10 ++++++++-- parity/run.rs | 6 ++++-- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/ethcore/src/engines/authority_round.rs b/ethcore/src/engines/authority_round.rs index 02993fe83..a478df6bb 100644 --- a/ethcore/src/engines/authority_round.rs +++ b/ethcore/src/engines/authority_round.rs @@ -73,14 +73,15 @@ pub struct AuthorityRound { step: AtomicUsize, proposed: AtomicBool, account_provider: Mutex>>, + password: RwLock>, } fn header_step(header: &Header) -> Result { - UntrustedRlp::new(&header.seal()[0]).as_val() + UntrustedRlp::new(&header.seal().get(0).expect("was either checked with verify_block_basic or is genesis; has 2 fields; qed (Make sure the spec file has a correct genesis seal)")).as_val() } fn header_signature(header: &Header) -> Result { - UntrustedRlp::new(&header.seal()[1]).as_val::().map(Into::into) + UntrustedRlp::new(&header.seal().get(1).expect("was checked with verify_block_basic; has 2 fields; qed")).as_val::().map(Into::into) } trait AsMillis { @@ -107,6 +108,7 @@ impl AuthorityRound { step: AtomicUsize::new(initial_step), proposed: AtomicBool::new(false), account_provider: Mutex::new(None), + password: RwLock::new(None), }); let handler = TransitionHandler { engine: Arc::downgrade(&engine) }; try!(engine.transition_service.register_handler(Arc::new(handler))); @@ -198,6 +200,7 @@ impl Engine for AuthorityRound { } fn populate_from_parent(&self, header: &mut Header, parent: &Header, gas_floor_target: U256, _gas_ceil_target: U256) { + header.set_difficulty(parent.difficulty().clone()); header.set_gas_limit({ let gas_limit = parent.gas_limit().clone(); let bound_divisor = self.our_params.gas_limit_bound_divisor; @@ -225,7 +228,7 @@ impl Engine for AuthorityRound { if self.is_step_proposer(step, header.author()) { if let Some(ref ap) = *self.account_provider.lock() { // Account should be permanently unlocked, otherwise sealing will fail. - if let Ok(signature) = ap.sign(*header.author(), None, header.bare_hash()) { + if let Ok(signature) = ap.sign(*header.author(), self.password.read().clone(), header.bare_hash()) { trace!(target: "poa", "generate_seal: Issuing a block for step {}.", step); self.proposed.store(true, AtomicOrdering::SeqCst); return Some(vec![encode(&step).to_vec(), encode(&(&*signature as &[u8])).to_vec()]); @@ -308,6 +311,10 @@ impl Engine for AuthorityRound { *self.message_channel.lock() = Some(message_channel); } + fn set_signer(&self, _address: Address, password: String) { + *self.password.write() = Some(password); + } + fn register_account_provider(&self, account_provider: Arc) { *self.account_provider.lock() = Some(account_provider); } diff --git a/ethcore/src/engines/basic_authority.rs b/ethcore/src/engines/basic_authority.rs index 264a2d55a..4db8357e6 100644 --- a/ethcore/src/engines/basic_authority.rs +++ b/ethcore/src/engines/basic_authority.rs @@ -59,6 +59,7 @@ pub struct BasicAuthority { our_params: BasicAuthorityParams, builtins: BTreeMap, account_provider: Mutex>>, + password: RwLock>, } impl BasicAuthority { @@ -68,7 +69,8 @@ impl BasicAuthority { params: params, our_params: our_params, builtins: builtins, - account_provider: Mutex::new(None) + account_provider: Mutex::new(None), + password: RwLock::new(None), } } } @@ -115,7 +117,7 @@ impl Engine for BasicAuthority { let header = block.header(); let message = header.bare_hash(); // account should be pernamently unlocked, otherwise sealing will fail - if let Ok(signature) = ap.sign(*block.header().author(), None, message) { + if let Ok(signature) = ap.sign(*block.header().author(), self.password.read().clone(), message) { return Some(vec![::rlp::encode(&(&*signature as &[u8])).to_vec()]); } else { trace!(target: "basicauthority", "generate_seal: FAIL: accounts secret key unavailable"); @@ -177,6 +179,10 @@ impl Engine for BasicAuthority { t.sender().map(|_|()) // Perform EC recovery and cache sender } + fn set_signer(&self, _address: Address, password: String) { + *self.password.write() = Some(password); + } + fn register_account_provider(&self, ap: Arc) { *self.account_provider.lock() = Some(ap); } diff --git a/parity/run.rs b/parity/run.rs index cd2392ae6..d535b63ee 100644 --- a/parity/run.rs +++ b/parity/run.rs @@ -221,8 +221,10 @@ pub fn execute(cmd: RunCmd, logger: Arc) -> Result<(), String> { miner.set_extra_data(cmd.miner_extras.extra_data); miner.set_transactions_limit(cmd.miner_extras.transactions_limit); let engine_signer = cmd.miner_extras.engine_signer; - if !passwords.into_iter().any(|p| miner.set_engine_signer(engine_signer, p).is_ok()) { - return Err(format!("No password found for the consensus signer {}. Make sure valid password is present in files passed using `--password`.", cmd.miner_extras.engine_signer)); + if engine_signer != Default::default() { + if !passwords.into_iter().any(|p| miner.set_engine_signer(engine_signer, p).is_ok()) { + return Err(format!("No password found for the consensus signer {}. Make sure valid password is present in files passed using `--password`.", engine_signer)); + } } // create client config From 3ae09de0190ededd318fc50e35d2974f85400bc9 Mon Sep 17 00:00:00 2001 From: keorn Date: Wed, 7 Dec 2016 11:40:46 +0100 Subject: [PATCH 08/56] restore is_new_best --- ethcore/src/engines/authority_round.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/ethcore/src/engines/authority_round.rs b/ethcore/src/engines/authority_round.rs index a478df6bb..c78193e3f 100644 --- a/ethcore/src/engines/authority_round.rs +++ b/ethcore/src/engines/authority_round.rs @@ -304,7 +304,16 @@ impl Engine for AuthorityRound { } fn is_new_best_block(&self, _best_total_difficulty: U256, best_header: HeaderView, _parent_details: &BlockDetails, new_header: &HeaderView) -> bool { - new_header.number() > best_header.number() + let new_number = new_header.number(); + let best_number = best_header.number(); + if new_number != best_number { + new_number > best_number + } else { + // Take the oldest step at given height. + let new_step: usize = Rlp::new(&new_header.seal()[0]).as_val(); + let best_step: usize = Rlp::new(&best_header.seal()[0]).as_val(); + new_step < best_step + } } fn register_message_channel(&self, message_channel: IoChannel) { From 21a3cf7b6586d3c14cc8de8dcc5a0e92b65c1d39 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Wed, 7 Dec 2016 11:44:45 +0100 Subject: [PATCH 09/56] Swap order of addressbook & acocunts merge --- rpc/src/v1/impls/parity_accounts.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpc/src/v1/impls/parity_accounts.rs b/rpc/src/v1/impls/parity_accounts.rs index ea927de4e..2631bc3ce 100644 --- a/rpc/src/v1/impls/parity_accounts.rs +++ b/rpc/src/v1/impls/parity_accounts.rs @@ -57,7 +57,7 @@ impl ParityAccounts for ParityAccountsClient where C: MiningBlock let info = try!(store.accounts_info().map_err(|e| errors::account("Could not fetch account info.", e))); let other = store.addresses_info().expect("addresses_info always returns Ok; qed"); - Ok(info.into_iter().chain(other.into_iter()).map(|(a, v)| { + Ok(other.into_iter().chain(info.into_iter()).map(|(a, v)| { let m = map![ "name".to_owned() => to_value(&v.name), "meta".to_owned() => to_value(&v.meta), From f7586109df8ed3cc1c20bd9774a2c4359ed1a903 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Wed, 7 Dec 2016 11:48:08 +0100 Subject: [PATCH 10/56] Ignore meta.deleted for accounts --- js/src/redux/providers/personalActions.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/js/src/redux/providers/personalActions.js b/js/src/redux/providers/personalActions.js index a1e9845db..7b51683b0 100644 --- a/js/src/redux/providers/personalActions.js +++ b/js/src/redux/providers/personalActions.js @@ -27,17 +27,18 @@ export function personalAccountsInfo (accountsInfo) { Object.keys(accountsInfo || {}) .map((address) => Object.assign({}, accountsInfo[address], { address })) - .filter((account) => !account.meta.deleted) .forEach((account) => { if (account.uuid) { accounts[account.address] = account; - } else if (account.meta.wallet) { - account.wallet = true; - wallets[account.address] = account; - } else if (account.meta.contract) { - contracts[account.address] = account; - } else { - contacts[account.address] = account; + } else if (!account.meta.deleted) { + if (account.meta.wallet) { + account.wallet = true; + wallets[account.address] = account; + } else if (account.meta.contract) { + contracts[account.address] = account; + } else { + contacts[account.address] = account; + } } }); From 5bdb6e4f22a9ab6d47b3a7dbcebccd1f4b0bac5b Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Wed, 7 Dec 2016 11:51:48 +0100 Subject: [PATCH 11/56] Ignore meta.deleted for account name display --- js/src/redux/providers/personalActions.js | 17 ++++++++--------- js/src/ui/IdentityName/identityName.js | 2 +- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/js/src/redux/providers/personalActions.js b/js/src/redux/providers/personalActions.js index 7b51683b0..47056af2f 100644 --- a/js/src/redux/providers/personalActions.js +++ b/js/src/redux/providers/personalActions.js @@ -27,18 +27,17 @@ export function personalAccountsInfo (accountsInfo) { Object.keys(accountsInfo || {}) .map((address) => Object.assign({}, accountsInfo[address], { address })) + .filter((account) => account.uuid || !account.meta.deleted) .forEach((account) => { if (account.uuid) { accounts[account.address] = account; - } else if (!account.meta.deleted) { - if (account.meta.wallet) { - account.wallet = true; - wallets[account.address] = account; - } else if (account.meta.contract) { - contracts[account.address] = account; - } else { - contacts[account.address] = account; - } + } else if (account.meta.wallet) { + account.wallet = true; + wallets[account.address] = account; + } else if (account.meta.contract) { + contracts[account.address] = account; + } else { + contacts[account.address] = account; } }); diff --git a/js/src/ui/IdentityName/identityName.js b/js/src/ui/IdentityName/identityName.js index 85ff34a35..8f95ce116 100644 --- a/js/src/ui/IdentityName/identityName.js +++ b/js/src/ui/IdentityName/identityName.js @@ -37,7 +37,7 @@ class IdentityName extends Component { render () { 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); + const hasAccount = account && (account.uuid || !account.meta || !account.meta.deleted); if (!hasAccount && empty) { return null; From 5faa4a85cb926e6036f33d4a1b43155e32026420 Mon Sep 17 00:00:00 2001 From: keorn Date: Wed, 7 Dec 2016 14:49:07 +0100 Subject: [PATCH 12/56] remove dummy type --- ethcore/src/engines/authority_round.rs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/ethcore/src/engines/authority_round.rs b/ethcore/src/engines/authority_round.rs index c78193e3f..f966bd7f6 100644 --- a/ethcore/src/engines/authority_round.rs +++ b/ethcore/src/engines/authority_round.rs @@ -21,7 +21,7 @@ use std::sync::Weak; use std::time::{UNIX_EPOCH, Duration}; use util::*; use ethkey::{verify_address, Signature}; -use rlp::{UntrustedRlp, View, encode}; +use rlp::{UntrustedRlp, Rlp, View, encode}; use account_provider::AccountProvider; use block::*; use spec::CommonParams; @@ -68,7 +68,7 @@ pub struct AuthorityRound { params: CommonParams, our_params: AuthorityRoundParams, builtins: BTreeMap, - transition_service: IoService, + transition_service: IoService<()>, message_channel: Mutex>>, step: AtomicUsize, proposed: AtomicBool, @@ -103,7 +103,7 @@ impl AuthorityRound { params: params, our_params: our_params, builtins: builtins, - transition_service: try!(IoService::::start()), + transition_service: try!(IoService::<()>::start()), message_channel: Mutex::new(None), step: AtomicUsize::new(initial_step), proposed: AtomicBool::new(false), @@ -147,20 +147,17 @@ struct TransitionHandler { engine: Weak, } -#[derive(Clone)] -struct BlockArrived; - const ENGINE_TIMEOUT_TOKEN: TimerToken = 23; -impl IoHandler for TransitionHandler { - fn initialize(&self, io: &IoContext) { +impl IoHandler<()> for TransitionHandler { + fn initialize(&self, io: &IoContext<()>) { if let Some(engine) = self.engine.upgrade() { io.register_timer_once(ENGINE_TIMEOUT_TOKEN, engine.remaining_step_duration().as_millis()) .unwrap_or_else(|e| warn!(target: "poa", "Failed to start consensus step timer: {}.", e)) } } - fn timeout(&self, io: &IoContext, timer: TimerToken) { + fn timeout(&self, io: &IoContext<()>, timer: TimerToken) { if timer == ENGINE_TIMEOUT_TOKEN { if let Some(engine) = self.engine.upgrade() { engine.step.fetch_add(1, AtomicOrdering::SeqCst); From 727ace0561e54fd0fefa7c89937198983e12cfde Mon Sep 17 00:00:00 2001 From: keorn Date: Wed, 7 Dec 2016 15:14:21 +0100 Subject: [PATCH 13/56] add test --- ethcore/src/engines/authority_round.rs | 4 ++-- ethcore/src/engines/basic_authority.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ethcore/src/engines/authority_round.rs b/ethcore/src/engines/authority_round.rs index f966bd7f6..f632c9382 100644 --- a/ethcore/src/engines/authority_round.rs +++ b/ethcore/src/engines/authority_round.rs @@ -391,9 +391,7 @@ mod tests { fn generates_seal_and_does_not_double_propose() { let tap = AccountProvider::transient_provider(); let addr1 = tap.insert_account("1".sha3(), "1").unwrap(); - tap.unlock_account_permanently(addr1, "1".into()).unwrap(); let addr2 = tap.insert_account("2".sha3(), "2").unwrap(); - tap.unlock_account_permanently(addr2, "2".into()).unwrap(); let spec = Spec::new_test_round(); let engine = &*spec.engine; @@ -409,12 +407,14 @@ mod tests { let b2 = OpenBlock::new(engine, Default::default(), false, db2, &genesis_header, last_hashes, addr2, (3141562.into(), 31415620.into()), vec![]).unwrap(); let b2 = b2.close_and_lock(); + engine.set_signer(addr1, "1".into()); if let Some(seal) = engine.generate_seal(b1.block()) { assert!(b1.clone().try_seal(engine, seal).is_ok()); // Second proposal is forbidden. assert!(engine.generate_seal(b1.block()).is_none()); } + engine.set_signer(addr2, "2".into()); if let Some(seal) = engine.generate_seal(b2.block()) { assert!(b2.clone().try_seal(engine, seal).is_ok()); // Second proposal is forbidden. diff --git a/ethcore/src/engines/basic_authority.rs b/ethcore/src/engines/basic_authority.rs index 4db8357e6..1070d3a3d 100644 --- a/ethcore/src/engines/basic_authority.rs +++ b/ethcore/src/engines/basic_authority.rs @@ -257,10 +257,10 @@ mod tests { fn can_generate_seal() { let tap = AccountProvider::transient_provider(); let addr = tap.insert_account("".sha3(), "").unwrap(); - tap.unlock_account_permanently(addr, "".into()).unwrap(); let spec = new_test_authority(); let engine = &*spec.engine; + engine.set_signer(addr, "".into()); engine.register_account_provider(Arc::new(tap)); let genesis_header = spec.genesis_header(); let mut db_result = get_temp_state_db(); From 5f1021822d4180833c085eb9cebd3d76dc0ff7f5 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Wed, 7 Dec 2016 21:38:28 +0100 Subject: [PATCH 14/56] Cleanups on js-precompiled (#3738) * Cleanups on js-precompiled * Combined * Adjust based on Pr comments --- js/scripts/release.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/js/scripts/release.sh b/js/scripts/release.sh index 3ff4a577c..ee2f6e0a6 100755 --- a/js/scripts/release.sh +++ b/js/scripts/release.sh @@ -34,11 +34,16 @@ git fetch origin 2>$GITLOG git checkout -b $BRANCH echo "*** Committing compiled files for $UTCDATE" +mv build ../build.new +git pull origin/$BRANCH -X ours --commit -m "$UTCDATE [merge]" +git rm build/* +git commit -m "$UTCDATE [rm]" +mv -f ../build.new/* build/ +rm -rf ../build.new git add . git commit -m "$UTCDATE" echo "*** Merging remote" -git merge origin/$BRANCH -X ours --commit -m "$UTCDATE [release]" git push origin HEAD:refs/heads/$BRANCH 2>$GITLOG PRECOMPILED_HASH=`git rev-parse HEAD` From 15ec63750ec3adcbef7a1167145ecaab8311c339 Mon Sep 17 00:00:00 2001 From: Arkadiy Paronyan Date: Thu, 8 Dec 2016 11:31:57 +0100 Subject: [PATCH 15/56] Enable Panic=abort (#3423) * Enable panic=abort * Update remaining crate versions to 1.5 * Run tests in release mode * Enable panic=abort for release profile only * Added travis_wait * Travis timeout set to 40 --- .gitlab-ci.yml | 8 ++-- .travis.yml | 5 +-- Cargo.lock | 88 ++++++++++++++++++++-------------------- Cargo.toml | 2 +- dapps/js-glue/Cargo.toml | 2 +- dapps/ui/Cargo.toml | 2 +- db/Cargo.toml | 2 +- devtools/Cargo.toml | 2 +- ethash/Cargo.toml | 2 +- evmjit/Cargo.toml | 2 +- ipc/codegen/Cargo.toml | 2 +- ipc/nano/Cargo.toml | 2 +- ipc/rpc/Cargo.toml | 2 +- rpc/rpctest/Cargo.toml | 2 +- stratum/Cargo.toml | 2 +- test.sh | 2 +- 16 files changed, 63 insertions(+), 64 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 94ac69d2c..2460678d4 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -401,7 +401,7 @@ test-darwin: - git submodule update --init --recursive script: - export RUST_BACKTRACE=1 - - ./test.sh $CARGOFLAGS --no-release + - ./test.sh $CARGOFLAGS tags: - osx allow_failure: true @@ -428,7 +428,7 @@ test-rust-stable: script: - export RUST_BACKTRACE=1 - echo $JS_FILES_MODIFIED - - if [ "$JS_FILES_MODIFIED" = 0 ]; then echo "skip js test"&./test.sh $CARGOFLAGS --no-release; else echo "skip rust test"&./js/scripts/lint.sh&./js/scripts/test.sh&./js/scripts/build.sh; fi + - if [ "$JS_FILES_MODIFIED" = 0 ]; then echo "skip js test"&./test.sh $CARGOFLAGS; else echo "skip rust test"&./js/scripts/lint.sh&./js/scripts/test.sh&./js/scripts/build.sh; fi tags: - rust - rust-stable @@ -457,7 +457,7 @@ test-rust-beta: script: - export RUST_BACKTRACE=1 - echo $JS_FILES_MODIFIED - - ./test.sh $CARGOFLAGS --no-release + - ./test.sh $CARGOFLAGS tags: - rust - rust-beta @@ -471,7 +471,7 @@ test-rust-nightly: - git submodule update --init --recursive script: - export RUST_BACKTRACE=1 - - ./test.sh $CARGOFLAGS --no-release + - ./test.sh $CARGOFLAGS tags: - rust - rust-nightly diff --git a/.travis.yml b/.travis.yml index 6f3fd9933..f1e02396b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ git: matrix: include: - rust: stable - env: RUN_TESTS="true" TEST_OPTIONS="--no-release" + env: RUN_TESTS="true" TEST_OPTIONS="" - rust: stable env: RUN_COVERAGE="true" - rust: stable @@ -71,8 +71,7 @@ install: script: - if [ "$RUN_TESTS" = "true" ]; then ./js/scripts/lint.sh && - ./js/scripts/test.sh && - ./test.sh $TEST_OPTIONS --verbose; + travis_wait 40 ./test.sh $TEST_OPTIONS; fi - if [ "$RUN_COVERAGE" = "true" ]; then ./scripts/cov.sh "$KCOV_CMD"; fi diff --git a/Cargo.lock b/Cargo.lock index 0e1c2b416..8b212a1f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,18 +10,18 @@ dependencies = [ "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.5.0", "ethcore-dapps 1.5.0", - "ethcore-devtools 1.4.0", + "ethcore-devtools 1.5.0", "ethcore-hash-fetch 1.5.0", "ethcore-io 1.5.0", - "ethcore-ipc 1.4.0", - "ethcore-ipc-codegen 1.4.0", + "ethcore-ipc 1.5.0", + "ethcore-ipc-codegen 1.5.0", "ethcore-ipc-hypervisor 1.2.0", - "ethcore-ipc-nano 1.4.0", + "ethcore-ipc-nano 1.5.0", "ethcore-ipc-tests 0.1.0", "ethcore-logger 1.5.0", "ethcore-rpc 1.5.0", "ethcore-signer 1.5.0", - "ethcore-stratum 1.4.0", + "ethcore-stratum 1.5.0", "ethcore-util 1.5.0", "ethsync 1.5.0", "fdlimit 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -273,7 +273,7 @@ dependencies = [ [[package]] name = "ethash" -version = "1.4.0" +version = "1.5.0" dependencies = [ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -291,18 +291,18 @@ dependencies = [ "clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "ethash 1.4.0", + "ethash 1.5.0", "ethcore-bloom-journal 0.1.0", - "ethcore-devtools 1.4.0", + "ethcore-devtools 1.5.0", "ethcore-io 1.5.0", - "ethcore-ipc 1.4.0", - "ethcore-ipc-codegen 1.4.0", - "ethcore-ipc-nano 1.4.0", + "ethcore-ipc 1.5.0", + "ethcore-ipc-codegen 1.5.0", + "ethcore-ipc-nano 1.5.0", "ethcore-util 1.5.0", "ethjson 0.1.0", "ethkey 0.2.0", "ethstore 0.1.0", - "evmjit 1.4.0", + "evmjit 1.5.0", "heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.10.0-a.0 (git+https://github.com/ethcore/hyper)", "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -343,7 +343,7 @@ version = "1.5.0" dependencies = [ "clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "ethcore-devtools 1.4.0", + "ethcore-devtools 1.5.0", "ethcore-hash-fetch 1.5.0", "ethcore-rpc 1.5.0", "ethcore-util 1.5.0", @@ -356,7 +356,7 @@ dependencies = [ "mime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "mime_guess 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-ui 1.4.0", + "parity-ui 1.5.0", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "serde 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -370,7 +370,7 @@ dependencies = [ [[package]] name = "ethcore-devtools" -version = "1.4.0" +version = "1.5.0" dependencies = [ "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -400,9 +400,9 @@ dependencies = [ [[package]] name = "ethcore-ipc" -version = "1.4.0" +version = "1.5.0" dependencies = [ - "ethcore-devtools 1.4.0", + "ethcore-devtools 1.5.0", "ethcore-util 1.5.0", "nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git)", "semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -410,7 +410,7 @@ dependencies = [ [[package]] name = "ethcore-ipc-codegen" -version = "1.4.0" +version = "1.5.0" dependencies = [ "aster 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", "quasi 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -423,9 +423,9 @@ dependencies = [ name = "ethcore-ipc-hypervisor" version = "1.2.0" dependencies = [ - "ethcore-ipc 1.4.0", - "ethcore-ipc-codegen 1.4.0", - "ethcore-ipc-nano 1.4.0", + "ethcore-ipc 1.5.0", + "ethcore-ipc-codegen 1.5.0", + "ethcore-ipc-nano 1.5.0", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git)", "semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -434,9 +434,9 @@ dependencies = [ [[package]] name = "ethcore-ipc-nano" -version = "1.4.0" +version = "1.5.0" dependencies = [ - "ethcore-ipc 1.4.0", + "ethcore-ipc 1.5.0", "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git)", @@ -446,10 +446,10 @@ dependencies = [ name = "ethcore-ipc-tests" version = "0.1.0" dependencies = [ - "ethcore-devtools 1.4.0", - "ethcore-ipc 1.4.0", - "ethcore-ipc-codegen 1.4.0", - "ethcore-ipc-nano 1.4.0", + "ethcore-devtools 1.5.0", + "ethcore-ipc 1.5.0", + "ethcore-ipc-codegen 1.5.0", + "ethcore-ipc-nano 1.5.0", "ethcore-util 1.5.0", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git)", @@ -475,7 +475,7 @@ version = "1.5.0" dependencies = [ "ansi_term 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ethcore-devtools 1.4.0", + "ethcore-devtools 1.5.0", "ethcore-io 1.5.0", "ethcore-util 1.5.0", "ethcrypto 0.1.0", @@ -499,11 +499,11 @@ name = "ethcore-rpc" version = "1.5.0" dependencies = [ "clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)", - "ethash 1.4.0", + "ethash 1.5.0", "ethcore 1.5.0", - "ethcore-devtools 1.4.0", + "ethcore-devtools 1.5.0", "ethcore-io 1.5.0", - "ethcore-ipc 1.4.0", + "ethcore-ipc 1.5.0", "ethcore-util 1.5.0", "ethcrypto 0.1.0", "ethjson 0.1.0", @@ -530,14 +530,14 @@ version = "1.5.0" dependencies = [ "clippy 0.0.103 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "ethcore-devtools 1.4.0", + "ethcore-devtools 1.5.0", "ethcore-io 1.5.0", "ethcore-rpc 1.5.0", "ethcore-util 1.5.0", "jsonrpc-core 4.0.0 (git+https://github.com/ethcore/jsonrpc.git)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-ui 1.4.0", + "parity-ui 1.5.0", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "ws 0.5.3 (git+https://github.com/ethcore/ws-rs.git?branch=mio-upstream-stable)", @@ -545,13 +545,13 @@ dependencies = [ [[package]] name = "ethcore-stratum" -version = "1.4.0" +version = "1.5.0" dependencies = [ "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "ethcore-devtools 1.4.0", - "ethcore-ipc 1.4.0", - "ethcore-ipc-codegen 1.4.0", - "ethcore-ipc-nano 1.4.0", + "ethcore-devtools 1.5.0", + "ethcore-ipc 1.5.0", + "ethcore-ipc-codegen 1.5.0", + "ethcore-ipc-nano 1.5.0", "ethcore-util 1.5.0", "jsonrpc-core 4.0.0 (git+https://github.com/ethcore/jsonrpc.git)", "jsonrpc-tcp-server 0.1.0 (git+https://github.com/ethcore/jsonrpc.git)", @@ -573,7 +573,7 @@ dependencies = [ "eth-secp256k1 0.5.4 (git+https://github.com/ethcore/rust-secp256k1)", "ethcore-bigint 0.1.2", "ethcore-bloom-journal 0.1.0", - "ethcore-devtools 1.4.0", + "ethcore-devtools 1.5.0", "heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -661,9 +661,9 @@ dependencies = [ "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "ethcore 1.5.0", "ethcore-io 1.5.0", - "ethcore-ipc 1.4.0", - "ethcore-ipc-codegen 1.4.0", - "ethcore-ipc-nano 1.4.0", + "ethcore-ipc 1.5.0", + "ethcore-ipc-codegen 1.5.0", + "ethcore-ipc-nano 1.5.0", "ethcore-network 1.5.0", "ethcore-util 1.5.0", "heapsize 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -677,7 +677,7 @@ dependencies = [ [[package]] name = "evmjit" -version = "1.4.0" +version = "1.5.0" dependencies = [ "tiny-keccak 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1254,7 +1254,7 @@ dependencies = [ [[package]] name = "parity-ui" -version = "1.4.0" +version = "1.5.0" dependencies = [ "parity-ui-dev 1.4.0", "parity-ui-precompiled 1.4.0 (git+https://github.com/ethcore/js-precompiled.git)", diff --git a/Cargo.toml b/Cargo.toml index 078d2916c..65bb0dbc6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -88,4 +88,4 @@ name = "parity" [profile.release] debug = false lto = false - +panic = "abort" diff --git a/dapps/js-glue/Cargo.toml b/dapps/js-glue/Cargo.toml index b85122e90..827c67ef5 100644 --- a/dapps/js-glue/Cargo.toml +++ b/dapps/js-glue/Cargo.toml @@ -1,7 +1,7 @@ [package] description = "Base Package for all Parity built-in dapps" name = "parity-dapps-glue" -version = "1.4.0" +version = "1.5.0" license = "GPL-3.0" authors = ["Ethcore "] [build-dependencies] diff --git a/db/Cargo.toml b/db/Cargo.toml index 2b4a19892..9642ed882 100644 --- a/db/Cargo.toml +++ b/db/Cargo.toml @@ -3,7 +3,7 @@ description = "Ethcore Database" homepage = "http://ethcore.io" license = "GPL-3.0" name = "ethcore-db" -version = "1.4.0" +version = "1.5.0" authors = ["Ethcore "] build = "build.rs" diff --git a/devtools/Cargo.toml b/devtools/Cargo.toml index 77b05b4cc..3b648c450 100644 --- a/devtools/Cargo.toml +++ b/devtools/Cargo.toml @@ -3,7 +3,7 @@ description = "Ethcore development/test/build tools" homepage = "http://ethcore.io" license = "GPL-3.0" name = "ethcore-devtools" -version = "1.4.0" +version = "1.5.0" authors = ["Ethcore "] [dependencies] diff --git a/ethash/Cargo.toml b/ethash/Cargo.toml index d2fb37d94..bf1ba990e 100644 --- a/ethash/Cargo.toml +++ b/ethash/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ethash" -version = "1.4.0" +version = "1.5.0" authors = ["arkpar "] [lib] diff --git a/ipc/codegen/Cargo.toml b/ipc/codegen/Cargo.toml index 1c61db49f..2867609d6 100644 --- a/ipc/codegen/Cargo.toml +++ b/ipc/codegen/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ethcore-ipc-codegen" -version = "1.4.0" +version = "1.5.0" authors = ["Nikolay Volf"] license = "GPL-3.0" description = "Macros to auto-generate implementations for ipc call" diff --git a/ipc/nano/Cargo.toml b/ipc/nano/Cargo.toml index b358eb23a..32171bbf4 100644 --- a/ipc/nano/Cargo.toml +++ b/ipc/nano/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ethcore-ipc-nano" -version = "1.4.0" +version = "1.5.0" authors = ["Nikolay Volf "] license = "GPL-3.0" diff --git a/ipc/rpc/Cargo.toml b/ipc/rpc/Cargo.toml index 9e0dfd91b..1aecb3292 100644 --- a/ipc/rpc/Cargo.toml +++ b/ipc/rpc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ethcore-ipc" -version = "1.4.0" +version = "1.5.0" authors = ["Nikolay Volf "] license = "GPL-3.0" diff --git a/rpc/rpctest/Cargo.toml b/rpc/rpctest/Cargo.toml index 37248ccc3..19c7feb7c 100644 --- a/rpc/rpctest/Cargo.toml +++ b/rpc/rpctest/Cargo.toml @@ -1,7 +1,7 @@ [package] description = "Rpc test client." name = "rpctest" -version = "1.4.0" +version = "1.5.0" license = "GPL-3.0" authors = ["Ethcore "] diff --git a/stratum/Cargo.toml b/stratum/Cargo.toml index 28f5208dd..609f4ee9b 100644 --- a/stratum/Cargo.toml +++ b/stratum/Cargo.toml @@ -1,7 +1,7 @@ [package] description = "Ethcore stratum lib" name = "ethcore-stratum" -version = "1.4.0" +version = "1.5.0" license = "GPL-3.0" authors = ["Ethcore "] build = "build.rs" diff --git a/test.sh b/test.sh index 3e9074478..f5a636bab 100755 --- a/test.sh +++ b/test.sh @@ -2,7 +2,7 @@ # Running Parity Full Test Sute FEATURES="json-tests" -OPTIONS="--verbose --release" +OPTIONS="--release" case $1 in --no-json) From cbd5fe7c0745c55e4c4612d41b17e0a1fc10ebdc Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Thu, 8 Dec 2016 14:48:09 +0100 Subject: [PATCH 16/56] Update with -X only for merge (#3745) --- js/scripts/release.sh | 4 ++-- js/scripts/test.js | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 js/scripts/test.js diff --git a/js/scripts/release.sh b/js/scripts/release.sh index ee2f6e0a6..fa62cd249 100755 --- a/js/scripts/release.sh +++ b/js/scripts/release.sh @@ -35,9 +35,9 @@ git checkout -b $BRANCH echo "*** Committing compiled files for $UTCDATE" mv build ../build.new -git pull origin/$BRANCH -X ours --commit -m "$UTCDATE [merge]" +git pull origin/$BRANCH --commit --no-edit -X ours git rm build/* -git commit -m "$UTCDATE [rm]" +git commit -m "$UTCDATE [rm old]" mv -f ../build.new/* build/ rm -rf ../build.new git add . diff --git a/js/scripts/test.js b/js/scripts/test.js new file mode 100644 index 000000000..d29038fa8 --- /dev/null +++ b/js/scripts/test.js @@ -0,0 +1 @@ +// test script From 5d224df2d5ece5632b4b813d0d667fa67a63cdb6 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Thu, 8 Dec 2016 15:02:45 +0100 Subject: [PATCH 17/56] Release script back to using fetch/merge (#3746) * Update with -X only for merge * Release back to using fetch/merge --- js/scripts/release.sh | 6 +++--- js/scripts/test.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/js/scripts/release.sh b/js/scripts/release.sh index fa62cd249..ff09a5ba8 100755 --- a/js/scripts/release.sh +++ b/js/scripts/release.sh @@ -35,13 +35,13 @@ git checkout -b $BRANCH echo "*** Committing compiled files for $UTCDATE" mv build ../build.new -git pull origin/$BRANCH --commit --no-edit -X ours +git merge origin/$BRANCH -X ours --commit -m "$UTCDATE [merge]" git rm build/* -git commit -m "$UTCDATE [rm old]" +git commit -m "$UTCDATE [cleanup]" mv -f ../build.new/* build/ rm -rf ../build.new git add . -git commit -m "$UTCDATE" +git commit -m "$UTCDATE [update]" echo "*** Merging remote" git push origin HEAD:refs/heads/$BRANCH 2>$GITLOG diff --git a/js/scripts/test.js b/js/scripts/test.js index d29038fa8..829d1f8c3 100644 --- a/js/scripts/test.js +++ b/js/scripts/test.js @@ -1 +1 @@ -// test script +// test script 2 From fb80cf6190c3b34c09d65bf966fdeab3c2fdfd8b Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Thu, 8 Dec 2016 15:20:53 +0100 Subject: [PATCH 18/56] Add existing release files before merge (#3747) --- js/scripts/release.sh | 4 +++- js/scripts/test.js | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/js/scripts/release.sh b/js/scripts/release.sh index ff09a5ba8..aaafba87e 100755 --- a/js/scripts/release.sh +++ b/js/scripts/release.sh @@ -35,13 +35,15 @@ git checkout -b $BRANCH echo "*** Committing compiled files for $UTCDATE" mv build ../build.new +git add . +git commit -m "$UTCDATE [update]" git merge origin/$BRANCH -X ours --commit -m "$UTCDATE [merge]" git rm build/* git commit -m "$UTCDATE [cleanup]" mv -f ../build.new/* build/ rm -rf ../build.new git add . -git commit -m "$UTCDATE [update]" +git commit -m "$UTCDATE [release]" echo "*** Merging remote" git push origin HEAD:refs/heads/$BRANCH 2>$GITLOG diff --git a/js/scripts/test.js b/js/scripts/test.js index 829d1f8c3..ded13a298 100644 --- a/js/scripts/test.js +++ b/js/scripts/test.js @@ -1 +1 @@ -// test script 2 +// test script 3 From 328db0c124a59680fc6e13c73832c419f0d0c6f5 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Thu, 8 Dec 2016 15:39:27 +0100 Subject: [PATCH 19/56] Replace build directory completely (#3748) --- js/scripts/release.sh | 6 +++--- js/scripts/test.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/js/scripts/release.sh b/js/scripts/release.sh index aaafba87e..1cf3095ef 100755 --- a/js/scripts/release.sh +++ b/js/scripts/release.sh @@ -38,10 +38,10 @@ mv build ../build.new git add . git commit -m "$UTCDATE [update]" git merge origin/$BRANCH -X ours --commit -m "$UTCDATE [merge]" -git rm build/* +git rm -r build +rm -rf build git commit -m "$UTCDATE [cleanup]" -mv -f ../build.new/* build/ -rm -rf ../build.new +mv ../build.new build git add . git commit -m "$UTCDATE [release]" diff --git a/js/scripts/test.js b/js/scripts/test.js index ded13a298..318fd7c84 100644 --- a/js/scripts/test.js +++ b/js/scripts/test.js @@ -1 +1 @@ -// test script 3 +// test script 4 From 69e010bbf90051488b965746034a0d9dfd408007 Mon Sep 17 00:00:00 2001 From: GitLab Build Bot Date: Thu, 8 Dec 2016 14:46:49 +0000 Subject: [PATCH 20/56] [ci skip] js-precompiled 20161208-144436 --- Cargo.lock | 2 +- js/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8b212a1f4..b05b2755d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1271,7 +1271,7 @@ dependencies = [ [[package]] name = "parity-ui-precompiled" version = "1.4.0" -source = "git+https://github.com/ethcore/js-precompiled.git#1690a80b9f56e33c8344f28eb637bacd97c9da14" +source = "git+https://github.com/ethcore/js-precompiled.git#e5eabdb4f30e9c6bf9b7cb98f0029a71ba202a19" 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 dd4ff1046..c6a099425 100644 --- a/js/package.json +++ b/js/package.json @@ -1,6 +1,6 @@ { "name": "parity.js", - "version": "0.2.97", + "version": "0.2.98", "main": "release/index.js", "jsnext:main": "src/index.js", "author": "Parity Team ", From 715761a7149ffb649244cd7f07c4dc83619e7b65 Mon Sep 17 00:00:00 2001 From: Nicolas Gotchac Date: Thu, 8 Dec 2016 15:53:29 +0100 Subject: [PATCH 21/56] Edit Multisig Wallet settings (#3740) * WIP Sending tokens in multi-sig wallet * Working Token transfer for multi-sig wallet #3282 * Add operation hash to transfer modal * Add existing wallet from address #3282 * Wallet delete redirect to Wallets/Accounts #3282 * Rightly check balance in Transfer // Get all accounts balances #3282 * Fix linting * Better Header UI for Wallet * Use the `~` webpack alias * Use Webpack `~` alias * Add `ETH` format to number typed input * Fix wallet creation hint && eth input type * Update dailylimit #3282 * Fix too long copied message * WIP Wallet settings modification #3282 * WIP edit contract parameters #3282 * Edit Wallet parameters #3282 * Don't show wallets if none * Fix Transfer for Wallet #3282 * Optimized version of contract code * Fix wrong max in Wallet creation // Round gas in API --- js/src/api/format/input.js | 13 +- js/src/contracts/code/wallet.js | 2 +- .../WalletDetails/walletDetails.js | 4 +- .../CreateWallet/WalletInfo/walletInfo.js | 3 +- .../CreateWallet/WalletType/walletType.js | 8 +- .../modals/CreateWallet/createWalletStore.js | 2 +- js/src/modals/Transfer/store.js | 19 +- js/src/modals/Transfer/transfer.js | 7 +- js/src/modals/WalletSettings/index.js | 17 + .../modals/WalletSettings/walletSettings.css | 63 ++++ .../modals/WalletSettings/walletSettings.js | 321 ++++++++++++++++++ .../WalletSettings/walletSettingsStore.js | 306 +++++++++++++++++ js/src/modals/index.js | 4 +- js/src/redux/providers/walletActions.js | 146 ++++---- js/src/ui/CopyToClipboard/copyToClipboard.css | 9 + js/src/ui/CopyToClipboard/copyToClipboard.js | 8 +- js/src/ui/Form/AddressSelect/addressSelect.js | 2 +- js/src/ui/Form/TypedInput/typedInput.css | 27 ++ js/src/ui/Form/TypedInput/typedInput.js | 85 ++++- js/src/util/validation.js | 2 +- js/src/views/Accounts/accounts.js | 4 + .../Wallet/Confirmations/confirmations.js | 62 ++-- js/src/views/Wallet/wallet.js | 38 ++- 23 files changed, 1034 insertions(+), 118 deletions(-) create mode 100644 js/src/modals/WalletSettings/index.js create mode 100644 js/src/modals/WalletSettings/walletSettings.css create mode 100644 js/src/modals/WalletSettings/walletSettings.js create mode 100644 js/src/modals/WalletSettings/walletSettingsStore.js diff --git a/js/src/api/format/input.js b/js/src/api/format/input.js index 6d261c674..16fbd4d2e 100644 --- a/js/src/api/format/input.js +++ b/js/src/api/format/input.js @@ -112,11 +112,15 @@ export function inNumber10 (number) { } export function inNumber16 (number) { - if (isInstanceOf(number, BigNumber)) { - return inHex(number.toString(16)); + const bn = isInstanceOf(number, BigNumber) + ? number + : (new BigNumber(number || 0)); + + if (!bn.isInteger()) { + throw new Error(`[format/input::inNumber16] the given number is not an integer: ${bn.toFormat()}`); } - return inHex((new BigNumber(number || 0)).toString(16)); + return inHex(bn.toString(16)); } export function inOptions (options) { @@ -130,6 +134,9 @@ export function inOptions (options) { case 'gas': case 'gasPrice': + options[key] = inNumber16((new BigNumber(options[key])).round()); + break; + case 'value': case 'nonce': options[key] = inNumber16(options[key]); diff --git a/js/src/contracts/code/wallet.js b/js/src/contracts/code/wallet.js index a4db4459b..94aa04b7b 100644 --- a/js/src/contracts/code/wallet.js +++ b/js/src/contracts/code/wallet.js @@ -19,5 +19,5 @@ * @from https://github.com/ethereum/dapp-bin/blob/dd5c485359074d49f571693ae064ce78970f3d6d/wallet/wallet.sol * @date 22-Nov-2016 @ 15h00 UTC */ -export default '0x606060405234620000005760405162001a0638038062001a06833981016040528080518201919060200180519060200190919080519060200190919050505b805b83835b600060018351016001819055503373ffffffffffffffffffffffffffffffffffffffff166002600161010081101562000000570160005b5081905550600161010260003373ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600090505b825181101562000158578281815181101562000000579060200190602002015173ffffffffffffffffffffffffffffffffffffffff1660028260020161010081101562000000570160005b50819055508060020161010260008584815181101562000000579060200190602002015173ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b806001019050620000b4565b816000819055505b5050508061010581905550620001896200019c6401000000000262001832176401000000009004565b610107819055505b505b505050620001b1565b60006201518042811562000000570490505b90565b61184680620001c06000396000f3606060405236156100f4576000357c010000000000000000000000000000000000000000000000000000000090048063173825d91461015c5780632f54bf6e146101795780634123cb6b146101ac57806352375093146101cf5780635c52c2f5146101f2578063659010e7146102015780637065cb4814610224578063746c917114610241578063797af62714610264578063b20d30a914610297578063b61d27f6146102b4578063b75c7dc614610306578063ba51a6df14610323578063c2cf732614610340578063c41a360a1461037c578063cbf0b0c0146103c3578063f00d4b5d146103e0578063f1736d8614610406575b61015a5b6000341115610157577fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c3334604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a15b5b565b005b34610000576101776004808035906020019091905050610429565b005b34610000576101946004808035906020019091905050610553565b60405180821515815260200191505060405180910390f35b34610000576101b961058b565b6040518082815260200191505060405180910390f35b34610000576101dc610591565b6040518082815260200191505060405180910390f35b34610000576101ff610598565b005b346100005761020e6105d3565b6040518082815260200191505060405180910390f35b346100005761023f60048080359060200190919050506105da565b005b346100005761024e61070d565b6040518082815260200191505060405180910390f35b346100005761027f6004808035906020019091905050610713565b60405180821515815260200191505060405180910390f35b34610000576102b26004808035906020019091905050610abf565b005b34610000576102ec60048080359060200190919080359060200190919080359060200190820180359060200191909192905050610afa565b604051808260001916815260200191505060405180910390f35b34610000576103216004808035906020019091905050610e68565b005b346100005761033e6004808035906020019091905050610f5f565b005b34610000576103646004808035906020019091908035906020019091905050610fe7565b60405180821515815260200191505060405180910390f35b34610000576103976004808035906020019091905050611065565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34610000576103de6004808035906020019091905050611085565b005b346100005761040460048080359060200190919080359060200190919050506110d0565b005b3461000057610413611254565b6040518082815260200191505060405180910390f35b60006000366040518083838082843782019150509250505060405180910390206104528161125b565b1561054d5761010260008473ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054915060008214156104925761054c565b60016001540360005411156104a65761054c565b6000600283610100811015610000570160005b5081905550600061010260008573ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506104f661147f565b6104fe61157a565b7f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da83604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15b5b5b505050565b6000600061010260008473ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541190505b919050565b60015481565b6101075481565b6000366040518083838082843782019150509250505060405180910390206105bf8161125b565b156105cf576000610106819055505b5b5b50565b6101065481565b6000366040518083838082843782019150509250505060405180910390206106018161125b565b156107085761060f82610553565b1561061957610707565b61062161147f565b60fa6001541015156106365761063561157a565b5b60fa60015410151561064757610707565b6001600081548092919060010191905055508173ffffffffffffffffffffffffffffffffffffffff166002600154610100811015610000570160005b508190555060015461010260008473ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c382604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a15b5b5b5050565b60005481565b60008161071f8161125b565b15610ab857600061010860008560001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515610ab65761010860008460001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1661010860008560001916815260200190815260200160002060010154610108600086600019168152602001908152602001600020600201604051808280546001816001161561010002031660029004801561086d5780601f106108425761010080835404028352916020019161086d565b820191906000526020600020905b81548152906001019060200180831161085057829003601f168201915b505091505060006040518083038185876185025a03f192505050507fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a33846101086000876000191681526020019081526020016000206001015461010860008860001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16610108600089600019168152602001908152602001600020600201604051808673ffffffffffffffffffffffffffffffffffffffff168152602001856000191681526020018481526020018373ffffffffffffffffffffffffffffffffffffffff168152602001806020018281038252838181546001816001161561010002031660029004815260200191508054600181600116156101000203166002900480156109ef5780601f106109c4576101008083540402835291602001916109ef565b820191906000526020600020905b8154815290600101906020018083116109d257829003601f168201915b5050965050505050505060405180910390a161010860008460001916815260200190815260200160002060006000820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600182016000905560028201805460018160011615610100020316600290046000825580601f10610a735750610aaa565b601f016020900490600052602060002090810190610aa991905b80821115610aa5576000816000905550600101610a8d565b5090565b5b50505060019150610ab7565b5b5b5b50919050565b600036604051808383808284378201915050925050506040518091039020610ae68161125b565b15610af55781610105819055505b5b5b5050565b6000610b0533610553565b15610e5f57610b13846116c9565b15610bfc577f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd0043385878686604051808673ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018060200182810382528484828181526020019250808284378201915050965050505050505060405180910390a18473ffffffffffffffffffffffffffffffffffffffff168484846040518083838082843782019150509250505060006040518083038185876185025a03f1925050505060006001029050610e5e565b60003643604051808484808284378201915050828152602001935050505060405180910390209050610c2d81610713565b158015610c8b5750600061010860008360001916815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b15610e5d578461010860008360001916815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff02191690836c01000000000000000000000000908102040217905550836101086000836000191681526020019081526020016000206001018190555082826101086000846000191681526020019081526020016000206002019190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610d6657803560ff1916838001178555610d94565b82800160010185558215610d94579182015b82811115610d93578235825591602001919060010190610d78565b5b509050610db991905b80821115610db5576000816000905550600101610d9d565b5090565b50507f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf3281338688878760405180876000191681526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018473ffffffffffffffffffffffffffffffffffffffff168152602001806020018281038252848482818152602001925080828437820191505097505050505050505060405180910390a15b5b5b5b949350505050565b60006000600061010260003373ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205492506000831415610ea957610f59565b8260020a915061010360008560001916815260200190815260200160002090506000828260010154161115610f585780600001600081548092919060010191905055508181600101600082825403925050819055507fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b3385604051808373ffffffffffffffffffffffffffffffffffffffff168152602001826000191681526020019250505060405180910390a15b5b50505050565b600036604051808383808284378201915050925050506040518091039020610f868161125b565b15610fe257600154821115610f9a57610fe1565b81600081905550610fa961147f565b7facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da826040518082815260200191505060405180910390a15b5b5b5050565b6000600060006000610103600087600019168152602001908152602001600020925061010260008673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205491506000821415611048576000935061105c565b8160020a9050600081846001015416141593505b50505092915050565b6000600260018301610100811015610000570160005b505490505b919050565b6000366040518083838082843782019150509250505060405180910390206110ac8161125b565b156110cb578173ffffffffffffffffffffffffffffffffffffffff16ff5b5b5b5050565b60006000366040518083838082843782019150509250505060405180910390206110f98161125b565b1561124d5761110783610553565b156111115761124c565b61010260008573ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549150600082141561114c5761124c565b61115461147f565b8273ffffffffffffffffffffffffffffffffffffffff16600283610100811015610000570160005b5081905550600061010260008673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508161010260008573ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055507fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c8484604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a15b5b5b50505050565b6101055481565b600060006000600061010260003373ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549250600083141561129e57611477565b61010360008660001916815260200190815260200160002091506000826000015414156113555760005482600001819055506000826001018190555061010480548091906001018154818355818115116113245781836000526020600020918201910161132391905b8082111561131f576000816000905550600101611307565b5090565b5b5050508260020181905550846101048360020154815481101561000057906000526020600020900160005b50819055505b8260020a90506000818360010154161415611476577fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda3386604051808373ffffffffffffffffffffffffffffffffffffffff168152602001826000191681526020019250505060405180910390a16001826000015411151561144d5761010461010360008760001916815260200190815260200160002060020154815481101561000057906000526020600020900160005b5060009055610103600086600019168152602001908152602001600020600060008201600090556001820160009055600282016000905550506001935061147756611475565b8160000160008154809291906001900391905055508082600101600082825417925050819055505b5b5b505050919050565b60006000610104805490509150600090505b8181101561156d57610108600061010483815481101561000057906000526020600020900160005b505460001916815260200190815260200160002060006000820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600182016000905560028201805460018160011615610100020316600290046000825580601f10611527575061155e565b601f01602090049060005260206000209081019061155d91905b80821115611559576000816000905550600101611541565b5090565b5b5050505b806001019050611491565b61157561174f565b5b5050565b6000600190505b6001548110156116c5575b600154811080156115b057506000600282610100811015610000570160005b505414155b156115c257808060010191505061158c565b5b60016001541180156115e9575060006002600154610100811015610000570160005b5054145b1561160657600160008154809291906001900391905055506115c3565b6001548110801561162c575060006002600154610100811015610000570160005b505414155b801561164a57506000600282610100811015610000570160005b5054145b156116c0576002600154610100811015610000570160005b5054600282610100811015610000570160005b5081905550806101026000600284610100811015610000570160005b505481526020019081526020016000208190555060006002600154610100811015610000570160005b50819055505b611581565b5b50565b60006116d433610553565b1561174957610107546116e5611832565b1115611704576000610106819055506116fc611832565b610107819055505b610106548261010654011015801561172457506101055482610106540111155b1561174357816101066000828254019250508190555060019050611748565b600090505b5b5b919050565b60006000610104805490509150600090505b818110156117f357600060010261010482815481101561000057906000526020600020900160005b5054600019161415156117e757610103600061010483815481101561000057906000526020600020900160005b5054600019168152602001908152602001600020600060008201600090556001820160009055600282016000905550505b5b806001019050611761565b6101048054600082559060005260206000209081019061182b91905b8082111561182757600081600090555060010161180f565b5090565b5b505b5050565b600062015180428115610000570490505b9056'; +export default '0x606060405234610000576040516113bb3803806113bb83398101604090815281516020830151918301519201915b805b83835b815160019081019055600033600160a060020a03166003825b505550600160a060020a033316600090815261010260205260408120600190555b82518110156100ee57828181518110156100005790602001906020020151600160a060020a0316600282600201610100811015610000570160005b5081905550806002016101026000858481518110156100005790602001906020020151600160a060020a03168152602001908152602001600020819055505b60010161006c565b60008290555b50505061010581905561011264010000000061127861012182021704565b610107555b505b50505061012b565b6201518042045b90565b611282806101396000396000f3606060405236156100da5760e060020a6000350463173825d981146101305780632f54bf6e146101425780634123cb6b1461016657806352375093146101855780635c52c2f5146101a4578063659010e7146101b35780637065cb48146101d2578063746c9171146101e4578063797af62714610203578063b20d30a914610227578063b61d27f614610239578063b75c7dc61461026b578063ba51a6df1461027d578063c2cf73261461028f578063c41a360a146102b6578063cbf0b0c0146102e2578063f00d4b5d146102f4578063f1736d8614610309575b61012e5b600034111561012b5760408051600160a060020a033316815234602082015281517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c929181900390910190a15b5b565b005b346100005761012e600435610328565b005b3461000057610152600435610415565b604080519115158252519081900360200190f35b3461000057610173610436565b60408051918252519081900360200190f35b346100005761017361043c565b60408051918252519081900360200190f35b346100005761012e610443565b005b346100005761017361047b565b60408051918252519081900360200190f35b346100005761012e600435610482565b005b3461000057610173610571565b60408051918252519081900360200190f35b3461000057610152600435610577565b604080519115158252519081900360200190f35b346100005761012e6004356107e3565b005b34610000576101736004803590602480359160443591820191013561081c565b60408051918252519081900360200190f35b346100005761012e600435610ab3565b005b346100005761012e600435610b5e565b005b3461000057610152600435602435610be0565b604080519115158252519081900360200190f35b34610000576102c6600435610c35565b60408051600160a060020a039092168252519081900360200190f35b346100005761012e600435610c55565b005b346100005761012e600435602435610c93565b005b3461000057610173610d8c565b60408051918252519081900360200190f35b600060003660405180838380828437820191505092505050604051809103902061035181610d93565b1561040e57600160a060020a03831660009081526101026020526040902054915081151561037e5761040e565b60016001540360005411156103925761040e565b6000600283610100811015610000570160005b5055600160a060020a038316600090815261010260205260408120556103c9610f32565b6103d1611002565b60408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a15b5b5b505050565b600160a060020a03811660009081526101026020526040812054115b919050565b60015481565b6101075481565b60003660405180838380828437820191505092505050604051809103902061046a81610d93565b15610476576000610106555b5b5b50565b6101065481565b6000366040518083838082843782019150509250505060405180910390206104a981610d93565b1561056b576104b782610415565b156104c15761056b565b6104c9610f32565b60015460fa90106104dc576104dc611002565b5b60015460fa90106104ed5761056b565b60018054810190819055600160a060020a03831690600290610100811015610000570160005b5055600154600160a060020a03831660008181526101026020908152604091829020939093558051918252517f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3929181900390910190a15b5b5b5050565b60005481565b60008161058381610d93565b156107da5760008381526101086020526040902054600160a060020a0316156107da5760008381526101086020526040908190208054600180830154935160029384018054600160a060020a0390941695949093919283928592918116156101000260001901160480156106385780601f1061060d57610100808354040283529160200191610638565b820191906000526020600020905b81548152906001019060200180831161061b57829003601f168201915b505091505060006040518083038185876185025a03f15050506000848152610108602090815260409182902060018082015482548551600160a060020a033381811683529682018c905296810183905295166060860181905260a06080870181815260029586018054958616156101000260001901909516959095049087018190527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a975094958a95929491939290919060c08301908490801561073d5780601f106107125761010080835404028352916020019161073d565b820191906000526020600020905b81548152906001019060200180831161072057829003601f168201915b5050965050505050505060405180910390a16000838152610108602052604081208054600160a060020a0319168155600180820183905560028083018054858255939493909281161561010002600019011604601f81901061079f57506107d1565b601f0160209004906000526020600020908101906107d191905b808211156107cd57600081556001016107b9565b5090565b5b505050600191505b5b5b5b50919050565b60003660405180838380828437820191505092505050604051809103902061080a81610d93565b1561056b576101058290555b5b5b5050565b600061082733610415565b15610aa85761083584611131565b156108f3577f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd00433858786866040518086600160a060020a0316815260200185815260200184600160a060020a0316815260200180602001828103825284848281815260200192508082843760405192018290039850909650505050505050a184600160a060020a03168484846040518083838082843782019150509250505060006040518083038185876185025a03f15060009350610aa892505050565b6000364360405180848480828437820191505082815260200193505050506040518091039020905061092481610577565b158015610947575060008181526101086020526040902054600160a060020a0316155b15610aa857600081815261010860209081526040822080546c01000000000000000000000000808a0204600160a060020a0319909116178155600180820188905560029182018054818652948490209094601f928116156101000260001901169290920481019290920481019185919087908390106109d15782800160ff198235161785556109fe565b828001600101855582156109fe579182015b828111156109fe5782358255916020019190600101906109e3565b5b50610a1f9291505b808211156107cd57600081556001016107b9565b5090565b50507f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf32813386888787604051808760001916815260200186600160a060020a0316815260200185815260200184600160a060020a031681526020018060200182810382528484828181526020019250808284376040519201829003995090975050505050505050a15b5b5b5b949350505050565b600160a060020a033316600090815261010260205260408120549080821515610adb57610b57565b50506000828152610103602052604081206001810154600284900a929083161115610b575780546001908101825581018054839003905560408051600160a060020a03331681526020810186905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5b50505050565b600036604051808383808284378201915050925050506040518091039020610b8581610d93565b1561056b57600154821115610b995761056b565b6000829055610ba6610f32565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15b5b5b5050565b600082815261010360209081526040808320600160a060020a038516845261010290925282205482811515610c185760009350610c2c565b8160020a9050808360010154166000141593505b50505092915050565b6000600282600101610100811015610000570160005b505490505b919050565b600036604051808383808284378201915050925050506040518091039020610c7c81610d93565b1561056b5781600160a060020a0316ff5b5b5b5050565b6000600036604051808383808284378201915050925050506040518091039020610cbc81610d93565b15610b5757610cca83610415565b15610cd457610b57565b600160a060020a038416600090815261010260205260409020549150811515610cfc57610b57565b610d04610f32565b82600160a060020a0316600283610100811015610000570160005b5055600160a060020a0380851660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b5b5b50505050565b6101055481565b600160a060020a033316600090815261010260205260408120548180821515610dbb57610f28565b60008581526101036020526040902080549092501515610e4f576000805483556001808401919091556101048054918201808255828015829011610e2457600083815260209020610e249181019083015b808211156107cd57600081556001016107b9565b5090565b5b50505060028301819055610104805487929081101561000057906000526020600020900160005b50555b8260020a90508082600101541660001415610f285760408051600160a060020a03331681526020810187905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a1815460019011610f155760008581526101036020526040902060020154610104805490919081101561000057906000526020600020900160005b506000908190558581526101036020526040812081815560018082018390556002909101919091559350610f2856610f28565b8154600019018255600182018054821790555b5b5b505050919050565b6101045460005b81811015610ff557610108600061010483815481101561000057906000526020600020900160005b50548152602081019190915260400160009081208054600160a060020a0319168155600180820183905560028083018054858255939493909281161561010002600019011604601f819010610fb65750610fe8565b601f016020900490600052602060002090810190610fe891905b808211156107cd57600081556001016107b9565b5090565b5b5050505b600101610f39565b61056b6111a4565b5b5050565b60015b600154811015610476575b600154811080156110325750600281610100811015610000570160005b505415155b1561103f57600101611010565b5b600160015411801561106457506002600154610100811015610000570160005b5054155b156110785760018054600019019055611040565b6001548110801561109c57506002600154610100811015610000570160005b505415155b80156110b85750600281610100811015610000570160005b5054155b15611128576002600154610100811015610000570160005b5054600282610100811015610000570160005b5055806101026000600283610100811015610000570160005b505481526020019081526020016000208190555060006002600154610100811015610000570160005b50555b611005565b5b50565b600061113c33610415565b15610431576101075461114d611278565b111561116657600061010655611161611278565b610107555b610106548281011080159061118357506101055482610106540111155b1561119957506101068054820190556001610431565b5060005b5b5b919050565b6101045460005b818110156112215761010481815481101561000057906000526020600020900160005b50541561121857610103600061010483815481101561000057906000526020600020900160005b505481526020810191909152604001600090812081815560018101829055600201555b5b6001016111ab565b610104805460008083559190915261040e907f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b808211156107cd57600081556001016107b9565b5090565b5b505b5050565b6201518042045b9056'; diff --git a/js/src/modals/CreateWallet/WalletDetails/walletDetails.js b/js/src/modals/CreateWallet/WalletDetails/walletDetails.js index 5d581b81d..314425dcf 100644 --- a/js/src/modals/CreateWallet/WalletDetails/walletDetails.js +++ b/js/src/modals/CreateWallet/WalletDetails/walletDetails.js @@ -117,15 +117,17 @@ export default class WalletDetails extends Component { onChange={ this.onRequiredChange } param={ parseAbiType('uint') } min={ 1 } + max={ wallet.owners.length + 1 } /> diff --git a/js/src/modals/CreateWallet/WalletInfo/walletInfo.js b/js/src/modals/CreateWallet/WalletInfo/walletInfo.js index 344f4e09a..bbbe5877f 100644 --- a/js/src/modals/CreateWallet/WalletInfo/walletInfo.js +++ b/js/src/modals/CreateWallet/WalletInfo/walletInfo.js @@ -17,6 +17,7 @@ import React, { Component, PropTypes } from 'react'; import { CompletedStep, IdentityIcon, CopyToClipboard } from '~/ui'; +import { fromWei } from '~/api/util/wei'; import styles from '../createWallet.css'; @@ -62,7 +63,7 @@ export default class WalletInfo extends Component { { required } owners are required to confirm a transaction.

- The daily limit is set to { daylimit }. + The daily limit is set to { fromWei(daylimit).toFormat() } ETH.

); diff --git a/js/src/modals/CreateWallet/WalletType/walletType.js b/js/src/modals/CreateWallet/WalletType/walletType.js index e77d58fc6..868c6ad9b 100644 --- a/js/src/modals/CreateWallet/WalletType/walletType.js +++ b/js/src/modals/CreateWallet/WalletType/walletType.js @@ -43,7 +43,13 @@ export default class WalletType extends Component { return [ { label: 'Multi-Sig wallet', key: 'MULTISIG', - description: 'A standard multi-signature Wallet' + description: ( + + Create/Deploy a + standard multi-signature + Wallet + + ) }, { label: 'Watch a wallet', key: 'WATCH', diff --git a/js/src/modals/CreateWallet/createWalletStore.js b/js/src/modals/CreateWallet/createWalletStore.js index f5e2f1855..d8c308a12 100644 --- a/js/src/modals/CreateWallet/createWalletStore.js +++ b/js/src/modals/CreateWallet/createWalletStore.js @@ -16,7 +16,7 @@ import { observable, computed, action, transaction } from 'mobx'; -import { validateUint, validateAddress, validateName } from '../../util/validation'; +import { validateUint, validateAddress, validateName } from '~/util/validation'; import { ERROR_CODES } from '~/api/transport/error'; import Contract from '~/api/contract'; diff --git a/js/src/modals/Transfer/store.js b/js/src/modals/Transfer/store.js index a0c7967b9..8f8baf55f 100644 --- a/js/src/modals/Transfer/store.js +++ b/js/src/modals/Transfer/store.js @@ -23,7 +23,7 @@ import { bytesToHex } from '~/api/util/format'; import Contract from '~/api/contract'; import ERRORS from './errors'; import { ERROR_CODES } from '~/api/transport/error'; -import { DEFAULT_GAS, DEFAULT_GASPRICE, MAX_GAS_ESTIMATION } from '../../util/constants'; +import { DEFAULT_GAS, DEFAULT_GASPRICE, MAX_GAS_ESTIMATION } from '~/util/constants'; const TITLES = { transfer: 'transfer details', @@ -116,7 +116,6 @@ export default class TransferStore { this.api = api; const { account, balance, gasLimit, senders, onClose, newError, sendersBalances } = props; - this.account = account; this.balance = balance; this.gasLimit = gasLimit; @@ -412,34 +411,38 @@ export default class TransferStore { return; } - const { gas, gasPrice, tag, valueAll, isEth } = this; + const { gas, gasPrice, tag, valueAll, isEth, isWallet } = this; const gasTotal = new BigNumber(gasPrice || 0).mul(new BigNumber(gas || 0)); const availableEth = new BigNumber(balance.tokens[0].value); const senderBalance = this.balance.tokens.find((b) => tag === b.token.tag); - const available = new BigNumber(senderBalance.value); const format = new BigNumber(senderBalance.token.format || 1); + const available = isWallet + ? this.api.util.fromWei(new BigNumber(senderBalance.value)) + : (new BigNumber(senderBalance.value)).div(format); let { value, valueError } = this; let totalEth = gasTotal; let totalError = null; if (valueAll) { - if (isEth) { + if (isEth && !isWallet) { const bn = this.api.util.fromWei(availableEth.minus(gasTotal)); value = (bn.lt(0) ? new BigNumber(0.0) : bn).toString(); + } else if (isEth) { + value = (available.lt(0) ? new BigNumber(0.0) : available).toString(); } else { - value = available.div(format).toString(); + value = available.toString(); } } - if (isEth) { + if (isEth && !isWallet) { totalEth = totalEth.plus(this.api.util.toWei(value || 0)); } - if (new BigNumber(value || 0).gt(available.div(format))) { + if (new BigNumber(value || 0).gt(available)) { valueError = ERRORS.largeAmount; } else if (valueError === ERRORS.largeAmount) { valueError = null; diff --git a/js/src/modals/Transfer/transfer.js b/js/src/modals/Transfer/transfer.js index 402e3ae4f..e1e2a0951 100644 --- a/js/src/modals/Transfer/transfer.js +++ b/js/src/modals/Transfer/transfer.js @@ -139,8 +139,8 @@ class Transfer extends Component { ? (

-

- This transaction needs confirmation from other owners. +

+

This transaction needs confirmation from other owners.

-

+
) : null @@ -298,7 +298,6 @@ function mapStateToProps (initState, initProps) { return (state) => { const { gasLimit } = state.nodeStatus; const sendersBalances = senders ? pick(state.balances.balances, Object.keys(senders)) : null; - return { gasLimit, wallet, senders, sendersBalances }; }; } diff --git a/js/src/modals/WalletSettings/index.js b/js/src/modals/WalletSettings/index.js new file mode 100644 index 000000000..9b15a5f3b --- /dev/null +++ b/js/src/modals/WalletSettings/index.js @@ -0,0 +1,17 @@ +// 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 . + +export default from './walletSettings'; diff --git a/js/src/modals/WalletSettings/walletSettings.css b/js/src/modals/WalletSettings/walletSettings.css new file mode 100644 index 000000000..ae52013cd --- /dev/null +++ b/js/src/modals/WalletSettings/walletSettings.css @@ -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 . +*/ + +.splitInput { + display: flex; + flex-direction: row; + + > * { + flex: 1; + + margin: 0 0.25em; + + &:first-child { + margin-left: 0; + } + + &:last-child { + margin-right: 0; + } + } +} + +.change { + background-color: rgba(255, 255, 255, 0.1); + padding: 0.75em 1.75em; + margin-bottom: 1em; + + &.add { + background-color: rgba(139, 195, 74, 0.5); + } + + &.remove { + background-color: rgba(244, 67, 54, 0.5); + } + + .label { + text-transform: uppercase; + margin-bottom: 0.5em; + margin-left: -1em; + font-size: 0.8em; + } +} + +.eth:after { + content: 'ETH'; + font-size: 0.75em; + margin-left: 0.125em; +} + diff --git a/js/src/modals/WalletSettings/walletSettings.js b/js/src/modals/WalletSettings/walletSettings.js new file mode 100644 index 000000000..1b2b2cc1a --- /dev/null +++ b/js/src/modals/WalletSettings/walletSettings.js @@ -0,0 +1,321 @@ +// 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 . + +import React, { Component, PropTypes } from 'react'; +import { connect } from 'react-redux'; +import { observer } from 'mobx-react'; +import { pick } from 'lodash'; + +import ActionDone from 'material-ui/svg-icons/action/done'; +import ContentClear from 'material-ui/svg-icons/content/clear'; +import NavigationArrowForward from 'material-ui/svg-icons/navigation/arrow-forward'; +import { parseAbiType } from '~/util/abi'; + +import { Button, Modal, TxHash, BusyStep, Form, TypedInput, InputAddress, AddressSelect } from '~/ui'; +import { fromWei } from '~/api/util/wei'; + +import WalletSettingsStore from './walletSettingsStore.js'; +import styles from './walletSettings.css'; + +@observer +class WalletSettings extends Component { + static contextTypes = { + api: PropTypes.object.isRequired + }; + + static propTypes = { + accounts: PropTypes.object.isRequired, + wallet: PropTypes.object.isRequired, + onClose: PropTypes.func.isRequired, + senders: PropTypes.object.isRequired + }; + + store = new WalletSettingsStore(this.context.api, this.props.wallet); + + render () { + const { stage, steps, waiting, rejected } = this.store; + + if (rejected) { + return ( + + + + ); + } + + return ( + s.title) } + waiting={ waiting } + > + { this.renderPage() } + + ); + } + + renderPage () { + const { step } = this.store; + + switch (step) { + case 'SENDING': + return ( + + { + this.store.requests.map((req) => { + const key = req.id; + + if (req.txhash) { + return (); + } + + if (req.rejected) { + return (

The transaction #{parseInt(key, 16)} has been rejected

); + } + }) + } +
+ ); + + case 'CONFIRMATION': + const { changes } = this.store; + + return ( +
+

You are about to make the following modifications

+
+ { this.renderChanges(changes) } +
+
+ ); + + default: + case 'EDIT': + const { wallet, errors } = this.store; + const { accounts, senders } = this.props; + + return ( +
+

+ In order to edit this contract's settings, at + least { this.store.initialWallet.require.toNumber() } owners have to + send the very same modifications. + Otherwise, no modification will be taken into account... +

+ + + + + +
+ + + +
+ + ); + } + } + + renderChanges (changes) { + return changes.map((change, index) => ( +
+ { this.renderChange(change) } +
+ )); + } + + renderChange (change) { + const { accounts } = this.props; + + switch (change.type) { + case 'dailylimit': + return ( +
+
Change Daily Limit
+
+ from + { fromWei(change.initial).toFormat() } + + to + { fromWei(change.value).toFormat() } + +
+
+ ); + + case 'require': + return ( +
+
Change Required Owners
+
+ from + { change.initial.toNumber() } + to + { change.value.toNumber() } +
+
+ ); + + case 'add_owner': + return ( +
+
Add Owner
+
+ +
+
+ ); + + case 'remove_owner': + return ( +
+
Remove Owner
+
+ +
+
+ ); + } + } + + renderDialogActions () { + const { onClose } = this.props; + const { step, hasErrors, rejected, onNext, send, done } = this.store; + + const cancelBtn = ( +