Backports for beta 2.2.5 (#10047)
* bump beta to 2.2.5 * Fix empty steps (#9939) * Don't send empty step twice or empty step then block. * Perform basic validation of locally sealed blocks. * Don't include empty step twice. * Strict empty steps validation (#10041) * Add two failings tests for strict empty steps. * Implement strict validation of empty steps. * ethcore: enable constantinople on ethereum (#10031) * ethcore: change blockreward to 2e18 for foundation after constantinople * ethcore: delay diff bomb by 2e6 blocks for foundation after constantinople * ethcore: enable eip-{145,1014,1052,1283} for foundation after constantinople * Change test miner max memory to malloc reports. (#10024) * Fix: test corpus_inaccessible panic (#10019) If system uptime is less than the duration in the test, thread will panic due to: 'overflow when subtracting duration from instant'. Changed duration to 20 seconds to make it unlikely the test will fail due to this condition. Since no operations that carry a similar risk of panic occur outside of the tests, it doesn't seem warranted to depend on an external crate to fix this. * Bump crossbeam. (#10048)
This commit is contained in:
parent
f44d885b6d
commit
7fbcdfeed4
70
Cargo.lock
generated
70
Cargo.lock
generated
@ -286,8 +286,26 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam"
|
name = "crossbeam"
|
||||||
version = "0.3.2"
|
version = "0.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-channel 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam-deque 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam-epoch 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-channel"
|
||||||
|
version = "0.2.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-epoch 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-deque"
|
name = "crossbeam-deque"
|
||||||
@ -298,6 +316,15 @@ dependencies = [
|
|||||||
"crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-deque"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-epoch 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-deque"
|
name = "crossbeam-deque"
|
||||||
version = "0.6.1"
|
version = "0.6.1"
|
||||||
@ -334,6 +361,19 @@ dependencies = [
|
|||||||
"scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-epoch"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-utils"
|
name = "crossbeam-utils"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
@ -347,6 +387,14 @@ name = "crossbeam-utils"
|
|||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-utils"
|
||||||
|
version = "0.6.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crunchy"
|
name = "crunchy"
|
||||||
version = "0.1.6"
|
version = "0.1.6"
|
||||||
@ -566,7 +614,7 @@ dependencies = [
|
|||||||
"bn 0.4.4 (git+https://github.com/paritytech/bn)",
|
"bn 0.4.4 (git+https://github.com/paritytech/bn)",
|
||||||
"byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"common-types 0.1.0",
|
"common-types 0.1.0",
|
||||||
"crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"crossbeam 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethabi 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ethabi 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -2162,7 +2210,7 @@ version = "1.12.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"jni 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"jni 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"panic_hook 0.1.0",
|
"panic_hook 0.1.0",
|
||||||
"parity-ethereum 2.2.4",
|
"parity-ethereum 2.2.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2178,7 +2226,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parity-ethereum"
|
name = "parity-ethereum"
|
||||||
version = "2.2.4"
|
version = "2.2.5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -2227,7 +2275,7 @@ dependencies = [
|
|||||||
"parity-rpc-client 1.4.0",
|
"parity-rpc-client 1.4.0",
|
||||||
"parity-runtime 0.1.0",
|
"parity-runtime 0.1.0",
|
||||||
"parity-updater 1.12.0",
|
"parity-updater 1.12.0",
|
||||||
"parity-version 2.2.4",
|
"parity-version 2.2.5",
|
||||||
"parity-whisper 0.1.0",
|
"parity-whisper 0.1.0",
|
||||||
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -2382,7 +2430,7 @@ dependencies = [
|
|||||||
"parity-crypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parity-crypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parity-runtime 0.1.0",
|
"parity-runtime 0.1.0",
|
||||||
"parity-updater 1.12.0",
|
"parity-updater 1.12.0",
|
||||||
"parity-version 2.2.4",
|
"parity-version 2.2.5",
|
||||||
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"patricia-trie 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"patricia-trie 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pretty_assertions 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -2479,7 +2527,7 @@ dependencies = [
|
|||||||
"parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parity-hash-fetch 1.12.0",
|
"parity-hash-fetch 1.12.0",
|
||||||
"parity-path 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parity-path 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parity-version 2.2.4",
|
"parity-version 2.2.5",
|
||||||
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -2489,7 +2537,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parity-version"
|
name = "parity-version"
|
||||||
version = "2.2.4"
|
version = "2.2.5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parity-bytes 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rlp 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -4067,13 +4115,17 @@ dependencies = [
|
|||||||
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
||||||
"checksum cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "6ec65ee4f9c9d16f335091d23693457ed4928657ba4982289d7fafee03bc614a"
|
"checksum cmake 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "6ec65ee4f9c9d16f335091d23693457ed4928657ba4982289d7fafee03bc614a"
|
||||||
"checksum combine 3.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fc1d011beeed29187b8db2ac3925c8dd4d3e87db463dc9d2d2833985388fc5bc"
|
"checksum combine 3.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fc1d011beeed29187b8db2ac3925c8dd4d3e87db463dc9d2d2833985388fc5bc"
|
||||||
"checksum crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24ce9782d4d5c53674646a6a4c1863a21a8fc0cb649b3c94dfc16e45071dea19"
|
"checksum crossbeam 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d7408247b1b87f480890f28b670c5f8d9a8a4274833433fe74dc0dfd46d33650"
|
||||||
|
"checksum crossbeam-channel 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7b85741761b7f160bc5e7e0c14986ef685b7f8bf9b7ad081c60c604bb4649827"
|
||||||
"checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3"
|
"checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3"
|
||||||
|
"checksum crossbeam-deque 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7792c4a9b5a4222f654e3728a3dd945aacc24d2c3a1a096ed265d80e4929cb9a"
|
||||||
"checksum crossbeam-deque 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3486aefc4c0487b9cb52372c97df0a48b8c249514af1ee99703bf70d2f2ceda1"
|
"checksum crossbeam-deque 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3486aefc4c0487b9cb52372c97df0a48b8c249514af1ee99703bf70d2f2ceda1"
|
||||||
"checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150"
|
"checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150"
|
||||||
"checksum crossbeam-epoch 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "30fecfcac6abfef8771151f8be4abc9e4edc112c2bcb233314cafde2680536e9"
|
"checksum crossbeam-epoch 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "30fecfcac6abfef8771151f8be4abc9e4edc112c2bcb233314cafde2680536e9"
|
||||||
|
"checksum crossbeam-epoch 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2449aaa4ec7ef96e5fb24db16024b935df718e9ae1cec0a1e68feeca2efca7b8"
|
||||||
"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
|
"checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
|
||||||
"checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015"
|
"checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015"
|
||||||
|
"checksum crossbeam-utils 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e07fc155212827475223f0bcfae57e945e694fc90950ddf3f6695bbfd5555c72"
|
||||||
"checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda"
|
"checksum crunchy 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a2f4a431c5c9f662e1200b7c7f02c34e91361150e382089a8f2dec3ba680cbda"
|
||||||
"checksum crunchy 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c240f247c278fa08a6d4820a6a222bfc6e0d999e51ba67be94f44c905b2161f2"
|
"checksum crunchy 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c240f247c278fa08a6d4820a6a222bfc6e0d999e51ba67be94f44c905b2161f2"
|
||||||
"checksum ct-logs 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "95a4bf5107667e12bf6ce31a3a5066d67acc88942b6742117a41198734aaccaa"
|
"checksum ct-logs 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "95a4bf5107667e12bf6ce31a3a5066d67acc88942b6742117a41198734aaccaa"
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
description = "Parity Ethereum client"
|
description = "Parity Ethereum client"
|
||||||
name = "parity-ethereum"
|
name = "parity-ethereum"
|
||||||
# NOTE Make sure to update util/version/Cargo.toml as well
|
# NOTE Make sure to update util/version/Cargo.toml as well
|
||||||
version = "2.2.4"
|
version = "2.2.5"
|
||||||
license = "GPL-3.0"
|
license = "GPL-3.0"
|
||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ blooms-db = { path = "../util/blooms-db" }
|
|||||||
bn = { git = "https://github.com/paritytech/bn", default-features = false }
|
bn = { git = "https://github.com/paritytech/bn", default-features = false }
|
||||||
byteorder = "1.0"
|
byteorder = "1.0"
|
||||||
common-types = { path = "types" }
|
common-types = { path = "types" }
|
||||||
crossbeam = "0.3"
|
crossbeam = "0.4"
|
||||||
ethash = { path = "../ethash" }
|
ethash = { path = "../ethash" }
|
||||||
ethcore-bloom-journal = { path = "../util/bloom" }
|
ethcore-bloom-journal = { path = "../util/bloom" }
|
||||||
parity-bytes = "0.1"
|
parity-bytes = "0.1"
|
||||||
|
@ -179,14 +179,15 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn corpus_inaccessible() {
|
fn corpus_inaccessible() {
|
||||||
let mut cache = Cache::new(Default::default(), Duration::from_secs(5 * 3600));
|
let duration = Duration::from_secs(20);
|
||||||
|
let mut cache = Cache::new(Default::default(), duration.clone());
|
||||||
|
|
||||||
cache.set_gas_price_corpus(vec![].into());
|
cache.set_gas_price_corpus(vec![].into());
|
||||||
assert_eq!(cache.gas_price_corpus(), Some(vec![].into()));
|
assert_eq!(cache.gas_price_corpus(), Some(vec![].into()));
|
||||||
|
|
||||||
{
|
{
|
||||||
let corpus_time = &mut cache.corpus.as_mut().unwrap().1;
|
let corpus_time = &mut cache.corpus.as_mut().unwrap().1;
|
||||||
*corpus_time = *corpus_time - Duration::from_secs(6 * 3600);
|
*corpus_time = *corpus_time - duration;
|
||||||
}
|
}
|
||||||
assert!(cache.gas_price_corpus().is_none());
|
assert!(cache.gas_price_corpus().is_none());
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,8 @@
|
|||||||
"durationLimit": "0x0d",
|
"durationLimit": "0x0d",
|
||||||
"blockReward": {
|
"blockReward": {
|
||||||
"0": "0x4563918244F40000",
|
"0": "0x4563918244F40000",
|
||||||
"4370000": "0x29A2241AF62C0000"
|
"4370000": "0x29A2241AF62C0000",
|
||||||
|
"7080000": "0x1BC16D674EC80000"
|
||||||
},
|
},
|
||||||
"homesteadTransition": "0x118c30",
|
"homesteadTransition": "0x118c30",
|
||||||
"daoHardforkTransition": "0x1d4c00",
|
"daoHardforkTransition": "0x1d4c00",
|
||||||
@ -134,7 +135,8 @@
|
|||||||
],
|
],
|
||||||
"eip100bTransition": 4370000,
|
"eip100bTransition": 4370000,
|
||||||
"difficultyBombDelays": {
|
"difficultyBombDelays": {
|
||||||
"4370000": 3000000
|
"4370000": 3000000,
|
||||||
|
"7080000": 2000000
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -159,7 +161,11 @@
|
|||||||
"eip140Transition": 4370000,
|
"eip140Transition": 4370000,
|
||||||
"eip211Transition": 4370000,
|
"eip211Transition": 4370000,
|
||||||
"eip214Transition": 4370000,
|
"eip214Transition": 4370000,
|
||||||
"eip658Transition": 4370000
|
"eip658Transition": 4370000,
|
||||||
|
"eip145Transition": 7080000,
|
||||||
|
"eip1014Transition": 7080000,
|
||||||
|
"eip1052Transition": 7080000,
|
||||||
|
"eip1283Transition": 7080000
|
||||||
},
|
},
|
||||||
"genesis": {
|
"genesis": {
|
||||||
"seal": {
|
"seal": {
|
||||||
|
@ -2305,11 +2305,7 @@ impl ScheduleInfo for Client {
|
|||||||
impl ImportSealedBlock for Client {
|
impl ImportSealedBlock for Client {
|
||||||
fn import_sealed_block(&self, block: SealedBlock) -> EthcoreResult<H256> {
|
fn import_sealed_block(&self, block: SealedBlock) -> EthcoreResult<H256> {
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
let raw = block.rlp_bytes();
|
|
||||||
let header = block.header().clone();
|
let header = block.header().clone();
|
||||||
let hash = header.hash();
|
|
||||||
self.notify(|n| n.block_pre_import(&raw, &hash, header.difficulty()));
|
|
||||||
|
|
||||||
let route = {
|
let route = {
|
||||||
// Do a super duper basic verification to detect potential bugs
|
// Do a super duper basic verification to detect potential bugs
|
||||||
if let Err(e) = self.engine.verify_block_basic(&header) {
|
if let Err(e) = self.engine.verify_block_basic(&header) {
|
||||||
@ -2327,14 +2323,15 @@ impl ImportSealedBlock for Client {
|
|||||||
let block_data = block.rlp_bytes();
|
let block_data = block.rlp_bytes();
|
||||||
|
|
||||||
let route = self.importer.commit_block(block, &header, encoded::Block::new(block_data), self);
|
let route = self.importer.commit_block(block, &header, encoded::Block::new(block_data), self);
|
||||||
trace!(target: "client", "Imported sealed block #{} ({})", header.number(), hash);
|
trace!(target: "client", "Imported sealed block #{} ({})", header.number(), header.hash());
|
||||||
self.state_db.write().sync_cache(&route.enacted, &route.retracted, false);
|
self.state_db.write().sync_cache(&route.enacted, &route.retracted, false);
|
||||||
route
|
route
|
||||||
};
|
};
|
||||||
|
let h = header.hash();
|
||||||
let route = ChainRoute::from([route].as_ref());
|
let route = ChainRoute::from([route].as_ref());
|
||||||
self.importer.miner.chain_new_blocks(
|
self.importer.miner.chain_new_blocks(
|
||||||
self,
|
self,
|
||||||
&[hash],
|
&[h],
|
||||||
&[],
|
&[],
|
||||||
route.enacted(),
|
route.enacted(),
|
||||||
route.retracted(),
|
route.retracted(),
|
||||||
@ -2342,16 +2339,16 @@ impl ImportSealedBlock for Client {
|
|||||||
);
|
);
|
||||||
self.notify(|notify| {
|
self.notify(|notify| {
|
||||||
notify.new_blocks(
|
notify.new_blocks(
|
||||||
vec![hash],
|
vec![h],
|
||||||
vec![],
|
vec![],
|
||||||
route.clone(),
|
route.clone(),
|
||||||
vec![hash],
|
vec![h],
|
||||||
vec![],
|
vec![],
|
||||||
start.elapsed(),
|
start.elapsed(),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
self.db.read().key_value().flush().expect("DB flush failed.");
|
self.db.read().key_value().flush().expect("DB flush failed.");
|
||||||
Ok(hash)
|
Ok(h)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,6 +81,8 @@ pub struct AuthorityRoundParams {
|
|||||||
pub empty_steps_transition: u64,
|
pub empty_steps_transition: u64,
|
||||||
/// Number of accepted empty steps.
|
/// Number of accepted empty steps.
|
||||||
pub maximum_empty_steps: usize,
|
pub maximum_empty_steps: usize,
|
||||||
|
/// Transition block to strict empty steps validation.
|
||||||
|
pub strict_empty_steps_transition: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
const U16_MAX: usize = ::std::u16::MAX as usize;
|
const U16_MAX: usize = ::std::u16::MAX as usize;
|
||||||
@ -110,6 +112,7 @@ impl From<ethjson::spec::AuthorityRoundParams> for AuthorityRoundParams {
|
|||||||
maximum_uncle_count: p.maximum_uncle_count.map_or(0, Into::into),
|
maximum_uncle_count: p.maximum_uncle_count.map_or(0, Into::into),
|
||||||
empty_steps_transition: p.empty_steps_transition.map_or(u64::max_value(), |n| ::std::cmp::max(n.into(), 1)),
|
empty_steps_transition: p.empty_steps_transition.map_or(u64::max_value(), |n| ::std::cmp::max(n.into(), 1)),
|
||||||
maximum_empty_steps: p.maximum_empty_steps.map_or(0, Into::into),
|
maximum_empty_steps: p.maximum_empty_steps.map_or(0, Into::into),
|
||||||
|
strict_empty_steps_transition: p.strict_empty_steps_transition.map_or(0, Into::into),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -421,6 +424,7 @@ pub struct AuthorityRound {
|
|||||||
maximum_uncle_count_transition: u64,
|
maximum_uncle_count_transition: u64,
|
||||||
maximum_uncle_count: usize,
|
maximum_uncle_count: usize,
|
||||||
empty_steps_transition: u64,
|
empty_steps_transition: u64,
|
||||||
|
strict_empty_steps_transition: u64,
|
||||||
maximum_empty_steps: usize,
|
maximum_empty_steps: usize,
|
||||||
machine: EthereumMachine,
|
machine: EthereumMachine,
|
||||||
}
|
}
|
||||||
@ -674,6 +678,7 @@ impl AuthorityRound {
|
|||||||
maximum_uncle_count: our_params.maximum_uncle_count,
|
maximum_uncle_count: our_params.maximum_uncle_count,
|
||||||
empty_steps_transition: our_params.empty_steps_transition,
|
empty_steps_transition: our_params.empty_steps_transition,
|
||||||
maximum_empty_steps: our_params.maximum_empty_steps,
|
maximum_empty_steps: our_params.maximum_empty_steps,
|
||||||
|
strict_empty_steps_transition: our_params.strict_empty_steps_transition,
|
||||||
machine: machine,
|
machine: machine,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1250,8 +1255,11 @@ impl Engine<EthereumMachine> for AuthorityRound {
|
|||||||
// reported as there's no way to tell whether the empty step message was never sent or simply not included.
|
// reported as there's no way to tell whether the empty step message was never sent or simply not included.
|
||||||
let empty_steps_len = if header.number() >= self.empty_steps_transition {
|
let empty_steps_len = if header.number() >= self.empty_steps_transition {
|
||||||
let validate_empty_steps = || -> Result<usize, Error> {
|
let validate_empty_steps = || -> Result<usize, Error> {
|
||||||
|
let strict_empty_steps = header.number() >= self.strict_empty_steps_transition;
|
||||||
let empty_steps = header_empty_steps(header)?;
|
let empty_steps = header_empty_steps(header)?;
|
||||||
let empty_steps_len = empty_steps.len();
|
let empty_steps_len = empty_steps.len();
|
||||||
|
let mut prev_empty_step = 0;
|
||||||
|
|
||||||
for empty_step in empty_steps {
|
for empty_step in empty_steps {
|
||||||
if empty_step.step <= parent_step || empty_step.step >= step {
|
if empty_step.step <= parent_step || empty_step.step >= step {
|
||||||
Err(EngineError::InsufficientProof(
|
Err(EngineError::InsufficientProof(
|
||||||
@ -1267,7 +1275,20 @@ impl Engine<EthereumMachine> for AuthorityRound {
|
|||||||
Err(EngineError::InsufficientProof(
|
Err(EngineError::InsufficientProof(
|
||||||
format!("invalid empty step proof: {:?}", empty_step)))?;
|
format!("invalid empty step proof: {:?}", empty_step)))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if strict_empty_steps {
|
||||||
|
if empty_step.step <= prev_empty_step {
|
||||||
|
Err(EngineError::InsufficientProof(format!(
|
||||||
|
"{} empty step: {:?}",
|
||||||
|
if empty_step.step == prev_empty_step { "duplicate" } else { "unordered" },
|
||||||
|
empty_step
|
||||||
|
)))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prev_empty_step = empty_step.step;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(empty_steps_len)
|
Ok(empty_steps_len)
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1518,10 +1539,40 @@ mod tests {
|
|||||||
use spec::Spec;
|
use spec::Spec;
|
||||||
use transaction::{Action, Transaction};
|
use transaction::{Action, Transaction};
|
||||||
use engines::{Seal, Engine, EngineError, EthEngine};
|
use engines::{Seal, Engine, EngineError, EthEngine};
|
||||||
use engines::validator_set::TestSet;
|
use engines::validator_set::{TestSet, SimpleList};
|
||||||
use error::{Error, ErrorKind};
|
use error::{Error, ErrorKind};
|
||||||
use super::{AuthorityRoundParams, AuthorityRound, EmptyStep, SealedEmptyStep, calculate_score};
|
use super::{AuthorityRoundParams, AuthorityRound, EmptyStep, SealedEmptyStep, calculate_score};
|
||||||
|
|
||||||
|
fn aura<F>(f: F) -> Arc<AuthorityRound> where
|
||||||
|
F: FnOnce(&mut AuthorityRoundParams),
|
||||||
|
{
|
||||||
|
let mut params = AuthorityRoundParams {
|
||||||
|
step_duration: 1,
|
||||||
|
start_step: Some(1),
|
||||||
|
validators: Box::new(TestSet::default()),
|
||||||
|
validate_score_transition: 0,
|
||||||
|
validate_step_transition: 0,
|
||||||
|
immediate_transitions: true,
|
||||||
|
maximum_uncle_count_transition: 0,
|
||||||
|
maximum_uncle_count: 0,
|
||||||
|
empty_steps_transition: u64::max_value(),
|
||||||
|
maximum_empty_steps: 0,
|
||||||
|
block_reward: Default::default(),
|
||||||
|
block_reward_contract_transition: 0,
|
||||||
|
block_reward_contract: Default::default(),
|
||||||
|
strict_empty_steps_transition: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
// mutate aura params
|
||||||
|
f(&mut params);
|
||||||
|
|
||||||
|
// create engine
|
||||||
|
let mut c_params = ::spec::CommonParams::default();
|
||||||
|
c_params.gas_limit_bound_divisor = 5.into();
|
||||||
|
let machine = ::machine::EthereumMachine::regular(c_params, Default::default());
|
||||||
|
AuthorityRound::new(params, machine).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn has_valid_metadata() {
|
fn has_valid_metadata() {
|
||||||
let engine = Spec::new_test_round().engine;
|
let engine = Spec::new_test_round().engine;
|
||||||
@ -1695,28 +1746,9 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn reports_skipped() {
|
fn reports_skipped() {
|
||||||
let last_benign = Arc::new(AtomicUsize::new(0));
|
let last_benign = Arc::new(AtomicUsize::new(0));
|
||||||
let params = AuthorityRoundParams {
|
let aura = aura(|p| {
|
||||||
step_duration: 1,
|
p.validators = Box::new(TestSet::new(Default::default(), last_benign.clone()));
|
||||||
start_step: Some(1),
|
});
|
||||||
validators: Box::new(TestSet::new(Default::default(), last_benign.clone())),
|
|
||||||
validate_score_transition: 0,
|
|
||||||
validate_step_transition: 0,
|
|
||||||
immediate_transitions: true,
|
|
||||||
maximum_uncle_count_transition: 0,
|
|
||||||
maximum_uncle_count: 0,
|
|
||||||
empty_steps_transition: u64::max_value(),
|
|
||||||
maximum_empty_steps: 0,
|
|
||||||
block_reward: Default::default(),
|
|
||||||
block_reward_contract_transition: 0,
|
|
||||||
block_reward_contract: Default::default(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let aura = {
|
|
||||||
let mut c_params = ::spec::CommonParams::default();
|
|
||||||
c_params.gas_limit_bound_divisor = 5.into();
|
|
||||||
let machine = ::machine::EthereumMachine::regular(c_params, Default::default());
|
|
||||||
AuthorityRound::new(params, machine).unwrap()
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut parent_header: Header = Header::default();
|
let mut parent_header: Header = Header::default();
|
||||||
parent_header.set_seal(vec![encode(&1usize)]);
|
parent_header.set_seal(vec![encode(&1usize)]);
|
||||||
@ -1745,29 +1777,9 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_uncles_transition() {
|
fn test_uncles_transition() {
|
||||||
let last_benign = Arc::new(AtomicUsize::new(0));
|
let aura = aura(|params| {
|
||||||
let params = AuthorityRoundParams {
|
params.maximum_uncle_count_transition = 1;
|
||||||
step_duration: 1,
|
});
|
||||||
start_step: Some(1),
|
|
||||||
validators: Box::new(TestSet::new(Default::default(), last_benign.clone())),
|
|
||||||
validate_score_transition: 0,
|
|
||||||
validate_step_transition: 0,
|
|
||||||
immediate_transitions: true,
|
|
||||||
maximum_uncle_count_transition: 1,
|
|
||||||
maximum_uncle_count: 0,
|
|
||||||
empty_steps_transition: u64::max_value(),
|
|
||||||
maximum_empty_steps: 0,
|
|
||||||
block_reward: Default::default(),
|
|
||||||
block_reward_contract_transition: 0,
|
|
||||||
block_reward_contract: Default::default(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let aura = {
|
|
||||||
let mut c_params = ::spec::CommonParams::default();
|
|
||||||
c_params.gas_limit_bound_divisor = 5.into();
|
|
||||||
let machine = ::machine::EthereumMachine::regular(c_params, Default::default());
|
|
||||||
AuthorityRound::new(params, machine).unwrap()
|
|
||||||
};
|
|
||||||
|
|
||||||
assert_eq!(aura.maximum_uncle_count(0), 2);
|
assert_eq!(aura.maximum_uncle_count(0), 2);
|
||||||
assert_eq!(aura.maximum_uncle_count(1), 0);
|
assert_eq!(aura.maximum_uncle_count(1), 0);
|
||||||
@ -1801,27 +1813,9 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
#[should_panic(expected="authority_round: step duration can't be zero")]
|
#[should_panic(expected="authority_round: step duration can't be zero")]
|
||||||
fn test_step_duration_zero() {
|
fn test_step_duration_zero() {
|
||||||
let last_benign = Arc::new(AtomicUsize::new(0));
|
aura(|params| {
|
||||||
let params = AuthorityRoundParams {
|
params.step_duration = 0;
|
||||||
step_duration: 0,
|
});
|
||||||
start_step: Some(1),
|
|
||||||
validators: Box::new(TestSet::new(Default::default(), last_benign.clone())),
|
|
||||||
validate_score_transition: 0,
|
|
||||||
validate_step_transition: 0,
|
|
||||||
immediate_transitions: true,
|
|
||||||
maximum_uncle_count_transition: 0,
|
|
||||||
maximum_uncle_count: 0,
|
|
||||||
empty_steps_transition: u64::max_value(),
|
|
||||||
maximum_empty_steps: 0,
|
|
||||||
block_reward: Default::default(),
|
|
||||||
block_reward_contract_transition: 0,
|
|
||||||
block_reward_contract: Default::default(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut c_params = ::spec::CommonParams::default();
|
|
||||||
c_params.gas_limit_bound_divisor = 5.into();
|
|
||||||
let machine = ::machine::EthereumMachine::regular(c_params, Default::default());
|
|
||||||
AuthorityRound::new(params, machine).unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_empty_steps() -> (Spec, Arc<AccountProvider>, Vec<Address>) {
|
fn setup_empty_steps() -> (Spec, Arc<AccountProvider>, Vec<Address>) {
|
||||||
@ -1849,6 +1843,23 @@ mod tests {
|
|||||||
SealedEmptyStep { signature, step }
|
SealedEmptyStep { signature, step }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_empty_steps_seal(header: &mut Header, step: u64, block_signature: ðkey::Signature, empty_steps: &[SealedEmptyStep]) {
|
||||||
|
header.set_seal(vec![
|
||||||
|
encode(&(step as usize)),
|
||||||
|
encode(&(&**block_signature as &[u8])),
|
||||||
|
::rlp::encode_list(&empty_steps),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn assert_insufficient_proof<T: ::std::fmt::Debug>(result: Result<T, Error>, contains: &str) {
|
||||||
|
match result {
|
||||||
|
Err(Error(ErrorKind::Engine(EngineError::InsufficientProof(ref s)), _)) =>{
|
||||||
|
assert!(s.contains(contains), "Expected {:?} to contain {:?}", s, contains);
|
||||||
|
},
|
||||||
|
e => assert!(false, "Unexpected result: {:?}", e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn broadcast_empty_step_message() {
|
fn broadcast_empty_step_message() {
|
||||||
let (spec, tap, accounts) = setup_empty_steps();
|
let (spec, tap, accounts) = setup_empty_steps();
|
||||||
@ -2050,46 +2061,31 @@ mod tests {
|
|||||||
|
|
||||||
// empty step with invalid step
|
// empty step with invalid step
|
||||||
let empty_steps = vec![SealedEmptyStep { signature: 0.into(), step: 2 }];
|
let empty_steps = vec![SealedEmptyStep { signature: 0.into(), step: 2 }];
|
||||||
header.set_seal(vec![
|
set_empty_steps_seal(&mut header, 2, &signature, &empty_steps);
|
||||||
encode(&2usize),
|
|
||||||
encode(&(&*signature as &[u8])),
|
|
||||||
::rlp::encode_list(&empty_steps),
|
|
||||||
]);
|
|
||||||
|
|
||||||
assert!(match engine.verify_block_family(&header, &parent_header) {
|
assert_insufficient_proof(
|
||||||
Err(Error(ErrorKind::Engine(EngineError::InsufficientProof(ref s)), _))
|
engine.verify_block_family(&header, &parent_header),
|
||||||
if s.contains("invalid step") => true,
|
"invalid step"
|
||||||
_ => false,
|
);
|
||||||
});
|
|
||||||
|
|
||||||
// empty step with invalid signature
|
// empty step with invalid signature
|
||||||
let empty_steps = vec![SealedEmptyStep { signature: 0.into(), step: 1 }];
|
let empty_steps = vec![SealedEmptyStep { signature: 0.into(), step: 1 }];
|
||||||
header.set_seal(vec![
|
set_empty_steps_seal(&mut header, 2, &signature, &empty_steps);
|
||||||
encode(&2usize),
|
|
||||||
encode(&(&*signature as &[u8])),
|
|
||||||
::rlp::encode_list(&empty_steps),
|
|
||||||
]);
|
|
||||||
|
|
||||||
assert!(match engine.verify_block_family(&header, &parent_header) {
|
assert_insufficient_proof(
|
||||||
Err(Error(ErrorKind::Engine(EngineError::InsufficientProof(ref s)), _))
|
engine.verify_block_family(&header, &parent_header),
|
||||||
if s.contains("invalid empty step proof") => true,
|
"invalid empty step proof"
|
||||||
_ => false,
|
);
|
||||||
});
|
|
||||||
|
|
||||||
// empty step with valid signature from incorrect proposer for step
|
// empty step with valid signature from incorrect proposer for step
|
||||||
engine.set_signer(tap.clone(), addr1, "1".into());
|
engine.set_signer(tap.clone(), addr1, "1".into());
|
||||||
let empty_steps = vec![sealed_empty_step(engine, 1, &parent_header.hash())];
|
let empty_steps = vec![sealed_empty_step(engine, 1, &parent_header.hash())];
|
||||||
header.set_seal(vec![
|
set_empty_steps_seal(&mut header, 2, &signature, &empty_steps);
|
||||||
encode(&2usize),
|
|
||||||
encode(&(&*signature as &[u8])),
|
|
||||||
::rlp::encode_list(&empty_steps),
|
|
||||||
]);
|
|
||||||
|
|
||||||
assert!(match engine.verify_block_family(&header, &parent_header) {
|
assert_insufficient_proof(
|
||||||
Err(Error(ErrorKind::Engine(EngineError::InsufficientProof(ref s)), _))
|
engine.verify_block_family(&header, &parent_header),
|
||||||
if s.contains("invalid empty step proof") => true,
|
"invalid empty step proof"
|
||||||
_ => false,
|
);
|
||||||
});
|
|
||||||
|
|
||||||
// valid empty steps
|
// valid empty steps
|
||||||
engine.set_signer(tap.clone(), addr1, "1".into());
|
engine.set_signer(tap.clone(), addr1, "1".into());
|
||||||
@ -2100,11 +2096,7 @@ mod tests {
|
|||||||
let empty_steps = vec![empty_step2, empty_step3];
|
let empty_steps = vec![empty_step2, empty_step3];
|
||||||
header.set_difficulty(calculate_score(0, 4, 2));
|
header.set_difficulty(calculate_score(0, 4, 2));
|
||||||
let signature = tap.sign(addr1, Some("1".into()), header.bare_hash()).unwrap();
|
let signature = tap.sign(addr1, Some("1".into()), header.bare_hash()).unwrap();
|
||||||
header.set_seal(vec![
|
set_empty_steps_seal(&mut header, 4, &signature, &empty_steps);
|
||||||
encode(&4usize),
|
|
||||||
encode(&(&*signature as &[u8])),
|
|
||||||
::rlp::encode_list(&empty_steps),
|
|
||||||
]);
|
|
||||||
|
|
||||||
assert!(engine.verify_block_family(&header, &parent_header).is_ok());
|
assert!(engine.verify_block_family(&header, &parent_header).is_ok());
|
||||||
}
|
}
|
||||||
@ -2216,28 +2208,11 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_empty_steps() {
|
fn test_empty_steps() {
|
||||||
let last_benign = Arc::new(AtomicUsize::new(0));
|
let engine = aura(|p| {
|
||||||
let params = AuthorityRoundParams {
|
p.step_duration = 4;
|
||||||
step_duration: 4,
|
p.empty_steps_transition = 0;
|
||||||
start_step: Some(1),
|
p.maximum_empty_steps = 0;
|
||||||
validators: Box::new(TestSet::new(Default::default(), last_benign.clone())),
|
});
|
||||||
validate_score_transition: 0,
|
|
||||||
validate_step_transition: 0,
|
|
||||||
immediate_transitions: true,
|
|
||||||
maximum_uncle_count_transition: 0,
|
|
||||||
maximum_uncle_count: 0,
|
|
||||||
empty_steps_transition: 0,
|
|
||||||
maximum_empty_steps: 10,
|
|
||||||
block_reward: Default::default(),
|
|
||||||
block_reward_contract_transition: 0,
|
|
||||||
block_reward_contract: Default::default(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut c_params = ::spec::CommonParams::default();
|
|
||||||
c_params.gas_limit_bound_divisor = 5.into();
|
|
||||||
let machine = ::machine::EthereumMachine::regular(c_params, Default::default());
|
|
||||||
let engine = AuthorityRound::new(params, machine).unwrap();
|
|
||||||
|
|
||||||
|
|
||||||
let parent_hash: H256 = 1.into();
|
let parent_hash: H256 = 1.into();
|
||||||
let signature = H520::default();
|
let signature = H520::default();
|
||||||
@ -2261,4 +2236,85 @@ mod tests {
|
|||||||
assert_eq!(engine.empty_steps(0, 3, parent_hash), vec![]);
|
assert_eq!(engine.empty_steps(0, 3, parent_hash), vec![]);
|
||||||
assert_eq!(engine.empty_steps(0, 4, parent_hash), vec![step(3)]);
|
assert_eq!(engine.empty_steps(0, 4, parent_hash), vec![step(3)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_reject_duplicate_empty_steps() {
|
||||||
|
// given
|
||||||
|
let (_spec, tap, accounts) = setup_empty_steps();
|
||||||
|
let engine = aura(|p| {
|
||||||
|
p.validators = Box::new(SimpleList::new(accounts.clone()));
|
||||||
|
p.step_duration = 4;
|
||||||
|
p.empty_steps_transition = 0;
|
||||||
|
p.maximum_empty_steps = 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut parent = Header::default();
|
||||||
|
parent.set_seal(vec![encode(&0usize)]);
|
||||||
|
|
||||||
|
let mut header = Header::default();
|
||||||
|
header.set_number(parent.number() + 1);
|
||||||
|
header.set_parent_hash(parent.hash());
|
||||||
|
header.set_author(accounts[0]);
|
||||||
|
|
||||||
|
// when
|
||||||
|
engine.set_signer(tap.clone(), accounts[1], "0".into());
|
||||||
|
let empty_steps = vec![
|
||||||
|
sealed_empty_step(&*engine, 1, &parent.hash()),
|
||||||
|
sealed_empty_step(&*engine, 1, &parent.hash()),
|
||||||
|
];
|
||||||
|
let step = 2;
|
||||||
|
let signature = tap.sign(accounts[0], Some("1".into()), header.bare_hash()).unwrap();
|
||||||
|
set_empty_steps_seal(&mut header, step, &signature, &empty_steps);
|
||||||
|
header.set_difficulty(calculate_score(0, step, empty_steps.len()));
|
||||||
|
|
||||||
|
// then
|
||||||
|
assert_insufficient_proof(
|
||||||
|
engine.verify_block_family(&header, &parent),
|
||||||
|
"duplicate empty step"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_reject_empty_steps_out_of_order() {
|
||||||
|
// given
|
||||||
|
let (_spec, tap, accounts) = setup_empty_steps();
|
||||||
|
let engine = aura(|p| {
|
||||||
|
p.validators = Box::new(SimpleList::new(accounts.clone()));
|
||||||
|
p.step_duration = 4;
|
||||||
|
p.empty_steps_transition = 0;
|
||||||
|
p.maximum_empty_steps = 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut parent = Header::default();
|
||||||
|
parent.set_seal(vec![encode(&0usize)]);
|
||||||
|
|
||||||
|
let mut header = Header::default();
|
||||||
|
header.set_number(parent.number() + 1);
|
||||||
|
header.set_parent_hash(parent.hash());
|
||||||
|
header.set_author(accounts[0]);
|
||||||
|
|
||||||
|
// when
|
||||||
|
engine.set_signer(tap.clone(), accounts[1], "0".into());
|
||||||
|
let es1 = sealed_empty_step(&*engine, 1, &parent.hash());
|
||||||
|
engine.set_signer(tap.clone(), accounts[0], "1".into());
|
||||||
|
let es2 = sealed_empty_step(&*engine, 2, &parent.hash());
|
||||||
|
|
||||||
|
let mut empty_steps = vec![es2, es1];
|
||||||
|
|
||||||
|
let step = 3;
|
||||||
|
let signature = tap.sign(accounts[1], Some("0".into()), header.bare_hash()).unwrap();
|
||||||
|
set_empty_steps_seal(&mut header, step, &signature, &empty_steps);
|
||||||
|
header.set_difficulty(calculate_score(0, step, empty_steps.len()));
|
||||||
|
|
||||||
|
// then make sure it's rejected because of the order
|
||||||
|
assert_insufficient_proof(
|
||||||
|
engine.verify_block_family(&header, &parent),
|
||||||
|
"unordered empty step"
|
||||||
|
);
|
||||||
|
|
||||||
|
// now try to fix the order
|
||||||
|
empty_steps.reverse();
|
||||||
|
set_empty_steps_seal(&mut header, step, &signature, &empty_steps);
|
||||||
|
assert_eq!(engine.verify_block_family(&header, &parent).unwrap(), ());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,12 +34,18 @@ pub struct TestSet {
|
|||||||
last_benign: Arc<AtomicUsize>,
|
last_benign: Arc<AtomicUsize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for TestSet {
|
||||||
|
fn default() -> Self {
|
||||||
|
TestSet::new(Default::default(), Default::default())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl TestSet {
|
impl TestSet {
|
||||||
pub fn new(last_malicious: Arc<AtomicUsize>, last_benign: Arc<AtomicUsize>) -> Self {
|
pub fn new(last_malicious: Arc<AtomicUsize>, last_benign: Arc<AtomicUsize>) -> Self {
|
||||||
TestSet {
|
TestSet {
|
||||||
validator: SimpleList::new(vec![Address::from_str("7d577a597b2742b498cb5cf0c26cdcd726d39e6e").unwrap()]),
|
validator: SimpleList::new(vec![Address::from_str("7d577a597b2742b498cb5cf0c26cdcd726d39e6e").unwrap()]),
|
||||||
last_malicious: last_malicious,
|
last_malicious,
|
||||||
last_benign: last_benign,
|
last_benign,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -979,7 +979,7 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> {
|
|||||||
scope.builder().stack_size(::std::cmp::max(self.schedule.max_depth.saturating_sub(depth_threshold) * STACK_SIZE_PER_DEPTH, local_stack_size)).spawn(move || {
|
scope.builder().stack_size(::std::cmp::max(self.schedule.max_depth.saturating_sub(depth_threshold) * STACK_SIZE_PER_DEPTH, local_stack_size)).spawn(move || {
|
||||||
self.call_with_stack_depth(params, substate, stack_depth, tracer, vm_tracer)
|
self.call_with_stack_depth(params, substate, stack_depth, tracer, vm_tracer)
|
||||||
}).expect("Sub-thread creation cannot fail; the host might run out of resources; qed")
|
}).expect("Sub-thread creation cannot fail; the host might run out of resources; qed")
|
||||||
}).join()
|
}).join().expect("Sub-thread never panics; qed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1063,7 +1063,7 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> {
|
|||||||
scope.builder().stack_size(::std::cmp::max(self.schedule.max_depth.saturating_sub(depth_threshold) * STACK_SIZE_PER_DEPTH, local_stack_size)).spawn(move || {
|
scope.builder().stack_size(::std::cmp::max(self.schedule.max_depth.saturating_sub(depth_threshold) * STACK_SIZE_PER_DEPTH, local_stack_size)).spawn(move || {
|
||||||
self.create_with_stack_depth(params, substate, stack_depth, tracer, vm_tracer)
|
self.create_with_stack_depth(params, substate, stack_depth, tracer, vm_tracer)
|
||||||
}).expect("Sub-thread creation cannot fail; the host might run out of resources; qed")
|
}).expect("Sub-thread creation cannot fail; the host might run out of resources; qed")
|
||||||
}).join()
|
}).join().expect("Sub-thread never panics; qed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,11 +192,11 @@ pub fn take_snapshot<W: SnapshotWriter + Send>(
|
|||||||
state_guards.push(state_guard);
|
state_guards.push(state_guard);
|
||||||
}
|
}
|
||||||
|
|
||||||
let block_hashes = block_guard.join()?;
|
let block_hashes = block_guard.join().expect("Sub-thread never panics; qed")?;
|
||||||
let mut state_hashes = Vec::new();
|
let mut state_hashes = Vec::new();
|
||||||
|
|
||||||
for guard in state_guards {
|
for guard in state_guards {
|
||||||
let part_state_hashes = guard.join()?;
|
let part_state_hashes = guard.join().expect("Sub-thread never panics; qed")?;
|
||||||
state_hashes.extend(part_state_hashes);
|
state_hashes.extend(part_state_hashes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,6 +68,8 @@ pub struct AuthorityRoundParams {
|
|||||||
/// Maximum number of accepted empty steps.
|
/// Maximum number of accepted empty steps.
|
||||||
#[serde(rename="maximumEmptySteps")]
|
#[serde(rename="maximumEmptySteps")]
|
||||||
pub maximum_empty_steps: Option<Uint>,
|
pub maximum_empty_steps: Option<Uint>,
|
||||||
|
/// Strict validation of empty steps transition block.
|
||||||
|
pub strict_empty_steps_transition: Option<Uint>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Authority engine deserialization.
|
/// Authority engine deserialization.
|
||||||
|
@ -26,12 +26,18 @@ pub mod client;
|
|||||||
use self::tx::{Tx, TxExt, PairExt};
|
use self::tx::{Tx, TxExt, PairExt};
|
||||||
use self::client::TestClient;
|
use self::client::TestClient;
|
||||||
|
|
||||||
|
// max mem for 3 transaction, this is relative
|
||||||
|
// to the global use allocator, the value is currently
|
||||||
|
// set to reflect malloc usage.
|
||||||
|
// 50 was enough when using jmalloc.
|
||||||
|
const TEST_QUEUE_MAX_MEM: usize = 80;
|
||||||
|
|
||||||
fn new_queue() -> TransactionQueue {
|
fn new_queue() -> TransactionQueue {
|
||||||
TransactionQueue::new(
|
TransactionQueue::new(
|
||||||
txpool::Options {
|
txpool::Options {
|
||||||
max_count: 3,
|
max_count: 3,
|
||||||
max_per_sender: 3,
|
max_per_sender: 3,
|
||||||
max_mem_usage: 50
|
max_mem_usage: TEST_QUEUE_MAX_MEM
|
||||||
},
|
},
|
||||||
verifier::Options {
|
verifier::Options {
|
||||||
minimal_gas_price: 1.into(),
|
minimal_gas_price: 1.into(),
|
||||||
@ -49,7 +55,7 @@ fn should_return_correct_nonces_when_dropped_because_of_limit() {
|
|||||||
txpool::Options {
|
txpool::Options {
|
||||||
max_count: 3,
|
max_count: 3,
|
||||||
max_per_sender: 1,
|
max_per_sender: 1,
|
||||||
max_mem_usage: 50
|
max_mem_usage: TEST_QUEUE_MAX_MEM
|
||||||
},
|
},
|
||||||
verifier::Options {
|
verifier::Options {
|
||||||
minimal_gas_price: 1.into(),
|
minimal_gas_price: 1.into(),
|
||||||
@ -103,7 +109,7 @@ fn should_never_drop_local_transactions_from_different_senders() {
|
|||||||
txpool::Options {
|
txpool::Options {
|
||||||
max_count: 3,
|
max_count: 3,
|
||||||
max_per_sender: 1,
|
max_per_sender: 1,
|
||||||
max_mem_usage: 50
|
max_mem_usage: TEST_QUEUE_MAX_MEM
|
||||||
},
|
},
|
||||||
verifier::Options {
|
verifier::Options {
|
||||||
minimal_gas_price: 1.into(),
|
minimal_gas_price: 1.into(),
|
||||||
@ -477,7 +483,7 @@ fn should_prefer_current_transactions_when_hitting_the_limit() {
|
|||||||
txpool::Options {
|
txpool::Options {
|
||||||
max_count: 1,
|
max_count: 1,
|
||||||
max_per_sender: 2,
|
max_per_sender: 2,
|
||||||
max_mem_usage: 50
|
max_mem_usage: TEST_QUEUE_MAX_MEM
|
||||||
},
|
},
|
||||||
verifier::Options {
|
verifier::Options {
|
||||||
minimal_gas_price: 1.into(),
|
minimal_gas_price: 1.into(),
|
||||||
@ -707,7 +713,7 @@ fn should_accept_local_transactions_below_min_gas_price() {
|
|||||||
txpool::Options {
|
txpool::Options {
|
||||||
max_count: 3,
|
max_count: 3,
|
||||||
max_per_sender: 3,
|
max_per_sender: 3,
|
||||||
max_mem_usage: 50
|
max_mem_usage: TEST_QUEUE_MAX_MEM
|
||||||
},
|
},
|
||||||
verifier::Options {
|
verifier::Options {
|
||||||
minimal_gas_price: 10.into(),
|
minimal_gas_price: 10.into(),
|
||||||
@ -890,7 +896,7 @@ fn should_include_local_transaction_to_a_full_pool() {
|
|||||||
txpool::Options {
|
txpool::Options {
|
||||||
max_count: 1,
|
max_count: 1,
|
||||||
max_per_sender: 2,
|
max_per_sender: 2,
|
||||||
max_mem_usage: 50
|
max_mem_usage: TEST_QUEUE_MAX_MEM
|
||||||
},
|
},
|
||||||
verifier::Options {
|
verifier::Options {
|
||||||
minimal_gas_price: 1.into(),
|
minimal_gas_price: 1.into(),
|
||||||
@ -922,7 +928,7 @@ fn should_avoid_verifying_transaction_already_in_pool() {
|
|||||||
txpool::Options {
|
txpool::Options {
|
||||||
max_count: 1,
|
max_count: 1,
|
||||||
max_per_sender: 2,
|
max_per_sender: 2,
|
||||||
max_mem_usage: 50
|
max_mem_usage: TEST_QUEUE_MAX_MEM
|
||||||
},
|
},
|
||||||
verifier::Options {
|
verifier::Options {
|
||||||
minimal_gas_price: 1.into(),
|
minimal_gas_price: 1.into(),
|
||||||
@ -957,7 +963,7 @@ fn should_avoid_reverifying_recently_rejected_transactions() {
|
|||||||
txpool::Options {
|
txpool::Options {
|
||||||
max_count: 1,
|
max_count: 1,
|
||||||
max_per_sender: 2,
|
max_per_sender: 2,
|
||||||
max_mem_usage: 50
|
max_mem_usage: TEST_QUEUE_MAX_MEM
|
||||||
},
|
},
|
||||||
verifier::Options {
|
verifier::Options {
|
||||||
minimal_gas_price: 1.into(),
|
minimal_gas_price: 1.into(),
|
||||||
@ -999,7 +1005,7 @@ fn should_reject_early_in_case_gas_price_is_less_than_min_effective() {
|
|||||||
txpool::Options {
|
txpool::Options {
|
||||||
max_count: 1,
|
max_count: 1,
|
||||||
max_per_sender: 2,
|
max_per_sender: 2,
|
||||||
max_mem_usage: 50
|
max_mem_usage: TEST_QUEUE_MAX_MEM
|
||||||
},
|
},
|
||||||
verifier::Options {
|
verifier::Options {
|
||||||
minimal_gas_price: 1.into(),
|
minimal_gas_price: 1.into(),
|
||||||
@ -1039,7 +1045,7 @@ fn should_not_reject_early_in_case_gas_price_is_less_than_min_effective() {
|
|||||||
txpool::Options {
|
txpool::Options {
|
||||||
max_count: 1,
|
max_count: 1,
|
||||||
max_per_sender: 2,
|
max_per_sender: 2,
|
||||||
max_mem_usage: 50
|
max_mem_usage: TEST_QUEUE_MAX_MEM
|
||||||
},
|
},
|
||||||
verifier::Options {
|
verifier::Options {
|
||||||
minimal_gas_price: 1.into(),
|
minimal_gas_price: 1.into(),
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "parity-version"
|
name = "parity-version"
|
||||||
# NOTE: this value is used for Parity Ethereum version string (via env CARGO_PKG_VERSION)
|
# NOTE: this value is used for Parity Ethereum version string (via env CARGO_PKG_VERSION)
|
||||||
version = "2.2.4"
|
version = "2.2.5"
|
||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user