Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: retrieves timeout propose and timeout commit dynamically per height according to the app version #1494

Merged
merged 91 commits into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from 81 commits
Commits
Show all changes
91 commits
Select commit Hold shift + click to select a range
f231895
extends ResponseEndBlock protobuf message with timeouts
staheri14 Sep 18, 2024
41a2cb0
reads the timeouts and attempts to set them
staheri14 Sep 18, 2024
1fc1edf
extends state struct with timeout fields
staheri14 Sep 18, 2024
597f667
updates timeouts based on EndBlockResponse
staheri14 Sep 18, 2024
2397315
updates consensus configs based on ApplyBlock's results
staheri14 Sep 18, 2024
03fb213
changes the type of timeout fields in protobuf to uint64
staheri14 Sep 18, 2024
a104580
uses time.Duration for protobuf fields
staheri14 Sep 19, 2024
30bc1c0
adds timeout fields to RequestInfo
staheri14 Sep 19, 2024
7b3618b
consolidates timeouts inside one protobuf message type
staheri14 Sep 20, 2024
fa27abe
moves tiemouts to the response msg
staheri14 Sep 20, 2024
6e2fb78
adds timemouts to InitchainRespo se
staheri14 Sep 24, 2024
a7d1e1b
corrects some of the docs
staheri14 Sep 24, 2024
0904cd5
remnants of adding timeouts to the InitchainResponse
staheri14 Sep 24, 2024
0271370
disambiguates a comment
staheri14 Sep 24, 2024
47329db
minor edits
staheri14 Sep 24, 2024
8ef6666
adds some todos
staheri14 Sep 24, 2024
6a92b18
fixes godocs
staheri14 Sep 25, 2024
782efa1
adds timeouts to the State protobuf message to be saved in the statedb
staheri14 Sep 25, 2024
26dfedf
fixes godocs
staheri14 Sep 25, 2024
020efac
Merge remote-tracking branch 'origin/v0.34.x-celestia' into sanaz/add…
staheri14 Sep 25, 2024
490189c
makes timeouts field not nullable
staheri14 Sep 25, 2024
852d07f
exposes Timeout fields of the State
staheri14 Sep 25, 2024
f1568a6
copies over timeout values when converting from proto to local state …
staheri14 Sep 25, 2024
00d8e1c
tests copying timeouts
staheri14 Sep 25, 2024
3b6cbb3
extends TestStateSaveLoad to account for timeout equality
staheri14 Sep 25, 2024
98feed8
adds a clarifying comment
staheri14 Sep 25, 2024
9ecf2d1
integrates timeouts in TestABCIResponsesSaveLoad1
staheri14 Sep 25, 2024
063fafd
sets non-zero timeouts for the TestStateProto
staheri14 Sep 25, 2024
bbfbd59
creates a new testcase for state with non-zero tiemouts
staheri14 Sep 25, 2024
77e31ca
sets the initial state's timeouts using InitChainResponse timeouts
staheri14 Sep 25, 2024
b8b7b5a
improves docs
staheri14 Sep 26, 2024
d48a120
adds a todo about setting timeouts in stateSync
staheri14 Sep 27, 2024
6d53ec3
saves timeouts separately in the store
staheri14 Oct 2, 2024
4d79406
fixes a godoc
staheri14 Oct 2, 2024
eddd24b
adds a todo
staheri14 Oct 2, 2024
647cd29
logs timeout propose and timeout commit
staheri14 Oct 2, 2024
ca5cbf6
logs timeouts in second unit
staheri14 Oct 2, 2024
bf59cd5
checks if config is not nil
staheri14 Oct 2, 2024
585d682
removes the logs
staheri14 Oct 2, 2024
bd49c4c
extends store interface with LoadConsensusTimeoutsInfo
staheri14 Oct 3, 2024
2c24116
adds two new methods for calculation of timeouts
staheri14 Oct 3, 2024
61ea40b
utilizes new methods for commit time and timeout propose
staheri14 Oct 3, 2024
5dca0dc
adds logs
staheri14 Oct 3, 2024
bebd8d5
Merge remote-tracking branch 'origin/v0.34.x-celestia' into sanaz/add…
staheri14 Oct 3, 2024
4831733
updates protobufs
staheri14 Oct 3, 2024
cfdd2c3
adds further logs for monitoring timeout changes during consensus ope…
staheri14 Oct 4, 2024
e3ae19c
logs timeouts when calculated
staheri14 Oct 4, 2024
1e08820
removes some of logs
staheri14 Oct 4, 2024
f8eaf2d
removes some logs
staheri14 Oct 4, 2024
eff0bb2
minor fix and godoc update
staheri14 Oct 4, 2024
9865ebe
logs the state and the header's app version after each ApplyBlock
staheri14 Oct 4, 2024
6f88a30
adds an rpc route for timeout info
staheri14 Oct 7, 2024
3f8320f
implements ConsensusTimeoutsInfo for baseRPCClient
staheri14 Oct 7, 2024
d6ecfd4
adds some missing parts
staheri14 Oct 7, 2024
d8815a3
adds a test for the retrieval of timeout info per height
staheri14 Oct 7, 2024
377751e
fixes a comment
staheri14 Oct 7, 2024
598e9be
revises the test to retrieve states after all are saved
staheri14 Oct 8, 2024
a34d103
fixes a typo
staheri14 Oct 8, 2024
f06eae6
covers a tricky corner case for the genesis state
staheri14 Oct 8, 2024
3347fe7
does not amend configs in updatoToState
staheri14 Oct 8, 2024
fbe4f62
formats some lines
staheri14 Oct 8, 2024
86bd130
implements ConsensusTimeoutsInfo for the local client
staheri14 Oct 9, 2024
8fe698f
converts height ptr to int64
staheri14 Oct 9, 2024
5785b37
converts height ptr to int64
staheri14 Oct 9, 2024
f7cda78
Merge branch 'sanaz/adds-timeouts-to-endblock-abci' of github.com:cel…
staheri14 Oct 9, 2024
66f3f21
implements ConsensusTimeoutsInfo for the mock client
staheri14 Oct 9, 2024
0ebf51c
fixes redundant imports
staheri14 Oct 9, 2024
ee9bda2
implements a missing method for the mock store
staheri14 Oct 9, 2024
9f11257
falls back to the configs timeouts if none is available in the state
staheri14 Oct 10, 2024
aabf2c6
clarifies why a test case is valid under the new implementation
staheri14 Oct 10, 2024
5e7abef
adds further clarifying comments about the tests that use the timeout…
staheri14 Oct 10, 2024
98e3e13
comments on the new methods for Commit and Propose time calculation
staheri14 Oct 10, 2024
fc2fc76
deletes fmt statements
staheri14 Oct 10, 2024
30a663f
deletes a todo
staheri14 Oct 10, 2024
d7e21f4
replaces Propose calls with ProposeWithCustomTimeout
staheri14 Oct 11, 2024
d872374
uses last state timeout for the tests
staheri14 Oct 11, 2024
1776442
removes some unused comments
staheri14 Oct 11, 2024
6211697
implements ConsensusTimeoutsInfo for the light client
staheri14 Oct 11, 2024
122058b
fixes some formatting inconsistencies
staheri14 Oct 11, 2024
f74d19b
cleans up the code
staheri14 Oct 11, 2024
0fd7f5e
clarifies a comment
staheri14 Oct 11, 2024
10be8b1
sets the inital value of timeouts to the custom timeout
staheri14 Oct 11, 2024
363058a
adds unttest for ProposeWithCustomTimeout and CommitWithCustomTimeout
staheri14 Oct 11, 2024
85e92f3
clarifies what default means
staheri14 Oct 11, 2024
5d399b5
chore: comment feedback @rootulp
evan-forbes Oct 14, 2024
081ecce
chore: review feedback
evan-forbes Oct 14, 2024
f12da04
chore: remove rpc and timeouts from the state store
evan-forbes Oct 14, 2024
12639d4
fix: use the timeouts passed from info
evan-forbes Oct 14, 2024
e772715
Merge branch 'sanaz/adds-timeouts-to-endblock-abci' of github.com:cel…
evan-forbes Oct 14, 2024
1ef98d0
chore: linter
evan-forbes Oct 14, 2024
23e3fb1
chore: remaining two comments
evan-forbes Oct 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
920 changes: 653 additions & 267 deletions abci/types/types.pb.go

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions blockchain/v0/reactor.go
Original file line number Diff line number Diff line change
Expand Up @@ -410,8 +410,7 @@ FOR_LOOP:
// TODO: batch saves so we dont persist to disk every block
bcR.store.SaveBlock(first, firstParts, second.LastCommit)

// TODO: same thing for app - but we would need a way to
// get the hash without persisting the state
// TODO: same thing for app - but we would need a way to get the hash without persisting the state
state, _, err = bcR.blockExec.ApplyBlock(state, firstID, first, second.LastCommit)
if err != nil {
// TODO This is bad, are we zombie?
Expand Down
42 changes: 36 additions & 6 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,14 +167,14 @@ type BaseConfig struct { //nolint: maligned
chainID string

// The root directory for all data.
// This should be set in viper so it can unmarshal into this struct
// This should be set in viper so that it can unmarshal into this struct
RootDir string `mapstructure:"home"`

// TCP or UNIX socket address of the ABCI application,
// or the name of an ABCI application compiled in with the CometBFT binary
ProxyApp string `mapstructure:"proxy_app"`

// A custom human readable name for this node
// A custom human-readable name for this node
Moniker string `mapstructure:"moniker"`

// If this node is many blocks behind the tip of the chain, FastSync
Expand Down Expand Up @@ -212,7 +212,7 @@ type BaseConfig struct { //nolint: maligned
// Output format: 'plain' (colored text) or 'json'
LogFormat string `mapstructure:"log_format"`

// Path to the JSON file containing the initial validator set and other meta data
// Path to the JSON file containing the initial validator set and other metadata
Genesis string `mapstructure:"genesis_file"`

// Path to the JSON file containing the private key to use as a validator in the consensus protocol
Expand Down Expand Up @@ -279,7 +279,7 @@ func (cfg BaseConfig) PrivValidatorKeyFile() string {
return rootify(cfg.PrivValidatorKey, cfg.RootDir)
}

// PrivValidatorFile returns the full path to the priv_validator_state.json file
// PrivValidatorStateFile returns the full path to the priv_validator_state.json file
func (cfg BaseConfig) PrivValidatorStateFile() string {
return rootify(cfg.PrivValidatorState, cfg.RootDir)
}
Expand Down Expand Up @@ -871,7 +871,7 @@ func DefaultStateSyncConfig() *StateSyncConfig {
}
}

// TestFastSyncConfig returns a default configuration for the state sync service
// TestStateSyncConfig returns a default configuration for the state sync service
func TestStateSyncConfig() *StateSyncConfig {
return DefaultStateSyncConfig()
}
Expand Down Expand Up @@ -1055,6 +1055,20 @@ func (cfg *ConsensusConfig) Propose(round int32) time.Duration {
) * time.Nanosecond
}

// ProposeWithCustomTimeout is identical to Propose. However,
// it calculates the amount of time to wait for a proposal using the supplied
// customTimeout.
// If customTimeout is 0, the default TimeoutCommit is used.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit] the comment wrapping here is weird. If you use VScode, you can use rewrap to format this better.

https://marketplace.visualstudio.com/items?itemName=stkb.rewrap

Suggested change
// ProposeWithCustomTimeout is identical to Propose. However,
// it calculates the amount of time to wait for a proposal using the supplied
// customTimeout.
// If customTimeout is 0, the default TimeoutCommit is used.
// ProposeWithCustomTimeout is identical to Propose. However, it calculates the
// amount of time to wait for a proposal using the supplied customTimeout. If
// customTimeout is 0, the default TimeoutCommit is used.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ahh shoot missed this one

I agree with these comment wrappers, which it was part of the linting rules

func (cfg *ConsensusConfig) ProposeWithCustomTimeout(round int32, customTimeout time.Duration) time.Duration {
// this is to capture any unforeseen cases where the customTimeout is 0
var timeoutPropose time.Duration
if customTimeout == 0 {
// falling back to default timeout
timeoutPropose = cfg.TimeoutPropose
}
return time.Duration(timeoutPropose.Nanoseconds()+cfg.TimeoutProposeDelta.Nanoseconds()*int64(round)) * time.Nanosecond
staheri14 marked this conversation as resolved.
Show resolved Hide resolved
}
staheri14 marked this conversation as resolved.
Show resolved Hide resolved

// Prevote returns the amount of time to wait for straggler votes after receiving any +2/3 prevotes
func (cfg *ConsensusConfig) Prevote(round int32) time.Duration {
return time.Duration(
Expand All @@ -1070,11 +1084,23 @@ func (cfg *ConsensusConfig) Precommit(round int32) time.Duration {
}

// Commit returns the amount of time to wait for straggler votes after receiving +2/3 precommits
// for a single block (ie. a commit).
// for a single block (i.e., a commit).
func (cfg *ConsensusConfig) Commit(t time.Time) time.Time {
return t.Add(cfg.TimeoutCommit)
}

// CommitWithCustomTimeout is identical to Commit. However, it calculates the time for commit using the supplied customTimeout.
// If customTimeout is 0, the default TimeoutCommit is used.
staheri14 marked this conversation as resolved.
Show resolved Hide resolved
func (cfg *ConsensusConfig) CommitWithCustomTimeout(t time.Time, customTimeout time.Duration) time.Time {
// this is to capture any unforeseen cases where the customTimeout is 0
var timeoutCommit time.Duration
if customTimeout == 0 {
// falling back to default timeout
timeoutCommit = cfg.TimeoutCommit
}
return t.Add(timeoutCommit)
}
staheri14 marked this conversation as resolved.
Show resolved Hide resolved

// WalFile returns the full path to the write-ahead log file
func (cfg *ConsensusConfig) WalFile() string {
if cfg.walFile != "" {
Expand All @@ -1091,6 +1117,8 @@ func (cfg *ConsensusConfig) SetWalFile(walFile string) {
// ValidateBasic performs basic validation (checking param bounds, etc.) and
// returns an error if any check fails.
func (cfg *ConsensusConfig) ValidateBasic() error {
// TODO we may want to remove this check if TimeoutPropose is removed from
// the config
staheri14 marked this conversation as resolved.
Show resolved Hide resolved
if cfg.TimeoutPropose < 0 {
return errors.New("timeout_propose can't be negative")
}
Expand All @@ -1109,6 +1137,8 @@ func (cfg *ConsensusConfig) ValidateBasic() error {
if cfg.TimeoutPrecommitDelta < 0 {
return errors.New("timeout_precommit_delta can't be negative")
}
// TODO we may want to remove this check if TimeoutCommit is removed from
// the config
staheri14 marked this conversation as resolved.
Show resolved Hide resolved
if cfg.TimeoutCommit < 0 {
return errors.New("timeout_commit can't be negative")
}
Expand Down
8 changes: 6 additions & 2 deletions consensus/mempool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func TestMempoolProgressInHigherRound(t *testing.T) {
timeoutCh := subscribe(cs.eventBus, types.EventQueryTimeoutPropose)
cs.setProposal = func(proposal *types.Proposal) error {
if cs.Height == 2 && cs.Round == 0 {
// dont set the proposal in round 0 so we timeout and
// don't set the proposal in round 0 so we timeout and
// go to next round
cs.Logger.Info("Ignoring set proposal at height 2, round 0")
return nil
Expand All @@ -91,7 +91,11 @@ func TestMempoolProgressInHigherRound(t *testing.T) {
round = 0

ensureNewRound(newRoundCh, height, round) // first round at next height
deliverTxsRange(cs, 0, 1) // we deliver txs, but dont set a proposal so we get the next round
deliverTxsRange(cs, 0, 1) // we deliver txs, but don't set a proposal so we get the next round
// The use of cs.config.TimeoutPropose.Nanoseconds() as the timeout propose is acceptable in this test case, the following line.
// Even though timeouts are version-dependent, cs is created with an empty previous state in this scenario.
// As there's no timeout propose in the previous state, we default to the timeout propose in the config.
// This makes the test case valid.
ensureNewTimeout(timeoutCh, height, round, cs.config.TimeoutPropose.Nanoseconds())

round++ // moving to the next round
Expand Down
9 changes: 7 additions & 2 deletions consensus/replay.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,8 @@ LOOP:
}

// NOTE: since the priv key is set when the msgs are received
// it will attempt to eg double sign but we can just ignore it
// since the votes will be replayed and we'll get to the next step
// it will attempt to e.g., double sign, but we can just ignore it
// since the votes will be replayed, and we'll get to the next step
if err := cs.readReplayMessage(msg, nil); err != nil {
return err
}
Expand Down Expand Up @@ -362,6 +362,11 @@ func (h *Handshaker) ReplayBlocksWithContext(
state.ConsensusParams = types.UpdateConsensusParams(state.ConsensusParams, res.ConsensusParams)
state.Version.Consensus.App = state.ConsensusParams.Version.AppVersion
}

// update timeouts based on the InitChainSync response
state.TimeoutCommit = res.Timeouts.TimeoutCommit
state.TimeoutPropose = res.Timeouts.TimeoutPropose

evan-forbes marked this conversation as resolved.
Show resolved Hide resolved
// We update the last results hash with the empty hash, to conform with RFC-6962.
state.LastResultsHash = merkle.HashFromByteSlices(nil)
if err := h.stateStore.Save(state); err != nil {
Expand Down
4 changes: 2 additions & 2 deletions consensus/replay_file.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const (
//--------------------------------------------------------
// replay messages interactively or all at once

// replay the wal file
// RunReplayFile replays the wal file
func RunReplayFile(config cfg.BaseConfig, csConfig *cfg.ConsensusConfig, console bool) {
consensusState := newConsensusStateForReplay(config, csConfig)

Expand All @@ -38,7 +38,7 @@ func RunReplayFile(config cfg.BaseConfig, csConfig *cfg.ConsensusConfig, console
}
}

// Replay msgs in file or start the console
// ReplayFile replays msgs in file or start the console
func (cs *State) ReplayFile(file string, console bool) error {

if cs.IsRunning() {
Expand Down
31 changes: 25 additions & 6 deletions consensus/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -674,9 +674,28 @@ func (cs *State) updateToState(state sm.State) {
// to be gathered for the first block.
// And alternative solution that relies on clocks:
// cs.StartTime = state.LastBlockTime.Add(timeoutCommit)
cs.StartTime = cs.config.Commit(cmttime.Now())

if state.LastBlockHeight == 0 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't CommitTime.IsZero() only for the first block i.e. when state.LastBlockHeight == 0. Can you find a case where this is not true?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was just to be extra sure, didn't see any harm to add an extra check here. If you think it is excessive, I can remove it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want to keep this can you compact this into a simpler IsGenesis method and then just have a single if statement to set cs.StartTime

// state represents the genesis state, hence the StartTime should be set based on the state's TimeoutCommit
// we don't use cs.state.TimeoutCommit because that is zero
cs.StartTime = cs.config.CommitWithCustomTimeout(cmttime.Now(), state.TimeoutCommit)
} else {
// if state does not represent the genesis state,
// we use the cs.state.TimeoutCommit
cs.StartTime = cs.config.CommitWithCustomTimeout(cmttime.Now(), cs.state.TimeoutCommit)
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit] instead of code comments that distract from the functionality, we can move the comments into code. For example

Suggested change
// state represents the genesis state, hence the StartTime should be set based on the state's TimeoutCommit
// we don't use cs.state.TimeoutCommit because that is zero
cs.StartTime = cs.config.CommitWithCustomTimeout(cmttime.Now(), state.TimeoutCommit)
} else {
// if state does not represent the genesis state,
// we use the cs.state.TimeoutCommit
cs.StartTime = cs.config.CommitWithCustomTimeout(cmttime.Now(), cs.state.TimeoutCommit)
}
if state.IsGenesis() {
// Don't use cs.state.TimeoutCommit because that is zero
cs.StartTime = cs.config.CommitWithCustomTimeout(cmttime.Now(), state.TimeoutCommit)
} else {
cs.StartTime = cs.config.CommitWithCustomTimeout(cmttime.Now(), cs.state.TimeoutCommit)
}

with the addition of

func (state State) IsGenesis() bool {
	return state.LastBlockHeight == 0
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment wasn't addressed.


} else {
cs.StartTime = cs.config.Commit(cs.CommitTime)
if state.LastBlockHeight == 0 {
// state represents the genesis state, hence the StartTime should be set based on the state's TimeoutCommit
// we don't use cs.state.TimeoutCommit because that is zero
cs.StartTime = cs.config.CommitWithCustomTimeout(cs.CommitTime, state.TimeoutCommit)
} else {
// if state does not represent the genesis state,
// we use the cs.state.TimeoutCommit
cs.StartTime = cs.config.CommitWithCustomTimeout(cs.CommitTime, cs.state.TimeoutCommit)
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit] same potential refactor as above


}

cs.Validators = validators
Expand Down Expand Up @@ -1113,7 +1132,7 @@ func (cs *State) enterPropose(height int64, round int32) {
}()

// If we don't get the proposal and all block parts quick enough, enterPrevote
cs.scheduleTimeout(cs.config.Propose(round), height, round, cstypes.RoundStepPropose)
cs.scheduleTimeout(cs.config.ProposeWithCustomTimeout(round, cs.state.TimeoutPropose), height, round, cstypes.RoundStepPropose)

// Nothing more to do if we're not a validator
if cs.privValidator == nil {
Expand Down Expand Up @@ -1682,7 +1701,7 @@ func (cs *State) finalizeCommit(height int64) {
// exists.
//
// Either way, the State should not be resumed until we
// successfully call ApplyBlock (ie. later here, or in Handshake after
// successfully call ApplyBlock (i.e., later here, or in Handshake after
// restart).
endMsg := EndHeightMessage{height}
if err := cs.wal.WriteSync(endMsg); err != nil { // NOTE: fsync
Expand All @@ -1698,7 +1717,7 @@ func (cs *State) finalizeCommit(height int64) {
stateCopy := cs.state.Copy()

// Execute and commit the block, update and save the state, and update the mempool.
// NOTE The block.AppHash wont reflect these txs until the next block.
// NOTE The block.AppHash won't reflect these txs until the next block.
var (
err error
retainHeight int64
Expand Down Expand Up @@ -1741,7 +1760,7 @@ func (cs *State) finalizeCommit(height int64) {

fail.Fail() // XXX

// Private validator might have changed it's key pair => refetch pubkey.
// Private validator might have changed its key pair => refetch pubkey.
if err := cs.updatePrivValidatorPubKey(); err != nil {
logger.Error("failed to get private validator pubkey", "err", err)
}
Expand Down
24 changes: 16 additions & 8 deletions consensus/state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ func TestStateEnterProposeNoPrivValidator(t *testing.T) {
startTestRound(cs, height, round)

// if we're not a validator, EnterPropose should timeout
// The use of cs.config.TimeoutPropose.Nanoseconds() as the timeout propose is acceptable in this test case.
// Even though timeouts are version-dependent, cs is created with an empty previous state in this scenario.
// As there's no timeout propose in the previous state, we default to the timeout propose in the config.
// This makes the test case valid.
ensureNewTimeout(timeoutCh, height, round, cs.config.TimeoutPropose.Nanoseconds())

if cs.GetRoundState().Proposal != nil {
Expand Down Expand Up @@ -179,6 +183,10 @@ func TestStateEnterProposeYesPrivValidator(t *testing.T) {
}

// if we're a validator, enterPropose should not timeout
// The use of cs.config.TimeoutPropose.Nanoseconds() as the timeout propose is acceptable in this test case.
// Even though timeouts are version-dependent, cs is created with an empty previous state in this scenario.
// As there's no timeout propose in the previous state, we default to the timeout propose in the config.
// This makes the test case valid.
ensureNoNewTimeout(timeoutCh, cs.config.TimeoutPropose.Nanoseconds())
}

Expand Down Expand Up @@ -310,7 +318,7 @@ func TestStateOversizedBlock(t *testing.T) {
lockedRound = -1
// if the block is oversized cs1 should log an error with the block part message as it exceeds
// the consensus params. The block is not added to cs.ProposalBlock so the node timeouts.
ensureNewTimeout(timeoutProposeCh, height, round, cs1.config.Propose(round).Nanoseconds())
ensureNewTimeout(timeoutProposeCh, height, round, cs1.config.ProposeWithCustomTimeout(round, cs1.state.TimeoutPropose).Nanoseconds())
// and then should send nil prevote and precommit regardless of whether other validators prevote and
// precommit on it
}
Expand Down Expand Up @@ -497,7 +505,7 @@ func TestStateLockNoPOL(t *testing.T) {
incrementRound(vs2)

// now we're on a new round and not the proposer, so wait for timeout
ensureNewTimeout(timeoutProposeCh, height, round, cs1.config.Propose(round).Nanoseconds())
ensureNewTimeout(timeoutProposeCh, height, round, cs1.config.ProposeWithCustomTimeout(round, cs1.state.TimeoutPropose).Nanoseconds())

rs := cs1.GetRoundState()

Expand Down Expand Up @@ -1029,7 +1037,7 @@ func TestStateLockPOLSafety1(t *testing.T) {
*/

// timeout of propose
ensureNewTimeout(timeoutProposeCh, height, round, cs1.config.Propose(round).Nanoseconds())
ensureNewTimeout(timeoutProposeCh, height, round, cs1.config.ProposeWithCustomTimeout(round, cs1.state.TimeoutPropose).Nanoseconds())

// finish prevote
ensurePrevote(voteCh, height, round)
Expand Down Expand Up @@ -1199,7 +1207,7 @@ func TestProposeValidBlock(t *testing.T) {
t.Log("### ONTO ROUND 2")

// timeout of propose
ensureNewTimeout(timeoutProposeCh, height, round, cs1.config.Propose(round).Nanoseconds())
ensureNewTimeout(timeoutProposeCh, height, round, cs1.config.ProposeWithCustomTimeout(round, cs1.state.TimeoutPropose).Nanoseconds())

ensurePrevote(voteCh, height, round)
validatePrevote(t, cs1, round, vss[0], propBlockHash)
Expand Down Expand Up @@ -1326,7 +1334,7 @@ func TestSetValidBlockOnDelayedProposal(t *testing.T) {
startTestRound(cs1, cs1.Height, round)
ensureNewRound(newRoundCh, height, round)

ensureNewTimeout(timeoutProposeCh, height, round, cs1.config.Propose(round).Nanoseconds())
ensureNewTimeout(timeoutProposeCh, height, round, cs1.config.ProposeWithCustomTimeout(round, cs1.state.TimeoutPropose).Nanoseconds())

ensurePrevote(voteCh, height, round)
validatePrevote(t, cs1, round, vss[0], nil)
Expand Down Expand Up @@ -1407,7 +1415,7 @@ func TestWaitingTimeoutProposeOnNewRound(t *testing.T) {
rs := cs1.GetRoundState()
assert.True(t, rs.Step == cstypes.RoundStepPropose) // P0 does not prevote before timeoutPropose expires

ensureNewTimeout(timeoutWaitCh, height, round, cs1.config.Propose(round).Nanoseconds())
ensureNewTimeout(timeoutWaitCh, height, round, cs1.config.ProposeWithCustomTimeout(round, cs1.state.TimeoutPropose).Nanoseconds())

ensurePrevote(voteCh, height, round)
validatePrevote(t, cs1, round, vss[0], nil)
Expand Down Expand Up @@ -1471,7 +1479,7 @@ func TestWaitTimeoutProposeOnNilPolkaForTheCurrentRound(t *testing.T) {
incrementRound(vss[1:]...)
signAddVotes(cs1, cmtproto.PrevoteType, nil, types.PartSetHeader{}, vs2, vs3, vs4)

ensureNewTimeout(timeoutProposeCh, height, round, cs1.config.Propose(round).Nanoseconds())
ensureNewTimeout(timeoutProposeCh, height, round, cs1.config.ProposeWithCustomTimeout(round, cs1.state.TimeoutPropose).Nanoseconds())

ensurePrevote(voteCh, height, round)
validatePrevote(t, cs1, round, vss[0], nil)
Expand Down Expand Up @@ -1619,7 +1627,7 @@ func TestStartNextHeightCorrectlyAfterTimeout(t *testing.T) {

cs1.txNotifier.(*fakeTxNotifier).Notify()

ensureNewTimeout(timeoutProposeCh, height+1, round, cs1.config.Propose(round).Nanoseconds())
ensureNewTimeout(timeoutProposeCh, height+1, round, cs1.config.ProposeWithCustomTimeout(round, cs1.state.TimeoutPropose).Nanoseconds())
rs = cs1.GetRoundState()
assert.False(
t,
Expand Down
4 changes: 4 additions & 0 deletions light/rpc/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,10 @@ func (c *Client) ConsensusParams(ctx context.Context, height *int64) (*ctypes.Re
return res, nil
}

func (c *Client) ConsensusTimeoutsInfo(ctx context.Context, height int64) (*abci.TimeoutsInfo, error) {
return c.next.ConsensusTimeoutsInfo(ctx, height)
}

func (c *Client) Health(ctx context.Context) (*ctypes.ResultHealth, error) {
return c.next.Health(ctx)
}
Expand Down
Loading
Loading