From 5b2d726a024e7fc42b65fa39f820904a4cfd0b50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Thu, 14 Apr 2016 14:12:04 +0200 Subject: [PATCH 1/9] Changing cors header to be optional --- Cargo.lock | 2 +- parity/main.rs | 13 ++++++------- rpc/src/lib.rs | 4 ++-- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7c1bdbfaf..e058b7b59 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -538,7 +538,7 @@ dependencies = [ [[package]] name = "jsonrpc-http-server" version = "5.0.1" -source = "git+https://github.com/debris/jsonrpc-http-server.git#239066b94660a1af24c8b2efc16e800f9c7cce18" +source = "git+https://github.com/debris/jsonrpc-http-server.git#054b9b92b0c209b25a92e382b40a240818e4810a" dependencies = [ "hyper 0.9.0-mio (git+https://github.com/hyperium/hyper?branch=mio)", "jsonrpc-core 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/parity/main.rs b/parity/main.rs index 8c4a9ddf0..2f36468f6 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -133,8 +133,7 @@ API and Console Options: --jsonrpc-interface IP Specify the hostname portion of the JSONRPC API server, IP should be an interface's IP address, or all (all interfaces) or local [default: local]. - --jsonrpc-cors URL Specify CORS header for JSON-RPC API responses - [default: null]. + --jsonrpc-cors URL Specify CORS header for JSON-RPC API responses. --jsonrpc-apis APIS Specify the APIs available through the JSONRPC interface. APIS is a comma-delimited list of API name. Possible name are web3, eth and net. @@ -242,7 +241,7 @@ struct Args { flag_jsonrpc: bool, flag_jsonrpc_interface: String, flag_jsonrpc_port: u16, - flag_jsonrpc_cors: String, + flag_jsonrpc_cors: Option, flag_jsonrpc_apis: String, flag_webapp: bool, flag_webapp_port: u16, @@ -307,7 +306,7 @@ fn setup_rpc_server( secret_store: Arc, miner: Arc, url: &SocketAddr, - cors_domain: &str, + cors_domain: Option, apis: Vec<&str>, ) -> RpcServer { use rpc::v1::*; @@ -380,7 +379,7 @@ fn setup_rpc_server( _secret_store: Arc, _miner: Arc, _url: &str, - _cors_domain: &str, + _cors_domain: Option, _apis: Vec<&str>, ) -> ! { die!("Your Parity version has been compiled without JSON-RPC support.") @@ -713,7 +712,7 @@ impl Configuration { self.args.flag_rpcport.unwrap_or(self.args.flag_jsonrpc_port) ); let addr = SocketAddr::from_str(&url).unwrap_or_else(|_| die!("{}: Invalid JSONRPC listen host/port given.", url)); - let cors_domain = self.args.flag_rpccorsdomain.as_ref().unwrap_or(&self.args.flag_jsonrpc_cors); + let cors_domain = self.args.flag_jsonrpc_cors.clone().or(self.args.flag_rpccorsdomain.clone()); Some(setup_rpc_server( service.client(), @@ -721,7 +720,7 @@ impl Configuration { account_service.clone(), miner.clone(), &addr, - &cors_domain, + cors_domain, apis.split(',').collect() )) } else { diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs index f059750d2..f79cbe828 100644 --- a/rpc/src/lib.rs +++ b/rpc/src/lib.rs @@ -58,8 +58,8 @@ impl RpcServer { } /// Start server asynchronously and returns result with `Server` handle on success or an error. - pub fn start_http(&self, addr: &SocketAddr, cors_domain: &str) -> Result { + pub fn start_http(&self, addr: &SocketAddr, cors_domain: Option) -> Result { let cors_domain = cors_domain.to_owned(); - Server::start(addr, self.handler.clone(), jsonrpc_http_server::AccessControlAllowOrigin::Value(cors_domain)) + Server::start(addr, self.handler.clone(), cors_domain.map(jsonrpc_http_server::AccessControlAllowOrigin::Value)) } } From 313e77fc3bd6cbaee18b8eea252fbcf0d4379d80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Thu, 14 Apr 2016 19:30:53 +0200 Subject: [PATCH 2/9] Bumping jsonrpc-http-server --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index e058b7b59..509e60aa4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -538,7 +538,7 @@ dependencies = [ [[package]] name = "jsonrpc-http-server" version = "5.0.1" -source = "git+https://github.com/debris/jsonrpc-http-server.git#054b9b92b0c209b25a92e382b40a240818e4810a" +source = "git+https://github.com/debris/jsonrpc-http-server.git#e728f2e080799b7a62b0b5cf5fa9d4ad65cd8c96" dependencies = [ "hyper 0.9.0-mio (git+https://github.com/hyperium/hyper?branch=mio)", "jsonrpc-core 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", From d909bc05c4a41658d998bdbe214237503c09bb7c Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 14 Apr 2016 12:01:12 -0700 Subject: [PATCH 3/9] Sensible gas limits for eth_sendTransaction (#953) * Sensible gas limits for eth_sendTransaction Fixes #859 * Compile fix. * Remove !. --- miner/src/lib.rs | 5 ++++- miner/src/miner.rs | 4 ++++ parity/main.rs | 4 ++-- rpc/src/v1/impls/eth.rs | 13 +++---------- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/miner/src/lib.rs b/miner/src/lib.rs index 27f914181..9ba2cdc1c 100644 --- a/miner/src/lib.rs +++ b/miner/src/lib.rs @@ -132,8 +132,11 @@ pub trait MinerService : Send + Sync { /// Returns highest transaction nonce for given address. fn last_nonce(&self, address: &Address) -> Option; - /// Suggested gas price + /// Suggested gas price. fn sensible_gas_price(&self) -> U256 { x!(20000000000u64) } + + /// Suggested gas limit. + fn sensible_gas_limit(&self) -> U256 { x!(21000) } } /// Mining status diff --git a/miner/src/miner.rs b/miner/src/miner.rs index 7f7dc2980..5169be2c5 100644 --- a/miner/src/miner.rs +++ b/miner/src/miner.rs @@ -201,6 +201,10 @@ impl MinerService for Miner { *self.transaction_queue.lock().unwrap().minimal_gas_price() * x!(110) / x!(100) } + fn sensible_gas_limit(&self) -> U256 { + *self.gas_floor_target.read().unwrap() / x!(5) + } + /// Get the author that we will seal blocks as. fn author(&self) -> Address { *self.author.read().unwrap() diff --git a/parity/main.rs b/parity/main.rs index 8c4a9ddf0..bbf7e27a9 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -622,9 +622,9 @@ impl Configuration { let mut secret_store = SecretStore::new_in(Path::new(&self.keys_path())); if self.args.cmd_new { println!("Please note that password is NOT RECOVERABLE."); - println!("Type password: "); + print!("Type password: "); let password = read_password().unwrap(); - println!("Repeat password: "); + print!("Repeat password: "); let password_repeat = read_password().unwrap(); if password != password_repeat { println!("Passwords do not match!"); diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index c885407cc..5a7f93e17 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -40,14 +40,6 @@ use v1::helpers::{PollFilter, PollManager, ExternalMinerService, ExternalMiner}; use util::keys::store::AccountProvider; use serde; -fn default_gas() -> U256 { - U256::from(21_000) -} - -fn default_call_gas() -> U256 { - U256::from(50_000_000) -} - /// Eth rpc implementation. pub struct EthClient where C: BlockChainClient, @@ -180,7 +172,7 @@ impl EthClient Ok(EthTransaction { nonce: request.nonce.unwrap_or_else(|| client.nonce(&from)), action: request.to.map_or(Action::Create, Action::Call), - gas: request.gas.unwrap_or_else(default_call_gas), + gas: request.gas.unwrap_or(U256::from(50_000_000)), gas_price: request.gas_price.unwrap_or_else(|| miner.sensible_gas_price()), value: request.value.unwrap_or_else(U256::zero), data: request.data.map_or_else(Vec::new, |d| d.to_vec()) @@ -498,7 +490,7 @@ impl Eth for EthClient .map(|nonce| nonce + U256::one())) .unwrap_or_else(|| client.nonce(&request.from)), action: request.to.map_or(Action::Create, Action::Call), - gas: request.gas.unwrap_or_else(default_gas), + gas: request.gas.unwrap_or_else(|| miner.sensible_gas_limit()), gas_price: request.gas_price.unwrap_or_else(|| miner.sensible_gas_price()), value: request.value.unwrap_or_else(U256::zero), data: request.data.map_or_else(Vec::new, |d| d.to_vec()), @@ -524,6 +516,7 @@ impl Eth for EthClient } fn call(&self, params: Params) -> Result { + trace!(target: "jsonrpc", "call: {:?}", params); from_params_discard_second(params).and_then(|(request, )| { let signed = try!(self.sign_call(request)); let client = take_weak!(self.client); From 1708a0e3b4cde0c8e341020d057e71047ac72bfc Mon Sep 17 00:00:00 2001 From: "Denis S. Soldatov aka General-Beck" Date: Fri, 15 Apr 2016 02:04:35 +0700 Subject: [PATCH 4/9] Update Dockerfile switch to RUST 1.8 stable remove cargo update --- docker/ubuntu-arm/Dockerfile | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/docker/ubuntu-arm/Dockerfile b/docker/ubuntu-arm/Dockerfile index 70f2c67cf..9678912cb 100644 --- a/docker/ubuntu-arm/Dockerfile +++ b/docker/ubuntu-arm/Dockerfile @@ -12,11 +12,9 @@ RUN apt-get -y update && \ # install multirust RUN curl -sf https://raw.githubusercontent.com/brson/multirust/master/blastoff.sh | sh -s -- --yes ENV RUST_TARGETS="arm-unknown-linux-gnueabihf" -# multirust override beta -RUN multirust override beta # multirust add arm--linux-gnuabhf toolchain -RUN multirust add-target beta arm-unknown-linux-gnueabihf +RUN multirust add-target stable arm-unknown-linux-gnueabihf # show backtraces ENV RUST_BACKTRACE 1 @@ -41,7 +39,6 @@ RUN git clone https://github.com/ethcore/parity && \ cat .cargo/config && \ rustc -vV && \ cargo -V && \ - cargo update && \ cargo build --target arm-unknown-linux-gnueabihf --release --verbose && \ ls /build/parity/target/arm-unknown-linux-gnueabihf/release/parity && \ file /build/parity/target/arm-unknown-linux-gnueabihf/release/parity && \ From c4c17aa1da125b61bbd0e62c1d7fc8792eb6c8b2 Mon Sep 17 00:00:00 2001 From: Adam Goldman Date: Fri, 15 Apr 2016 07:07:46 +0200 Subject: [PATCH 5/9] bump status page version 0.1.7 (#955) --- webapp/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp/Cargo.toml b/webapp/Cargo.toml index eb3e9c042..255e345e8 100644 --- a/webapp/Cargo.toml +++ b/webapp/Cargo.toml @@ -17,7 +17,7 @@ ethcore-rpc = { path = "../rpc" } ethcore-util = { path = "../util" } parity-webapp = { git = "https://github.com/tomusdrw/parity-webapp.git" } # List of apps -parity-status = { git = "https://github.com/tomusdrw/parity-status.git", version = "0.1.5" } +parity-status = { git = "https://github.com/tomusdrw/parity-status.git", version = "0.1.7" } parity-wallet = { git = "https://github.com/tomusdrw/parity-wallet.git", optional = true } clippy = { version = "0.0.63", optional = true} From 99b8e28051ffd86050529df6cf88d2e0b8d24cb8 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 14 Apr 2016 22:13:38 -0700 Subject: [PATCH 6/9] Update mod.rs --- parity/hypervisor/mod.rs | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/parity/hypervisor/mod.rs b/parity/hypervisor/mod.rs index d65d5076e..bbc95b150 100644 --- a/parity/hypervisor/mod.rs +++ b/parity/hypervisor/mod.rs @@ -88,20 +88,18 @@ impl Hypervisor { /// Does nothing when it is already started on module is inside the /// main binary fn start_module(&self, module_id: IpcModuleId) { - Self::match_module(&module_id).map(|binary_id| - { - let mut processes = self.processes.write().unwrap(); - { - let process = processes.get(binary_id); - if process.is_some() { - // already started for another module - return; - } + Self::match_module(&module_id).map(|binary_id| { + let mut processes = self.processes.write().unwrap(); + { + if processes.get(binary_id).is_some() { + // already started for another module + return; } - let child = Command::new(binary_id).spawn().unwrap_or_else( - |e| panic!("Hypervisor cannot start binary: {}", e)); - processes.insert(binary_id, child); - }); + } + let child = Command::new(binary_id).spawn().unwrap_or_else( + |e| panic!("Hypervisor cannot start binary: {}", e)); + processes.insert(binary_id, child); + }); } /// Reports if all modules are checked in From 00372cf74769ed73b046a814c0607f6444dd65ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Fri, 15 Apr 2016 07:38:23 +0200 Subject: [PATCH 7/9] Removing a transaction from queue now removes all from this sender with lower nonces. (#950) * Changing to wipe-out all transactions from particular sender lower then given nonce. * Changing given nonce to be client_nonce * Fixing test_client to support proper nonces when transactions are added to blockchain * Fixing logic for transactions from new blocks in chain --- ethcore/src/client/test_client.rs | 14 ++++- miner/src/miner.rs | 51 +++++++++--------- miner/src/transaction_queue.rs | 88 ++++++++++++++++++++----------- sync/src/chain.rs | 29 +++++++--- 4 files changed, 116 insertions(+), 66 deletions(-) diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index df5587719..339ae214b 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -48,6 +48,8 @@ pub struct TestBlockChainClient { pub difficulty: RwLock, /// Balances. pub balances: RwLock>, + /// Nonces. + pub nonces: RwLock>, /// Storage. pub storage: RwLock>, /// Code. @@ -90,6 +92,7 @@ impl TestBlockChainClient { last_hash: RwLock::new(H256::new()), difficulty: RwLock::new(From::from(0)), balances: RwLock::new(HashMap::new()), + nonces: RwLock::new(HashMap::new()), storage: RwLock::new(HashMap::new()), code: RwLock::new(HashMap::new()), execution_result: RwLock::new(None), @@ -116,6 +119,11 @@ impl TestBlockChainClient { self.balances.write().unwrap().insert(address, balance); } + /// Set nonce of account `address` to `nonce`. + pub fn set_nonce(&self, address: Address, nonce: U256) { + self.nonces.write().unwrap().insert(address, nonce); + } + /// Set `code` at `address`. pub fn set_code(&self, address: Address, code: Bytes) { self.code.write().unwrap().insert(address, code); @@ -157,6 +165,8 @@ impl TestBlockChainClient { EachBlockWith::Transaction | EachBlockWith::UncleAndTransaction => { let mut txs = RlpStream::new_list(1); let keypair = KeyPair::create().unwrap(); + // Update nonces value + self.nonces.write().unwrap().insert(keypair.address(), U256::one()); let tx = Transaction { action: Action::Create, value: U256::from(100), @@ -222,8 +232,8 @@ impl BlockChainClient for TestBlockChainClient { unimplemented!(); } - fn nonce(&self, _address: &Address) -> U256 { - U256::zero() + fn nonce(&self, address: &Address) -> U256 { + self.nonces.read().unwrap().get(address).cloned().unwrap_or_else(U256::zero) } fn code(&self, address: &Address) -> Option { diff --git a/miner/src/miner.rs b/miner/src/miner.rs index 5169be2c5..af89a7345 100644 --- a/miner/src/miner.rs +++ b/miner/src/miner.rs @@ -133,13 +133,13 @@ impl Miner { } }; let mut queue = self.transaction_queue.lock().unwrap(); - queue.remove_all( - &invalid_transactions.into_iter().collect::>(), - |a: &Address| AccountDetails { - nonce: chain.nonce(a), - balance: chain.balance(a), - } - ); + let fetch_account = |a: &Address| AccountDetails { + nonce: chain.nonce(a), + balance: chain.balance(a), + }; + for hash in invalid_transactions.into_iter() { + queue.remove_invalid(&hash, &fetch_account); + } if let Some(block) = b { if sealing_work.peek_last_ref().map_or(true, |pb| pb.block().fields().header.hash() != block.block().fields().header.hash()) { trace!(target: "miner", "Pushing a new, refreshed or borrowed pending {}...", block.block().fields().header.hash()); @@ -299,7 +299,7 @@ impl MinerService for Miner { } } - fn chain_new_blocks(&self, chain: &BlockChainClient, imported: &[H256], invalid: &[H256], enacted: &[H256], retracted: &[H256]) { + fn chain_new_blocks(&self, chain: &BlockChainClient, _imported: &[H256], _invalid: &[H256], enacted: &[H256], retracted: &[H256]) { fn fetch_transactions(chain: &BlockChainClient, hash: &H256) -> Vec { let block = chain .block(BlockId::Hash(*hash)) @@ -309,6 +309,11 @@ impl MinerService for Miner { block.transactions() } + // 1. We ignore blocks that were `imported` (because it means that they are not in canon-chain, and transactions + // should be still available in the queue. + // 2. We ignore blocks that are `invalid` because it doesn't have any meaning in terms of the transactions that + // are in those blocks + // First update gas limit in transaction queue self.update_gas_limit(chain); @@ -330,29 +335,23 @@ impl MinerService for Miner { }); } - // ...and after that remove old ones + // ...and at the end remove old ones { - let in_chain = { - let mut in_chain = HashSet::new(); - in_chain.extend(imported); - in_chain.extend(enacted); - in_chain.extend(invalid); - in_chain - .into_iter() - .collect::>() - }; - - let in_chain = in_chain + let in_chain = enacted .par_iter() .map(|h: &H256| fetch_transactions(chain, h)); - in_chain.for_each(|txs| { - let hashes = txs.iter().map(|tx| tx.hash()).collect::>(); + in_chain.for_each(|mut txs| { let mut transaction_queue = self.transaction_queue.lock().unwrap(); - transaction_queue.remove_all(&hashes, |a| AccountDetails { - nonce: chain.nonce(a), - balance: chain.balance(a) - }); + + let to_remove = txs.drain(..) + .map(|tx| { + tx.sender().expect("Transaction is in block, so sender has to be defined.") + }) + .collect::>(); + for sender in to_remove.into_iter() { + transaction_queue.remove_all(sender, chain.nonce(&sender)); + } }); } diff --git a/miner/src/transaction_queue.rs b/miner/src/transaction_queue.rs index fad864a5a..95f2056b5 100644 --- a/miner/src/transaction_queue.rs +++ b/miner/src/transaction_queue.rs @@ -65,8 +65,8 @@ //! assert_eq!(top[1], st2); //! //! // And when transaction is removed (but nonce haven't changed) -//! // it will move invalid transactions to future -//! txq.remove(&st1.hash(), &default_nonce); +//! // it will move subsequent transactions to future +//! txq.remove_invalid(&st1.hash(), &default_nonce); //! assert_eq!(txq.status().pending, 0); //! assert_eq!(txq.status().future, 1); //! assert_eq!(txq.top_transactions().len(), 0); @@ -76,11 +76,13 @@ //! # Maintaing valid state //! //! 1. Whenever transaction is imported to queue (to queue) all other transactions from this sender are revalidated in current. It means that they are moved to future and back again (height recalculation & gap filling). -//! 2. Whenever transaction is removed: +//! 2. Whenever invalid transaction is removed: //! - When it's removed from `future` - all `future` transactions heights are recalculated and then //! we check if the transactions should go to `current` (comparing state nonce) //! - When it's removed from `current` - all transactions from this sender (`current` & `future`) are recalculated. -//! +//! 3. `remove_all` is used to inform the queue about client (state) nonce changes. +//! - It removes all transactions (either from `current` or `future`) with nonce < client nonce +//! - It moves matching `future` transactions to `current` use std::default::Default; use std::cmp::{Ordering}; @@ -398,22 +400,28 @@ impl TransactionQueue { self.import_tx(vtx, client_account.nonce).map_err(Error::Transaction) } - /// Removes all transactions identified by hashes given in slice - /// - /// If gap is introduced marks subsequent transactions as future - pub fn remove_all(&mut self, transaction_hashes: &[H256], fetch_account: T) - where T: Fn(&Address) -> AccountDetails { - for hash in transaction_hashes { - self.remove(&hash, &fetch_account); - } + /// Removes all transactions from particular sender up to (excluding) given client (state) nonce. + /// Client (State) Nonce = next valid nonce for this sender. + pub fn remove_all(&mut self, sender: Address, client_nonce: U256) { + // We will either move transaction to future or remove it completely + // so there will be no transactions from this sender in current + self.last_nonces.remove(&sender); + // First update height of transactions in future to avoid collisions + self.update_future(&sender, client_nonce); + // This should move all current transactions to future and remove old transactions + self.move_all_to_future(&sender, client_nonce); + // And now lets check if there is some batch of transactions in future + // that should be placed in current. It should also update last_nonces. + self.move_matching_future_to_current(sender, client_nonce, client_nonce); } - /// Removes transaction identified by hashes from queue. + /// Removes invalid transaction identified by hash from queue. + /// Assumption is that this transaction nonce is not related to client nonce, + /// so transactions left in queue are processed according to client nonce. /// /// If gap is introduced marks subsequent transactions as future - pub fn remove(&mut self, transaction_hash: &H256, fetch_account: &T) + pub fn remove_invalid(&mut self, transaction_hash: &H256, fetch_account: &T) where T: Fn(&Address) -> AccountDetails { - let transaction = self.by_hash.remove(transaction_hash); if transaction.is_none() { // We don't know this transaction @@ -425,7 +433,6 @@ impl TransactionQueue { let nonce = transaction.nonce(); let current_nonce = fetch_account(&sender).nonce; - // Remove from future let order = self.future.drop(&sender, &nonce); if order.is_some() { @@ -465,7 +472,7 @@ impl TransactionQueue { if k >= current_nonce { self.future.insert(*sender, k, order.update_height(k, current_nonce)); } else { - trace!(target: "miner", "Dropping old transaction: {:?} (nonce: {} < {})", order.hash, k, current_nonce); + trace!(target: "miner", "Removing old transaction: {:?} (nonce: {} < {})", order.hash, k, current_nonce); // Remove the transaction completely self.by_hash.remove(&order.hash); } @@ -486,7 +493,7 @@ impl TransactionQueue { if k >= current_nonce { self.future.insert(*sender, k, order.update_height(k, current_nonce)); } else { - trace!(target: "miner", "Dropping old transaction: {:?} (nonce: {} < {})", order.hash, k, current_nonce); + trace!(target: "miner", "Removing old transaction: {:?} (nonce: {} < {})", order.hash, k, current_nonce); self.by_hash.remove(&order.hash); } } @@ -665,9 +672,14 @@ mod test { new_unsigned_tx(U256::from(123)).sign(&keypair.secret()) } + + fn default_nonce_val() -> U256 { + U256::from(123) + } + fn default_nonce(_address: &Address) -> AccountDetails { AccountDetails { - nonce: U256::from(123), + nonce: default_nonce_val(), balance: !U256::zero() } } @@ -965,8 +977,7 @@ mod test { // given let prev_nonce = |a: &Address| AccountDetails{ nonce: default_nonce(a).nonce - U256::one(), balance: !U256::zero() }; - let next2_nonce = |a: &Address| AccountDetails{ nonce: default_nonce(a).nonce + U256::from(2), balance: - !U256::zero() }; + let next2_nonce = default_nonce_val() + U256::from(3); let mut txq = TransactionQueue::new(); @@ -976,7 +987,7 @@ mod test { assert_eq!(txq.status().future, 2); // when - txq.remove(&tx.hash(), &next2_nonce); + txq.remove_all(tx.sender().unwrap(), next2_nonce); // should remove both transactions since they are not valid // then @@ -1019,8 +1030,8 @@ mod test { assert_eq!(txq2.status().future, 1); // when - txq2.remove(&tx.hash(), &default_nonce); - txq2.remove(&tx2.hash(), &default_nonce); + txq2.remove_all(tx.sender().unwrap(), tx.nonce + U256::one()); + txq2.remove_all(tx2.sender().unwrap(), tx2.nonce + U256::one()); // then @@ -1042,7 +1053,7 @@ mod test { assert_eq!(txq.status().pending, 3); // when - txq.remove(&tx.hash(), &default_nonce); + txq.remove_invalid(&tx.hash(), &default_nonce); // then let stats = txq.status(); @@ -1152,7 +1163,7 @@ mod test { assert_eq!(txq.status().pending, 2); // when - txq.remove(&tx1.hash(), &default_nonce); + txq.remove_invalid(&tx1.hash(), &default_nonce); assert_eq!(txq.status().pending, 0); assert_eq!(txq.status().future, 1); txq.add(tx1.clone(), &default_nonce).unwrap(); @@ -1166,8 +1177,6 @@ mod test { #[test] fn should_not_move_to_future_if_state_nonce_is_higher() { // given - let next_nonce = |a: &Address| AccountDetails { nonce: default_nonce(a).nonce + U256::one(), balance: - !U256::zero() }; let mut txq = TransactionQueue::new(); let (tx, tx2) = new_txs(U256::from(1)); let tx3 = new_tx(); @@ -1178,7 +1187,8 @@ mod test { assert_eq!(txq.status().pending, 3); // when - txq.remove(&tx.hash(), &next_nonce); + let sender = tx.sender().unwrap(); + txq.remove_all(sender, default_nonce_val() + U256::one()); // then let stats = txq.status(); @@ -1254,7 +1264,7 @@ mod test { assert_eq!(txq.status().future, 2); // when - txq.remove(&tx1.hash(), &next_nonce); + txq.remove_invalid(&tx1.hash(), &next_nonce); // then let stats = txq.status(); @@ -1286,4 +1296,22 @@ mod test { // then assert_eq!(txq.last_nonce(&from), Some(nonce)); } + + #[test] + fn should_remove_old_transaction_even_if_newer_transaction_was_not_known() { + // given + let mut txq = TransactionQueue::new(); + let (tx1, tx2) = new_txs(U256::one()); + let (nonce1, nonce2) = (tx1.nonce, tx2.nonce); + let details1 = |_a: &Address| AccountDetails { nonce: nonce1, balance: !U256::zero() }; + + // Insert first transaction + txq.add(tx1, &details1).unwrap(); + + // when + txq.remove_all(tx2.sender().unwrap(), nonce2 + U256::one()); + + // then + assert!(txq.top_transactions().is_empty()); + } } diff --git a/sync/src/chain.rs b/sync/src/chain.rs index e2c11af1a..6313c7022 100644 --- a/sync/src/chain.rs +++ b/sync/src/chain.rs @@ -1694,21 +1694,34 @@ mod tests { let good_blocks = vec![client.block_hash_delta_minus(2)]; let retracted_blocks = vec![client.block_hash_delta_minus(1)]; - // Add some balance to clients + // Add some balance to clients and reset nonces for h in &[good_blocks[0], retracted_blocks[0]] { let block = client.block(BlockId::Hash(*h)).unwrap(); let view = BlockView::new(&block); client.set_balance(view.transactions()[0].sender().unwrap(), U256::from(1_000_000_000)); + client.set_nonce(view.transactions()[0].sender().unwrap(), U256::from(0)); } - let mut queue = VecDeque::new(); - let mut io = TestIo::new(&mut client, &mut queue, None); // when - sync.chain_new_blocks(&mut io, &[], &[], &[], &good_blocks); - assert_eq!(sync.miner.status().transactions_in_future_queue, 0); - assert_eq!(sync.miner.status().transactions_in_pending_queue, 1); - sync.chain_new_blocks(&mut io, &good_blocks, &[], &[], &retracted_blocks); + { + let mut queue = VecDeque::new(); + let mut io = TestIo::new(&mut client, &mut queue, None); + sync.chain_new_blocks(&mut io, &[], &[], &[], &good_blocks); + assert_eq!(sync.miner.status().transactions_in_future_queue, 0); + assert_eq!(sync.miner.status().transactions_in_pending_queue, 1); + } + // We need to update nonce status (because we say that the block has been imported) + for h in &[good_blocks[0]] { + let block = client.block(BlockId::Hash(*h)).unwrap(); + let view = BlockView::new(&block); + client.set_nonce(view.transactions()[0].sender().unwrap(), U256::from(1)); + } + { + let mut queue = VecDeque::new(); + let mut io = TestIo::new(&mut client, &mut queue, None); + sync.chain_new_blocks(&mut io, &[], &[], &good_blocks, &retracted_blocks); + } // then let status = sync.miner.status(); @@ -1735,7 +1748,7 @@ mod tests { sync.chain_new_blocks(&mut io, &[], &[], &[], &good_blocks); assert_eq!(sync.miner.status().transactions_in_future_queue, 0); assert_eq!(sync.miner.status().transactions_in_pending_queue, 0); - sync.chain_new_blocks(&mut io, &good_blocks, &[], &[], &retracted_blocks); + sync.chain_new_blocks(&mut io, &[], &[], &good_blocks, &retracted_blocks); // then let status = sync.miner.status(); From e7d8cfb8e0aa7188e8a26399d30279a9f867fe35 Mon Sep 17 00:00:00 2001 From: arkpar Date: Fri, 15 Apr 2016 13:55:39 +0200 Subject: [PATCH 8/9] update nanomsg-sys --- Cargo.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eef290a2d..a15e59793 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -375,7 +375,7 @@ dependencies = [ "jsonrpc-core 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-http-server 4.0.0 (git+https://github.com/tomusdrw/jsonrpc-http-server.git?branch=old-hyper)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-status 0.1.6 (git+https://github.com/tomusdrw/parity-status.git)", + "parity-status 0.1.7 (git+https://github.com/tomusdrw/parity-status.git)", "parity-wallet 0.1.1 (git+https://github.com/tomusdrw/parity-wallet.git)", "parity-webapp 0.1.0 (git+https://github.com/tomusdrw/parity-webapp.git)", ] @@ -715,7 +715,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "nanomsg" version = "0.5.0" -source = "git+https://github.com/ethcore/nanomsg.rs.git#26449b15f29b850bcf62a577f1ee3a56474a0bc9" +source = "git+https://github.com/ethcore/nanomsg.rs.git#754e517e1bceddca6943e866ca141f883c853527" dependencies = [ "libc 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", "nanomsg-sys 0.5.0 (git+https://github.com/ethcore/nanomsg.rs.git)", @@ -724,7 +724,7 @@ dependencies = [ [[package]] name = "nanomsg-sys" version = "0.5.0" -source = "git+https://github.com/ethcore/nanomsg.rs.git#26449b15f29b850bcf62a577f1ee3a56474a0bc9" +source = "git+https://github.com/ethcore/nanomsg.rs.git#754e517e1bceddca6943e866ca141f883c853527" dependencies = [ "gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -796,8 +796,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "parity-status" -version = "0.1.6" -source = "git+https://github.com/tomusdrw/parity-status.git#bbd45f5ccc6a0ccc9ed2c8b666b012844f9b89a8" +version = "0.1.7" +source = "git+https://github.com/tomusdrw/parity-status.git#5b7010eb7ecc38e80ab506902e083dc0dd48c43f" dependencies = [ "parity-webapp 0.1.0 (git+https://github.com/tomusdrw/parity-webapp.git)", ] From d84f382ab86e204919208ca32cee0f178c4ffa59 Mon Sep 17 00:00:00 2001 From: arkpar Date: Fri, 15 Apr 2016 14:45:49 +0200 Subject: [PATCH 9/9] fixed build --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a15e59793..3d07e2360 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -715,7 +715,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "nanomsg" version = "0.5.0" -source = "git+https://github.com/ethcore/nanomsg.rs.git#754e517e1bceddca6943e866ca141f883c853527" +source = "git+https://github.com/ethcore/nanomsg.rs.git#9c81fb3b0f71714b173d0abf14bfd30addf8c7b1" dependencies = [ "libc 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", "nanomsg-sys 0.5.0 (git+https://github.com/ethcore/nanomsg.rs.git)", @@ -724,7 +724,7 @@ dependencies = [ [[package]] name = "nanomsg-sys" version = "0.5.0" -source = "git+https://github.com/ethcore/nanomsg.rs.git#754e517e1bceddca6943e866ca141f883c853527" +source = "git+https://github.com/ethcore/nanomsg.rs.git#9c81fb3b0f71714b173d0abf14bfd30addf8c7b1" dependencies = [ "gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",