Skip to content

Commit d0afa34

Browse files
melekessergio-mena
authored andcommitted
feat(abci): move timeout_commit into FinalizeBlockResponse (cometbft#3089)
as `next_block_delay` ADR-115: cometbft#2966 Closes cometbft#2655 --- - [ ] ~~Tests written/updated~~ - [x] Changelog entry added in `.changelog` (we use [unclog](https://github.com/informalsystems/unclog) to manage our changelog) - [x] Updated relevant documentation (`docs/` or `spec/`) and code comments - [x] Title follows the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) spec --------- Co-authored-by: Sergio Mena <[email protected]>
1 parent c8beeea commit d0afa34

File tree

18 files changed

+224
-53
lines changed

18 files changed

+224
-53
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- `[config]` Move `timeout_commit` into the ABCI `FinalizeBlockResponse`
2+
([\#2655](https://github.com/cometbft/cometbft/issues/2655))

abci/types/application.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package types
22

3-
import "context"
3+
import (
4+
"context"
5+
)
46

57
//go:generate ../../scripts/mockery_generate.sh Application
68

abci/types/types.pb.go

Lines changed: 54 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

buf.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
version: v1
12
build:
23
roots:
34
- proto

config/config.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,9 +158,12 @@ func (cfg *Config) ValidateBasic() error {
158158
return nil
159159
}
160160

161-
// CheckDeprecated returns any deprecation warnings. These are printed to the operator on startup
161+
// CheckDeprecated returns any deprecation warnings. These are printed to the operator on startup.
162162
func (cfg *Config) CheckDeprecated() []string {
163163
var warnings []string
164+
if cfg.Consensus.TimeoutCommit != 0 {
165+
warnings = append(warnings, "[consensus.timeout_commit] is deprecated. Use `next_block_delay` in the ABCI `FinalizeBlockResponse`.")
166+
}
164167
return warnings
165168
}
166169

@@ -996,6 +999,7 @@ type ConsensusConfig struct {
996999
// height (this gives us a chance to receive some more precommits, even
9971000
// though we already have +2/3).
9981001
// NOTE: when modifying, make sure to update time_iota_ms genesis parameter
1002+
// Deprecated: use `next_block_delay` in the ABCI application's `FinalizeBlockResponse`.
9991003
TimeoutCommit time.Duration `mapstructure:"timeout_commit"`
10001004

10011005
// Make progress as soon as we have all the precommits (as if TimeoutCommit = 0)
@@ -1078,6 +1082,7 @@ func (cfg *ConsensusConfig) Precommit(round int32) time.Duration {
10781082

10791083
// Commit returns the amount of time to wait for straggler votes after receiving +2/3 precommits
10801084
// for a single block (ie. a commit).
1085+
// Deprecated: use `next_block_delay` in the ABCI application's `FinalizeBlockResponse`.
10811086
func (cfg *ConsensusConfig) Commit(t time.Time) time.Time {
10821087
return t.Add(cfg.TimeoutCommit)
10831088
}

consensus/reactor_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -637,9 +637,9 @@ func TestReactorWithTimeoutCommit(t *testing.T) {
637637
N := 4
638638
css, cleanup := randConsensusNet(t, N, "consensus_reactor_with_timeout_commit_test", newMockTickerFunc(false), newKVStore)
639639
defer cleanup()
640-
// override default SkipTimeoutCommit == true for tests
640+
// override default NextBlockDelay == 0 for tests
641641
for i := 0; i < N; i++ {
642-
css[i].config.SkipTimeoutCommit = false
642+
css[i].state.NextBlockDelay = 1 * time.Second
643643
}
644644

645645
reactors, blocksSubs, eventBuses := startConsensusNet(t, css, N-1)

consensus/state.go

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -718,15 +718,20 @@ func (cs *State) updateToState(state sm.State) {
718718
cs.updateHeight(height)
719719
cs.updateRoundStep(0, cstypes.RoundStepNewHeight)
720720

721+
timeoutCommit := state.NextBlockDelay
722+
// If the ABCI app didn't set a delay, use the deprecated config value.
723+
if timeoutCommit == 0 {
724+
timeoutCommit = cs.config.TimeoutCommit //nolint:staticcheck
725+
}
721726
if cs.CommitTime.IsZero() {
722727
// "Now" makes it easier to sync up dev nodes.
723-
// We add timeoutCommit to allow transactions
724-
// to be gathered for the first block.
725-
// And alternative solution that relies on clocks:
726-
// cs.StartTime = state.LastBlockTime.Add(timeoutCommit)
727-
cs.StartTime = cs.config.Commit(cmttime.Now())
728+
//
729+
// We add timeoutCommit to allow transactions to be gathered for
730+
// the first block. An alternative solution that relies on clocks:
731+
// `cs.StartTime = state.LastBlockTime.Add(timeoutCommit)`
732+
cs.StartTime = cmttime.Now().Add(timeoutCommit)
728733
} else {
729-
cs.StartTime = cs.config.Commit(cs.CommitTime)
734+
cs.StartTime = cs.CommitTime.Add(timeoutCommit)
730735
}
731736

732737
cs.Validators = validators
@@ -1042,7 +1047,7 @@ func (cs *State) handleTxsAvailable() {
10421047

10431048
// Enter: `timeoutNewHeight` by startTime (commitTime+timeoutCommit),
10441049
//
1045-
// or, if SkipTimeoutCommit==true, after receiving all precommits from (height,round-1)
1050+
// or, if NextBlockDelay==0, after receiving all precommits from (height,round-1)
10461051
//
10471052
// Enter: `timeoutPrecommits` after any +2/3 precommits from (height,round-1)
10481053
// Enter: +2/3 precommits for nil at (height,round-1)
@@ -2211,7 +2216,8 @@ func (cs *State) addVote(vote *types.Vote, peerID p2p.ID) (added bool, err error
22112216
cs.evsw.FireEvent(types.EventVote, vote)
22122217

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

23702376
if !blockID.IsNil() {
23712377
cs.enterCommit(height, vote.Round)
2372-
if cs.config.SkipTimeoutCommit && precommits.HasAll() {
2378+
skipTimeoutCommit := cs.state.NextBlockDelay == 0 && cs.config.TimeoutCommit == 0 //nolint:staticcheck
2379+
if skipTimeoutCommit && precommits.HasAll() {
23732380
cs.enterNewRound(cs.Height, 0)
23742381
}
23752382
} else {

consensus/state_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2761,6 +2761,7 @@ func (n *fakeTxNotifier) Notify() {
27612761
func TestStartNextHeightCorrectlyAfterTimeout(t *testing.T) {
27622762
config.Consensus.SkipTimeoutCommit = false
27632763
cs1, vss := randState(4)
2764+
cs1.state.NextBlockDelay = 10 * time.Millisecond
27642765
cs1.txNotifier = &fakeTxNotifier{ch: make(chan struct{})}
27652766

27662767
vs2, vs3, vs4 := vss[1], vss[2], vss[3]
@@ -2825,6 +2826,7 @@ func TestResetTimeoutPrecommitUponNewHeight(t *testing.T) {
28252826

28262827
config.Consensus.SkipTimeoutCommit = false
28272828
cs1, vss := randState(4)
2829+
cs1.state.NextBlockDelay = 10 * time.Millisecond
28282830

28292831
vs2, vs3, vs4 := vss[1], vss[2], vss[3]
28302832
height, round := cs1.Height, cs1.Round

docs/app-dev/indexing-transactions.md

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,6 @@ transferBalance200FinalizeBlock12 1
118118
transferNodeNothingFinalizeBlock12 1
119119
120120
```
121-
122121
The event number is a local variable kept by the indexer and incremented when a new event is processed.
123122
It is an `int64` variable and has no other semantics besides being used to associate attributes belonging to the same events within a height.
124123
This variable is not atomically incremented as event indexing is deterministic. **Should this ever change**, the event id generation
@@ -174,32 +173,30 @@ Example:
174173

175174
```go
176175
func (app *Application) FinalizeBlock(_ context.Context, req *types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) {
177-
178-
//...
179-
tx_results[0] := &types.ExecTxResult{
180-
Code: CodeTypeOK,
181-
// With every transaction we can emit a series of events. To make it simple, we just emit the same events.
182-
Events: []types.Event{
183-
{
184-
Type: "app",
185-
Attributes: []types.EventAttribute{
186-
{Key: "creator", Value: "Cosmoshi Netowoko", Index: true},
187-
{Key: "key", Value: key, Index: true},
188-
{Key: "index_key", Value: "index is working", Index: true},
189-
{Key: "noindex_key", Value: "index is working", Index: false},
190-
},
191-
},
192-
{
193-
Type: "app",
194-
Attributes: []types.EventAttribute{
195-
{Key: "creator", Value: "Cosmoshi", Index: true},
196-
{Key: "key", Value: value, Index: true},
197-
{Key: "index_key", Value: "index is working", Index: true},
198-
{Key: "noindex_key", Value: "index is working", Index: false},
199-
},
200-
},
201-
},
202-
}
176+
tx_results[0] := &types.ExecTxResult{
177+
Code: CodeTypeOK,
178+
// With every transaction we can emit a series of events. To make it simple, we just emit the same events.
179+
Events: []types.Event{
180+
{
181+
Type: "app",
182+
Attributes: []types.EventAttribute{
183+
{Key: "creator", Value: "Cosmoshi Netowoko", Index: true},
184+
{Key: "key", Value: key, Index: true},
185+
{Key: "index_key", Value: "index is working", Index: true},
186+
{Key: "noindex_key", Value: "index is working", Index: false},
187+
},
188+
},
189+
{
190+
Type: "app",
191+
Attributes: []types.EventAttribute{
192+
{Key: "creator", Value: "Cosmoshi", Index: true},
193+
{Key: "key", Value: value, Index: true},
194+
{Key: "index_key", Value: "index is working", Index: true},
195+
{Key: "noindex_key", Value: "index is working", Index: false},
196+
},
197+
},
198+
},
199+
}
203200

204201
block_events = []types.Event{
205202
{

docs/guides/go-built-in.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,10 +375,13 @@ func (app *KVStoreApplication) FinalizeBlock(_ context.Context, req *abcitypes.R
375375

376376
return &abcitypes.ResponseFinalizeBlock{
377377
TxResults: txs,
378+
NextBlockDelay: 1 * time.Second,
378379
}, nil
379380
}
380381
```
381382

383+
`NextBlockDelay` is a delay between the time when the current block is committed and the next height is started. Normally you don't need to change the default value (1s). Please refer to the [spec](../../spec/abci/abci++_methods.md#finalizeblock) for more information.
384+
382385
Transactions are not guaranteed to be valid when they are delivered to an application, even if they were valid when they were proposed.
383386

384387
This can happen if the application state is used to determine transaction validity.

0 commit comments

Comments
 (0)