avoid replaying long empty slots on old votes (#1304)
* avoid replaying long empty slots on old votes * fixup! * fixup! * fixup!
This commit is contained in:
parent
0be77f9cbc
commit
300e0d57c1
|
@ -74,6 +74,31 @@ proc aggregate_attestations*(
|
|||
|
||||
none(AggregateAndProof)
|
||||
|
||||
proc isValidAttestationSlot(
|
||||
pool: AttestationPool, attestationSlot: Slot, attestationBlck: BlockRef): bool =
|
||||
# If we allow voting for very old blocks, the state transaction below will go
|
||||
# nuts and keep processing empty slots
|
||||
logScope:
|
||||
attestationSlot
|
||||
attestationBlck = shortLog(attestationBlck)
|
||||
|
||||
if not (attestationBlck.slot > pool.blockPool.finalizedHead.slot):
|
||||
debug "voting for already-finalized block"
|
||||
return false
|
||||
|
||||
# we'll also cap it at 4 epochs which is somewhat arbitrary, but puts an
|
||||
# upper bound on the processing done to validate the attestation
|
||||
# TODO revisit with less arbitrary approach
|
||||
if not (attestationSlot >= attestationBlck.slot):
|
||||
debug "voting for block that didn't exist at the time"
|
||||
return false
|
||||
|
||||
if not ((attestationSlot - attestationBlck.slot) <= uint64(4 * SLOTS_PER_EPOCH)):
|
||||
debug "voting for very old block"
|
||||
return false
|
||||
|
||||
true
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v0.11.1/specs/phase0/p2p-interface.md#attestation-subnets
|
||||
proc isValidAttestation*(
|
||||
pool: var AttestationPool, attestation: Attestation, current_slot: Slot,
|
||||
|
@ -132,6 +157,10 @@ proc isValidAttestation*(
|
|||
pool.blockPool.addMissing(attestation.data.beacon_block_root)
|
||||
return false
|
||||
|
||||
if not isValidAttestationSlot(pool, attestation.data.slot, attestationBlck):
|
||||
# Not in spec - check that rewinding to the state is sane
|
||||
return false
|
||||
|
||||
pool.blockPool.withState(
|
||||
pool.blockPool.tmpState,
|
||||
BlockSlot(blck: attestationBlck, slot: attestation.data.slot)):
|
||||
|
@ -222,6 +251,10 @@ proc isValidAggregatedAttestation*(
|
|||
debug "isValidAggregatedAttestation: attestation has no or invalid aggregation bits"
|
||||
return false
|
||||
|
||||
if not isValidAttestationSlot(pool, aggregate.data.slot, attestationBlck):
|
||||
# Not in spec - check that rewinding to the state is sane
|
||||
return false
|
||||
|
||||
# [REJECT] aggregate_and_proof.selection_proof selects the validator as an
|
||||
# aggregator for the slot -- i.e. is_aggregator(state, aggregate.data.slot,
|
||||
# aggregate.data.index, aggregate_and_proof.selection_proof) returns True.
|
||||
|
|
|
@ -694,6 +694,7 @@ proc installBeaconApiHandlers(rpcServer: RpcServer, node: BeaconNode) =
|
|||
root: Option[Eth2Digest]) -> StringOfJson:
|
||||
requireOneOf(slot, root)
|
||||
if slot.isSome:
|
||||
# TODO sanity check slot so that it doesn't cause excessive rewinding
|
||||
let blk = node.blockPool.head.blck.atSlot(slot.get)
|
||||
node.blockPool.withState(node.blockPool.tmpState, blk):
|
||||
return jsonResult(state)
|
||||
|
|
Loading…
Reference in New Issue