From 926c469fcc233b6f151fb80e78811c9054ee710f Mon Sep 17 00:00:00 2001 From: "M. J. Fromberger" Date: Tue, 22 Feb 2022 09:14:40 -0800 Subject: [PATCH 1/3] Restore building docs for master on docs.tendermint.com. (#7969) There are a lot of existing links to the master section of the site, and my attempts to get a redirector working have so far not succeeded. While it still makes sense to not publish docs for unreleased code, a 404 is almost certainly more disruptive than seeing docs for unreleased stuff. This includes the docs in the build again, but does not add them back to the selector menu. That allows URLs to resolve but encourages folks to use the released versions when they have a choice. I left the redirect for the RPC link in place, since that's still useful. Updates #7935. --- docs/versions | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/versions b/docs/versions index 90a8a4cf1..70754facc 100644 --- a/docs/versions +++ b/docs/versions @@ -1,3 +1,4 @@ +master master v0.33.x v0.33 v0.34.x v0.34 v0.35.x v0.35 From 912751cf930c5bc2da068e0d2834e09d56ae78b3 Mon Sep 17 00:00:00 2001 From: Sam Kleinman Date: Tue, 22 Feb 2022 13:34:17 -0500 Subject: [PATCH 2/3] math: remove panics in safe math ops (#7962) * math: remove panics in safe math ops * fix docs * fix lint --- internal/consensus/state.go | 15 ++++++-- internal/consensus/types/height_vote_set.go | 6 +++- internal/state/store.go | 6 +++- libs/math/safemath.go | 39 +++++++++------------ 4 files changed, 40 insertions(+), 26 deletions(-) diff --git a/internal/consensus/state.go b/internal/consensus/state.go index 12b023a1f..5e54a0720 100644 --- a/internal/consensus/state.go +++ b/internal/consensus/state.go @@ -1086,6 +1086,8 @@ func (cs *State) handleTxsAvailable(ctx context.Context) { // Enter: +2/3 prevotes any or +2/3 precommits for block or any from (height, round) // NOTE: cs.StartTime was already set for height. func (cs *State) enterNewRound(ctx context.Context, height int64, round int32) { + // TODO: remove panics in this function and return an error + logger := cs.logger.With("height", height, "round", round) if cs.Height != height || round < cs.Round || (cs.Round == round && cs.Step != cstypes.RoundStepNewHeight) { @@ -1106,7 +1108,11 @@ func (cs *State) enterNewRound(ctx context.Context, height int64, round int32) { validators := cs.Validators if cs.Round < round { validators = validators.Copy() - validators.IncrementProposerPriority(tmmath.SafeSubInt32(round, cs.Round)) + r, err := tmmath.SafeSubInt32(round, cs.Round) + if err != nil { + panic(err) + } + validators.IncrementProposerPriority(r) } // Setup new round @@ -1126,7 +1132,12 @@ func (cs *State) enterNewRound(ctx context.Context, height int64, round int32) { cs.ProposalBlockParts = nil } - cs.Votes.SetRound(tmmath.SafeAddInt32(round, 1)) // also track next round (round+1) to allow round-skipping + r, err := tmmath.SafeAddInt32(round, 1) + if err != nil { + panic(err) + } + + cs.Votes.SetRound(r) // also track next round (round+1) to allow round-skipping cs.TriggeredTimeoutPrecommit = false if err := cs.eventBus.PublishEventNewRound(ctx, cs.NewRoundEvent()); err != nil { diff --git a/internal/consensus/types/height_vote_set.go b/internal/consensus/types/height_vote_set.go index 86c5d4c46..dd8630725 100644 --- a/internal/consensus/types/height_vote_set.go +++ b/internal/consensus/types/height_vote_set.go @@ -85,7 +85,11 @@ func (hvs *HeightVoteSet) Round() int32 { func (hvs *HeightVoteSet) SetRound(round int32) { hvs.mtx.Lock() defer hvs.mtx.Unlock() - newRound := tmmath.SafeSubInt32(hvs.round, 1) + newRound, err := tmmath.SafeSubInt32(hvs.round, 1) + if err != nil { + panic(err) + } + if hvs.round != 0 && (round < newRound) { panic("SetRound() must increment hvs.round") } diff --git a/internal/state/store.go b/internal/state/store.go index c8b99b36d..c3e7b24a6 100644 --- a/internal/state/store.go +++ b/internal/state/store.go @@ -504,8 +504,12 @@ func (store dbStore) LoadValidators(height int64) (*types.ValidatorSet, error) { if err != nil { return nil, err } + h, err := tmmath.SafeConvertInt32(height - lastStoredHeight) + if err != nil { + return nil, err + } - vs.IncrementProposerPriority(tmmath.SafeConvertInt32(height - lastStoredHeight)) // mutate + vs.IncrementProposerPriority(h) // mutate vi2, err := vs.ToProto() if err != nil { return nil, err diff --git a/libs/math/safemath.go b/libs/math/safemath.go index ff7f0908f..af40548ea 100644 --- a/libs/math/safemath.go +++ b/libs/math/safemath.go @@ -9,41 +9,37 @@ var ErrOverflowInt32 = errors.New("int32 overflow") var ErrOverflowUint8 = errors.New("uint8 overflow") var ErrOverflowInt8 = errors.New("int8 overflow") -// SafeAddInt32 adds two int32 integers -// If there is an overflow this will panic -func SafeAddInt32(a, b int32) int32 { +// SafeAddInt32 adds two int32 integers. +func SafeAddInt32(a, b int32) (int32, error) { if b > 0 && (a > math.MaxInt32-b) { - panic(ErrOverflowInt32) + return 0, ErrOverflowInt32 } else if b < 0 && (a < math.MinInt32-b) { - panic(ErrOverflowInt32) + return 0, ErrOverflowInt32 } - return a + b + return a + b, nil } -// SafeSubInt32 subtracts two int32 integers -// If there is an overflow this will panic -func SafeSubInt32(a, b int32) int32 { +// SafeSubInt32 subtracts two int32 integers. +func SafeSubInt32(a, b int32) (int32, error) { if b > 0 && (a < math.MinInt32+b) { - panic(ErrOverflowInt32) + return 0, ErrOverflowInt32 } else if b < 0 && (a > math.MaxInt32+b) { - panic(ErrOverflowInt32) + return 0, ErrOverflowInt32 } - return a - b + return a - b, nil } -// SafeConvertInt32 takes a int and checks if it overflows -// If there is an overflow this will panic -func SafeConvertInt32(a int64) int32 { +// SafeConvertInt32 takes a int and checks if it overflows. +func SafeConvertInt32(a int64) (int32, error) { if a > math.MaxInt32 { - panic(ErrOverflowInt32) + return 0, ErrOverflowInt32 } else if a < math.MinInt32 { - panic(ErrOverflowInt32) + return 0, ErrOverflowInt32 } - return int32(a) + return int32(a), nil } -// SafeConvertUint8 takes an int64 and checks if it overflows -// If there is an overflow it returns an error +// SafeConvertUint8 takes an int64 and checks if it overflows. func SafeConvertUint8(a int64) (uint8, error) { if a > math.MaxUint8 { return 0, ErrOverflowUint8 @@ -53,8 +49,7 @@ func SafeConvertUint8(a int64) (uint8, error) { return uint8(a), nil } -// SafeConvertInt8 takes an int64 and checks if it overflows -// If there is an overflow it returns an error +// SafeConvertInt8 takes an int64 and checks if it overflows. func SafeConvertInt8(a int64) (int8, error) { if a > math.MaxInt8 { return 0, ErrOverflowInt8 From 2ffb26260053c87e4b44c0d00063494d771dcfec Mon Sep 17 00:00:00 2001 From: Sam Kleinman Date: Tue, 22 Feb 2022 15:04:16 -0500 Subject: [PATCH 3/3] context: cleaning up context dead ends (#7963) --- cmd/tendermint/commands/light.go | 3 +-- internal/rpc/core/events.go | 2 +- rpc/client/event_test.go | 2 +- rpc/client/helpers.go | 4 ++-- rpc/client/http/ws.go | 2 +- rpc/client/main_test.go | 4 ++-- rpc/client/rpc_test.go | 8 ++++---- test/e2e/node/main.go | 2 +- test/e2e/runner/benchmark.go | 5 ++--- 9 files changed, 15 insertions(+), 17 deletions(-) diff --git a/cmd/tendermint/commands/light.go b/cmd/tendermint/commands/light.go index 8ea9860a5..fbb6e00db 100644 --- a/cmd/tendermint/commands/light.go +++ b/cmd/tendermint/commands/light.go @@ -1,7 +1,6 @@ package commands import ( - "context" "errors" "fmt" "net/http" @@ -149,7 +148,7 @@ for applications built w/ Cosmos SDK). // Initiate the light client. If the trusted store already has blocks in it, this // will be used else we use the trusted options. c, err := light.NewHTTPClient( - context.Background(), + cmd.Context(), chainID, light.TrustOptions{ Period: trustingPeriod, diff --git a/internal/rpc/core/events.go b/internal/rpc/core/events.go index 054183817..045d20f4d 100644 --- a/internal/rpc/core/events.go +++ b/internal/rpc/core/events.go @@ -57,7 +57,7 @@ func (env *Environment) Subscribe(ctx context.Context, query string) (*coretypes // Capture the current ID, since it can change in the future. subscriptionID := callInfo.RPCRequest.ID go func() { - opctx, opcancel := context.WithCancel(context.Background()) + opctx, opcancel := context.WithCancel(context.TODO()) defer opcancel() for { diff --git a/rpc/client/event_test.go b/rpc/client/event_test.go index 19bb7b140..2e4b2242a 100644 --- a/rpc/client/event_test.go +++ b/rpc/client/event_test.go @@ -51,7 +51,7 @@ func testTxEventsSent(ctx context.Context, t *testing.T, broadcastMethod string, }() // and wait for confirmation - evt, err := client.WaitForOneEvent(c, types.EventTxValue, waitForEventTimeout) + evt, err := client.WaitForOneEvent(ctx, c, types.EventTxValue, waitForEventTimeout) require.NoError(t, err) // and make sure it has the proper info diff --git a/rpc/client/helpers.go b/rpc/client/helpers.go index b9ad05aac..f771d6156 100644 --- a/rpc/client/helpers.go +++ b/rpc/client/helpers.go @@ -57,9 +57,9 @@ func WaitForHeight(ctx context.Context, c StatusClient, h int64, waiter Waiter) // when the timeout duration has expired. // // This handles subscribing and unsubscribing under the hood -func WaitForOneEvent(c EventsClient, eventValue string, timeout time.Duration) (types.EventData, error) { +func WaitForOneEvent(ctx context.Context, c EventsClient, eventValue string, timeout time.Duration) (types.EventData, error) { const subscriber = "helpers" - ctx, cancel := context.WithTimeout(context.Background(), timeout) + ctx, cancel := context.WithTimeout(ctx, timeout) defer cancel() // register for the next event of this type diff --git a/rpc/client/http/ws.go b/rpc/client/http/ws.go index 43a70b74e..62a8ccf97 100644 --- a/rpc/client/http/ws.go +++ b/rpc/client/http/ws.go @@ -140,7 +140,7 @@ func (w *wsEvents) UnsubscribeAll(ctx context.Context, subscriber string) error func (w *wsEvents) redoSubscriptionsAfter(d time.Duration) { time.Sleep(d) - ctx := context.Background() + ctx := context.TODO() w.mtx.Lock() defer w.mtx.Unlock() diff --git a/rpc/client/main_test.go b/rpc/client/main_test.go index 9bd52174b..d799d8b85 100644 --- a/rpc/client/main_test.go +++ b/rpc/client/main_test.go @@ -15,10 +15,10 @@ import ( rpctest "github.com/tendermint/tendermint/rpc/test" ) -func NodeSuite(t *testing.T, logger log.Logger) (service.Service, *config.Config) { +func NodeSuite(ctx context.Context, t *testing.T, logger log.Logger) (service.Service, *config.Config) { t.Helper() - ctx, cancel := context.WithCancel(context.Background()) + ctx, cancel := context.WithCancel(ctx) conf, err := rpctest.CreateConfig(t, t.Name()) require.NoError(t, err) diff --git a/rpc/client/rpc_test.go b/rpc/client/rpc_test.go index fbdf257ed..14e689405 100644 --- a/rpc/client/rpc_test.go +++ b/rpc/client/rpc_test.go @@ -95,7 +95,7 @@ func TestClientOperations(t *testing.T) { logger := log.NewTestingLogger(t) - _, conf := NodeSuite(t, logger) + _, conf := NodeSuite(ctx, t, logger) t.Run("NilCustomHTTPClient", func(t *testing.T) { _, err := rpchttp.NewWithClient("http://example.com", nil) @@ -193,7 +193,7 @@ func TestClientMethodCalls(t *testing.T) { defer cancel() logger := log.NewTestingLogger(t) - n, conf := NodeSuite(t, logger) + n, conf := NodeSuite(ctx, t, logger) // for broadcast tx tests pool := getMempool(t, n) @@ -471,7 +471,7 @@ func TestClientMethodCalls(t *testing.T) { }) t.Run("Events", func(t *testing.T) { t.Run("Header", func(t *testing.T) { - evt, err := client.WaitForOneEvent(c, types.EventNewBlockHeaderValue, waitForEventTimeout) + evt, err := client.WaitForOneEvent(ctx, c, types.EventNewBlockHeaderValue, waitForEventTimeout) require.NoError(t, err, "%d: %+v", i, err) _, ok := evt.(types.EventDataNewBlockHeader) require.True(t, ok, "%d: %#v", i, evt) @@ -583,7 +583,7 @@ func TestClientMethodCallsAdvanced(t *testing.T) { logger := log.NewTestingLogger(t) - n, conf := NodeSuite(t, logger) + n, conf := NodeSuite(ctx, t, logger) pool := getMempool(t, n) t.Run("UnconfirmedTxs", func(t *testing.T) { diff --git a/test/e2e/node/main.go b/test/e2e/node/main.go index 5a60a20bd..704cc06bb 100644 --- a/test/e2e/node/main.go +++ b/test/e2e/node/main.go @@ -175,7 +175,7 @@ func startLightNode(ctx context.Context, cfg *Config) error { providers := rpcEndpoints(tmcfg.P2P.PersistentPeers) c, err := light.NewHTTPClient( - context.Background(), + ctx, cfg.ChainID, light.TrustOptions{ Period: tmcfg.StateSync.TrustPeriod, diff --git a/test/e2e/runner/benchmark.go b/test/e2e/runner/benchmark.go index 50a2c33f9..7c5e9009b 100644 --- a/test/e2e/runner/benchmark.go +++ b/test/e2e/runner/benchmark.go @@ -43,7 +43,7 @@ func Benchmark(ctx context.Context, testnet *e2e.Testnet, benchmarkLength int64) logger.Info("Ending benchmark period", "height", block.Height) // fetch a sample of blocks - blocks, err := fetchBlockChainSample(testnet, benchmarkLength) + blocks, err := fetchBlockChainSample(ctx, testnet, benchmarkLength) if err != nil { return err } @@ -128,7 +128,7 @@ func (t *testnetStats) String() string { // fetchBlockChainSample waits for `benchmarkLength` amount of blocks to pass, fetching // all of the headers for these blocks from an archive node and returning it. -func fetchBlockChainSample(testnet *e2e.Testnet, benchmarkLength int64) ([]*types.BlockMeta, error) { +func fetchBlockChainSample(ctx context.Context, testnet *e2e.Testnet, benchmarkLength int64) ([]*types.BlockMeta, error) { var blocks []*types.BlockMeta // Find the first archive node @@ -139,7 +139,6 @@ func fetchBlockChainSample(testnet *e2e.Testnet, benchmarkLength int64) ([]*type } // find the latest height - ctx := context.Background() s, err := c.Status(ctx) if err != nil { return nil, err