[stable] Backports (#8919)

* Fixed AuthorityRound deadlock on shutdown, closes #8088 (#8803)

* CI: Fix docker tags (#8822)

* scripts: enable docker builds for beta and stable

* scripts: docker latest should be beta not master

* scripts: docker latest is master

* Fix concurrent access to signer queue (#8854)

* Fix concurrent access to signer queue

* Put request back to the queue if confirmation failed

* typo: fix docs and rename functions to be more specific

`request_notify` does not need to be public, and it's renamed to `notify_result`.
`notify` is renamed to `notify_message`.

* Change trace info "Transaction" -> "Request"

* Add new ovh bootnodes and fix port for foundation bootnode 3.2 (#8886)

* Add new ovh bootnodes and fix port for foundation bootnode 3.2

* Remove old bootnodes.

* Remove duplicate 1118980bf48b0a3640bdba04e0fe78b1add18e1cd99bf22d53daac1fd9972ad650df52176e7c7d89d1114cfef2bc23a2959aa54998a46afcf7d91809f0855082

* Block 0 is valid in queries (#8891)

Early exit for block nr 0 leads to spurious error about pruning: `…your node is running with state pruning…`.

Fixes #7547, #8762

* update jsonrpc libs, fixed ipc leak, closes #8774 (#8876)

Instead of cherrypicking 8b78141b20b75da508ce82bccc9286e3d7858a7b, just ran cargo update -p jsonrpc-core

* Add ETC Cooperative-run load balanced parity node (#8892)

* Minor fix in chain supplier and light provider (#8906)

* fix chain supplier increment

* fix light provider block_headers
This commit is contained in:
Andrew Jones 2018-06-19 07:09:08 +01:00 committed by Afri Schoedon
parent 718b398a17
commit ba79cad670
12 changed files with 184 additions and 133 deletions

View File

@ -184,6 +184,8 @@ docker-build:
stage: build
only:
- tags
- beta
- stable
- triggers
before_script:
- docker info

63
Cargo.lock generated
View File

@ -1266,7 +1266,7 @@ dependencies = [
[[package]]
name = "jsonrpc-core"
version = "8.0.1"
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.10#b5125be0251dd3b45abe14f4e3bd57bd1f1fd45d"
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.10#2b8e5d5b42b8631009be29ea28dab98946d9d096"
dependencies = [
"futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1278,7 +1278,7 @@ dependencies = [
[[package]]
name = "jsonrpc-http-server"
version = "8.0.0"
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.10#b5125be0251dd3b45abe14f4e3bd57bd1f1fd45d"
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.10#2b8e5d5b42b8631009be29ea28dab98946d9d096"
dependencies = [
"hyper 0.11.24 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.10)",
@ -1291,7 +1291,7 @@ dependencies = [
[[package]]
name = "jsonrpc-ipc-server"
version = "8.0.0"
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.10#b5125be0251dd3b45abe14f4e3bd57bd1f1fd45d"
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.10#2b8e5d5b42b8631009be29ea28dab98946d9d096"
dependencies = [
"jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.10)",
"jsonrpc-server-utils 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.10)",
@ -1303,7 +1303,7 @@ dependencies = [
[[package]]
name = "jsonrpc-macros"
version = "8.0.0"
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.10#b5125be0251dd3b45abe14f4e3bd57bd1f1fd45d"
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.10#2b8e5d5b42b8631009be29ea28dab98946d9d096"
dependencies = [
"jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.10)",
"jsonrpc-pubsub 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.10)",
@ -1313,7 +1313,7 @@ dependencies = [
[[package]]
name = "jsonrpc-pubsub"
version = "8.0.0"
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.10#b5125be0251dd3b45abe14f4e3bd57bd1f1fd45d"
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.10#2b8e5d5b42b8631009be29ea28dab98946d9d096"
dependencies = [
"jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.10)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1323,7 +1323,7 @@ dependencies = [
[[package]]
name = "jsonrpc-server-utils"
version = "8.0.0"
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.10#b5125be0251dd3b45abe14f4e3bd57bd1f1fd45d"
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.10#2b8e5d5b42b8631009be29ea28dab98946d9d096"
dependencies = [
"bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"globset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1336,7 +1336,7 @@ dependencies = [
[[package]]
name = "jsonrpc-tcp-server"
version = "8.0.0"
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.10#b5125be0251dd3b45abe14f4e3bd57bd1f1fd45d"
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.10#2b8e5d5b42b8631009be29ea28dab98946d9d096"
dependencies = [
"jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.10)",
"jsonrpc-server-utils 8.0.0 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.10)",
@ -1348,7 +1348,7 @@ dependencies = [
[[package]]
name = "jsonrpc-ws-server"
version = "8.0.0"
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.10#b5125be0251dd3b45abe14f4e3bd57bd1f1fd45d"
source = "git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.10#2b8e5d5b42b8631009be29ea28dab98946d9d096"
dependencies = [
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-core 8.0.1 (git+https://github.com/paritytech/jsonrpc.git?branch=parity-1.10)",
@ -1620,14 +1620,13 @@ dependencies = [
[[package]]
name = "mio-named-pipes"
version = "0.1.4"
source = "git+https://github.com/alexcrichton/mio-named-pipes#9c1bbb985b74374d3b7eda76937279f8e977ef81"
version = "0.1.5"
source = "git+https://github.com/alexcrichton/mio-named-pipes#6ad80e67fe7993423b281bc13d307785ade05d37"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1650,6 +1649,15 @@ dependencies = [
"ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "miow"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"socket2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "msdos_time"
version = "0.1.5"
@ -2155,12 +2163,12 @@ dependencies = [
[[package]]
name = "parity-tokio-ipc"
version = "0.1.5"
source = "git+https://github.com/nikvolf/parity-tokio-ipc#d6c5b3cfcc913a1b9cf0f0562a10b083ceb9fb7c"
source = "git+https://github.com/nikvolf/parity-tokio-ipc#2af3e5b6b746552d8181069a2c6be068377df1de"
dependencies = [
"bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"mio-named-pipes 0.1.4 (git+https://github.com/alexcrichton/mio-named-pipes)",
"mio-named-pipes 0.1.5 (git+https://github.com/alexcrichton/mio-named-pipes)",
"miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2589,7 +2597,7 @@ dependencies = [
[[package]]
name = "redox_syscall"
version = "0.1.31"
version = "0.1.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@ -2924,6 +2932,17 @@ dependencies = [
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "socket2"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "spmc"
version = "0.2.2"
@ -3088,7 +3107,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -3132,7 +3151,7 @@ source = "git+https://github.com/nikvolf/tokio-named-pipes#0b9b728eaeb0a6673c287
dependencies = [
"bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
"mio-named-pipes 0.1.4 (git+https://github.com/alexcrichton/mio-named-pipes)",
"mio-named-pipes 0.1.5 (git+https://github.com/alexcrichton/mio-named-pipes)",
"tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -3673,9 +3692,10 @@ dependencies = [
"checksum mime_guess 2.0.0-alpha.2 (registry+https://github.com/rust-lang/crates.io-index)" = "27a5e6679a0614e25adc14c6434ba84e41632b765a6d9cb2031a0cca682699ae"
"checksum miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "609ce024854aeb19a0ef7567d348aaa5a746b32fb72e336df7fcc16869d7e2b4"
"checksum mio 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)" = "6d771e3ef92d58a8da8df7d6976bfca9371ed1de6619d9d5a5ce5b1f29b85bfe"
"checksum mio-named-pipes 0.1.4 (git+https://github.com/alexcrichton/mio-named-pipes)" = "<none>"
"checksum mio-named-pipes 0.1.5 (git+https://github.com/alexcrichton/mio-named-pipes)" = "<none>"
"checksum mio-uds 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1731a873077147b626d89cc6c2a0db6288d607496c5d10c0cfcf3adc697ec673"
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
"checksum miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9224c91f82b3c47cf53dcf78dfaa20d6888fbcc5d272d5f2fcdf8a697f3c987d"
"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"
@ -3731,7 +3751,7 @@ dependencies = [
"checksum rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b614fe08b6665cb9a231d07ac1364b0ef3cb3698f1239ee0c4c3a88a524f54c8"
"checksum rayon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed02d09394c94ffbdfdc755ad62a132e94c3224a8354e78a1200ced34df12edf"
"checksum rayon-core 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e64b609139d83da75902f88fd6c01820046840a18471e4dfcd5ac7c0f46bea53"
"checksum redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "8dde11f18c108289bef24469638a04dce49da56084f2d50618b226e47eb04509"
"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1"
"checksum regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "744554e01ccbd98fff8c457c3b092cd67af62a555a43bfe97ae8a0451f7799fa"
"checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db"
"checksum relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1576e382688d7e9deecea24417e350d3062d97e32e45d70b1cde65994ff1489a"
@ -3770,6 +3790,7 @@ dependencies = [
"checksum smallvec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8fcd03faf178110ab0334d74ca9631d77f94c8c11cc77fcb59538abf0025695d"
"checksum snappy 0.1.0 (git+https://github.com/paritytech/rust-snappy)" = "<none>"
"checksum snappy-sys 0.1.0 (git+https://github.com/paritytech/rust-snappy)" = "<none>"
"checksum socket2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "06dc9f86ee48652b7c80f3d254e3b9accb67a928c562c64d10d7b016d3d98dab"
"checksum spmc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cd1f11d1fb5fd41834e55ce0b85a186efbf2f2afd9fdb09e2c8d72f9bff1ad1a"
"checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b"
"checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"

View File

@ -54,6 +54,7 @@ pub trait Provider: Send + Sync {
/// results within must adhere to the `skip` and `reverse` parameters.
fn block_headers(&self, req: request::CompleteHeadersRequest) -> Option<request::HeadersResponse> {
use request::HashOrNumber;
const MAX_HEADERS_TO_SEND: u64 = 512;
if req.max == 0 { return None }
@ -82,10 +83,12 @@ pub trait Provider: Send + Sync {
}
};
let headers: Vec<_> = (0u64..req.max as u64)
.map(|x: u64| x.saturating_mul(req.skip + 1))
let max = ::std::cmp::min(MAX_HEADERS_TO_SEND, req.max);
let headers: Vec<_> = (0u64..max)
.map(|x: u64| x.saturating_mul(req.skip.saturating_add(1)))
.take_while(|x| if req.reverse { x < &start_num } else { best_num.saturating_sub(start_num) >= *x })
.map(|x| if req.reverse { start_num - x } else { start_num + x })
.map(|x| if req.reverse { start_num.saturating_sub(x) } else { start_num.saturating_add(x) })
.map(|x| self.block_header(BlockId::Number(x)))
.take_while(|x| x.is_some())
.flat_map(|x| x)

View File

@ -57,7 +57,8 @@
"enode://814920f1ec9510aa9ea1c8f79d8b6e6a462045f09caa2ae4055b0f34f7416fca6facd3dd45f1cf1673c0209e0503f02776b8ff94020e98b6679a0dc561b4eba0@104.154.136.117:30303",
"enode://72e445f4e89c0f476d404bc40478b0df83a5b500d2d2e850e08eb1af0cd464ab86db6160d0fde64bd77d5f0d33507ae19035671b3c74fec126d6e28787669740@104.198.71.200:30303",
"enode://39abab9d2a41f53298c0c9dc6bbca57b0840c3ba9dccf42aa27316addc1b7e56ade32a0a9f7f52d6c5db4fe74d8824bcedfeaecf1a4e533cacb71cf8100a9442@144.76.238.49:30303",
"enode://f50e675a34f471af2438b921914b5f06499c7438f3146f6b8936f1faeb50b8a91d0d0c24fb05a66f05865cd58c24da3e664d0def806172ddd0d4c5bdbf37747e@144.76.238.49:30306"
"enode://f50e675a34f471af2438b921914b5f06499c7438f3146f6b8936f1faeb50b8a91d0d0c24fb05a66f05865cd58c24da3e664d0def806172ddd0d4c5bdbf37747e@144.76.238.49:30306",
"enode://83b33409349ffa25e150555f7b4f8deebc68f3d34d782129dc3c8ba07b880c209310a4191e1725f2f6bef59bce9452d821111eaa786deab08a7e6551fca41f4f@159.89.223.6:30303"
],
"accounts": {
"0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },

View File

@ -174,16 +174,13 @@
"stateRoot": "0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544"
},
"nodes": [
"enode://81863f47e9bd652585d3f78b4b2ee07b93dad603fd9bc3c293e1244250725998adc88da0cef48f1de89b15ab92b15db8f43dc2b6fb8fbd86a6f217a1dd886701@193.70.55.37:30303",
"enode://4afb3a9137a88267c02651052cf6fb217931b8c78ee058bb86643542a4e2e0a8d24d47d871654e1b78a276c363f3c1bc89254a973b00adc359c9e9a48f140686@144.217.139.5:30303",
"enode://c16d390b32e6eb1c312849fe12601412313165df1a705757d671296f1ac8783c5cff09eab0118ac1f981d7148c85072f0f26407e5c68598f3ad49209fade404d@139.99.51.203:30303",
"enode://4faf867a2e5e740f9b874e7c7355afee58a2d1ace79f7b692f1d553a1134eddbeb5f9210dd14dc1b774a46fd5f063a8bc1fa90579e13d9d18d1f59bac4a4b16b@139.99.160.213:30303",
"enode://6a868ced2dec399c53f730261173638a93a40214cf299ccf4d42a76e3fa54701db410669e8006347a4b3a74fa090bb35af0320e4bc8d04cf5b7f582b1db285f5@163.172.131.191:30303",
"enode://66a483383882a518fcc59db6c017f9cd13c71261f13c8d7e67ed43adbbc82a932d88d2291f59be577e9425181fc08828dc916fdd053af935a9491edf9d6006ba@212.47.247.103:30303",
"enode://cd6611461840543d5b9c56fbf088736154c699c43973b3a1a32390cf27106f87e58a818a606ccb05f3866de95a4fe860786fea71bf891ea95f234480d3022aa3@163.172.157.114:30303",
"enode://78b094cb27ceeecbe311bc278f4fde8b9a265db42d268c88484c94d7a2d19b82a1bd22dfd6c2bd4d90f9b05e6d42255e6eb85de15f73848ff82ed0be9cdf5202@52.233.198.218:30303",
"enode://00526537cb7e1aa6cf49714f0635fd0f608904d8d0693b949eea2dcdfdb0abbe4c794003a5fe57aa662d0a9215e8dfa4d2deb6ef0101c5e185e2617721813d43@40.65.122.44:30303",
"enode://4a456b4b6e6ee1f51389763e51b80fe04782c762445d96c32a96ebd34bd9178c1894924d5101123eacfd4f0fc4da25b5e1ee7f18832ac0bf4c6d6ac81442d698@40.71.6.49:3030",
"enode://68f85e7403976aa92318eff804cbe9bc988e0f5230d9d07ae4def030cbae16603262638e272d19875b7e5c54e296ba88ab6ec6e98face9e2537346c4dce78882@52.243.47.211:30303",
"enode://dc72806c3aa8fda207c8c018aba8d6cf143728b3628b6ded8d5e8cdeb8aa05cbd53f710ecd014c9a8f0d1e98f2874bff8afb15a229202f510a9c0258d1f6d109@159.203.210.80:30303",
"enode://5a62f19d35c0da8b576c9414568c728d4744e6e9d436c0f9db27456400011414f515871f13a6b8e0468534b5116cfe765d7630f680f1707a38467940a9f62511@45.55.33.62:30303",
"enode://605e04a43b1156966b3a3b66b980c87b7f18522f7f712035f84576016be909a2798a438b2b17b1a8c58db314d88539a77419ca4be36148c086900fba487c9d39@188.166.255.12:30303",
"enode://1d1f7bcb159d308eb2f3d5e32dc5f8786d714ec696bb2f7e3d982f9bcd04c938c139432f13aadcaf5128304a8005e8606aebf5eebd9ec192a1471c13b5e31d49@138.201.223.35:30303",
"enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@52.16.188.185:30303",
"enode://3f1d12044546b76342d59d4a05532c14b85aa669704bfe1f864fe079415aa2c02d743e03218e57a33fb94523adb54032871a6c51b2cc5514cb7c7e35b3ed0a99@13.93.211.84:30303",
@ -195,7 +192,6 @@
"enode://1c7a64d76c0334b0418c004af2f67c50e36a3be60b5e4790bdac0439d21603469a85fad36f2473c9a80eb043ae60936df905fa28f1ff614c3e5dc34f15dcd2dc@40.118.3.223:30308",
"enode://85c85d7143ae8bb96924f2b54f1b3e70d8c4d367af305325d30a61385a432f247d2c75c45c6b4a60335060d072d7f5b35dd1d4c45f76941f62a4f83b6e75daaf@40.118.3.223:30309",
"enode://de471bccee3d042261d52e9bff31458daecc406142b401d4cd848f677479f73104b9fdeb090af9583d3391b7f10cb2ba9e26865dd5fca4fcdc0fb1e3b723c786@54.94.239.50:30303",
"enode://1118980bf48b0a3640bdba04e0fe78b1add18e1cd99bf22d53daac1fd9972ad650df52176e7c7d89d1114cfef2bc23a2959aa54998a46afcf7d91809f0855082@52.74.57.123:30303",
"enode://4cd540b2c3292e17cff39922e864094bf8b0741fcc8c5dcea14957e389d7944c70278d872902e3d0345927f621547efa659013c400865485ab4bfa0c6596936f@138.201.144.135:30303",
"enode://01f76fa0561eca2b9a7e224378dd854278735f1449793c46ad0c4e79e8775d080c21dcc455be391e90a98153c3b05dcc8935c8440de7b56fe6d67251e33f4e3c@51.15.42.252:30303",
"enode://2c9059f05c352b29d559192fe6bca272d965c9f2290632a2cfda7f83da7d2634f3ec45ae3a72c54dd4204926fb8082dcf9686e0d7504257541c86fc8569bcf4b@163.172.171.38:30303",

View File

@ -944,7 +944,8 @@ impl Client {
match id {
BlockId::Pending => self.state_at(BlockId::Latest),
id => match self.block_number(id) {
None | Some(0) => None,
None => None,
Some(0) => self.state_at(id),
Some(n) => self.state_at(BlockId::Number(n - 1)),
}
}

View File

@ -374,12 +374,16 @@ impl Decodable for SealedEmptyStep {
}
}
struct PermissionedStep {
inner: Step,
can_propose: AtomicBool,
}
/// Engine using `AuthorityRound` proof-of-authority BFT consensus.
pub struct AuthorityRound {
transition_service: IoService<()>,
step: Arc<Step>,
can_propose: AtomicBool,
client: RwLock<Option<Weak<EngineClient>>>,
step: Arc<PermissionedStep>,
client: Arc<RwLock<Option<Weak<EngineClient>>>>,
signer: RwLock<EngineSigner>,
validators: Box<ValidatorSet>,
validate_score_transition: u64,
@ -397,7 +401,7 @@ pub struct AuthorityRound {
// header-chain validator.
struct EpochVerifier {
step: Arc<Step>,
step: Arc<PermissionedStep>,
subchain_validators: SimpleList,
empty_steps_transition: u64,
}
@ -405,7 +409,7 @@ struct EpochVerifier {
impl super::EpochVerifier<EthereumMachine> for EpochVerifier {
fn verify_light(&self, header: &Header) -> Result<(), Error> {
// Validate the timestamp
verify_timestamp(&*self.step, header_step(header, self.empty_steps_transition)?)?;
verify_timestamp(&self.step.inner, header_step(header, self.empty_steps_transition)?)?;
// always check the seal since it's fast.
// nothing heavier to do.
verify_external(header, &self.subchain_validators, self.empty_steps_transition)
@ -604,13 +608,15 @@ impl AuthorityRound {
let engine = Arc::new(
AuthorityRound {
transition_service: IoService::<()>::start()?,
step: Arc::new(Step {
inner: AtomicUsize::new(initial_step),
calibrate: our_params.start_step.is_none(),
duration: our_params.step_duration,
step: Arc::new(PermissionedStep {
inner: Step {
inner: AtomicUsize::new(initial_step),
calibrate: our_params.start_step.is_none(),
duration: our_params.step_duration,
},
can_propose: AtomicBool::new(true),
}),
can_propose: AtomicBool::new(true),
client: RwLock::new(None),
client: Arc::new(RwLock::new(None)),
signer: Default::default(),
validators: our_params.validators,
validate_score_transition: our_params.validate_score_transition,
@ -628,7 +634,10 @@ impl AuthorityRound {
// Do not initialize timeouts for tests.
if should_timeout {
let handler = TransitionHandler { engine: Arc::downgrade(&engine) };
let handler = TransitionHandler {
step: engine.step.clone(),
client: engine.client.clone(),
};
engine.transition_service.register_handler(Arc::new(handler))?;
}
Ok(engine)
@ -654,7 +663,7 @@ impl AuthorityRound {
}
fn generate_empty_step(&self, parent_hash: &H256) {
let step = self.step.load();
let step = self.step.inner.load();
let empty_step_rlp = empty_step_rlp(step, parent_hash);
if let Ok(signature) = self.sign(keccak(&empty_step_rlp)).map(Into::into) {
@ -686,34 +695,37 @@ fn unix_now() -> Duration {
}
struct TransitionHandler {
engine: Weak<AuthorityRound>,
step: Arc<PermissionedStep>,
client: Arc<RwLock<Option<Weak<EngineClient>>>>,
}
const ENGINE_TIMEOUT_TOKEN: TimerToken = 23;
impl IoHandler<()> for TransitionHandler {
fn initialize(&self, io: &IoContext<()>) {
if let Some(engine) = self.engine.upgrade() {
let remaining = engine.step.duration_remaining();
io.register_timer_once(ENGINE_TIMEOUT_TOKEN, remaining.as_millis())
.unwrap_or_else(|e| warn!(target: "engine", "Failed to start consensus step timer: {}.", e))
}
let remaining = self.step.inner.duration_remaining().as_millis();
io.register_timer_once(ENGINE_TIMEOUT_TOKEN, remaining)
.unwrap_or_else(|e| warn!(target: "engine", "Failed to start consensus step timer: {}.", e))
}
fn timeout(&self, io: &IoContext<()>, timer: TimerToken) {
if timer == ENGINE_TIMEOUT_TOKEN {
if let Some(engine) = self.engine.upgrade() {
// NOTE we might be lagging by couple of steps in case the timeout
// has not been called fast enough.
// Make sure to advance up to the actual step.
while engine.step.duration_remaining().as_millis() == 0 {
engine.step();
// NOTE we might be lagging by couple of steps in case the timeout
// has not been called fast enough.
// Make sure to advance up to the actual step.
while self.step.inner.duration_remaining().as_millis() == 0 {
self.step.inner.increment();
self.step.can_propose.store(true, AtomicOrdering::SeqCst);
if let Some(ref weak) = *self.client.read() {
if let Some(c) = weak.upgrade() {
c.update_sealing();
}
}
let next_run_at = engine.step.duration_remaining().as_millis() >> 2;
io.register_timer_once(ENGINE_TIMEOUT_TOKEN, next_run_at)
.unwrap_or_else(|e| warn!(target: "engine", "Failed to restart consensus step timer: {}.", e))
}
let next_run_at = self.step.inner.duration_remaining().as_millis() >> 2;
io.register_timer_once(ENGINE_TIMEOUT_TOKEN, next_run_at)
.unwrap_or_else(|e| warn!(target: "engine", "Failed to restart consensus step timer: {}.", e))
}
}
}
@ -730,8 +742,8 @@ impl Engine<EthereumMachine> for AuthorityRound {
}
fn step(&self) {
self.step.increment();
self.can_propose.store(true, AtomicOrdering::SeqCst);
self.step.inner.increment();
self.step.can_propose.store(true, AtomicOrdering::SeqCst);
if let Some(ref weak) = *self.client.read() {
if let Some(c) = weak.upgrade() {
c.update_sealing();
@ -778,7 +790,7 @@ impl Engine<EthereumMachine> for AuthorityRound {
fn populate_from_parent(&self, header: &mut Header, parent: &Header) {
let parent_step = header_step(parent, self.empty_steps_transition).expect("Header has been verified; qed");
let current_step = self.step.load();
let current_step = self.step.inner.load();
let current_empty_steps_len = if header.number() >= self.empty_steps_transition {
self.empty_steps(parent_step.into(), current_step.into(), parent.hash()).len()
@ -804,7 +816,7 @@ impl Engine<EthereumMachine> for AuthorityRound {
let empty_step: EmptyStep = rlp.as_val().map_err(fmt_err)?;;
if empty_step.verify(&*self.validators).unwrap_or(false) {
if self.step.check_future(empty_step.step).is_ok() {
if self.step.inner.check_future(empty_step.step).is_ok() {
trace!(target: "engine", "handle_message: received empty step message {:?}", empty_step);
self.handle_empty_step_message(empty_step);
} else {
@ -824,13 +836,16 @@ impl Engine<EthereumMachine> for AuthorityRound {
fn generate_seal(&self, block: &ExecutedBlock, parent: &Header) -> Seal {
// first check to avoid generating signature most of the time
// (but there's still a race to the `compare_and_swap`)
if !self.can_propose.load(AtomicOrdering::SeqCst) { return Seal::None; }
if !self.step.can_propose.load(AtomicOrdering::SeqCst) {
trace!(target: "engine", "Aborting seal generation. Can't propose.");
return Seal::None;
}
let header = block.header();
let parent_step: U256 = header_step(parent, self.empty_steps_transition)
.expect("Header has been verified; qed").into();
let step = self.step.load();
let step = self.step.inner.load();
// filter messages from old and future steps and different parents
let empty_steps = if header.number() >= self.empty_steps_transition {
@ -907,7 +922,7 @@ impl Engine<EthereumMachine> for AuthorityRound {
trace!(target: "engine", "generate_seal: Issuing a block for step {}.", step);
// only issue the seal if we were the first to reach the compare_and_swap.
if self.can_propose.compare_and_swap(true, false, AtomicOrdering::SeqCst) {
if self.step.can_propose.compare_and_swap(true, false, AtomicOrdering::SeqCst) {
self.clear_empty_steps(parent_step);
@ -985,7 +1000,7 @@ impl Engine<EthereumMachine> for AuthorityRound {
.decode();
let parent_step = header_step(&parent, self.empty_steps_transition)?;
let current_step = self.step.load();
let current_step = self.step.inner.load();
self.empty_steps(parent_step.into(), current_step.into(), parent.hash())
} else {
// we're verifying a block, extract empty steps from the seal
@ -1019,7 +1034,7 @@ impl Engine<EthereumMachine> for AuthorityRound {
// If yes then probably benign reporting needs to be moved further in the verification.
let set_number = header.number();
match verify_timestamp(&*self.step, header_step(header, self.empty_steps_transition)?) {
match verify_timestamp(&self.step.inner, header_step(header, self.empty_steps_transition)?) {
Err(BlockError::InvalidSeal) => {
self.validators.report_benign(header.author(), set_number, header.number());
Err(BlockError::InvalidSeal.into())
@ -1261,7 +1276,7 @@ impl Engine<EthereumMachine> for AuthorityRound {
// This way, upon encountering an epoch change, the proposer from the
// new set will be forced to wait until the next step to avoid sealing a
// block that breaks the invariant that the parent's step < the block's step.
self.can_propose.store(false, AtomicOrdering::SeqCst);
self.step.can_propose.store(false, AtomicOrdering::SeqCst);
return Some(combine_proofs(signal_number, &pending.proof, &*finality_proof));
}
}

View File

@ -45,7 +45,7 @@ pub use self::requests::{
TransactionRequest, FilledTransactionRequest, ConfirmationRequest, ConfirmationPayload, CallRequest,
};
pub use self::signing_queue::{
ConfirmationsQueue, ConfirmationReceiver, ConfirmationResult,
ConfirmationsQueue, ConfirmationReceiver, ConfirmationResult, ConfirmationSender,
SigningQueue, QueueEvent, DefaultAccount,
QUEUE_LIMIT as SIGNING_QUEUE_LIMIT,
};

View File

@ -75,16 +75,17 @@ pub trait SigningQueue: Send + Sync {
/// `ConfirmationReceiver` is a `Future` awaiting for resolution of the given request.
fn add_request(&self, request: ConfirmationPayload, origin: Origin) -> Result<(U256, ConfirmationReceiver), QueueAddError>;
/// Removes a request from the queue.
/// Notifies possible token holders that request was rejected.
fn request_rejected(&self, id: U256) -> Option<ConfirmationRequest>;
fn request_rejected(&self, sender: ConfirmationSender) -> Option<ConfirmationRequest>;
/// Removes a request from the queue.
/// Notifies possible token holders that request was confirmed and given hash was assigned.
fn request_confirmed(&self, id: U256, result: ConfirmationResult) -> Option<ConfirmationRequest>;
fn request_confirmed(&self, sender: ConfirmationSender, result: ConfirmationResult) -> Option<ConfirmationRequest>;
/// Returns a request if it is contained in the queue.
fn peek(&self, id: &U256) -> Option<ConfirmationRequest>;
/// Put a request taken from `SigningQueue::take` back to the queue.
fn request_untouched(&self, sender: ConfirmationSender);
/// Returns and removes a request if it is contained in the queue.
fn take(&self, id: &U256) -> Option<ConfirmationSender>;
/// Return copy of all the requests in the queue.
fn requests(&self) -> Vec<ConfirmationRequest>;
@ -96,9 +97,12 @@ pub trait SigningQueue: Send + Sync {
fn is_empty(&self) -> bool;
}
struct ConfirmationSender {
/// Confirmation request information with result notifier.
pub struct ConfirmationSender {
/// Confirmation request information.
pub request: ConfirmationRequest,
sender: oneshot::Sender<ConfirmationResult>,
request: ConfirmationRequest,
}
/// Receiving end of the Confirmation channel; can be used as a `Future` to await for `ConfirmationRequest`
@ -122,36 +126,29 @@ impl ConfirmationsQueue {
/// Notifies consumer that the communcation is over.
/// No more events will be sent after this function is invoked.
pub fn finish(&self) {
self.notify(QueueEvent::Finish);
self.notify_message(QueueEvent::Finish);
self.on_event.write().clear();
}
/// Notifies receiver about the event happening in this queue.
fn notify(&self, message: QueueEvent) {
for listener in &*self.on_event.read() {
listener(message.clone())
}
/// Notifies `ConfirmationReceiver` holder about the result given a request.
fn notify_result(&self, sender: ConfirmationSender, result: Option<ConfirmationResult>) -> Option<ConfirmationRequest> {
// notify receiver about the event
self.notify_message(result.clone().map_or_else(
|| QueueEvent::RequestRejected(sender.request.id),
|_| QueueEvent::RequestConfirmed(sender.request.id)
));
// notify confirmation receiver about resolution
let result = result.ok_or(errors::request_rejected());
sender.sender.send(result);
Some(sender.request)
}
/// Removes requests from this queue and notifies `ConfirmationReceiver` holder about the result.
/// Notifies also a receiver about that event.
fn remove(&self, id: U256, result: Option<ConfirmationResult>) -> Option<ConfirmationRequest> {
let sender = self.queue.write().remove(&id);
if let Some(sender) = sender {
// notify receiver about the event
self.notify(result.clone().map_or_else(
|| QueueEvent::RequestRejected(id),
|_| QueueEvent::RequestConfirmed(id)
));
// notify confirmation receiver about resolution
let result = result.ok_or(errors::request_rejected());
sender.sender.send(result);
Some(sender.request)
} else {
None
/// Notifies receiver about the event happening in this queue.
fn notify_message(&self, message: QueueEvent) {
for listener in &*self.on_event.read() {
listener(message.clone())
}
}
}
@ -193,22 +190,26 @@ impl SigningQueue for ConfirmationsQueue {
(id, receiver)
};
// Notify listeners
self.notify(QueueEvent::NewRequest(id));
self.notify_message(QueueEvent::NewRequest(id));
Ok(res)
}
fn peek(&self, id: &U256) -> Option<ConfirmationRequest> {
self.queue.read().get(id).map(|sender| sender.request.clone())
fn take(&self, id: &U256) -> Option<ConfirmationSender> {
self.queue.write().remove(id)
}
fn request_rejected(&self, id: U256) -> Option<ConfirmationRequest> {
debug!(target: "own_tx", "Signer: Request rejected ({:?}).", id);
self.remove(id, None)
fn request_rejected(&self, sender: ConfirmationSender) -> Option<ConfirmationRequest> {
debug!(target: "own_tx", "Signer: Request rejected ({:?}).", sender.request.id);
self.notify_result(sender, None)
}
fn request_confirmed(&self, id: U256, result: ConfirmationResult) -> Option<ConfirmationRequest> {
debug!(target: "own_tx", "Signer: Transaction confirmed ({:?}).", id);
self.remove(id, Some(result))
fn request_confirmed(&self, sender: ConfirmationSender, result: ConfirmationResult) -> Option<ConfirmationRequest> {
debug!(target: "own_tx", "Signer: Request confirmed ({:?}).", sender.request.id);
self.notify_result(sender, Some(result))
}
fn request_untouched(&self, sender: ConfirmationSender) {
self.queue.write().insert(sender.request.id, sender);
}
fn requests(&self) -> Vec<ConfirmationRequest> {
@ -261,7 +262,8 @@ mod test {
// when
let (id, future) = queue.add_request(request, Default::default()).unwrap();
queue.request_confirmed(id, Ok(ConfirmationResponse::SendTransaction(1.into())));
let sender = queue.take(&id).unwrap();
queue.request_confirmed(sender, Ok(ConfirmationResponse::SendTransaction(1.into())));
// then
let confirmation = future.wait().unwrap();

View File

@ -92,11 +92,11 @@ impl<D: Dispatcher + 'static> SignerClient<D> {
let dispatcher = self.dispatcher.clone();
let signer = self.signer.clone();
Box::new(signer.peek(&id).map(|confirmation| {
let mut payload = confirmation.payload.clone();
Box::new(signer.take(&id).map(|sender| {
let mut payload = sender.request.payload.clone();
// Modify payload
if let ConfirmationPayload::SendTransaction(ref mut request) = payload {
if let Some(sender) = modification.sender.clone() {
if let Some(sender) = modification.sender {
request.from = sender.into();
// Altering sender should always reset the nonce.
request.nonce = None;
@ -115,7 +115,9 @@ impl<D: Dispatcher + 'static> SignerClient<D> {
Either::A(fut.into_future().then(move |result| {
// Execute
if let Ok(ref response) = result {
signer.request_confirmed(id, Ok((*response).clone()));
signer.request_confirmed(sender, Ok((*response).clone()));
} else {
signer.request_untouched(sender);
}
result
@ -194,8 +196,9 @@ impl<D: Dispatcher + 'static> Signer for SignerClient<D> {
fn confirm_request_raw(&self, id: U256, bytes: Bytes) -> Result<ConfirmationResponse> {
let id = id.into();
self.signer.peek(&id).map(|confirmation| {
let result = match confirmation.payload {
self.signer.take(&id).map(|sender| {
let payload = sender.request.payload.clone();
let result = match payload {
ConfirmationPayload::SendTransaction(request) => {
Self::verify_transaction(bytes, request, |pending_transaction| {
self.dispatcher.dispatch_transaction(pending_transaction)
@ -224,14 +227,16 @@ impl<D: Dispatcher + 'static> Signer for SignerClient<D> {
},
};
if let Ok(ref response) = result {
self.signer.request_confirmed(id, Ok(response.clone()));
self.signer.request_confirmed(sender, Ok(response.clone()));
} else {
self.signer.request_untouched(sender);
}
result
}).unwrap_or_else(|| Err(errors::invalid_params("Unknown RequestID", id)))
}
fn reject_request(&self, id: U256) -> Result<bool> {
let res = self.signer.request_rejected(id.into());
let res = self.signer.take(&id.into()).map(|sender| self.signer.request_rejected(sender));
Ok(res.is_some())
}

View File

@ -110,7 +110,8 @@ fn should_add_sign_to_queue() {
::std::thread::spawn(move || loop {
if signer.requests().len() == 1 {
// respond
signer.request_confirmed(1.into(), Ok(ConfirmationResponse::Signature(0.into())));
let sender = signer.take(&1.into()).unwrap();
signer.request_confirmed(sender, Ok(ConfirmationResponse::Signature(0.into())));
break
}
::std::thread::sleep(Duration::from_millis(100))
@ -188,7 +189,8 @@ fn should_check_status_of_request_when_its_resolved() {
"id": 1
}"#;
tester.io.handle_request_sync(&request).expect("Sent");
tester.signer.request_confirmed(1.into(), Ok(ConfirmationResponse::Signature(1.into())));
let sender = tester.signer.take(&1.into()).unwrap();
tester.signer.request_confirmed(sender, Ok(ConfirmationResponse::Signature(1.into())));
// This is not ideal, but we need to give futures some time to be executed, and they need to run in a separate thread
thread::sleep(Duration::from_millis(20));
@ -259,7 +261,8 @@ fn should_add_transaction_to_queue() {
::std::thread::spawn(move || loop {
if signer.requests().len() == 1 {
// respond
signer.request_confirmed(1.into(), Ok(ConfirmationResponse::SendTransaction(0.into())));
let sender = signer.take(&1.into()).unwrap();
signer.request_confirmed(sender, Ok(ConfirmationResponse::SendTransaction(0.into())));
break
}
::std::thread::sleep(Duration::from_millis(100))
@ -335,7 +338,8 @@ fn should_add_sign_transaction_to_the_queue() {
::std::thread::spawn(move || loop {
if signer.requests().len() == 1 {
// respond
signer.request_confirmed(1.into(), Ok(ConfirmationResponse::SignTransaction(
let sender = signer.take(&1.into()).unwrap();
signer.request_confirmed(sender, Ok(ConfirmationResponse::SignTransaction(
RichRawTransaction::from_signed(t.into(), 0x0, u64::max_value())
)));
break
@ -442,7 +446,8 @@ fn should_add_decryption_to_the_queue() {
::std::thread::spawn(move || loop {
if signer.requests().len() == 1 {
// respond
signer.request_confirmed(1.into(), Ok(ConfirmationResponse::Decrypt(vec![0x1, 0x2].into())));
let sender = signer.take(&1.into()).unwrap();
signer.request_confirmed(sender, Ok(ConfirmationResponse::Decrypt(vec![0x1, 0x2].into())));
break
}
::std::thread::sleep(Duration::from_millis(10))

View File

@ -1579,7 +1579,7 @@ impl ChainSync {
let max_count = cmp::min(MAX_HEADERS_TO_SEND, max_headers);
let mut count = 0;
let mut data = Bytes::new();
let inc = (skip + 1) as BlockNumber;
let inc = skip.saturating_add(1) as BlockNumber;
let overlay = io.chain_overlay().read();
while number <= last && count < max_count {
@ -1598,10 +1598,10 @@ impl ChainSync {
if number <= inc || number == 0 {
break;
}
number -= inc;
number = number.saturating_sub(inc);
}
else {
number += inc;
number = number.saturating_add(inc);
}
}
let mut rlp = RlpStream::new_list(count as usize);