Files
tendermint/node/debug.go
William Banfield 03ee71eac4 PR feedback fixes
2021-08-02 12:50:13 -04:00

83 lines
2.3 KiB
Go

package node
import (
"net"
"github.com/tendermint/tendermint/config"
cfg "github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/libs/log"
"github.com/tendermint/tendermint/libs/service"
rpccore "github.com/tendermint/tendermint/rpc/core"
sm "github.com/tendermint/tendermint/state"
"github.com/tendermint/tendermint/store"
"github.com/tendermint/tendermint/types"
)
// Debug manages an RPC service that exports methods to debug a failed node.
// After a node shuts down due to a consensus failure,, it will no longer start
// up and cannot easily be inspected. A Debug value provides a similar interface
// to the node, using the underlying Tendermint data stores, without bringing up
// any other components. A caller can query the Debug service to inspect the
// persisted state and debug the failure.
type Debug struct {
service.BaseService
blockStore sm.BlockStore
stateStore sm.Store
rpcConfig *cfg.RPCConfig
listeners []net.Listener
}
func NewDebugFromConfig(cfg *config.Config) (*Debug, error) {
blockStoreDB, err := config.DefaultDBProvider(&config.DBContext{ID: _blockStoreID, Config: cfg})
if err != nil {
return nil, err
}
blockStore := store.NewBlockStore(blockStoreDB)
stateDB, err := config.DefaultDBProvider(&config.DBContext{ID: _stateStoreID, Config: cfg})
if err != nil {
return nil, err
}
stateStore := sm.NewStore(stateDB)
return NewDebug(cfg.RPC, blockStore, stateStore), nil
}
func NewDebug(rpcConfig *cfg.RPCConfig, blockStore sm.BlockStore, stateStore sm.Store) *Debug {
return &Debug{
blockStore: blockStore,
stateStore: stateStore,
rpcConfig: rpcConfig,
}
}
func NewDefaultDebug() (*Debug, error) {
cfg := config.Config{
BaseConfig: config.DefaultBaseConfig(),
RPC: config.DefaultRPCConfig(),
}
return NewDebugFromConfig(&cfg)
}
func (debug *Debug) OnStart() error {
rpcCoreEnv := rpccore.Environment{
StateStore: debug.stateStore,
BlockStore: debug.blockStore,
}
routes := rpcCoreEnv.InfoRoutes()
l := log.MustNewDefaultLogger(log.LogFormatPlain, log.LogLevelInfo, false)
listeners, err := startRPCServers(debug.rpcConfig, l, routes, types.NopEventBus{})
if err != nil {
return err
}
debug.listeners = listeners
return nil
}
func (debug *Debug) OnStop() {
for i := len(debug.listeners) - 1; i >= 0; i-- {
debug.listeners[i].Close()
}
}