Browse Source

libs/os: remove arbitrary os.Exit (#7284)

I think calling os.Exit at arbitrary points is _bad_ and is good to
delete. I think panics in the case of data courruption have a chance
of providing useful information.
pull/7289/head
Sam Kleinman 3 years ago
committed by GitHub
parent
commit
2a455be46c
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 22 additions and 26 deletions
  1. +13
    -10
      internal/consensus/replay_file.go
  2. +4
    -9
      internal/state/store.go
  3. +0
    -5
      libs/os/os.go
  4. +5
    -2
      rpc/jsonrpc/test/main.go

+ 13
- 10
internal/consensus/replay_file.go View File

@ -18,7 +18,6 @@ import (
sm "github.com/tendermint/tendermint/internal/state" sm "github.com/tendermint/tendermint/internal/state"
"github.com/tendermint/tendermint/internal/store" "github.com/tendermint/tendermint/internal/store"
"github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/libs/log"
tmos "github.com/tendermint/tendermint/libs/os"
tmpubsub "github.com/tendermint/tendermint/libs/pubsub" tmpubsub "github.com/tendermint/tendermint/libs/pubsub"
"github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/types"
) )
@ -92,7 +91,10 @@ func (cs *State) ReplayFile(file string, console bool) error {
var msg *TimedWALMessage var msg *TimedWALMessage
for { for {
if nextN == 0 && console { if nextN == 0 && console {
nextN = pb.replayConsoleLoop()
nextN, err = pb.replayConsoleLoop()
if err != nil {
return err
}
} }
msg, err = pb.dec.Decode() msg, err = pb.dec.Decode()
@ -194,16 +196,17 @@ func (cs *State) startForReplay() {
}()*/ }()*/
} }
// console function for parsing input and running commands
func (pb *playback) replayConsoleLoop() int {
// console function for parsing input and running commands. The integer
// return value is invalid unless the error is nil.
func (pb *playback) replayConsoleLoop() (int, error) {
for { for {
fmt.Printf("> ") fmt.Printf("> ")
bufReader := bufio.NewReader(os.Stdin) bufReader := bufio.NewReader(os.Stdin)
line, more, err := bufReader.ReadLine() line, more, err := bufReader.ReadLine()
if more { if more {
tmos.Exit("input is too long")
return 0, fmt.Errorf("input is too long")
} else if err != nil { } else if err != nil {
tmos.Exit(err.Error())
return 0, err
} }
tokens := strings.Split(string(line), " ") tokens := strings.Split(string(line), " ")
@ -217,13 +220,13 @@ func (pb *playback) replayConsoleLoop() int {
// "next N" -> replay next N messages // "next N" -> replay next N messages
if len(tokens) == 1 { if len(tokens) == 1 {
return 0
return 0, nil
} }
i, err := strconv.Atoi(tokens[1]) i, err := strconv.Atoi(tokens[1])
if err != nil { if err != nil {
fmt.Println("next takes an integer argument") fmt.Println("next takes an integer argument")
} else { } else {
return i
return i, nil
} }
case "back": case "back":
@ -233,7 +236,7 @@ func (pb *playback) replayConsoleLoop() int {
// NOTE: "back" is not supported in the state machine design, // NOTE: "back" is not supported in the state machine design,
// so we restart and replay up to // so we restart and replay up to
ctx := context.Background()
ctx := context.TODO()
// ensure all new step events are regenerated as expected // ensure all new step events are regenerated as expected
newStepSub, err := pb.cs.eventBus.SubscribeWithArgs(ctx, tmpubsub.SubscribeArgs{ newStepSub, err := pb.cs.eventBus.SubscribeWithArgs(ctx, tmpubsub.SubscribeArgs{
@ -241,7 +244,7 @@ func (pb *playback) replayConsoleLoop() int {
Query: types.EventQueryNewRoundStep, Query: types.EventQueryNewRoundStep,
}) })
if err != nil { if err != nil {
tmos.Exit(fmt.Sprintf("failed to subscribe %s to %v", subscriber, types.EventQueryNewRoundStep))
return 0, fmt.Errorf("failed to subscribe %s to %v", subscriber, types.EventQueryNewRoundStep)
} }
defer func() { defer func() {
args := tmpubsub.UnsubscribeArgs{Subscriber: subscriber, Query: types.EventQueryNewRoundStep} args := tmpubsub.UnsubscribeArgs{Subscriber: subscriber, Query: types.EventQueryNewRoundStep}


+ 4
- 9
internal/state/store.go View File

@ -11,7 +11,6 @@ import (
abci "github.com/tendermint/tendermint/abci/types" abci "github.com/tendermint/tendermint/abci/types"
tmmath "github.com/tendermint/tendermint/libs/math" tmmath "github.com/tendermint/tendermint/libs/math"
tmos "github.com/tendermint/tendermint/libs/os"
tmstate "github.com/tendermint/tendermint/proto/tendermint/state" tmstate "github.com/tendermint/tendermint/proto/tendermint/state"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types" tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
"github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/types"
@ -126,8 +125,7 @@ func (store dbStore) loadState(key []byte) (state State, err error) {
err = proto.Unmarshal(buf, sp) err = proto.Unmarshal(buf, sp)
if err != nil { if err != nil {
// DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED // DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED
tmos.Exit(fmt.Sprintf(`LoadState: Data has been corrupted or its spec has changed:
%v\n`, err))
panic(fmt.Sprintf("data has been corrupted or its spec has changed: %+v", err))
} }
sm, err := FromProto(sp) sm, err := FromProto(sp)
@ -424,8 +422,7 @@ func (store dbStore) LoadABCIResponses(height int64) (*tmstate.ABCIResponses, er
err = abciResponses.Unmarshal(buf) err = abciResponses.Unmarshal(buf)
if err != nil { if err != nil {
// DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED // DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED
tmos.Exit(fmt.Sprintf(`LoadABCIResponses: Data has been corrupted or its spec has
changed: %v\n`, err))
panic(fmt.Sprintf("data has been corrupted or its spec has changed: %+v", err))
} }
// TODO: ensure that buf is completely read. // TODO: ensure that buf is completely read.
@ -544,8 +541,7 @@ func loadValidatorsInfo(db dbm.DB, height int64) (*tmstate.ValidatorsInfo, error
err = v.Unmarshal(buf) err = v.Unmarshal(buf)
if err != nil { if err != nil {
// DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED // DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED
tmos.Exit(fmt.Sprintf(`LoadValidators: Data has been corrupted or its spec has changed:
%v\n`, err))
panic(fmt.Sprintf("data has been corrupted or its spec has changed: %+v", err))
} }
// TODO: ensure that buf is completely read. // TODO: ensure that buf is completely read.
@ -632,8 +628,7 @@ func (store dbStore) loadConsensusParamsInfo(height int64) (*tmstate.ConsensusPa
paramsInfo := new(tmstate.ConsensusParamsInfo) paramsInfo := new(tmstate.ConsensusParamsInfo)
if err = paramsInfo.Unmarshal(buf); err != nil { if err = paramsInfo.Unmarshal(buf); err != nil {
// DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED // DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED
tmos.Exit(fmt.Sprintf(`LoadConsensusParams: Data has been corrupted or its spec has changed:
%v\n`, err))
panic(fmt.Sprintf(`data has been corrupted or its spec has changed: %+v`, err))
} }
// TODO: ensure that buf is completely read. // TODO: ensure that buf is completely read.


+ 0
- 5
libs/os/os.go View File

@ -29,11 +29,6 @@ func TrapSignal(logger logger, cb func()) {
}() }()
} }
func Exit(s string) {
fmt.Printf(s + "\n")
os.Exit(1)
}
// EnsureDir ensures the given directory exists, creating it if necessary. // EnsureDir ensures the given directory exists, creating it if necessary.
// Errors if the path already exists as a non-directory. // Errors if the path already exists as a non-directory.
func EnsureDir(dir string, mode os.FileMode) error { func EnsureDir(dir string, mode os.FileMode) error {


+ 5
- 2
rpc/jsonrpc/test/main.go View File

@ -3,6 +3,7 @@ package main
import ( import (
"fmt" "fmt"
"net/http" "net/http"
"os"
"github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/libs/log"
tmos "github.com/tendermint/tendermint/libs/os" tmos "github.com/tendermint/tendermint/libs/os"
@ -35,10 +36,12 @@ func main() {
config := rpcserver.DefaultConfig() config := rpcserver.DefaultConfig()
listener, err := rpcserver.Listen("tcp://127.0.0.1:8008", config.MaxOpenConnections) listener, err := rpcserver.Listen("tcp://127.0.0.1:8008", config.MaxOpenConnections)
if err != nil { if err != nil {
tmos.Exit(err.Error())
logger.Error("rpc listening", "err", err)
os.Exit(1)
} }
if err = rpcserver.Serve(listener, mux, logger, config); err != nil { if err = rpcserver.Serve(listener, mux, logger, config); err != nil {
tmos.Exit(err.Error())
logger.Error("rpc serve", "err", err)
os.Exit(1)
} }
} }

Loading…
Cancel
Save