Skip to content

Commit

Permalink
feat: implement PayloadProof function (#14356)
Browse files Browse the repository at this point in the history
* feat: implement function `PayloadProof` to calculate proof of execution payload

* remove comments

* feat: implement function to compute field roots of

* feat: implement function to compute `BeaconBlock` field roots and add tests

* fix dependencies

* check if interface implements the assserted type

* fix: lint

* replace `ok != true` with `!ok`

* remove unused parameter from `PayloadProof`

* remove test and move `PayloadProof` to `blocks/proofs.go`

* remove `PayloadProof` from `fieldtrie`

* replace `fieldtrie.ProofFromMerkleLayers` with `trie.ProofFromMerkleLayers`

* Update container/trie/sparse_merkle.go

* update dependencies

---------

Co-authored-by: Radosław Kapka <[email protected]>
Co-authored-by: Radosław Kapka <[email protected]>
  • Loading branch information
3 people authored Aug 21, 2024
1 parent ed3d7d4 commit 7c213ce
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 19 deletions.
15 changes: 0 additions & 15 deletions beacon-chain/state/fieldtrie/field_trie_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,6 @@ import (
ethpb "github.com/prysmaticlabs/prysm/v5/proto/prysm/v1alpha1"
)

// ProofFromMerkleLayers creates a proof starting at the leaf index of the state Merkle layers.
func ProofFromMerkleLayers(layers [][][]byte, startingLeafIndex int) [][]byte {
// The merkle tree structure looks as follows:
// [[r1, r2, r3, r4], [parent1, parent2], [root]]
proof := make([][]byte, 0)
currentIndex := startingLeafIndex
for i := 0; i < len(layers)-1; i++ {
neighborIdx := currentIndex ^ 1
neighbor := layers[i][neighborIdx]
proof = append(proof, neighbor)
currentIndex = currentIndex / 2
}
return proof
}

func (f *FieldTrie) validateIndices(idxs []uint64) error {
length := f.length
if f.dataType == types.CompressedArray {
Expand Down
1 change: 1 addition & 0 deletions beacon-chain/state/state-native/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ go_library(
"//consensus-types/primitives:go_default_library",
"//container/multi-value-slice:go_default_library",
"//container/slice:go_default_library",
"//container/trie:go_default_library",
"//crypto/bls:go_default_library",
"//crypto/hash:go_default_library",
"//encoding/bytesutil:go_default_library",
Expand Down
8 changes: 4 additions & 4 deletions beacon-chain/state/state-native/proofs.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import (
"context"
"encoding/binary"

"github.com/prysmaticlabs/prysm/v5/beacon-chain/state/fieldtrie"
"github.com/prysmaticlabs/prysm/v5/beacon-chain/state/state-native/types"
"github.com/prysmaticlabs/prysm/v5/container/trie"
"github.com/prysmaticlabs/prysm/v5/encoding/bytesutil"
"github.com/prysmaticlabs/prysm/v5/runtime/version"
)
Expand Down Expand Up @@ -56,7 +56,7 @@ func (b *BeaconState) CurrentSyncCommitteeProof(ctx context.Context) ([][]byte,
if err := b.recomputeDirtyFields(ctx); err != nil {
return nil, err
}
return fieldtrie.ProofFromMerkleLayers(b.merkleLayers, types.CurrentSyncCommittee.RealPosition()), nil
return trie.ProofFromMerkleLayers(b.merkleLayers, types.CurrentSyncCommittee.RealPosition()), nil
}

// NextSyncCommitteeProof from the state's Merkle trie representation.
Expand All @@ -74,7 +74,7 @@ func (b *BeaconState) NextSyncCommitteeProof(ctx context.Context) ([][]byte, err
if err := b.recomputeDirtyFields(ctx); err != nil {
return nil, err
}
return fieldtrie.ProofFromMerkleLayers(b.merkleLayers, types.NextSyncCommittee.RealPosition()), nil
return trie.ProofFromMerkleLayers(b.merkleLayers, types.NextSyncCommittee.RealPosition()), nil
}

// FinalizedRootProof crafts a Merkle proof for the finalized root
Expand Down Expand Up @@ -102,7 +102,7 @@ func (b *BeaconState) FinalizedRootProof(ctx context.Context) ([][]byte, error)
epochRoot := bytesutil.ToBytes32(epochBuf)
proof := make([][]byte, 0)
proof = append(proof, epochRoot[:])
branch := fieldtrie.ProofFromMerkleLayers(b.merkleLayers, types.FinalizedCheckpoint.RealPosition())
branch := trie.ProofFromMerkleLayers(b.merkleLayers, types.FinalizedCheckpoint.RealPosition())
proof = append(proof, branch...)
return proof, nil
}
1 change: 1 addition & 0 deletions consensus-types/blocks/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ go_library(
importpath = "github.com/prysmaticlabs/prysm/v5/consensus-types/blocks",
visibility = ["//visibility:public"],
deps = [
"//beacon-chain/state/stateutil:go_default_library",
"//config/fieldparams:go_default_library",
"//config/params:go_default_library",
"//consensus-types:go_default_library",
Expand Down
73 changes: 73 additions & 0 deletions consensus-types/blocks/proofs.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,23 @@ package blocks
import (
"context"
"encoding/binary"
"errors"
"fmt"

"github.com/prysmaticlabs/prysm/v5/beacon-chain/state/stateutil"
"github.com/prysmaticlabs/prysm/v5/config/params"
"github.com/prysmaticlabs/prysm/v5/container/trie"
"github.com/prysmaticlabs/prysm/v5/crypto/hash/htr"
"github.com/prysmaticlabs/prysm/v5/encoding/ssz"
"github.com/prysmaticlabs/prysm/v5/runtime/version"
"go.opencensus.io/trace"
)

const (
payloadFieldIndex = 9
bodyFieldIndex = 4
)

func ComputeBlockBodyFieldRoots(ctx context.Context, blockBody *BeaconBlockBody) ([][]byte, error) {
_, span := trace.StartSpan(ctx, "blocks.ComputeBlockBodyFieldRoots")
defer span.End()
Expand Down Expand Up @@ -172,3 +180,68 @@ func ComputeBlockBodyFieldRoots(ctx context.Context, blockBody *BeaconBlockBody)

return fieldRoots, nil
}

func ComputeBlockFieldRoots(ctx context.Context, block *BeaconBlock) ([][]byte, error) {
_, span := trace.StartSpan(ctx, "blocks.ComputeBlockFieldRoots")
defer span.End()

if block == nil {
return nil, errNilBlock
}

fieldRoots := make([][]byte, 5)
for i := range fieldRoots {
fieldRoots[i] = make([]byte, 32)
}

// Slot
slotRoot := ssz.Uint64Root(uint64(block.slot))
copy(fieldRoots[0], slotRoot[:])

// Proposer Index
proposerRoot := ssz.Uint64Root(uint64(block.proposerIndex))
copy(fieldRoots[1], proposerRoot[:])

// Parent Root
copy(fieldRoots[2], block.parentRoot[:])

// State Root
copy(fieldRoots[3], block.stateRoot[:])

// block body Root
blockBodyRoot, err := block.body.HashTreeRoot()
if err != nil {
return nil, err
}
copy(fieldRoots[4], blockBodyRoot[:])

return fieldRoots, nil
}

func PayloadProof(ctx context.Context, block *BeaconBlock) ([][]byte, error) {
i := block.Body()
blockBody, ok := i.(*BeaconBlockBody)
if !ok {
return nil, errors.New("failed to cast block body")
}

blockBodyFieldRoots, err := ComputeBlockBodyFieldRoots(ctx, blockBody)
if err != nil {
return nil, err
}

blockBodyFieldRootsTrie := stateutil.Merkleize(blockBodyFieldRoots)
blockBodyProof := trie.ProofFromMerkleLayers(blockBodyFieldRootsTrie, payloadFieldIndex)

beaconBlockFieldRoots, err := ComputeBlockFieldRoots(ctx, block)
if err != nil {
return nil, err
}

beaconBlockFieldRootsTrie := stateutil.Merkleize(beaconBlockFieldRoots)
beaconBlockProof := trie.ProofFromMerkleLayers(beaconBlockFieldRootsTrie, bodyFieldIndex)

finalProof := append(blockBodyProof, beaconBlockProof...)

return finalProof, nil
}
15 changes: 15 additions & 0 deletions container/trie/sparse_merkle.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,3 +259,18 @@ func (m *SparseMerkleTrie) NumOfItems() int {
}
return len(m.originalItems)
}

// ProofFromMerkleLayers creates a proof starting at the leaf index of the merkle layers.
func ProofFromMerkleLayers(layers [][][]byte, startingLeafIndex int) [][]byte {
// The merkle tree structure looks as follows:
// [[r1, r2, r3, r4], [parent1, parent2], [root]]
proof := make([][]byte, 0)
currentIndex := startingLeafIndex
for i := 0; i < len(layers)-1; i++ {
neighborIdx := currentIndex ^ 1
neighbor := layers[i][neighborIdx]
proof = append(proof, neighbor)
currentIndex = currentIndex / 2
}
return proof
}

0 comments on commit 7c213ce

Please sign in to comment.