Skip to content
Merged
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
31 changes: 19 additions & 12 deletions clients/consensus/rpc/types.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,29 @@
package rpc

// ExecutionProof represents a cryptographic proof of execution that
// an execution payload is valid.
// ExecutionProof represents a signed cryptographic proof attesting that
// an execution payload is valid, as returned by the Lighthouse
// /eth/v1/beacon/execution_proofs/{block_root} endpoint.
type ExecutionProof struct {
// Which proof type (zkVM+EL combination) this proof belongs to
ProofId uint8 `json:"proof_id"`
Message ExecutionProofMessage `json:"message"`
ValidatorIndex string `json:"validator_index"`
Signature string `json:"signature"`
}

// The slot of the beacon block this proof validates
Slot string `json:"slot"`
// ExecutionProofMessage is the inner message of an ExecutionProof.
type ExecutionProofMessage struct {
// Which proof type (zkVM+EL combination) this proof belongs to.
ProofType uint8 `json:"proof_type"`

// The block hash of the execution payload this proof validates
BlockHash string `json:"block_hash"`
// Hex-encoded proof bytes (e.g. "0x...").
ProofData string `json:"proof_data"`

// The beacon block root corresponding to the beacon block
BlockRoot string `json:"block_root"`
// Public input the proof commits to.
PublicInput ExecutionProofPublicInput `json:"public_input"`
}

// The actual proof data (byte array)
ProofData []byte `json:"proof_data"`
// ExecutionProofPublicInput is the public input committed to by an execution proof.
type ExecutionProofPublicInput struct {
NewPayloadRequestRoot string `json:"new_payload_request_root"`
}

// ExecutionProofsResponse represents the API response for execution proofs
Expand Down
52 changes: 18 additions & 34 deletions handlers/slot.go
Original file line number Diff line number Diff line change
Expand Up @@ -1045,7 +1045,7 @@ func getSlotPageBlockData(ctx context.Context, blockData *services.CombinedBlock
}

// Fetch execution proofs for this block
getSlotPageExecutionProofs(pageData, blockData.Root)
getSlotPageExecutionProofs(pageData, blockData.Root, uint64(blockData.Header.Message.Slot))

// Load execution payload bids for ePBS (gloas+) blocks
if blockData.Block.Version >= spec.DataVersionGloas {
Expand Down Expand Up @@ -1292,7 +1292,7 @@ func getSlotPageConsolidationRequests(pageData *models.SlotPageBlockData, consol
pageData.ConsolidationRequestsCount = uint64(len(pageData.ConsolidationRequests))
}

func getSlotPageExecutionProofs(pageData *models.SlotPageBlockData, blockRoot phase0.Root) {
func getSlotPageExecutionProofs(pageData *models.SlotPageBlockData, blockRoot phase0.Root, slot uint64) {
// Get a ready beacon client to fetch execution proofs
beaconIndexer := services.GlobalBeaconService.GetBeaconIndexer()
client := beaconIndexer.GetReadyClient(false)
Expand All @@ -1316,46 +1316,30 @@ func getSlotPageExecutionProofs(pageData *models.SlotPageBlockData, blockRoot ph
return
}

// Log successful fetch
logrus.WithFields(logrus.Fields{
"blockRoot": fmt.Sprintf("0x%x", blockRoot),
"proofCount": len(proofsResponse.Data),
}).Info("Successfully fetched execution proofs")

// Convert RPC proofs to page data model
pageData.ExecutionProofsCount = uint64(len(proofsResponse.Data))
pageData.ExecutionProofs = make([]*models.SlotPageExecutionProof, pageData.ExecutionProofsCount)
for i, proof := range proofsResponse.Data {
// Parse slot from string
slot, err := strconv.ParseUint(proof.Slot, 10, 64)
if err != nil {
logrus.WithError(err).WithField("slot", proof.Slot).Warn("Error parsing proof slot")
continue
}

// Decode hex strings
blockHash, err := hex.DecodeString(strings.TrimPrefix(proof.BlockHash, "0x"))
if err != nil {
logrus.WithError(err).WithField("blockHash", proof.BlockHash).Warn("Error decoding block hash")
continue
}
// Block hash is sourced from the execution payload on the page itself,
// since the Lighthouse execution_proofs response does not include it.
var blockHash []byte
if pageData.ExecutionData != nil {
blockHash = pageData.ExecutionData.BlockHash
}

blockRootBytes, err := hex.DecodeString(strings.TrimPrefix(proof.BlockRoot, "0x"))
pageData.ExecutionProofs = make([]*models.SlotPageExecutionProof, 0, len(proofsResponse.Data))
for _, proof := range proofsResponse.Data {
proofData, err := hex.DecodeString(strings.TrimPrefix(proof.Message.ProofData, "0x"))
if err != nil {
logrus.WithError(err).WithField("blockRoot", proof.BlockRoot).Warn("Error decoding block root")
logrus.WithError(err).WithField("proofType", proof.Message.ProofType).Warn("Error decoding proof data")
continue
}

// proof.ProofData is already a byte array from JSON, no need to decode

pageData.ExecutionProofs[i] = &models.SlotPageExecutionProof{
ProofId: proof.ProofId,
pageData.ExecutionProofs = append(pageData.ExecutionProofs, &models.SlotPageExecutionProof{
ProofId: proof.Message.ProofType,
Slot: slot,
BlockHash: blockHash,
BlockRoot: blockRootBytes,
ProofData: proof.ProofData,
}
BlockRoot: blockRoot[:],
ProofData: proofData,
})
}
pageData.ExecutionProofsCount = uint64(len(pageData.ExecutionProofs))
}

func getSlotPageBids(pageData *models.SlotPageBlockData) {
Expand Down
2 changes: 1 addition & 1 deletion templates/slot/proofs.html
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
<div class="col-md-10">
{{ len $proof.ProofData }} bytes
{{ if gt (len $proof.ProofData) 1024 }}
({{ printf "%.2f" (div (len $proof.ProofData) 1024.0) }} KB)
({{ printf "%.2f" (div (float64 (len $proof.ProofData)) 1024.0) }} KB)
{{ end }}
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion templates/slot/slot.html
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ <h1 class="h4 my-2 mb-md-0 h1-pager">
<a class="nav-link" id="attestations-tab" data-bs-toggle="tab" href="#attestations" role="tab" aria-controls="attestations" aria-selected="false">Attestations <span class="badge bg-secondary text-white">{{ .Block.AttestationsCount }}</span></a>
</li>
<li class="nav-item">
<a class="nav-link" id="proofs-tab" data-bs-toggle="tab" href="#proofs" role="tab" aria-controls="proofs" aria-selected="false">Proofs</a>
<a class="nav-link" id="proofs-tab" data-bs-toggle="tab" href="#proofs" role="tab" aria-controls="proofs" aria-selected="false">Proofs <span class="badge bg-secondary text-white">{{ .Block.ExecutionProofsCount }}</span></a>
</li>
{{ if gt .Block.PtcVotesCount 0 }}
<li class="nav-item">
Expand Down