have each validator randomly pick a stability subnet, per spec (#2194)
This commit is contained in:
parent
8cc7effe52
commit
048a67d525
|
@ -359,11 +359,12 @@ proc installAttestationSubnetHandlers(node: BeaconNode, subnets: set[uint8])
|
|||
|
||||
await allFutures(attestationSubscriptions)
|
||||
|
||||
proc updateStabilitySubnetMetadata(node: BeaconNode, stabilitySubnet: uint64) =
|
||||
proc updateStabilitySubnetMetadata(
|
||||
node: BeaconNode, stabilitySubnets: set[uint8]) =
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/p2p-interface.md#metadata
|
||||
node.network.metadata.seq_number += 1
|
||||
for subnet in 0'u8 ..< ATTESTATION_SUBNET_COUNT:
|
||||
node.network.metadata.attnets[subnet] = (subnet == stabilitySubnet)
|
||||
node.network.metadata.attnets[subnet] = (subnet in stabilitySubnets)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/validator.md#phase-0-attestation-subnet-stability
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/p2p-interface.md#attestation-subnet-bitfield
|
||||
|
@ -374,7 +375,11 @@ proc updateStabilitySubnetMetadata(node: BeaconNode, stabilitySubnet: uint64) =
|
|||
# be the correct one and the ENR will not increase in size.
|
||||
warn "Failed to update record on subnet cycle", error = res.error
|
||||
else:
|
||||
debug "Stability subnet changed, updated ENR attnets", stabilitySubnet
|
||||
debug "Stability subnets changed, updated ENR attnets", stabilitySubnets
|
||||
|
||||
func getStabilitySubnets(stabilitySubnets: auto): set[uint8] =
|
||||
for subnetInfo in stabilitySubnets:
|
||||
result.incl subnetInfo.subnet
|
||||
|
||||
proc cycleAttestationSubnets(node: BeaconNode, slot: Slot) {.async.} =
|
||||
static: doAssert RANDOM_SUBNETS_PER_VALIDATOR == 1
|
||||
|
@ -394,7 +399,8 @@ proc cycleAttestationSubnets(node: BeaconNode, slot: Slot) {.async.} =
|
|||
node.chainDag.headState.data.data, attachedValidators,
|
||||
node.attestationSubnets, slot.epoch)
|
||||
|
||||
let prevStabilitySubnet = node.attestationSubnets.stabilitySubnet
|
||||
let prevStabilitySubnets =
|
||||
getStabilitySubnets(node.attestationSubnets.stabilitySubnets)
|
||||
|
||||
node.attestationSubnets = newAttestationSubnets
|
||||
debug "Attestation subnets",
|
||||
|
@ -403,9 +409,7 @@ proc cycleAttestationSubnets(node: BeaconNode, slot: Slot) {.async.} =
|
|||
node.attestationSubnets.subscribedSubnets[1 - epochParity],
|
||||
upcoming_subnets = node.attestationSubnets.subscribedSubnets[epochParity],
|
||||
new_subnets = newSubnets,
|
||||
stability_subnet = node.attestationSubnets.stabilitySubnet,
|
||||
stability_subnet_expiration_epoch =
|
||||
node.attestationSubnets.stabilitySubnetExpirationEpoch
|
||||
stability_subnets = node.attestationSubnets.stabilitySubnets
|
||||
|
||||
block:
|
||||
var unsubscriptions: seq[Future[void]] = @[]
|
||||
|
@ -417,9 +421,11 @@ proc cycleAttestationSubnets(node: BeaconNode, slot: Slot) {.async.} =
|
|||
|
||||
await node.installAttestationSubnetHandlers(newSubnets)
|
||||
|
||||
let stabilitySubnet = node.attestationSubnets.stabilitySubnet
|
||||
if stabilitySubnet != prevStabilitySubnet:
|
||||
node.updateStabilitySubnetMetadata(stabilitySubnet)
|
||||
let stabilitySubnets =
|
||||
getStabilitySubnets(node.attestationSubnets.stabilitySubnets)
|
||||
|
||||
if stabilitySubnets != prevStabilitySubnets:
|
||||
node.updateStabilitySubnetMetadata(stabilitySubnets)
|
||||
|
||||
proc getAttestationSubnetHandlers(node: BeaconNode): Future[void] =
|
||||
var initialSubnets: set[uint8]
|
||||
|
@ -432,11 +438,15 @@ proc getAttestationSubnetHandlers(node: BeaconNode): Future[void] =
|
|||
# - Restarting the node with a presistent netkey
|
||||
# - When going from synced -> syncing -> synced state
|
||||
let wallEpoch = node.beaconClock.now().slotOrZero().epoch
|
||||
node.attestationSubnets.stabilitySubnet = rand(ATTESTATION_SUBNET_COUNT - 1).uint64
|
||||
node.attestationSubnets.stabilitySubnetExpirationEpoch =
|
||||
wallEpoch + getStabilitySubnetLength()
|
||||
|
||||
node.updateStabilitySubnetMetadata(node.attestationSubnets.stabilitySubnet)
|
||||
doAssert node.attestationSubnets.stabilitySubnets.len == 0
|
||||
for _ in 0 ..< node.attachedValidators.count:
|
||||
node.attestationSubnets.stabilitySubnets.add (
|
||||
subnet: rand(ATTESTATION_SUBNET_COUNT - 1).uint8,
|
||||
expiration: wallEpoch + getStabilitySubnetLength())
|
||||
|
||||
node.updateStabilitySubnetMetadata(
|
||||
node.attestationSubnets.stabilitySubnets.getStabilitySubnets)
|
||||
|
||||
# Sets the "current" and "future" attestation subnets. One of these gets
|
||||
# replaced by get_attestation_subnet_changes() immediately.
|
||||
|
@ -465,6 +475,8 @@ proc removeMessageHandlers(node: BeaconNode): Future[void] =
|
|||
node.attestationSubnets.subscribedSubnets[1] = {}
|
||||
doAssert not node.getTopicSubscriptionEnabled()
|
||||
|
||||
node.attestationSubnets.stabilitySubnets.setLen(0)
|
||||
|
||||
var unsubscriptions = mapIt(
|
||||
[getBeaconBlocksTopic(node.forkDigest),
|
||||
getVoluntaryExitsTopic(node.forkDigest),
|
||||
|
|
|
@ -458,8 +458,7 @@ type
|
|||
|
||||
AttestationSubnets* = object
|
||||
subscribedSubnets*: array[2, set[uint8]]
|
||||
stabilitySubnet*: uint64
|
||||
stabilitySubnetExpirationEpoch*: Epoch
|
||||
stabilitySubnets*: seq[tuple[subnet: uint8, expiration: Epoch]]
|
||||
|
||||
# This matches the mutable state of the Solidity deposit contract
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/solidity_deposit_contract/deposit_contract.sol
|
||||
|
|
|
@ -132,12 +132,20 @@ proc get_attestation_subnet_changes*(
|
|||
var attestationSubnets = prevAttestationSubnets
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.0/specs/phase0/validator.md#phase-0-attestation-subnet-stability
|
||||
let prevStabilitySubnet = {attestationSubnets.stabilitySubnet.uint8}
|
||||
if epoch >= attestationSubnets.stabilitySubnetExpirationEpoch:
|
||||
attestationSubnets.stabilitySubnet =
|
||||
rand(ATTESTATION_SUBNET_COUNT - 1).uint64
|
||||
attestationSubnets.stabilitySubnetExpirationEpoch =
|
||||
epoch + getStabilitySubnetLength()
|
||||
var
|
||||
prevStabilitySubnets: set[uint8] = {}
|
||||
stabilitySet: set[uint8] = {}
|
||||
for i in 0 ..< attestationSubnets.stabilitySubnets.len:
|
||||
static: doAssert ATTESTATION_SUBNET_COUNT <= high(uint8)
|
||||
prevStabilitySubnets.incl attestationSubnets.stabilitySubnets[i].subnet
|
||||
|
||||
if epoch >= attestationSubnets.stabilitySubnets[i].expiration:
|
||||
attestationSubnets.stabilitySubnets[i].subnet =
|
||||
rand(ATTESTATION_SUBNET_COUNT - 1).uint8
|
||||
attestationSubnets.stabilitySubnets[i].expiration =
|
||||
epoch + getStabilitySubnetLength()
|
||||
|
||||
stabilitySet.incl attestationSubnets.stabilitySubnets[i].subnet
|
||||
|
||||
var nextEpochSubnets: set[uint8]
|
||||
for it in get_committee_assignments(
|
||||
|
@ -148,16 +156,15 @@ proc get_attestation_subnet_changes*(
|
|||
|
||||
let
|
||||
epochParity = epoch mod 2
|
||||
stabilitySet = {attestationSubnets.stabilitySubnet.uint8}
|
||||
currentEpochSubnets = attestationSubnets.subscribedSubnets[1 - epochParity]
|
||||
|
||||
expiringSubnets =
|
||||
(prevStabilitySubnet +
|
||||
(prevStabilitySubnets +
|
||||
attestationSubnets.subscribedSubnets[epochParity]) -
|
||||
nextEpochSubnets - currentEpochSubnets - stabilitySet
|
||||
newSubnets =
|
||||
(nextEpochSubnets + stabilitySet) -
|
||||
(currentEpochSubnets + prevStabilitySubnet)
|
||||
(currentEpochSubnets + prevStabilitySubnets)
|
||||
|
||||
doAssert newSubnets.len <= attachedValidators.len + 1
|
||||
|
||||
|
|
Loading…
Reference in New Issue