Merge remote-tracking branch 'origin/master' into fix-win-ci
This commit is contained in:
		
						commit
						b418cb8da3
					
				
							
								
								
									
										29
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										29
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							@ -884,18 +884,6 @@ name = "itoa"
 | 
				
			|||||||
version = "0.1.1"
 | 
					version = "0.1.1"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "jsonrpc-core"
 | 
					 | 
				
			||||||
version = "3.0.2"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
					 | 
				
			||||||
 "parking_lot 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
					 | 
				
			||||||
 "serde 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
					 | 
				
			||||||
 "serde_codegen 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
					 | 
				
			||||||
 "serde_json 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "jsonrpc-core"
 | 
					name = "jsonrpc-core"
 | 
				
			||||||
version = "4.0.0"
 | 
					version = "4.0.0"
 | 
				
			||||||
@ -1348,7 +1336,7 @@ dependencies = [
 | 
				
			|||||||
 "ethcore-signer 1.5.0",
 | 
					 "ethcore-signer 1.5.0",
 | 
				
			||||||
 "ethcore-util 1.5.0",
 | 
					 "ethcore-util 1.5.0",
 | 
				
			||||||
 "futures 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
					 "futures 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
				
			||||||
 "jsonrpc-core 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
					 "jsonrpc-core 4.0.0 (git+https://github.com/ethcore/jsonrpc.git)",
 | 
				
			||||||
 "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
					 "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)",
 | 
					 "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
				
			||||||
 "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
					 "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
				
			||||||
@ -1379,7 +1367,7 @@ dependencies = [
 | 
				
			|||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "parity-ui-precompiled"
 | 
					name = "parity-ui-precompiled"
 | 
				
			||||||
version = "1.4.0"
 | 
					version = "1.4.0"
 | 
				
			||||||
source = "git+https://github.com/ethcore/js-precompiled.git#2cdda91549dfeebd94775b348a443f8ee5446e9f"
 | 
					source = "git+https://github.com/ethcore/js-precompiled.git#3d390b35737ce212d358f26b5ec8d9644b252a88"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
					 "parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
@ -1400,17 +1388,6 @@ dependencies = [
 | 
				
			|||||||
 "target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
					 "target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "parking_lot"
 | 
					 | 
				
			||||||
version = "0.2.8"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
					 | 
				
			||||||
 "libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
					 | 
				
			||||||
 "smallvec 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
					 | 
				
			||||||
 "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "parking_lot"
 | 
					name = "parking_lot"
 | 
				
			||||||
version = "0.3.6"
 | 
					version = "0.3.6"
 | 
				
			||||||
@ -2231,7 +2208,6 @@ dependencies = [
 | 
				
			|||||||
"checksum isatty 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7408a548dc0e406b7912d9f84c261cc533c1866e047644a811c133c56041ac0c"
 | 
					"checksum isatty 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7408a548dc0e406b7912d9f84c261cc533c1866e047644a811c133c56041ac0c"
 | 
				
			||||||
"checksum itertools 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "086e1fa5fe48840b1cfdef3a20c7e3115599f8d5c4c87ef32a794a7cdd184d76"
 | 
					"checksum itertools 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "086e1fa5fe48840b1cfdef3a20c7e3115599f8d5c4c87ef32a794a7cdd184d76"
 | 
				
			||||||
"checksum itoa 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ae3088ea4baeceb0284ee9eea42f591226e6beaecf65373e41b38d95a1b8e7a1"
 | 
					"checksum itoa 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ae3088ea4baeceb0284ee9eea42f591226e6beaecf65373e41b38d95a1b8e7a1"
 | 
				
			||||||
"checksum jsonrpc-core 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3c5094610b07f28f3edaf3947b732dadb31dbba4941d4d0c1c7a8350208f4414"
 | 
					 | 
				
			||||||
"checksum jsonrpc-core 4.0.0 (git+https://github.com/ethcore/jsonrpc.git)" = "<none>"
 | 
					"checksum jsonrpc-core 4.0.0 (git+https://github.com/ethcore/jsonrpc.git)" = "<none>"
 | 
				
			||||||
"checksum jsonrpc-http-server 6.1.1 (git+https://github.com/ethcore/jsonrpc.git)" = "<none>"
 | 
					"checksum jsonrpc-http-server 6.1.1 (git+https://github.com/ethcore/jsonrpc.git)" = "<none>"
 | 
				
			||||||
"checksum jsonrpc-ipc-server 0.2.4 (git+https://github.com/ethcore/jsonrpc.git)" = "<none>"
 | 
					"checksum jsonrpc-ipc-server 0.2.4 (git+https://github.com/ethcore/jsonrpc.git)" = "<none>"
 | 
				
			||||||
@ -2279,7 +2255,6 @@ dependencies = [
 | 
				
			|||||||
"checksum owning_ref 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8d91377085359426407a287ab16884a0111ba473aa6844ff01d4ec20ce3d75e7"
 | 
					"checksum owning_ref 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8d91377085359426407a287ab16884a0111ba473aa6844ff01d4ec20ce3d75e7"
 | 
				
			||||||
"checksum parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "98378dec0a185da2b7180308752f0bad73aaa949c3e0a3b0528d0e067945f7ab"
 | 
					"checksum parity-dapps-glue 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "98378dec0a185da2b7180308752f0bad73aaa949c3e0a3b0528d0e067945f7ab"
 | 
				
			||||||
"checksum parity-ui-precompiled 1.4.0 (git+https://github.com/ethcore/js-precompiled.git)" = "<none>"
 | 
					"checksum parity-ui-precompiled 1.4.0 (git+https://github.com/ethcore/js-precompiled.git)" = "<none>"
 | 
				
			||||||
"checksum parking_lot 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "968f685642555d2f7e202c48b8b11de80569e9bfea817f7f12d7c61aac62d4e6"
 | 
					 | 
				
			||||||
"checksum parking_lot 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e1435e7a2a00dfebededd6c6bdbd54008001e94b4a2aadd6aef0dc4c56317621"
 | 
					"checksum parking_lot 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e1435e7a2a00dfebededd6c6bdbd54008001e94b4a2aadd6aef0dc4c56317621"
 | 
				
			||||||
"checksum parking_lot_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb1b97670a2ffadce7c397fb80a3d687c4f3060140b885621ef1653d0e5d5068"
 | 
					"checksum parking_lot_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb1b97670a2ffadce7c397fb80a3d687c4f3060140b885621ef1653d0e5d5068"
 | 
				
			||||||
"checksum phf 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)" = "447d9d45f2e0b4a9b532e808365abf18fc211be6ca217202fcd45236ef12f026"
 | 
					"checksum phf 0.7.14 (registry+https://github.com/rust-lang/crates.io-index)" = "447d9d45f2e0b4a9b532e808365abf18fc211be6ca217202fcd45236ef12f026"
 | 
				
			||||||
 | 
				
			|||||||
@ -24,7 +24,7 @@ use ethcore::service::ClientIoMessage;
 | 
				
			|||||||
use ethcore::block_import_error::BlockImportError;
 | 
					use ethcore::block_import_error::BlockImportError;
 | 
				
			||||||
use ethcore::block_status::BlockStatus;
 | 
					use ethcore::block_status::BlockStatus;
 | 
				
			||||||
use ethcore::verification::queue::{HeaderQueue, QueueInfo};
 | 
					use ethcore::verification::queue::{HeaderQueue, QueueInfo};
 | 
				
			||||||
use ethcore::transaction::SignedTransaction;
 | 
					use ethcore::transaction::{SignedTransaction, PendingTransaction};
 | 
				
			||||||
use ethcore::blockchain_info::BlockChainInfo;
 | 
					use ethcore::blockchain_info::BlockChainInfo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use io::IoChannel;
 | 
					use io::IoChannel;
 | 
				
			||||||
@ -114,7 +114,7 @@ impl Provider for Client {
 | 
				
			|||||||
		Vec::new()
 | 
							Vec::new()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn pending_transactions(&self) -> Vec<SignedTransaction> {
 | 
						fn ready_transactions(&self) -> Vec<PendingTransaction> {
 | 
				
			||||||
		Vec::new()
 | 
							Vec::new()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -20,7 +20,7 @@
 | 
				
			|||||||
use ethcore::blockchain_info::BlockChainInfo;
 | 
					use ethcore::blockchain_info::BlockChainInfo;
 | 
				
			||||||
use ethcore::client::{BlockChainClient, EachBlockWith, TestBlockChainClient};
 | 
					use ethcore::client::{BlockChainClient, EachBlockWith, TestBlockChainClient};
 | 
				
			||||||
use ethcore::ids::BlockId;
 | 
					use ethcore::ids::BlockId;
 | 
				
			||||||
use ethcore::transaction::SignedTransaction;
 | 
					use ethcore::transaction::PendingTransaction;
 | 
				
			||||||
use network::{PeerId, NodeId};
 | 
					use network::{PeerId, NodeId};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use net::buffer_flow::FlowParams;
 | 
					use net::buffer_flow::FlowParams;
 | 
				
			||||||
@ -169,8 +169,8 @@ impl Provider for TestProvider {
 | 
				
			|||||||
		req.requests.into_iter().map(|_| ::rlp::EMPTY_LIST_RLP.to_vec()).collect()
 | 
							req.requests.into_iter().map(|_| ::rlp::EMPTY_LIST_RLP.to_vec()).collect()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn pending_transactions(&self) -> Vec<SignedTransaction> {
 | 
						fn ready_transactions(&self) -> Vec<PendingTransaction> {
 | 
				
			||||||
		self.0.client.pending_transactions()
 | 
							self.0.client.ready_transactions()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -19,7 +19,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use ethcore::blockchain_info::BlockChainInfo;
 | 
					use ethcore::blockchain_info::BlockChainInfo;
 | 
				
			||||||
use ethcore::client::{BlockChainClient, ProvingBlockChainClient};
 | 
					use ethcore::client::{BlockChainClient, ProvingBlockChainClient};
 | 
				
			||||||
use ethcore::transaction::SignedTransaction;
 | 
					use ethcore::transaction::PendingTransaction;
 | 
				
			||||||
use ethcore::ids::BlockId;
 | 
					use ethcore::ids::BlockId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use util::{Bytes, H256};
 | 
					use util::{Bytes, H256};
 | 
				
			||||||
@ -79,7 +79,7 @@ pub trait Provider: Send + Sync {
 | 
				
			|||||||
	fn header_proofs(&self, req: request::HeaderProofs) -> Vec<Bytes>;
 | 
						fn header_proofs(&self, req: request::HeaderProofs) -> Vec<Bytes>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// Provide pending transactions.
 | 
						/// Provide pending transactions.
 | 
				
			||||||
	fn pending_transactions(&self) -> Vec<SignedTransaction>;
 | 
						fn ready_transactions(&self) -> Vec<PendingTransaction>;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Implementation of a light client data provider for a client.
 | 
					// Implementation of a light client data provider for a client.
 | 
				
			||||||
@ -178,7 +178,7 @@ impl<T: ProvingBlockChainClient + ?Sized> Provider for T {
 | 
				
			|||||||
		req.requests.into_iter().map(|_| ::rlp::EMPTY_LIST_RLP.to_vec()).collect()
 | 
							req.requests.into_iter().map(|_| ::rlp::EMPTY_LIST_RLP.to_vec()).collect()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn pending_transactions(&self) -> Vec<SignedTransaction> {
 | 
						fn ready_transactions(&self) -> Vec<PendingTransaction> {
 | 
				
			||||||
		BlockChainClient::pending_transactions(self)
 | 
							BlockChainClient::ready_transactions(self)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -44,7 +44,7 @@ use env_info::LastHashes;
 | 
				
			|||||||
use verification;
 | 
					use verification;
 | 
				
			||||||
use verification::{PreverifiedBlock, Verifier};
 | 
					use verification::{PreverifiedBlock, Verifier};
 | 
				
			||||||
use block::*;
 | 
					use block::*;
 | 
				
			||||||
use transaction::{LocalizedTransaction, SignedTransaction, Transaction, Action};
 | 
					use transaction::{LocalizedTransaction, SignedTransaction, Transaction, PendingTransaction, Action};
 | 
				
			||||||
use blockchain::extras::TransactionAddress;
 | 
					use blockchain::extras::TransactionAddress;
 | 
				
			||||||
use types::filter::Filter;
 | 
					use types::filter::Filter;
 | 
				
			||||||
use types::mode::Mode as IpcMode;
 | 
					use types::mode::Mode as IpcMode;
 | 
				
			||||||
@ -1334,8 +1334,8 @@ impl BlockChainClient for Client {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn pending_transactions(&self) -> Vec<SignedTransaction> {
 | 
						fn ready_transactions(&self) -> Vec<PendingTransaction> {
 | 
				
			||||||
		self.miner.pending_transactions(self.chain.read().best_block_number())
 | 
							self.miner.ready_transactions(self.chain.read().best_block_number())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn queue_consensus_message(&self, message: Bytes) {
 | 
						fn queue_consensus_message(&self, message: Bytes) {
 | 
				
			||||||
 | 
				
			|||||||
@ -21,7 +21,7 @@ use util::*;
 | 
				
			|||||||
use rlp::*;
 | 
					use rlp::*;
 | 
				
			||||||
use ethkey::{Generator, Random};
 | 
					use ethkey::{Generator, Random};
 | 
				
			||||||
use devtools::*;
 | 
					use devtools::*;
 | 
				
			||||||
use transaction::{Transaction, LocalizedTransaction, SignedTransaction, Action};
 | 
					use transaction::{Transaction, LocalizedTransaction, SignedTransaction, PendingTransaction, Action};
 | 
				
			||||||
use blockchain::TreeRoute;
 | 
					use blockchain::TreeRoute;
 | 
				
			||||||
use client::{
 | 
					use client::{
 | 
				
			||||||
	BlockChainClient, MiningBlockChainClient, BlockChainInfo, BlockStatus, BlockId,
 | 
						BlockChainClient, MiningBlockChainClient, BlockChainInfo, BlockStatus, BlockId,
 | 
				
			||||||
@ -688,8 +688,8 @@ impl BlockChainClient for TestBlockChainClient {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	fn broadcast_consensus_message(&self, _message: Bytes) {}
 | 
						fn broadcast_consensus_message(&self, _message: Bytes) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn pending_transactions(&self) -> Vec<SignedTransaction> {
 | 
						fn ready_transactions(&self) -> Vec<PendingTransaction> {
 | 
				
			||||||
		self.miner.pending_transactions(self.chain_info().best_block_number)
 | 
							self.miner.ready_transactions(self.chain_info().best_block_number)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn signing_network_id(&self) -> Option<u64> { None }
 | 
						fn signing_network_id(&self) -> Option<u64> { None }
 | 
				
			||||||
 | 
				
			|||||||
@ -21,7 +21,7 @@ use blockchain::TreeRoute;
 | 
				
			|||||||
use verification::queue::QueueInfo as BlockQueueInfo;
 | 
					use verification::queue::QueueInfo as BlockQueueInfo;
 | 
				
			||||||
use block::{OpenBlock, SealedBlock};
 | 
					use block::{OpenBlock, SealedBlock};
 | 
				
			||||||
use header::{BlockNumber};
 | 
					use header::{BlockNumber};
 | 
				
			||||||
use transaction::{LocalizedTransaction, SignedTransaction};
 | 
					use transaction::{LocalizedTransaction, SignedTransaction, PendingTransaction};
 | 
				
			||||||
use log_entry::LocalizedLogEntry;
 | 
					use log_entry::LocalizedLogEntry;
 | 
				
			||||||
use filter::Filter;
 | 
					use filter::Filter;
 | 
				
			||||||
use views::{BlockView};
 | 
					use views::{BlockView};
 | 
				
			||||||
@ -211,8 +211,8 @@ pub trait BlockChainClient : Sync + Send {
 | 
				
			|||||||
	/// Used by PoA to communicate with peers.
 | 
						/// Used by PoA to communicate with peers.
 | 
				
			||||||
	fn broadcast_consensus_message(&self, message: Bytes);
 | 
						fn broadcast_consensus_message(&self, message: Bytes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// list all transactions
 | 
						/// List all transactions that are allowed into the next block.
 | 
				
			||||||
	fn pending_transactions(&self) -> Vec<SignedTransaction>;
 | 
						fn ready_transactions(&self) -> Vec<PendingTransaction>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// Sorted list of transaction gas prices from at least last sample_size blocks.
 | 
						/// Sorted list of transaction gas prices from at least last sample_size blocks.
 | 
				
			||||||
	fn gas_price_corpus(&self, sample_size: usize) -> Vec<U256> {
 | 
						fn gas_price_corpus(&self, sample_size: usize) -> Vec<U256> {
 | 
				
			||||||
 | 
				
			|||||||
@ -115,7 +115,7 @@ impl BanningTransactionQueue {
 | 
				
			|||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		self.queue.add(transaction, TransactionOrigin::External, account_details, gas_estimator)
 | 
							self.queue.add(transaction, TransactionOrigin::External, None, account_details, gas_estimator)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// Ban transaction with given hash.
 | 
						/// Ban transaction with given hash.
 | 
				
			||||||
@ -263,7 +263,7 @@ mod tests {
 | 
				
			|||||||
		let mut txq = queue();
 | 
							let mut txq = queue();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
		txq.queue().add(tx, TransactionOrigin::External, &default_account_details, &gas_required).unwrap();
 | 
							txq.queue().add(tx, TransactionOrigin::External, None, &default_account_details, &gas_required).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// then
 | 
							// then
 | 
				
			||||||
		// should also deref to queue
 | 
							// should also deref to queue
 | 
				
			||||||
 | 
				
			|||||||
@ -28,7 +28,7 @@ use client::TransactionImportResult;
 | 
				
			|||||||
use executive::contract_address;
 | 
					use executive::contract_address;
 | 
				
			||||||
use block::{ClosedBlock, IsBlock, Block};
 | 
					use block::{ClosedBlock, IsBlock, Block};
 | 
				
			||||||
use error::*;
 | 
					use error::*;
 | 
				
			||||||
use transaction::{Action, SignedTransaction};
 | 
					use transaction::{Action, SignedTransaction, PendingTransaction};
 | 
				
			||||||
use receipt::{Receipt, RichReceipt};
 | 
					use receipt::{Receipt, RichReceipt};
 | 
				
			||||||
use spec::Spec;
 | 
					use spec::Spec;
 | 
				
			||||||
use engines::{Engine, Seal};
 | 
					use engines::{Engine, Seal};
 | 
				
			||||||
@ -320,11 +320,12 @@ impl Miner {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		let _timer = PerfTimer::new("prepare_block");
 | 
							let _timer = PerfTimer::new("prepare_block");
 | 
				
			||||||
 | 
							let chain_info = chain.chain_info();
 | 
				
			||||||
		let (transactions, mut open_block, original_work_hash) = {
 | 
							let (transactions, mut open_block, original_work_hash) = {
 | 
				
			||||||
			let transactions = {self.transaction_queue.lock().top_transactions()};
 | 
								let transactions = {self.transaction_queue.lock().top_transactions_at(chain_info.best_block_number)};
 | 
				
			||||||
			let mut sealing_work = self.sealing_work.lock();
 | 
								let mut sealing_work = self.sealing_work.lock();
 | 
				
			||||||
			let last_work_hash = sealing_work.queue.peek_last_ref().map(|pb| pb.block().fields().header.hash());
 | 
								let last_work_hash = sealing_work.queue.peek_last_ref().map(|pb| pb.block().fields().header.hash());
 | 
				
			||||||
			let best_hash = chain.best_block_header().sha3();
 | 
								let best_hash = chain_info.best_block_hash;
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
			// check to see if last ClosedBlock in would_seals is actually same parent block.
 | 
								// check to see if last ClosedBlock in would_seals is actually same parent block.
 | 
				
			||||||
			// if so
 | 
								// if so
 | 
				
			||||||
@ -577,8 +578,14 @@ impl Miner {
 | 
				
			|||||||
		prepare_new
 | 
							prepare_new
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn add_transactions_to_queue(&self, chain: &MiningBlockChainClient, transactions: Vec<SignedTransaction>, default_origin: TransactionOrigin, transaction_queue: &mut BanningTransactionQueue) ->
 | 
						fn add_transactions_to_queue(
 | 
				
			||||||
		Vec<Result<TransactionImportResult, Error>> {
 | 
							&self,
 | 
				
			||||||
 | 
							chain: &MiningBlockChainClient,
 | 
				
			||||||
 | 
							transactions: Vec<SignedTransaction>,
 | 
				
			||||||
 | 
							default_origin: TransactionOrigin,
 | 
				
			||||||
 | 
							min_block: Option<BlockNumber>,
 | 
				
			||||||
 | 
							transaction_queue: &mut BanningTransactionQueue)
 | 
				
			||||||
 | 
							-> Vec<Result<TransactionImportResult, Error>> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		let fetch_account = |a: &Address| AccountDetails {
 | 
							let fetch_account = |a: &Address| AccountDetails {
 | 
				
			||||||
			nonce: chain.latest_nonce(a),
 | 
								nonce: chain.latest_nonce(a),
 | 
				
			||||||
@ -613,7 +620,7 @@ impl Miner {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
						match origin {
 | 
											match origin {
 | 
				
			||||||
							TransactionOrigin::Local | TransactionOrigin::RetractedBlock => {
 | 
												TransactionOrigin::Local | TransactionOrigin::RetractedBlock => {
 | 
				
			||||||
								transaction_queue.add(tx, origin, &fetch_account, &gas_required)
 | 
													transaction_queue.add(tx, origin, min_block, &fetch_account, &gas_required)
 | 
				
			||||||
							},
 | 
												},
 | 
				
			||||||
							TransactionOrigin::External => {
 | 
												TransactionOrigin::External => {
 | 
				
			||||||
								transaction_queue.add_with_banlist(tx, &fetch_account, &gas_required)
 | 
													transaction_queue.add_with_banlist(tx, &fetch_account, &gas_required)
 | 
				
			||||||
@ -839,7 +846,7 @@ impl MinerService for Miner {
 | 
				
			|||||||
		let results = {
 | 
							let results = {
 | 
				
			||||||
			let mut transaction_queue = self.transaction_queue.lock();
 | 
								let mut transaction_queue = self.transaction_queue.lock();
 | 
				
			||||||
			self.add_transactions_to_queue(
 | 
								self.add_transactions_to_queue(
 | 
				
			||||||
				chain, transactions, TransactionOrigin::External, &mut transaction_queue
 | 
									chain, transactions, TransactionOrigin::External, None, &mut transaction_queue
 | 
				
			||||||
			)
 | 
								)
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -857,17 +864,17 @@ impl MinerService for Miner {
 | 
				
			|||||||
	fn import_own_transaction(
 | 
						fn import_own_transaction(
 | 
				
			||||||
		&self,
 | 
							&self,
 | 
				
			||||||
		chain: &MiningBlockChainClient,
 | 
							chain: &MiningBlockChainClient,
 | 
				
			||||||
		transaction: SignedTransaction,
 | 
							pending: PendingTransaction,
 | 
				
			||||||
	) -> Result<TransactionImportResult, Error> {
 | 
						) -> Result<TransactionImportResult, Error> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		let hash = transaction.hash();
 | 
							let hash = pending.transaction.hash();
 | 
				
			||||||
		trace!(target: "own_tx", "Importing transaction: {:?}", transaction);
 | 
							trace!(target: "own_tx", "Importing transaction: {:?}", pending);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		let imported = {
 | 
							let imported = {
 | 
				
			||||||
			// Be sure to release the lock before we call prepare_work_sealing
 | 
								// Be sure to release the lock before we call prepare_work_sealing
 | 
				
			||||||
			let mut transaction_queue = self.transaction_queue.lock();
 | 
								let mut transaction_queue = self.transaction_queue.lock();
 | 
				
			||||||
			let import = self.add_transactions_to_queue(
 | 
								let import = self.add_transactions_to_queue(
 | 
				
			||||||
				chain, vec![transaction], TransactionOrigin::Local, &mut transaction_queue
 | 
									chain, vec![pending.transaction], TransactionOrigin::Local, pending.min_block, &mut transaction_queue
 | 
				
			||||||
			).pop().expect("one result returned per added transaction; one added => one result; qed");
 | 
								).pop().expect("one result returned per added transaction; one added => one result; qed");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			match import {
 | 
								match import {
 | 
				
			||||||
@ -902,9 +909,9 @@ impl MinerService for Miner {
 | 
				
			|||||||
		imported
 | 
							imported
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn all_transactions(&self) -> Vec<SignedTransaction> {
 | 
						fn pending_transactions(&self) -> Vec<PendingTransaction> {
 | 
				
			||||||
		let queue = self.transaction_queue.lock();
 | 
							let queue = self.transaction_queue.lock();
 | 
				
			||||||
		queue.top_transactions()
 | 
							queue.pending_transactions(BlockNumber::max_value())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn local_transactions(&self) -> BTreeMap<H256, LocalTransactionStatus> {
 | 
						fn local_transactions(&self) -> BTreeMap<H256, LocalTransactionStatus> {
 | 
				
			||||||
@ -915,22 +922,26 @@ impl MinerService for Miner {
 | 
				
			|||||||
			.collect()
 | 
								.collect()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn pending_transactions(&self, best_block: BlockNumber) -> Vec<SignedTransaction> {
 | 
						fn future_transactions(&self) -> Vec<PendingTransaction> {
 | 
				
			||||||
 | 
							self.transaction_queue.lock().future_transactions()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fn ready_transactions(&self, best_block: BlockNumber) -> Vec<PendingTransaction> {
 | 
				
			||||||
		let queue = self.transaction_queue.lock();
 | 
							let queue = self.transaction_queue.lock();
 | 
				
			||||||
		match self.options.pending_set {
 | 
							match self.options.pending_set {
 | 
				
			||||||
			PendingSet::AlwaysQueue => queue.top_transactions(),
 | 
								PendingSet::AlwaysQueue => queue.pending_transactions(best_block),
 | 
				
			||||||
			PendingSet::SealingOrElseQueue => {
 | 
								PendingSet::SealingOrElseQueue => {
 | 
				
			||||||
				self.from_pending_block(
 | 
									self.from_pending_block(
 | 
				
			||||||
					best_block,
 | 
										best_block,
 | 
				
			||||||
					|| queue.top_transactions(),
 | 
										|| queue.pending_transactions(best_block),
 | 
				
			||||||
					|sealing| sealing.transactions().to_owned()
 | 
										|sealing| sealing.transactions().iter().map(|t| t.clone().into()).collect()
 | 
				
			||||||
				)
 | 
									)
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			PendingSet::AlwaysSealing => {
 | 
								PendingSet::AlwaysSealing => {
 | 
				
			||||||
				self.from_pending_block(
 | 
									self.from_pending_block(
 | 
				
			||||||
					best_block,
 | 
										best_block,
 | 
				
			||||||
					|| vec![],
 | 
										|| vec![],
 | 
				
			||||||
					|sealing| sealing.transactions().to_owned()
 | 
										|sealing| sealing.transactions().iter().map(|t| t.clone().into()).collect()
 | 
				
			||||||
				)
 | 
									)
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -1126,7 +1137,7 @@ impl MinerService for Miner {
 | 
				
			|||||||
				}).for_each(|txs| {
 | 
									}).for_each(|txs| {
 | 
				
			||||||
					let mut transaction_queue = self.transaction_queue.lock();
 | 
										let mut transaction_queue = self.transaction_queue.lock();
 | 
				
			||||||
					let _ = self.add_transactions_to_queue(
 | 
										let _ = self.add_transactions_to_queue(
 | 
				
			||||||
						chain, txs, TransactionOrigin::RetractedBlock, &mut transaction_queue
 | 
											chain, txs, TransactionOrigin::RetractedBlock, None, &mut transaction_queue
 | 
				
			||||||
					);
 | 
										);
 | 
				
			||||||
				});
 | 
									});
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -1159,7 +1170,7 @@ mod tests {
 | 
				
			|||||||
	use ethkey::{Generator, Random};
 | 
						use ethkey::{Generator, Random};
 | 
				
			||||||
	use client::{BlockChainClient, TestBlockChainClient, EachBlockWith, TransactionImportResult};
 | 
						use client::{BlockChainClient, TestBlockChainClient, EachBlockWith, TransactionImportResult};
 | 
				
			||||||
	use header::BlockNumber;
 | 
						use header::BlockNumber;
 | 
				
			||||||
	use types::transaction::{Transaction, SignedTransaction, Action};
 | 
						use types::transaction::{Transaction, SignedTransaction, PendingTransaction, Action};
 | 
				
			||||||
	use spec::Spec;
 | 
						use spec::Spec;
 | 
				
			||||||
	use tests::helpers::{generate_dummy_client};
 | 
						use tests::helpers::{generate_dummy_client};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1238,12 +1249,12 @@ mod tests {
 | 
				
			|||||||
		let transaction = transaction();
 | 
							let transaction = transaction();
 | 
				
			||||||
		let best_block = 0;
 | 
							let best_block = 0;
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
		let res = miner.import_own_transaction(&client, transaction);
 | 
							let res = miner.import_own_transaction(&client, PendingTransaction::new(transaction, None));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// then
 | 
							// then
 | 
				
			||||||
		assert_eq!(res.unwrap(), TransactionImportResult::Current);
 | 
							assert_eq!(res.unwrap(), TransactionImportResult::Current);
 | 
				
			||||||
		assert_eq!(miner.all_transactions().len(), 1);
 | 
							assert_eq!(miner.pending_transactions().len(), 1);
 | 
				
			||||||
		assert_eq!(miner.pending_transactions(best_block).len(), 1);
 | 
							assert_eq!(miner.ready_transactions(best_block).len(), 1);
 | 
				
			||||||
		assert_eq!(miner.pending_transactions_hashes(best_block).len(), 1);
 | 
							assert_eq!(miner.pending_transactions_hashes(best_block).len(), 1);
 | 
				
			||||||
		assert_eq!(miner.pending_receipts(best_block).len(), 1);
 | 
							assert_eq!(miner.pending_receipts(best_block).len(), 1);
 | 
				
			||||||
		// This method will let us know if pending block was created (before calling that method)
 | 
							// This method will let us know if pending block was created (before calling that method)
 | 
				
			||||||
@ -1258,12 +1269,12 @@ mod tests {
 | 
				
			|||||||
		let transaction = transaction();
 | 
							let transaction = transaction();
 | 
				
			||||||
		let best_block = 10;
 | 
							let best_block = 10;
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
		let res = miner.import_own_transaction(&client, transaction);
 | 
							let res = miner.import_own_transaction(&client, PendingTransaction::new(transaction, None));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// then
 | 
							// then
 | 
				
			||||||
		assert_eq!(res.unwrap(), TransactionImportResult::Current);
 | 
							assert_eq!(res.unwrap(), TransactionImportResult::Current);
 | 
				
			||||||
		assert_eq!(miner.all_transactions().len(), 1);
 | 
							assert_eq!(miner.pending_transactions().len(), 1);
 | 
				
			||||||
		assert_eq!(miner.pending_transactions(best_block).len(), 0);
 | 
							assert_eq!(miner.ready_transactions(best_block).len(), 0);
 | 
				
			||||||
		assert_eq!(miner.pending_transactions_hashes(best_block).len(), 0);
 | 
							assert_eq!(miner.pending_transactions_hashes(best_block).len(), 0);
 | 
				
			||||||
		assert_eq!(miner.pending_receipts(best_block).len(), 0);
 | 
							assert_eq!(miner.pending_receipts(best_block).len(), 0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -1280,9 +1291,9 @@ mod tests {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		// then
 | 
							// then
 | 
				
			||||||
		assert_eq!(res.unwrap(), TransactionImportResult::Current);
 | 
							assert_eq!(res.unwrap(), TransactionImportResult::Current);
 | 
				
			||||||
		assert_eq!(miner.all_transactions().len(), 1);
 | 
							assert_eq!(miner.pending_transactions().len(), 1);
 | 
				
			||||||
		assert_eq!(miner.pending_transactions_hashes(best_block).len(), 0);
 | 
							assert_eq!(miner.pending_transactions_hashes(best_block).len(), 0);
 | 
				
			||||||
		assert_eq!(miner.pending_transactions(best_block).len(), 0);
 | 
							assert_eq!(miner.ready_transactions(best_block).len(), 0);
 | 
				
			||||||
		assert_eq!(miner.pending_receipts(best_block).len(), 0);
 | 
							assert_eq!(miner.pending_receipts(best_block).len(), 0);
 | 
				
			||||||
		// This method will let us know if pending block was created (before calling that method)
 | 
							// This method will let us know if pending block was created (before calling that method)
 | 
				
			||||||
		assert!(miner.prepare_work_sealing(&client));
 | 
							assert!(miner.prepare_work_sealing(&client));
 | 
				
			||||||
@ -1315,7 +1326,7 @@ mod tests {
 | 
				
			|||||||
		assert!(miner.pending_block().is_none());
 | 
							assert!(miner.pending_block().is_none());
 | 
				
			||||||
		assert_eq!(client.chain_info().best_block_number, 3 as BlockNumber);
 | 
							assert_eq!(client.chain_info().best_block_number, 3 as BlockNumber);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		assert_eq!(miner.import_own_transaction(client, transaction()).unwrap(), TransactionImportResult::Current);
 | 
							assert_eq!(miner.import_own_transaction(client, PendingTransaction::new(transaction(), None)).unwrap(), TransactionImportResult::Current);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		miner.update_sealing(client);
 | 
							miner.update_sealing(client);
 | 
				
			||||||
		client.flush_queue();
 | 
							client.flush_queue();
 | 
				
			||||||
 | 
				
			|||||||
@ -62,7 +62,7 @@ use block::ClosedBlock;
 | 
				
			|||||||
use header::BlockNumber;
 | 
					use header::BlockNumber;
 | 
				
			||||||
use receipt::{RichReceipt, Receipt};
 | 
					use receipt::{RichReceipt, Receipt};
 | 
				
			||||||
use error::{Error, CallError};
 | 
					use error::{Error, CallError};
 | 
				
			||||||
use transaction::SignedTransaction;
 | 
					use transaction::{SignedTransaction, PendingTransaction};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Miner client API
 | 
					/// Miner client API
 | 
				
			||||||
pub trait MinerService : Send + Sync {
 | 
					pub trait MinerService : Send + Sync {
 | 
				
			||||||
@ -118,7 +118,7 @@ pub trait MinerService : Send + Sync {
 | 
				
			|||||||
		Vec<Result<TransactionImportResult, Error>>;
 | 
							Vec<Result<TransactionImportResult, Error>>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// Imports own (node owner) transaction to queue.
 | 
						/// Imports own (node owner) transaction to queue.
 | 
				
			||||||
	fn import_own_transaction(&self, chain: &MiningBlockChainClient, transaction: SignedTransaction) ->
 | 
						fn import_own_transaction(&self, chain: &MiningBlockChainClient, transaction: PendingTransaction) ->
 | 
				
			||||||
		Result<TransactionImportResult, Error>;
 | 
							Result<TransactionImportResult, Error>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// Returns hashes of transactions currently in pending
 | 
						/// Returns hashes of transactions currently in pending
 | 
				
			||||||
@ -144,11 +144,14 @@ pub trait MinerService : Send + Sync {
 | 
				
			|||||||
	/// Query pending transactions for hash.
 | 
						/// Query pending transactions for hash.
 | 
				
			||||||
	fn transaction(&self, best_block: BlockNumber, hash: &H256) -> Option<SignedTransaction>;
 | 
						fn transaction(&self, best_block: BlockNumber, hash: &H256) -> Option<SignedTransaction>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// Get a list of all transactions.
 | 
						/// Get a list of all pending transactions in the queue.
 | 
				
			||||||
	fn all_transactions(&self) -> Vec<SignedTransaction>;
 | 
						fn pending_transactions(&self) -> Vec<PendingTransaction>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// Get a list of all pending transactions.
 | 
						/// Get a list of all transactions that can go into the given block.
 | 
				
			||||||
	fn pending_transactions(&self, best_block: BlockNumber) -> Vec<SignedTransaction>;
 | 
						fn ready_transactions(&self, best_block: BlockNumber) -> Vec<PendingTransaction>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/// Get a list of all future transactions.
 | 
				
			||||||
 | 
						fn future_transactions(&self) -> Vec<PendingTransaction>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// Get a list of local transactions with statuses.
 | 
						/// Get a list of local transactions with statuses.
 | 
				
			||||||
	fn local_transactions(&self) -> BTreeMap<H256, LocalTransactionStatus>;
 | 
						fn local_transactions(&self) -> BTreeMap<H256, LocalTransactionStatus>;
 | 
				
			||||||
 | 
				
			|||||||
@ -51,8 +51,8 @@
 | 
				
			|||||||
//!		let gas_estimator = |_tx: &SignedTransaction| 2.into();
 | 
					//!		let gas_estimator = |_tx: &SignedTransaction| 2.into();
 | 
				
			||||||
//!
 | 
					//!
 | 
				
			||||||
//!		let mut txq = TransactionQueue::default();
 | 
					//!		let mut txq = TransactionQueue::default();
 | 
				
			||||||
//!		txq.add(st2.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
					//!		txq.add(st2.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
//!		txq.add(st1.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
					//!		txq.add(st1.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
//!
 | 
					//!
 | 
				
			||||||
//!		// Check status
 | 
					//!		// Check status
 | 
				
			||||||
//!		assert_eq!(txq.status().pending, 2);
 | 
					//!		assert_eq!(txq.status().pending, 2);
 | 
				
			||||||
@ -94,6 +94,7 @@ use util::table::Table;
 | 
				
			|||||||
use transaction::*;
 | 
					use transaction::*;
 | 
				
			||||||
use error::{Error, TransactionError};
 | 
					use error::{Error, TransactionError};
 | 
				
			||||||
use client::TransactionImportResult;
 | 
					use client::TransactionImportResult;
 | 
				
			||||||
 | 
					use header::BlockNumber;
 | 
				
			||||||
use miner::local_transactions::{LocalTransactionsList, Status as LocalTransactionStatus};
 | 
					use miner::local_transactions::{LocalTransactionsList, Status as LocalTransactionStatus};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Transaction origin
 | 
					/// Transaction origin
 | 
				
			||||||
@ -253,18 +254,21 @@ impl Ord for TransactionOrder {
 | 
				
			|||||||
/// Verified transaction (with sender)
 | 
					/// Verified transaction (with sender)
 | 
				
			||||||
#[derive(Debug)]
 | 
					#[derive(Debug)]
 | 
				
			||||||
struct VerifiedTransaction {
 | 
					struct VerifiedTransaction {
 | 
				
			||||||
	/// Transaction
 | 
						/// Transaction.
 | 
				
			||||||
	transaction: SignedTransaction,
 | 
						transaction: SignedTransaction,
 | 
				
			||||||
	/// transaction origin
 | 
						/// Transaction origin.
 | 
				
			||||||
	origin: TransactionOrigin,
 | 
						origin: TransactionOrigin,
 | 
				
			||||||
 | 
						/// Delay until specifid block.
 | 
				
			||||||
 | 
						min_block: Option<BlockNumber>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl VerifiedTransaction {
 | 
					impl VerifiedTransaction {
 | 
				
			||||||
	fn new(transaction: SignedTransaction, origin: TransactionOrigin) -> Result<Self, Error> {
 | 
						fn new(transaction: SignedTransaction, origin: TransactionOrigin, min_block: Option<BlockNumber>) -> Result<Self, Error> {
 | 
				
			||||||
		try!(transaction.sender());
 | 
							try!(transaction.sender());
 | 
				
			||||||
		Ok(VerifiedTransaction {
 | 
							Ok(VerifiedTransaction {
 | 
				
			||||||
			transaction: transaction,
 | 
								transaction: transaction,
 | 
				
			||||||
			origin: origin,
 | 
								origin: origin,
 | 
				
			||||||
 | 
								min_block: min_block,
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -620,6 +624,7 @@ impl TransactionQueue {
 | 
				
			|||||||
		&mut self,
 | 
							&mut self,
 | 
				
			||||||
		tx: SignedTransaction,
 | 
							tx: SignedTransaction,
 | 
				
			||||||
		origin: TransactionOrigin,
 | 
							origin: TransactionOrigin,
 | 
				
			||||||
 | 
							min_block: Option<BlockNumber>,
 | 
				
			||||||
		fetch_account: &F,
 | 
							fetch_account: &F,
 | 
				
			||||||
		gas_estimator: &G,
 | 
							gas_estimator: &G,
 | 
				
			||||||
	) -> Result<TransactionImportResult, Error> where
 | 
						) -> Result<TransactionImportResult, Error> where
 | 
				
			||||||
@ -630,7 +635,7 @@ impl TransactionQueue {
 | 
				
			|||||||
			let hash = tx.hash();
 | 
								let hash = tx.hash();
 | 
				
			||||||
			let cloned_tx = tx.clone();
 | 
								let cloned_tx = tx.clone();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			let result = self.add_internal(tx, origin, fetch_account, gas_estimator);
 | 
								let result = self.add_internal(tx, origin, min_block, fetch_account, gas_estimator);
 | 
				
			||||||
			match result {
 | 
								match result {
 | 
				
			||||||
				Ok(TransactionImportResult::Current) => {
 | 
									Ok(TransactionImportResult::Current) => {
 | 
				
			||||||
					self.local_transactions.mark_pending(hash);
 | 
										self.local_transactions.mark_pending(hash);
 | 
				
			||||||
@ -651,7 +656,7 @@ impl TransactionQueue {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
			result
 | 
								result
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			self.add_internal(tx, origin, fetch_account, gas_estimator)
 | 
								self.add_internal(tx, origin, min_block, fetch_account, gas_estimator)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -660,6 +665,7 @@ impl TransactionQueue {
 | 
				
			|||||||
		&mut self,
 | 
							&mut self,
 | 
				
			||||||
		tx: SignedTransaction,
 | 
							tx: SignedTransaction,
 | 
				
			||||||
		origin: TransactionOrigin,
 | 
							origin: TransactionOrigin,
 | 
				
			||||||
 | 
							min_block: Option<BlockNumber>,
 | 
				
			||||||
		fetch_account: &F,
 | 
							fetch_account: &F,
 | 
				
			||||||
		gas_estimator: &G,
 | 
							gas_estimator: &G,
 | 
				
			||||||
	) -> Result<TransactionImportResult, Error> where
 | 
						) -> Result<TransactionImportResult, Error> where
 | 
				
			||||||
@ -728,7 +734,7 @@ impl TransactionQueue {
 | 
				
			|||||||
		// Verify signature
 | 
							// Verify signature
 | 
				
			||||||
		try!(tx.check_low_s());
 | 
							try!(tx.check_low_s());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		let vtx = try!(VerifiedTransaction::new(tx, origin));
 | 
							let vtx = try!(VerifiedTransaction::new(tx, origin, min_block));
 | 
				
			||||||
		let client_account = fetch_account(&vtx.sender());
 | 
							let client_account = fetch_account(&vtx.sender());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		let cost = vtx.transaction.value + vtx.transaction.gas_price * vtx.transaction.gas;
 | 
							let cost = vtx.transaction.value + vtx.transaction.gas_price * vtx.transaction.gas;
 | 
				
			||||||
@ -968,10 +974,48 @@ impl TransactionQueue {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	/// Returns top transactions from the queue ordered by priority.
 | 
						/// Returns top transactions from the queue ordered by priority.
 | 
				
			||||||
	pub fn top_transactions(&self) -> Vec<SignedTransaction> {
 | 
						pub fn top_transactions(&self) -> Vec<SignedTransaction> {
 | 
				
			||||||
		self.current.by_priority
 | 
							self.top_transactions_at(BlockNumber::max_value())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fn filter_pending_transaction<F>(&self, best_block: BlockNumber, mut f: F)
 | 
				
			||||||
 | 
							where F: FnMut(&VerifiedTransaction) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							let mut delayed = HashSet::new();
 | 
				
			||||||
 | 
							for t in self.current.by_priority.iter() {
 | 
				
			||||||
 | 
								let tx = self.by_hash.get(&t.hash).expect("All transactions in `current` and `future` are always included in `by_hash`");
 | 
				
			||||||
 | 
								let sender = tx.sender();
 | 
				
			||||||
 | 
								if delayed.contains(&sender) {
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if tx.min_block.unwrap_or(0) > best_block {
 | 
				
			||||||
 | 
									delayed.insert(sender);
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								f(&tx);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/// Returns top transactions from the queue ordered by priority.
 | 
				
			||||||
 | 
						pub fn top_transactions_at(&self, best_block: BlockNumber) -> Vec<SignedTransaction> {
 | 
				
			||||||
 | 
							let mut r = Vec::new();
 | 
				
			||||||
 | 
							self.filter_pending_transaction(best_block, |tx| r.push(tx.transaction.clone()));
 | 
				
			||||||
 | 
							r
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/// Return all ready transactions.
 | 
				
			||||||
 | 
						pub fn pending_transactions(&self, best_block: BlockNumber) -> Vec<PendingTransaction> {
 | 
				
			||||||
 | 
							let mut r = Vec::new();
 | 
				
			||||||
 | 
							self.filter_pending_transaction(best_block, |tx| r.push(PendingTransaction::new(tx.transaction.clone(), tx.min_block)));
 | 
				
			||||||
 | 
							r
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/// Return all ready transactions.
 | 
				
			||||||
 | 
						pub fn future_transactions(&self) -> Vec<PendingTransaction> {
 | 
				
			||||||
 | 
							self.future.by_priority
 | 
				
			||||||
			.iter()
 | 
								.iter()
 | 
				
			||||||
			.map(|t| self.by_hash.get(&t.hash).expect("All transactions in `current` and `future` are always included in `by_hash`"))
 | 
								.map(|t| self.by_hash.get(&t.hash).expect("All transactions in `current` and `future` are always included in `by_hash`"))
 | 
				
			||||||
			.map(|t| t.transaction.clone())
 | 
								.map(|t| PendingTransaction { transaction: t.transaction.clone(), min_block: t.min_block })
 | 
				
			||||||
			.collect()
 | 
								.collect()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -980,15 +1024,6 @@ impl TransactionQueue {
 | 
				
			|||||||
		self.local_transactions.all_transactions()
 | 
							self.local_transactions.all_transactions()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#[cfg(test)]
 | 
					 | 
				
			||||||
	fn future_transactions(&self) -> Vec<SignedTransaction> {
 | 
					 | 
				
			||||||
		self.future.by_priority
 | 
					 | 
				
			||||||
			.iter()
 | 
					 | 
				
			||||||
			.map(|t| self.by_hash.get(&t.hash).expect("All transactions in `current` and `future` are always included in `by_hash`"))
 | 
					 | 
				
			||||||
			.map(|t| t.transaction.clone())
 | 
					 | 
				
			||||||
			.collect()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/// Returns hashes of all transactions from current, ordered by priority.
 | 
						/// Returns hashes of all transactions from current, ordered by priority.
 | 
				
			||||||
	pub fn pending_hashes(&self) -> Vec<H256> {
 | 
						pub fn pending_hashes(&self) -> Vec<H256> {
 | 
				
			||||||
		self.current.by_priority
 | 
							self.current.by_priority
 | 
				
			||||||
@ -1353,14 +1388,14 @@ mod test {
 | 
				
			|||||||
		let (tx1, tx2) = new_tx_pair(123.into(), 1.into(), 1.into(), 0.into());
 | 
							let (tx1, tx2) = new_tx_pair(123.into(), 1.into(), 1.into(), 0.into());
 | 
				
			||||||
		let sender = tx1.sender().unwrap();
 | 
							let sender = tx1.sender().unwrap();
 | 
				
			||||||
		let nonce = tx1.nonce;
 | 
							let nonce = tx1.nonce;
 | 
				
			||||||
		txq.add(tx1.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx1.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		txq.add(tx2.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx2.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		assert_eq!(txq.status().pending, 2);
 | 
							assert_eq!(txq.status().pending, 2);
 | 
				
			||||||
		assert_eq!(txq.last_nonce(&sender), Some(nonce + 1.into()));
 | 
							assert_eq!(txq.last_nonce(&sender), Some(nonce + 1.into()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
		let tx = new_tx(123.into(), 1.into());
 | 
							let tx = new_tx(123.into(), 1.into());
 | 
				
			||||||
		let res = txq.add(tx.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator);
 | 
							let res = txq.add(tx.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// then
 | 
							// then
 | 
				
			||||||
		// No longer the case as we don't even consider a transaction that isn't above a full
 | 
							// No longer the case as we don't even consider a transaction that isn't above a full
 | 
				
			||||||
@ -1392,12 +1427,12 @@ mod test {
 | 
				
			|||||||
			gas_limit: !U256::zero(),
 | 
								gas_limit: !U256::zero(),
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
		let (tx1, tx2) = new_tx_pair_default(1.into(), 0.into());
 | 
							let (tx1, tx2) = new_tx_pair_default(1.into(), 0.into());
 | 
				
			||||||
		let tx1 = VerifiedTransaction::new(tx1, TransactionOrigin::External).unwrap();
 | 
							let tx1 = VerifiedTransaction::new(tx1, TransactionOrigin::External, None).unwrap();
 | 
				
			||||||
		let tx2 = VerifiedTransaction::new(tx2, TransactionOrigin::External).unwrap();
 | 
							let tx2 = VerifiedTransaction::new(tx2, TransactionOrigin::External, None).unwrap();
 | 
				
			||||||
		let mut by_hash = {
 | 
							let mut by_hash = {
 | 
				
			||||||
			let mut x = HashMap::new();
 | 
								let mut x = HashMap::new();
 | 
				
			||||||
			let tx1 = VerifiedTransaction::new(tx1.transaction.clone(), TransactionOrigin::External).unwrap();
 | 
								let tx1 = VerifiedTransaction::new(tx1.transaction.clone(), TransactionOrigin::External, None).unwrap();
 | 
				
			||||||
			let tx2 = VerifiedTransaction::new(tx2.transaction.clone(), TransactionOrigin::External).unwrap();
 | 
								let tx2 = VerifiedTransaction::new(tx2.transaction.clone(), TransactionOrigin::External, None).unwrap();
 | 
				
			||||||
			x.insert(tx1.hash(), tx1);
 | 
								x.insert(tx1.hash(), tx1);
 | 
				
			||||||
			x.insert(tx2.hash(), tx2);
 | 
								x.insert(tx2.hash(), tx2);
 | 
				
			||||||
			x
 | 
								x
 | 
				
			||||||
@ -1435,12 +1470,12 @@ mod test {
 | 
				
			|||||||
		// Create two transactions with same nonce
 | 
							// Create two transactions with same nonce
 | 
				
			||||||
		// (same hash)
 | 
							// (same hash)
 | 
				
			||||||
		let (tx1, tx2) = new_tx_pair_default(0.into(), 0.into());
 | 
							let (tx1, tx2) = new_tx_pair_default(0.into(), 0.into());
 | 
				
			||||||
		let tx1 = VerifiedTransaction::new(tx1, TransactionOrigin::External).unwrap();
 | 
							let tx1 = VerifiedTransaction::new(tx1, TransactionOrigin::External, None).unwrap();
 | 
				
			||||||
		let tx2 = VerifiedTransaction::new(tx2, TransactionOrigin::External).unwrap();
 | 
							let tx2 = VerifiedTransaction::new(tx2, TransactionOrigin::External, None).unwrap();
 | 
				
			||||||
		let by_hash = {
 | 
							let by_hash = {
 | 
				
			||||||
			let mut x = HashMap::new();
 | 
								let mut x = HashMap::new();
 | 
				
			||||||
			let tx1 = VerifiedTransaction::new(tx1.transaction.clone(), TransactionOrigin::External).unwrap();
 | 
								let tx1 = VerifiedTransaction::new(tx1.transaction.clone(), TransactionOrigin::External, None).unwrap();
 | 
				
			||||||
			let tx2 = VerifiedTransaction::new(tx2.transaction.clone(), TransactionOrigin::External).unwrap();
 | 
								let tx2 = VerifiedTransaction::new(tx2.transaction.clone(), TransactionOrigin::External, None).unwrap();
 | 
				
			||||||
			x.insert(tx1.hash(), tx1);
 | 
								x.insert(tx1.hash(), tx1);
 | 
				
			||||||
			x.insert(tx2.hash(), tx2);
 | 
								x.insert(tx2.hash(), tx2);
 | 
				
			||||||
			x
 | 
								x
 | 
				
			||||||
@ -1482,10 +1517,10 @@ mod test {
 | 
				
			|||||||
			gas_limit: !U256::zero(),
 | 
								gas_limit: !U256::zero(),
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
		let tx = new_tx_default();
 | 
							let tx = new_tx_default();
 | 
				
			||||||
		let tx1 = VerifiedTransaction::new(tx.clone(), TransactionOrigin::External).unwrap();
 | 
							let tx1 = VerifiedTransaction::new(tx.clone(), TransactionOrigin::External, None).unwrap();
 | 
				
			||||||
		let order1 = TransactionOrder::for_transaction(&tx1, 0.into(), 1.into(), PrioritizationStrategy::GasPriceOnly);
 | 
							let order1 = TransactionOrder::for_transaction(&tx1, 0.into(), 1.into(), PrioritizationStrategy::GasPriceOnly);
 | 
				
			||||||
		assert!(set.insert(tx1.sender(), tx1.nonce(), order1).is_none());
 | 
							assert!(set.insert(tx1.sender(), tx1.nonce(), order1).is_none());
 | 
				
			||||||
		let tx2 = VerifiedTransaction::new(tx, TransactionOrigin::External).unwrap();
 | 
							let tx2 = VerifiedTransaction::new(tx, TransactionOrigin::External, None).unwrap();
 | 
				
			||||||
		let order2 = TransactionOrder::for_transaction(&tx2, 0.into(), 1.into(), PrioritizationStrategy::GasPriceOnly);
 | 
							let order2 = TransactionOrder::for_transaction(&tx2, 0.into(), 1.into(), PrioritizationStrategy::GasPriceOnly);
 | 
				
			||||||
		assert!(set.insert(tx2.sender(), tx2.nonce(), order2).is_some());
 | 
							assert!(set.insert(tx2.sender(), tx2.nonce(), order2).is_some());
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -1502,7 +1537,7 @@ mod test {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		assert_eq!(set.gas_price_entry_limit(), 0.into());
 | 
							assert_eq!(set.gas_price_entry_limit(), 0.into());
 | 
				
			||||||
		let tx = new_tx_default();
 | 
							let tx = new_tx_default();
 | 
				
			||||||
		let tx1 = VerifiedTransaction::new(tx.clone(), TransactionOrigin::External).unwrap();
 | 
							let tx1 = VerifiedTransaction::new(tx.clone(), TransactionOrigin::External, None).unwrap();
 | 
				
			||||||
		let order1 = TransactionOrder::for_transaction(&tx1, 0.into(), 1.into(), PrioritizationStrategy::GasPriceOnly);
 | 
							let order1 = TransactionOrder::for_transaction(&tx1, 0.into(), 1.into(), PrioritizationStrategy::GasPriceOnly);
 | 
				
			||||||
		assert!(set.insert(tx1.sender(), tx1.nonce(), order1.clone()).is_none());
 | 
							assert!(set.insert(tx1.sender(), tx1.nonce(), order1.clone()).is_none());
 | 
				
			||||||
		assert_eq!(set.gas_price_entry_limit(), 2.into());
 | 
							assert_eq!(set.gas_price_entry_limit(), 2.into());
 | 
				
			||||||
@ -1517,12 +1552,12 @@ mod test {
 | 
				
			|||||||
			!U256::zero() };
 | 
								!U256::zero() };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// First insert one transaction to future
 | 
							// First insert one transaction to future
 | 
				
			||||||
		let res = txq.add(tx, TransactionOrigin::External, &prev_nonce, &gas_estimator);
 | 
							let res = txq.add(tx, TransactionOrigin::External, None, &prev_nonce, &gas_estimator);
 | 
				
			||||||
		assert_eq!(res.unwrap(), TransactionImportResult::Future);
 | 
							assert_eq!(res.unwrap(), TransactionImportResult::Future);
 | 
				
			||||||
		assert_eq!(txq.status().future, 1);
 | 
							assert_eq!(txq.status().future, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// now import second transaction to current
 | 
							// now import second transaction to current
 | 
				
			||||||
		let res = txq.add(tx2.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator);
 | 
							let res = txq.add(tx2.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// and then there should be only one transaction in current (the one with higher gas_price)
 | 
							// and then there should be only one transaction in current (the one with higher gas_price)
 | 
				
			||||||
		assert_eq!(res.unwrap(), TransactionImportResult::Current);
 | 
							assert_eq!(res.unwrap(), TransactionImportResult::Current);
 | 
				
			||||||
@ -1542,12 +1577,12 @@ mod test {
 | 
				
			|||||||
			!U256::zero() };
 | 
								!U256::zero() };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// First insert one transaction to future
 | 
							// First insert one transaction to future
 | 
				
			||||||
		let res = txq.add(tx.clone(), TransactionOrigin::External, &prev_nonce, &gas_estimator);
 | 
							let res = txq.add(tx.clone(), TransactionOrigin::External, None, &prev_nonce, &gas_estimator);
 | 
				
			||||||
		assert_eq!(res.unwrap(), TransactionImportResult::Future);
 | 
							assert_eq!(res.unwrap(), TransactionImportResult::Future);
 | 
				
			||||||
		assert_eq!(txq.status().future, 1);
 | 
							assert_eq!(txq.status().future, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// now import second transaction to current
 | 
							// now import second transaction to current
 | 
				
			||||||
		let res = txq.add(tx2.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator);
 | 
							let res = txq.add(tx2.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// then
 | 
							// then
 | 
				
			||||||
		assert_eq!(res.unwrap(), TransactionImportResult::Current);
 | 
							assert_eq!(res.unwrap(), TransactionImportResult::Current);
 | 
				
			||||||
@ -1566,7 +1601,7 @@ mod test {
 | 
				
			|||||||
		let tx = new_tx_default();
 | 
							let tx = new_tx_default();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
		let res = txq.add(tx, TransactionOrigin::External, &default_account_details, &gas_estimator);
 | 
							let res = txq.add(tx, TransactionOrigin::External, None, &default_account_details, &gas_estimator);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// then
 | 
							// then
 | 
				
			||||||
		assert_eq!(res.unwrap(), TransactionImportResult::Current);
 | 
							assert_eq!(res.unwrap(), TransactionImportResult::Current);
 | 
				
			||||||
@ -1585,10 +1620,10 @@ mod test {
 | 
				
			|||||||
		txq.set_minimal_gas_price(15.into());
 | 
							txq.set_minimal_gas_price(15.into());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
		let res1 = txq.add(tx1, TransactionOrigin::External, &default_account_details, &gas_estimator);
 | 
							let res1 = txq.add(tx1, TransactionOrigin::External, None, &default_account_details, &gas_estimator);
 | 
				
			||||||
		let res2 = txq.add(tx2, TransactionOrigin::External, &default_account_details, &gas_estimator);
 | 
							let res2 = txq.add(tx2, TransactionOrigin::External, None, &default_account_details, &gas_estimator);
 | 
				
			||||||
		let res3 = txq.add(tx3, TransactionOrigin::External, &default_account_details, &gas_estimator);
 | 
							let res3 = txq.add(tx3, TransactionOrigin::External, None, &default_account_details, &gas_estimator);
 | 
				
			||||||
		let res4 = txq.add(tx4, TransactionOrigin::External, &default_account_details, &gas_estimator);
 | 
							let res4 = txq.add(tx4, TransactionOrigin::External, None, &default_account_details, &gas_estimator);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// then
 | 
							// then
 | 
				
			||||||
		assert_eq!(res1.unwrap(), TransactionImportResult::Current);
 | 
							assert_eq!(res1.unwrap(), TransactionImportResult::Current);
 | 
				
			||||||
@ -1619,10 +1654,10 @@ mod test {
 | 
				
			|||||||
		txq.set_minimal_gas_price(15.into());
 | 
							txq.set_minimal_gas_price(15.into());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
		let res1 = txq.add(tx1, TransactionOrigin::External, &default_account_details, &gas_estimator);
 | 
							let res1 = txq.add(tx1, TransactionOrigin::External, None, &default_account_details, &gas_estimator);
 | 
				
			||||||
		let res2 = txq.add(tx2, TransactionOrigin::External, &default_account_details, &gas_estimator);
 | 
							let res2 = txq.add(tx2, TransactionOrigin::External, None, &default_account_details, &gas_estimator);
 | 
				
			||||||
		let res3 = txq.add(tx3, TransactionOrigin::External, &default_account_details, &gas_estimator);
 | 
							let res3 = txq.add(tx3, TransactionOrigin::External, None, &default_account_details, &gas_estimator);
 | 
				
			||||||
		let res4 = txq.add(tx4, TransactionOrigin::External, &default_account_details, &gas_estimator);
 | 
							let res4 = txq.add(tx4, TransactionOrigin::External, None, &default_account_details, &gas_estimator);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// then
 | 
							// then
 | 
				
			||||||
		assert_eq!(res1.unwrap(), TransactionImportResult::Current);
 | 
							assert_eq!(res1.unwrap(), TransactionImportResult::Current);
 | 
				
			||||||
@ -1665,7 +1700,7 @@ mod test {
 | 
				
			|||||||
		txq.set_gas_limit(limit);
 | 
							txq.set_gas_limit(limit);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
		let res = txq.add(tx, TransactionOrigin::External, &default_account_details, &gas_estimator);
 | 
							let res = txq.add(tx, TransactionOrigin::External, None, &default_account_details, &gas_estimator);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// then
 | 
							// then
 | 
				
			||||||
		assert_eq!(unwrap_tx_err(res), TransactionError::GasLimitExceeded {
 | 
							assert_eq!(unwrap_tx_err(res), TransactionError::GasLimitExceeded {
 | 
				
			||||||
@ -1689,7 +1724,7 @@ mod test {
 | 
				
			|||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
		let res = txq.add(tx, TransactionOrigin::External, &account, &gas_estimator);
 | 
							let res = txq.add(tx, TransactionOrigin::External, None, &account, &gas_estimator);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// then
 | 
							// then
 | 
				
			||||||
		assert_eq!(unwrap_tx_err(res), TransactionError::InsufficientBalance {
 | 
							assert_eq!(unwrap_tx_err(res), TransactionError::InsufficientBalance {
 | 
				
			||||||
@ -1709,7 +1744,7 @@ mod test {
 | 
				
			|||||||
		txq.set_minimal_gas_price(tx.gas_price + U256::one());
 | 
							txq.set_minimal_gas_price(tx.gas_price + U256::one());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
		let res = txq.add(tx, TransactionOrigin::External, &default_account_details, &gas_estimator);
 | 
							let res = txq.add(tx, TransactionOrigin::External, None, &default_account_details, &gas_estimator);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// then
 | 
							// then
 | 
				
			||||||
		assert_eq!(unwrap_tx_err(res), TransactionError::InsufficientGasPrice {
 | 
							assert_eq!(unwrap_tx_err(res), TransactionError::InsufficientGasPrice {
 | 
				
			||||||
@ -1729,7 +1764,7 @@ mod test {
 | 
				
			|||||||
		txq.set_minimal_gas_price(tx.gas_price + U256::one());
 | 
							txq.set_minimal_gas_price(tx.gas_price + U256::one());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
		let res = txq.add(tx, TransactionOrigin::Local, &default_account_details, &gas_estimator);
 | 
							let res = txq.add(tx, TransactionOrigin::Local, None, &default_account_details, &gas_estimator);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// then
 | 
							// then
 | 
				
			||||||
		assert_eq!(res.unwrap(), TransactionImportResult::Current);
 | 
							assert_eq!(res.unwrap(), TransactionImportResult::Current);
 | 
				
			||||||
@ -1759,7 +1794,7 @@ mod test {
 | 
				
			|||||||
			rlp::decode(s.as_raw())
 | 
								rlp::decode(s.as_raw())
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
		let res = txq.add(stx, TransactionOrigin::External, &default_account_details, &gas_estimator);
 | 
							let res = txq.add(stx, TransactionOrigin::External, None, &default_account_details, &gas_estimator);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// then
 | 
							// then
 | 
				
			||||||
		assert!(res.is_err());
 | 
							assert!(res.is_err());
 | 
				
			||||||
@ -1773,8 +1808,8 @@ mod test {
 | 
				
			|||||||
		let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
 | 
							let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
		txq.add(tx.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		txq.add(tx2.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx2.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// then
 | 
							// then
 | 
				
			||||||
		let top = txq.top_transactions();
 | 
							let top = txq.top_transactions();
 | 
				
			||||||
@ -1793,9 +1828,9 @@ mod test {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
		// first insert the one with higher gas price
 | 
							// first insert the one with higher gas price
 | 
				
			||||||
		txq.add(tx2.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx2.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		// then the one with lower gas price, but local
 | 
							// then the one with lower gas price, but local
 | 
				
			||||||
		txq.add(tx.clone(), TransactionOrigin::Local, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx.clone(), TransactionOrigin::Local, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// then
 | 
							// then
 | 
				
			||||||
		let top = txq.top_transactions();
 | 
							let top = txq.top_transactions();
 | 
				
			||||||
@ -1812,15 +1847,15 @@ mod test {
 | 
				
			|||||||
		// the second one has same nonce but higher `gas_price`
 | 
							// the second one has same nonce but higher `gas_price`
 | 
				
			||||||
		let (_, tx0) = new_similar_tx_pair();
 | 
							let (_, tx0) = new_similar_tx_pair();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		txq.add(tx0.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx0.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		txq.add(tx1.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx1.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		// the one with higher gas price is first
 | 
							// the one with higher gas price is first
 | 
				
			||||||
		assert_eq!(txq.top_transactions()[0], tx0);
 | 
							assert_eq!(txq.top_transactions()[0], tx0);
 | 
				
			||||||
		assert_eq!(txq.top_transactions()[1], tx1);
 | 
							assert_eq!(txq.top_transactions()[1], tx1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
		// insert second as local
 | 
							// insert second as local
 | 
				
			||||||
		txq.add(tx2.clone(), TransactionOrigin::Local, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx2.clone(), TransactionOrigin::Local, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// then
 | 
							// then
 | 
				
			||||||
		// the order should be updated
 | 
							// the order should be updated
 | 
				
			||||||
@ -1839,9 +1874,9 @@ mod test {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
		// first insert local one with higher gas price
 | 
							// first insert local one with higher gas price
 | 
				
			||||||
		txq.add(tx2.clone(), TransactionOrigin::Local, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx2.clone(), TransactionOrigin::Local, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		// then the one with lower gas price, but from retracted block
 | 
							// then the one with lower gas price, but from retracted block
 | 
				
			||||||
		txq.add(tx.clone(), TransactionOrigin::RetractedBlock, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx.clone(), TransactionOrigin::RetractedBlock, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// then
 | 
							// then
 | 
				
			||||||
		let top = txq.top_transactions();
 | 
							let top = txq.top_transactions();
 | 
				
			||||||
@ -1857,8 +1892,8 @@ mod test {
 | 
				
			|||||||
		let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
 | 
							let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
		txq.add(tx.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		txq.add(tx2.clone(), TransactionOrigin::Local, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx2.clone(), TransactionOrigin::Local, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// then
 | 
							// then
 | 
				
			||||||
		let top = txq.top_transactions();
 | 
							let top = txq.top_transactions();
 | 
				
			||||||
@ -1877,10 +1912,10 @@ mod test {
 | 
				
			|||||||
		let (tx1, tx2) = new_tx_pair_with_gas_price_increment(3.into());
 | 
							let (tx1, tx2) = new_tx_pair_with_gas_price_increment(3.into());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// insert everything
 | 
							// insert everything
 | 
				
			||||||
		txq.add(txa.clone(), TransactionOrigin::External, &prev_nonce, &gas_estimator).unwrap();
 | 
							txq.add(txa.clone(), TransactionOrigin::External, None, &prev_nonce, &gas_estimator).unwrap();
 | 
				
			||||||
		txq.add(txb.clone(), TransactionOrigin::External, &prev_nonce, &gas_estimator).unwrap();
 | 
							txq.add(txb.clone(), TransactionOrigin::External, None, &prev_nonce, &gas_estimator).unwrap();
 | 
				
			||||||
		txq.add(tx1.clone(), TransactionOrigin::External, &prev_nonce, &gas_estimator).unwrap();
 | 
							txq.add(tx1.clone(), TransactionOrigin::External, None, &prev_nonce, &gas_estimator).unwrap();
 | 
				
			||||||
		txq.add(tx2.clone(), TransactionOrigin::External, &prev_nonce, &gas_estimator).unwrap();
 | 
							txq.add(tx2.clone(), TransactionOrigin::External, None, &prev_nonce, &gas_estimator).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		assert_eq!(txq.status().future, 4);
 | 
							assert_eq!(txq.status().future, 4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1889,10 +1924,10 @@ mod test {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		// then
 | 
							// then
 | 
				
			||||||
		let top = txq.future_transactions();
 | 
							let top = txq.future_transactions();
 | 
				
			||||||
		assert_eq!(top[0], txa);
 | 
							assert_eq!(top[0].transaction, txa);
 | 
				
			||||||
		assert_eq!(top[1], txb);
 | 
							assert_eq!(top[1].transaction, txb);
 | 
				
			||||||
		assert_eq!(top[2], tx1);
 | 
							assert_eq!(top[2].transaction, tx1);
 | 
				
			||||||
		assert_eq!(top[3], tx2);
 | 
							assert_eq!(top[3].transaction, tx2);
 | 
				
			||||||
		assert_eq!(top.len(), 4);
 | 
							assert_eq!(top.len(), 4);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1905,10 +1940,10 @@ mod test {
 | 
				
			|||||||
		let (tx1, tx2) = new_tx_pair_with_gas_price_increment(3.into());
 | 
							let (tx1, tx2) = new_tx_pair_with_gas_price_increment(3.into());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// insert everything
 | 
							// insert everything
 | 
				
			||||||
		txq.add(txa.clone(), TransactionOrigin::Local, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(txa.clone(), TransactionOrigin::Local, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		txq.add(txb.clone(), TransactionOrigin::Local, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(txb.clone(), TransactionOrigin::Local, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		txq.add(tx1.clone(), TransactionOrigin::Local, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx1.clone(), TransactionOrigin::Local, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		txq.add(tx2.clone(), TransactionOrigin::Local, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx2.clone(), TransactionOrigin::Local, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		let top = txq.top_transactions();
 | 
							let top = txq.top_transactions();
 | 
				
			||||||
		assert_eq!(top[0], tx1);
 | 
							assert_eq!(top[0], tx1);
 | 
				
			||||||
@ -1938,10 +1973,10 @@ mod test {
 | 
				
			|||||||
		let (tx1, tx2) = new_tx_pair_with_gas_price_increment(3.into());
 | 
							let (tx1, tx2) = new_tx_pair_with_gas_price_increment(3.into());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// insert everything
 | 
							// insert everything
 | 
				
			||||||
		txq.add(txa.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(txa.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		txq.add(txb.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(txb.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		txq.add(tx1.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx1.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		txq.add(tx2.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx2.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		let top = txq.top_transactions();
 | 
							let top = txq.top_transactions();
 | 
				
			||||||
		assert_eq!(top[0], tx1);
 | 
							assert_eq!(top[0], tx1);
 | 
				
			||||||
@ -1970,8 +2005,8 @@ mod test {
 | 
				
			|||||||
		let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
 | 
							let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
		txq.add(tx.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		txq.add(tx2.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx2.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// then
 | 
							// then
 | 
				
			||||||
		let top = txq.pending_hashes();
 | 
							let top = txq.pending_hashes();
 | 
				
			||||||
@ -1988,8 +2023,8 @@ mod test {
 | 
				
			|||||||
		let (tx, tx2) = new_tx_pair_default(2.into(), 0.into());
 | 
							let (tx, tx2) = new_tx_pair_default(2.into(), 0.into());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
		let res1 = txq.add(tx.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							let res1 = txq.add(tx.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		let res2 = txq.add(tx2.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							let res2 = txq.add(tx2.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// then
 | 
							// then
 | 
				
			||||||
		assert_eq!(res1, TransactionImportResult::Current);
 | 
							assert_eq!(res1, TransactionImportResult::Current);
 | 
				
			||||||
@ -2002,6 +2037,26 @@ mod test {
 | 
				
			|||||||
		assert_eq!(top[0], tx);
 | 
							assert_eq!(top[0], tx);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#[test]
 | 
				
			||||||
 | 
						fn should_handle_min_block() {
 | 
				
			||||||
 | 
							// given
 | 
				
			||||||
 | 
							let mut txq = TransactionQueue::default();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// when
 | 
				
			||||||
 | 
							let res1 = txq.add(tx.clone(), TransactionOrigin::External, Some(1), &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
 | 
							let res2 = txq.add(tx2.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// then
 | 
				
			||||||
 | 
							assert_eq!(res1, TransactionImportResult::Current);
 | 
				
			||||||
 | 
							assert_eq!(res2, TransactionImportResult::Current);
 | 
				
			||||||
 | 
							let top = txq.top_transactions_at(0);
 | 
				
			||||||
 | 
							assert_eq!(top.len(), 0);
 | 
				
			||||||
 | 
							let top = txq.top_transactions_at(1);
 | 
				
			||||||
 | 
							assert_eq!(top.len(), 2);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#[test]
 | 
						#[test]
 | 
				
			||||||
	fn should_correctly_update_futures_when_removing() {
 | 
						fn should_correctly_update_futures_when_removing() {
 | 
				
			||||||
		// given
 | 
							// given
 | 
				
			||||||
@ -2012,8 +2067,8 @@ mod test {
 | 
				
			|||||||
		let mut txq = TransactionQueue::default();
 | 
							let mut txq = TransactionQueue::default();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
 | 
							let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
 | 
				
			||||||
		txq.add(tx.clone(), TransactionOrigin::External, &prev_nonce, &gas_estimator).unwrap();
 | 
							txq.add(tx.clone(), TransactionOrigin::External, None, &prev_nonce, &gas_estimator).unwrap();
 | 
				
			||||||
		txq.add(tx2.clone(), TransactionOrigin::External, &prev_nonce, &gas_estimator).unwrap();
 | 
							txq.add(tx2.clone(), TransactionOrigin::External, None, &prev_nonce, &gas_estimator).unwrap();
 | 
				
			||||||
		assert_eq!(txq.status().future, 2);
 | 
							assert_eq!(txq.status().future, 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
@ -2035,13 +2090,13 @@ mod test {
 | 
				
			|||||||
		let tx1 = new_unsigned_tx(124.into(), default_gas_val(), 1.into()).sign(secret, None);
 | 
							let tx1 = new_unsigned_tx(124.into(), default_gas_val(), 1.into()).sign(secret, None);
 | 
				
			||||||
		let tx2 = new_unsigned_tx(125.into(), default_gas_val(), 1.into()).sign(secret, None);
 | 
							let tx2 = new_unsigned_tx(125.into(), default_gas_val(), 1.into()).sign(secret, None);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		txq.add(tx, TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx, TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		assert_eq!(txq.status().pending, 1);
 | 
							assert_eq!(txq.status().pending, 1);
 | 
				
			||||||
		txq.add(tx2, TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx2, TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		assert_eq!(txq.status().future, 1);
 | 
							assert_eq!(txq.status().future, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
		txq.add(tx1, TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx1, TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// then
 | 
							// then
 | 
				
			||||||
		let stats = txq.status();
 | 
							let stats = txq.status();
 | 
				
			||||||
@ -2057,8 +2112,8 @@ mod test {
 | 
				
			|||||||
		// given
 | 
							// given
 | 
				
			||||||
		let mut txq2 = TransactionQueue::default();
 | 
							let mut txq2 = TransactionQueue::default();
 | 
				
			||||||
		let (tx, tx2) = new_tx_pair_default(3.into(), 0.into());
 | 
							let (tx, tx2) = new_tx_pair_default(3.into(), 0.into());
 | 
				
			||||||
		txq2.add(tx.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq2.add(tx.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		txq2.add(tx2.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq2.add(tx2.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		assert_eq!(txq2.status().pending, 1);
 | 
							assert_eq!(txq2.status().pending, 1);
 | 
				
			||||||
		assert_eq!(txq2.status().future, 1);
 | 
							assert_eq!(txq2.status().future, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -2079,10 +2134,10 @@ mod test {
 | 
				
			|||||||
		let mut txq = TransactionQueue::default();
 | 
							let mut txq = TransactionQueue::default();
 | 
				
			||||||
		let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
 | 
							let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
 | 
				
			||||||
		let tx3 = new_tx_default();
 | 
							let tx3 = new_tx_default();
 | 
				
			||||||
		txq.add(tx2.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx2.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		assert_eq!(txq.status().future, 1);
 | 
							assert_eq!(txq.status().future, 1);
 | 
				
			||||||
		txq.add(tx3.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx3.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		txq.add(tx.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		assert_eq!(txq.status().pending, 3);
 | 
							assert_eq!(txq.status().pending, 3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
@ -2101,8 +2156,8 @@ mod test {
 | 
				
			|||||||
		let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
 | 
							let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// add
 | 
							// add
 | 
				
			||||||
		txq.add(tx2.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx2.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		txq.add(tx.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		let stats = txq.status();
 | 
							let stats = txq.status();
 | 
				
			||||||
		assert_eq!(stats.pending, 2);
 | 
							assert_eq!(stats.pending, 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -2121,11 +2176,11 @@ mod test {
 | 
				
			|||||||
		let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
 | 
							let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
 | 
				
			||||||
		let sender = tx.sender().unwrap();
 | 
							let sender = tx.sender().unwrap();
 | 
				
			||||||
		let nonce = tx.nonce;
 | 
							let nonce = tx.nonce;
 | 
				
			||||||
		txq.add(tx.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		assert_eq!(txq.status().pending, 1);
 | 
							assert_eq!(txq.status().pending, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
		let res = txq.add(tx2.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator);
 | 
							let res = txq.add(tx2.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// then
 | 
							// then
 | 
				
			||||||
		let t = txq.top_transactions();
 | 
							let t = txq.top_transactions();
 | 
				
			||||||
@ -2142,14 +2197,14 @@ mod test {
 | 
				
			|||||||
		txq.current.set_limit(10);
 | 
							txq.current.set_limit(10);
 | 
				
			||||||
		let (tx1, tx2) = new_tx_pair_default(4.into(), 1.into());
 | 
							let (tx1, tx2) = new_tx_pair_default(4.into(), 1.into());
 | 
				
			||||||
		let (tx3, tx4) = new_tx_pair_default(4.into(), 2.into());
 | 
							let (tx3, tx4) = new_tx_pair_default(4.into(), 2.into());
 | 
				
			||||||
		txq.add(tx1.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx1.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		txq.add(tx3.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx3.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		assert_eq!(txq.status().pending, 2);
 | 
							assert_eq!(txq.status().pending, 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
		txq.add(tx2.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx2.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		assert_eq!(txq.status().future, 1);
 | 
							assert_eq!(txq.status().future, 1);
 | 
				
			||||||
		txq.add(tx4.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx4.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// then
 | 
							// then
 | 
				
			||||||
		assert_eq!(txq.status().future, 1);
 | 
							assert_eq!(txq.status().future, 1);
 | 
				
			||||||
@ -2160,11 +2215,11 @@ mod test {
 | 
				
			|||||||
		let mut txq = TransactionQueue::with_limits(PrioritizationStrategy::GasPriceOnly, 100, default_gas_val() * U256::from(2), !U256::zero());
 | 
							let mut txq = TransactionQueue::with_limits(PrioritizationStrategy::GasPriceOnly, 100, default_gas_val() * U256::from(2), !U256::zero());
 | 
				
			||||||
		let (tx1, tx2) = new_tx_pair_default(U256::from(1), U256::from(1));
 | 
							let (tx1, tx2) = new_tx_pair_default(U256::from(1), U256::from(1));
 | 
				
			||||||
		let (tx3, tx4) = new_tx_pair_default(U256::from(1), U256::from(2));
 | 
							let (tx3, tx4) = new_tx_pair_default(U256::from(1), U256::from(2));
 | 
				
			||||||
		txq.add(tx1.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx1.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		txq.add(tx2.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx2.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		txq.add(tx3.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx3.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		// limited by gas
 | 
							// limited by gas
 | 
				
			||||||
		txq.add(tx4.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap_err();
 | 
							txq.add(tx4.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap_err();
 | 
				
			||||||
		assert_eq!(txq.status().pending, 2);
 | 
							assert_eq!(txq.status().pending, 2);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -2174,12 +2229,12 @@ mod test {
 | 
				
			|||||||
		let (tx1, tx2) = new_tx_pair_default(U256::from(1), U256::from(1));
 | 
							let (tx1, tx2) = new_tx_pair_default(U256::from(1), U256::from(1));
 | 
				
			||||||
		let (tx3, tx4) = new_tx_pair_default(U256::from(1), U256::from(2));
 | 
							let (tx3, tx4) = new_tx_pair_default(U256::from(1), U256::from(2));
 | 
				
			||||||
		let (tx5, _) = new_tx_pair_default(U256::from(1), U256::from(2));
 | 
							let (tx5, _) = new_tx_pair_default(U256::from(1), U256::from(2));
 | 
				
			||||||
		txq.add(tx1.clone(), TransactionOrigin::Local, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx1.clone(), TransactionOrigin::Local, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		txq.add(tx2.clone(), TransactionOrigin::Local, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx2.clone(), TransactionOrigin::Local, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		// Not accepted because of limit
 | 
							// Not accepted because of limit
 | 
				
			||||||
		txq.add(tx5.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap_err();
 | 
							txq.add(tx5.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap_err();
 | 
				
			||||||
		txq.add(tx3.clone(), TransactionOrigin::Local, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx3.clone(), TransactionOrigin::Local, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		txq.add(tx4.clone(), TransactionOrigin::Local, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx4.clone(), TransactionOrigin::Local, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		assert_eq!(txq.status().pending, 4);
 | 
							assert_eq!(txq.status().pending, 4);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -2191,7 +2246,7 @@ mod test {
 | 
				
			|||||||
		let fetch_last_nonce = |_a: &Address| AccountDetails { nonce: last_nonce, balance: !U256::zero() };
 | 
							let fetch_last_nonce = |_a: &Address| AccountDetails { nonce: last_nonce, balance: !U256::zero() };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
		let res = txq.add(tx, TransactionOrigin::External, &fetch_last_nonce, &gas_estimator);
 | 
							let res = txq.add(tx, TransactionOrigin::External, None, &fetch_last_nonce, &gas_estimator);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// then
 | 
							// then
 | 
				
			||||||
		assert_eq!(unwrap_tx_err(res), TransactionError::Old);
 | 
							assert_eq!(unwrap_tx_err(res), TransactionError::Old);
 | 
				
			||||||
@ -2207,12 +2262,12 @@ mod test {
 | 
				
			|||||||
			balance: !U256::zero() };
 | 
								balance: !U256::zero() };
 | 
				
			||||||
		let mut txq = TransactionQueue::default();
 | 
							let mut txq = TransactionQueue::default();
 | 
				
			||||||
		let (_tx1, tx2) = new_tx_pair_default(1.into(), 0.into());
 | 
							let (_tx1, tx2) = new_tx_pair_default(1.into(), 0.into());
 | 
				
			||||||
		txq.add(tx2.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx2.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		assert_eq!(txq.status().future, 1);
 | 
							assert_eq!(txq.status().future, 1);
 | 
				
			||||||
		assert_eq!(txq.status().pending, 0);
 | 
							assert_eq!(txq.status().pending, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
		let res = txq.add(tx2.clone(), TransactionOrigin::External, &nonce, &gas_estimator);
 | 
							let res = txq.add(tx2.clone(), TransactionOrigin::External, None, &nonce, &gas_estimator);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// then
 | 
							// then
 | 
				
			||||||
		assert_eq!(unwrap_tx_err(res), TransactionError::AlreadyImported);
 | 
							assert_eq!(unwrap_tx_err(res), TransactionError::AlreadyImported);
 | 
				
			||||||
@ -2226,15 +2281,15 @@ mod test {
 | 
				
			|||||||
		// given
 | 
							// given
 | 
				
			||||||
		let mut txq = TransactionQueue::default();
 | 
							let mut txq = TransactionQueue::default();
 | 
				
			||||||
		let (tx1, tx2) = new_tx_pair_default(1.into(), 0.into());
 | 
							let (tx1, tx2) = new_tx_pair_default(1.into(), 0.into());
 | 
				
			||||||
		txq.add(tx1.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx1.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		txq.add(tx2.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx2.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		assert_eq!(txq.status().pending, 2);
 | 
							assert_eq!(txq.status().pending, 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
		txq.remove_invalid(&tx1.hash(), &default_account_details);
 | 
							txq.remove_invalid(&tx1.hash(), &default_account_details);
 | 
				
			||||||
		assert_eq!(txq.status().pending, 0);
 | 
							assert_eq!(txq.status().pending, 0);
 | 
				
			||||||
		assert_eq!(txq.status().future, 1);
 | 
							assert_eq!(txq.status().future, 1);
 | 
				
			||||||
		txq.add(tx1.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx1.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// then
 | 
							// then
 | 
				
			||||||
		let stats = txq.status();
 | 
							let stats = txq.status();
 | 
				
			||||||
@ -2248,10 +2303,10 @@ mod test {
 | 
				
			|||||||
		let mut txq = TransactionQueue::default();
 | 
							let mut txq = TransactionQueue::default();
 | 
				
			||||||
		let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
 | 
							let (tx, tx2) = new_tx_pair_default(1.into(), 0.into());
 | 
				
			||||||
		let tx3 = new_tx_default();
 | 
							let tx3 = new_tx_default();
 | 
				
			||||||
		txq.add(tx2.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx2.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		assert_eq!(txq.status().future, 1);
 | 
							assert_eq!(txq.status().future, 1);
 | 
				
			||||||
		txq.add(tx3.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx3.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		txq.add(tx.clone(), TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx.clone(), TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		assert_eq!(txq.status().pending, 3);
 | 
							assert_eq!(txq.status().pending, 3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
@ -2278,8 +2333,8 @@ mod test {
 | 
				
			|||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
		txq.add(tx, TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx, TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		txq.add(tx2, TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx2, TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// then
 | 
							// then
 | 
				
			||||||
		let stats = txq.status();
 | 
							let stats = txq.status();
 | 
				
			||||||
@ -2306,10 +2361,10 @@ mod test {
 | 
				
			|||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
		txq.add(tx1, TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx1, TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		txq.add(tx2, TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx2, TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		assert_eq!(txq.status().future, 1);
 | 
							assert_eq!(txq.status().future, 1);
 | 
				
			||||||
		txq.add(tx0, TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx0, TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// then
 | 
							// then
 | 
				
			||||||
		let stats = txq.status();
 | 
							let stats = txq.status();
 | 
				
			||||||
@ -2327,8 +2382,8 @@ mod test {
 | 
				
			|||||||
			!U256::zero() };
 | 
								!U256::zero() };
 | 
				
			||||||
		let mut txq = TransactionQueue::default();
 | 
							let mut txq = TransactionQueue::default();
 | 
				
			||||||
		let (tx1, tx2) = new_tx_pair_default(1.into(), 0.into());
 | 
							let (tx1, tx2) = new_tx_pair_default(1.into(), 0.into());
 | 
				
			||||||
		txq.add(tx1.clone(), TransactionOrigin::External, &previous_nonce, &gas_estimator).unwrap();
 | 
							txq.add(tx1.clone(), TransactionOrigin::External, None, &previous_nonce, &gas_estimator).unwrap();
 | 
				
			||||||
		txq.add(tx2, TransactionOrigin::External, &previous_nonce, &gas_estimator).unwrap();
 | 
							txq.add(tx2, TransactionOrigin::External, None, &previous_nonce, &gas_estimator).unwrap();
 | 
				
			||||||
		assert_eq!(txq.status().future, 2);
 | 
							assert_eq!(txq.status().future, 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
@ -2359,7 +2414,7 @@ mod test {
 | 
				
			|||||||
		let details = |_a: &Address| AccountDetails { nonce: nonce, balance: !U256::zero() };
 | 
							let details = |_a: &Address| AccountDetails { nonce: nonce, balance: !U256::zero() };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
		txq.add(tx, TransactionOrigin::External, &details, &gas_estimator).unwrap();
 | 
							txq.add(tx, TransactionOrigin::External, None, &details, &gas_estimator).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// then
 | 
							// then
 | 
				
			||||||
		assert_eq!(txq.last_nonce(&from), Some(nonce));
 | 
							assert_eq!(txq.last_nonce(&from), Some(nonce));
 | 
				
			||||||
@ -2374,7 +2429,7 @@ mod test {
 | 
				
			|||||||
		let details1 = |_a: &Address| AccountDetails { nonce: nonce1, balance: !U256::zero() };
 | 
							let details1 = |_a: &Address| AccountDetails { nonce: nonce1, balance: !U256::zero() };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Insert first transaction
 | 
							// Insert first transaction
 | 
				
			||||||
		txq.add(tx1, TransactionOrigin::External, &details1, &gas_estimator).unwrap();
 | 
							txq.add(tx1, TransactionOrigin::External, None, &details1, &gas_estimator).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
		txq.remove_all(tx2.sender().unwrap(), nonce2 + U256::one());
 | 
							txq.remove_all(tx2.sender().unwrap(), nonce2 + U256::one());
 | 
				
			||||||
@ -2394,9 +2449,9 @@ mod test {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
		// Insert first transaction
 | 
							// Insert first transaction
 | 
				
			||||||
		assert_eq!(txq.add(tx1, TransactionOrigin::External, &details1, &gas_estimator).unwrap(), TransactionImportResult::Current);
 | 
							assert_eq!(txq.add(tx1, TransactionOrigin::External, None, &details1, &gas_estimator).unwrap(), TransactionImportResult::Current);
 | 
				
			||||||
		// Second should go to future
 | 
							// Second should go to future
 | 
				
			||||||
		assert_eq!(txq.add(tx2, TransactionOrigin::External, &details1, &gas_estimator).unwrap(), TransactionImportResult::Future);
 | 
							assert_eq!(txq.add(tx2, TransactionOrigin::External, None, &details1, &gas_estimator).unwrap(), TransactionImportResult::Future);
 | 
				
			||||||
		// Now block is imported
 | 
							// Now block is imported
 | 
				
			||||||
		txq.remove_all(sender, nonce2 - U256::from(1));
 | 
							txq.remove_all(sender, nonce2 - U256::from(1));
 | 
				
			||||||
		// tx2 should be not be promoted to current
 | 
							// tx2 should be not be promoted to current
 | 
				
			||||||
@ -2415,9 +2470,9 @@ mod test {
 | 
				
			|||||||
		assert_eq!(txq.has_local_pending_transactions(), false);
 | 
							assert_eq!(txq.has_local_pending_transactions(), false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
		assert_eq!(txq.add(tx1, TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap(), TransactionImportResult::Current);
 | 
							assert_eq!(txq.add(tx1, TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap(), TransactionImportResult::Current);
 | 
				
			||||||
		assert_eq!(txq.has_local_pending_transactions(), false);
 | 
							assert_eq!(txq.has_local_pending_transactions(), false);
 | 
				
			||||||
		assert_eq!(txq.add(tx2, TransactionOrigin::Local, &default_account_details, &gas_estimator).unwrap(), TransactionImportResult::Current);
 | 
							assert_eq!(txq.add(tx2, TransactionOrigin::Local, None, &default_account_details, &gas_estimator).unwrap(), TransactionImportResult::Current);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// then
 | 
							// then
 | 
				
			||||||
		assert_eq!(txq.has_local_pending_transactions(), true);
 | 
							assert_eq!(txq.has_local_pending_transactions(), true);
 | 
				
			||||||
@ -2432,8 +2487,8 @@ mod test {
 | 
				
			|||||||
			default_account_details(a).balance };
 | 
								default_account_details(a).balance };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
		assert_eq!(txq.add(tx2, TransactionOrigin::External, &prev_nonce, &gas_estimator).unwrap(), TransactionImportResult::Future);
 | 
							assert_eq!(txq.add(tx2, TransactionOrigin::External, None, &prev_nonce, &gas_estimator).unwrap(), TransactionImportResult::Future);
 | 
				
			||||||
		assert_eq!(txq.add(tx1.clone(), TransactionOrigin::External, &prev_nonce, &gas_estimator).unwrap(), TransactionImportResult::Future);
 | 
							assert_eq!(txq.add(tx1.clone(), TransactionOrigin::External, None, &prev_nonce, &gas_estimator).unwrap(), TransactionImportResult::Future);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// then
 | 
							// then
 | 
				
			||||||
		assert_eq!(txq.future.by_priority.len(), 1);
 | 
							assert_eq!(txq.future.by_priority.len(), 1);
 | 
				
			||||||
@ -2458,14 +2513,14 @@ mod test {
 | 
				
			|||||||
			(tx.sign(secret, None), tx2.sign(secret, None), tx2_2.sign(secret, None), tx3.sign(secret, None))
 | 
								(tx.sign(secret, None), tx2.sign(secret, None), tx2_2.sign(secret, None), tx3.sign(secret, None))
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
		let sender = tx1.sender().unwrap();
 | 
							let sender = tx1.sender().unwrap();
 | 
				
			||||||
		txq.add(tx1, TransactionOrigin::Local, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx1, TransactionOrigin::Local, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		txq.add(tx2, TransactionOrigin::Local, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx2, TransactionOrigin::Local, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		txq.add(tx3, TransactionOrigin::Local, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx3, TransactionOrigin::Local, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		assert_eq!(txq.future.by_priority.len(), 0);
 | 
							assert_eq!(txq.future.by_priority.len(), 0);
 | 
				
			||||||
		assert_eq!(txq.current.by_priority.len(), 3);
 | 
							assert_eq!(txq.current.by_priority.len(), 3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
		let res = txq.add(tx2_2, TransactionOrigin::Local, &default_account_details, &gas_estimator);
 | 
							let res = txq.add(tx2_2, TransactionOrigin::Local, None, &default_account_details, &gas_estimator);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// then
 | 
							// then
 | 
				
			||||||
		assert_eq!(txq.last_nonce(&sender).unwrap(), 125.into());
 | 
							assert_eq!(txq.last_nonce(&sender).unwrap(), 125.into());
 | 
				
			||||||
@ -2481,8 +2536,8 @@ mod test {
 | 
				
			|||||||
		let high_gas = |_: &SignedTransaction| 100_001.into();
 | 
							let high_gas = |_: &SignedTransaction| 100_001.into();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
		let res1 = txq.add(tx1, TransactionOrigin::Local, &default_account_details, &gas_estimator);
 | 
							let res1 = txq.add(tx1, TransactionOrigin::Local, None, &default_account_details, &gas_estimator);
 | 
				
			||||||
		let res2 = txq.add(tx2, TransactionOrigin::Local, &default_account_details, &high_gas);
 | 
							let res2 = txq.add(tx2, TransactionOrigin::Local, None, &default_account_details, &high_gas);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// then
 | 
							// then
 | 
				
			||||||
		assert_eq!(res1.unwrap(), TransactionImportResult::Current);
 | 
							assert_eq!(res1.unwrap(), TransactionImportResult::Current);
 | 
				
			||||||
@ -2502,10 +2557,10 @@ mod test {
 | 
				
			|||||||
		let nonce1 = tx1.nonce;
 | 
							let nonce1 = tx1.nonce;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Insert all transactions
 | 
							// Insert all transactions
 | 
				
			||||||
		txq.add(tx1, TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx1, TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		txq.add(tx2, TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx2, TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		txq.add(tx3, TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx3, TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		txq.add(tx4, TransactionOrigin::External, &default_account_details, &gas_estimator).unwrap();
 | 
							txq.add(tx4, TransactionOrigin::External, None, &default_account_details, &gas_estimator).unwrap();
 | 
				
			||||||
		assert_eq!(txq.top_transactions().len(), 4);
 | 
							assert_eq!(txq.top_transactions().len(), 4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
 | 
				
			|||||||
@ -28,6 +28,9 @@ use rlp::{Rlp, View};
 | 
				
			|||||||
use spec::Spec;
 | 
					use spec::Spec;
 | 
				
			||||||
use views::BlockView;
 | 
					use views::BlockView;
 | 
				
			||||||
use util::stats::Histogram;
 | 
					use util::stats::Histogram;
 | 
				
			||||||
 | 
					use ethkey::KeyPair;
 | 
				
			||||||
 | 
					use transaction::{PendingTransaction, Transaction, Action};
 | 
				
			||||||
 | 
					use miner::MinerService;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[test]
 | 
					#[test]
 | 
				
			||||||
fn imports_from_empty() {
 | 
					fn imports_from_empty() {
 | 
				
			||||||
@ -284,3 +287,37 @@ fn change_history_size() {
 | 
				
			|||||||
	let client = Client::new(config, &test_spec, dir.as_path(), Arc::new(Miner::with_spec(&test_spec)), IoChannel::disconnected(), &db_config).unwrap();
 | 
						let client = Client::new(config, &test_spec, dir.as_path(), Arc::new(Miner::with_spec(&test_spec)), IoChannel::disconnected(), &db_config).unwrap();
 | 
				
			||||||
	assert_eq!(client.state().balance(&address), 100.into());
 | 
						assert_eq!(client.state().balance(&address), 100.into());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[test]
 | 
				
			||||||
 | 
					fn does_not_propagate_delayed_transactions() {
 | 
				
			||||||
 | 
						let key = KeyPair::from_secret("test".sha3()).unwrap();
 | 
				
			||||||
 | 
						let secret = key.secret();
 | 
				
			||||||
 | 
						let tx0 = PendingTransaction::new(Transaction {
 | 
				
			||||||
 | 
							nonce: 0.into(),
 | 
				
			||||||
 | 
							gas_price: 0.into(),
 | 
				
			||||||
 | 
							gas: 21000.into(),
 | 
				
			||||||
 | 
							action: Action::Call(Address::default()),
 | 
				
			||||||
 | 
							value: 0.into(),
 | 
				
			||||||
 | 
							data: Vec::new(),
 | 
				
			||||||
 | 
						}.sign(secret, None), Some(2));
 | 
				
			||||||
 | 
						let tx1 = PendingTransaction::new(Transaction {
 | 
				
			||||||
 | 
							nonce: 1.into(),
 | 
				
			||||||
 | 
							gas_price: 0.into(),
 | 
				
			||||||
 | 
							gas: 21000.into(),
 | 
				
			||||||
 | 
							action: Action::Call(Address::default()),
 | 
				
			||||||
 | 
							value: 0.into(),
 | 
				
			||||||
 | 
							data: Vec::new(),
 | 
				
			||||||
 | 
						}.sign(secret, None), None);
 | 
				
			||||||
 | 
						let client_result = generate_dummy_client(1);
 | 
				
			||||||
 | 
						let client = client_result.reference();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						client.miner().import_own_transaction(&**client, tx0).unwrap();
 | 
				
			||||||
 | 
						client.miner().import_own_transaction(&**client, tx1).unwrap();
 | 
				
			||||||
 | 
						assert_eq!(0, client.ready_transactions().len());
 | 
				
			||||||
 | 
						assert_eq!(2, client.miner().pending_transactions().len());
 | 
				
			||||||
 | 
						push_blocks_to_client(client, 53, 2, 2);
 | 
				
			||||||
 | 
						client.flush_queue();
 | 
				
			||||||
 | 
						assert_eq!(2, client.ready_transactions().len());
 | 
				
			||||||
 | 
						assert_eq!(2, client.miner().pending_transactions().len());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -390,6 +390,34 @@ impl Deref for LocalizedTransaction {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Queued transaction with additional information.
 | 
				
			||||||
 | 
					#[derive(Debug, Clone, PartialEq, Eq, Binary)]
 | 
				
			||||||
 | 
					pub struct PendingTransaction {
 | 
				
			||||||
 | 
						/// Signed transaction data.
 | 
				
			||||||
 | 
						pub transaction: SignedTransaction,
 | 
				
			||||||
 | 
						/// To be activated at this block. `None` for immediately.
 | 
				
			||||||
 | 
						pub min_block: Option<BlockNumber>,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl PendingTransaction {
 | 
				
			||||||
 | 
						/// Create a new pending transaction from signed transaction.
 | 
				
			||||||
 | 
						pub fn new(signed: SignedTransaction, min_block: Option<BlockNumber>) -> Self {
 | 
				
			||||||
 | 
							PendingTransaction {
 | 
				
			||||||
 | 
								transaction: signed,
 | 
				
			||||||
 | 
								min_block: min_block,
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl From<SignedTransaction> for PendingTransaction {
 | 
				
			||||||
 | 
						fn from(t: SignedTransaction) -> Self {
 | 
				
			||||||
 | 
							PendingTransaction {
 | 
				
			||||||
 | 
								transaction: t,
 | 
				
			||||||
 | 
								min_block: None,
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[test]
 | 
					#[test]
 | 
				
			||||||
fn sender_test() {
 | 
					fn sender_test() {
 | 
				
			||||||
	let t: SignedTransaction = decode(&::rustc_serialize::hex::FromHex::from_hex("f85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804").unwrap());
 | 
						let t: SignedTransaction = decode(&::rustc_serialize::hex::FromHex::from_hex("f85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804").unwrap());
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "name": "parity.js",
 | 
					  "name": "parity.js",
 | 
				
			||||||
  "version": "0.2.127",
 | 
					  "version": "0.2.128",
 | 
				
			||||||
  "main": "release/index.js",
 | 
					  "main": "release/index.js",
 | 
				
			||||||
  "jsnext:main": "src/index.js",
 | 
					  "jsnext:main": "src/index.js",
 | 
				
			||||||
  "author": "Parity Team <admin@parity.io>",
 | 
					  "author": "Parity Team <admin@parity.io>",
 | 
				
			||||||
 | 
				
			|||||||
@ -38,7 +38,7 @@ export default class SecureApi extends Api {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  setToken = () => {
 | 
					  setToken = () => {
 | 
				
			||||||
    window.localStorage.setItem('sysuiToken', this._transport.token);
 | 
					    window.localStorage.setItem('sysuiToken', this._transport.token);
 | 
				
			||||||
    console.log('SecureApi:setToken', this._transport.token);
 | 
					    // DEBUG: console.log('SecureApi:setToken', this._transport.token);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _checkNodeUp () {
 | 
					  _checkNodeUp () {
 | 
				
			||||||
@ -149,14 +149,14 @@ export default class SecureApi extends Api {
 | 
				
			|||||||
        this._signerPort = signerPort.toNumber();
 | 
					        this._signerPort = signerPort.toNumber();
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    console.log('SecureApi:connectSuccess', this._transport.token);
 | 
					    // DEBUG: console.log('SecureApi:connectSuccess', this._transport.token);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  updateToken (token, connectState = 0) {
 | 
					  updateToken (token, connectState = 0) {
 | 
				
			||||||
    this._connectState = connectState;
 | 
					    this._connectState = connectState;
 | 
				
			||||||
    this._transport.updateToken(token.replace(/[^a-zA-Z0-9]/g, ''));
 | 
					    this._transport.updateToken(token.replace(/[^a-zA-Z0-9]/g, ''));
 | 
				
			||||||
    this._followConnection();
 | 
					    this._followConnection();
 | 
				
			||||||
    console.log('SecureApi:updateToken', this._transport.token, connectState);
 | 
					    // DEBUG: console.log('SecureApi:updateToken', this._transport.token, connectState);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  get dappsPort () {
 | 
					  get dappsPort () {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"><dict><key>CFBundlePackageType</key><string>APPL</string><key>CFBundleInfoDictionaryVersion</key><string>6.0</string>
 | 
					<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"><dict><key>CFBundleIconFiles</key><string>Parity.png</string><key>CFBundlePackageType</key><string>APPL</string><key>CFBundleInfoDictionaryVersion</key><string>6.0</string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <key>CFBundleName</key>                      <string>Parity Ethereum</string>
 | 
					    <key>CFBundleName</key>                      <string>Parity Ethereum</string>
 | 
				
			||||||
    <key>CFBundleExecutable</key>                <string>go.sh</string>
 | 
					    <key>CFBundleExecutable</key>                <string>go.sh</string>
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										
											BIN
										
									
								
								mac/Parity Ethereum.app/Contents/Parity.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								mac/Parity Ethereum.app/Contents/Parity.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 106 KiB  | 
@ -145,7 +145,7 @@ macro_rules! usage {
 | 
				
			|||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				let config_file = raw_args.flag_config.clone().unwrap_or_else(|| raw_args.clone().into_args(Config::default()).flag_config);
 | 
									let config_file = raw_args.flag_config.clone().unwrap_or_else(|| raw_args.clone().into_args(Config::default()).flag_config);
 | 
				
			||||||
				let config_file = replace_home("", &config_file);
 | 
									let config_file = replace_home(&::dir::default_data_path(), &config_file);
 | 
				
			||||||
				let config = match (fs::File::open(&config_file), raw_args.flag_config.is_some()) {
 | 
									let config = match (fs::File::open(&config_file), raw_args.flag_config.is_some()) {
 | 
				
			||||||
					// Load config file
 | 
										// Load config file
 | 
				
			||||||
					(Ok(mut file), _) => {
 | 
										(Ok(mut file), _) => {
 | 
				
			||||||
 | 
				
			|||||||
@ -21,6 +21,16 @@ use util::journaldb::Algorithm;
 | 
				
			|||||||
use helpers::replace_home;
 | 
					use helpers::replace_home;
 | 
				
			||||||
use app_dirs::{AppInfo, get_app_root, AppDataType};
 | 
					use app_dirs::{AppInfo, get_app_root, AppDataType};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[cfg(target_os = "macos")] const AUTHOR: &'static str = "Parity";
 | 
				
			||||||
 | 
					#[cfg(target_os = "macos")] const PRODUCT: &'static str = "io.parity.ethereum";
 | 
				
			||||||
 | 
					#[cfg(target_os = "macos")] const PRODUCT_HYPERVISOR: &'static str = "io.parity.ethereum-updates";
 | 
				
			||||||
 | 
					#[cfg(target_os = "windows")] const AUTHOR: &'static str = "Parity";
 | 
				
			||||||
 | 
					#[cfg(target_os = "windows")] const PRODUCT: &'static str = "Ethereum";
 | 
				
			||||||
 | 
					#[cfg(target_os = "windows")] const PRODUCT_HYPERVISOR: &'static str = "EthereumUpdates";
 | 
				
			||||||
 | 
					#[cfg(not(any(target_os = "windows", target_os = "macos")))] const AUTHOR: &'static str = "parity";
 | 
				
			||||||
 | 
					#[cfg(not(any(target_os = "windows", target_os = "macos")))] const PRODUCT: &'static str = "io.parity.ethereum";
 | 
				
			||||||
 | 
					#[cfg(not(any(target_os = "windows", target_os = "macos")))] const PRODUCT_HYPERVISOR: &'static str = "io.parity.ethereum-updates";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// this const is irrelevent cause we do have migrations now,
 | 
					// this const is irrelevent cause we do have migrations now,
 | 
				
			||||||
// but we still use it for backwards compatibility
 | 
					// but we still use it for backwards compatibility
 | 
				
			||||||
const LEGACY_CLIENT_DB_VER_STR: &'static str = "5.3";
 | 
					const LEGACY_CLIENT_DB_VER_STR: &'static str = "5.3";
 | 
				
			||||||
@ -195,12 +205,12 @@ impl DatabaseDirectories {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn default_data_path() -> String {
 | 
					pub fn default_data_path() -> String {
 | 
				
			||||||
	let app_info = AppInfo { name: "parity", author: "parity" };
 | 
						let app_info = AppInfo { name: PRODUCT, author: AUTHOR };
 | 
				
			||||||
	get_app_root(AppDataType::UserData, &app_info).map(|p| p.to_string_lossy().into_owned()).unwrap_or_else(|_| "$HOME/.parity".to_owned())
 | 
						get_app_root(AppDataType::UserData, &app_info).map(|p| p.to_string_lossy().into_owned()).unwrap_or_else(|_| "$HOME/.parity".to_owned())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn default_hypervisor_path() -> String {
 | 
					pub fn default_hypervisor_path() -> String {
 | 
				
			||||||
	let app_info = AppInfo { name: "parity-hypervisor", author: "parity" };
 | 
						let app_info = AppInfo { name: PRODUCT_HYPERVISOR, author: AUTHOR };
 | 
				
			||||||
	get_app_root(AppDataType::UserData, &app_info).map(|p| p.to_string_lossy().into_owned()).unwrap_or_else(|_| "$HOME/.parity-hypervisor".to_owned())
 | 
						get_app_root(AppDataType::UserData, &app_info).map(|p| p.to_string_lossy().into_owned()).unwrap_or_else(|_| "$HOME/.parity-hypervisor".to_owned())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -72,7 +72,7 @@ pub fn start(conf: Configuration, deps: Dependencies) -> Result<Option<SignerSer
 | 
				
			|||||||
fn codes_path(path: String) -> PathBuf {
 | 
					fn codes_path(path: String) -> PathBuf {
 | 
				
			||||||
	let mut p = PathBuf::from(path);
 | 
						let mut p = PathBuf::from(path);
 | 
				
			||||||
	p.push(CODES_FILENAME);
 | 
						p.push(CODES_FILENAME);
 | 
				
			||||||
	let _ = restrict_permissions_owner(&p);
 | 
						let _ = restrict_permissions_owner(&p, true, false);
 | 
				
			||||||
	p
 | 
						p
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -23,7 +23,7 @@ use util::bytes::ToPretty;
 | 
				
			|||||||
use ethkey::Signature;
 | 
					use ethkey::Signature;
 | 
				
			||||||
use ethcore::miner::MinerService;
 | 
					use ethcore::miner::MinerService;
 | 
				
			||||||
use ethcore::client::MiningBlockChainClient;
 | 
					use ethcore::client::MiningBlockChainClient;
 | 
				
			||||||
use ethcore::transaction::{Action, SignedTransaction, Transaction};
 | 
					use ethcore::transaction::{Action, SignedTransaction, PendingTransaction, Transaction};
 | 
				
			||||||
use ethcore::account_provider::AccountProvider;
 | 
					use ethcore::account_provider::AccountProvider;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use jsonrpc_core::Error;
 | 
					use jsonrpc_core::Error;
 | 
				
			||||||
@ -147,9 +147,9 @@ fn decrypt(accounts: &AccountProvider, address: Address, msg: Bytes, password: S
 | 
				
			|||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn dispatch_transaction<C, M>(client: &C, miner: &M, signed_transaction: SignedTransaction) -> Result<H256, Error>
 | 
					pub fn dispatch_transaction<C, M>(client: &C, miner: &M, signed_transaction: PendingTransaction) -> Result<H256, Error>
 | 
				
			||||||
	where C: MiningBlockChainClient, M: MinerService {
 | 
						where C: MiningBlockChainClient, M: MinerService {
 | 
				
			||||||
	let hash = signed_transaction.hash();
 | 
						let hash = signed_transaction.transaction.hash();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	miner.import_own_transaction(client, signed_transaction)
 | 
						miner.import_own_transaction(client, signed_transaction)
 | 
				
			||||||
		.map_err(errors::from_transaction_error)
 | 
							.map_err(errors::from_transaction_error)
 | 
				
			||||||
@ -190,6 +190,7 @@ pub fn sign_and_dispatch<C, M>(client: &C, miner: &M, accounts: &AccountProvider
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let network_id = client.signing_network_id();
 | 
						let network_id = client.signing_network_id();
 | 
				
			||||||
 | 
						let min_block = filled.min_block.clone();
 | 
				
			||||||
	let signed_transaction = try!(sign_no_dispatch(client, miner, accounts, filled, password));
 | 
						let signed_transaction = try!(sign_no_dispatch(client, miner, accounts, filled, password));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let (signed_transaction, token) = match signed_transaction {
 | 
						let (signed_transaction, token) = match signed_transaction {
 | 
				
			||||||
@ -198,7 +199,8 @@ pub fn sign_and_dispatch<C, M>(client: &C, miner: &M, accounts: &AccountProvider
 | 
				
			|||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	trace!(target: "miner", "send_transaction: dispatching tx: {} for network ID {:?}", rlp::encode(&signed_transaction).to_vec().pretty(), network_id);
 | 
						trace!(target: "miner", "send_transaction: dispatching tx: {} for network ID {:?}", rlp::encode(&signed_transaction).to_vec().pretty(), network_id);
 | 
				
			||||||
	dispatch_transaction(&*client, &*miner, signed_transaction).map(|hash| {
 | 
						let pending_transaction = PendingTransaction::new(signed_transaction, min_block);
 | 
				
			||||||
 | 
						dispatch_transaction(&*client, &*miner, pending_transaction).map(|hash| {
 | 
				
			||||||
		match token {
 | 
							match token {
 | 
				
			||||||
			Some(ref token) => WithToken::Yes(hash, token.clone()),
 | 
								Some(ref token) => WithToken::Yes(hash, token.clone()),
 | 
				
			||||||
			None => WithToken::No(hash),
 | 
								None => WithToken::No(hash),
 | 
				
			||||||
@ -217,6 +219,7 @@ pub fn fill_optional_fields<C, M>(request: TransactionRequest, client: &C, miner
 | 
				
			|||||||
		gas: request.gas.unwrap_or_else(|| miner.sensible_gas_limit()),
 | 
							gas: request.gas.unwrap_or_else(|| miner.sensible_gas_limit()),
 | 
				
			||||||
		value: request.value.unwrap_or_else(|| 0.into()),
 | 
							value: request.value.unwrap_or_else(|| 0.into()),
 | 
				
			||||||
		data: request.data.unwrap_or_else(Vec::new),
 | 
							data: request.data.unwrap_or_else(Vec::new),
 | 
				
			||||||
 | 
							min_block: request.min_block,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -33,6 +33,8 @@ pub struct TransactionRequest {
 | 
				
			|||||||
	pub data: Option<Bytes>,
 | 
						pub data: Option<Bytes>,
 | 
				
			||||||
	/// Transaction's nonce
 | 
						/// Transaction's nonce
 | 
				
			||||||
	pub nonce: Option<U256>,
 | 
						pub nonce: Option<U256>,
 | 
				
			||||||
 | 
						/// Delay until this block if specified.
 | 
				
			||||||
 | 
						pub min_block: Option<u64>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Transaction request coming from RPC with default values filled in.
 | 
					/// Transaction request coming from RPC with default values filled in.
 | 
				
			||||||
@ -52,6 +54,8 @@ pub struct FilledTransactionRequest {
 | 
				
			|||||||
	pub data: Bytes,
 | 
						pub data: Bytes,
 | 
				
			||||||
	/// Transaction's nonce
 | 
						/// Transaction's nonce
 | 
				
			||||||
	pub nonce: Option<U256>,
 | 
						pub nonce: Option<U256>,
 | 
				
			||||||
 | 
						/// Delay until this block if specified.
 | 
				
			||||||
 | 
						pub min_block: Option<u64>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl From<FilledTransactionRequest> for TransactionRequest {
 | 
					impl From<FilledTransactionRequest> for TransactionRequest {
 | 
				
			||||||
@ -64,6 +68,7 @@ impl From<FilledTransactionRequest> for TransactionRequest {
 | 
				
			|||||||
			value: Some(r.value),
 | 
								value: Some(r.value),
 | 
				
			||||||
			data: Some(r.data),
 | 
								data: Some(r.data),
 | 
				
			||||||
			nonce: r.nonce,
 | 
								nonce: r.nonce,
 | 
				
			||||||
 | 
								min_block: r.min_block,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -328,6 +328,7 @@ mod test {
 | 
				
			|||||||
			value: 10_000_000.into(),
 | 
								value: 10_000_000.into(),
 | 
				
			||||||
			data: vec![],
 | 
								data: vec![],
 | 
				
			||||||
			nonce: None,
 | 
								nonce: None,
 | 
				
			||||||
 | 
								min_block: None,
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -38,7 +38,7 @@ use ethcore::header::{Header as BlockHeader, BlockNumber as EthBlockNumber};
 | 
				
			|||||||
use ethcore::block::IsBlock;
 | 
					use ethcore::block::IsBlock;
 | 
				
			||||||
use ethcore::views::*;
 | 
					use ethcore::views::*;
 | 
				
			||||||
use ethcore::ethereum::Ethash;
 | 
					use ethcore::ethereum::Ethash;
 | 
				
			||||||
use ethcore::transaction::{Transaction as EthTransaction, SignedTransaction, Action};
 | 
					use ethcore::transaction::{Transaction as EthTransaction, SignedTransaction, PendingTransaction, Action};
 | 
				
			||||||
use ethcore::log_entry::LogEntry;
 | 
					use ethcore::log_entry::LogEntry;
 | 
				
			||||||
use ethcore::filter::Filter as EthcoreFilter;
 | 
					use ethcore::filter::Filter as EthcoreFilter;
 | 
				
			||||||
use ethcore::snapshot::SnapshotService;
 | 
					use ethcore::snapshot::SnapshotService;
 | 
				
			||||||
@ -617,7 +617,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		let raw_transaction = raw.to_vec();
 | 
							let raw_transaction = raw.to_vec();
 | 
				
			||||||
		match UntrustedRlp::new(&raw_transaction).as_val() {
 | 
							match UntrustedRlp::new(&raw_transaction).as_val() {
 | 
				
			||||||
			Ok(signed_transaction) => dispatch_transaction(&*take_weak!(self.client), &*take_weak!(self.miner), signed_transaction).map(Into::into),
 | 
								Ok(signed_transaction) => dispatch_transaction(&*take_weak!(self.client), &*take_weak!(self.miner), PendingTransaction::new(signed_transaction, None)).map(Into::into),
 | 
				
			||||||
			Err(e) => Err(errors::from_rlp_error(e)),
 | 
								Err(e) => Err(errors::from_rlp_error(e)),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
@ -270,7 +270,13 @@ impl<C, M, S: ?Sized, U> Parity for ParityClient<C, M, S, U> where
 | 
				
			|||||||
	fn pending_transactions(&self) -> Result<Vec<Transaction>, Error> {
 | 
						fn pending_transactions(&self) -> Result<Vec<Transaction>, Error> {
 | 
				
			||||||
		try!(self.active());
 | 
							try!(self.active());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Ok(take_weak!(self.miner).all_transactions().into_iter().map(Into::into).collect::<Vec<_>>())
 | 
							Ok(take_weak!(self.miner).pending_transactions().into_iter().map(Into::into).collect::<Vec<_>>())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fn future_transactions(&self) -> Result<Vec<Transaction>, Error> {
 | 
				
			||||||
 | 
							try!(self.active());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Ok(take_weak!(self.miner).future_transactions().into_iter().map(Into::into).collect::<Vec<_>>())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn pending_transactions_stats(&self) -> Result<BTreeMap<H256, TransactionStats>, Error> {
 | 
						fn pending_transactions_stats(&self) -> Result<BTreeMap<H256, TransactionStats>, Error> {
 | 
				
			||||||
 | 
				
			|||||||
@ -21,7 +21,7 @@ use std::sync::{Arc, Weak};
 | 
				
			|||||||
use rlp::{UntrustedRlp, View};
 | 
					use rlp::{UntrustedRlp, View};
 | 
				
			||||||
use ethcore::account_provider::AccountProvider;
 | 
					use ethcore::account_provider::AccountProvider;
 | 
				
			||||||
use ethcore::client::MiningBlockChainClient;
 | 
					use ethcore::client::MiningBlockChainClient;
 | 
				
			||||||
use ethcore::transaction::SignedTransaction;
 | 
					use ethcore::transaction::{SignedTransaction, PendingTransaction};
 | 
				
			||||||
use ethcore::miner::MinerService;
 | 
					use ethcore::miner::MinerService;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use jsonrpc_core::Error;
 | 
					use jsonrpc_core::Error;
 | 
				
			||||||
@ -82,6 +82,9 @@ impl<C: 'static, M: 'static> SignerClient<C, M> where C: MiningBlockChainClient,
 | 
				
			|||||||
				if let Some(gas) = modification.gas {
 | 
									if let Some(gas) = modification.gas {
 | 
				
			||||||
					request.gas = gas.into();
 | 
										request.gas = gas.into();
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
									if let Some(ref min_block) = modification.min_block {
 | 
				
			||||||
 | 
										request.min_block = min_block.as_ref().and_then(|b| b.to_min_block_num());
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			let result = f(&*client, &*miner, &*accounts, payload);
 | 
								let result = f(&*client, &*miner, &*accounts, payload);
 | 
				
			||||||
			// Execute
 | 
								// Execute
 | 
				
			||||||
@ -155,7 +158,8 @@ impl<C: 'static, M: 'static> Signer for SignerClient<C, M> where C: MiningBlockC
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
					// Dispatch if everything is ok
 | 
										// Dispatch if everything is ok
 | 
				
			||||||
					if sender_matches && data_matches && value_matches && nonce_matches {
 | 
										if sender_matches && data_matches && value_matches && nonce_matches {
 | 
				
			||||||
						dispatch_transaction(&*client, &*miner, signed_transaction)
 | 
											let pending_transaction = PendingTransaction::new(signed_transaction, request.min_block);
 | 
				
			||||||
 | 
											dispatch_transaction(&*client, &*miner, pending_transaction)
 | 
				
			||||||
							.map(Into::into)
 | 
												.map(Into::into)
 | 
				
			||||||
							.map(ConfirmationResponse::SendTransaction)
 | 
												.map(ConfirmationResponse::SendTransaction)
 | 
				
			||||||
					} else {
 | 
										} else {
 | 
				
			||||||
 | 
				
			|||||||
@ -22,7 +22,7 @@ use ethcore::error::{Error, CallError};
 | 
				
			|||||||
use ethcore::client::{MiningBlockChainClient, Executed, CallAnalytics};
 | 
					use ethcore::client::{MiningBlockChainClient, Executed, CallAnalytics};
 | 
				
			||||||
use ethcore::block::{ClosedBlock, IsBlock};
 | 
					use ethcore::block::{ClosedBlock, IsBlock};
 | 
				
			||||||
use ethcore::header::BlockNumber;
 | 
					use ethcore::header::BlockNumber;
 | 
				
			||||||
use ethcore::transaction::SignedTransaction;
 | 
					use ethcore::transaction::{SignedTransaction, PendingTransaction};
 | 
				
			||||||
use ethcore::receipt::{Receipt, RichReceipt};
 | 
					use ethcore::receipt::{Receipt, RichReceipt};
 | 
				
			||||||
use ethcore::miner::{MinerService, MinerStatus, TransactionImportResult, LocalTransactionStatus};
 | 
					use ethcore::miner::{MinerService, MinerStatus, TransactionImportResult, LocalTransactionStatus};
 | 
				
			||||||
use ethcore::account_provider::Error as AccountError;
 | 
					use ethcore::account_provider::Error as AccountError;
 | 
				
			||||||
@ -160,17 +160,17 @@ impl MinerService for TestMinerService {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// Imports transactions to transaction queue.
 | 
						/// Imports transactions to transaction queue.
 | 
				
			||||||
	fn import_own_transaction(&self, chain: &MiningBlockChainClient, transaction: SignedTransaction) ->
 | 
						fn import_own_transaction(&self, chain: &MiningBlockChainClient, pending: PendingTransaction) ->
 | 
				
			||||||
		Result<TransactionImportResult, Error> {
 | 
							Result<TransactionImportResult, Error> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// keep the pending nonces up to date
 | 
							// keep the pending nonces up to date
 | 
				
			||||||
		if let Ok(ref sender) = transaction.sender() {
 | 
							if let Ok(ref sender) = pending.transaction.sender() {
 | 
				
			||||||
			let nonce = self.last_nonce(sender).unwrap_or(chain.latest_nonce(sender));
 | 
								let nonce = self.last_nonce(sender).unwrap_or(chain.latest_nonce(sender));
 | 
				
			||||||
			self.last_nonces.write().insert(sender.clone(), nonce + U256::from(1));
 | 
								self.last_nonces.write().insert(sender.clone(), nonce + U256::from(1));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// lets assume that all txs are valid
 | 
							// lets assume that all txs are valid
 | 
				
			||||||
		self.imported_transactions.lock().push(transaction);
 | 
							self.imported_transactions.lock().push(pending.transaction);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Ok(TransactionImportResult::Current)
 | 
							Ok(TransactionImportResult::Current)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -204,16 +204,20 @@ impl MinerService for TestMinerService {
 | 
				
			|||||||
		self.pending_transactions.lock().get(hash).cloned()
 | 
							self.pending_transactions.lock().get(hash).cloned()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn all_transactions(&self) -> Vec<SignedTransaction> {
 | 
						fn pending_transactions(&self) -> Vec<PendingTransaction> {
 | 
				
			||||||
		self.pending_transactions.lock().values().cloned().collect()
 | 
							self.pending_transactions.lock().values().cloned().map(Into::into).collect()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn local_transactions(&self) -> BTreeMap<H256, LocalTransactionStatus> {
 | 
						fn local_transactions(&self) -> BTreeMap<H256, LocalTransactionStatus> {
 | 
				
			||||||
		self.local_transactions.lock().iter().map(|(hash, stats)| (*hash, stats.clone())).collect()
 | 
							self.local_transactions.lock().iter().map(|(hash, stats)| (*hash, stats.clone())).collect()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn pending_transactions(&self, _best_block: BlockNumber) -> Vec<SignedTransaction> {
 | 
						fn ready_transactions(&self, _best_block: BlockNumber) -> Vec<PendingTransaction> {
 | 
				
			||||||
		self.pending_transactions.lock().values().cloned().collect()
 | 
							self.pending_transactions.lock().values().cloned().map(Into::into).collect()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fn future_transactions(&self) -> Vec<PendingTransaction> {
 | 
				
			||||||
 | 
							vec![]
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fn pending_receipt(&self, _best_block: BlockNumber, hash: &H256) -> Option<RichReceipt> {
 | 
						fn pending_receipt(&self, _best_block: BlockNumber, hash: &H256) -> Option<RichReceipt> {
 | 
				
			||||||
 | 
				
			|||||||
@ -501,7 +501,7 @@ fn rpc_eth_pending_transaction_by_hash() {
 | 
				
			|||||||
		tester.miner.pending_transactions.lock().insert(H256::zero(), tx);
 | 
							tester.miner.pending_transactions.lock().insert(H256::zero(), tx);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let response = r#"{"jsonrpc":"2.0","result":{"blockHash":null,"blockNumber":null,"creates":null,"from":"0x0f65fe9276bc9a24ae7083ae28e2660ef72df99e","gas":"0x5208","gasPrice":"0x1","hash":"0x41df922fd0d4766fcc02e161f8295ec28522f329ae487f14d811e4b64c8d6e31","input":"0x","networkId":null,"nonce":"0x0","publicKey":"0x7ae46da747962c2ee46825839c1ef9298e3bd2e70ca2938495c3693a485ec3eaa8f196327881090ff64cf4fbb0a48485d4f83098e189ed3b7a87d5941b59f789","r":"0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353","raw":"0xf85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804","s":"0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804","standardV":"0x0","to":"0x095e7baea6a6c7c4c2dfeb977efac326af552d87","transactionIndex":null,"v":"0x1b","value":"0xa"},"id":1}"#;
 | 
						let response = r#"{"jsonrpc":"2.0","result":{"blockHash":null,"blockNumber":null,"creates":null,"from":"0x0f65fe9276bc9a24ae7083ae28e2660ef72df99e","gas":"0x5208","gasPrice":"0x1","hash":"0x41df922fd0d4766fcc02e161f8295ec28522f329ae487f14d811e4b64c8d6e31","input":"0x","minBlock":null,"networkId":null,"nonce":"0x0","publicKey":"0x7ae46da747962c2ee46825839c1ef9298e3bd2e70ca2938495c3693a485ec3eaa8f196327881090ff64cf4fbb0a48485d4f83098e189ed3b7a87d5941b59f789","r":"0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353","raw":"0xf85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804","s":"0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804","standardV":"0x0","to":"0x095e7baea6a6c7c4c2dfeb977efac326af552d87","transactionIndex":null,"v":"0x1b","value":"0xa"},"id":1}"#;
 | 
				
			||||||
	let request = r#"{
 | 
						let request = r#"{
 | 
				
			||||||
		"jsonrpc": "2.0",
 | 
							"jsonrpc": "2.0",
 | 
				
			||||||
		"method": "eth_getTransactionByHash",
 | 
							"method": "eth_getTransactionByHash",
 | 
				
			||||||
@ -817,6 +817,7 @@ fn rpc_eth_sign_transaction() {
 | 
				
			|||||||
		r#""gas":"0x76c0","gasPrice":"0x9184e72a000","# +
 | 
							r#""gas":"0x76c0","gasPrice":"0x9184e72a000","# +
 | 
				
			||||||
		&format!("\"hash\":\"0x{:?}\",", t.hash()) +
 | 
							&format!("\"hash\":\"0x{:?}\",", t.hash()) +
 | 
				
			||||||
		r#""input":"0x","# +
 | 
							r#""input":"0x","# +
 | 
				
			||||||
 | 
							r#""minBlock":null,"# +
 | 
				
			||||||
		&format!("\"networkId\":{},", t.network_id().map_or("null".to_owned(), |n| format!("{}", n))) +
 | 
							&format!("\"networkId\":{},", t.network_id().map_or("null".to_owned(), |n| format!("{}", n))) +
 | 
				
			||||||
		r#""nonce":"0x1","# +
 | 
							r#""nonce":"0x1","# +
 | 
				
			||||||
		&format!("\"publicKey\":\"0x{:?}\",", t.public_key().unwrap()) +
 | 
							&format!("\"publicKey\":\"0x{:?}\",", t.public_key().unwrap()) +
 | 
				
			||||||
 | 
				
			|||||||
@ -82,6 +82,7 @@ fn should_return_list_of_items_to_confirm() {
 | 
				
			|||||||
		value: U256::from(1),
 | 
							value: U256::from(1),
 | 
				
			||||||
		data: vec![],
 | 
							data: vec![],
 | 
				
			||||||
		nonce: None,
 | 
							nonce: None,
 | 
				
			||||||
 | 
							min_block: None,
 | 
				
			||||||
	})).unwrap();
 | 
						})).unwrap();
 | 
				
			||||||
	tester.signer.add_request(ConfirmationPayload::Signature(1.into(), 5.into())).unwrap();
 | 
						tester.signer.add_request(ConfirmationPayload::Signature(1.into(), 5.into())).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -89,7 +90,7 @@ fn should_return_list_of_items_to_confirm() {
 | 
				
			|||||||
	let request = r#"{"jsonrpc":"2.0","method":"signer_requestsToConfirm","params":[],"id":1}"#;
 | 
						let request = r#"{"jsonrpc":"2.0","method":"signer_requestsToConfirm","params":[],"id":1}"#;
 | 
				
			||||||
	let response = concat!(
 | 
						let response = concat!(
 | 
				
			||||||
		r#"{"jsonrpc":"2.0","result":["#,
 | 
							r#"{"jsonrpc":"2.0","result":["#,
 | 
				
			||||||
		r#"{"id":"0x1","payload":{"sendTransaction":{"data":"0x","from":"0x0000000000000000000000000000000000000001","gas":"0x989680","gasPrice":"0x2710","nonce":null,"to":"0xd46e8dd67c5d32be8058bb8eb970870f07244567","value":"0x1"}}},"#,
 | 
							r#"{"id":"0x1","payload":{"sendTransaction":{"data":"0x","from":"0x0000000000000000000000000000000000000001","gas":"0x989680","gasPrice":"0x2710","minBlock":null,"nonce":null,"to":"0xd46e8dd67c5d32be8058bb8eb970870f07244567","value":"0x1"}}},"#,
 | 
				
			||||||
		r#"{"id":"0x2","payload":{"sign":{"address":"0x0000000000000000000000000000000000000001","hash":"0x0000000000000000000000000000000000000000000000000000000000000005"}}}"#,
 | 
							r#"{"id":"0x2","payload":{"sign":{"address":"0x0000000000000000000000000000000000000001","hash":"0x0000000000000000000000000000000000000000000000000000000000000005"}}}"#,
 | 
				
			||||||
		r#"],"id":1}"#
 | 
							r#"],"id":1}"#
 | 
				
			||||||
	);
 | 
						);
 | 
				
			||||||
@ -111,6 +112,7 @@ fn should_reject_transaction_from_queue_without_dispatching() {
 | 
				
			|||||||
		value: U256::from(1),
 | 
							value: U256::from(1),
 | 
				
			||||||
		data: vec![],
 | 
							data: vec![],
 | 
				
			||||||
		nonce: None,
 | 
							nonce: None,
 | 
				
			||||||
 | 
							min_block: None,
 | 
				
			||||||
	})).unwrap();
 | 
						})).unwrap();
 | 
				
			||||||
	assert_eq!(tester.signer.requests().len(), 1);
 | 
						assert_eq!(tester.signer.requests().len(), 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -136,6 +138,7 @@ fn should_not_remove_transaction_if_password_is_invalid() {
 | 
				
			|||||||
		value: U256::from(1),
 | 
							value: U256::from(1),
 | 
				
			||||||
		data: vec![],
 | 
							data: vec![],
 | 
				
			||||||
		nonce: None,
 | 
							nonce: None,
 | 
				
			||||||
 | 
							min_block: None,
 | 
				
			||||||
	})).unwrap();
 | 
						})).unwrap();
 | 
				
			||||||
	assert_eq!(tester.signer.requests().len(), 1);
 | 
						assert_eq!(tester.signer.requests().len(), 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -178,6 +181,7 @@ fn should_confirm_transaction_and_dispatch() {
 | 
				
			|||||||
		value: U256::from(1),
 | 
							value: U256::from(1),
 | 
				
			||||||
		data: vec![],
 | 
							data: vec![],
 | 
				
			||||||
		nonce: None,
 | 
							nonce: None,
 | 
				
			||||||
 | 
							min_block: None,
 | 
				
			||||||
	})).unwrap();
 | 
						})).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let t = Transaction {
 | 
						let t = Transaction {
 | 
				
			||||||
@ -223,6 +227,7 @@ fn should_confirm_transaction_with_token() {
 | 
				
			|||||||
		value: U256::from(1),
 | 
							value: U256::from(1),
 | 
				
			||||||
		data: vec![],
 | 
							data: vec![],
 | 
				
			||||||
		nonce: None,
 | 
							nonce: None,
 | 
				
			||||||
 | 
							min_block: None,
 | 
				
			||||||
	})).unwrap();
 | 
						})).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let t = Transaction {
 | 
						let t = Transaction {
 | 
				
			||||||
@ -270,6 +275,7 @@ fn should_confirm_transaction_with_rlp() {
 | 
				
			|||||||
		value: U256::from(1),
 | 
							value: U256::from(1),
 | 
				
			||||||
		data: vec![],
 | 
							data: vec![],
 | 
				
			||||||
		nonce: None,
 | 
							nonce: None,
 | 
				
			||||||
 | 
							min_block: None,
 | 
				
			||||||
	})).unwrap();
 | 
						})).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let t = Transaction {
 | 
						let t = Transaction {
 | 
				
			||||||
@ -317,6 +323,7 @@ fn should_return_error_when_sender_does_not_match() {
 | 
				
			|||||||
		value: U256::from(1),
 | 
							value: U256::from(1),
 | 
				
			||||||
		data: vec![],
 | 
							data: vec![],
 | 
				
			||||||
		nonce: None,
 | 
							nonce: None,
 | 
				
			||||||
 | 
							min_block: None,
 | 
				
			||||||
	})).unwrap();
 | 
						})).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	let t = Transaction {
 | 
						let t = Transaction {
 | 
				
			||||||
 | 
				
			|||||||
@ -285,6 +285,7 @@ fn should_add_sign_transaction_to_the_queue() {
 | 
				
			|||||||
		r#""gas":"0x76c0","gasPrice":"0x9184e72a000","# +
 | 
							r#""gas":"0x76c0","gasPrice":"0x9184e72a000","# +
 | 
				
			||||||
		&format!("\"hash\":\"0x{:?}\",", t.hash()) +
 | 
							&format!("\"hash\":\"0x{:?}\",", t.hash()) +
 | 
				
			||||||
		r#""input":"0x","# +
 | 
							r#""input":"0x","# +
 | 
				
			||||||
 | 
							r#""minBlock":null,"# +
 | 
				
			||||||
		&format!("\"networkId\":{},", t.network_id().map_or("null".to_owned(), |n| format!("{}", n))) +
 | 
							&format!("\"networkId\":{},", t.network_id().map_or("null".to_owned(), |n| format!("{}", n))) +
 | 
				
			||||||
		r#""nonce":"0x1","# +
 | 
							r#""nonce":"0x1","# +
 | 
				
			||||||
		&format!("\"publicKey\":\"0x{:?}\",", t.public_key().unwrap()) +
 | 
							&format!("\"publicKey\":\"0x{:?}\",", t.public_key().unwrap()) +
 | 
				
			||||||
 | 
				
			|||||||
@ -123,6 +123,10 @@ build_rpc_trait! {
 | 
				
			|||||||
		#[rpc(name = "parity_pendingTransactions")]
 | 
							#[rpc(name = "parity_pendingTransactions")]
 | 
				
			||||||
		fn pending_transactions(&self) -> Result<Vec<Transaction>, Error>;
 | 
							fn pending_transactions(&self) -> Result<Vec<Transaction>, Error>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// Returns all future transactions from transaction queue.
 | 
				
			||||||
 | 
							#[rpc(name = "parity_futureTransactions")]
 | 
				
			||||||
 | 
							fn future_transactions(&self) -> Result<Vec<Transaction>, Error>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// Returns propagation statistics on transactions pending in the queue.
 | 
							/// Returns propagation statistics on transactions pending in the queue.
 | 
				
			||||||
		#[rpc(name = "parity_pendingTransactionsStats")]
 | 
							#[rpc(name = "parity_pendingTransactionsStats")]
 | 
				
			||||||
		fn pending_transactions_stats(&self) -> Result<BTreeMap<H256, TransactionStats>, Error>;
 | 
							fn pending_transactions_stats(&self) -> Result<BTreeMap<H256, TransactionStats>, Error>;
 | 
				
			||||||
 | 
				
			|||||||
@ -139,7 +139,7 @@ mod tests {
 | 
				
			|||||||
	fn test_serialize_block_transactions() {
 | 
						fn test_serialize_block_transactions() {
 | 
				
			||||||
		let t = BlockTransactions::Full(vec![Transaction::default()]);
 | 
							let t = BlockTransactions::Full(vec![Transaction::default()]);
 | 
				
			||||||
		let serialized = serde_json::to_string(&t).unwrap();
 | 
							let serialized = serde_json::to_string(&t).unwrap();
 | 
				
			||||||
		assert_eq!(serialized, r#"[{"hash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0","blockHash":null,"blockNumber":null,"transactionIndex":null,"from":"0x0000000000000000000000000000000000000000","to":null,"value":"0x0","gasPrice":"0x0","gas":"0x0","input":"0x","creates":null,"raw":"0x","publicKey":null,"networkId":null,"standardV":"0x0","v":"0x0","r":"0x0","s":"0x0"}]"#);
 | 
							assert_eq!(serialized, r#"[{"hash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0","blockHash":null,"blockNumber":null,"transactionIndex":null,"from":"0x0000000000000000000000000000000000000000","to":null,"value":"0x0","gasPrice":"0x0","gas":"0x0","input":"0x","creates":null,"raw":"0x","publicKey":null,"networkId":null,"standardV":"0x0","v":"0x0","r":"0x0","s":"0x0","minBlock":null}]"#);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		let t = BlockTransactions::Hashes(vec![H256::default().into()]);
 | 
							let t = BlockTransactions::Hashes(vec![H256::default().into()]);
 | 
				
			||||||
		let serialized = serde_json::to_string(&t).unwrap();
 | 
							let serialized = serde_json::to_string(&t).unwrap();
 | 
				
			||||||
 | 
				
			|||||||
@ -14,12 +14,12 @@
 | 
				
			|||||||
// You should have received a copy of the GNU General Public License
 | 
					// You should have received a copy of the GNU General Public License
 | 
				
			||||||
// along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | 
					// along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use serde::{Deserialize, Deserializer, Error};
 | 
					use serde::{Deserialize, Deserializer, Error, Serialize, Serializer};
 | 
				
			||||||
use serde::de::Visitor;
 | 
					use serde::de::Visitor;
 | 
				
			||||||
use ethcore::client::BlockId;
 | 
					use ethcore::client::BlockId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Represents rpc api block number param.
 | 
					/// Represents rpc api block number param.
 | 
				
			||||||
#[derive(Debug, PartialEq, Clone)]
 | 
					#[derive(Debug, PartialEq, Clone, Hash, Eq)]
 | 
				
			||||||
pub enum BlockNumber {
 | 
					pub enum BlockNumber {
 | 
				
			||||||
	/// Number
 | 
						/// Number
 | 
				
			||||||
	Num(u64),
 | 
						Num(u64),
 | 
				
			||||||
@ -44,6 +44,27 @@ impl Deserialize for BlockNumber {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl BlockNumber {
 | 
				
			||||||
 | 
						/// Convert block number to min block target.
 | 
				
			||||||
 | 
						pub fn to_min_block_num(&self) -> Option<u64> {
 | 
				
			||||||
 | 
							match *self {
 | 
				
			||||||
 | 
								BlockNumber::Num(ref x) => Some(*x),
 | 
				
			||||||
 | 
								_ => None,
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Serialize for BlockNumber {
 | 
				
			||||||
 | 
						fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer {
 | 
				
			||||||
 | 
							match *self {
 | 
				
			||||||
 | 
								BlockNumber::Num(ref x) => serializer.serialize_str(&format!("0x{:x}", x)),
 | 
				
			||||||
 | 
								BlockNumber::Latest => serializer.serialize_str("latest"),
 | 
				
			||||||
 | 
								BlockNumber::Earliest => serializer.serialize_str("earliest"),
 | 
				
			||||||
 | 
								BlockNumber::Pending => serializer.serialize_str("pending"),
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct BlockNumberVisitor;
 | 
					struct BlockNumberVisitor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Visitor for BlockNumberVisitor {
 | 
					impl Visitor for BlockNumberVisitor {
 | 
				
			||||||
 | 
				
			|||||||
@ -20,7 +20,7 @@ use std::fmt;
 | 
				
			|||||||
use serde::{Serialize, Serializer};
 | 
					use serde::{Serialize, Serializer};
 | 
				
			||||||
use util::log::Colour;
 | 
					use util::log::Colour;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use v1::types::{U256, TransactionRequest, RichRawTransaction, H160, H256, H520, Bytes};
 | 
					use v1::types::{U256, TransactionRequest, RichRawTransaction, H160, H256, H520, Bytes, BlockNumber};
 | 
				
			||||||
use v1::helpers;
 | 
					use v1::helpers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Confirmation waiting in a queue
 | 
					/// Confirmation waiting in a queue
 | 
				
			||||||
@ -193,6 +193,9 @@ pub struct TransactionModification {
 | 
				
			|||||||
	pub gas_price: Option<U256>,
 | 
						pub gas_price: Option<U256>,
 | 
				
			||||||
	/// Modified gas
 | 
						/// Modified gas
 | 
				
			||||||
	pub gas: Option<U256>,
 | 
						pub gas: Option<U256>,
 | 
				
			||||||
 | 
						/// Modified min block
 | 
				
			||||||
 | 
						#[serde(rename="minBlock")]
 | 
				
			||||||
 | 
						pub min_block: Option<Option<BlockNumber>>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Represents two possible return values.
 | 
					/// Represents two possible return values.
 | 
				
			||||||
@ -234,7 +237,7 @@ impl<A, B> Serialize for Either<A, B>  where
 | 
				
			|||||||
mod tests {
 | 
					mod tests {
 | 
				
			||||||
	use std::str::FromStr;
 | 
						use std::str::FromStr;
 | 
				
			||||||
	use serde_json;
 | 
						use serde_json;
 | 
				
			||||||
	use v1::types::{U256, H256};
 | 
						use v1::types::{U256, H256, BlockNumber};
 | 
				
			||||||
	use v1::helpers;
 | 
						use v1::helpers;
 | 
				
			||||||
	use super::*;
 | 
						use super::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -267,12 +270,13 @@ mod tests {
 | 
				
			|||||||
				value: 100_000.into(),
 | 
									value: 100_000.into(),
 | 
				
			||||||
				data: vec![1, 2, 3],
 | 
									data: vec![1, 2, 3],
 | 
				
			||||||
				nonce: Some(1.into()),
 | 
									nonce: Some(1.into()),
 | 
				
			||||||
 | 
									min_block: None,
 | 
				
			||||||
			}),
 | 
								}),
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
		let res = serde_json::to_string(&ConfirmationRequest::from(request));
 | 
							let res = serde_json::to_string(&ConfirmationRequest::from(request));
 | 
				
			||||||
		let expected = r#"{"id":"0xf","payload":{"sendTransaction":{"from":"0x0000000000000000000000000000000000000000","to":null,"gasPrice":"0x2710","gas":"0x3a98","value":"0x186a0","data":"0x010203","nonce":"0x1"}}}"#;
 | 
							let expected = r#"{"id":"0xf","payload":{"sendTransaction":{"from":"0x0000000000000000000000000000000000000000","to":null,"gasPrice":"0x2710","gas":"0x3a98","value":"0x186a0","data":"0x010203","nonce":"0x1","minBlock":null}}}"#;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// then
 | 
							// then
 | 
				
			||||||
		assert_eq!(res.unwrap(), expected.to_owned());
 | 
							assert_eq!(res.unwrap(), expected.to_owned());
 | 
				
			||||||
@ -291,12 +295,13 @@ mod tests {
 | 
				
			|||||||
				value: 100_000.into(),
 | 
									value: 100_000.into(),
 | 
				
			||||||
				data: vec![1, 2, 3],
 | 
									data: vec![1, 2, 3],
 | 
				
			||||||
				nonce: Some(1.into()),
 | 
									nonce: Some(1.into()),
 | 
				
			||||||
 | 
									min_block: None,
 | 
				
			||||||
			}),
 | 
								}),
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// when
 | 
							// when
 | 
				
			||||||
		let res = serde_json::to_string(&ConfirmationRequest::from(request));
 | 
							let res = serde_json::to_string(&ConfirmationRequest::from(request));
 | 
				
			||||||
		let expected = r#"{"id":"0xf","payload":{"signTransaction":{"from":"0x0000000000000000000000000000000000000000","to":null,"gasPrice":"0x2710","gas":"0x3a98","value":"0x186a0","data":"0x010203","nonce":"0x1"}}}"#;
 | 
							let expected = r#"{"id":"0xf","payload":{"signTransaction":{"from":"0x0000000000000000000000000000000000000000","to":null,"gasPrice":"0x2710","gas":"0x3a98","value":"0x186a0","data":"0x010203","nonce":"0x1","minBlock":null}}}"#;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// then
 | 
							// then
 | 
				
			||||||
		assert_eq!(res.unwrap(), expected.to_owned());
 | 
							assert_eq!(res.unwrap(), expected.to_owned());
 | 
				
			||||||
@ -324,7 +329,8 @@ mod tests {
 | 
				
			|||||||
	fn should_deserialize_modification() {
 | 
						fn should_deserialize_modification() {
 | 
				
			||||||
		// given
 | 
							// given
 | 
				
			||||||
		let s1 = r#"{
 | 
							let s1 = r#"{
 | 
				
			||||||
			"gasPrice":"0xba43b7400"
 | 
								"gasPrice":"0xba43b7400",
 | 
				
			||||||
 | 
								"minBlock":"0x42"
 | 
				
			||||||
		}"#;
 | 
							}"#;
 | 
				
			||||||
		let s2 = r#"{"gas": "0x1233"}"#;
 | 
							let s2 = r#"{"gas": "0x1233"}"#;
 | 
				
			||||||
		let s3 = r#"{}"#;
 | 
							let s3 = r#"{}"#;
 | 
				
			||||||
@ -338,14 +344,17 @@ mod tests {
 | 
				
			|||||||
		assert_eq!(res1, TransactionModification {
 | 
							assert_eq!(res1, TransactionModification {
 | 
				
			||||||
			gas_price: Some(U256::from_str("0ba43b7400").unwrap()),
 | 
								gas_price: Some(U256::from_str("0ba43b7400").unwrap()),
 | 
				
			||||||
			gas: None,
 | 
								gas: None,
 | 
				
			||||||
 | 
								min_block: Some(Some(BlockNumber::Num(0x42))),
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
		assert_eq!(res2, TransactionModification {
 | 
							assert_eq!(res2, TransactionModification {
 | 
				
			||||||
			gas_price: None,
 | 
								gas_price: None,
 | 
				
			||||||
			gas: Some(U256::from_str("1233").unwrap()),
 | 
								gas: Some(U256::from_str("1233").unwrap()),
 | 
				
			||||||
 | 
								min_block: None,
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
		assert_eq!(res3, TransactionModification {
 | 
							assert_eq!(res3, TransactionModification {
 | 
				
			||||||
			gas_price: None,
 | 
								gas_price: None,
 | 
				
			||||||
			gas: None,
 | 
								gas: None,
 | 
				
			||||||
 | 
								min_block: None,
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -17,9 +17,9 @@
 | 
				
			|||||||
use serde::{Serialize, Serializer};
 | 
					use serde::{Serialize, Serializer};
 | 
				
			||||||
use ethcore::miner;
 | 
					use ethcore::miner;
 | 
				
			||||||
use ethcore::contract_address;
 | 
					use ethcore::contract_address;
 | 
				
			||||||
use ethcore::transaction::{LocalizedTransaction, Action, SignedTransaction};
 | 
					use ethcore::transaction::{LocalizedTransaction, Action, PendingTransaction, SignedTransaction};
 | 
				
			||||||
use v1::helpers::errors;
 | 
					use v1::helpers::errors;
 | 
				
			||||||
use v1::types::{Bytes, H160, H256, U256, H512};
 | 
					use v1::types::{Bytes, H160, H256, U256, H512, BlockNumber};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Transaction
 | 
					/// Transaction
 | 
				
			||||||
#[derive(Debug, Default, Clone, PartialEq, Serialize)]
 | 
					#[derive(Debug, Default, Clone, PartialEq, Serialize)]
 | 
				
			||||||
@ -69,6 +69,9 @@ pub struct Transaction {
 | 
				
			|||||||
	pub r: U256,
 | 
						pub r: U256,
 | 
				
			||||||
	/// The S field of the signature.
 | 
						/// The S field of the signature.
 | 
				
			||||||
	pub s: U256,
 | 
						pub s: U256,
 | 
				
			||||||
 | 
						/// Transaction activates at specified block.
 | 
				
			||||||
 | 
						#[serde(rename="minBlock")]
 | 
				
			||||||
 | 
						pub min_block: Option<BlockNumber>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Local Transaction Status
 | 
					/// Local Transaction Status
 | 
				
			||||||
@ -187,6 +190,7 @@ impl From<LocalizedTransaction> for Transaction {
 | 
				
			|||||||
			v: t.original_v().into(),
 | 
								v: t.original_v().into(),
 | 
				
			||||||
			r: signature.r().into(),
 | 
								r: signature.r().into(),
 | 
				
			||||||
			s: signature.s().into(),
 | 
								s: signature.s().into(),
 | 
				
			||||||
 | 
								min_block: None,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -220,10 +224,19 @@ impl From<SignedTransaction> for Transaction {
 | 
				
			|||||||
			v: t.original_v().into(),
 | 
								v: t.original_v().into(),
 | 
				
			||||||
			r: signature.r().into(),
 | 
								r: signature.r().into(),
 | 
				
			||||||
			s: signature.s().into(),
 | 
								s: signature.s().into(),
 | 
				
			||||||
 | 
								min_block: None,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl From<PendingTransaction> for Transaction {
 | 
				
			||||||
 | 
						fn from(t: PendingTransaction) -> Transaction {
 | 
				
			||||||
 | 
							let mut r = Transaction::from(t.transaction);
 | 
				
			||||||
 | 
							r.min_block = t.min_block.map(|b| BlockNumber::Num(b));
 | 
				
			||||||
 | 
							r
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl From<miner::LocalTransactionStatus> for LocalTransactionStatus {
 | 
					impl From<miner::LocalTransactionStatus> for LocalTransactionStatus {
 | 
				
			||||||
	fn from(s: miner::LocalTransactionStatus) -> Self {
 | 
						fn from(s: miner::LocalTransactionStatus) -> Self {
 | 
				
			||||||
		use ethcore::miner::LocalTransactionStatus::*;
 | 
							use ethcore::miner::LocalTransactionStatus::*;
 | 
				
			||||||
@ -248,7 +261,7 @@ mod tests {
 | 
				
			|||||||
	fn test_transaction_serialize() {
 | 
						fn test_transaction_serialize() {
 | 
				
			||||||
		let t = Transaction::default();
 | 
							let t = Transaction::default();
 | 
				
			||||||
		let serialized = serde_json::to_string(&t).unwrap();
 | 
							let serialized = serde_json::to_string(&t).unwrap();
 | 
				
			||||||
		assert_eq!(serialized, r#"{"hash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0","blockHash":null,"blockNumber":null,"transactionIndex":null,"from":"0x0000000000000000000000000000000000000000","to":null,"value":"0x0","gasPrice":"0x0","gas":"0x0","input":"0x","creates":null,"raw":"0x","publicKey":null,"networkId":null,"standardV":"0x0","v":"0x0","r":"0x0","s":"0x0"}"#);
 | 
							assert_eq!(serialized, r#"{"hash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0","blockHash":null,"blockNumber":null,"transactionIndex":null,"from":"0x0000000000000000000000000000000000000000","to":null,"value":"0x0","gasPrice":"0x0","gas":"0x0","input":"0x","creates":null,"raw":"0x","publicKey":null,"networkId":null,"standardV":"0x0","v":"0x0","r":"0x0","s":"0x0","minBlock":null}"#);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#[test]
 | 
						#[test]
 | 
				
			||||||
 | 
				
			|||||||
@ -16,7 +16,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
//! `TransactionRequest` type
 | 
					//! `TransactionRequest` type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use v1::types::{Bytes, H160, U256};
 | 
					use v1::types::{Bytes, H160, U256, BlockNumber};
 | 
				
			||||||
use v1::helpers;
 | 
					use v1::helpers;
 | 
				
			||||||
use util::log::Colour;
 | 
					use util::log::Colour;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -41,6 +41,9 @@ pub struct TransactionRequest {
 | 
				
			|||||||
	pub data: Option<Bytes>,
 | 
						pub data: Option<Bytes>,
 | 
				
			||||||
	/// Transaction's nonce
 | 
						/// Transaction's nonce
 | 
				
			||||||
	pub nonce: Option<U256>,
 | 
						pub nonce: Option<U256>,
 | 
				
			||||||
 | 
						/// Delay until this block if specified.
 | 
				
			||||||
 | 
						#[serde(rename="minBlock")]
 | 
				
			||||||
 | 
						pub min_block: Option<BlockNumber>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn format_ether(i: U256) -> String {
 | 
					pub fn format_ether(i: U256) -> String {
 | 
				
			||||||
@ -90,6 +93,7 @@ impl From<helpers::TransactionRequest> for TransactionRequest {
 | 
				
			|||||||
			value: r.value.map(Into::into),
 | 
								value: r.value.map(Into::into),
 | 
				
			||||||
			data: r.data.map(Into::into),
 | 
								data: r.data.map(Into::into),
 | 
				
			||||||
			nonce: r.nonce.map(Into::into),
 | 
								nonce: r.nonce.map(Into::into),
 | 
				
			||||||
 | 
								min_block: r.min_block.map(|b| BlockNumber::Num(b)),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -104,6 +108,7 @@ impl From<helpers::FilledTransactionRequest> for TransactionRequest {
 | 
				
			|||||||
			value: Some(r.value.into()),
 | 
								value: Some(r.value.into()),
 | 
				
			||||||
			data: Some(r.data.into()),
 | 
								data: Some(r.data.into()),
 | 
				
			||||||
			nonce: r.nonce.map(Into::into),
 | 
								nonce: r.nonce.map(Into::into),
 | 
				
			||||||
 | 
								min_block: r.min_block.map(|b| BlockNumber::Num(b)),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -118,6 +123,7 @@ impl Into<helpers::TransactionRequest> for TransactionRequest {
 | 
				
			|||||||
			value: self.value.map(Into::into),
 | 
								value: self.value.map(Into::into),
 | 
				
			||||||
			data: self.data.map(Into::into),
 | 
								data: self.data.map(Into::into),
 | 
				
			||||||
			nonce: self.nonce.map(Into::into),
 | 
								nonce: self.nonce.map(Into::into),
 | 
				
			||||||
 | 
								min_block: self.min_block.and_then(|b| b.to_min_block_num()),
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -128,7 +134,7 @@ mod tests {
 | 
				
			|||||||
	use std::str::FromStr;
 | 
						use std::str::FromStr;
 | 
				
			||||||
	use rustc_serialize::hex::FromHex;
 | 
						use rustc_serialize::hex::FromHex;
 | 
				
			||||||
	use serde_json;
 | 
						use serde_json;
 | 
				
			||||||
	use v1::types::{U256, H160};
 | 
						use v1::types::{U256, H160, BlockNumber};
 | 
				
			||||||
	use super::*;
 | 
						use super::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#[test]
 | 
						#[test]
 | 
				
			||||||
@ -140,7 +146,8 @@ mod tests {
 | 
				
			|||||||
			"gas":"0x2",
 | 
								"gas":"0x2",
 | 
				
			||||||
			"value":"0x3",
 | 
								"value":"0x3",
 | 
				
			||||||
			"data":"0x123456",
 | 
								"data":"0x123456",
 | 
				
			||||||
			"nonce":"0x4"
 | 
								"nonce":"0x4",
 | 
				
			||||||
 | 
								"minBlock":"0x13"
 | 
				
			||||||
		}"#;
 | 
							}"#;
 | 
				
			||||||
		let deserialized: TransactionRequest = serde_json::from_str(s).unwrap();
 | 
							let deserialized: TransactionRequest = serde_json::from_str(s).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -152,6 +159,7 @@ mod tests {
 | 
				
			|||||||
			value: Some(U256::from(3)),
 | 
								value: Some(U256::from(3)),
 | 
				
			||||||
			data: Some(vec![0x12, 0x34, 0x56].into()),
 | 
								data: Some(vec![0x12, 0x34, 0x56].into()),
 | 
				
			||||||
			nonce: Some(U256::from(4)),
 | 
								nonce: Some(U256::from(4)),
 | 
				
			||||||
 | 
								min_block: Some(BlockNumber::Num(0x13)),
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -174,7 +182,8 @@ mod tests {
 | 
				
			|||||||
			gas: Some(U256::from_str("76c0").unwrap()),
 | 
								gas: Some(U256::from_str("76c0").unwrap()),
 | 
				
			||||||
			value: Some(U256::from_str("9184e72a").unwrap()),
 | 
								value: Some(U256::from_str("9184e72a").unwrap()),
 | 
				
			||||||
			data: Some("d46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675".from_hex().unwrap().into()),
 | 
								data: Some("d46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675".from_hex().unwrap().into()),
 | 
				
			||||||
			nonce: None
 | 
								nonce: None,
 | 
				
			||||||
 | 
								min_block: None,
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -191,6 +200,7 @@ mod tests {
 | 
				
			|||||||
			value: None,
 | 
								value: None,
 | 
				
			||||||
			data: None,
 | 
								data: None,
 | 
				
			||||||
			nonce: None,
 | 
								nonce: None,
 | 
				
			||||||
 | 
								min_block: None,
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -214,6 +224,7 @@ mod tests {
 | 
				
			|||||||
			value: None,
 | 
								value: None,
 | 
				
			||||||
			data: Some(vec![0x85, 0x95, 0xba, 0xb1].into()),
 | 
								data: Some(vec![0x85, 0x95, 0xba, 0xb1].into()),
 | 
				
			||||||
			nonce: None,
 | 
								nonce: None,
 | 
				
			||||||
 | 
								min_block: None,
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -91,7 +91,7 @@ fn list_transactions(signer: &mut SignerRpc) -> Result<String, String> {
 | 
				
			|||||||
fn sign_transaction(
 | 
					fn sign_transaction(
 | 
				
			||||||
	signer: &mut SignerRpc, id: U256, password: &str
 | 
						signer: &mut SignerRpc, id: U256, password: &str
 | 
				
			||||||
) -> Result<String, String> {
 | 
					) -> Result<String, String> {
 | 
				
			||||||
	try!(signer.confirm_request(id, None, None, password).map(|res| {
 | 
						try!(signer.confirm_request(id, None, None, None, password).map(|res| {
 | 
				
			||||||
		match res {
 | 
							match res {
 | 
				
			||||||
			Ok(u) => Ok(format!("Signed transaction id: {:#x}", u)),
 | 
								Ok(u) => Ok(format!("Signed transaction id: {:#x}", u)),
 | 
				
			||||||
			Err(e) => Err(format!("{:?}", e)),
 | 
								Err(e) => Err(format!("{:?}", e)),
 | 
				
			||||||
 | 
				
			|||||||
@ -8,7 +8,6 @@ version = "1.4.0"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[dependencies]
 | 
					[dependencies]
 | 
				
			||||||
futures = "0.1"
 | 
					futures = "0.1"
 | 
				
			||||||
jsonrpc-core = "3.0.2"
 | 
					 | 
				
			||||||
lazy_static = "0.2.1"
 | 
					lazy_static = "0.2.1"
 | 
				
			||||||
log = "0.3.6"
 | 
					log = "0.3.6"
 | 
				
			||||||
matches = "0.1.2"
 | 
					matches = "0.1.2"
 | 
				
			||||||
@ -17,6 +16,7 @@ serde = "0.8"
 | 
				
			|||||||
serde_json = "0.8"
 | 
					serde_json = "0.8"
 | 
				
			||||||
tempdir = "0.3.5"
 | 
					tempdir = "0.3.5"
 | 
				
			||||||
url = "1.2.0"
 | 
					url = "1.2.0"
 | 
				
			||||||
 | 
					jsonrpc-core = { git = "https://github.com/ethcore/jsonrpc.git" }
 | 
				
			||||||
ws = { git = "https://github.com/ethcore/ws-rs.git", branch = "mio-upstream-stable" }
 | 
					ws = { git = "https://github.com/ethcore/ws-rs.git", branch = "mio-upstream-stable" }
 | 
				
			||||||
ethcore-rpc = { path = "../rpc" }
 | 
					ethcore-rpc = { path = "../rpc" }
 | 
				
			||||||
ethcore-signer = { path = "../signer" }
 | 
					ethcore-signer = { path = "../signer" }
 | 
				
			||||||
 | 
				
			|||||||
@ -36,7 +36,7 @@ use futures::{BoxFuture, Canceled, Complete, Future, oneshot, done};
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use jsonrpc_core::{Id, Version, Params, Error as JsonRpcError};
 | 
					use jsonrpc_core::{Id, Version, Params, Error as JsonRpcError};
 | 
				
			||||||
use jsonrpc_core::request::MethodCall;
 | 
					use jsonrpc_core::request::MethodCall;
 | 
				
			||||||
use jsonrpc_core::response::{SyncOutput, Success, Failure};
 | 
					use jsonrpc_core::response::{Output, Success, Failure};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// The actual websocket connection handler, passed into the
 | 
					/// The actual websocket connection handler, passed into the
 | 
				
			||||||
/// event loop of ws-rs
 | 
					/// event loop of ws-rs
 | 
				
			||||||
@ -107,13 +107,13 @@ impl Handler for RpcHandler {
 | 
				
			|||||||
		let ret: Result<JsonValue, JsonRpcError>;
 | 
							let ret: Result<JsonValue, JsonRpcError>;
 | 
				
			||||||
		let response_id;
 | 
							let response_id;
 | 
				
			||||||
		let string = &msg.to_string();
 | 
							let string = &msg.to_string();
 | 
				
			||||||
		match json::from_str::<SyncOutput>(&string) {
 | 
							match json::from_str::<Output>(&string) {
 | 
				
			||||||
			Ok(SyncOutput::Success(Success { result, id: Id::Num(id), .. })) =>
 | 
								Ok(Output::Success(Success { result, id: Id::Num(id), .. })) =>
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				ret = Ok(result);
 | 
									ret = Ok(result);
 | 
				
			||||||
				response_id = id as usize;
 | 
									response_id = id as usize;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			Ok(SyncOutput::Failure(Failure { error, id: Id::Num(id), .. })) => {
 | 
								Ok(Output::Failure(Failure { error, id: Id::Num(id), .. })) => {
 | 
				
			||||||
				ret = Err(error);
 | 
									ret = Err(error);
 | 
				
			||||||
				response_id = id as usize;
 | 
									response_id = id as usize;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,5 @@
 | 
				
			|||||||
use client::{Rpc, RpcError};
 | 
					use client::{Rpc, RpcError};
 | 
				
			||||||
use rpc::v1::types::{ConfirmationRequest,
 | 
					use rpc::v1::types::{ConfirmationRequest, TransactionModification, U256, BlockNumber};
 | 
				
			||||||
					 TransactionModification,
 | 
					 | 
				
			||||||
					 U256};
 | 
					 | 
				
			||||||
use serde_json::{Value as JsonValue, to_value};
 | 
					use serde_json::{Value as JsonValue, to_value};
 | 
				
			||||||
use std::path::PathBuf;
 | 
					use std::path::PathBuf;
 | 
				
			||||||
use futures::{BoxFuture, Canceled};
 | 
					use futures::{BoxFuture, Canceled};
 | 
				
			||||||
@ -24,12 +22,13 @@ impl SignerRpc {
 | 
				
			|||||||
		id: U256,
 | 
							id: U256,
 | 
				
			||||||
		new_gas: Option<U256>,
 | 
							new_gas: Option<U256>,
 | 
				
			||||||
		new_gas_price: Option<U256>,
 | 
							new_gas_price: Option<U256>,
 | 
				
			||||||
 | 
							new_min_block: Option<Option<BlockNumber>>,
 | 
				
			||||||
		pwd: &str
 | 
							pwd: &str
 | 
				
			||||||
	) -> BoxFuture<Result<U256, RpcError>, Canceled>
 | 
						) -> BoxFuture<Result<U256, RpcError>, Canceled>
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		self.rpc.request("signer_confirmRequest", vec![
 | 
							self.rpc.request("signer_confirmRequest", vec![
 | 
				
			||||||
			to_value(&format!("{:#x}", id)),
 | 
								to_value(&format!("{:#x}", id)),
 | 
				
			||||||
			to_value(&TransactionModification { gas_price: new_gas_price, gas: new_gas }),
 | 
								to_value(&TransactionModification { gas_price: new_gas_price, gas: new_gas, min_block: new_min_block }),
 | 
				
			||||||
			to_value(&pwd),
 | 
								to_value(&pwd),
 | 
				
			||||||
		])
 | 
							])
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
@ -1919,15 +1919,15 @@ impl ChainSync {
 | 
				
			|||||||
			return 0;
 | 
								return 0;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		let transactions = io.chain().pending_transactions();
 | 
							let transactions = io.chain().ready_transactions();
 | 
				
			||||||
		if transactions.is_empty() {
 | 
							if transactions.is_empty() {
 | 
				
			||||||
			return 0;
 | 
								return 0;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		let all_transactions_hashes = transactions.iter().map(|tx| tx.hash()).collect::<HashSet<H256>>();
 | 
							let all_transactions_hashes = transactions.iter().map(|tx| tx.transaction.hash()).collect::<HashSet<H256>>();
 | 
				
			||||||
		let all_transactions_rlp = {
 | 
							let all_transactions_rlp = {
 | 
				
			||||||
			let mut packet = RlpStream::new_list(transactions.len());
 | 
								let mut packet = RlpStream::new_list(transactions.len());
 | 
				
			||||||
			for tx in &transactions { packet.append(tx); }
 | 
								for tx in &transactions { packet.append(&tx.transaction); }
 | 
				
			||||||
			packet.out()
 | 
								packet.out()
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1965,11 +1965,11 @@ impl ChainSync {
 | 
				
			|||||||
					// Construct RLP
 | 
										// Construct RLP
 | 
				
			||||||
					let mut packet = RlpStream::new_list(to_send.len());
 | 
										let mut packet = RlpStream::new_list(to_send.len());
 | 
				
			||||||
					for tx in &transactions {
 | 
										for tx in &transactions {
 | 
				
			||||||
						if to_send.contains(&tx.hash()) {
 | 
											if to_send.contains(&tx.transaction.hash()) {
 | 
				
			||||||
							packet.append(tx);
 | 
												packet.append(&tx.transaction);
 | 
				
			||||||
							// update stats
 | 
												// update stats
 | 
				
			||||||
							let id = io.peer_session_info(*peer_id).and_then(|info| info.id);
 | 
												let id = io.peer_session_info(*peer_id).and_then(|info| info.id);
 | 
				
			||||||
							stats.propagated(tx.hash(), id, block_number);
 | 
												stats.propagated(tx.transaction.hash(), id, block_number);
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -44,15 +44,16 @@ impl IoHandler<ClientIoMessage> for TestIoHandler {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn new_tx(secret: &H256, nonce: U256) -> SignedTransaction {
 | 
					fn new_tx(secret: &H256, nonce: U256) -> PendingTransaction {
 | 
				
			||||||
	Transaction {
 | 
						let signed = Transaction {
 | 
				
			||||||
		nonce: nonce.into(),
 | 
							nonce: nonce.into(),
 | 
				
			||||||
		gas_price: 0.into(),
 | 
							gas_price: 0.into(),
 | 
				
			||||||
		gas: 21000.into(),
 | 
							gas: 21000.into(),
 | 
				
			||||||
		action: Action::Call(Address::default()),
 | 
							action: Action::Call(Address::default()),
 | 
				
			||||||
		value: 0.into(),
 | 
							value: 0.into(),
 | 
				
			||||||
		data: Vec::new(),
 | 
							data: Vec::new(),
 | 
				
			||||||
	}.sign(secret, None)
 | 
						}.sign(secret, None);
 | 
				
			||||||
 | 
						PendingTransaction::new(signed, None)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[test]
 | 
					#[test]
 | 
				
			||||||
 | 
				
			|||||||
@ -21,6 +21,8 @@ use std::path::{PathBuf};
 | 
				
			|||||||
use target_info::Target;
 | 
					use target_info::Target;
 | 
				
			||||||
use util::misc;
 | 
					use util::misc;
 | 
				
			||||||
use ipc_common_types::{VersionInfo, ReleaseTrack};
 | 
					use ipc_common_types::{VersionInfo, ReleaseTrack};
 | 
				
			||||||
 | 
					use util::path::restrict_permissions_owner; 
 | 
				
			||||||
 | 
					use util::misc::platform;
 | 
				
			||||||
use util::{Address, H160, H256, FixedHash, Mutex, Bytes};
 | 
					use util::{Address, H160, H256, FixedHash, Mutex, Bytes};
 | 
				
			||||||
use ethsync::{SyncProvider};
 | 
					use ethsync::{SyncProvider};
 | 
				
			||||||
use ethcore::client::{BlockId, BlockChainClient, ChainNotify};
 | 
					use ethcore::client::{BlockId, BlockChainClient, ChainNotify};
 | 
				
			||||||
@ -210,7 +212,8 @@ impl Updater {
 | 
				
			|||||||
				let dest = self.updates_path(&Self::update_file_name(&fetched.version));
 | 
									let dest = self.updates_path(&Self::update_file_name(&fetched.version));
 | 
				
			||||||
				fs::create_dir_all(dest.parent().expect("at least one thing pushed; qed")).map_err(|e| format!("Unable to create updates path: {:?}", e))?;
 | 
									fs::create_dir_all(dest.parent().expect("at least one thing pushed; qed")).map_err(|e| format!("Unable to create updates path: {:?}", e))?;
 | 
				
			||||||
				fs::copy(&b, &dest).map_err(|e| format!("Unable to copy update: {:?}", e))?;
 | 
									fs::copy(&b, &dest).map_err(|e| format!("Unable to copy update: {:?}", e))?;
 | 
				
			||||||
				info!(target: "updater", "Copied file to {}", dest.display());
 | 
									restrict_permissions_owner(&dest, false, true).map_err(|e| format!("Unable to update permissions: {}", e))?;
 | 
				
			||||||
 | 
									info!(target: "updater", "Installed updated binary to {}", dest.display());
 | 
				
			||||||
				let auto = match self.update_policy.filter {
 | 
									let auto = match self.update_policy.filter {
 | 
				
			||||||
					UpdateFilter::All => true,
 | 
										UpdateFilter::All => true,
 | 
				
			||||||
					UpdateFilter::Critical if fetched.is_critical /* TODO: or is on a bad fork */ => true,
 | 
										UpdateFilter::Critical if fetched.is_critical /* TODO: or is on a bad fork */ => true,
 | 
				
			||||||
 | 
				
			|||||||
@ -1168,8 +1168,8 @@ fn save_key(path: &Path, key: &Secret) {
 | 
				
			|||||||
			return;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
	if let Err(e) = restrict_permissions_owner(path) {
 | 
						if let Err(e) = restrict_permissions_owner(path, true, false) {
 | 
				
			||||||
		warn!(target: "network", "Failed to modify permissions of the file (chmod: {})", e);
 | 
							warn!(target: "network", "Failed to modify permissions of the file ({})", e);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if let Err(e) = file.write(&key.hex().into_bytes()) {
 | 
						if let Err(e) = file.write(&key.hex().into_bytes()) {
 | 
				
			||||||
		warn!("Error writing key file: {:?}", e);
 | 
							warn!("Error writing key file: {:?}", e);
 | 
				
			||||||
 | 
				
			|||||||
@ -86,18 +86,15 @@ pub mod ethereum {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Restricts the permissions of given path only to the owner.
 | 
					/// Restricts the permissions of given path only to the owner.
 | 
				
			||||||
#[cfg(not(windows))]
 | 
					#[cfg(unix)]
 | 
				
			||||||
pub fn restrict_permissions_owner(file_path: &Path) -> Result<(), i32>  {
 | 
					pub fn restrict_permissions_owner(file_path: &Path, write: bool, executable: bool) -> Result<(), String>  {
 | 
				
			||||||
	let cstr = ::std::ffi::CString::new(file_path.to_str().unwrap()).unwrap();
 | 
						let perms = ::std::os::unix::fs::PermissionsExt::from_mode(0o400 + write as u32 * 0o200 + executable as u32 * 0o100);
 | 
				
			||||||
	match unsafe { ::libc::chmod(cstr.as_ptr(), ::libc::S_IWUSR | ::libc::S_IRUSR) } {
 | 
						::std::fs::set_permissions(file_path, perms).map_err(|e| format!("{:?}", e))
 | 
				
			||||||
		0 => Ok(()),
 | 
					 | 
				
			||||||
		x => Err(x),
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Restricts the permissions of given path only to the owner.
 | 
					/// Restricts the permissions of given path only to the owner.
 | 
				
			||||||
#[cfg(windows)]
 | 
					#[cfg(not(unix))]
 | 
				
			||||||
pub fn restrict_permissions_owner(_file_path: &Path) -> Result<(), i32>  {
 | 
					pub fn restrict_permissions_owner(_file_path: &Path, _write: bool, _executable: bool) -> Result<(), String>  {
 | 
				
			||||||
	//TODO: implement me
 | 
						//TODO: implement me
 | 
				
			||||||
	Ok(())
 | 
						Ok(())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user