Fix attester and proposer duties optimistic execution behavior. (#4657)

* Fix attester and proposer duties optimistic execution behavior.

* Address review comments.

* Address review comments more efficiently.
This commit is contained in:
Eugene Kabanov 2023-02-24 01:13:17 +02:00 committed by GitHub
parent 7c83a7b48f
commit e21742a325
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 44 additions and 21 deletions

View File

@ -241,8 +241,12 @@ proc installNimbusApiHandlers*(router: var RestRouter, node: BeaconNode) =
block:
let res = node.getSyncedHead(wallSlot)
if res.isErr():
return RestApiResponse.jsonError(Http503, BeaconNodeInSyncError,
$res.error())
let tres = res.get()
if tres.optimistic:
return RestApiResponse.jsonError(Http503, BeaconNodeInSyncError)
res.get()
tres.head
let proposalState = assignClone(node.dag.headState)
node.dag.withUpdatedState(
proposalState[],

View File

@ -30,17 +30,26 @@ func match(data: openArray[char], charset: set[char]): int =
return 1
0
proc getSyncedHead*(node: BeaconNode, slot: Slot): Result[BlockRef, cstring] =
let head = node.dag.head
if node.isSynced(head) != SyncStatus.synced:
return err("Beacon node not fully and non-optimistically synced")
proc getSyncedHead*(
node: BeaconNode,
slot: Slot
): Result[tuple[head: BlockRef, optimistic: bool], cstring] =
let
head = node.dag.head
optimistic =
case node.isSynced(head)
of SyncStatus.unsynced:
return err("Beacon node not fully and non-optimistically synced")
of SyncStatus.synced:
false
of SyncStatus.optimistic:
true
# Enough ahead not to know the shuffling
if slot > head.slot + SLOTS_PER_EPOCH * 2:
return err("Requesting far ahead of the current head")
ok(head)
ok((head, optimistic))
func getCurrentSlot*(node: BeaconNode, slot: Slot):
Result[Slot, cstring] =
@ -49,8 +58,10 @@ func getCurrentSlot*(node: BeaconNode, slot: Slot):
else:
err("Requesting slot too far ahead of the current head")
proc getSyncedHead*(node: BeaconNode,
epoch: Epoch): Result[BlockRef, cstring] =
proc getSyncedHead*(
node: BeaconNode,
epoch: Epoch,
): Result[tuple[head: BlockRef, optimistic: bool], cstring] =
if epoch > MaxEpoch:
return err("Requesting epoch for which slot would overflow")
node.getSyncedHead(epoch.start_slot())

View File

@ -63,9 +63,9 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
wallEpoch = wallTime.slotOrZero().epoch
if res > wallEpoch + 1:
return RestApiResponse.jsonError(Http400, InvalidEpochValueError,
"Cannot request duties past next epoch")
"Cannot request duties past next epoch")
res
let qhead =
let (qhead, qoptimistic) =
block:
let res = node.getSyncedHead(qepoch)
if res.isErr():
@ -102,10 +102,9 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
)
res
# getSyncedHead() implies non-optimistic node.
let optimistic =
if node.currentSlot().epoch() >= node.dag.cfg.BELLATRIX_FORK_EPOCH:
some(false)
some(qoptimistic)
else:
none[bool]()
@ -126,9 +125,9 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
wallEpoch = wallTime.slotOrZero().epoch
if res > wallEpoch + 1:
return RestApiResponse.jsonError(Http400, InvalidEpochValueError,
"Cannot request duties past next epoch")
"Cannot request duties past next epoch")
res
let qhead =
let (qhead, qoptimistic) =
block:
let res = node.getSyncedHead(qepoch)
if res.isErr():
@ -156,10 +155,9 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
)
res
# getSyncedHead() implies non-optimistic node.
let optimistic =
if node.currentSlot().epoch() >= node.dag.cfg.BELLATRIX_FORK_EPOCH:
some(false)
some(qoptimistic)
else:
none[bool]()
@ -364,7 +362,10 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
if res.isErr():
return RestApiResponse.jsonError(Http503, BeaconNodeInSyncError,
$res.error())
res.get()
let tres = res.get()
if tres.optimistic:
return RestApiResponse.jsonError(Http503, BeaconNodeInSyncError)
tres.head
let
proposer = node.dag.getProposer(qhead, qslot).valueOr:
return RestApiResponse.jsonError(Http400, ProposerNotFoundError)
@ -454,7 +455,10 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
if res.isErr():
return RestApiResponse.jsonError(Http503, BeaconNodeInSyncError,
$res.error())
res.get()
let tres = res.get()
if tres.optimistic:
return RestApiResponse.jsonError(Http503, BeaconNodeInSyncError)
tres.head
let proposer = node.dag.getProposer(qhead, qslot).valueOr:
return RestApiResponse.jsonError(Http400, ProposerNotFoundError)
@ -544,8 +548,12 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
block:
let res = node.getSyncedHead(qslot)
if res.isErr():
return RestApiResponse.jsonError(Http503, BeaconNodeInSyncError,
$res.error())
let tres = res.get()
if tres.optimistic:
return RestApiResponse.jsonError(Http503, BeaconNodeInSyncError)
res.get()
tres.head
let epochRef = node.dag.getEpochRef(qhead, qslot.epoch, true).valueOr:
return RestApiResponse.jsonError(Http400, PrunedStateError, $error)
makeAttestationData(epochRef, qhead.atSlot(qslot), qindex)
@ -784,7 +792,7 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
# Check if node is fully synced.
let sres = node.getSyncedHead(qslot)
if sres.isErr():
if sres.isErr() or sres.get().optimistic:
return RestApiResponse.jsonError(Http503, BeaconNodeInSyncError)
var contribution = SyncCommitteeContribution()