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 }