support connecting to peers without bellatrix (#4011)

* support connecting to peers without bellatrix

Make discovery fork ID aware of scheduled Bellatrix fork to enable
connections to peers that don't have Bellatrix scheduled yet.
Without this, has peering issues with peers on older SW version.

* expand tests with compatibility checks

* more exhaustive compatibility checks
This commit is contained in:
Etan Kissling 2022-08-21 19:36:46 +02:00 committed by GitHub
parent 74dc388ad9
commit f1ddcfff0f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 132 additions and 7 deletions

View File

@ -126,6 +126,11 @@ OK: 4/4 Fail: 0/4 Skip: 0/4
+ Missing Authorization header [Beacon Node] [Preset: mainnet] OK + Missing Authorization header [Beacon Node] [Preset: mainnet] OK
``` ```
OK: 5/5 Fail: 0/5 Skip: 0/5 OK: 5/5 Fail: 0/5 Skip: 0/5
## Discovery fork ID
```diff
+ Expected fork IDs OK
```
OK: 1/1 Fail: 0/1 Skip: 0/1
## Diverging hardforks ## Diverging hardforks
```diff ```diff
+ Non-tail block in common OK + Non-tail block in common OK
@ -590,4 +595,4 @@ OK: 1/1 Fail: 0/1 Skip: 0/1
OK: 9/9 Fail: 0/9 Skip: 0/9 OK: 9/9 Fail: 0/9 Skip: 0/9
---TOTAL--- ---TOTAL---
OK: 331/336 Fail: 0/336 Skip: 5/336 OK: 332/337 Fail: 0/337 Skip: 5/337

View File

@ -125,8 +125,8 @@ func getENRForkID*(cfg: RuntimeConfig,
func getDiscoveryForkID*(cfg: RuntimeConfig, func getDiscoveryForkID*(cfg: RuntimeConfig,
epoch: Epoch, epoch: Epoch,
genesis_validators_root: Eth2Digest): ENRForkID = genesis_validators_root: Eth2Digest): ENRForkID =
# Until 1 epoch from fork, returns pre-fork value # Until 1 epoch from fork, return pre-fork value.
if epoch + 1 >= cfg.ALTAIR_FORK_EPOCH: if cfg.nextForkEpochAtEpoch(epoch) - epoch <= 1:
getENRForkID(cfg, epoch, genesis_validators_root) getENRForkID(cfg, epoch, genesis_validators_root)
else: else:
let let

View File

@ -1,10 +1,16 @@
# beacon_chain
# Copyright (c) 2021-2022 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.used.} {.used.}
import import
testutils/unittests, testutils/unittests,
chronos, stew/shims/net, eth/keys, eth/p2p/discoveryv5/enr, chronos, stew/shims/net, eth/keys, eth/p2p/discoveryv5/enr,
../beacon_chain/spec/datatypes/base, ../beacon_chain/spec/[forks, network],
../beacon_chain/spec/network,
../beacon_chain/networking/[eth2_network, eth2_discovery], ../beacon_chain/networking/[eth2_network, eth2_discovery],
./testutil ./testutil
@ -201,3 +207,117 @@ suite "Fork id compatibility test":
fork_digest: ForkDigest([byte 0, 1, 2, 3]), fork_digest: ForkDigest([byte 0, 1, 2, 3]),
next_fork_version: Version([byte 0, 0, 0, 0]), next_fork_version: Version([byte 0, 0, 0, 0]),
next_fork_epoch: Epoch(2))) next_fork_epoch: Epoch(2)))
suite "Discovery fork ID":
test "Expected fork IDs":
let genesis_validators_root = ZERO_HASH
var cfg = defaultRuntimeConfig
cfg.ALTAIR_FORK_EPOCH = 5.Epoch
cfg.BELLATRIX_FORK_EPOCH = 10.Epoch
let
# Phase 0
phase0ForkId = block:
let
current_fork_version = cfg.GENESIS_FORK_VERSION
next_fork_version = current_fork_version
fork_digest = compute_fork_digest(
current_fork_version, genesis_validators_root)
forkId = ENRForkID(
fork_digest: fork_digest,
next_fork_version: next_fork_version,
next_fork_epoch: FAR_FUTURE_EPOCH)
for epoch in GENESIS_EPOCH ..< cfg.ALTAIR_FORK_EPOCH - 1:
check cfg.getDiscoveryForkID(epoch, genesis_validators_root) == forkId
forkId
# Altair should become visible 1 epoch before the fork
phase0AltairForkId = block:
let
current_fork_version = cfg.GENESIS_FORK_VERSION
next_fork_version = cfg.ALTAIR_FORK_VERSION
fork_digest = compute_fork_digest(
current_fork_version, genesis_validators_root)
forkId = ENRForkID(
fork_digest: fork_digest,
next_fork_version: next_fork_version,
next_fork_epoch: cfg.ALTAIR_FORK_EPOCH)
for epoch in cfg.ALTAIR_FORK_EPOCH - 1 ..< cfg.ALTAIR_FORK_EPOCH:
check cfg.getDiscoveryForkID(epoch, genesis_validators_root) == forkId
forkId
# Altair
altairForkId = block:
let
current_fork_version = cfg.ALTAIR_FORK_VERSION
next_fork_version = current_fork_version
fork_digest = compute_fork_digest(
current_fork_version, genesis_validators_root)
forkId = ENRForkID(
fork_digest: fork_digest,
next_fork_version: next_fork_version,
next_fork_epoch: FAR_FUTURE_EPOCH)
for epoch in cfg.ALTAIR_FORK_EPOCH ..< cfg.BELLATRIX_FORK_EPOCH - 1:
check cfg.getDiscoveryForkID(epoch, genesis_validators_root) == forkId
forkId
# Bellatrix should become visible 1 epoch before the fork
altairBellatrixForkId = block:
let
current_fork_version = cfg.ALTAIR_FORK_VERSION
next_fork_version = cfg.BELLATRIX_FORK_VERSION
fork_digest = compute_fork_digest(
current_fork_version, genesis_validators_root)
forkId = ENRForkID(
fork_digest: fork_digest,
next_fork_version: next_fork_version,
next_fork_epoch: cfg.BELLATRIX_FORK_EPOCH)
for epoch in cfg.BELLATRIX_FORK_EPOCH - 1 ..< cfg.BELLATRIX_FORK_EPOCH:
check cfg.getDiscoveryForkID(epoch, genesis_validators_root) == forkId
forkId
# Bellatrix
bellatrixForkId = block:
let
current_fork_version = cfg.BELLATRIX_FORK_VERSION
next_fork_version = current_fork_version
fork_digest = compute_fork_digest(
current_fork_version, genesis_validators_root)
forkId = ENRForkID(
fork_digest: fork_digest,
next_fork_version: next_fork_version,
next_fork_epoch: FAR_FUTURE_EPOCH)
for epoch in cfg.BELLATRIX_FORK_EPOCH ..< cfg.BELLATRIX_FORK_EPOCH + 5:
check cfg.getDiscoveryForkID(epoch, genesis_validators_root) == forkId
forkId
check: # isCompatibleForkId(ourForkId, peerForkId)
isCompatibleForkId(phase0ForkId, phase0ForkId)
isCompatibleForkId(phase0ForkId, phase0AltairForkId)
not isCompatibleForkId(phase0ForkId, altairForkId)
not isCompatibleForkId(phase0ForkId, altairBellatrixForkId)
not isCompatibleForkId(phase0ForkId, bellatrixForkId)
not isCompatibleForkId(phase0AltairForkId, phase0ForkId) # fork -1 epoch
isCompatibleForkId(phase0AltairForkId, phase0AltairForkId)
not isCompatibleForkId(phase0AltairForkId, altairForkId)
not isCompatibleForkId(phase0AltairForkId, altairBellatrixForkId)
not isCompatibleForkId(phase0AltairForkId, bellatrixForkId)
not isCompatibleForkId(altairForkId, phase0ForkId)
not isCompatibleForkId(altairForkId, phase0AltairForkId)
isCompatibleForkId(altairForkId, altairForkId)
isCompatibleForkId(altairForkId, altairBellatrixForkId)
not isCompatibleForkId(altairForkId, bellatrixForkId)
not isCompatibleForkId(altairBellatrixForkId, phase0ForkId)
not isCompatibleForkId(altairBellatrixForkId, phase0AltairForkId)
not isCompatibleForkId(altairBellatrixForkId, altairForkId) # fork -1 ep
isCompatibleForkId(altairBellatrixForkId, altairBellatrixForkId)
not isCompatibleForkId(altairBellatrixForkId, bellatrixForkId)
not isCompatibleForkId(bellatrixForkId, phase0ForkId)
not isCompatibleForkId(bellatrixForkId, phase0AltairForkId)
not isCompatibleForkId(bellatrixForkId, altairForkId)
not isCompatibleForkId(bellatrixForkId, altairBellatrixForkId)
isCompatibleForkId(bellatrixForkId, bellatrixForkId)