diff --git a/Cargo.lock b/Cargo.lock index 8816cc517..840684b2d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1928,14 +1928,16 @@ dependencies = [ "checksum itoa 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ae3088ea4baeceb0284ee9eea42f591226e6beaecf65373e41b38d95a1b8e7a1" "checksum json-ipc-server 0.2.4 (git+https://github.com/ethcore/json-ipc-server.git)" = "" "checksum json-tcp-server 0.1.0 (git+https://github.com/ethcore/json-tcp-server)" = "" -"checksum jsonrpc-core 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e913b3c809aab9378889da8b990b4a46b98bd4794c8117946a1cf63c5f87bcde" +"checksum jsonrpc-core 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3c5094610b07f28f3edaf3947b732dadb31dbba4941d4d0c1c7a8350208f4414" "checksum jsonrpc-http-server 6.1.0 (git+https://github.com/ethcore/jsonrpc-http-server.git)" = "" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" "checksum lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "49247ec2a285bb3dcb23cbd9c35193c025e7251bfce77c1d5da97e6362dffe7f" "checksum libc 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "23e3757828fa702a20072c37ff47938e9dd331b92fac6e223d26d4b7a55f7ee2" +"checksum linked-hash-map 0.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "83f7ff3baae999fdf921cccf54b61842bb3b26868d50d02dff48052ebec8dd79" "checksum linked-hash-map 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6d262045c5b87c0861b3f004610afd0e2c851e2908d08b6c870cbb9d5f494ecd" "checksum log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ab83497bf8bf4ed2a74259c1c802351fcd67a65baa86394b6ba73c36f4838054" +"checksum lru-cache 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "42d50dcb5d9f145df83b1043207e1ac0c37c9c779c4e128ca4655abc3f3cbf8c" "checksum matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "15305656809ce5a4805b1ff2946892810992197ce1270ff79baded852187942e" "checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20" "checksum mime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a74cc2587bf97c49f3f5bab62860d6abf3902ca73b66b51d9b049fbdcd727bd2" @@ -1989,7 +1991,7 @@ dependencies = [ "checksum rayon 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "655df67c314c30fa3055a365eae276eb88aa4f3413a352a1ab32c1320eda41ea" "checksum regex 0.1.68 (registry+https://github.com/rust-lang/crates.io-index)" = "b4329b8928a284580a1c63ec9d846b12f6d3472317243ff7077aff11f23f2b29" "checksum regex-syntax 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "841591b1e05609a643e3b4d0045fce04f701daba7151ddcd3ad47b080693d5a9" -"checksum ring 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d059a6a96d3be79042e3f70eb97945912839265f9d8ab45b921abaf266c70dbb" +"checksum ring 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0d2f6547bf9640f1d3cc4e771f82374ec8fd237c17eeb3ff5cd5ccbe22377a09" "checksum rocksdb 0.4.5 (git+https://github.com/ethcore/rust-rocksdb)" = "" "checksum rocksdb-sys 0.3.0 (git+https://github.com/ethcore/rust-rocksdb)" = "" "checksum rotor 0.6.3 (git+https://github.com/ethcore/rotor)" = "" @@ -1997,7 +1999,7 @@ dependencies = [ "checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a" "checksum rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "6159e4e6e559c81bd706afe9c8fd68f547d3e851ce12e76b1de7914bab61691b" "checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084" -"checksum rustls 0.1.1 (git+https://github.com/ctz/rustls)" = "" +"checksum rustls 0.1.2 (git+https://github.com/ctz/rustls)" = "" "checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac" "checksum semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2d5b7638a1f03815d94e88cb3b3c08e87f0db4d683ef499d1836aaf70a45623f" "checksum serde 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b1dfda9ebb31d29fa8b94d7eb3031a86a8dcec065f0fe268a30f98867bf45775" @@ -2042,7 +2044,7 @@ dependencies = [ "checksum vecio 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0795a11576d29ae80525a3fda315bf7b534f8feb9d34101e5fe63fb95bb2fd24" "checksum vergen 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "56b639f935488eb40f06d17c3e3bcc3054f6f75d264e187b1107c8d1cba8d31c" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" -"checksum webpki 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5dc10a815fabbb0c3145c1153240528f3a8703a47e26e8dbb4a5d4f6386200ad" +"checksum webpki 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "813503a5985585e0812d430cd1328ee322f47f66629c8ed4ecab939cf9e92f91" "checksum winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4dfaaa8fbdaa618fa6914b59b2769d690dd7521920a18d84b42d254678dd5fd4" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" "checksum ws 0.5.2 (git+https://github.com/ethcore/ws-rs.git?branch=mio-upstream-stable)" = "" diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 3dbf56e35..f8b4259d5 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -853,9 +853,12 @@ impl BlockChainClient for Client { fn transaction_receipt(&self, id: TransactionID) -> Option { let chain = self.chain.read(); - self.transaction_address(id).and_then(|address| chain.block_number(&address.block_hash).and_then(|block_number| { + self.transaction_address(id) + .and_then(|address| chain.block_number(&address.block_hash).and_then(|block_number| { let t = chain.block_body(&address.block_hash) - .and_then(|block| BodyView::new(&block).localized_transaction_at(&address.block_hash, block_number, address.index)); + .and_then(|block| { + BodyView::new(&block).localized_transaction_at(&address.block_hash, block_number, address.index) + }); match (t, chain.transaction_receipt(&address)) { (Some(tx), Some(receipt)) => { diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index a3d35d87e..2b0585db7 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -924,7 +924,7 @@ impl MinerService for Miner { out_of_chain.for_each(|txs| { let mut transaction_queue = self.transaction_queue.lock(); let _ = self.add_transactions_to_queue( - chain, txs, TransactionOrigin::External, &mut transaction_queue + chain, txs, TransactionOrigin::RetractedBlock, &mut transaction_queue ); }); } diff --git a/ethcore/src/miner/transaction_queue.rs b/ethcore/src/miner/transaction_queue.rs index 7db65eacb..bad30c925 100644 --- a/ethcore/src/miner/transaction_queue.rs +++ b/ethcore/src/miner/transaction_queue.rs @@ -98,6 +98,8 @@ pub enum TransactionOrigin { Local, /// External transaction received from network External, + /// Transactions from retracted blocks + RetractedBlock, } impl PartialOrd for TransactionOrigin { @@ -112,10 +114,11 @@ impl Ord for TransactionOrigin { return Ordering::Equal; } - if *self == TransactionOrigin::Local { - Ordering::Less - } else { - Ordering::Greater + match (*self, *other) { + (TransactionOrigin::RetractedBlock, _) => Ordering::Less, + (_, TransactionOrigin::RetractedBlock) => Ordering::Greater, + (TransactionOrigin::Local, _) => Ordering::Less, + _ => Ordering::Greater, } } } @@ -1014,6 +1017,17 @@ mod test { new_tx_pair_default(0.into(), 1.into()) } + #[test] + fn test_ordering() { + assert_eq!(TransactionOrigin::Local.cmp(&TransactionOrigin::External), Ordering::Less); + assert_eq!(TransactionOrigin::RetractedBlock.cmp(&TransactionOrigin::Local), Ordering::Less); + assert_eq!(TransactionOrigin::RetractedBlock.cmp(&TransactionOrigin::External), Ordering::Less); + + assert_eq!(TransactionOrigin::External.cmp(&TransactionOrigin::Local), Ordering::Greater); + assert_eq!(TransactionOrigin::Local.cmp(&TransactionOrigin::RetractedBlock), Ordering::Greater); + assert_eq!(TransactionOrigin::External.cmp(&TransactionOrigin::RetractedBlock), Ordering::Greater); + } + #[test] fn should_return_correct_nonces_when_dropped_because_of_limit() { // given @@ -1375,6 +1389,27 @@ mod test { assert_eq!(top.len(), 2); } + #[test] + fn should_prioritize_reimported_transactions_within_same_nonce_height() { + // given + let mut txq = TransactionQueue::new(); + let tx = new_tx_default(); + // the second one has same nonce but higher `gas_price` + let (_, tx2) = new_similar_tx_pair(); + + // when + // first insert local one with higher gas price + txq.add(tx2.clone(), &default_account_details, TransactionOrigin::Local).unwrap(); + // then the one with lower gas price, but from retracted block + txq.add(tx.clone(), &default_account_details, TransactionOrigin::RetractedBlock).unwrap(); + + // then + let top = txq.top_transactions(); + assert_eq!(top[0], tx); // retracted should be first + assert_eq!(top[1], tx2); + assert_eq!(top.len(), 2); + } + #[test] fn should_not_prioritize_local_transactions_with_different_nonce_height() { // given diff --git a/util/bigint/src/hash.rs b/util/bigint/src/hash.rs index 97b9545bc..f782d1f90 100644 --- a/util/bigint/src/hash.rs +++ b/util/bigint/src/hash.rs @@ -64,11 +64,11 @@ pub fn clean_0x(s: &str) -> &str { macro_rules! impl_hash { ($from: ident, $size: expr) => { - #[derive(Eq)] #[repr(C)] /// Unformatted binary data of fixed length. pub struct $from (pub [u8; $size]); + impl From<[u8; $size]> for $from { fn from(bytes: [u8; $size]) -> Self { $from(bytes) @@ -210,6 +210,8 @@ macro_rules! impl_hash { } } + impl Eq for $from {} + impl PartialEq for $from { fn eq(&self, other: &Self) -> bool { for i in 0..$size {