client/authority-discovery: Limit number of connections to authorities (#4487)

* client/authority-discovery: Limit number of connections to authorities

Instead of connecting to all sentry nodes of all authorities, with this
patch the authority discovery module does the following:

- Choose one sentry node per authority at random.

- Choose MAX_NUM_AUTHORITY_CONN out of the above at random.

The module uses randomness to prevent hot spots, e.g. all nodes trying
to connect to a single node. If the authority discovery module would
choose the nodes to connect to at random on each new address that it
learns of, the node would go through a lot of connection churn.  Instead
it creates a random seed at start up and uses this seed for its RNG on
each update cycle.

* client/authority-discovery: Extract address cache into own module

* client/authority-discovery/src/addr_cache: Add basic unit tests

* client/authority-discovery: Replace unwrap with expect on [u8] cmp

* .maintain/sentry-node/docker-compose.yml: Prefix endpoint flags

* client/authority-discovery/src/addr_cache: Use sort_unstable and cmp

* client/authority-discovery: Use BTreeMap in addr_cache for sorted iter

To reduce connection churn it is preferrable to have `get_subset` of the
`addr_cache` to return the same result on repeated calls. `get_subset`
iterates a map. To make the process of iteration deterministic, use a
`BTreeMap` instead of a `HashMap`.
This commit is contained in:
Max Inden
2020-01-03 21:40:19 +01:00
committed by Gavin Wood
parent fa1e42a2a1
commit 5cf682cece
7 changed files with 301 additions and 117 deletions
@@ -9,26 +9,27 @@ build = "build.rs"
prost-build = "0.5.0"
[dependencies]
sp-authority-discovery = { version = "2.0.0", path = "../../primitives/authority-discovery" }
bytes = "0.4.12"
sc-client-api = { version = "2.0.0", path = "../api" }
codec = { package = "parity-scale-codec", default-features = false, version = "1.0.3" }
derive_more = "0.99.2"
futures = "0.3.1"
futures-timer = "2.0"
sc-keystore = { version = "2.0.0", path = "../keystore" }
libp2p = { version = "0.13.2", default-features = false, features = ["secp256k1", "libp2p-websocket"] }
log = "0.4.8"
sc-network = { version = "0.8", path = "../network" }
sp-core = { version = "2.0.0", path = "../../primitives/core" }
sp-blockchain = { version = "2.0.0", path = "../../primitives/blockchain" }
prost = "0.5.0"
rand = "0.7.2"
sc-client-api = { version = "2.0.0", path = "../api" }
sc-keystore = { version = "2.0.0", path = "../keystore" }
sc-network = { version = "0.8", path = "../network" }
serde_json = "1.0.41"
sp-authority-discovery = { version = "2.0.0", path = "../../primitives/authority-discovery" }
sp-blockchain = { version = "2.0.0", path = "../../primitives/blockchain" }
sp-core = { version = "2.0.0", path = "../../primitives/core" }
sp-runtime = { version = "2.0.0", path = "../../primitives/runtime" }
[dev-dependencies]
env_logger = "0.7.0"
parking_lot = "0.9.0"
quickcheck = "0.9.0"
sc-peerset = { version = "2.0.0", path = "../peerset" }
sp-test-primitives = { version = "2.0.0", path = "../../primitives/test-primitives" }
sp-api = { version = "2.0.0", path = "../../primitives/api" }
sp-test-primitives = { version = "2.0.0", path = "../../primitives/test-primitives" }