add some support for electra aggregated attestations (#6283)

This commit is contained in:
tersec 2024-05-14 07:12:35 +03:00 committed by GitHub
parent 87605d08a7
commit 3f972a2ca5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 55 additions and 32 deletions

View File

@ -414,7 +414,7 @@ proc scheduleAttestationCheck*(
proc scheduleAggregateChecks*(
batchCrypto: ref BatchCrypto, fork: Fork,
signedAggregateAndProof: SignedAggregateAndProof, dag: ChainDAGRef,
signedAggregateAndProof: phase0.SignedAggregateAndProof, dag: ChainDAGRef,
attesting_indices: openArray[ValidatorIndex]
): Result[tuple[
aggregatorFut, slotFut, aggregateFut: FutureBatchResult,

View File

@ -412,7 +412,7 @@ proc processAttestation*(
proc processSignedAggregateAndProof*(
self: ref Eth2Processor, src: MsgSource,
signedAggregateAndProof: SignedAggregateAndProof,
signedAggregateAndProof: phase0.SignedAggregateAndProof,
checkSignature = true, checkCover = true): Future[ValidationRes] {.async: (raises: [CancelledError]).} =
var wallTime = self.getCurrentBeaconTime()
let (afterGenesis, wallSlot) = wallTime.toSlot()

View File

@ -822,7 +822,7 @@ proc validateAttestation*(
proc validateAggregate*(
pool: ref AttestationPool,
batchCrypto: ref BatchCrypto,
signedAggregateAndProof: SignedAggregateAndProof,
signedAggregateAndProof: phase0.SignedAggregateAndProof,
wallTime: BeaconTime,
checkSignature = true, checkCover = true):
Future[Result[

View File

@ -838,7 +838,7 @@ template gossipMaxSize(T: untyped): uint32 =
# have lists bounded at MAX_VALIDATORS_PER_COMMITTEE (2048) items, thus
# having max sizes significantly smaller than GOSSIP_MAX_SIZE.
elif T is phase0.Attestation or T is phase0.AttesterSlashing or
T is SignedAggregateAndProof or T is phase0.SignedBeaconBlock or
T is phase0.SignedAggregateAndProof or T is phase0.SignedBeaconBlock or
T is altair.SignedBeaconBlock or T is SomeForkyLightClientObject:
GOSSIP_MAX_SIZE
else:
@ -2611,7 +2611,7 @@ proc broadcastBlsToExecutionChange*(
node.broadcast(topic, bls_to_execution_change)
proc broadcastAggregateAndProof*(
node: Eth2Node, proof: SignedAggregateAndProof):
node: Eth2Node, proof: phase0.SignedAggregateAndProof):
Future[SendResult] {.async: (raises: [CancelledError], raw: true).} =
let topic = getAggregateAndProofsTopic(
node.forkDigestAtEpoch(node.getWallEpoch))

View File

@ -1111,6 +1111,10 @@ proc addDenebMessageHandlers(
for topic in blobSidecarTopics(forkDigest):
node.network.subscribe(topic, basicParams)
proc addElectraMessageHandlers(
node: BeaconNode, forkDigest: ForkDigest, slot: Slot) =
node.addDenebMessageHandlers(forkDigest, slot)
proc removeAltairMessageHandlers(node: BeaconNode, forkDigest: ForkDigest) =
node.removePhase0MessageHandlers(forkDigest)
@ -1131,6 +1135,9 @@ proc removeDenebMessageHandlers(node: BeaconNode, forkDigest: ForkDigest) =
for topic in blobSidecarTopics(forkDigest):
node.network.unsubscribe(topic)
proc removeElectraMessageHandlers(node: BeaconNode, forkDigest: ForkDigest) =
node.removeDenebMessageHandlers(forkDigest)
proc updateSyncCommitteeTopics(node: BeaconNode, slot: Slot) =
template lastSyncUpdate: untyped =
node.consensusManager[].actionTracker.lastSyncUpdate
@ -1359,7 +1366,7 @@ proc updateGossipStatus(node: BeaconNode, slot: Slot) {.async.} =
removeAltairMessageHandlers, # bellatrix (altair handlers, different forkDigest)
removeCapellaMessageHandlers,
removeDenebMessageHandlers,
removeDenebMessageHandlers # maybe duplicate is correct, don't know yet
removeElectraMessageHandlers
]
for gossipFork in oldGossipForks:
@ -1372,7 +1379,7 @@ proc updateGossipStatus(node: BeaconNode, slot: Slot) {.async.} =
addAltairMessageHandlers, # bellatrix (altair handlers, different forkDigest)
addCapellaMessageHandlers,
addDenebMessageHandlers,
addDenebMessageHandlers # repeat is probably correct
addElectraMessageHandlers
]
for gossipFork in newGossipForks:
@ -1750,6 +1757,7 @@ proc installMessageValidators(node: BeaconNode) =
# beacon_attestation_{subnet_id}
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/phase0/p2p-interface.md#beacon_attestation_subnet_id
for it in SubnetId:
debugRaiseAssert "allow for electra.Attestation"
closureScope: # Needed for inner `proc`; don't lift it out of loop.
let subnet_id = it
node.network.addAsyncValidator(
@ -1762,9 +1770,10 @@ proc installMessageValidators(node: BeaconNode) =
# beacon_aggregate_and_proof
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.4/specs/phase0/p2p-interface.md#beacon_aggregate_and_proof
debugRaiseAssert "allow for electra.SignedAggregateAndProof"
node.network.addAsyncValidator(
getAggregateAndProofsTopic(digest), proc (
signedAggregateAndProof: SignedAggregateAndProof
signedAggregateAndProof: phase0.SignedAggregateAndProof
): Future[ValidationResult] {.async: (raises: [CancelledError]).} =
return toValidationResult(
await node.processor.processSignedAggregateAndProof(
@ -1848,6 +1857,9 @@ proc installMessageValidators(node: BeaconNode) =
node.processor[].processBlobSidecar(
MsgSource.gossip, blobSidecar, subnet_id)))
when consensusFork >= ConsensusFork.Electra:
discard
node.installLightClientMessageValidators()
proc stop(node: BeaconNode) =

View File

@ -801,7 +801,7 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
block:
if contentBody.isNone():
return RestApiResponse.jsonError(Http400, EmptyRequestBodyError)
let dres = decodeBody(seq[SignedAggregateAndProof], contentBody.get())
let dres = decodeBody(seq[phase0.SignedAggregateAndProof], contentBody.get())
if dres.isErr():
return RestApiResponse.jsonError(Http400,
InvalidAggregateAndProofObjectError,

View File

@ -196,6 +196,17 @@ type
NextSyncCommitteeBranch =
array[log2trunc(NEXT_SYNC_COMMITTEE_GINDEX), Eth2Digest]
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/validator.md#aggregateandproof
AggregateAndProof* = object
aggregator_index*: uint64 # `ValidatorIndex` after validation
aggregate*: Attestation
selection_proof*: ValidatorSig
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/validator.md#signedaggregateandproof
SignedAggregateAndProof* = object
message*: AggregateAndProof
signature*: ValidatorSig
# https://github.com/ethereum/consensus-specs/blob/v1.4.0-beta.5/specs/capella/light-client/sync-protocol.md#modified-lightclientheader
LightClientHeader* = object
beacon*: BeaconBlockHeader

View File

@ -44,7 +44,6 @@ type
createJsonFlavor RestJson
RestJson.useDefaultSerializationFor(
AggregateAndProof,
AttestationData,
BLSToExecutionChange,
BeaconBlockHeader,
@ -168,7 +167,6 @@ RestJson.useDefaultSerializationFor(
SetFeeRecipientRequest,
SetGasLimitRequest,
SetGraffitiRequest,
SignedAggregateAndProof,
SignedBLSToExecutionChange,
SignedBeaconBlockHeader,
SignedConsolidation,
@ -263,12 +261,14 @@ RestJson.useDefaultSerializationFor(
electra_mev.ExecutionPayloadAndBlobsBundle,
electra_mev.SignedBlindedBeaconBlock,
electra_mev.SignedBuilderBid,
phase0.AggregateAndProof,
phase0.Attestation,
phase0.AttesterSlashing,
phase0.BeaconBlock,
phase0.BeaconBlockBody,
phase0.BeaconState,
phase0.IndexedAttestation,
phase0.SignedAggregateAndProof,
phase0.SignedBeaconBlock,
phase0.TrustedAttestation
)
@ -365,7 +365,7 @@ type
seq[RestSignedContributionAndProof] |
seq[RestSyncCommitteeMessage] |
seq[RestSyncCommitteeSubscription] |
seq[SignedAggregateAndProof] |
seq[phase0.SignedAggregateAndProof] |
seq[SignedValidatorRegistrationV1] |
seq[ValidatorIndex] |
seq[RestBeaconCommitteeSelection] |
@ -2743,7 +2743,7 @@ proc readValue*(reader: var JsonReader[RestJson],
reader.raiseUnexpectedValue("Field `fork_info` is missing")
let data =
block:
let res = decodeJsonString(AggregateAndProof, data.get())
let res = decodeJsonString(phase0.AggregateAndProof, data.get())
if res.isErr():
reader.raiseUnexpectedValue(
"Incorrect field `aggregate_and_proof` format")

View File

@ -477,7 +477,7 @@ type
serializedFieldName: "aggregation_slot".}: Web3SignerAggregationSlotData
of Web3SignerRequestKind.AggregateAndProof:
aggregateAndProof* {.
serializedFieldName: "aggregate_and_proof".}: AggregateAndProof
serializedFieldName: "aggregate_and_proof".}: phase0.AggregateAndProof
of Web3SignerRequestKind.Attestation:
attestation*: AttestationData
of Web3SignerRequestKind.BlockV2:
@ -799,7 +799,7 @@ func init*(t: typedesc[Web3SignerRequest], fork: Fork,
)
func init*(t: typedesc[Web3SignerRequest], fork: Fork,
genesis_validators_root: Eth2Digest, data: AggregateAndProof,
genesis_validators_root: Eth2Digest, data: phase0.AggregateAndProof,
signingRoot: Opt[Eth2Digest] = Opt.none(Eth2Digest)
): Web3SignerRequest =
Web3SignerRequest(

View File

@ -80,7 +80,7 @@ proc getAggregatedAttestationPlain*(
## https://ethereum.github.io/beacon-APIs/#/Validator/getAggregatedAttestation
proc publishAggregateAndProofs*(
body: seq[SignedAggregateAndProof]
body: seq[phase0.SignedAggregateAndProof]
): RestPlainResponse {.
rest, endpoint: "/eth/v1/validator/aggregate_and_proofs",
meth: MethodPost.}

View File

@ -108,7 +108,7 @@ proc verify_block_signature*(
func compute_aggregate_and_proof_signing_root*(
fork: Fork, genesis_validators_root: Eth2Digest,
aggregate_and_proof: AggregateAndProof): Eth2Digest =
aggregate_and_proof: phase0.AggregateAndProof): Eth2Digest =
let
epoch = epoch(aggregate_and_proof.aggregate.data.slot)
domain = get_domain(
@ -117,7 +117,7 @@ func compute_aggregate_and_proof_signing_root*(
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/validator.md#broadcast-aggregate
func get_aggregate_and_proof_signature*(fork: Fork, genesis_validators_root: Eth2Digest,
aggregate_and_proof: AggregateAndProof,
aggregate_and_proof: phase0.AggregateAndProof,
privkey: ValidatorPrivKey): CookedSig =
let signing_root = compute_aggregate_and_proof_signing_root(
fork, genesis_validators_root, aggregate_and_proof)
@ -126,7 +126,7 @@ func get_aggregate_and_proof_signature*(fork: Fork, genesis_validators_root: Eth
proc verify_aggregate_and_proof_signature*(
fork: Fork, genesis_validators_root: Eth2Digest,
aggregate_and_proof: AggregateAndProof,
aggregate_and_proof: phase0.AggregateAndProof,
pubkey: ValidatorPubKey | CookedPubKey, signature: SomeSig): bool =
withTrust(signature):
let signing_root = compute_aggregate_and_proof_signing_root(

View File

@ -164,7 +164,7 @@ func block_signature_set*(
# See also: verify_aggregate_and_proof_signature
func aggregate_and_proof_signature_set*(
fork: Fork, genesis_validators_root: Eth2Digest,
aggregate_and_proof: AggregateAndProof,
aggregate_and_proof: phase0.AggregateAndProof,
pubkey: CookedPubKey, signature: CookedSig): SignatureSet =
let signing_root = compute_aggregate_and_proof_signing_root(
fork, genesis_validators_root, aggregate_and_proof)

View File

@ -1890,7 +1890,7 @@ proc produceSyncCommitteeContribution*(
proc publishAggregateAndProofs*(
vc: ValidatorClientRef,
data: seq[SignedAggregateAndProof],
data: seq[phase0.SignedAggregateAndProof],
strategy: ApiStrategyKind
): Future[bool] {.async.} =
const

View File

@ -85,7 +85,7 @@ proc serveAttestation(
return res
proc serveAggregateAndProof*(service: AttestationServiceRef,
proof: AggregateAndProof,
proof: phase0.AggregateAndProof,
validator: AttachedValidator): Future[bool] {.
async.} =
let
@ -117,8 +117,8 @@ proc serveAggregateAndProof*(service: AttestationServiceRef,
err_name = exc.name, err_msg = exc.msg
return false
let signedProof = SignedAggregateAndProof(message: proof,
signature: signature)
let signedProof = phase0.SignedAggregateAndProof(
message: proof, signature: signature)
logScope:
delay = vc.getDelay(slot.aggregate_deadline())
@ -306,7 +306,7 @@ proc produceAndPublishAggregates(service: AttestationServiceRef,
block:
var res: seq[Future[bool]]
for item in aggregateItems:
let proof = AggregateAndProof(
let proof = phase0.AggregateAndProof(
aggregator_index: item.aggregator_index,
aggregate: aggAttestation,
selection_proof: item.selection_proof

View File

@ -1537,8 +1537,8 @@ proc signAndSendAggregate(
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/validator.md#construct-aggregate
# https://github.com/ethereum/consensus-specs/blob/v1.4.0/specs/phase0/validator.md#aggregateandproof
var
msg = SignedAggregateAndProof(
message: AggregateAndProof(
msg = phase0.SignedAggregateAndProof(
message: phase0.AggregateAndProof(
aggregator_index: uint64 validator_index,
selection_proof: selectionProof))

View File

@ -252,7 +252,7 @@ proc routeAttestation*(
attestation, subnet_id, checkSignature = true)
proc routeSignedAggregateAndProof*(
router: ref MessageRouter, proof: SignedAggregateAndProof,
router: ref MessageRouter, proof: phase0.SignedAggregateAndProof,
checkSignature = true):
Future[SendResult] {.async: (raises: [CancelledError]).} =
## Validate and broadcast aggregate

View File

@ -685,7 +685,7 @@ proc registerAggregate*(
self: var ValidatorMonitor,
src: MsgSource,
seen_timestamp: BeaconTime,
aggregate_and_proof: AggregateAndProof,
aggregate_and_proof: phase0.AggregateAndProof,
attesting_indices: openArray[ValidatorIndex]) =
let
slot = aggregate_and_proof.aggregate.data.slot

View File

@ -735,7 +735,7 @@ proc getAttestationSignature*(v: AttachedValidator, fork: Fork,
proc getAggregateAndProofSignature*(v: AttachedValidator,
fork: Fork,
genesis_validators_root: Eth2Digest,
aggregate_and_proof: AggregateAndProof
aggregate_and_proof: phase0.AggregateAndProof
): Future[SignatureResult]
{.async: (raises: [CancelledError]).} =
case v.kind

View File

@ -60,7 +60,7 @@ suite "Message signatures":
fork0, genesis_validators_root1, slot, root, privkey0).toValidatorSig)
test "Aggregate and proof signatures":
let aggregate_and_proof = AggregateAndProof(
let aggregate_and_proof = phase0.AggregateAndProof(
aggregate: phase0.Attestation(
aggregation_bits: CommitteeValidatorsBits.init(8)))

View File

@ -678,7 +678,7 @@ block:
GetAggregatedAttestationResponse,
AgAttestation.toOpenArrayByte(0, len(AgAttestation) - 1),
Opt.some(contentType)).tryGet().data
agProof = AggregateAndProof(
agProof = phase0.AggregateAndProof(
aggregator_index: 1'u64,
aggregate: agAttestation,
selection_proof: ValidatorSig.fromHex(SomeSignature).get())