diff --git a/node/node.go b/node/node.go index a3795ea14..37cff9776 100644 --- a/node/node.go +++ b/node/node.go @@ -72,7 +72,6 @@ type nodeImpl struct { stateSync bool // whether the node should state sync on startup stateSyncReactor *statesync.Reactor // for hosting and restoring state sync snapshots stateSyncProvider statesync.StateProvider // provides state data for bootstrapping a node - stateSyncGenesis sm.State // provides the genesis state for state sync consensusState *cs.State // latest consensus state consensusReactor *cs.Reactor // for participating in the consensus pexReactor *pex.Reactor // for exchanging peer addresses @@ -440,7 +439,6 @@ func makeNode(config *cfg.Config, consensusReactor: csReactor, stateSyncReactor: stateSyncReactor, stateSync: stateSync, - stateSyncGenesis: state, // Shouldn't be necessary, but need a way to pass the genesis state pexReactor: pexReactor, pexReactorV2: pexReactorV2, evidenceReactor: evReactor, @@ -662,8 +660,15 @@ func (n *nodeImpl) OnStart() error { if !ok { return fmt.Errorf("this blockchain reactor does not support switching from state sync") } - err := startStateSync(n.stateSyncReactor, bcR, n.consensusReactor, n.stateSyncProvider, - n.config.StateSync, n.config.FastSyncMode, n.stateStore, n.blockStore, n.stateSyncGenesis) + + // we need to get the genesis state to get parameters such as + state, err := sm.MakeGenesisState(n.genesisDoc) + if err != nil { + return fmt.Errorf("unable to derive state: %w", err) + } + + err = startStateSync(n.stateSyncReactor, bcR, n.consensusReactor, n.stateSyncProvider, + n.config.StateSync, n.config.FastSyncMode, n.stateStore, n.blockStore, state) if err != nil { return fmt.Errorf("failed to start state sync: %w", err) } @@ -1028,7 +1033,7 @@ func (n *nodeImpl) NodeInfo() p2p.NodeInfo { func startStateSync(ssR *statesync.Reactor, bcR fastSyncReactor, conR *cs.Reactor, stateProvider statesync.StateProvider, config *cfg.StateSyncConfig, fastSync bool, stateStore sm.Store, blockStore *store.BlockStore, state sm.State) error { - ssR.Logger.Info("Starting state sync") + ssR.Logger.Info("starting state sync...") if stateProvider == nil { var err error @@ -1050,13 +1055,13 @@ func startStateSync(ssR *statesync.Reactor, bcR fastSyncReactor, conR *cs.Reacto go func() { err := ssR.Sync(stateProvider, config.DiscoveryTime) if err != nil { - ssR.Logger.Error("State sync failed", "err", err) + ssR.Logger.Error("state sync failed", "err", err) return } state, err := stateStore.Load() if err != nil { - ssR.Logger.Error("failed to load state", "err", err) + ssR.Logger.Error("failed to load state after statesync", "err", err) } if fastSync { @@ -1065,7 +1070,7 @@ func startStateSync(ssR *statesync.Reactor, bcR fastSyncReactor, conR *cs.Reacto conR.Metrics.FastSyncing.Set(1) err = bcR.SwitchToFastSync(state) if err != nil { - ssR.Logger.Error("Failed to switch to fast sync", "err", err) + ssR.Logger.Error("failed to switch to fast sync", "err", err) return } } else { @@ -1122,16 +1127,11 @@ func loadStateFromDBOrGenesisDocProvider( } if state.IsEmpty() { - // 2. If it's not there, load it from the genesis doc + // 2. If it's not there, derive it from the genesis doc state, err = sm.MakeGenesisState(genDoc) if err != nil { return sm.State{}, err } - - // 3. Save the new state to disk - if err := stateStore.Save(state); err != nil { - return sm.State{}, err - } } return state, nil diff --git a/node/node_test.go b/node/node_test.go index 963a2f86b..6ab0301b4 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -25,6 +25,7 @@ import ( "github.com/tendermint/tendermint/internal/mempool" mempoolv0 "github.com/tendermint/tendermint/internal/mempool/v0" "github.com/tendermint/tendermint/internal/p2p" + "github.com/tendermint/tendermint/internal/test/factory" "github.com/tendermint/tendermint/libs/log" tmrand "github.com/tendermint/tendermint/libs/rand" "github.com/tendermint/tendermint/privval" @@ -619,3 +620,22 @@ func state(nVals int, height int64) (sm.State, dbm.DB, []types.PrivValidator) { } return s, stateDB, privVals } + +func TestLoadStateFromGenesis(t *testing.T) { + stateDB := dbm.NewMemDB() + stateStore := sm.NewStore(stateDB) + config := cfg.ResetTestRoot("load_state_from_genesis") + + loadedState, err := stateStore.Load() + require.NoError(t, err) + require.True(t, loadedState.IsEmpty()) + + genDoc, _ := factory.RandGenesisDoc(config, 0, false, 10) + + state, err := loadStateFromDBOrGenesisDocProvider( + stateStore, + genDoc, + ) + require.NoError(t, err) + require.NotNil(t, state) +} diff --git a/node/setup.go b/node/setup.go index d1b8fbd41..dc12bf989 100644 --- a/node/setup.go +++ b/node/setup.go @@ -295,7 +295,7 @@ func createEvidenceReactor( evidencePool, err := evidence.NewPool(logger, evidenceDB, sm.NewStore(stateDB), blockStore) if err != nil { - return nil, nil, nil, err + return nil, nil, nil, fmt.Errorf("creating evidence pool: %w", err) } var ( diff --git a/rpc/jsonrpc/server/http_json_handler.go b/rpc/jsonrpc/server/http_json_handler.go index eb8a22eb4..bbb32b407 100644 --- a/rpc/jsonrpc/server/http_json_handler.go +++ b/rpc/jsonrpc/server/http_json_handler.go @@ -141,7 +141,7 @@ func makeJSONRPCHandler(funcMap map[string]*RPCFunc, logger log.Logger) http.Han if len(responses) > 0 { if wErr := WriteRPCResponseHTTP(w, c, responses...); wErr != nil { - logger.Error("failed to write responses", "res", responses, "err", wErr) + logger.Error("failed to write responses", "err", wErr) } } } diff --git a/state/state.go b/state/state.go index d5362fc40..bf266085c 100644 --- a/state/state.go +++ b/state/state.go @@ -341,7 +341,7 @@ func MakeGenesisState(genDoc *types.GenesisDoc) (State, error) { } var validatorSet, nextValidatorSet *types.ValidatorSet - if genDoc.Validators == nil { + if genDoc.Validators == nil || len(genDoc.Validators) == 0 { validatorSet = types.NewValidatorSet(nil) nextValidatorSet = types.NewValidatorSet(nil) } else { diff --git a/state/store.go b/state/store.go index 3b67632df..84b19a685 100644 --- a/state/store.go +++ b/state/store.go @@ -107,43 +107,6 @@ func NewStore(db dbm.DB) Store { return dbStore{db} } -// LoadStateFromDBOrGenesisFile loads the most recent state from the database, -// or creates a new one from the given genesisFilePath. -func (store dbStore) LoadFromDBOrGenesisFile(genesisFilePath string) (State, error) { - state, err := store.Load() - if err != nil { - return State{}, err - } - if state.IsEmpty() { - var err error - state, err = MakeGenesisStateFromFile(genesisFilePath) - if err != nil { - return state, err - } - } - - return state, nil -} - -// LoadStateFromDBOrGenesisDoc loads the most recent state from the database, -// or creates a new one from the given genesisDoc. -func (store dbStore) LoadFromDBOrGenesisDoc(genesisDoc *types.GenesisDoc) (State, error) { - state, err := store.Load() - if err != nil { - return State{}, err - } - - if state.IsEmpty() { - var err error - state, err = MakeGenesisState(genesisDoc) - if err != nil { - return state, err - } - } - - return state, nil -} - // LoadState loads the State from the database. func (store dbStore) Load() (State, error) { return store.loadState(stateKey)