2021-09-29 17:46:51 +00:00
|
|
|
package stateutil
|
2021-07-27 15:47:03 +00:00
|
|
|
|
|
|
|
import (
|
2023-03-17 11:41:02 +00:00
|
|
|
"github.com/pkg/errors"
|
2023-03-17 18:52:56 +00:00
|
|
|
"github.com/prysmaticlabs/prysm/v4/crypto/hash/htr"
|
|
|
|
"github.com/prysmaticlabs/prysm/v4/encoding/ssz"
|
|
|
|
ethpb "github.com/prysmaticlabs/prysm/v4/proto/prysm/v1alpha1"
|
2021-07-27 15:47:03 +00:00
|
|
|
)
|
|
|
|
|
2022-08-03 18:47:30 +00:00
|
|
|
// SyncCommitteeRoot computes the HashTreeRoot Merkleization of a committee root.
|
2021-07-27 15:47:03 +00:00
|
|
|
// a SyncCommitteeRoot struct according to the eth2
|
|
|
|
// Simple Serialize specification.
|
2021-09-29 17:46:51 +00:00
|
|
|
func SyncCommitteeRoot(committee *ethpb.SyncCommittee) ([32]byte, error) {
|
2021-07-27 15:47:03 +00:00
|
|
|
var fieldRoots [][32]byte
|
|
|
|
if committee == nil {
|
|
|
|
return [32]byte{}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Field 1: Vector[BLSPubkey, SYNC_COMMITTEE_SIZE]
|
|
|
|
pubKeyRoots := make([][32]byte, 0)
|
|
|
|
for _, pubkey := range committee.Pubkeys {
|
2023-03-17 11:41:02 +00:00
|
|
|
r, err := merkleizePubkey(pubkey)
|
2021-07-27 15:47:03 +00:00
|
|
|
if err != nil {
|
|
|
|
return [32]byte{}, err
|
|
|
|
}
|
|
|
|
pubKeyRoots = append(pubKeyRoots, r)
|
|
|
|
}
|
2023-03-17 11:41:02 +00:00
|
|
|
pubkeyRoot, err := ssz.BitwiseMerkleize(pubKeyRoots, uint64(len(pubKeyRoots)), uint64(len(pubKeyRoots)))
|
2021-07-27 15:47:03 +00:00
|
|
|
if err != nil {
|
|
|
|
return [32]byte{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Field 2: BLSPubkey
|
2023-03-17 11:41:02 +00:00
|
|
|
aggregateKeyRoot, err := merkleizePubkey(committee.AggregatePubkey)
|
2021-07-27 15:47:03 +00:00
|
|
|
if err != nil {
|
|
|
|
return [32]byte{}, err
|
|
|
|
}
|
|
|
|
fieldRoots = [][32]byte{pubkeyRoot, aggregateKeyRoot}
|
|
|
|
|
2023-03-17 11:41:02 +00:00
|
|
|
return ssz.BitwiseMerkleize(fieldRoots, uint64(len(fieldRoots)), uint64(len(fieldRoots)))
|
2021-07-27 15:47:03 +00:00
|
|
|
}
|
|
|
|
|
2023-03-17 11:41:02 +00:00
|
|
|
func merkleizePubkey(pubkey []byte) ([32]byte, error) {
|
|
|
|
if len(pubkey) == 0 {
|
|
|
|
return [32]byte{}, errors.New("zero length pubkey provided")
|
|
|
|
}
|
2022-03-04 15:19:07 +00:00
|
|
|
chunks, err := ssz.PackByChunk([][]byte{pubkey})
|
2021-07-27 15:47:03 +00:00
|
|
|
if err != nil {
|
|
|
|
return [32]byte{}, err
|
|
|
|
}
|
2023-03-17 11:41:02 +00:00
|
|
|
outputChunk := make([][32]byte, 1)
|
|
|
|
htr.VectorizedSha256(chunks, outputChunk)
|
|
|
|
|
|
|
|
return outputChunk[0], nil
|
2021-07-27 15:47:03 +00:00
|
|
|
}
|