broadcast optimistic light client updates (#3499)
After proposing a new block, broadcasts a `OptimisticLightClientUpdate`. Works for both locally proposed blocks as well as VC submitted ones.
This commit is contained in:
parent
05ffe7b2bf
commit
9f8894fb43
|
@ -2355,3 +2355,17 @@ proc broadcastSignedContributionAndProof*(
|
|||
node: Eth2Node, msg: SignedContributionAndProof) =
|
||||
let topic = getSyncCommitteeContributionAndProofTopic(node.forkDigests.altair)
|
||||
node.broadcast(topic, msg)
|
||||
|
||||
proc broadcastOptimisticLightClientUpdate*(
|
||||
node: Eth2Node, msg: OptimisticLightClientUpdate) =
|
||||
let
|
||||
forkDigest =
|
||||
if msg.fork_version == node.cfg.SHARDING_FORK_VERSION:
|
||||
node.forkDigests.sharding
|
||||
elif msg.fork_version == node.cfg.BELLATRIX_FORK_VERSION:
|
||||
node.forkDigests.bellatrix
|
||||
else:
|
||||
doAssert msg.fork_version == node.cfg.ALTAIR_FORK_VERSION
|
||||
node.forkDigests.altair
|
||||
topic = getOptimisticLightClientUpdateTopic(forkDigest)
|
||||
node.broadcast(topic, msg)
|
||||
|
|
|
@ -7,6 +7,10 @@
|
|||
|
||||
{.push raises: [Defect].}
|
||||
|
||||
# References to `vFuture` refer to the pre-release proposal of the libp2p based
|
||||
# light client sync protocol. Conflicting release versions are not in use.
|
||||
# https://github.com/ethereum/consensus-specs/pull/2802
|
||||
|
||||
import
|
||||
std/[hashes, typetraits],
|
||||
chronicles,
|
||||
|
@ -146,6 +150,9 @@ const
|
|||
# https://github.com/ethereum/consensus-specs/blob/v1.1.10/specs/altair/validator.md#broadcast-sync-committee-contribution
|
||||
syncContributionSlotOffset* = TimeDiff(nanoseconds:
|
||||
NANOSECONDS_PER_SLOT.int64 * 2 div INTERVALS_PER_SLOT)
|
||||
# https://github.com/ethereum/consensus-specs/blob/vFuture/specs/altair/sync-protocol.md#block-proposal
|
||||
optimisticLightClientUpdateSlotOffset* = TimeDiff(nanoseconds:
|
||||
NANOSECONDS_PER_SLOT.int64 div INTERVALS_PER_SLOT)
|
||||
|
||||
func toFloatSeconds*(t: TimeDiff): float =
|
||||
float(t.nanoseconds) / 1_000_000_000.0
|
||||
|
@ -167,6 +174,8 @@ func sync_committee_message_deadline*(s: Slot): BeaconTime =
|
|||
s.start_beacon_time + syncCommitteeMessageSlotOffset
|
||||
func sync_contribution_deadline*(s: Slot): BeaconTime =
|
||||
s.start_beacon_time + syncContributionSlotOffset
|
||||
func optimistic_light_client_update_time*(s: Slot): BeaconTime =
|
||||
s.start_beacon_time + optimisticLightClientUpdateSlotOffset
|
||||
|
||||
func slotOrZero*(time: BeaconTime): Slot =
|
||||
let exSlot = time.toSlot
|
||||
|
|
|
@ -7,6 +7,10 @@
|
|||
|
||||
{.push raises: [Defect].}
|
||||
|
||||
# References to `vFuture` refer to the pre-release proposal of the libp2p based
|
||||
# light client sync protocol. Conflicting release versions are not in use.
|
||||
# https://github.com/ethereum/consensus-specs/pull/2802
|
||||
|
||||
import
|
||||
# Standard library
|
||||
std/[os, osproc, sequtils, streams, tables],
|
||||
|
@ -738,6 +742,19 @@ proc handleSyncCommitteeMessages(node: BeaconNode, head: BlockRef, slot: Slot) =
|
|||
asyncSpawn createAndSendSyncCommitteeMessage(node, slot, validator,
|
||||
subcommitteeIdx, head)
|
||||
|
||||
proc handleOptimisticLightClientUpdates(
|
||||
node: BeaconNode, head: BlockRef, slot: Slot) =
|
||||
if slot < node.dag.cfg.ALTAIR_FORK_EPOCH.start_slot():
|
||||
return
|
||||
doAssert head.parent != nil, "Newly proposed block lacks parent reference"
|
||||
let msg = node.dag.lightClientCache.optimisticUpdate
|
||||
if msg.attested_header.slot != head.parent.bid.slot:
|
||||
notice "No optimistic light client update for proposed block",
|
||||
slot = slot, block_root = shortLog(head.root)
|
||||
return
|
||||
node.network.broadcastOptimisticLightClientUpdate(msg)
|
||||
notice "Sent optimistic light client update", message = shortLog(msg)
|
||||
|
||||
proc signAndSendContribution(node: BeaconNode,
|
||||
validator: AttachedValidator,
|
||||
contribution: SyncCommitteeContribution,
|
||||
|
@ -1070,7 +1087,10 @@ proc handleValidatorDuties*(node: BeaconNode, lastSlot, slot: Slot) {.async.} =
|
|||
|
||||
curSlot += 1
|
||||
|
||||
head = await handleProposal(node, head, slot)
|
||||
let
|
||||
newHead = await handleProposal(node, head, slot)
|
||||
didSubmitBlock = (newHead != head)
|
||||
head = newHead
|
||||
|
||||
let
|
||||
# The latest point in time when we'll be sending out attestations
|
||||
|
@ -1120,6 +1140,16 @@ proc handleValidatorDuties*(node: BeaconNode, lastSlot, slot: Slot) {.async.} =
|
|||
handleAttestations(node, head, slot)
|
||||
handleSyncCommitteeMessages(node, head, slot)
|
||||
|
||||
if node.config.serveLightClientData and didSubmitBlock:
|
||||
let cutoff = node.beaconClock.fromNow(
|
||||
slot.optimistic_light_client_update_time())
|
||||
if cutoff.inFuture:
|
||||
debug "Waiting to send optimistic light client update",
|
||||
head = shortLog(head),
|
||||
optimisticLightClientUpdateCutoff = shortLog(cutoff.offset)
|
||||
await sleepAsync(cutoff.offset)
|
||||
handleOptimisticLightClientUpdates(node, head, slot)
|
||||
|
||||
updateValidatorMetrics(node) # the important stuff is done, update the vanity numbers
|
||||
|
||||
# https://github.com/ethereum/consensus-specs/blob/v1.1.10/specs/phase0/validator.md#broadcast-aggregate
|
||||
|
@ -1277,6 +1307,25 @@ proc sendBeaconBlock*(node: BeaconNode, forked: ForkedSignedBeaconBlock
|
|||
notice "Block published",
|
||||
blockRoot = shortLog(blck.root), blck = shortLog(blck.message),
|
||||
signature = shortLog(blck.signature)
|
||||
|
||||
if node.config.serveLightClientData:
|
||||
# The optimistic light client update is sent with a delay because it
|
||||
# only validates once the new block has been processed by the peers.
|
||||
# https://github.com/ethereum/consensus-specs/blob/vFuture/specs/altair/sync-protocol.md#block-proposal
|
||||
proc publishOptimisticLightClientUpdate() {.async.} =
|
||||
let cutoff = node.beaconClock.fromNow(
|
||||
wallTime.slotOrZero.optimistic_light_client_update_time())
|
||||
if cutoff.inFuture:
|
||||
debug "Waiting to publish optimistic light client update",
|
||||
blockRoot = shortLog(blck.root), blck = shortLog(blck.message),
|
||||
signature = shortLog(blck.signature),
|
||||
optimisticLightClientUpdateCutoff = shortLog(cutoff.offset)
|
||||
await sleepAsync(cutoff.offset)
|
||||
handleOptimisticLightClientUpdates(
|
||||
node, newBlockRef.get, wallTime.slotOrZero)
|
||||
|
||||
asyncSpawn publishOptimisticLightClientUpdate()
|
||||
|
||||
true
|
||||
else:
|
||||
warn "Unable to add proposed block to block pool",
|
||||
|
|
Loading…
Reference in New Issue