mirror of
https://github.com/tendermint/tendermint.git
synced 2026-02-04 11:02:06 +00:00
85 lines
2.4 KiB
Go
85 lines
2.4 KiB
Go
package node
|
|
|
|
import (
|
|
"net"
|
|
|
|
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(config *cfg.Config) (*Debug, error) {
|
|
blockStoreDB, err := cfg.DefaultDBProvider(&cfg.DBContext{ID: _blockStoreID, Config: config})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
blockStore := store.NewBlockStore(blockStoreDB)
|
|
stateDB, err := cfg.DefaultDBProvider(&cfg.DBContext{ID: _stateStoreID, Config: config})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
stateStore := sm.NewStore(stateDB)
|
|
|
|
return NewDebug(config.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) {
|
|
config := cfg.Config{
|
|
BaseConfig: cfg.DefaultBaseConfig(),
|
|
RPC: cfg.DefaultRPCConfig(),
|
|
}
|
|
return NewDebugFromConfig(&config)
|
|
}
|
|
|
|
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-- {
|
|
err := debug.listeners[i].Close()
|
|
if err != nil {
|
|
debug.Logger.Error("Error stopping debug rpc listener", "err", err)
|
|
}
|
|
}
|
|
}
|