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

     1  package gossip
     2  
     3  import (
     4  	"errors"
     5  
     6  	"github.com/unicornultrafoundation/go-helios/hash"
     7  	"github.com/unicornultrafoundation/go-helios/u2udb/batched"
     8  
     9  	"github.com/unicornultrafoundation/go-u2u/native/iblockproc"
    10  	"github.com/unicornultrafoundation/go-u2u/native/ibr"
    11  	"github.com/unicornultrafoundation/go-u2u/native/ier"
    12  	"github.com/unicornultrafoundation/go-u2u/u2u/genesis"
    13  )
    14  
    15  // ApplyGenesis writes initial state.
    16  func (s *Store) ApplyGenesis(g genesis.Genesis) (genesisHash hash.Hash, err error) {
    17  	// use batching wrapper for hot tables
    18  	unwrap := s.WrapTablesAsBatched()
    19  	defer unwrap()
    20  
    21  	// write epochs
    22  	var topEr *ier.LlrIdxFullEpochRecord
    23  	g.Epochs.ForEach(func(er ier.LlrIdxFullEpochRecord) bool {
    24  		if er.EpochState.Rules.NetworkID != g.NetworkID || er.EpochState.Rules.Name != g.NetworkName {
    25  			err = errors.New("network ID/name mismatch")
    26  			return false
    27  		}
    28  		if topEr == nil {
    29  			topEr = &er
    30  		}
    31  		s.WriteFullEpochRecord(er)
    32  		return true
    33  	})
    34  	if err != nil {
    35  		return genesisHash, err
    36  	}
    37  	if topEr == nil {
    38  		return genesisHash, errors.New("no ERs in genesis")
    39  	}
    40  	var prevEs *iblockproc.EpochState
    41  	s.ForEachHistoryBlockEpochState(func(bs iblockproc.BlockState, es iblockproc.EpochState) bool {
    42  		s.WriteUpgradeHeight(bs, es, prevEs)
    43  		prevEs = &es
    44  		return true
    45  	})
    46  	s.SetBlockEpochState(topEr.BlockState, topEr.EpochState)
    47  	s.FlushBlockEpochState()
    48  
    49  	// write blocks
    50  	g.Blocks.ForEach(func(br ibr.LlrIdxFullBlockRecord) bool {
    51  		s.WriteFullBlockRecord(br)
    52  		return true
    53  	})
    54  
    55  	// write EVM items
    56  	err = s.evm.ApplyGenesis(g)
    57  	if err != nil {
    58  		return genesisHash, err
    59  	}
    60  
    61  	// write LLR state
    62  	s.setLlrState(LlrState{
    63  		LowestEpochToDecide: topEr.Idx + 1,
    64  		LowestEpochToFill:   topEr.Idx + 1,
    65  		LowestBlockToDecide: topEr.BlockState.LastBlock.Idx + 1,
    66  		LowestBlockToFill:   topEr.BlockState.LastBlock.Idx + 1,
    67  	})
    68  	s.FlushLlrState()
    69  
    70  	s.SetGenesisID(g.GenesisID)
    71  	s.SetGenesisBlockIndex(topEr.BlockState.LastBlock.Idx)
    72  
    73  	return genesisHash, err
    74  }
    75  
    76  func (s *Store) WrapTablesAsBatched() (unwrap func()) {
    77  	origTables := s.table
    78  
    79  	batchedBlocks := batched.Wrap(s.table.Blocks)
    80  	s.table.Blocks = batchedBlocks
    81  
    82  	batchedBlockHashes := batched.Wrap(s.table.BlockHashes)
    83  	s.table.BlockHashes = batchedBlockHashes
    84  
    85  	unwrapEVM := s.evm.WrapTablesAsBatched()
    86  	return func() {
    87  		unwrapEVM()
    88  		_ = batchedBlocks.Flush()
    89  		_ = batchedBlockHashes.Flush()
    90  		s.table = origTables
    91  	}
    92  }