Skip to content
Closed

Rtw #7781

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AllTests-mainnet.md
Original file line number Diff line number Diff line change
Expand Up @@ -846,7 +846,7 @@ AllTests-mainnet
+ Signing aggregate and proof (getAggregateAndProofSignature(phase0)) OK
+ Signing aggregation slot (getSlotSignature()) OK
+ Signing attestation (getAttestationSignature()) OK
+ Signing payload attestation message (getPayloadAttestationSignature()) OK
+ Signing payload attestation (getPayloadAttestationSignature()) OK
+ Signing randao reveal (getEpochSignature()) OK
+ Signing validator registration (getBuilderSignature()) OK
+ Signing voluntary exit (getValidatorExitSignature()) OK
Expand Down
16 changes: 8 additions & 8 deletions beacon_chain/spec/signatures.nim
Original file line number Diff line number Diff line change
Expand Up @@ -480,28 +480,28 @@ proc verify_execution_payload_envelope_signature*(
fork, genesis_validators_root, epoch, msg)
blsVerify(pubkey, signing_root.data, signature)

# https://github.com/ethereum/consensus-specs/blob/v1.6.0-beta.0/specs/gloas/validator.md#constructing-a-payload-attestation
# https://github.com/ethereum/consensus-specs/blob/v1.6.1/specs/gloas/validator.md#constructing-a-payload-attestation
func compute_payload_attestation_message_signing_root*(
fork: Fork, genesis_validators_root: Eth2Digest,
msg: PayloadAttestationMessage): Eth2Digest =
data: PayloadAttestationData): Eth2Digest =
let
epoch = msg.data.slot.epoch
epoch = data.slot.epoch
domain = get_domain(
fork, DOMAIN_PTC_ATTESTER, epoch, genesis_validators_root)
compute_signing_root(msg, domain)
compute_signing_root(data, domain)

func get_payload_attestation_message_signature*(
fork: Fork, genesis_validators_root: Eth2Digest,
msg: PayloadAttestationMessage,
data: PayloadAttestationData,
privkey: ValidatorPrivKey): CookedSig =
let signing_root = compute_payload_attestation_message_signing_root(
fork, genesis_validators_root, msg)
fork, genesis_validators_root, data)
blsSign(privkey, signing_root.data)

proc verify_payload_attestation_message_signature*(
fork: Fork, genesis_validators_root: Eth2Digest,
msg: PayloadAttestationMessage,
data: PayloadAttestationData,
pubkey: ValidatorPubKey | CookedPubKey, signature: SomeSig): bool =
let signing_root = compute_payload_attestation_message_signing_root(
fork, genesis_validators_root, msg)
fork, genesis_validators_root, data)
blsVerify(pubkey, signing_root.data, signature)
2 changes: 1 addition & 1 deletion beacon_chain/spec/signatures_batch.nim
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ func payload_attestation_signature_set*(
payload_attestation_message: PayloadAttestationMessage,
pubkey: CookedPubKey, signature: CookedSig): SignatureSet =
let signing_root = compute_payload_attestation_message_signing_root(
fork, genesis_validators_root, payload_attestation_message)
fork, genesis_validators_root, payload_attestation_message.data)

SignatureSet.init(pubkey, signing_root, signature)

Expand Down
107 changes: 107 additions & 0 deletions beacon_chain/validators/beacon_validators.nim
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,104 @@ proc sendSyncCommitteeContributions(
asyncSpawn signAndSendContribution(
node, validator, subcommitteeIdx, head, slot)

proc checkPayloadPresent(
node: BeaconNode, beacon_block_root: Eth2Digest): bool =
## Check if we received the payload envelope for
## this slot and a corresponding block

let blockData = node.dag.getForkedBlock(beacon_block_root).valueOr:
return false

withBlck(blockData):
when consensusFork >= ConsensusFork.Gloas:
var envelope: TrustedSignedExecutionPayloadEnvelope
if not node.dag.db.getExecutionPayloadEnvelope(
beacon_block_root, envelope):
return false

# check that the envelope correctly references this block
if envelope.message.beacon_block_root != beacon_block_root:
return false
return true
else:
return true

proc checkBlobDataAvailable*(
node: BeaconNode, beacon_block_root: Eth2Digest
): bool =
## Check if the blob sidecars for this slot are available
debugGloasComment"TODO - check for blob availability"
return true

proc createAndSendPayloadAttestation(node: BeaconNode,
fork: Fork,
genesis_validators_root: Eth2Digest,
validator: AttachedValidator,
validator_index: ValidatorIndex,
slot: Slot,
beacon_block_root: Eth2Digest)
{.async: (raises: [CancelledError]).} =
let
payload_present = node.checkPayloadPresent(beacon_block_root)
blob_data_available = node.checkBlobDataAvailable(beacon_block_root)

let data = PayloadAttestationData(
beacon_block_root: beacon_block_root,
slot: slot,
payload_present: payload_present,
blob_data_available: blob_data_available
)

let signature = block:
let res = await validator.getPayloadAttestationSignature(
fork, genesis_validators_root, data)
if res.isErr():
warn "Unble to sign payload attestation",
validator = shortLog(validator),
data = shortLog(data),
error_msg = res.error()
return
res.get()

let message = PayloadAttestationMessage(
validator_index: validator_index.uint64,
data: data,
signature: signature
)

discard await node.router.routePayloadAttestationMessage(
message, checkSignature = false, checkValidator = false)

proc sendPayloadAttestations(
node: BeaconNode, head: BlockRef, slot: Slot) =
## Perform payload attestation duties for PTC members

let consensusFork = node.dag.cfg.consensusForkAtEpoch(slot.epoch)
if consensusFork < ConsensusFork.Gloas:
return

# Get the beacon block root for the slot we are attesting to
let target = head.atSlot(slot)
if head != target.blck:
notice "Payload attestation to a state in the past",
attestationTarget = shortLog(target),
head = shortLog(head)

let
fork = node.dag.forkAtEpoch(slot.epoch)
genesis_validators_root = node.dag.genesis_validators_root

withState(node.dag.headState):
when consensusFork >= ConsensusFork.Gloas:
var cache: StateCache
for vidx in get_ptc(forkyState.data, slot, cache):
let validator = node.getValidatorForDuties(vidx, slot).valueOr:
continue

asyncSpawn createAndSendPayloadAttestation(
node, fork, genesis_validators_root, validator, vidx, slot,
target.blck.root )

proc handleProposal(node: BeaconNode, head: BlockRef, slot: Slot):
Future[BlockRef] {.async: (raises: [CancelledError]).} =
## Perform the proposal for the given slot, iff we have a validator attached
Expand Down Expand Up @@ -1263,6 +1361,15 @@ proc handleValidatorDuties*(node: BeaconNode, lastSlot, slot: Slot) {.async: (ra
sendAttestations(node, head, slot)
sendSyncCommitteeMessages(node, head, slot)

let payloadAttestationCutOff = node.beaconClock.fromNow(
slot.payload_attestation_deadline(node.dag.timeParams))
if payloadAttestationCutOff.inFuture:
debug "Waiting to send payload attestations",
payloadAttestationCutOff = shortLog(payloadAttestationCutOff.offset)
await sleepAsync(payloadAttestationCutOff.offset)

sendPayloadAttestations(node, head, slot)

updateValidatorMetrics(node) # the important stuff is done, update the vanity numbers

# https://github.com/ethereum/consensus-specs/blob/v1.5.0-beta.2/specs/phase0/validator.md#broadcast-aggregate
Expand Down
3 changes: 2 additions & 1 deletion beacon_chain/validators/message_router.nim
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,8 @@ proc routeBlsToExecutionChange*(
proc routePayloadAttestationMessage*(
router: ref MessageRouter,
message: PayloadAttestationMessage,
checkSignature, checkValidator: bool = true):
checkSignature: bool = true,
checkValidator: bool = true):
Future[SendResult] {.async: (raises: [CancelledError]).} =
block:
let res = await router.processor.processPayloadAttestationMessage(
Expand Down
4 changes: 2 additions & 2 deletions beacon_chain/validators/validator_pool.nim
Original file line number Diff line number Diff line change
Expand Up @@ -803,14 +803,14 @@ proc getBuilderSignature*(v: AttachedValidator, genesis_fork_version: Version,
# https://github.com/ethereum/consensus-specs/blob/v1.6.1/specs/gloas/validator.md#constructing-payload_attestations
proc getPayloadAttestationSignature*(v: AttachedValidator, fork: Fork,
genesis_validators_root: Eth2Digest,
message: PayloadAttestationMessage,
data: PayloadAttestationData,
): Future[SignatureResult]
{.async: (raises: [CancelledError]).} =
case v.kind
of ValidatorKind.Local:
SignatureResult.ok(
get_payload_attestation_message_signature(
fork, genesis_validators_root, message,
fork, genesis_validators_root, data,
v.data.privateKey).toValidatorSig())
of ValidatorKind.Remote:
return SignatureResult.err("Remote signer lacks payload attestation support")
24 changes: 10 additions & 14 deletions tests/test_signing_node.nim
Original file line number Diff line number Diff line change
Expand Up @@ -837,25 +837,21 @@ block:
sres2.get() == rres2.get()
sres3.get() == rres3.get()

asyncTest "Signing payload attestation message (getPayloadAttestationSignature())":
asyncTest "Signing payload attestation (getPayloadAttestationSignature())":
let
payloadMessage = PayloadAttestationMessage(
validator_index: 100,
data: PayloadAttestationData(
beacon_block_root: SomeOtherRoot,
slot: Slot(10),
payload_present: true,
blob_data_available: true
),
signature: ValidatorSig.fromHex(SomeSignature).get()
payloadData = PayloadAttestationData(
beacon_block_root: SomeOtherRoot,
slot: Slot(10),
payload_present: true,
blob_data_available: true
)

sres1 = await validator1.getPayloadAttestationSignature(SigningFork,
GenesisValidatorsRoot, payloadMessage)
GenesisValidatorsRoot, payloadData)
sres2 = await validator2.getPayloadAttestationSignature(SigningFork,
GenesisValidatorsRoot, payloadMessage)
GenesisValidatorsRoot, payloadData)
sres3 = await validator3.getPayloadAttestationSignature(SigningFork,
GenesisValidatorsRoot, payloadMessage)

GenesisValidatorsRoot, payloadData)
check:
sres1.isOk()
sres2.isOk()
Expand Down
16 changes: 8 additions & 8 deletions tests/test_spec_signatures.nim
Original file line number Diff line number Diff line change
Expand Up @@ -244,17 +244,17 @@ suite "Message signatures":

test "payload attestation message signatures":
let
msg0 = default(PayloadAttestationMessage)
msg1 = (var m = msg0; m.data.slot = m.data.slot + 1; m)
sig = get_payload_attestation_message_signature(fork0, gvr0, msg0, privkey0).toValidatorSig
data0 = default(PayloadAttestationData)
data1 = (var d = data0; d.slot = d.slot + 1; d)
sig = get_payload_attestation_message_signature(fork0, gvr0, data0, privkey0).toValidatorSig

check:
verify_payload_attestation_message_signature(fork0, gvr0, msg0, pubkey0, sig)
verify_payload_attestation_message_signature(fork0, gvr0, data0, pubkey0, sig)

not verify_payload_attestation_message_signature(fork1, gvr0, msg0, pubkey0, sig)
not verify_payload_attestation_message_signature(fork0, gvr1, msg0, pubkey0, sig)
not verify_payload_attestation_message_signature(fork0, gvr0, msg1, pubkey0, sig)
not verify_payload_attestation_message_signature(fork0, gvr0, msg0, pubkey1, sig)
not verify_payload_attestation_message_signature(fork1, gvr0, data0, pubkey0, sig)
not verify_payload_attestation_message_signature(fork0, gvr1, data0, pubkey0, sig)
not verify_payload_attestation_message_signature(fork0, gvr0, data1, pubkey0, sig)
not verify_payload_attestation_message_signature(fork0, gvr0, data0, pubkey1, sig)

test "BLS to execution change signatures":
let
Expand Down
Loading