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  }