github.com/unicornultrafoundation/go-u2u@v1.0.0-rc1.0.20240205080301-e74a83d3fadc/gossip/store_decided_state.go (about)

     1  package gossip
     2  
     3  import (
     4  	"github.com/unicornultrafoundation/go-helios/native/idx"
     5  	"github.com/unicornultrafoundation/go-helios/native/pos"
     6  	"github.com/unicornultrafoundation/go-u2u/log"
     7  	ethparams "github.com/unicornultrafoundation/go-u2u/params"
     8  	"github.com/unicornultrafoundation/go-u2u/rlp"
     9  
    10  	"github.com/unicornultrafoundation/go-u2u/native/iblockproc"
    11  	"github.com/unicornultrafoundation/go-u2u/u2u"
    12  )
    13  
    14  const sKey = "s"
    15  
    16  type BlockEpochState struct {
    17  	BlockState *iblockproc.BlockState
    18  	EpochState *iblockproc.EpochState
    19  }
    20  
    21  // TODO propose to pass bs, es arguments by pointer
    22  func (s *Store) SetHistoryBlockEpochState(epoch idx.Epoch, bs iblockproc.BlockState, es iblockproc.EpochState) {
    23  	bs, es = bs.Copy(), es.Copy()
    24  	bes := &BlockEpochState{
    25  		BlockState: &bs,
    26  		EpochState: &es,
    27  	}
    28  	// Write to the DB
    29  	s.rlp.Set(s.table.BlockEpochStateHistory, epoch.Bytes(), bes)
    30  	// Save to the LRU cache
    31  	s.cache.BlockEpochStateHistory.Add(epoch, bes, nominalSize)
    32  }
    33  
    34  func (s *Store) GetHistoryBlockEpochState(epoch idx.Epoch) (*iblockproc.BlockState, *iblockproc.EpochState) {
    35  	// Get HistoryBlockEpochState from LRU cache first.
    36  	if v, ok := s.cache.BlockEpochStateHistory.Get(epoch); ok {
    37  		bes := v.(*BlockEpochState)
    38  		if bes.EpochState.Epoch == epoch {
    39  			bs := bes.BlockState.Copy()
    40  			es := bes.EpochState.Copy()
    41  			return &bs, &es
    42  		}
    43  	}
    44  	// read from DB
    45  	v, ok := s.rlp.Get(s.table.BlockEpochStateHistory, epoch.Bytes(), &BlockEpochState{}).(*BlockEpochState)
    46  	if !ok {
    47  		return nil, nil
    48  	}
    49  	// Save to the LRU cache
    50  	s.cache.BlockEpochStateHistory.Add(epoch, v, nominalSize)
    51  	bs := v.BlockState.Copy()
    52  	es := v.EpochState.Copy()
    53  	return &bs, &es
    54  }
    55  
    56  func (s *Store) ForEachHistoryBlockEpochState(fn func(iblockproc.BlockState, iblockproc.EpochState) bool) {
    57  	it := s.table.BlockEpochStateHistory.NewIterator(nil, nil)
    58  	defer it.Release()
    59  	for it.Next() {
    60  		bes := BlockEpochState{}
    61  		err := rlp.DecodeBytes(it.Value(), &bes)
    62  		if err != nil {
    63  			s.Log.Crit("Failed to decode BlockEpochState", "err", err)
    64  		}
    65  		if !fn(*bes.BlockState, *bes.EpochState) {
    66  			break
    67  		}
    68  	}
    69  }
    70  
    71  func (s *Store) GetHistoryEpochState(epoch idx.Epoch) *iblockproc.EpochState {
    72  	// check current BlockEpochState as a cache
    73  	if v := s.cache.BlockEpochState.Load(); v != nil {
    74  		bes := v.(*BlockEpochState)
    75  		if bes.EpochState.Epoch == epoch {
    76  			es := bes.EpochState.Copy()
    77  			return &es
    78  		}
    79  	}
    80  	_, es := s.GetHistoryBlockEpochState(epoch)
    81  	return es
    82  }
    83  
    84  func (s *Store) HasHistoryBlockEpochState(epoch idx.Epoch) bool {
    85  	has, _ := s.table.BlockEpochStateHistory.Has(epoch.Bytes())
    86  	return has
    87  }
    88  
    89  func (s *Store) HasBlockEpochState() bool {
    90  	has, _ := s.table.BlockEpochState.Has([]byte(sKey))
    91  	return has
    92  }
    93  
    94  // SetBlockEpochState stores the latest block and epoch state in memory
    95  func (s *Store) SetBlockEpochState(bs iblockproc.BlockState, es iblockproc.EpochState) {
    96  	bs, es = bs.Copy(), es.Copy()
    97  	s.cache.BlockEpochState.Store(&BlockEpochState{&bs, &es})
    98  }
    99  
   100  func (s *Store) getBlockEpochState() BlockEpochState {
   101  	if v := s.cache.BlockEpochState.Load(); v != nil {
   102  		return *v.(*BlockEpochState)
   103  	}
   104  	v, ok := s.rlp.Get(s.table.BlockEpochState, []byte(sKey), &BlockEpochState{}).(*BlockEpochState)
   105  	if !ok {
   106  		log.Crit("Epoch state reading failed: genesis not applied")
   107  	}
   108  	s.cache.BlockEpochState.Store(v)
   109  	return *v
   110  }
   111  
   112  // FlushBlockEpochState stores the latest epoch and block state in DB
   113  func (s *Store) FlushBlockEpochState() {
   114  	s.rlp.Set(s.table.BlockEpochState, []byte(sKey), s.getBlockEpochState())
   115  }
   116  
   117  // GetBlockState retrieves the latest block state
   118  func (s *Store) GetBlockState() iblockproc.BlockState {
   119  	return *s.getBlockEpochState().BlockState
   120  }
   121  
   122  // GetEpochState retrieves the latest epoch state
   123  func (s *Store) GetEpochState() iblockproc.EpochState {
   124  	return *s.getBlockEpochState().EpochState
   125  }
   126  
   127  func (s *Store) GetBlockEpochState() (iblockproc.BlockState, iblockproc.EpochState) {
   128  	bes := s.getBlockEpochState()
   129  	return *bes.BlockState, *bes.EpochState
   130  }
   131  
   132  // GetEpoch retrieves the current epoch
   133  func (s *Store) GetEpoch() idx.Epoch {
   134  	return s.GetEpochState().Epoch
   135  }
   136  
   137  // GetValidators retrieves current validators
   138  func (s *Store) GetValidators() *pos.Validators {
   139  	return s.GetEpochState().Validators
   140  }
   141  
   142  // GetEpochValidators retrieves the current epoch and validators atomically
   143  func (s *Store) GetEpochValidators() (*pos.Validators, idx.Epoch) {
   144  	es := s.GetEpochState()
   145  	return es.Validators, es.Epoch
   146  }
   147  
   148  // GetLatestBlockIndex retrieves the current block number
   149  func (s *Store) GetLatestBlockIndex() idx.Block {
   150  	return s.GetBlockState().LastBlock.Idx
   151  }
   152  
   153  // GetRules retrieves current network rules
   154  func (s *Store) GetRules() u2u.Rules {
   155  	return s.GetEpochState().Rules
   156  }
   157  
   158  // GetEvmChainConfig retrieves current EVM chain config
   159  func (s *Store) GetEvmChainConfig() *ethparams.ChainConfig {
   160  	return s.GetRules().EvmChainConfig(s.GetUpgradeHeights())
   161  }
   162  
   163  // GetEpochRules retrieves current network rules and epoch atomically
   164  func (s *Store) GetEpochRules() (u2u.Rules, idx.Epoch) {
   165  	es := s.GetEpochState()
   166  	return es.Rules, es.Epoch
   167  }