github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/state/v1/field_roots.go (about) 1 package v1 2 3 import ( 4 "context" 5 "encoding/binary" 6 "sync" 7 8 "github.com/dgraph-io/ristretto" 9 "github.com/pkg/errors" 10 "github.com/prysmaticlabs/prysm/beacon-chain/state/stateutil" 11 pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1" 12 "github.com/prysmaticlabs/prysm/shared/bytesutil" 13 "github.com/prysmaticlabs/prysm/shared/featureconfig" 14 "github.com/prysmaticlabs/prysm/shared/hashutil" 15 "github.com/prysmaticlabs/prysm/shared/htrutils" 16 "github.com/prysmaticlabs/prysm/shared/params" 17 "go.opencensus.io/trace" 18 ) 19 20 var ( 21 leavesCache = make(map[string][][32]byte, params.BeaconConfig().BeaconStateFieldCount) 22 layersCache = make(map[string][][][32]byte, params.BeaconConfig().BeaconStateFieldCount) 23 lock sync.RWMutex 24 ) 25 26 const cacheSize = 100000 27 28 var nocachedHasher *stateRootHasher 29 var cachedHasher *stateRootHasher 30 31 func init() { 32 rootsCache, err := ristretto.NewCache(&ristretto.Config{ 33 NumCounters: cacheSize, // number of keys to track frequency of (1M). 34 MaxCost: 1 << 22, // maximum cost of cache (3MB). 35 // 100,000 roots will take up approximately 3 MB in memory. 36 BufferItems: 64, // number of keys per Get buffer. 37 }) 38 if err != nil { 39 panic(err) 40 } 41 // Temporarily disable roots cache until cache issues can be resolved. 42 cachedHasher = &stateRootHasher{rootsCache: rootsCache} 43 nocachedHasher = &stateRootHasher{} 44 } 45 46 type stateRootHasher struct { 47 rootsCache *ristretto.Cache 48 } 49 50 // computeFieldRoots returns the hash tree root computations of every field in 51 // the beacon state as a list of 32 byte roots. 52 func computeFieldRoots(ctx context.Context, state *pb.BeaconState) ([][]byte, error) { 53 if featureconfig.Get().EnableSSZCache { 54 return cachedHasher.computeFieldRootsWithHasher(ctx, state) 55 } 56 return nocachedHasher.computeFieldRootsWithHasher(ctx, state) 57 } 58 59 func (h *stateRootHasher) computeFieldRootsWithHasher(ctx context.Context, state *pb.BeaconState) ([][]byte, error) { 60 ctx, span := trace.StartSpan(ctx, "beaconState.computeFieldRootsWithHasher") 61 defer span.End() 62 63 if state == nil { 64 return nil, errors.New("nil state") 65 } 66 hasher := hashutil.CustomSHA256Hasher() 67 fieldRoots := make([][]byte, params.BeaconConfig().BeaconStateFieldCount) 68 69 // Genesis time root. 70 genesisRoot := htrutils.Uint64Root(state.GenesisTime) 71 fieldRoots[0] = genesisRoot[:] 72 73 // Genesis validator root. 74 r := [32]byte{} 75 copy(r[:], state.GenesisValidatorsRoot) 76 fieldRoots[1] = r[:] 77 78 // Slot root. 79 slotRoot := htrutils.Uint64Root(uint64(state.Slot)) 80 fieldRoots[2] = slotRoot[:] 81 82 // Fork data structure root. 83 forkHashTreeRoot, err := htrutils.ForkRoot(state.Fork) 84 if err != nil { 85 return nil, errors.Wrap(err, "could not compute fork merkleization") 86 } 87 fieldRoots[3] = forkHashTreeRoot[:] 88 89 // BeaconBlockHeader data structure root. 90 headerHashTreeRoot, err := stateutil.BlockHeaderRoot(state.LatestBlockHeader) 91 if err != nil { 92 return nil, errors.Wrap(err, "could not compute block header merkleization") 93 } 94 fieldRoots[4] = headerHashTreeRoot[:] 95 96 // BlockRoots array root. 97 blockRootsRoot, err := h.arraysRoot(state.BlockRoots, uint64(params.BeaconConfig().SlotsPerHistoricalRoot), "BlockRoots") 98 if err != nil { 99 return nil, errors.Wrap(err, "could not compute block roots merkleization") 100 } 101 fieldRoots[5] = blockRootsRoot[:] 102 103 // StateRoots array root. 104 stateRootsRoot, err := h.arraysRoot(state.StateRoots, uint64(params.BeaconConfig().SlotsPerHistoricalRoot), "StateRoots") 105 if err != nil { 106 return nil, errors.Wrap(err, "could not compute state roots merkleization") 107 } 108 fieldRoots[6] = stateRootsRoot[:] 109 110 // HistoricalRoots slice root. 111 historicalRootsRt, err := htrutils.HistoricalRootsRoot(state.HistoricalRoots) 112 if err != nil { 113 return nil, errors.Wrap(err, "could not compute historical roots merkleization") 114 } 115 fieldRoots[7] = historicalRootsRt[:] 116 117 // Eth1Data data structure root. 118 eth1HashTreeRoot, err := eth1Root(hasher, state.Eth1Data) 119 if err != nil { 120 return nil, errors.Wrap(err, "could not compute eth1data merkleization") 121 } 122 fieldRoots[8] = eth1HashTreeRoot[:] 123 124 // Eth1DataVotes slice root. 125 eth1VotesRoot, err := eth1DataVotesRoot(state.Eth1DataVotes) 126 if err != nil { 127 return nil, errors.Wrap(err, "could not compute eth1data votes merkleization") 128 } 129 fieldRoots[9] = eth1VotesRoot[:] 130 131 // Eth1DepositIndex root. 132 eth1DepositIndexBuf := make([]byte, 8) 133 binary.LittleEndian.PutUint64(eth1DepositIndexBuf, state.Eth1DepositIndex) 134 eth1DepositBuf := bytesutil.ToBytes32(eth1DepositIndexBuf) 135 fieldRoots[10] = eth1DepositBuf[:] 136 137 // Validators slice root. 138 validatorsRoot, err := h.validatorRegistryRoot(state.Validators) 139 if err != nil { 140 return nil, errors.Wrap(err, "could not compute validator registry merkleization") 141 } 142 fieldRoots[11] = validatorsRoot[:] 143 144 // Balances slice root. 145 balancesRoot, err := stateutil.Uint64ListRootWithRegistryLimit(state.Balances) 146 if err != nil { 147 return nil, errors.Wrap(err, "could not compute validator balances merkleization") 148 } 149 fieldRoots[12] = balancesRoot[:] 150 151 // RandaoMixes array root. 152 randaoRootsRoot, err := h.arraysRoot(state.RandaoMixes, uint64(params.BeaconConfig().EpochsPerHistoricalVector), "RandaoMixes") 153 if err != nil { 154 return nil, errors.Wrap(err, "could not compute randao roots merkleization") 155 } 156 fieldRoots[13] = randaoRootsRoot[:] 157 158 // Slashings array root. 159 slashingsRootsRoot, err := htrutils.SlashingsRoot(state.Slashings) 160 if err != nil { 161 return nil, errors.Wrap(err, "could not compute slashings merkleization") 162 } 163 fieldRoots[14] = slashingsRootsRoot[:] 164 165 // PreviousEpochAttestations slice root. 166 prevAttsRoot, err := h.epochAttestationsRoot(state.PreviousEpochAttestations) 167 if err != nil { 168 return nil, errors.Wrap(err, "could not compute previous epoch attestations merkleization") 169 } 170 fieldRoots[15] = prevAttsRoot[:] 171 172 // CurrentEpochAttestations slice root. 173 currAttsRoot, err := h.epochAttestationsRoot(state.CurrentEpochAttestations) 174 if err != nil { 175 return nil, errors.Wrap(err, "could not compute current epoch attestations merkleization") 176 } 177 fieldRoots[16] = currAttsRoot[:] 178 179 // JustificationBits root. 180 justifiedBitsRoot := bytesutil.ToBytes32(state.JustificationBits) 181 fieldRoots[17] = justifiedBitsRoot[:] 182 183 // PreviousJustifiedCheckpoint data structure root. 184 prevCheckRoot, err := htrutils.CheckpointRoot(hasher, state.PreviousJustifiedCheckpoint) 185 if err != nil { 186 return nil, errors.Wrap(err, "could not compute previous justified checkpoint merkleization") 187 } 188 fieldRoots[18] = prevCheckRoot[:] 189 190 // CurrentJustifiedCheckpoint data structure root. 191 currJustRoot, err := htrutils.CheckpointRoot(hasher, state.CurrentJustifiedCheckpoint) 192 if err != nil { 193 return nil, errors.Wrap(err, "could not compute current justified checkpoint merkleization") 194 } 195 fieldRoots[19] = currJustRoot[:] 196 197 // FinalizedCheckpoint data structure root. 198 finalRoot, err := htrutils.CheckpointRoot(hasher, state.FinalizedCheckpoint) 199 if err != nil { 200 return nil, errors.Wrap(err, "could not compute finalized checkpoint merkleization") 201 } 202 fieldRoots[20] = finalRoot[:] 203 return fieldRoots, nil 204 }