Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reduce LC optsync latency #4002

Merged
merged 4 commits into from
Aug 25, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 1 addition & 12 deletions AllTests-mainnet.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,17 +56,6 @@ OK: 6/6 Fail: 0/6 Skip: 0/6
+ basics OK
```
OK: 1/1 Fail: 0/1 Skip: 0/1
## Block clearance (light client) [Preset: mainnet]
```diff
+ Delayed finality update OK
+ Error conditions OK
+ Incremental sync OK
+ Initial sync OK
+ Low slot numbers OK
+ Reorg OK
+ Reverse incremental sync OK
```
OK: 7/7 Fail: 0/7 Skip: 0/7
## Block pool altair processing [Preset: mainnet]
```diff
+ Invalid signatures [Preset: mainnet] OK
Expand Down Expand Up @@ -590,4 +579,4 @@ OK: 1/1 Fail: 0/1 Skip: 0/1
OK: 9/9 Fail: 0/9 Skip: 0/9

---TOTAL---
OK: 331/336 Fail: 0/336 Skip: 5/336
OK: 324/329 Fail: 0/329 Skip: 5/329
13 changes: 7 additions & 6 deletions beacon_chain/beacon_node.nim
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ import

# Local modules
"."/[beacon_clock, beacon_chain_db, conf, light_client],
./gossip_processing/[eth2_processor, block_processor],
./gossip_processing/[eth2_processor, block_processor, optimistic_processor],
./networking/eth2_network,
./eth1/eth1_monitor,
./consensus_object_pools/[
blockchain_dag, block_quarantine, consensus_manager, exit_pool,
attestation_pool, sync_committee_msg_pool],
./spec/datatypes/[base, altair],
./spec/eth2_apis/dynamic_fee_recipients,
./sync/[optimistic_sync_light_client, sync_manager, request_manager],
./sync/[sync_manager, request_manager],
./validators/[
action_tracker, message_router, validator_monitor, validator_pool,
keystore_management],
Expand All @@ -33,9 +33,9 @@ export
osproc, chronos, httpserver, presto, action_tracker,
beacon_clock, beacon_chain_db, conf, light_client,
attestation_pool, sync_committee_msg_pool, validator_pool,
eth2_network, eth1_monitor, optimistic_sync_light_client,
request_manager, sync_manager, eth2_processor, blockchain_dag,
block_quarantine, base, exit_pool, message_router, validator_monitor,
eth2_network, eth1_monitor, request_manager, sync_manager,
eth2_processor, optimistic_processor, blockchain_dag, block_quarantine,
base, exit_pool, message_router, validator_monitor,
consensus_manager, dynamic_fee_recipients

type
Expand All @@ -58,7 +58,7 @@ type
db*: BeaconChainDB
config*: BeaconNodeConf
attachedValidators*: ref ValidatorPool
lcOptSync*: LCOptimisticSync
optimisticProcessor*: OptimisticProcessor
lightClient*: LightClient
dag*: ChainDAGRef
quarantine*: ref Quarantine
Expand All @@ -83,6 +83,7 @@ type
consensusManager*: ref ConsensusManager
attachedValidatorBalanceTotal*: uint64
gossipState*: GossipState
blocksGossipState*: GossipState
beaconClock*: BeaconClock
restKeysCache*: Table[ValidatorPubKey, ValidatorIndex]
validatorMonitor*: ref ValidatorMonitor
Expand Down
63 changes: 28 additions & 35 deletions beacon_chain/beacon_node_light_client.nim
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,24 @@ import

logScope: topics = "beacnde"

func shouldSyncOptimistically*(node: BeaconNode, wallSlot: Slot): bool =
# Check whether light client is used for syncing
let optimisticHeader = node.lightClient.optimisticHeader.valueOr:
return false

# Check whether light client is sufficiently ahead of DAG
const minProgress = 8 * SLOTS_PER_EPOCH # Set arbitrarily
let dagSlot = getStateField(node.dag.headState, slot)
if dagSlot + minProgress > optimisticHeader.slot:
return false

# Check whether light client has synced sufficiently close to wall slot
const maxAge = 2 * SLOTS_PER_EPOCH
if optimisticHeader.slot < max(wallSlot, maxAge.Slot) - maxAge:
return false

true

proc initLightClient*(
node: BeaconNode,
rng: ref HmacDrbgContext,
Expand All @@ -30,52 +48,28 @@ proc initLightClient*(
# for broadcasting light client data as a server.

let
optimisticProcessor = proc(signedBlock: ForkedMsgTrustedSignedBeaconBlock):
optimisticHandler = proc(signedBlock: ForkedMsgTrustedSignedBeaconBlock):
Future[void] {.async.} =
debug "New LC optimistic block",
opt = signedBlock.toBlockId(),
dag = node.dag.head.bid,
wallSlot = node.currentSlot
return
optSync = initLCOptimisticSync(
node.network, getBeaconTime, optimisticProcessor,
config.safeSlotsToImportOptimistically)
optimisticProcessor = initOptimisticProcessor(
getBeaconTime, optimisticHandler)

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

if config.lightClientEnable:
proc shouldSyncOptimistically(slot: Slot): bool =
const
# Minimum number of slots to be ahead of DAG to use optimistic sync
minProgress = 8 * SLOTS_PER_EPOCH
# Maximum age of light client optimistic header to use optimistic sync
maxAge = 2 * SLOTS_PER_EPOCH

if slot < getStateField(node.dag.headState, slot) + minProgress:
false
elif getBeaconTime().slotOrZero > slot + maxAge:
false
else:
true

proc onFinalizedHeader(lightClient: LightClient) =
let optimisticHeader = lightClient.optimisticHeader.valueOr:
return
if not shouldSyncOptimistically(optimisticHeader.slot):
return
let finalizedHeader = lightClient.finalizedHeader.valueOr:
return
optSync.setOptimisticHeader(optimisticHeader)
optSync.setFinalizedHeader(finalizedHeader)
proc onFinalizedHeader(
lightClient: LightClient, finalizedHeader: BeaconBlockHeader) =
optimisticProcessor.setFinalizedHeader(finalizedHeader)

proc onOptimisticHeader(lightClient: LightClient) =
let optimisticHeader = lightClient.optimisticHeader.valueOr:
return
if not shouldSyncOptimistically(optimisticHeader.slot):
return
optSync.setOptimisticHeader(optimisticHeader)
proc onOptimisticHeader(
lightClient: LightClient, optimisticHeader: BeaconBlockHeader) =
optimisticProcessor.setOptimisticHeader(optimisticHeader)

lightClient.onFinalizedHeader = onFinalizedHeader
lightClient.onOptimisticHeader = onOptimisticHeader
Expand All @@ -86,14 +80,13 @@ proc initLightClient*(
lightClientEnable = config.lightClientEnable,
lightClientTrustedBlockRoot = config.lightClientTrustedBlockRoot

node.lcOptSync = optSync
node.optimisticProcessor = optimisticProcessor
node.lightClient = lightClient

proc startLightClient*(node: BeaconNode) =
if not node.config.lightClientEnable:
return

node.lcOptSync.start()
node.lightClient.start()

proc installLightClientMessageValidators*(node: BeaconNode) =
Expand Down
6 changes: 0 additions & 6 deletions beacon_chain/conf_light_client.nim
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,6 @@ type LightClientConf* = object
desc: "A file containing the hex-encoded 256 bit secret key to be used for verifying/generating JWT tokens"
name: "jwt-secret" .}: Option[string]

safeSlotsToImportOptimistically* {.
hidden
desc: "Modify SAFE_SLOTS_TO_IMPORT_OPTIMISTICALLY"
defaultValue: 128
name: "safe-slots-to-import-optimistically" .}: uint16

# Testing
stopAtEpoch* {.
hidden
Expand Down
Loading