Skip to content
Open
4 changes: 3 additions & 1 deletion AllTests-mainnet.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,15 @@ AllTests-mainnet
+ sanity check electra blocks [Preset: mainnet] OK
+ sanity check electra states [Preset: mainnet] OK
+ sanity check electra states, reusing buffers [Preset: mainnet] OK
+ sanity check execution payload envelopes [Preset: mainnet] OK
+ sanity check fulu and cross-fork getState rollback [Preset: mainnet] OK
+ sanity check fulu blocks [Preset: mainnet] OK
+ sanity check fulu states [Preset: mainnet] OK
+ sanity check fulu states, reusing buffers [Preset: mainnet] OK
+ sanity check genesis roundtrip [Preset: mainnet] OK
sanity check gloas and cross-fork getState rollback [Preset: mainnet] Skip
sanity check gloas blocks [Preset: mainnet] Skip
+ sanity check gloas data columns [Preset: mainnet] OK
sanity check gloas states [Preset: mainnet] Skip
sanity check gloas states, reusing buffers [Preset: mainnet] Skip
+ sanity check phase0 blocks [Preset: mainnet] OK
Expand Down Expand Up @@ -846,7 +848,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
20 changes: 17 additions & 3 deletions beacon_chain/beacon_chain_db.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1087,9 +1087,11 @@ proc getDataColumnSidecarSZ*(db: BeaconChainDB, root: Eth2Digest,
assign(dataPtr[], data)
db.columns.get(columnkey(root, index), decode).expectDb()

proc getDataColumnSidecar*(db: BeaconChainDB, root: Eth2Digest, index: ColumnIndex,
value: var fulu.DataColumnSidecar): bool =
if db.columns == nil: # Fulu has not been scheduled; DB table does not exist
proc getDataColumnSidecar*[
T: fulu.DataColumnSidecar | gloas.DataColumnSidecar](
db: BeaconChainDB, root: Eth2Digest,
index: ColumnIndex, value: var T): bool =
if db.columns == nil: # Gloas has not been scheduled; DB table does not exist
return false
db.columns.getSZSSZ(columnkey(root, index), value) == GetResult.found

Expand Down Expand Up @@ -1322,6 +1324,18 @@ proc containsState*(db: BeaconChainDB, key: Eth2Digest, legacy: bool = true): bo

(legacy and db.v0.containsState(key))

proc containsExecutionPayloadEnvelope*(
db: BeaconChainDB, root: Eth2Digest): bool =
if db.envelopes == nil:
return false
db.envelopes.contains(root.data).expectDb()

proc containsDataColumnSidecar*(
db: BeaconChainDB, root: Eth2Digest, index: ColumnIndex): bool =
if db.columns == nil:
return false
db.columns.contains(columnkey(root, index)).expectDb()

proc getBeaconBlockSummary*(db: BeaconChainDB, root: Eth2Digest):
Opt[BeaconBlockSummary] =
var summary: BeaconBlockSummary
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
105 changes: 105 additions & 0 deletions beacon_chain/validators/beacon_validators.nim
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,102 @@ proc sendSyncCommitteeContributions(
asyncSpawn signAndSendContribution(
node, validator, subcommitteeIdx, head, slot)

proc checkPayloadPresent(
node: BeaconNode, beacon_block_root: Eth2Digest): bool =
let blokData = node.dag.getForkedBlock(beacon_block_root).valueOr:
return false

withBlck(blokData):
when consensusFork >= ConsensusFork.Gloas:
node.dag.db.containsExecutionPayloadEnvelope(beacon_block_root)
else:
true

proc checkBlobDataAvailable(
node: BeaconNode, beacon_block_root: Eth2Digest): bool =
let blckData = node.dag.getForkedBlock(beacon_block_root).valueOr:
return false

withBlck(blckData):
when consensusFork >= ConsensusFork.Gloas:
# check that our custody columns are available
for columnIdx in node.dataColumnQuarantine.custodyColumns:
if not node.dag.db.containsDataColumnSidecar(
beacon_block_root, columnIdx):
return false
true
else:
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 +1359,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
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")
Loading
Loading