Skip to content

Commit

Permalink
Backport timeout_commit change
Browse files Browse the repository at this point in the history
  • Loading branch information
teddyding committed Oct 15, 2024
1 parent cfee87f commit 5b2e775
Show file tree
Hide file tree
Showing 8 changed files with 435 additions and 275 deletions.
455 changes: 256 additions & 199 deletions abci/types/types.pb.go

Large diffs are not rendered by default.

25 changes: 16 additions & 9 deletions consensus/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -718,15 +718,20 @@ func (cs *State) updateToState(state sm.State) {
cs.updateHeight(height)
cs.updateRoundStep(0, cstypes.RoundStepNewHeight)

timeoutCommit := state.NextBlockDelay
// If the ABCI app didn't set a delay, use the deprecated config value.
if timeoutCommit == 0 {
timeoutCommit = cs.config.TimeoutCommit //nolint:staticcheck
}
if cs.CommitTime.IsZero() {
// "Now" makes it easier to sync up dev nodes.
// We add timeoutCommit to allow transactions
// 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())
//
// We add timeoutCommit to allow transactions to be gathered for
// the first block. An alternative solution that relies on clocks:
// `cs.StartTime = state.LastBlockTime.Add(timeoutCommit)`
cs.StartTime = cmttime.Now().Add(timeoutCommit)
} else {
cs.StartTime = cs.config.Commit(cs.CommitTime)
cs.StartTime = cs.CommitTime.Add(timeoutCommit)
}

cs.Validators = validators
Expand Down Expand Up @@ -1042,7 +1047,7 @@ func (cs *State) handleTxsAvailable() {

// Enter: `timeoutNewHeight` by startTime (commitTime+timeoutCommit),
//
// or, if SkipTimeoutCommit==true, after receiving all precommits from (height,round-1)
// or, if NextBlockDelay==0, after receiving all precommits from (height,round-1)
//
// Enter: `timeoutPrecommits` after any +2/3 precommits from (height,round-1)
// Enter: +2/3 precommits for nil at (height,round-1)
Expand Down Expand Up @@ -2217,7 +2222,8 @@ func (cs *State) addVote(vote *types.Vote, peerID p2p.ID) (added bool, err error
cs.evsw.FireEvent(types.EventVote, vote)

// if we can skip timeoutCommit and have all the votes now,
if cs.config.SkipTimeoutCommit && cs.LastCommit.HasAll() {
skipTimeoutCommit := cs.state.NextBlockDelay == 0 && cs.config.TimeoutCommit == 0 //nolint:staticcheck
if skipTimeoutCommit && cs.LastCommit.HasAll() {
// go straight to new round (skip timeout commit)
// cs.scheduleTimeout(time.Duration(0), cs.Height, 0, cstypes.RoundStepNewHeight)
cs.enterNewRound(cs.Height, 0)
Expand Down Expand Up @@ -2375,7 +2381,8 @@ func (cs *State) addVote(vote *types.Vote, peerID p2p.ID) (added bool, err error

if !blockID.IsNil() {
cs.enterCommit(height, vote.Round)
if cs.config.SkipTimeoutCommit && precommits.HasAll() {
skipTimeoutCommit := cs.state.NextBlockDelay == 0 && cs.config.TimeoutCommit == 0 //nolint:staticcheck
if skipTimeoutCommit && precommits.HasAll() {
cs.enterNewRound(cs.Height, 0)
}
} else {
Expand Down
7 changes: 7 additions & 0 deletions proto/tendermint/abci/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import "tendermint/types/params.proto";
import "tendermint/types/validator.proto";
import "google/protobuf/timestamp.proto";
import "gogoproto/gogo.proto";
import "google/protobuf/duration.proto";

// NOTE: When using custom types, mind the warnings.
// https://github.com/cosmos/gogoproto/blob/master/custom_types.md#warnings-and-issues
Expand Down Expand Up @@ -363,6 +364,12 @@ message ResponseFinalizeBlock {
tendermint.types.ConsensusParams consensus_param_updates = 4;
// app_hash is the hash of the applications' state which is used to confirm that execution of the transactions was deterministic. It is up to the application to decide which algorithm to use.
bytes app_hash = 5;
// delay between the time when this block is committed and the next height is started.
// previously `timeout_commit` in config.toml
google.protobuf.Duration next_block_delay = 6 [
(gogoproto.nullable) = false,
(gogoproto.stdduration) = true
];
}

//----------------------------------------
Expand Down
190 changes: 123 additions & 67 deletions proto/tendermint/state/types.pb.go

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions proto/tendermint/state/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import "tendermint/types/validator.proto";
import "tendermint/types/params.proto";
import "tendermint/version/types.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/duration.proto";

// LegacyABCIResponses retains the responses
// of the legacy ABCI calls during block processing.
Expand Down Expand Up @@ -93,4 +94,11 @@ message State {

// the latest AppHash we've received from calling abci.Commit()
bytes app_hash = 13;

// delay between the time when this block is committed and the next height is started.
// previously `timeout_commit` in config.toml
google.protobuf.Duration next_block_delay = 15 [
(gogoproto.nullable) = false,
(gogoproto.stdduration) = true
];
}
14 changes: 14 additions & 0 deletions state/execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package state
import (
"bytes"
"context"
"errors"
"fmt"
"time"

Expand Down Expand Up @@ -282,6 +283,11 @@ func (blockExec *BlockExecutor) ApplyBlock(
blockExec.metrics.ConsensusParamUpdates.Add(1)
}

err = validateNextBlockDelay(abciResponse.NextBlockDelay)
if err != nil {
return state, fmt.Errorf("error in next block delay: %w", err)
}

// Update the state with the block and responses.
state, err = updateState(state, blockID, &block.Header, abciResponse, validatorUpdates)
if err != nil {
Expand Down Expand Up @@ -581,6 +587,13 @@ func validateValidatorUpdates(abciUpdates []abci.ValidatorUpdate,
return nil
}

func validateNextBlockDelay(nextBlockDelay time.Duration) error {
if nextBlockDelay < 0 {
return errors.New("negative duration")
}
return nil
}

// updateState returns a new State updated according to the header and responses.
func updateState(
state State,
Expand Down Expand Up @@ -649,6 +662,7 @@ func updateState(
LastHeightConsensusParamsChanged: lastHeightParamsChanged,
LastResultsHash: TxResultsHash(abciResponse.TxResults),
AppHash: nil,
NextBlockDelay: abciResponse.NextBlockDelay,
}, nil
}

Expand Down
10 changes: 10 additions & 0 deletions state/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ type State struct {

// the latest AppHash we've received from calling abci.Commit()
AppHash []byte

// delay between the time when this block is committed and the next height is started.
// previously `timeout_commit` in config.toml
NextBlockDelay time.Duration
}

// Copy makes a copy of the State for mutating.
Expand All @@ -102,6 +106,8 @@ func (state State) Copy() State {
AppHash: state.AppHash,

LastResultsHash: state.LastResultsHash,

NextBlockDelay: state.NextBlockDelay,
}
}

Expand Down Expand Up @@ -170,6 +176,7 @@ func (state *State) ToProto() (*cmtstate.State, error) {
sm.LastHeightConsensusParamsChanged = state.LastHeightConsensusParamsChanged
sm.LastResultsHash = state.LastResultsHash
sm.AppHash = state.AppHash
sm.NextBlockDelay = state.NextBlockDelay

return sm, nil
}
Expand Down Expand Up @@ -221,6 +228,7 @@ func FromProto(pb *cmtstate.State) (*State, error) { //nolint:golint
state.LastHeightConsensusParamsChanged = pb.LastHeightConsensusParamsChanged
state.LastResultsHash = pb.LastResultsHash
state.AppHash = pb.AppHash
state.NextBlockDelay = pb.NextBlockDelay

return state, nil
}
Expand Down Expand Up @@ -351,5 +359,7 @@ func MakeGenesisState(genDoc *types.GenesisDoc) (State, error) {
LastHeightConsensusParamsChanged: genDoc.InitialHeight,

AppHash: genDoc.AppHash,
// NextBlockDelay is set to 0 because the genesis block is committed.
NextBlockDelay: 0,
}, nil
}
1 change: 1 addition & 0 deletions test/e2e/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ func (app *Application) FinalizeBlock(_ context.Context, req *abci.RequestFinali
},
},
},
NextBlockDelay: 1 * time.Second,
}, nil
}

Expand Down

0 comments on commit 5b2e775

Please sign in to comment.