diff --git a/app/app.go b/app/app.go index 52fd39c9..d3fc8e36 100644 --- a/app/app.go +++ b/app/app.go @@ -20,6 +20,7 @@ import ( "github.com/cybercongress/cyberd/x/bandwidth" bw "github.com/cybercongress/cyberd/x/bandwidth/types" cbdbank "github.com/cybercongress/cyberd/x/bank" + "github.com/cybercongress/cyberd/x/debug" "github.com/cybercongress/cyberd/x/link" "github.com/cybercongress/cyberd/x/link/keeper" "github.com/cybercongress/cyberd/x/mint" @@ -86,8 +87,7 @@ type CyberdApp struct { latestBlockHeight int64 - // debug values - failBeforeHeight int64 + debugState *debug.State } // NewBasecoinApp returns a reference to a new CyberdApp given a @@ -235,7 +235,7 @@ func NewCyberdApp( // RANK PARAMS app.rankState.Load(ctx, app.Logger()) - app.failBeforeHeight = opts.FailBeforeHeight + app.debugState = &debug.State{Opts: opts.Debug, StartupBlock: app.latestBlockHeight} app.Seal() return app } @@ -450,10 +450,7 @@ func getSignersTags(tx sdk.Tx) sdk.Tags { func (app *CyberdApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock { - if app.failBeforeHeight != 0 && req.Header.Height == app.failBeforeHeight { - app.Logger().Info("Forced panic at begin blocker", "height", app.failBeforeHeight) - os.Exit(1) - } + debug.BeginBlocker(app.debugState, req, app.Logger()) // mint new tokens for the previous block mint.BeginBlocker(ctx, app.minter) diff --git a/app/options.go b/app/options.go index 1f325f75..bbac69fa 100644 --- a/app/options.go +++ b/app/options.go @@ -1,12 +1,13 @@ package app -import "github.com/cybercongress/cyberd/x/rank" +import ( + "github.com/cybercongress/cyberd/x/debug" + "github.com/cybercongress/cyberd/x/rank" +) type Options struct { - // main options ComputeUnit rank.ComputeUnit AllowSearch bool - // debug options - FailBeforeHeight int64 + Debug debug.Options } diff --git a/daemon/main.go b/daemon/main.go index 05396ff6..4fa3645f 100644 --- a/daemon/main.go +++ b/daemon/main.go @@ -10,6 +10,7 @@ import ( "github.com/cybercongress/cyberd/daemon/cmd" "github.com/cybercongress/cyberd/daemon/rpc" "github.com/cybercongress/cyberd/util" + "github.com/cybercongress/cyberd/x/debug" "github.com/cybercongress/cyberd/x/rank" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -24,10 +25,11 @@ import ( ) const ( - flagGpuEnabled = "compute-rank-on-gpu" - flagFailBeforeHeight = "fail-before-height" - flagSearchEnabled = "allow-search" - flagNotToSealAccPrefix = "not-to-seal-acc-prefix" + flagGpuEnabled = "compute-rank-on-gpu" + flagFailBeforeHeight = "fail-before-height" + flagFailRandomlyInNextNBlocks = "fail-randomly-in-next-n-blocks" + flagSearchEnabled = "allow-search" + flagNotToSealAccPrefix = "not-to-seal-acc-prefix" ) func main() { @@ -57,6 +59,7 @@ func main() { if c.Use == "start" { c.Flags().Bool(flagGpuEnabled, true, "Run cyberd with cuda calculations") c.Flags().Int64(flagFailBeforeHeight, 0, "Forced node shutdown before specified height") + c.Flags().Int64(flagFailRandomlyInNextNBlocks, 0, "Forced node shutdown at random heights") c.Flags().Bool(flagSearchEnabled, false, "Build index of links with ranks and allow to query search through RPC") } } @@ -78,9 +81,9 @@ func newApp(logger log.Logger, db dbm.DB, storeTracer io.Writer) abci.Applicatio } opts := app.Options{ - ComputeUnit: computeUnit, - AllowSearch: viper.GetBool(flagSearchEnabled), - FailBeforeHeight: viper.GetInt64(flagFailBeforeHeight), + ComputeUnit: computeUnit, + AllowSearch: viper.GetBool(flagSearchEnabled), + Debug: getDebugOptsFromFlags(), } cyberdApp := app.NewCyberdApp(logger, db, opts, pruning) rpc.SetCyberdApp(cyberdApp) @@ -104,3 +107,9 @@ func setAppPrefix(_ *cobra.Command, args []string) error { app.SetPrefix() return nil } + +func getDebugOptsFromFlags() (opts debug.Options) { + opts.FailRandomlyInNextNBlocks = viper.GetInt64(flagFailRandomlyInNextNBlocks) + opts.FailBeforeBlock = viper.GetInt64(flagFailBeforeHeight) + return +} diff --git a/x/debug/abci.go b/x/debug/abci.go new file mode 100644 index 00000000..3adda818 --- /dev/null +++ b/x/debug/abci.go @@ -0,0 +1,24 @@ +package debug + +import ( + abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/libs/log" + "math/rand" + "os" +) + +func BeginBlocker(state *State, req abci.RequestBeginBlock, log log.Logger) { + + if state.Opts.FailRandomlyInNextNBlocks != 0 { + randNum := rand.Int63n(state.Opts.FailRandomlyInNextNBlocks) + 1 + state.Opts.FailBeforeBlock = state.StartupBlock + randNum + state.Opts.FailRandomlyInNextNBlocks = 0 + log.Info("Scheduled forced panic at begin blocker ", "height", state.Opts.FailBeforeBlock) + } + + failBeforeBlock := state.Opts.FailBeforeBlock + if failBeforeBlock != 0 && req.Header.Height == failBeforeBlock { + log.Info("Forced panic at begin blocker", "height", failBeforeBlock) + os.Exit(1) + } +} diff --git a/x/debug/options.go b/x/debug/options.go new file mode 100644 index 00000000..b162160b --- /dev/null +++ b/x/debug/options.go @@ -0,0 +1,6 @@ +package debug + +type Options struct { + FailBeforeBlock int64 + FailRandomlyInNextNBlocks int64 +} diff --git a/x/debug/state.go b/x/debug/state.go new file mode 100644 index 00000000..97209ada --- /dev/null +++ b/x/debug/state.go @@ -0,0 +1,6 @@ +package debug + +type State struct { + Opts Options + StartupBlock int64 +}