Skip to content

Commit

Permalink
Add Hasher To State Data Types (#5244)
Browse files Browse the repository at this point in the history
* add hasher
* re-order stuff
* Merge refs/heads/master into addHasher
* Merge refs/heads/master into addHasher
* Merge refs/heads/master into addHasher
* Merge refs/heads/master into addHasher
* Merge refs/heads/master into addHasher
* Merge refs/heads/master into addHasher
* Merge refs/heads/master into addHasher
* Merge refs/heads/master into addHasher
* Merge refs/heads/master into addHasher
* Merge refs/heads/master into addHasher
  • Loading branch information
nisdas authored Mar 31, 2020
1 parent e22365c commit 7e50c36
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 68 deletions.
1 change: 0 additions & 1 deletion beacon-chain/state/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ go_library(
"//shared/sliceutil:go_default_library",
"@com_github_gogo_protobuf//proto:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_protolambda_zssz//merkle:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
"@com_github_prysmaticlabs_go_bitfield//:go_default_library",
"@io_opencensus_go//trace:go_default_library",
Expand Down
10 changes: 7 additions & 3 deletions beacon-chain/state/field_trie.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/hashutil"
"github.com/prysmaticlabs/prysm/shared/memorypool"
)

Expand Down Expand Up @@ -209,8 +210,9 @@ func handleByteArrays(val [][]byte, indices []uint64, convertAll bool) ([][32]by

func handleEth1DataSlice(val []*ethpb.Eth1Data, indices []uint64, convertAll bool) ([][32]byte, error) {
roots := [][32]byte{}
hasher := hashutil.CustomSHA256Hasher()
rootCreater := func(input *ethpb.Eth1Data) error {
newRoot, err := stateutil.Eth1Root(input)
newRoot, err := stateutil.Eth1Root(hasher, input)
if err != nil {
return err
}
Expand All @@ -237,8 +239,9 @@ func handleEth1DataSlice(val []*ethpb.Eth1Data, indices []uint64, convertAll boo

func handleValidatorSlice(val []*ethpb.Validator, indices []uint64, convertAll bool) ([][32]byte, error) {
roots := [][32]byte{}
hasher := hashutil.CustomSHA256Hasher()
rootCreater := func(input *ethpb.Validator) error {
newRoot, err := stateutil.ValidatorRoot(input)
newRoot, err := stateutil.ValidatorRoot(hasher, input)
if err != nil {
return err
}
Expand All @@ -265,8 +268,9 @@ func handleValidatorSlice(val []*ethpb.Validator, indices []uint64, convertAll b

func handlePendingAttestation(val []*pb.PendingAttestation, indices []uint64, convertAll bool) ([][32]byte, error) {
roots := [][32]byte{}
hasher := hashutil.CustomSHA256Hasher()
rootCreator := func(input *pb.PendingAttestation) error {
newRoot, err := stateutil.PendingAttestationRoot(input)
newRoot, err := stateutil.PendingAttestationRoot(hasher, input)
if err != nil {
return err
}
Expand Down
12 changes: 6 additions & 6 deletions beacon-chain/state/state_trie.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (

"github.com/gogo/protobuf/proto"
"github.com/pkg/errors"
"github.com/protolambda/zssz/merkle"
coreutils "github.com/prysmaticlabs/prysm/beacon-chain/core/state/stateutils"
"github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil"
pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
Expand Down Expand Up @@ -213,7 +212,7 @@ func (b *BeaconState) HashTreeRoot(ctx context.Context) ([32]byte, error) {
// pads the leaves to a power-of-two length.
func merkleize(leaves [][]byte) [][][]byte {
hashFunc := hashutil.CustomSHA256Hasher()
layers := make([][][]byte, merkle.GetDepth(uint64(len(leaves)))+1)
layers := make([][][]byte, stateutil.GetDepth(uint64(len(leaves)))+1)
for len(leaves) != 32 {
leaves = append(leaves, make([]byte, 32))
}
Expand All @@ -240,6 +239,7 @@ func merkleize(leaves [][]byte) [][][]byte {
}

func (b *BeaconState) rootSelector(field fieldIndex) ([32]byte, error) {
hasher := hashutil.CustomSHA256Hasher()
switch field {
case genesisTime:
return stateutil.Uint64Root(b.state.GenesisTime), nil
Expand Down Expand Up @@ -282,7 +282,7 @@ func (b *BeaconState) rootSelector(field fieldIndex) ([32]byte, error) {
case historicalRoots:
return stateutil.HistoricalRootsRoot(b.state.HistoricalRoots)
case eth1Data:
return stateutil.Eth1Root(b.state.Eth1Data)
return stateutil.Eth1Root(hasher, b.state.Eth1Data)
case eth1DataVotes:
if featureconfig.Get().EnableFieldTrie {
if b.rebuildTrie[field] {
Expand Down Expand Up @@ -360,11 +360,11 @@ func (b *BeaconState) rootSelector(field fieldIndex) ([32]byte, error) {
case justificationBits:
return bytesutil.ToBytes32(b.state.JustificationBits), nil
case previousJustifiedCheckpoint:
return stateutil.CheckpointRoot(b.state.PreviousJustifiedCheckpoint)
return stateutil.CheckpointRoot(hasher, b.state.PreviousJustifiedCheckpoint)
case currentJustifiedCheckpoint:
return stateutil.CheckpointRoot(b.state.CurrentJustifiedCheckpoint)
return stateutil.CheckpointRoot(hasher, b.state.CurrentJustifiedCheckpoint)
case finalizedCheckpoint:
return stateutil.CheckpointRoot(b.state.FinalizedCheckpoint)
return stateutil.CheckpointRoot(hasher, b.state.FinalizedCheckpoint)
}
return [32]byte{}, errors.New("invalid field index provided")
}
Expand Down
1 change: 1 addition & 0 deletions beacon-chain/state/stateutil/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ go_test(
"//proto/beacon/p2p/v1:go_default_library",
"//shared/bytesutil:go_default_library",
"//shared/featureconfig:go_default_library",
"//shared/hashutil:go_default_library",
"//shared/interop:go_default_library",
"//shared/params:go_default_library",
"//shared/testutil:go_default_library",
Expand Down
43 changes: 24 additions & 19 deletions beacon-chain/state/stateutil/attestations.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/featureconfig"
"github.com/prysmaticlabs/prysm/shared/hashutil"
"github.com/prysmaticlabs/prysm/shared/params"
)

Expand All @@ -24,16 +25,16 @@ func EpochAttestationsRoot(atts []*pb.PendingAttestation) ([32]byte, error) {

// PendingAttestationRoot describes a method from which the hash tree root
// of a pending attestation is returned.
func PendingAttestationRoot(att *pb.PendingAttestation) ([32]byte, error) {
func PendingAttestationRoot(hasher HashFn, att *pb.PendingAttestation) ([32]byte, error) {
fieldRoots := [][32]byte{}
if att != nil {
// Bitfield.
aggregationRoot, err := bitlistRoot(att.AggregationBits, params.BeaconConfig().MaxValidatorsPerCommittee)
aggregationRoot, err := bitlistRoot(hasher, att.AggregationBits, params.BeaconConfig().MaxValidatorsPerCommittee)
if err != nil {
return [32]byte{}, err
}
// Attestation data.
attDataRoot, err := attestationDataRoot(att.Data)
attDataRoot, err := attestationDataRoot(hasher, att.Data)
if err != nil {
return [32]byte{}, err
}
Expand All @@ -49,7 +50,7 @@ func PendingAttestationRoot(att *pb.PendingAttestation) ([32]byte, error) {

fieldRoots = [][32]byte{aggregationRoot, attDataRoot, inclusionRoot, proposerRoot}
}
return bitwiseMerkleizeArrays(fieldRoots, uint64(len(fieldRoots)), uint64(len(fieldRoots)))
return bitwiseMerkleizeArrays(hasher, fieldRoots, uint64(len(fieldRoots)), uint64(len(fieldRoots)))
}

func marshalAttestationData(data *ethpb.AttestationData) []byte {
Expand Down Expand Up @@ -88,17 +89,17 @@ func marshalAttestationData(data *ethpb.AttestationData) []byte {
return enc
}

func attestationRoot(att *ethpb.Attestation) ([32]byte, error) {
func attestationRoot(hasher HashFn, att *ethpb.Attestation) ([32]byte, error) {
fieldRoots := make([][32]byte, 3)

// Bitfield.
aggregationRoot, err := bitlistRoot(att.AggregationBits, params.BeaconConfig().MaxValidatorsPerCommittee)
aggregationRoot, err := bitlistRoot(hasher, att.AggregationBits, params.BeaconConfig().MaxValidatorsPerCommittee)
if err != nil {
return [32]byte{}, err
}
fieldRoots[0] = aggregationRoot

dataRoot, err := attestationDataRoot(att.Data)
dataRoot, err := attestationDataRoot(hasher, att.Data)
if err != nil {
return [32]byte{}, err
}
Expand All @@ -109,25 +110,27 @@ func attestationRoot(att *ethpb.Attestation) ([32]byte, error) {
if err != nil {
return [32]byte{}, err
}
sigRoot, err := bitwiseMerkleize(packedSig, uint64(len(packedSig)), uint64(len(packedSig)))
sigRoot, err := bitwiseMerkleize(hasher, packedSig, uint64(len(packedSig)), uint64(len(packedSig)))
if err != nil {
return [32]byte{}, err
}
fieldRoots[2] = sigRoot
return bitwiseMerkleizeArrays(fieldRoots, uint64(len(fieldRoots)), uint64(len(fieldRoots)))
return bitwiseMerkleizeArrays(hasher, fieldRoots, uint64(len(fieldRoots)), uint64(len(fieldRoots)))
}

func blockAttestationRoot(atts []*ethpb.Attestation) ([32]byte, error) {
hasher := hashutil.CustomSHA256Hasher()
roots := make([][]byte, len(atts))
for i := 0; i < len(atts); i++ {
pendingRoot, err := attestationRoot(atts[i])
pendingRoot, err := attestationRoot(hasher, atts[i])
if err != nil {
return [32]byte{}, errors.Wrap(err, "could not attestation merkleization")
}
roots[i] = pendingRoot[:]
}

attsRootsRoot, err := bitwiseMerkleize(
hasher,
roots,
uint64(len(roots)),
params.BeaconConfig().MaxAttestations,
Expand All @@ -146,7 +149,7 @@ func blockAttestationRoot(atts []*ethpb.Attestation) ([32]byte, error) {
return res, nil
}

func attestationDataRoot(data *ethpb.AttestationData) ([32]byte, error) {
func attestationDataRoot(hasher HashFn, data *ethpb.AttestationData) ([32]byte, error) {
fieldRoots := make([][]byte, 5)

if data != nil {
Expand All @@ -167,24 +170,24 @@ func attestationDataRoot(data *ethpb.AttestationData) ([32]byte, error) {
fieldRoots[2] = blockRoot[:]

// Source
sourceRoot, err := CheckpointRoot(data.Source)
sourceRoot, err := CheckpointRoot(hasher, data.Source)
if err != nil {
return [32]byte{}, errors.Wrap(err, "could not compute source checkpoint merkleization")
}
fieldRoots[3] = sourceRoot[:]

// Target
targetRoot, err := CheckpointRoot(data.Target)
targetRoot, err := CheckpointRoot(hasher, data.Target)
if err != nil {
return [32]byte{}, errors.Wrap(err, "could not compute target checkpoint merkleization")
}
fieldRoots[4] = targetRoot[:]
}

return bitwiseMerkleize(fieldRoots, uint64(len(fieldRoots)), uint64(len(fieldRoots)))
return bitwiseMerkleize(hasher, fieldRoots, uint64(len(fieldRoots)), uint64(len(fieldRoots)))
}

func (h *stateRootHasher) pendingAttestationRoot(att *pb.PendingAttestation) ([32]byte, error) {
func (h *stateRootHasher) pendingAttestationRoot(hasher HashFn, att *pb.PendingAttestation) ([32]byte, error) {
// Marshal attestation to determine if it exists in the cache.
enc := make([]byte, 2192)
fieldRoots := make([][]byte, 4)
Expand All @@ -211,14 +214,14 @@ func (h *stateRootHasher) pendingAttestationRoot(att *pb.PendingAttestation) ([3
}

// Bitfield.
aggregationRoot, err := bitlistRoot(att.AggregationBits, 2048)
aggregationRoot, err := bitlistRoot(hasher, att.AggregationBits, 2048)
if err != nil {
return [32]byte{}, err
}
fieldRoots[0] = aggregationRoot[:]

// Attestation data.
attDataRoot, err := attestationDataRoot(att.Data)
attDataRoot, err := attestationDataRoot(hasher, att.Data)
if err != nil {
return [32]byte{}, err
}
Expand All @@ -232,7 +235,7 @@ func (h *stateRootHasher) pendingAttestationRoot(att *pb.PendingAttestation) ([3
proposerRoot := bytesutil.ToBytes32(proposerBuf)
fieldRoots[3] = proposerRoot[:]
}
res, err := bitwiseMerkleize(fieldRoots, uint64(len(fieldRoots)), uint64(len(fieldRoots)))
res, err := bitwiseMerkleize(hasher, fieldRoots, uint64(len(fieldRoots)), uint64(len(fieldRoots)))
if err != nil {
return [32]byte{}, err
}
Expand All @@ -243,16 +246,18 @@ func (h *stateRootHasher) pendingAttestationRoot(att *pb.PendingAttestation) ([3
}

func (h *stateRootHasher) epochAttestationsRoot(atts []*pb.PendingAttestation) ([32]byte, error) {
hasher := hashutil.CustomSHA256Hasher()
roots := make([][]byte, len(atts))
for i := 0; i < len(atts); i++ {
pendingRoot, err := h.pendingAttestationRoot(atts[i])
pendingRoot, err := h.pendingAttestationRoot(hasher, atts[i])
if err != nil {
return [32]byte{}, errors.Wrap(err, "could not attestation merkleization")
}
roots[i] = pendingRoot[:]
}

attsRootsRoot, err := bitwiseMerkleize(
hasher,
roots,
uint64(len(roots)),
params.BeaconConfig().MaxAttestations*params.BeaconConfig().SlotsPerEpoch,
Expand Down
20 changes: 11 additions & 9 deletions beacon-chain/state/stateutil/blocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func BlockHeaderRoot(header *ethpb.BeaconBlockHeader) ([32]byte, error) {
bodyRoot := bytesutil.ToBytes32(header.BodyRoot)
fieldRoots[3] = bodyRoot[:]
}
return bitwiseMerkleize(fieldRoots, uint64(len(fieldRoots)), uint64(len(fieldRoots)))
return bitwiseMerkleize(hashutil.CustomSHA256Hasher(), fieldRoots, uint64(len(fieldRoots)), uint64(len(fieldRoots)))
}

// BlockRoot returns the block hash tree root of the provided block.
Expand All @@ -54,28 +54,29 @@ func BlockRoot(blk *ethpb.BeaconBlock) ([32]byte, error) {
}
fieldRoots[3] = bodyRoot
}
return bitwiseMerkleizeArrays(fieldRoots, uint64(len(fieldRoots)), uint64(len(fieldRoots)))
return bitwiseMerkleizeArrays(hashutil.CustomSHA256Hasher(), fieldRoots, uint64(len(fieldRoots)), uint64(len(fieldRoots)))
}

// BlockBodyRoot returns the hash tree root of the block body.
func BlockBodyRoot(body *ethpb.BeaconBlockBody) ([32]byte, error) {
if !featureconfig.Get().EnableBlockHTR {
return ssz.HashTreeRoot(body)
}
hasher := hashutil.CustomSHA256Hasher()
fieldRoots := make([][32]byte, 8)
if body != nil {
rawRandao := bytesutil.ToBytes96(body.RandaoReveal)
packedRandao, err := pack([][]byte{rawRandao[:]})
if err != nil {
return [32]byte{}, err
}
randaoRoot, err := bitwiseMerkleize(packedRandao, uint64(len(packedRandao)), uint64(len(packedRandao)))
randaoRoot, err := bitwiseMerkleize(hasher, packedRandao, uint64(len(packedRandao)), uint64(len(packedRandao)))
if err != nil {
return [32]byte{}, err
}
fieldRoots[0] = randaoRoot

eth1Root, err := Eth1Root(body.Eth1Data)
eth1Root, err := Eth1Root(hasher, body.Eth1Data)
if err != nil {
return [32]byte{}, err
}
Expand Down Expand Up @@ -112,13 +113,13 @@ func BlockBodyRoot(body *ethpb.BeaconBlockBody) ([32]byte, error) {
}
fieldRoots[7] = exitRoot
}
return bitwiseMerkleizeArrays(fieldRoots, uint64(len(fieldRoots)), uint64(len(fieldRoots)))
return bitwiseMerkleizeArrays(hasher, fieldRoots, uint64(len(fieldRoots)), uint64(len(fieldRoots)))
}

// Eth1Root computes the HashTreeRoot Merkleization of
// a BeaconBlockHeader struct according to the eth2
// Simple Serialize specification.
func Eth1Root(eth1Data *ethpb.Eth1Data) ([32]byte, error) {
func Eth1Root(hasher HashFn, eth1Data *ethpb.Eth1Data) ([32]byte, error) {
enc := make([]byte, 0, 96)
fieldRoots := make([][]byte, 3)
for i := 0; i < len(fieldRoots); i++ {
Expand Down Expand Up @@ -146,7 +147,7 @@ func Eth1Root(eth1Data *ethpb.Eth1Data) ([32]byte, error) {
}
}
}
root, err := bitwiseMerkleize(fieldRoots, uint64(len(fieldRoots)), uint64(len(fieldRoots)))
root, err := bitwiseMerkleize(hasher, fieldRoots, uint64(len(fieldRoots)), uint64(len(fieldRoots)))
if err != nil {
return [32]byte{}, err
}
Expand All @@ -162,8 +163,9 @@ func Eth1Root(eth1Data *ethpb.Eth1Data) ([32]byte, error) {
func Eth1DataVotesRoot(eth1DataVotes []*ethpb.Eth1Data) ([32]byte, error) {
eth1VotesRoots := make([][]byte, 0)
enc := make([]byte, len(eth1DataVotes)*32)
hasher := hashutil.CustomSHA256Hasher()
for i := 0; i < len(eth1DataVotes); i++ {
eth1, err := Eth1Root(eth1DataVotes[i])
eth1, err := Eth1Root(hasher, eth1DataVotes[i])
if err != nil {
return [32]byte{}, errors.Wrap(err, "could not compute eth1data merkleization")
}
Expand All @@ -180,7 +182,7 @@ func Eth1DataVotesRoot(eth1DataVotes []*ethpb.Eth1Data) ([32]byte, error) {
if err != nil {
return [32]byte{}, errors.Wrap(err, "could not chunk eth1 votes roots")
}
eth1VotesRootsRoot, err := bitwiseMerkleize(eth1Chunks, uint64(len(eth1Chunks)), params.BeaconConfig().SlotsPerEth1VotingPeriod)
eth1VotesRootsRoot, err := bitwiseMerkleize(hasher, eth1Chunks, uint64(len(eth1Chunks)), params.BeaconConfig().SlotsPerEth1VotingPeriod)
if err != nil {
return [32]byte{}, errors.Wrap(err, "could not compute eth1data votes merkleization")
}
Expand Down
Loading

0 comments on commit 7e50c36

Please sign in to comment.