github.com/unicornultrafoundation/go-u2u@v1.0.0-rc1.0.20240205080301-e74a83d3fadc/gossip/store_block.go (about) 1 package gossip 2 3 import ( 4 "math" 5 6 "github.com/unicornultrafoundation/go-helios/hash" 7 "github.com/unicornultrafoundation/go-helios/native/idx" 8 "github.com/unicornultrafoundation/go-u2u/core/types" 9 "github.com/unicornultrafoundation/go-u2u/log" 10 "github.com/unicornultrafoundation/go-u2u/rlp" 11 12 "github.com/unicornultrafoundation/go-u2u/evmcore" 13 "github.com/unicornultrafoundation/go-u2u/native" 14 ) 15 16 func (s *Store) GetGenesisID() *hash.Hash { 17 if v := s.cache.Genesis.Load(); v != nil { 18 val := v.(hash.Hash) 19 return &val 20 } 21 valBytes, err := s.table.Genesis.Get([]byte("g")) 22 if err != nil { 23 s.Log.Crit("Failed to get key-value", "err", err) 24 } 25 if len(valBytes) == 0 { 26 return nil 27 } 28 val := hash.BytesToHash(valBytes) 29 s.cache.Genesis.Store(val) 30 return &val 31 } 32 33 func (s *Store) fakeGenesisHash() hash.Event { 34 fakeGenesisHash := hash.Event(*s.GetGenesisID()) 35 for i := range fakeGenesisHash[:8] { 36 fakeGenesisHash[i] = 0 37 } 38 return fakeGenesisHash 39 } 40 41 func (s *Store) SetGenesisID(val hash.Hash) { 42 err := s.table.Genesis.Put([]byte("g"), val.Bytes()) 43 if err != nil { 44 s.Log.Crit("Failed to put key-value", "err", err) 45 } 46 s.cache.Genesis.Store(val) 47 } 48 49 // SetBlock stores chain block. 50 func (s *Store) SetBlock(n idx.Block, b *native.Block) { 51 s.rlp.Set(s.table.Blocks, n.Bytes(), b) 52 53 // Add to LRU cache. 54 s.cache.Blocks.Add(n, b, uint(b.EstimateSize())) 55 } 56 57 // GetBlock returns stored block. 58 func (s *Store) GetBlock(n idx.Block) *native.Block { 59 if n == 0 { 60 // fake genesis block for compatibility with web3 61 return &native.Block{ 62 Time: evmcore.FakeGenesisTime - 1, 63 Atropos: s.fakeGenesisHash(), 64 } 65 } 66 // Get block from LRU cache first. 67 if c, ok := s.cache.Blocks.Get(n); ok { 68 return c.(*native.Block) 69 } 70 71 block, _ := s.rlp.Get(s.table.Blocks, n.Bytes(), &native.Block{}).(*native.Block) 72 73 // Add to LRU cache. 74 if block != nil { 75 s.cache.Blocks.Add(n, block, uint(block.EstimateSize())) 76 } 77 78 return block 79 } 80 81 func (s *Store) HasBlock(n idx.Block) bool { 82 has, _ := s.table.Blocks.Has(n.Bytes()) 83 return has 84 } 85 86 func (s *Store) ForEachBlock(fn func(index idx.Block, block *native.Block)) { 87 it := s.table.Blocks.NewIterator(nil, nil) 88 defer it.Release() 89 for it.Next() { 90 var block native.Block 91 err := rlp.DecodeBytes(it.Value(), &block) 92 if err != nil { 93 s.Log.Crit("Failed to decode block", "err", err) 94 } 95 fn(idx.BytesToBlock(it.Key()), &block) 96 } 97 } 98 99 // SetBlockIndex stores chain block index. 100 func (s *Store) SetBlockIndex(id hash.Event, n idx.Block) { 101 if err := s.table.BlockHashes.Put(id.Bytes(), n.Bytes()); err != nil { 102 s.Log.Crit("Failed to put key-value", "err", err) 103 } 104 105 s.cache.BlockHashes.Add(id, n, nominalSize) 106 } 107 108 // GetBlockIndex returns stored block index. 109 func (s *Store) GetBlockIndex(id hash.Event) *idx.Block { 110 nVal, ok := s.cache.BlockHashes.Get(id) 111 if ok { 112 n, ok := nVal.(idx.Block) 113 if ok { 114 return &n 115 } 116 } 117 118 buf, err := s.table.BlockHashes.Get(id.Bytes()) 119 if err != nil { 120 s.Log.Crit("Failed to get key-value", "err", err) 121 } 122 if buf == nil { 123 if id == s.fakeGenesisHash() { 124 zero := idx.Block(0) 125 return &zero 126 } 127 return nil 128 } 129 n := idx.BytesToBlock(buf) 130 131 s.cache.BlockHashes.Add(id, n, nominalSize) 132 133 return &n 134 } 135 136 // SetGenesisBlockIndex stores genesis block index. 137 func (s *Store) SetGenesisBlockIndex(n idx.Block) { 138 if err := s.table.Genesis.Put([]byte("i"), n.Bytes()); err != nil { 139 s.Log.Crit("Failed to put key-value", "err", err) 140 } 141 } 142 143 // GetGenesisBlockIndex returns stored genesis block index. 144 func (s *Store) GetGenesisBlockIndex() *idx.Block { 145 buf, err := s.table.Genesis.Get([]byte("i")) 146 if err != nil { 147 s.Log.Crit("Failed to get key-value", "err", err) 148 } 149 if buf == nil { 150 return nil 151 } 152 n := idx.BytesToBlock(buf) 153 154 return &n 155 } 156 157 func (s *Store) GetGenesisTime() native.Timestamp { 158 n := s.GetGenesisBlockIndex() 159 if n == nil { 160 return 0 161 } 162 block := s.GetBlock(*n) 163 if block == nil { 164 return 0 165 } 166 return block.Time 167 } 168 169 func (s *Store) SetEpochBlock(b idx.Block, e idx.Epoch) { 170 err := s.table.EpochBlocks.Put((math.MaxUint64 - b).Bytes(), e.Bytes()) 171 if err != nil { 172 s.Log.Crit("Failed to set key-value", "err", err) 173 } 174 } 175 176 func (s *Store) FindBlockEpoch(b idx.Block) idx.Epoch { 177 if c, ok := s.cache.Blocks.Get(b); ok { 178 return c.(*native.Block).Atropos.Epoch() 179 } 180 181 it := s.table.EpochBlocks.NewIterator(nil, (math.MaxUint64 - b).Bytes()) 182 defer it.Release() 183 if !it.Next() { 184 return 0 185 } 186 return idx.BytesToEpoch(it.Value()) 187 } 188 189 func (s *Store) GetBlockTxs(n idx.Block, block *native.Block) types.Transactions { 190 if cached := s.evm.GetCachedEvmBlock(n); cached != nil { 191 return cached.Transactions 192 } 193 194 transactions := make(types.Transactions, 0, len(block.Txs)+len(block.InternalTxs)+len(block.Events)*10) 195 for _, txid := range block.InternalTxs { 196 tx := s.evm.GetTx(txid) 197 if tx == nil { 198 log.Crit("Internal tx not found", "tx", txid.String()) 199 continue 200 } 201 transactions = append(transactions, tx) 202 } 203 for _, txid := range block.Txs { 204 tx := s.evm.GetTx(txid) 205 if tx == nil { 206 log.Crit("Tx not found", "tx", txid.String()) 207 continue 208 } 209 transactions = append(transactions, tx) 210 } 211 for _, id := range block.Events { 212 e := s.GetEventPayload(id) 213 if e == nil { 214 log.Crit("Block event not found", "event", id.String()) 215 continue 216 } 217 transactions = append(transactions, e.Txs()...) 218 } 219 220 transactions = native.FilterSkippedTxs(transactions, block.SkippedTxs) 221 222 return transactions 223 }