Skip to content

Commit

Permalink
Merge branch 'unstable' into dev/etan/lc-testupdate
Browse files Browse the repository at this point in the history
  • Loading branch information
etan-status committed Jul 21, 2022
2 parents 1341658 + 735c1df commit f8c42ad
Show file tree
Hide file tree
Showing 20 changed files with 337 additions and 237 deletions.
22 changes: 14 additions & 8 deletions AllTests-mainnet.md
Original file line number Diff line number Diff line change
Expand Up @@ -287,14 +287,20 @@ OK: 9/9 Fail: 0/9 Skip: 0/9
OK: 3/3 Fail: 0/3 Skip: 0/3
## Light client processor [Preset: mainnet]
```diff
+ Duplicate bootstrap [Preset: mainnet] OK
+ Invalid bootstrap [Preset: mainnet] OK
+ Missing bootstrap (finality update) [Preset: mainnet] OK
+ Missing bootstrap (optimistic update) [Preset: mainnet] OK
+ Missing bootstrap (update) [Preset: mainnet] OK
+ Sync [Preset: mainnet] OK
+ Duplicate bootstrap (Optimistic) [Preset: mainnet] OK
+ Duplicate bootstrap (Strict) [Preset: mainnet] OK
+ Invalid bootstrap (Optimistic) [Preset: mainnet] OK
+ Invalid bootstrap (Strict) [Preset: mainnet] OK
+ Missing bootstrap (finality update) (Optimistic) [Preset: mainnet] OK
+ Missing bootstrap (finality update) (Strict) [Preset: mainnet] OK
+ Missing bootstrap (optimistic update) (Optimistic) [Preset: mainnet] OK
+ Missing bootstrap (optimistic update) (Strict) [Preset: mainnet] OK
+ Missing bootstrap (update) (Optimistic) [Preset: mainnet] OK
+ Missing bootstrap (update) (Strict) [Preset: mainnet] OK
+ Sync (Optimistic) [Preset: mainnet] OK
+ Sync (Strict) [Preset: mainnet] OK
```
OK: 6/6 Fail: 0/6 Skip: 0/6
OK: 12/12 Fail: 0/12 Skip: 0/12
## ListKeys requests [Preset: mainnet]
```diff
+ Correct token provided [Preset: mainnet] OK
Expand Down Expand Up @@ -580,4 +586,4 @@ OK: 1/1 Fail: 0/1 Skip: 0/1
OK: 9/9 Fail: 0/9 Skip: 0/9

---TOTAL---
OK: 321/326 Fail: 0/326 Skip: 5/326
OK: 327/332 Fail: 0/332 Skip: 5/332
2 changes: 0 additions & 2 deletions beacon_chain/beacon_chain_db_light_client.nim
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
# protocol. See https://github.com/ethereum/consensus-specs/pull/2802

import
# Standard library
std/os,
# Status libraries
chronicles,
eth/db/kvstore_sqlite3,
Expand Down
2 changes: 0 additions & 2 deletions beacon_chain/beacon_node.nim
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@ export
consensus_manager

type
RpcServer* = RpcHttpServer

EventBus* = object
blocksQueue*: AsyncEventQueue[EventBeaconBlockObject]
headQueue*: AsyncEventQueue[HeadChangeInfoObject]
Expand Down
4 changes: 2 additions & 2 deletions beacon_chain/beacon_node_light_client.nim
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ proc initLightClient*(
config.safeSlotsToImportOptimistically)

lightClient = createLightClient(
node.network, rng, config, cfg,
forkDigests, getBeaconTime, genesis_validators_root)
node.network, rng, config, cfg, forkDigests, getBeaconTime,
genesis_validators_root, LightClientFinalizationMode.Strict)

if config.lightClientEnable.get:
proc shouldSyncOptimistically(slot: Slot): bool =
Expand Down
52 changes: 28 additions & 24 deletions beacon_chain/conf.nim
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@ const
defaultListenAddress* = (static ValidIpAddress.init("0.0.0.0"))
defaultAdminListenAddress* = (static ValidIpAddress.init("127.0.0.1"))
defaultSigningNodeRequestTimeout* = 60
defaultBeaconNode* = "http://127.0.0.1:" & $DefaultEth2RestPort
defaultBeaconNode* = "http://127.0.0.1:" & $defaultEth2RestPort

defaultListenAddressDesc* = $defaultListenAddress
defaultAdminListenAddressDesc* = $defaultAdminListenAddress
defaultBeaconNodeDesc* = $defaultBeaconNode

when defined(windows):
{.pragma: windowsOnly.}
Expand Down Expand Up @@ -224,19 +228,19 @@ type
listenAddress* {.
desc: "Listening address for the Ethereum LibP2P and Discovery v5 traffic"
defaultValue: defaultListenAddress
defaultValueDesc: "0.0.0.0"
defaultValueDesc: $defaultListenAddressDesc
name: "listen-address" .}: ValidIpAddress

tcpPort* {.
desc: "Listening TCP port for Ethereum LibP2P traffic"
defaultValue: defaultEth2TcpPort
defaultValueDesc: "9000"
defaultValueDesc: $defaultEth2TcpPortDesc
name: "tcp-port" .}: Port

udpPort* {.
desc: "Listening UDP port for node discovery"
defaultValue: defaultEth2TcpPort
defaultValueDesc: "9000"
defaultValueDesc: $defaultEth2TcpPortDesc
name: "udp-port" .}: Port

maxPeers* {.
Expand Down Expand Up @@ -321,7 +325,7 @@ type
metricsAddress* {.
desc: "Listening address of the metrics server"
defaultValue: defaultAdminListenAddress
defaultValueDesc: "127.0.0.1"
defaultValueDesc: $defaultAdminListenAddressDesc
name: "metrics-address" .}: ValidIpAddress

metricsPort* {.
Expand Down Expand Up @@ -364,7 +368,7 @@ type
hidden
desc: "Listening address of the RPC server (deprecated for removal)"
defaultValue: defaultAdminListenAddress
defaultValueDesc: "127.0.0.1"
defaultValueDesc: $defaultAdminListenAddressDesc
name: "rpc-address" .}: ValidIpAddress

restEnabled* {.
Expand All @@ -374,14 +378,14 @@ type

restPort* {.
desc: "Port for the REST server"
defaultValue: DefaultEth2RestPort
defaultValueDesc: "5052"
defaultValue: defaultEth2RestPort
defaultValueDesc: $defaultEth2RestPortDesc
name: "rest-port" .}: Port

restAddress* {.
desc: "Listening address of the REST server"
defaultValue: defaultAdminListenAddress
defaultValueDesc: "127.0.0.1"
defaultValueDesc: $defaultAdminListenAddressDesc
name: "rest-address" .}: ValidIpAddress

restAllowedOrigin* {.
Expand Down Expand Up @@ -425,14 +429,14 @@ type

keymanagerPort* {.
desc: "Listening port for the REST keymanager API"
defaultValue: DefaultEth2RestPort
defaultValueDesc: "5052"
defaultValue: defaultEth2RestPort
defaultValueDesc: $defaultEth2RestPortDesc
name: "keymanager-port" .}: Port

keymanagerAddress* {.
desc: "Listening port for the REST keymanager API"
defaultValue: defaultAdminListenAddress
defaultValueDesc: "127.0.0.1"
defaultValueDesc: $defaultAdminListenAddressDesc
name: "keymanager-address" .}: ValidIpAddress

keymanagerAllowedOrigin* {.
Expand Down Expand Up @@ -539,14 +543,14 @@ type

bootstrapAddress* {.
desc: "The public IP address that will be advertised as a bootstrap node for the testnet"
defaultValue: init(ValidIpAddress, "127.0.0.1")
defaultValueDesc: "127.0.0.1"
defaultValue: init(ValidIpAddress, defaultAdminListenAddress)
defaultValueDesc: $defaultAdminListenAddressDesc
name: "bootstrap-address" .}: ValidIpAddress

bootstrapPort* {.
desc: "The TCP/UDP port that will be used by the bootstrap node"
defaultValue: defaultEth2TcpPort
defaultValueDesc: "9000"
defaultValueDesc: $defaultEth2TcpPortDesc
name: "bootstrap-port" .}: Port

genesisOffset* {.
Expand Down Expand Up @@ -651,7 +655,7 @@ type
restUrlForExit* {.
desc: "URL of the beacon node REST service"
defaultValue: defaultBeaconNode
defaultValueDesc: "http://127.0.0.1:5052"
defaultValueDesc: $defaultBeaconNodeDesc
name: "rest-url" .}: string

of BNStartUpCmd.record:
Expand Down Expand Up @@ -712,7 +716,7 @@ type
trustedNodeUrl* {.
desc: "URL of the REST API to sync from"
defaultValue: defaultBeaconNode
defaultValueDesc: "http://127.0.0.1:5052"
defaultValueDesc: $defaultBeaconNodeDesc
name: "trusted-node-url"
.}: string

Expand Down Expand Up @@ -777,14 +781,14 @@ type

keymanagerPort* {.
desc: "Listening port for the REST keymanager API"
defaultValue: DefaultEth2RestPort
defaultValueDesc: "5052"
defaultValue: defaultEth2RestPort
defaultValueDesc: $defaultEth2RestPortDesc
name: "keymanager-port" .}: Port

keymanagerAddress* {.
desc: "Listening port for the REST keymanager API"
defaultValue: defaultAdminListenAddress
defaultValueDesc: "127.0.0.1"
defaultValueDesc: $defaultAdminListenAddressDesc
name: "keymanager-address" .}: ValidIpAddress

keymanagerTokenFile* {.
Expand All @@ -805,7 +809,7 @@ type
beaconNodes* {.
desc: "URL addresses to one or more beacon node HTTP REST APIs",
defaultValue: @[defaultBeaconNode]
defaultValueDesc: "http://127.0.0.1:5052"
defaultValueDesc: $defaultBeaconNodeDesc
name: "beacon-node" .}: seq[string]

SigningNodeConf* = object
Expand Down Expand Up @@ -859,14 +863,14 @@ type

bindPort* {.
desc: "Port for the REST (BETA version) HTTP server"
defaultValue: DefaultEth2RestPort
defaultValueDesc: "5052"
defaultValue: defaultEth2RestPort
defaultValueDesc: $defaultEth2RestPortDesc
name: "bind-port" .}: Port

bindAddress* {.
desc: "Listening address of the REST (BETA version) HTTP server"
defaultValue: defaultAdminListenAddress
defaultValueDesc: "127.0.0.1"
defaultValueDesc: $defaultAdminListenAddressDesc
name: "bind-address" .}: ValidIpAddress

tlsEnabled* {.
Expand Down
6 changes: 3 additions & 3 deletions beacon_chain/conf_light_client.nim
Original file line number Diff line number Diff line change
Expand Up @@ -67,19 +67,19 @@ type LightClientConf* = object
listenAddress* {.
desc: "Listening address for the Ethereum LibP2P and Discovery v5 traffic"
defaultValue: defaultListenAddress
defaultValueDesc: "0.0.0.0"
defaultValueDesc: $defaultListenAddressDesc
name: "listen-address" .}: ValidIpAddress

tcpPort* {.
desc: "Listening TCP port for Ethereum LibP2P traffic"
defaultValue: defaultEth2TcpPort
defaultValueDesc: "9000"
defaultValueDesc: $defaultEth2TcpPortDesc
name: "tcp-port" .}: Port

udpPort* {.
desc: "Listening UDP port for node discovery"
defaultValue: defaultEth2TcpPort
defaultValueDesc: "9000"
defaultValueDesc: $defaultEth2TcpPortDesc
name: "udp-port" .}: Port

maxPeers* {.
Expand Down
68 changes: 48 additions & 20 deletions beacon_chain/gossip_processing/light_client_processor.nim
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,33 @@ type
VoidCallback* =
proc() {.gcsafe, raises: [Defect].}

LightClientFinalizationMode* {.pure.} = enum
Strict
## Only finalize light client data that:
## - has been signed by a supermajority (2/3) of the sync committee
## - has a valid finality proof
##
## Optimizes for security, but may become stuck if there is any of:
## - non-finality for an entire sync committee period
## - low sync committee participation for an entire sync committee period
## Such periods need to be covered by an out-of-band syncing mechanism.
##
## Note that a compromised supermajority of the sync committee is able to
## sign arbitrary light client data, even after being slashed. The light
## client cannot validate the slashing status of sync committee members.
## Likewise, voluntarily exited validators may sign bad light client data
## for the sync committee periods in which they used to be selected.

Optimistic
## Attempt to finalize light client data not satisfying strict conditions
## if there is no progress for an extended period of time and if there are
## repeated messages indicating that it is the best available data on the
## network for the affected time period.
##
## Optimizes for availability of recent data, but may end up on incorrect
## forks if run in a hostile network environment (no honest peers), or if
## the low sync committee participation is being exploited by bad actors.

LightClientProcessor* = object
## This manages the processing of received light client objects
##
Expand All @@ -48,13 +75,6 @@ type
##
## are then verified and added to:
## - `LightClientStore`
##
## The processor will also attempt to force-update the light client state
## if no update seems to be available on the network, that is both signed by
## a supermajority of sync committee members and also improves finality.
## This logic is triggered if there is no progress for an extended period
## of time, and there are repeated messages indicating that this is the best
## available data on the network during that time period.

# Config
# ----------------------------------------------------------------
Expand All @@ -72,9 +92,13 @@ type
cfg: RuntimeConfig
genesis_validators_root: Eth2Digest

lastProgressTick: BeaconTime # Moment when last update made progress
lastDuplicateTick: BeaconTime # Moment when last duplicate update received
numDuplicatesSinceProgress: int # Number of duplicates since last progress
case finalizationMode: LightClientFinalizationMode
of LightClientFinalizationMode.Strict:
discard
of LightClientFinalizationMode.Optimistic:
lastProgressTick: BeaconTime # Moment when last update made progress
lastDuplicateTick: BeaconTime # Moment when last duplicate update received
numDuplicatesSinceProgress: int # Number of duplicates since last progress

latestFinalityUpdate: altair.LightClientOptimisticUpdate

Expand All @@ -94,6 +118,7 @@ proc new*(
dumpDirInvalid, dumpDirIncoming: string,
cfg: RuntimeConfig,
genesis_validators_root: Eth2Digest,
finalizationMode: LightClientFinalizationMode,
store: ref Option[LightClientStore],
getBeaconTime: GetBeaconTimeFn,
getTrustedBlockRoot: GetTrustedBlockRootCallback,
Expand All @@ -112,8 +137,8 @@ proc new*(
onFinalizedHeader: onFinalizedHeader,
onOptimisticHeader: onOptimisticHeader,
cfg: cfg,
genesis_validators_root: genesis_validators_root
)
genesis_validators_root: genesis_validators_root,
finalizationMode: finalizationMode)

# Storage
# ------------------------------------------------------------------------------
Expand Down Expand Up @@ -146,6 +171,7 @@ proc tryForceUpdate(
store = self.store

if store[].isSome:
doAssert self.finalizationMode == LightClientFinalizationMode.Optimistic
case store[].get.try_light_client_store_force_update(wallSlot)
of NoUpdate:
discard
Expand Down Expand Up @@ -192,11 +218,12 @@ proc processObject(

if res.isErr:
when obj is altair.LightClientUpdate:
if store[].isSome and store[].get.best_valid_update.isSome:
# `best_valid_update` gets set when no supermajority / improved finality
# is available. In that case, we will wait for a better update that once
# again fulfills those conditions. If none is received within reasonable
# time, the light client store is force-updated to `best_valid_update`.
if self.finalizationMode == LightClientFinalizationMode.Optimistic and
store[].isSome and store[].get.best_valid_update.isSome:
# `best_valid_update` gets set when no supermajority / finality proof
# is available. In that case, we will wait for a better update.
# If none is made available within reasonable time, the light client
# is force-updated using the best known data to ensure sync progress.
case res.error
of BlockError.Duplicate:
if wallTime >= self.lastDuplicateTick + duplicateRateLimit:
Expand All @@ -215,9 +242,10 @@ proc processObject(
return res

when obj is altair.LightClientBootstrap | altair.LightClientUpdate:
self.lastProgressTick = wallTime
self.lastDuplicateTick = wallTime + duplicateCountDelay
self.numDuplicatesSinceProgress = 0
if self.finalizationMode == LightClientFinalizationMode.Optimistic:
self.lastProgressTick = wallTime
self.lastDuplicateTick = wallTime + duplicateCountDelay
self.numDuplicatesSinceProgress = 0

res

Expand Down

0 comments on commit f8c42ad

Please sign in to comment.