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 }