github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/state/stateutil/pending_attestation_root.go (about)

     1  package stateutil
     2  
     3  import (
     4  	"encoding/binary"
     5  
     6  	"github.com/pkg/errors"
     7  	pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
     8  	ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
     9  	"github.com/prysmaticlabs/prysm/shared/bytesutil"
    10  	"github.com/prysmaticlabs/prysm/shared/htrutils"
    11  	"github.com/prysmaticlabs/prysm/shared/params"
    12  )
    13  
    14  // PendingAttRootWithHasher describes a method from which the hash tree root
    15  // of a pending attestation is returned.
    16  func PendingAttRootWithHasher(hasher htrutils.HashFn, att *pb.PendingAttestation) ([32]byte, error) {
    17  	var fieldRoots [][32]byte
    18  
    19  	// Bitfield.
    20  	aggregationRoot, err := htrutils.BitlistRoot(hasher, att.AggregationBits, params.BeaconConfig().MaxValidatorsPerCommittee)
    21  	if err != nil {
    22  		return [32]byte{}, err
    23  	}
    24  	// Attestation data.
    25  	attDataRoot, err := attDataRootWithHasher(hasher, att.Data)
    26  	if err != nil {
    27  		return [32]byte{}, err
    28  	}
    29  	inclusionBuf := make([]byte, 8)
    30  	binary.LittleEndian.PutUint64(inclusionBuf, uint64(att.InclusionDelay))
    31  	// Inclusion delay.
    32  	inclusionRoot := bytesutil.ToBytes32(inclusionBuf)
    33  
    34  	proposerBuf := make([]byte, 8)
    35  	binary.LittleEndian.PutUint64(proposerBuf, uint64(att.ProposerIndex))
    36  	// Proposer index.
    37  	proposerRoot := bytesutil.ToBytes32(proposerBuf)
    38  
    39  	fieldRoots = [][32]byte{aggregationRoot, attDataRoot, inclusionRoot, proposerRoot}
    40  
    41  	return htrutils.BitwiseMerkleizeArrays(hasher, fieldRoots, uint64(len(fieldRoots)), uint64(len(fieldRoots)))
    42  }
    43  
    44  // PendingAttEncKey returns the encoded key in bytes of input `pendingAttestation`,
    45  // the returned key bytes can be used for caching purposes.
    46  func PendingAttEncKey(att *pb.PendingAttestation) []byte {
    47  	enc := make([]byte, 2192)
    48  
    49  	if att != nil {
    50  		copy(enc[0:2048], att.AggregationBits)
    51  
    52  		inclusionBuf := make([]byte, 8)
    53  		binary.LittleEndian.PutUint64(inclusionBuf, uint64(att.InclusionDelay))
    54  		copy(enc[2048:2056], inclusionBuf)
    55  
    56  		attDataBuf := marshalAttData(att.Data)
    57  		copy(enc[2056:2184], attDataBuf)
    58  
    59  		proposerBuf := make([]byte, 8)
    60  		binary.LittleEndian.PutUint64(proposerBuf, uint64(att.ProposerIndex))
    61  		copy(enc[2184:2192], proposerBuf)
    62  	}
    63  
    64  	return enc
    65  }
    66  
    67  func attDataRootWithHasher(hasher htrutils.HashFn, data *ethpb.AttestationData) ([32]byte, error) {
    68  	fieldRoots := make([][]byte, 5)
    69  
    70  	if data != nil {
    71  		// Slot.
    72  		slotBuf := make([]byte, 8)
    73  		binary.LittleEndian.PutUint64(slotBuf, uint64(data.Slot))
    74  		slotRoot := bytesutil.ToBytes32(slotBuf)
    75  		fieldRoots[0] = slotRoot[:]
    76  
    77  		// CommitteeIndex.
    78  		indexBuf := make([]byte, 8)
    79  		binary.LittleEndian.PutUint64(indexBuf, uint64(data.CommitteeIndex))
    80  		interRoot := bytesutil.ToBytes32(indexBuf)
    81  		fieldRoots[1] = interRoot[:]
    82  
    83  		// Beacon block root.
    84  		blockRoot := bytesutil.ToBytes32(data.BeaconBlockRoot)
    85  		fieldRoots[2] = blockRoot[:]
    86  
    87  		// Source
    88  		sourceRoot, err := htrutils.CheckpointRoot(hasher, data.Source)
    89  		if err != nil {
    90  			return [32]byte{}, errors.Wrap(err, "could not compute source checkpoint merkleization")
    91  		}
    92  		fieldRoots[3] = sourceRoot[:]
    93  
    94  		// Target
    95  		targetRoot, err := htrutils.CheckpointRoot(hasher, data.Target)
    96  		if err != nil {
    97  			return [32]byte{}, errors.Wrap(err, "could not compute target checkpoint merkleization")
    98  		}
    99  		fieldRoots[4] = targetRoot[:]
   100  	}
   101  
   102  	return htrutils.BitwiseMerkleize(hasher, fieldRoots, uint64(len(fieldRoots)), uint64(len(fieldRoots)))
   103  }
   104  
   105  func marshalAttData(data *ethpb.AttestationData) []byte {
   106  	enc := make([]byte, 128)
   107  
   108  	if data != nil {
   109  		// Slot.
   110  		slotBuf := make([]byte, 8)
   111  		binary.LittleEndian.PutUint64(slotBuf, uint64(data.Slot))
   112  		copy(enc[0:8], slotBuf)
   113  
   114  		// Committee index.
   115  		indexBuf := make([]byte, 8)
   116  		binary.LittleEndian.PutUint64(indexBuf, uint64(data.CommitteeIndex))
   117  		copy(enc[8:16], indexBuf)
   118  
   119  		copy(enc[16:48], data.BeaconBlockRoot)
   120  
   121  		// Source epoch and root.
   122  		if data.Source != nil {
   123  			sourceEpochBuf := make([]byte, 8)
   124  			binary.LittleEndian.PutUint64(sourceEpochBuf, uint64(data.Source.Epoch))
   125  			copy(enc[48:56], sourceEpochBuf)
   126  			copy(enc[56:88], data.Source.Root)
   127  		}
   128  
   129  		// Target.
   130  		if data.Target != nil {
   131  			targetEpochBuf := make([]byte, 8)
   132  			binary.LittleEndian.PutUint64(targetEpochBuf, uint64(data.Target.Epoch))
   133  			copy(enc[88:96], targetEpochBuf)
   134  			copy(enc[96:128], data.Target.Root)
   135  		}
   136  	}
   137  
   138  	return enc
   139  }