@@ -21,10 +21,11 @@ import (
21
21
cfg "github.com/cometbft/cometbft/config"
22
22
cs "github.com/cometbft/cometbft/consensus"
23
23
"github.com/cometbft/cometbft/crypto"
24
+ "github.com/cometbft/cometbft/crypto/tmhash"
24
25
"github.com/cometbft/cometbft/evidence"
25
26
"github.com/cometbft/cometbft/light"
26
27
27
- cmtjson "github.com/cometbft/cometbft/libs/json"
28
+ // cmtjson "github.com/cometbft/cometbft/libs/json"
28
29
"github.com/cometbft/cometbft/libs/log"
29
30
cmtpubsub "github.com/cometbft/cometbft/libs/pubsub"
30
31
"github.com/cometbft/cometbft/libs/service"
@@ -247,10 +248,14 @@ func BootstrapState(ctx context.Context, config *cfg.Config, dbProvider DBProvid
247
248
return fmt .Errorf ("state not empty, trying to initialize non empty state" )
248
249
}
249
250
250
- genState , _ , err := LoadStateFromDBOrGenesisDocProvider (stateDB , DefaultGenesisDocProviderFunc (config ))
251
- if err != nil {
252
- return err
253
- }
251
+ // genState, _, err := LoadStateFromDBOrGenesisDocProvider(stateDB, DefaultGenesisDocProviderFunc(config))
252
+ // if err != nil {
253
+ // return err
254
+ // }
255
+
256
+ genDoc , _ := DefaultGenesisDocProviderFunc (config )()
257
+
258
+ genState , err := LoadStateFromDBOrGenesisDoc (stateStore , stateDB , genDoc )
254
259
255
260
stateProvider , err := statesync .NewLightClientStateProvider (
256
261
ctx ,
@@ -873,11 +878,19 @@ func NewNodeWithContext(ctx context.Context,
873
878
DiscardABCIResponses : config .Storage .DiscardABCIResponses ,
874
879
})
875
880
876
- state , genDoc , err := LoadStateFromDBOrGenesisDocProvider (stateDB , genesisDocProvider )
881
+ // state, genDoc, err := LoadStateFromDBOrGenesisDocProvider(stateDB, genesisDocProvider)
882
+ genDoc , err := genesisDocProvider ()
877
883
if err != nil {
878
884
return nil , err
879
885
}
880
886
887
+ err = genDoc .ValidateAndComplete ()
888
+ if err != nil {
889
+ return nil , fmt .Errorf ("error in genesis doc: %w" , err )
890
+ }
891
+
892
+ state , err := LoadStateFromDBOrGenesisDoc (stateStore , stateDB , genDoc )
893
+
881
894
csMetrics , p2pMetrics , memplMetrics , smMetrics , abciMetrics := metricsProvider (genDoc .ChainID )
882
895
883
896
// Create the proxyApp and establish connections to the ABCI app (consensus, mempool, query).
@@ -1540,68 +1553,94 @@ func makeNodeInfo(
1540
1553
1541
1554
//------------------------------------------------------------------------------
1542
1555
1543
- var genesisDocKey = []byte ("genesisDoc " )
1556
+ var genesisDocHashKey = []byte ("genesisDocHash " )
1544
1557
1545
- // LoadStateFromDBOrGenesisDocProvider attempts to load the state from the
1558
+ // LoadStateFromDBOrGenesisDoc attempts to load the state from the
1546
1559
// database, or creates one using the given genesisDocProvider. On success this also
1547
1560
// returns the genesis doc loaded through the given provider.
1548
- func LoadStateFromDBOrGenesisDocProvider (
1561
+ func LoadStateFromDBOrGenesisDoc (
1562
+ stateStore sm.Store ,
1549
1563
stateDB dbm.DB ,
1550
- genesisDocProvider GenesisDocProvider ,
1551
- ) (sm.State , * types.GenesisDoc , error ) {
1552
- // Get genesis doc
1553
- genDoc , err := loadGenesisDoc (stateDB )
1554
- if err != nil {
1555
- genDoc , err = genesisDocProvider ()
1556
- if err != nil {
1557
- return sm.State {}, nil , err
1558
- }
1559
- // save genesis doc to prevent a certain class of user errors (e.g. when it
1560
- // was changed, accidentally or not). Also good for audit trail.
1561
- if err := saveGenesisDoc (stateDB , genDoc ); err != nil {
1562
- return sm.State {}, nil , err
1563
- }
1564
- }
1565
- stateStore := sm .NewStore (stateDB , sm.StoreOptions {
1566
- DiscardABCIResponses : false ,
1567
- })
1568
- state , err := stateStore .LoadFromDBOrGenesisDoc (genDoc )
1564
+ genDoc * types.GenesisDoc ,
1565
+ ) (sm.State , error ) {
1566
+ // 1. Verify genesisDoc hash in db if exists
1567
+ genDocHash , err := stateDB .Get (genesisDocHashKey )
1569
1568
if err != nil {
1570
- return sm.State {}, nil , err
1569
+ return sm.State {}, err
1571
1570
}
1572
- return state , genDoc , nil
1573
- }
1574
1571
1575
- // panics if failed to unmarshal bytes
1576
- func loadGenesisDoc (db dbm.DB ) (* types.GenesisDoc , error ) {
1577
- b , err := db .Get (genesisDocKey )
1578
- if err != nil {
1579
- panic (err )
1580
- }
1581
- if len (b ) == 0 {
1582
- return nil , errors .New ("genesis doc not found" )
1583
- }
1584
- var genDoc * types.GenesisDoc
1585
- err = cmtjson .Unmarshal (b , & genDoc )
1586
- if err != nil {
1587
- panic (fmt .Sprintf ("Failed to load genesis doc due to unmarshaling error: %v (bytes: %X)" , err , b ))
1572
+ validatorsHash := genDoc .ValidatorHash ()
1573
+
1574
+ incomingGenDocHash := tmhash .Sum (validatorsHash )
1575
+
1576
+ fmt .Println ("Loaded genesis doc" , "chain_id" , genDoc .ChainID , "app_hash" , genDoc .AppHash )
1577
+ fmt .Println ("incomingGenDocHash: " , incomingGenDocHash )
1578
+ fmt .Println ("genDocHash: " , genDocHash )
1579
+
1580
+ if len (genDocHash ) != 0 && ! bytes .Equal (genDocHash , incomingGenDocHash ) {
1581
+ return sm.State {}, fmt .Errorf ("genesis doc hash in db does not match loaded genesis doc" )
1588
1582
}
1589
- return genDoc , nil
1590
- }
1591
1583
1592
- // panics if failed to marshal the given genesis document
1593
- func saveGenesisDoc (db dbm.DB , genDoc * types.GenesisDoc ) error {
1594
- b , err := cmtjson .Marshal (genDoc )
1584
+ // 2. Attempt to load state form the database
1585
+ state , err := stateStore .Load ()
1595
1586
if err != nil {
1596
- return fmt . Errorf ( "failed to save genesis doc due to marshaling error: %w" , err )
1587
+ return sm. State {} , err
1597
1588
}
1598
- if err := db .SetSync (genesisDocKey , b ); err != nil {
1599
- return err
1589
+
1590
+ if state .IsEmpty () {
1591
+ // 3. If it's not there, derive it from the genesis doc
1592
+ state , err = sm .MakeGenesisState (genDoc )
1593
+ if err != nil {
1594
+ return sm.State {}, err
1595
+ }
1596
+
1597
+ // 4. save the gensis document to the state store so
1598
+ // its fetchable by other callers.
1599
+ if err := stateStore .Save (state ); err != nil {
1600
+ return sm.State {}, err
1601
+ }
1602
+
1603
+ // 5. Save the genDoc hash in the store if it doesn't already exist for future verification
1604
+ if len (genDocHash ) == 0 {
1605
+ if err := stateDB .SetSync (genesisDocHashKey , incomingGenDocHash ); err != nil {
1606
+ return sm.State {}, fmt .Errorf ("failed to save genesis doc hash to db: %w" , err )
1607
+ }
1608
+ }
1600
1609
}
1601
1610
1602
- return nil
1611
+ return state , nil
1603
1612
}
1604
1613
1614
+ // // panics if failed to unmarshal bytes
1615
+ // func loadGenesisDoc(db dbm.DB) (*types.GenesisDoc, error) {
1616
+ // b, err := db.Get(genesisDocKey)
1617
+ // if err != nil {
1618
+ // panic(err)
1619
+ // }
1620
+ // if len(b) == 0 {
1621
+ // return nil, errors.New("genesis doc not found")
1622
+ // }
1623
+ // var genDoc *types.GenesisDoc
1624
+ // err = cmtjson.Unmarshal(b, &genDoc)
1625
+ // if err != nil {
1626
+ // panic(fmt.Sprintf("Failed to load genesis doc due to unmarshaling error: %v (bytes: %X)", err, b))
1627
+ // }
1628
+ // return genDoc, nil
1629
+ // }
1630
+
1631
+ // // panics if failed to marshal the given genesis document
1632
+ // func saveGenesisDoc(db dbm.DB, genDoc *types.GenesisDoc) error {
1633
+ // b, err := cmtjson.Marshal(genDoc)
1634
+ // if err != nil {
1635
+ // return fmt.Errorf("failed to save genesis doc due to marshaling error: %w", err)
1636
+ // }
1637
+ // if err := db.SetSync(genesisDocKey, b); err != nil {
1638
+ // return err
1639
+ // }
1640
+
1641
+ // return nil
1642
+ // }
1643
+
1605
1644
func createAndStartPrivValidatorSocketClient (
1606
1645
listenAddr ,
1607
1646
chainID string ,
0 commit comments