github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/db/kv/genesis.go (about)

     1  package kv
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"fmt"
     7  	"io"
     8  	"io/ioutil"
     9  
    10  	"github.com/pkg/errors"
    11  	"github.com/prysmaticlabs/prysm/beacon-chain/core/blocks"
    12  	dbIface "github.com/prysmaticlabs/prysm/beacon-chain/db/iface"
    13  	iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
    14  	state "github.com/prysmaticlabs/prysm/beacon-chain/state/v1"
    15  	pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
    16  	"github.com/prysmaticlabs/prysm/proto/eth/v1alpha1/wrapper"
    17  	"github.com/prysmaticlabs/prysm/shared/params"
    18  )
    19  
    20  // SaveGenesisData bootstraps the beaconDB with a given genesis state.
    21  func (s *Store) SaveGenesisData(ctx context.Context, genesisState iface.BeaconState) error {
    22  	stateRoot, err := genesisState.HashTreeRoot(ctx)
    23  	if err != nil {
    24  		return err
    25  	}
    26  	genesisBlk := blocks.NewGenesisBlock(stateRoot[:])
    27  	genesisBlkRoot, err := genesisBlk.Block.HashTreeRoot()
    28  	if err != nil {
    29  		return errors.Wrap(err, "could not get genesis block root")
    30  	}
    31  	if err := s.SaveBlock(ctx, wrapper.WrappedPhase0SignedBeaconBlock(genesisBlk)); err != nil {
    32  		return errors.Wrap(err, "could not save genesis block")
    33  	}
    34  	if err := s.SaveState(ctx, genesisState, genesisBlkRoot); err != nil {
    35  		return errors.Wrap(err, "could not save genesis state")
    36  	}
    37  	if err := s.SaveStateSummary(ctx, &pbp2p.StateSummary{
    38  		Slot: 0,
    39  		Root: genesisBlkRoot[:],
    40  	}); err != nil {
    41  		return err
    42  	}
    43  
    44  	if err := s.SaveHeadBlockRoot(ctx, genesisBlkRoot); err != nil {
    45  		return errors.Wrap(err, "could not save head block root")
    46  	}
    47  	if err := s.SaveGenesisBlockRoot(ctx, genesisBlkRoot); err != nil {
    48  		return errors.Wrap(err, "could not save genesis block root")
    49  	}
    50  
    51  	return nil
    52  }
    53  
    54  // LoadGenesis loads a genesis state from a given file path, if no genesis exists already.
    55  func (s *Store) LoadGenesis(ctx context.Context, r io.Reader) error {
    56  	b, err := ioutil.ReadAll(r)
    57  	if err != nil {
    58  		return err
    59  	}
    60  	st := &pbp2p.BeaconState{}
    61  	if err := st.UnmarshalSSZ(b); err != nil {
    62  		return err
    63  	}
    64  	gs, err := state.InitializeFromProtoUnsafe(st)
    65  	if err != nil {
    66  		return err
    67  	}
    68  	existing, err := s.GenesisState(ctx)
    69  	if err != nil {
    70  		return err
    71  	}
    72  	// If some different genesis state existed already, return an error. The same genesis state is
    73  	// considered a no-op.
    74  	if existing != nil && !existing.IsNil() {
    75  		a, err := existing.HashTreeRoot(ctx)
    76  		if err != nil {
    77  			return err
    78  		}
    79  		b, err := gs.HashTreeRoot(ctx)
    80  		if err != nil {
    81  			return err
    82  		}
    83  		if a == b {
    84  			return nil
    85  		}
    86  		return dbIface.ErrExistingGenesisState
    87  	}
    88  
    89  	if !bytes.Equal(gs.Fork().CurrentVersion, params.BeaconConfig().GenesisForkVersion) {
    90  		return fmt.Errorf("loaded genesis fork version (%#x) does not match config genesis "+
    91  			"fork version (%#x)", gs.Fork().CurrentVersion, params.BeaconConfig().GenesisForkVersion)
    92  	}
    93  
    94  	return s.SaveGenesisData(ctx, gs)
    95  }
    96  
    97  // EnsureEmbeddedGenesis checks that a genesis block has been generated when an embedded genesis
    98  // state is used. If a genesis block does not exist, but a genesis state does, then we should call
    99  // SaveGenesisData on the existing genesis state.
   100  func (s *Store) EnsureEmbeddedGenesis(ctx context.Context) error {
   101  	gb, err := s.GenesisBlock(ctx)
   102  	if err != nil {
   103  		return err
   104  	}
   105  	if gb != nil && !gb.IsNil() {
   106  		return nil
   107  	}
   108  	gs, err := s.GenesisState(ctx)
   109  	if err != nil {
   110  		return err
   111  	}
   112  	if gs != nil && !gs.IsNil() {
   113  		return s.SaveGenesisData(ctx, gs)
   114  	}
   115  	return nil
   116  }