Compare commits
3 Commits
v1.10.5
...
v1.10.3-ci
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4b3ea9b1af | ||
|
|
5dd3729256 | ||
|
|
1c38cd8534 |
@@ -188,7 +188,7 @@ docker-build:
|
||||
before_script:
|
||||
- docker info
|
||||
script:
|
||||
- if [ "$CI_BUILD_REF_NAME" == "master" ]; then DOCKER_TAG="latest"; else DOCKER_TAG=$CI_BUILD_REF_NAME; fi
|
||||
- if [ "$CI_BUILD_REF_NAME" == "beta" ]; then DOCKER_TAG="latest"; else DOCKER_TAG=$CI_BUILD_REF_NAME; fi
|
||||
- echo "Tag:" $DOCKER_TAG
|
||||
- docker login -u $Docker_Hub_User_Parity -p $Docker_Hub_Pass_Parity
|
||||
- scripts/docker-build.sh $DOCKER_TAG
|
||||
|
||||
37
Cargo.lock
generated
37
Cargo.lock
generated
@@ -17,7 +17,7 @@ version = "1.2.1"
|
||||
source = "git+https://github.com/paritytech/app-dirs-rs#0b37f9481ce29e9d5174ad185bca695b206368eb"
|
||||
dependencies = [
|
||||
"ole32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"shell32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"shell32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"xdg 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
@@ -1677,11 +1677,6 @@ dependencies = [
|
||||
"tiny-keccak 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nan-preserving-float"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "net2"
|
||||
version = "0.2.31"
|
||||
@@ -1867,7 +1862,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "parity"
|
||||
version = "1.10.5"
|
||||
version = "1.10.3"
|
||||
dependencies = [
|
||||
"ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clap 2.29.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1915,7 +1910,7 @@ dependencies = [
|
||||
"parity-rpc 1.9.0",
|
||||
"parity-rpc-client 1.4.0",
|
||||
"parity-updater 1.9.0",
|
||||
"parity-version 1.10.5",
|
||||
"parity-version 1.10.3",
|
||||
"parity-whisper 0.1.0",
|
||||
"parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"path 0.1.0",
|
||||
@@ -1964,7 +1959,7 @@ dependencies = [
|
||||
"parity-reactor 0.1.0",
|
||||
"parity-ui 1.9.0",
|
||||
"parity-ui-deprecation 1.10.0",
|
||||
"parity-version 1.10.5",
|
||||
"parity-version 1.10.3",
|
||||
"parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2115,7 +2110,7 @@ dependencies = [
|
||||
"order-stat 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-reactor 0.1.0",
|
||||
"parity-updater 1.9.0",
|
||||
"parity-version 1.10.5",
|
||||
"parity-version 1.10.3",
|
||||
"parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2232,7 +2227,7 @@ dependencies = [
|
||||
"ethsync 1.9.0",
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-hash-fetch 1.9.0",
|
||||
"parity-version 1.10.5",
|
||||
"parity-version 1.10.3",
|
||||
"parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"path 0.1.0",
|
||||
"semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2241,7 +2236,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "parity-version"
|
||||
version = "1.10.5"
|
||||
version = "1.10.3"
|
||||
dependencies = [
|
||||
"ethcore-bytes 0.1.0",
|
||||
"rlp 0.2.1",
|
||||
@@ -2490,7 +2485,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pwasm-utils"
|
||||
version = "0.1.5"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2852,7 +2847,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "shell32-sys"
|
||||
version = "0.1.2"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -3438,19 +3433,18 @@ dependencies = [
|
||||
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-wasm 0.27.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pwasm-utils 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pwasm-utils 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"vm 0.1.0",
|
||||
"wasmi 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasmi 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmi"
|
||||
version = "0.2.0"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"nan-preserving-float 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parity-wasm 0.27.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -3679,7 +3673,6 @@ dependencies = [
|
||||
"checksum msdos_time 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "65ba9d75bcea84e07812618fedf284a64776c2f2ea0cad6bca7f69739695a958"
|
||||
"checksum multibase 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b9c35dac080fd6e16a99924c8dfdef0af89d797dd851adab25feaffacf7850d6"
|
||||
"checksum multihash 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d49add5f49eb08bfc4d01ff286b84a48f53d45314f165c2d6efe477222d24f3"
|
||||
"checksum nan-preserving-float 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34d4f00fcc2f4c9efa8cc971db0da9e28290e28e97af47585e48691ef10ff31f"
|
||||
"checksum net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)" = "3a80f842784ef6c9a958b68b7516bc7e35883c614004dd94959a4dca1b716c09"
|
||||
"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2"
|
||||
"checksum ntp 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "143149743832c6543b60a8ef2a26cd9122dfecec2b767158e852a7beecf6d7a0"
|
||||
@@ -3720,7 +3713,7 @@ dependencies = [
|
||||
"checksum primal-sieve 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c0911abe7b63ddec27527ba7579c3017f645eb992be6ddbfad605e34aca01876"
|
||||
"checksum protobuf 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "568a15e4d572d9a5e63ae3a55f84328c984842887db179b40b4cc6a608bac6a4"
|
||||
"checksum pulldown-cmark 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8361e81576d2e02643b04950e487ec172b687180da65c731c03cf336784e6c07"
|
||||
"checksum pwasm-utils 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d51e9954a77aab7b4b606dc315a49cbed187924f163b6750cdf6d5677dbf0839"
|
||||
"checksum pwasm-utils 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "54d440c3b56eee028aa5d4f18cbed8c6e0c9ae23563b93f344beb7e73854ea02"
|
||||
"checksum quasi 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18c45c4854d6d1cf5d531db97c75880feb91c958b0720f4ec1057135fec358b3"
|
||||
"checksum quasi_codegen 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51b9e25fa23c044c1803f43ca59c98dac608976dd04ce799411edd58ece776d4"
|
||||
"checksum quasi_macros 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29cec87bc2816766d7e4168302d505dd06b0a825aed41b00633d296e922e02dd"
|
||||
@@ -3759,7 +3752,7 @@ dependencies = [
|
||||
"checksum serde_ignored 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "190e9765dcedb56be63b6e0993a006c7e3b071a016a304736e4a315dc01fb142"
|
||||
"checksum serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c9db7266c7d63a4c4b7fe8719656ccdd51acf1bed6124b174f933b009fb10bcb"
|
||||
"checksum sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc30b1e1e8c40c121ca33b86c23308a090d19974ef001b4bf6e61fd1a0fb095c"
|
||||
"checksum shell32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9ee04b46101f57121c9da2b151988283b6beb79b34f5bb29a58ee48cb695122c"
|
||||
"checksum shell32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72f20b8f3c060374edb8046591ba28f62448c369ccbdc7b02075103fb3a9e38d"
|
||||
"checksum siphasher 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "833011ca526bd88f16778d32c699d325a9ad302fa06381cd66f7be63351d3f6d"
|
||||
"checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537"
|
||||
"checksum skeptic 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24ebf8a06f5f8bae61ae5bbc7af7aac4ef6907ae975130faba1199e5fe82256a"
|
||||
@@ -3821,7 +3814,7 @@ dependencies = [
|
||||
"checksum vergen 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c3365f36c57e5df714a34be40902b27a992eeddb9996eca52d0584611cf885d"
|
||||
"checksum version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6b772017e347561807c1aa192438c5fd74242a670a6cffacc40f2defd1dc069d"
|
||||
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||
"checksum wasmi 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46df76793c28cd8f590d5667f540a81c1c245440a17b03560e381226e27cf348"
|
||||
"checksum wasmi 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d19da510b59247935ad5f598357b3cc739912666d75d3d28318026478d95bbdb"
|
||||
"checksum webpki 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9e1622384bcb5458c6a3e3fa572f53ea8fef1cc85e535a2983dea87e9154fac2"
|
||||
"checksum webpki-roots 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "155d4060e5befdf3a6076bd28c22513473d9900b763c9e4521acc6f78a75415c"
|
||||
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
description = "Parity Ethereum client"
|
||||
name = "parity"
|
||||
# NOTE Make sure to update util/version/Cargo.toml as well
|
||||
version = "1.10.5"
|
||||
version = "1.10.3"
|
||||
license = "GPL-3.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ RUN apt-get update && \
|
||||
# evmjit dependencies
|
||||
zlib1g-dev \
|
||||
libedit-dev \
|
||||
libudev-dev &&\
|
||||
libudev-dev &&\
|
||||
# cmake and llvm ppa's. then update ppa's
|
||||
add-apt-repository -y "ppa:george-edison55/cmake-3.x" && \
|
||||
add-apt-repository "deb http://llvm.org/apt/trusty/ llvm-toolchain-trusty-3.7 main" && \
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
"eip150Transition": "0x0",
|
||||
"eip160Transition": "0x0",
|
||||
"ecip1017EraRounds": 10000000,
|
||||
|
||||
"eip161abcTransition": "0x7fffffffffffffff",
|
||||
"eip161dTransition": "0x7fffffffffffffff",
|
||||
"eip100bTransition": 2000000
|
||||
"eip161dTransition": "0x7fffffffffffffff"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -29,12 +29,7 @@
|
||||
"chainID": "0x40",
|
||||
"eip155Transition": "0x0",
|
||||
"eip98Transition": "0x7fffffffffffff",
|
||||
"eip86Transition": "0x7fffffffffffff",
|
||||
"wasmActivationTransition": 2000000,
|
||||
"eip140Transition": 2000000,
|
||||
"eip211Transition": 2000000,
|
||||
"eip214Transition": 2000000,
|
||||
"eip658Transition": 2000000
|
||||
"eip86Transition": "0x7fffffffffffff"
|
||||
},
|
||||
"genesis": {
|
||||
"seal": {
|
||||
@@ -72,10 +67,6 @@
|
||||
"0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
|
||||
"0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
|
||||
"0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
|
||||
"0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
|
||||
"0000000000000000000000000000000000000005": { "builtin": { "name": "modexp", "activate_at": 2000000, "pricing": { "modexp": { "divisor": 20 } } } },
|
||||
"0000000000000000000000000000000000000006": { "builtin": { "name": "alt_bn128_add", "activate_at": 2000000, "pricing": { "linear": { "base": 500, "word": 0 } } } },
|
||||
"0000000000000000000000000000000000000007": { "builtin": { "name": "alt_bn128_mul", "activate_at": 2000000, "pricing": { "linear": { "base": 40000, "word": 0 } } } },
|
||||
"0000000000000000000000000000000000000008": { "builtin": { "name": "alt_bn128_pairing", "activate_at": 2000000, "pricing": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 } } } }
|
||||
"0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,12 +57,6 @@ pub trait BlockProvider {
|
||||
/// (though not necessarily a part of the canon chain).
|
||||
fn is_known(&self, hash: &H256) -> bool;
|
||||
|
||||
/// Returns true if the given block is known and in the canon chain.
|
||||
fn is_canon(&self, hash: &H256) -> bool {
|
||||
let is_canon = || Some(hash == &self.block_hash(self.block_number(hash)?)?);
|
||||
is_canon().unwrap_or(false)
|
||||
}
|
||||
|
||||
/// Get the first block of the best part of the chain.
|
||||
/// Return `None` if there is no gap and the first block is the genesis.
|
||||
/// Any queries of blocks which precede this one are not guaranteed to
|
||||
@@ -159,7 +153,7 @@ pub trait BlockProvider {
|
||||
fn blocks_with_bloom(&self, bloom: &Bloom, from_block: BlockNumber, to_block: BlockNumber) -> Vec<BlockNumber>;
|
||||
|
||||
/// Returns logs matching given filter.
|
||||
fn logs<F>(&self, blocks: Vec<H256>, matches: F, limit: Option<usize>) -> Vec<LocalizedLogEntry>
|
||||
fn logs<F>(&self, blocks: Vec<BlockNumber>, matches: F, limit: Option<usize>) -> Vec<LocalizedLogEntry>
|
||||
where F: Fn(&LogEntry) -> bool + Send + Sync, Self: Sized;
|
||||
}
|
||||
|
||||
@@ -366,18 +360,16 @@ impl BlockProvider for BlockChain {
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Returns logs matching given filter. The order of logs returned will be the same as the order of the blocks
|
||||
/// provided. And it's the callers responsibility to sort blocks provided in advance.
|
||||
fn logs<F>(&self, mut blocks: Vec<H256>, matches: F, limit: Option<usize>) -> Vec<LocalizedLogEntry>
|
||||
fn logs<F>(&self, mut blocks: Vec<BlockNumber>, matches: F, limit: Option<usize>) -> Vec<LocalizedLogEntry>
|
||||
where F: Fn(&LogEntry) -> bool + Send + Sync, Self: Sized {
|
||||
// sort in reverse order
|
||||
blocks.reverse();
|
||||
blocks.sort_by(|a, b| b.cmp(a));
|
||||
|
||||
let mut logs = blocks
|
||||
.chunks(128)
|
||||
.flat_map(move |blocks_chunk| {
|
||||
blocks_chunk.into_par_iter()
|
||||
.filter_map(|hash| self.block_number(&hash).map(|r| (r, hash)))
|
||||
.filter_map(|number| self.block_hash(*number).map(|hash| (*number, hash)))
|
||||
.filter_map(|(number, hash)| self.block_receipts(&hash).map(|r| (number, hash, r.receipts)))
|
||||
.filter_map(|(number, hash, receipts)| self.block_body(&hash).map(|ref b| (number, hash, receipts, b.transaction_hashes())))
|
||||
.flat_map(|(number, hash, mut receipts, mut hashes)| {
|
||||
@@ -404,7 +396,7 @@ impl BlockProvider for BlockChain {
|
||||
.enumerate()
|
||||
.map(move |(i, log)| LocalizedLogEntry {
|
||||
entry: log,
|
||||
block_hash: *hash,
|
||||
block_hash: hash,
|
||||
block_number: number,
|
||||
transaction_hash: tx_hash,
|
||||
// iterating in reverse order
|
||||
@@ -1965,33 +1957,17 @@ mod tests {
|
||||
value: 103.into(),
|
||||
data: "601080600c6000396000f3006000355415600957005b60203560003555".from_hex().unwrap(),
|
||||
}.sign(&secret(), None);
|
||||
let t4 = Transaction {
|
||||
nonce: 0.into(),
|
||||
gas_price: 0.into(),
|
||||
gas: 100_000.into(),
|
||||
action: Action::Create,
|
||||
value: 104.into(),
|
||||
data: "601080600c6000396000f3006000355415600957005b60203560003555".from_hex().unwrap(),
|
||||
}.sign(&secret(), None);
|
||||
let tx_hash1 = t1.hash();
|
||||
let tx_hash2 = t2.hash();
|
||||
let tx_hash3 = t3.hash();
|
||||
let tx_hash4 = t4.hash();
|
||||
|
||||
let genesis = BlockBuilder::genesis();
|
||||
let b1 = genesis.add_block_with_transactions(vec![t1, t2]);
|
||||
let b2 = b1.add_block_with_transactions(iter::once(t3));
|
||||
let b3 = genesis.add_block_with(|| BlockOptions {
|
||||
transactions: vec![t4.clone()],
|
||||
difficulty: U256::from(9),
|
||||
..Default::default()
|
||||
}); // Branch block
|
||||
let b1_hash = b1.last().hash();
|
||||
let b1_number = b1.last().number();
|
||||
let b2_hash = b2.last().hash();
|
||||
let b2_number = b2.last().number();
|
||||
let b3_hash = b3.last().hash();
|
||||
let b3_number = b3.last().number();
|
||||
|
||||
let db = new_db();
|
||||
let bc = new_chain(&genesis.last().encoded(), db.clone());
|
||||
@@ -2022,21 +1998,10 @@ mod tests {
|
||||
],
|
||||
}
|
||||
]);
|
||||
insert_block(&db, &bc, &b3.last().encoded(), vec![
|
||||
Receipt {
|
||||
outcome: TransactionOutcome::StateRoot(H256::default()),
|
||||
gas_used: 10_000.into(),
|
||||
log_bloom: Default::default(),
|
||||
logs: vec![
|
||||
LogEntry { address: Default::default(), topics: vec![], data: vec![5], },
|
||||
],
|
||||
}
|
||||
]);
|
||||
|
||||
// when
|
||||
let logs1 = bc.logs(vec![b1_hash, b2_hash], |_| true, None);
|
||||
let logs2 = bc.logs(vec![b1_hash, b2_hash], |_| true, Some(1));
|
||||
let logs3 = bc.logs(vec![b3_hash], |_| true, None);
|
||||
let logs1 = bc.logs(vec![1, 2], |_| true, None);
|
||||
let logs2 = bc.logs(vec![1, 2], |_| true, Some(1));
|
||||
|
||||
// then
|
||||
assert_eq!(logs1, vec![
|
||||
@@ -2088,17 +2053,6 @@ mod tests {
|
||||
log_index: 0,
|
||||
}
|
||||
]);
|
||||
assert_eq!(logs3, vec![
|
||||
LocalizedLogEntry {
|
||||
entry: LogEntry { address: Default::default(), topics: vec![], data: vec![5] },
|
||||
block_hash: b3_hash,
|
||||
block_number: b3_number,
|
||||
transaction_hash: tx_hash4,
|
||||
transaction_index: 0,
|
||||
transaction_log_index: 0,
|
||||
log_index: 0,
|
||||
}
|
||||
]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use std::collections::{HashSet, HashMap, BTreeMap, BTreeSet, VecDeque};
|
||||
use std::collections::{HashSet, HashMap, BTreeMap, VecDeque};
|
||||
use std::str::FromStr;
|
||||
use std::sync::{Arc, Weak};
|
||||
use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering};
|
||||
@@ -1666,83 +1666,23 @@ impl BlockChainClient for Client {
|
||||
}
|
||||
|
||||
fn logs(&self, filter: Filter) -> Vec<LocalizedLogEntry> {
|
||||
// Wrap the logic inside a closure so that we can take advantage of question mark syntax.
|
||||
let fetch_logs = || {
|
||||
let chain = self.chain.read();
|
||||
|
||||
// First, check whether `filter.from_block` and `filter.to_block` is on the canon chain. If so, we can use the
|
||||
// optimized version.
|
||||
let is_canon = |id| {
|
||||
match id {
|
||||
&BlockId::Pending => true,
|
||||
// If it is referred by number, then it is always on the canon chain.
|
||||
&BlockId::Earliest | &BlockId::Latest | &BlockId::Number(_) => true,
|
||||
// If it is referred by hash, we see whether a hash -> number -> hash conversion gives us the same
|
||||
// result.
|
||||
&BlockId::Hash(ref hash) => chain.is_canon(hash),
|
||||
}
|
||||
};
|
||||
|
||||
let blocks = if is_canon(&filter.from_block) && is_canon(&filter.to_block) {
|
||||
// If we are on the canon chain, use bloom filter to fetch required hashes.
|
||||
let from = self.block_number_ref(&filter.from_block)?;
|
||||
let to = self.block_number_ref(&filter.to_block)?;
|
||||
|
||||
filter.bloom_possibilities().iter()
|
||||
.map(|bloom| {
|
||||
chain.blocks_with_bloom(bloom, from, to)
|
||||
})
|
||||
.flat_map(|m| m)
|
||||
// remove duplicate elements
|
||||
.collect::<BTreeSet<u64>>()
|
||||
.into_iter()
|
||||
.filter_map(|n| chain.block_hash(n))
|
||||
.collect::<Vec<H256>>()
|
||||
|
||||
} else {
|
||||
// Otherwise, we use a slower version that finds a link between from_block and to_block.
|
||||
let from_hash = Self::block_hash(&chain, &*self.miner, filter.from_block)?;
|
||||
let from_number = chain.block_number(&from_hash)?;
|
||||
let to_hash = Self::block_hash(&chain, &*self.miner, filter.from_block)?;
|
||||
|
||||
let blooms = filter.bloom_possibilities();
|
||||
let bloom_match = |header: &encoded::Header| {
|
||||
blooms.iter().any(|bloom| header.log_bloom().contains_bloom(bloom))
|
||||
};
|
||||
|
||||
let (blocks, last_hash) = {
|
||||
let mut blocks = Vec::new();
|
||||
let mut current_hash = to_hash;
|
||||
|
||||
loop {
|
||||
let header = chain.block_header_data(¤t_hash)?;
|
||||
if bloom_match(&header) {
|
||||
blocks.push(current_hash);
|
||||
}
|
||||
|
||||
// Stop if `from` block is reached.
|
||||
if header.number() <= from_number {
|
||||
break;
|
||||
}
|
||||
current_hash = header.parent_hash();
|
||||
}
|
||||
|
||||
blocks.reverse();
|
||||
(blocks, current_hash)
|
||||
};
|
||||
|
||||
// Check if we've actually reached the expected `from` block.
|
||||
if last_hash != from_hash || blocks.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
blocks
|
||||
};
|
||||
|
||||
Some(self.chain.read().logs(blocks, |entry| filter.matches(entry), filter.limit))
|
||||
let (from, to) = match (self.block_number_ref(&filter.from_block), self.block_number_ref(&filter.to_block)) {
|
||||
(Some(from), Some(to)) => (from, to),
|
||||
_ => return Vec::new(),
|
||||
};
|
||||
|
||||
fetch_logs().unwrap_or_default()
|
||||
let chain = self.chain.read();
|
||||
let blocks = filter.bloom_possibilities().iter()
|
||||
.map(move |bloom| {
|
||||
chain.blocks_with_bloom(bloom, from, to)
|
||||
})
|
||||
.flat_map(|m| m)
|
||||
// remove duplicate elements
|
||||
.collect::<HashSet<u64>>()
|
||||
.into_iter()
|
||||
.collect::<Vec<u64>>();
|
||||
|
||||
self.chain.read().logs(blocks, |entry| filter.matches(entry), filter.limit)
|
||||
}
|
||||
|
||||
fn filter_traces(&self, filter: TraceFilter) -> Option<Vec<LocalizedTrace>> {
|
||||
|
||||
@@ -428,14 +428,8 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> {
|
||||
self.state.discard_checkpoint();
|
||||
output.write(0, &builtin_out_buffer);
|
||||
|
||||
// Trace only top level calls and calls with balance transfer to builtins. The reason why we don't
|
||||
// trace all internal calls to builtin contracts is that memcpy (IDENTITY) is a heavily used
|
||||
// function.
|
||||
let is_transferred = match params.value {
|
||||
ActionValue::Transfer(value) => value != U256::zero(),
|
||||
ActionValue::Apparent(_) => false,
|
||||
};
|
||||
if self.depth == 0 || is_transferred {
|
||||
// trace only top level calls to builtins to avoid DDoS attacks
|
||||
if self.depth == 0 {
|
||||
let mut trace_output = tracer.prepare_trace_output();
|
||||
if let Some(out) = trace_output.as_mut() {
|
||||
*out = output.to_owned();
|
||||
@@ -728,12 +722,6 @@ mod tests {
|
||||
machine
|
||||
}
|
||||
|
||||
fn make_byzantium_machine(max_depth: usize) -> EthereumMachine {
|
||||
let mut machine = ::ethereum::new_byzantium_test_machine();
|
||||
machine.set_schedule_creation_rules(Box::new(move |s, _| s.max_depth = max_depth));
|
||||
machine
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_contract_address() {
|
||||
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
|
||||
@@ -826,76 +814,6 @@ mod tests {
|
||||
assert_eq!(substate.contracts_created.len(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_call_to_precompiled_tracing() {
|
||||
// code:
|
||||
//
|
||||
// 60 00 - push 00 out size
|
||||
// 60 00 - push 00 out offset
|
||||
// 60 00 - push 00 in size
|
||||
// 60 00 - push 00 in offset
|
||||
// 60 01 - push 01 value
|
||||
// 60 03 - push 03 to
|
||||
// 61 ffff - push fff gas
|
||||
// f1 - CALL
|
||||
|
||||
let code = "60006000600060006001600361fffff1".from_hex().unwrap();
|
||||
let sender = Address::from_str("4444444444444444444444444444444444444444").unwrap();
|
||||
let address = Address::from_str("5555555555555555555555555555555555555555").unwrap();
|
||||
|
||||
let mut params = ActionParams::default();
|
||||
params.address = address.clone();
|
||||
params.code_address = address.clone();
|
||||
params.sender = sender.clone();
|
||||
params.origin = sender.clone();
|
||||
params.gas = U256::from(100_000);
|
||||
params.code = Some(Arc::new(code));
|
||||
params.value = ActionValue::Transfer(U256::from(100));
|
||||
params.call_type = CallType::Call;
|
||||
let mut state = get_temp_state();
|
||||
state.add_balance(&sender, &U256::from(100), CleanupMode::NoEmpty).unwrap();
|
||||
let info = EnvInfo::default();
|
||||
let machine = make_byzantium_machine(5);
|
||||
let mut substate = Substate::new();
|
||||
let mut tracer = ExecutiveTracer::default();
|
||||
let mut vm_tracer = ExecutiveVMTracer::toplevel();
|
||||
|
||||
let mut ex = Executive::new(&mut state, &info, &machine);
|
||||
let output = BytesRef::Fixed(&mut[0u8;0]);
|
||||
ex.call(params, &mut substate, output, &mut tracer, &mut vm_tracer).unwrap();
|
||||
|
||||
assert_eq!(tracer.drain(), vec![FlatTrace {
|
||||
action: trace::Action::Call(trace::Call {
|
||||
from: "4444444444444444444444444444444444444444".into(),
|
||||
to: "5555555555555555555555555555555555555555".into(),
|
||||
value: 100.into(),
|
||||
gas: 100_000.into(),
|
||||
input: vec![],
|
||||
call_type: CallType::Call
|
||||
}),
|
||||
result: trace::Res::Call(trace::CallResult {
|
||||
gas_used: 33021.into(),
|
||||
output: vec![]
|
||||
}),
|
||||
subtraces: 1,
|
||||
trace_address: Default::default()
|
||||
}, FlatTrace {
|
||||
action: trace::Action::Call(trace::Call {
|
||||
from: "5555555555555555555555555555555555555555".into(),
|
||||
to: "0000000000000000000000000000000000000003".into(),
|
||||
value: 1.into(),
|
||||
gas: 66560.into(),
|
||||
input: vec![],
|
||||
call_type: CallType::Call
|
||||
}), result: trace::Res::Call(trace::CallResult {
|
||||
gas_used: 600.into(),
|
||||
output: vec![]
|
||||
}),
|
||||
subtraces: 0,
|
||||
trace_address: vec![0].into_iter().collect(),
|
||||
}]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
// Tracing is not suported in JIT
|
||||
fn test_call_to_create() {
|
||||
|
||||
@@ -709,7 +709,7 @@ impl Spec {
|
||||
author: *genesis.author(),
|
||||
timestamp: genesis.timestamp(),
|
||||
difficulty: *genesis.difficulty(),
|
||||
gas_limit: U256::max_value(),
|
||||
gas_limit: *genesis.gas_limit(),
|
||||
last_hashes: Arc::new(Vec::new()),
|
||||
gas_used: 0.into(),
|
||||
};
|
||||
@@ -718,7 +718,7 @@ impl Spec {
|
||||
let tx = Transaction {
|
||||
nonce: self.engine.account_start_nonce(0),
|
||||
action: Action::Call(a),
|
||||
gas: U256::max_value(),
|
||||
gas: U256::from(50_000_000), // TODO: share with client.
|
||||
gas_price: U256::default(),
|
||||
value: U256::default(),
|
||||
data: d,
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
use std::cell::{RefCell, RefMut};
|
||||
use std::collections::hash_map::Entry;
|
||||
use std::collections::{HashMap, BTreeMap, BTreeSet, HashSet};
|
||||
use std::collections::{HashMap, BTreeMap, HashSet};
|
||||
use std::fmt;
|
||||
use std::sync::Arc;
|
||||
use hash::{KECCAK_NULL_RLP, KECCAK_EMPTY};
|
||||
@@ -833,65 +833,40 @@ impl<B: Backend> State<B> {
|
||||
}))
|
||||
}
|
||||
|
||||
/// Populate a PodAccount map from this state, with another state as the account and storage query.
|
||||
pub fn to_pod_diff<X: Backend>(&mut self, query: &State<X>) -> trie::Result<PodState> {
|
||||
// Return a list of all touched addresses in cache.
|
||||
fn touched_addresses(&self) -> Vec<Address> {
|
||||
assert!(self.checkpoints.borrow().is_empty());
|
||||
self.cache.borrow().iter().map(|(add, _)| *add).collect()
|
||||
}
|
||||
|
||||
// Merge PodAccount::to_pod for cache of self and `query`.
|
||||
let all_addresses = self.cache.borrow().keys().cloned()
|
||||
.chain(query.cache.borrow().keys().cloned())
|
||||
.collect::<BTreeSet<_>>();
|
||||
fn query_pod(&mut self, query: &PodState, touched_addresses: &[Address]) -> trie::Result<()> {
|
||||
let pod = query.get();
|
||||
|
||||
Ok(PodState::from(all_addresses.into_iter().fold(Ok(BTreeMap::new()), |m: trie::Result<_>, address| {
|
||||
let mut m = m?;
|
||||
|
||||
let account = self.ensure_cached(&address, RequireCache::Code, true, |acc| {
|
||||
acc.map(|acc| {
|
||||
// Merge all modified storage keys.
|
||||
let all_keys = {
|
||||
let self_keys = acc.storage_changes().keys().cloned()
|
||||
.collect::<BTreeSet<_>>();
|
||||
|
||||
if let Some(ref query_storage) = query.cache.borrow().get(&address)
|
||||
.and_then(|opt| {
|
||||
Some(opt.account.as_ref()?.storage_changes().keys().cloned()
|
||||
.collect::<BTreeSet<_>>())
|
||||
})
|
||||
{
|
||||
self_keys.union(&query_storage).cloned().collect::<Vec<_>>()
|
||||
} else {
|
||||
self_keys.into_iter().collect::<Vec<_>>()
|
||||
}
|
||||
};
|
||||
|
||||
// Storage must be fetched after ensure_cached to avoid borrow problem.
|
||||
(*acc.balance(), *acc.nonce(), all_keys, acc.code().map(|x| x.to_vec()))
|
||||
})
|
||||
})?;
|
||||
|
||||
if let Some((balance, nonce, storage_keys, code)) = account {
|
||||
let storage = storage_keys.into_iter().fold(Ok(BTreeMap::new()), |s: trie::Result<_>, key| {
|
||||
let mut s = s?;
|
||||
|
||||
s.insert(key, self.storage_at(&address, &key)?);
|
||||
Ok(s)
|
||||
})?;
|
||||
|
||||
m.insert(address, PodAccount {
|
||||
balance, nonce, storage, code
|
||||
});
|
||||
for address in touched_addresses {
|
||||
if !self.ensure_cached(address, RequireCache::Code, true, |a| a.is_some())? {
|
||||
continue
|
||||
}
|
||||
|
||||
Ok(m)
|
||||
})?))
|
||||
if let Some(pod_account) = pod.get(address) {
|
||||
// needs to be split into two parts for the refcell code here
|
||||
// to work.
|
||||
for key in pod_account.storage.keys() {
|
||||
self.storage_at(address, key)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns a `StateDiff` describing the difference from `orig` to `self`.
|
||||
/// Consumes self.
|
||||
pub fn diff_from<X: Backend>(&self, mut orig: State<X>) -> trie::Result<StateDiff> {
|
||||
pub fn diff_from<X: Backend>(&self, orig: State<X>) -> trie::Result<StateDiff> {
|
||||
let addresses_post = self.touched_addresses();
|
||||
let pod_state_post = self.to_pod();
|
||||
let pod_state_pre = orig.to_pod_diff(self)?;
|
||||
Ok(pod_state::diff_pod(&pod_state_pre, &pod_state_post))
|
||||
let mut state_pre = orig;
|
||||
state_pre.query_pod(&pod_state_post, &addresses_post)?;
|
||||
Ok(pod_state::diff_pod(&state_pre.to_pod(), &pod_state_post))
|
||||
}
|
||||
|
||||
// load required account data from the databases.
|
||||
@@ -2234,6 +2209,9 @@ mod tests {
|
||||
let original = state.clone();
|
||||
state.kill_account(&a);
|
||||
|
||||
assert_eq!(original.touched_addresses(), vec![]);
|
||||
assert_eq!(state.touched_addresses(), vec![a]);
|
||||
|
||||
let diff = state.diff_from(original).unwrap();
|
||||
let diff_map = diff.get();
|
||||
assert_eq!(diff_map.len(), 1);
|
||||
@@ -2246,42 +2224,4 @@ mod tests {
|
||||
storage: Default::default()
|
||||
}), None).as_ref());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_trace_diff_unmodified_storage() {
|
||||
use pod_account;
|
||||
|
||||
let a = 10.into();
|
||||
let db = get_temp_state_db();
|
||||
|
||||
let (root, db) = {
|
||||
let mut state = State::new(db, U256::from(0), Default::default());
|
||||
state.set_storage(&a, H256::from(&U256::from(1u64)), H256::from(&U256::from(20u64))).unwrap();
|
||||
state.commit().unwrap();
|
||||
state.drop()
|
||||
};
|
||||
|
||||
let mut state = State::from_existing(db, root, U256::from(0u8), Default::default()).unwrap();
|
||||
let original = state.clone();
|
||||
state.set_storage(&a, H256::from(&U256::from(1u64)), H256::from(&U256::from(100u64))).unwrap();
|
||||
|
||||
let diff = state.diff_from(original).unwrap();
|
||||
let diff_map = diff.get();
|
||||
assert_eq!(diff_map.len(), 1);
|
||||
assert!(diff_map.get(&a).is_some());
|
||||
assert_eq!(diff_map.get(&a),
|
||||
pod_account::diff_pod(Some(&PodAccount {
|
||||
balance: U256::zero(),
|
||||
nonce: U256::zero(),
|
||||
code: Some(Default::default()),
|
||||
storage: vec![(H256::from(&U256::from(1u64)), H256::from(&U256::from(20u64)))]
|
||||
.into_iter().collect(),
|
||||
}), Some(&PodAccount {
|
||||
balance: U256::zero(),
|
||||
nonce: U256::zero(),
|
||||
code: Some(Default::default()),
|
||||
storage: vec![(H256::from(&U256::from(1u64)), H256::from(&U256::from(100u64)))]
|
||||
.into_iter().collect(),
|
||||
})).as_ref());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -458,7 +458,7 @@ mod tests {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn logs<F>(&self, _blocks: Vec<H256>, _matches: F, _limit: Option<usize>) -> Vec<LocalizedLogEntry>
|
||||
fn logs<F>(&self, _blocks: Vec<BlockNumber>, _matches: F, _limit: Option<usize>) -> Vec<LocalizedLogEntry>
|
||||
where F: Fn(&LogEntry) -> bool, Self: Sized {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
@@ -11,5 +11,5 @@ parity-wasm = "0.27"
|
||||
libc = "0.2"
|
||||
pwasm-utils = "0.1"
|
||||
vm = { path = "../vm" }
|
||||
wasmi = { version = "0.1.3", features = ["opt-in-32bit"] }
|
||||
ethcore-logger = { path = "../../logger" }
|
||||
wasmi = { version = "0.2" }
|
||||
|
||||
@@ -462,7 +462,7 @@
|
||||
<key>OVERWRITE_PERMISSIONS</key>
|
||||
<false/>
|
||||
<key>VERSION</key>
|
||||
<string>1.10.5</string>
|
||||
<string>1.10.3</string>
|
||||
</dict>
|
||||
<key>UUID</key>
|
||||
<string>2DCD5B81-7BAF-4DA1-9251-6274B089FD36</string>
|
||||
|
||||
@@ -3,4 +3,6 @@
|
||||
test -f /usr/local/libexec/uninstall-parity.sh && /usr/local/libexec/uninstall-parity.sh || true
|
||||
killall -9 parity && sleep 5
|
||||
su $USER -c "open /Applications/Parity\ Ethereum.app"
|
||||
sleep 5
|
||||
su $USER -c "open http://127.0.0.1:8180/"
|
||||
exit 0
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
!define DESCRIPTION "Fast, light, robust Ethereum implementation"
|
||||
!define VERSIONMAJOR 1
|
||||
!define VERSIONMINOR 10
|
||||
!define VERSIONBUILD 5
|
||||
!define VERSIONBUILD 3
|
||||
!define ARGS ""
|
||||
!define FIRST_START_ARGS "--mode=passive ui"
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ fn new(n: NewAccount) -> Result<String, String> {
|
||||
let secret_store = Box::new(secret_store(dir, Some(n.iterations))?);
|
||||
let acc_provider = AccountProvider::new(secret_store, AccountProviderSettings::default());
|
||||
let new_account = acc_provider.new_account(&password).map_err(|e| format!("Could not create new account: {}", e))?;
|
||||
Ok(format!("0x{:x}", new_account))
|
||||
Ok(format!("0x{:?}", new_account))
|
||||
}
|
||||
|
||||
fn list(list_cmd: ListAccounts) -> Result<String, String> {
|
||||
@@ -103,7 +103,7 @@ fn list(list_cmd: ListAccounts) -> Result<String, String> {
|
||||
let acc_provider = AccountProvider::new(secret_store, AccountProviderSettings::default());
|
||||
let accounts = acc_provider.accounts().map_err(|e| format!("{}", e))?;
|
||||
let result = accounts.into_iter()
|
||||
.map(|a| format!("0x{:x}", a))
|
||||
.map(|a| format!("0x{:?}", a))
|
||||
.collect::<Vec<String>>()
|
||||
.join("\n");
|
||||
|
||||
|
||||
@@ -129,8 +129,9 @@ impl LightFetch {
|
||||
}
|
||||
}
|
||||
BlockId::Hash(h) => {
|
||||
let idx = reqs.len();
|
||||
reqs.push(request::HeaderByHash(h.into()).into());
|
||||
|
||||
let idx = reqs.len();
|
||||
Ok(HeaderRef::Unresolved(idx, h.into()))
|
||||
}
|
||||
_ => Err(errors::unknown_block()) // latest, earliest, and pending will have all already returned.
|
||||
|
||||
@@ -230,18 +230,6 @@ fn eth_get_block() {
|
||||
assert_eq!(tester.handler.handle_request_sync(req_block).unwrap(), res_block);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn eth_get_block_by_hash() {
|
||||
let chain = extract_chain!("BlockchainTests/bcGasPricerTest/RPC_API_Test");
|
||||
let tester = EthTester::from_chain(&chain);
|
||||
|
||||
// We're looking for block number 4 from "RPC_API_Test_Frontier"
|
||||
let req_block = r#"{"method":"eth_getBlockByHash","params":["0x9c9bdab4cb53fd834e790b13545597f026494d42112e84c0aca9dd6bcc545295",false],"id":1,"jsonrpc":"2.0"}"#;
|
||||
|
||||
let res_block = r#"{"jsonrpc":"2.0","result":{"author":"0x8888f1f195afa192cfee860698584c030f4c9db1","difficulty":"0x200c0","extraData":"0x","gasLimit":"0x1dd8112","gasUsed":"0x5458","hash":"0x9c9bdab4cb53fd834e790b13545597f026494d42112e84c0aca9dd6bcc545295","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0x8888f1f195afa192cfee860698584c030f4c9db1","mixHash":"0xaddea8d25bb0f955fa6c1d58d74ab8a3fec99d37943e2a261e3b12f97d6bff7c","nonce":"0x8e18bed16d5a88da","number":"0x4","parentHash":"0x2cbf4fc930c5b4c87598f43fc8eb26dccdab2f58a7d0d3ca92ec60a5444a330e","receiptsRoot":"0x7ed8026cf72ed0e98e6fd53ab406e51ffd34397d9da0052494ff41376fda7b5f","sealFields":["0xa0addea8d25bb0f955fa6c1d58d74ab8a3fec99d37943e2a261e3b12f97d6bff7c","0x888e18bed16d5a88da"],"sha3Uncles":"0x75cc08a7cb2cf8081446659fecb2633fb6b922d26edd59bd2272b1f5cae1c78b","size":"0x661","stateRoot":"0x68805721294e365020aca15ed56c360d9dc2cf03cbeff84c9b84b8aed023bfb5","timestamp":"0x59d662ff","totalDifficulty":"0xa0180","transactions":["0xb094b9dc356dbb8b256402c6d5709288066ad6a372c90c9c516f14277545fd58"],"transactionsRoot":"0x97a593d8d7e15b57f5c6bb25bc6c325463ef99f874bc08a78656c3ab5cb23262","uncles":["0xa1e9c9ecd2af999e0723aae1dc55dd9789ca618e0b34badcc8ac7d9a3dad3af2","0x81d429b6b6635214a2b0f976cc4b2ed49808140d6bede50129bc10d22ac9249e"]},"id":1}"#;
|
||||
assert_eq!(tester.handler.handle_request_sync(req_block).unwrap(), res_block);
|
||||
}
|
||||
|
||||
// a frontier-like test with an expanded gas limit and balance on known account.
|
||||
const TRANSACTION_COUNT_SPEC: &'static [u8] = br#"{
|
||||
"name": "Frontier (Test)",
|
||||
|
||||
@@ -55,13 +55,7 @@ macro_rules! impl_uint {
|
||||
|
||||
impl fmt::LowerHex for $name {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
// TODO: remove this once updated to new version of primitives
|
||||
// including https://github.com/paritytech/primitives/pull/33
|
||||
// replace with `::core::fmt::LowerHex::fmt(self.0, f)`
|
||||
if f.alternate() {
|
||||
write!(f, "0x");
|
||||
}
|
||||
write!(f, "{:x}", self.0)
|
||||
write!(f, "{:#x}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,19 +102,19 @@ impl_uint!(U64, u64, 1);
|
||||
|
||||
impl serde::Serialize for U128 {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
|
||||
serializer.serialize_str(&format!("{:#x}", self))
|
||||
serializer.serialize_str(&format!("0x{:x}", self.0))
|
||||
}
|
||||
}
|
||||
|
||||
impl serde::Serialize for U256 {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
|
||||
serializer.serialize_str(&format!("{:#x}", self))
|
||||
serializer.serialize_str(&format!("0x{:x}", self.0))
|
||||
}
|
||||
}
|
||||
|
||||
impl serde::Serialize for U64 {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
|
||||
serializer.serialize_str(&format!("{:#x}", self))
|
||||
serializer.serialize_str(&format!("0x{:x}", self.0))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -309,12 +309,11 @@ case $BUILD_PLATFORM in
|
||||
x86_64-unknown-snap-gnu)
|
||||
ARC="amd64"
|
||||
EXT="snap"
|
||||
apt update
|
||||
apt install -y expect zip rhash
|
||||
snapcraft clean
|
||||
echo "Prepare snapcraft.yaml for build on Gitlab CI in Docker image"
|
||||
sed -i 's/git/'"$VER"'/g' snap/snapcraft.yaml
|
||||
if [[ "$CI_BUILD_REF_NAME" = "stable" || "$VER" == *1.10* ]];
|
||||
if [[ "$CI_BUILD_REF_NAME" = "beta" || "$VER" == *1.11* ]];
|
||||
then
|
||||
sed -i -e 's/grade: devel/grade: stable/' snap/snapcraft.yaml;
|
||||
fi
|
||||
|
||||
@@ -7,8 +7,8 @@ if [[ "$CI_COMMIT_REF_NAME" = "beta" || "$CI_COMMIT_REF_NAME" = "stable" ]]; the
|
||||
else
|
||||
export GIT_COMPARE=master;
|
||||
fi
|
||||
git fetch -a
|
||||
export RUST_FILES_MODIFIED="$(git --no-pager diff --name-only $GIT_COMPARE...$CI_COMMIT_SHA | grep -v -e ^\\. -e ^LICENSE -e ^README.md -e ^test.sh -e ^windows/ -e ^scripts/ -e ^mac/ -e ^nsis/ -e ^docs/ | wc -l)"
|
||||
export RUST_FILES_MODIFIED="$(git --no-pager diff --name-only $GIT_COMPARE...$CI_COMMIT_SHA | grep -v -e ^\\. -e ^LICENSE -e ^README.md -e ^test.sh -e ^windows/ -e ^scripts/ -e ^mac/ -e ^nsis/ | wc -l)"
|
||||
echo "RUST_FILES_MODIFIED: $RUST_FILES_MODIFIED"
|
||||
echo "RUST_FILES_MODIFIED: $RUST_FILES_MODIFIED"
|
||||
TEST_SWITCH=$1
|
||||
rust_test () {
|
||||
|
||||
@@ -56,7 +56,7 @@ enum RemoveFrom {
|
||||
/// the removals actually take effect.
|
||||
///
|
||||
/// journal format:
|
||||
/// ```text
|
||||
/// ```
|
||||
/// [era, 0] => [ id, [insert_0, ...], [remove_0, ...] ]
|
||||
/// [era, 1] => [ id, [insert_0, ...], [remove_0, ...] ]
|
||||
/// [era, n] => [ ... ]
|
||||
@@ -75,7 +75,7 @@ enum RemoveFrom {
|
||||
/// which includes an original key, if any.
|
||||
///
|
||||
/// The semantics of the `counter` are:
|
||||
/// ```text
|
||||
/// ```
|
||||
/// insert key k:
|
||||
/// counter already contains k: count += 1
|
||||
/// counter doesn't contain k:
|
||||
@@ -91,7 +91,7 @@ enum RemoveFrom {
|
||||
///
|
||||
/// Practically, this means that for each commit block turning from recent to ancient we do the
|
||||
/// following:
|
||||
/// ```text
|
||||
/// ```
|
||||
/// is_canonical:
|
||||
/// inserts: Ignored (left alone in the backing database).
|
||||
/// deletes: Enacted; however, recent history queue is checked for ongoing references. This is
|
||||
|
||||
@@ -39,7 +39,7 @@ use bytes::Bytes;
|
||||
/// the removals actually take effect.
|
||||
///
|
||||
/// journal format:
|
||||
/// ```text
|
||||
/// ```
|
||||
/// [era, 0] => [ id, [insert_0, ...], [remove_0, ...] ]
|
||||
/// [era, 1] => [ id, [insert_0, ...], [remove_0, ...] ]
|
||||
/// [era, n] => [ ... ]
|
||||
|
||||
@@ -227,13 +227,10 @@ pub struct NetworkContext<'s> {
|
||||
|
||||
impl<'s> NetworkContext<'s> {
|
||||
/// Create a new network IO access point. Takes references to all the data that can be updated within the IO handler.
|
||||
fn new(
|
||||
io: &'s IoContext<NetworkIoMessage>,
|
||||
fn new(io: &'s IoContext<NetworkIoMessage>,
|
||||
protocol: ProtocolId,
|
||||
session: Option<SharedSession>,
|
||||
sessions: Arc<RwLock<Slab<SharedSession>>>,
|
||||
reserved_peers: &'s HashSet<NodeId>,
|
||||
) -> NetworkContext<'s> {
|
||||
session: Option<SharedSession>, sessions: Arc<RwLock<Slab<SharedSession>>>,
|
||||
reserved_peers: &'s HashSet<NodeId>) -> NetworkContext<'s> {
|
||||
let id = session.as_ref().map(|s| s.lock().token());
|
||||
NetworkContext {
|
||||
io: io,
|
||||
@@ -725,8 +722,10 @@ impl Host {
|
||||
let address = {
|
||||
let mut nodes = self.nodes.write();
|
||||
if let Some(node) = nodes.get_mut(id) {
|
||||
node.attempts += 1;
|
||||
node.endpoint.address
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
debug!(target: "network", "Connection to expired node aborted");
|
||||
return;
|
||||
}
|
||||
@@ -738,7 +737,6 @@ impl Host {
|
||||
},
|
||||
Err(e) => {
|
||||
debug!(target: "network", "{}: Can't connect to address {:?}: {:?}", id, address, e);
|
||||
self.nodes.write().note_failure(&id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -824,17 +822,12 @@ impl Host {
|
||||
Err(e) => {
|
||||
let s = session.lock();
|
||||
trace!(target: "network", "Session read error: {}:{:?} ({:?}) {:?}", token, s.id(), s.remote_addr(), e);
|
||||
match *e.kind() {
|
||||
ErrorKind::Disconnect(DisconnectReason::IncompatibleProtocol) | ErrorKind::Disconnect(DisconnectReason::UselessPeer) => {
|
||||
if let Some(id) = s.id() {
|
||||
if !self.reserved_nodes.read().contains(id) {
|
||||
let mut nodes = self.nodes.write();
|
||||
nodes.note_failure(&id);
|
||||
nodes.mark_as_useless(id);
|
||||
}
|
||||
if let ErrorKind::Disconnect(DisconnectReason::IncompatibleProtocol) = *e.kind() {
|
||||
if let Some(id) = s.id() {
|
||||
if !self.reserved_nodes.read().contains(id) {
|
||||
self.nodes.write().mark_as_useless(id);
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
kill = true;
|
||||
break;
|
||||
@@ -898,10 +891,6 @@ impl Host {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Note connection success
|
||||
self.nodes.write().note_success(&id);
|
||||
|
||||
for (p, _) in self.handlers.read().iter() {
|
||||
if s.have_capability(*p) {
|
||||
ready_data.push(*p);
|
||||
@@ -1173,9 +1162,7 @@ impl IoHandler<NetworkIoMessage> for Host {
|
||||
if let Some(session) = session {
|
||||
session.lock().disconnect(io, DisconnectReason::DisconnectRequested);
|
||||
if let Some(id) = session.lock().id() {
|
||||
let mut nodes = self.nodes.write();
|
||||
nodes.note_failure(&id);
|
||||
nodes.mark_as_useless(id);
|
||||
self.nodes.write().mark_as_useless(id)
|
||||
}
|
||||
}
|
||||
trace!(target: "network", "Disabling peer {}", peer);
|
||||
|
||||
@@ -21,8 +21,6 @@ use std::net::{SocketAddr, ToSocketAddrs, SocketAddrV4, SocketAddrV6, Ipv4Addr,
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
use std::{fs, mem, slice};
|
||||
use std::time::{self, Duration, SystemTime};
|
||||
use rand::{self, Rng};
|
||||
use ethereum_types::H512;
|
||||
use rlp::*;
|
||||
use error::{Error, ErrorKind};
|
||||
@@ -130,64 +128,40 @@ impl FromStr for NodeEndpoint {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||
#[derive(PartialEq, Eq, Copy, Clone)]
|
||||
pub enum PeerType {
|
||||
_Required,
|
||||
Optional
|
||||
}
|
||||
|
||||
/// A type for representing an interaction (contact) with a node at a given time
|
||||
/// that was either a success or a failure.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum NodeContact {
|
||||
Success(SystemTime),
|
||||
Failure(SystemTime),
|
||||
}
|
||||
|
||||
impl NodeContact {
|
||||
fn success() -> NodeContact {
|
||||
NodeContact::Success(SystemTime::now())
|
||||
}
|
||||
|
||||
fn failure() -> NodeContact {
|
||||
NodeContact::Failure(SystemTime::now())
|
||||
}
|
||||
|
||||
fn time(&self) -> SystemTime {
|
||||
match *self {
|
||||
NodeContact::Success(t) | NodeContact::Failure(t) => t
|
||||
}
|
||||
}
|
||||
|
||||
/// Filters and old contact, returning `None` if it happened longer than a
|
||||
/// week ago.
|
||||
fn recent(&self) -> Option<&NodeContact> {
|
||||
let t = self.time();
|
||||
if let Ok(d) = t.elapsed() {
|
||||
if d < Duration::from_secs(60 * 60 * 24 * 7) {
|
||||
return Some(self);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Node {
|
||||
pub id: NodeId,
|
||||
pub endpoint: NodeEndpoint,
|
||||
pub peer_type: PeerType,
|
||||
pub last_contact: Option<NodeContact>,
|
||||
pub attempts: u32,
|
||||
pub failures: u32,
|
||||
}
|
||||
|
||||
const DEFAULT_FAILURE_PERCENTAGE: usize = 50;
|
||||
|
||||
impl Node {
|
||||
pub fn new(id: NodeId, endpoint: NodeEndpoint) -> Node {
|
||||
Node {
|
||||
id: id,
|
||||
endpoint: endpoint,
|
||||
peer_type: PeerType::Optional,
|
||||
last_contact: None,
|
||||
attempts: 0,
|
||||
failures: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the node's failure percentage (0..100) in buckets of 5%. If there are 0 connection attempts for this
|
||||
/// node the default failure percentage is returned (50%).
|
||||
pub fn failure_percentage(&self) -> usize {
|
||||
if self.attempts == 0 {
|
||||
DEFAULT_FAILURE_PERCENTAGE
|
||||
} else {
|
||||
(self.failures * 100 / self.attempts / 5 * 5) as usize
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -217,7 +191,8 @@ impl FromStr for Node {
|
||||
id: id,
|
||||
endpoint: endpoint,
|
||||
peer_type: PeerType::Optional,
|
||||
last_contact: None,
|
||||
attempts: 0,
|
||||
failures: 0,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -256,61 +231,28 @@ impl NodeTable {
|
||||
|
||||
/// Add a node to table
|
||||
pub fn add_node(&mut self, mut node: Node) {
|
||||
// preserve node last_contact
|
||||
node.last_contact = self.nodes.get(&node.id).and_then(|n| n.last_contact);
|
||||
// preserve attempts and failure counter
|
||||
let (attempts, failures) =
|
||||
self.nodes.get(&node.id).map_or((0, 0), |n| (n.attempts, n.failures));
|
||||
|
||||
node.attempts = attempts;
|
||||
node.failures = failures;
|
||||
|
||||
self.nodes.insert(node.id.clone(), node);
|
||||
}
|
||||
|
||||
/// Returns a list of ordered nodes according to their most recent contact
|
||||
/// and filtering useless nodes. The algorithm for creating the sorted nodes
|
||||
/// is:
|
||||
/// - Contacts that aren't recent (older than 1 week) are discarded
|
||||
/// - (1) Nodes with a successful contact are ordered (most recent success first)
|
||||
/// - (2) Nodes with unknown contact (older than 1 week or new nodes) are randomly shuffled
|
||||
/// - (3) Nodes with a failed contact are ordered (oldest failure first)
|
||||
/// - The final result is the concatenation of (1), (2) and (3)
|
||||
fn ordered_entries(&self) -> Vec<&Node> {
|
||||
let mut success = Vec::new();
|
||||
let mut failures = Vec::new();
|
||||
let mut unknown = Vec::new();
|
||||
let mut refs: Vec<&Node> = self.nodes.values()
|
||||
.filter(|n| !self.useless_nodes.contains(&n.id))
|
||||
.collect();
|
||||
|
||||
let nodes = self.nodes.values()
|
||||
.filter(|n| !self.useless_nodes.contains(&n.id));
|
||||
|
||||
for node in nodes {
|
||||
// discard contact points older that aren't recent
|
||||
match node.last_contact.as_ref().and_then(|c| c.recent()) {
|
||||
Some(&NodeContact::Success(_)) => {
|
||||
success.push(node);
|
||||
},
|
||||
Some(&NodeContact::Failure(_)) => {
|
||||
failures.push(node);
|
||||
},
|
||||
None => {
|
||||
unknown.push(node);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
success.sort_by(|a, b| {
|
||||
let a = a.last_contact.expect("vector only contains values with defined last_contact; qed");
|
||||
let b = b.last_contact.expect("vector only contains values with defined last_contact; qed");
|
||||
// inverse ordering, most recent successes come first
|
||||
b.time().cmp(&a.time())
|
||||
refs.sort_by(|a, b| {
|
||||
a.failure_percentage().cmp(&b.failure_percentage())
|
||||
.then_with(|| a.failures.cmp(&b.failures))
|
||||
.then_with(|| b.attempts.cmp(&a.attempts)) // we use reverse ordering for number of attempts
|
||||
});
|
||||
|
||||
failures.sort_by(|a, b| {
|
||||
let a = a.last_contact.expect("vector only contains values with defined last_contact; qed");
|
||||
let b = b.last_contact.expect("vector only contains values with defined last_contact; qed");
|
||||
// normal ordering, most distant failures come first
|
||||
a.time().cmp(&b.time())
|
||||
});
|
||||
|
||||
rand::thread_rng().shuffle(&mut unknown);
|
||||
|
||||
success.append(&mut unknown);
|
||||
success.append(&mut failures);
|
||||
success
|
||||
refs
|
||||
}
|
||||
|
||||
/// Returns node ids sorted by failure percentage, for nodes with the same failure percentage the absolute number of
|
||||
@@ -354,17 +296,10 @@ impl NodeTable {
|
||||
}
|
||||
}
|
||||
|
||||
/// Set last contact as failure for a node
|
||||
/// Increase failure counte for a node
|
||||
pub fn note_failure(&mut self, id: &NodeId) {
|
||||
if let Some(node) = self.nodes.get_mut(id) {
|
||||
node.last_contact = Some(NodeContact::failure());
|
||||
}
|
||||
}
|
||||
|
||||
/// Set last contact as success for a node
|
||||
pub fn note_success(&mut self, id: &NodeId) {
|
||||
if let Some(node) = self.nodes.get_mut(id) {
|
||||
node.last_contact = Some(NodeContact::success());
|
||||
node.failures += 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -461,38 +396,19 @@ mod json {
|
||||
pub nodes: Vec<Node>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub enum NodeContact {
|
||||
#[serde(rename = "success")]
|
||||
Success(u64),
|
||||
#[serde(rename = "failure")]
|
||||
Failure(u64),
|
||||
}
|
||||
|
||||
impl NodeContact {
|
||||
pub fn into_node_contact(self) -> super::NodeContact {
|
||||
match self {
|
||||
NodeContact::Success(s) => super::NodeContact::Success(
|
||||
time::UNIX_EPOCH + Duration::from_secs(s)
|
||||
),
|
||||
NodeContact::Failure(s) => super::NodeContact::Failure(
|
||||
time::UNIX_EPOCH + Duration::from_secs(s)
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Node {
|
||||
pub url: String,
|
||||
pub last_contact: Option<NodeContact>,
|
||||
pub attempts: u32,
|
||||
pub failures: u32,
|
||||
}
|
||||
|
||||
impl Node {
|
||||
pub fn into_node(self) -> Option<super::Node> {
|
||||
match super::Node::from_str(&self.url) {
|
||||
Ok(mut node) => {
|
||||
node.last_contact = self.last_contact.map(|c| c.into_node_contact());
|
||||
node.attempts = self.attempts;
|
||||
node.failures = self.failures;
|
||||
Some(node)
|
||||
},
|
||||
_ => None,
|
||||
@@ -502,18 +418,10 @@ mod json {
|
||||
|
||||
impl<'a> From<&'a super::Node> for Node {
|
||||
fn from(node: &'a super::Node) -> Self {
|
||||
let last_contact = node.last_contact.and_then(|c| {
|
||||
match c {
|
||||
super::NodeContact::Success(t) =>
|
||||
t.duration_since(time::UNIX_EPOCH).ok().map(|d| NodeContact::Success(d.as_secs())),
|
||||
super::NodeContact::Failure(t) =>
|
||||
t.duration_since(time::UNIX_EPOCH).ok().map(|d| NodeContact::Failure(d.as_secs())),
|
||||
}
|
||||
});
|
||||
|
||||
Node {
|
||||
url: format!("{}", node),
|
||||
last_contact
|
||||
attempts: node.attempts,
|
||||
failures: node.failures,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -556,54 +464,42 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn table_last_contact_order() {
|
||||
fn table_failure_percentage_order() {
|
||||
let node1 = Node::from_str("enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@22.99.55.44:7770").unwrap();
|
||||
let node2 = Node::from_str("enode://b979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@22.99.55.44:7770").unwrap();
|
||||
let node3 = Node::from_str("enode://c979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@22.99.55.44:7770").unwrap();
|
||||
let node4 = Node::from_str("enode://d979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@22.99.55.44:7770").unwrap();
|
||||
let node5 = Node::from_str("enode://e979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@22.99.55.44:7770").unwrap();
|
||||
let node6 = Node::from_str("enode://f979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@22.99.55.44:7770").unwrap();
|
||||
let id1 = H512::from_str("a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c").unwrap();
|
||||
let id2 = H512::from_str("b979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c").unwrap();
|
||||
let id3 = H512::from_str("c979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c").unwrap();
|
||||
let id4 = H512::from_str("d979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c").unwrap();
|
||||
let id5 = H512::from_str("e979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c").unwrap();
|
||||
let id6 = H512::from_str("f979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c").unwrap();
|
||||
let mut table = NodeTable::new(None);
|
||||
|
||||
table.add_node(node1);
|
||||
table.add_node(node2);
|
||||
table.add_node(node3);
|
||||
table.add_node(node4);
|
||||
table.add_node(node5);
|
||||
table.add_node(node6);
|
||||
|
||||
// failures - nodes 1 & 2
|
||||
// node 1 - failure percentage 100%
|
||||
table.get_mut(&id1).unwrap().attempts = 2;
|
||||
table.note_failure(&id1);
|
||||
table.note_failure(&id1);
|
||||
|
||||
// node2 - failure percentage 33%
|
||||
table.get_mut(&id2).unwrap().attempts = 3;
|
||||
table.note_failure(&id2);
|
||||
|
||||
// success - nodes 3 & 4
|
||||
table.note_success(&id3);
|
||||
table.note_success(&id4);
|
||||
// node3 - failure percentage 0%
|
||||
table.get_mut(&id3).unwrap().attempts = 1;
|
||||
|
||||
// success - node 5 (old contact)
|
||||
table.get_mut(&id5).unwrap().last_contact = Some(NodeContact::Success(time::UNIX_EPOCH));
|
||||
|
||||
// unknown - node 6
|
||||
// node4 - failure percentage 50% (default when no attempts)
|
||||
|
||||
let r = table.nodes(IpFilter::default());
|
||||
|
||||
assert_eq!(r[0][..], id4[..]); // most recent success
|
||||
assert_eq!(r[1][..], id3[..]);
|
||||
|
||||
// unknown (old contacts and new nodes), randomly shuffled
|
||||
assert!(
|
||||
r[2][..] == id5[..] && r[3][..] == id6[..] ||
|
||||
r[2][..] == id6[..] && r[3][..] == id5[..]
|
||||
);
|
||||
|
||||
assert_eq!(r[4][..], id1[..]); // oldest failure
|
||||
assert_eq!(r[5][..], id2[..]);
|
||||
assert_eq!(r[0][..], id3[..]);
|
||||
assert_eq!(r[1][..], id2[..]);
|
||||
assert_eq!(r[2][..], id4[..]);
|
||||
assert_eq!(r[3][..], id1[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -611,27 +507,23 @@ mod tests {
|
||||
let tempdir = TempDir::new("").unwrap();
|
||||
let node1 = Node::from_str("enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@22.99.55.44:7770").unwrap();
|
||||
let node2 = Node::from_str("enode://b979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@22.99.55.44:7770").unwrap();
|
||||
let node3 = Node::from_str("enode://c979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@22.99.55.44:7770").unwrap();
|
||||
let id1 = H512::from_str("a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c").unwrap();
|
||||
let id2 = H512::from_str("b979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c").unwrap();
|
||||
let id3 = H512::from_str("c979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c").unwrap();
|
||||
|
||||
{
|
||||
let mut table = NodeTable::new(Some(tempdir.path().to_str().unwrap().to_owned()));
|
||||
table.add_node(node1);
|
||||
table.add_node(node2);
|
||||
table.add_node(node3);
|
||||
|
||||
table.note_success(&id2);
|
||||
table.note_failure(&id3);
|
||||
table.get_mut(&id1).unwrap().attempts = 1;
|
||||
table.get_mut(&id2).unwrap().attempts = 1;
|
||||
table.note_failure(&id2);
|
||||
}
|
||||
|
||||
{
|
||||
let table = NodeTable::new(Some(tempdir.path().to_str().unwrap().to_owned()));
|
||||
let r = table.nodes(IpFilter::default());
|
||||
assert_eq!(r[0][..], id2[..]); // latest success
|
||||
assert_eq!(r[1][..], id1[..]); // unknown
|
||||
assert_eq!(r[2][..], id3[..]); // oldest failure
|
||||
assert_eq!(r[0][..], id1[..]);
|
||||
assert_eq!(r[1][..], id2[..]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
[package]
|
||||
name = "parity-version"
|
||||
# NOTE: this value is used for Parity version string (via env CARGO_PKG_VERSION)
|
||||
version = "1.10.5"
|
||||
version = "1.10.3"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
build = "build.rs"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user