Browse Source

Merge pull request #360 from tendermint/optional-skip-timeout-commit

Optional skip timeout commit
pull/362/head
Ethan Buchman 8 years ago
committed by GitHub
parent
commit
76b4a45f98
5 changed files with 74 additions and 23 deletions
  1. +5
    -4
      Makefile
  2. +2
    -0
      config/tendermint/config.go
  3. +1
    -0
      config/tendermint_test/config.go
  4. +44
    -0
      consensus/reactor_test.go
  5. +22
    -19
      consensus/state.go

+ 5
- 4
Makefile View File

@ -12,19 +12,19 @@ NOVENDOR = go list github.com/tendermint/tendermint/... | grep -v /vendor/
install: get_deps
go install github.com/tendermint/tendermint/cmd/tendermint
build:
build:
go build -o build/tendermint github.com/tendermint/tendermint/cmd/tendermint
build_race:
build_race:
go build -race -o build/tendermint github.com/tendermint/tendermint/cmd/tendermint
test: build
go test `${NOVENDOR}`
test_race: build
go test -race `${NOVENDOR}`
test_integrations:
test_integrations:
bash ./test/test.sh
test100: build
@ -48,6 +48,7 @@ get_deps:
get_vendor_deps:
go get github.com/Masterminds/glide
rm -rf vendor/
glide install
update_deps:


+ 2
- 0
config/tendermint/config.go View File

@ -84,6 +84,8 @@ func GetConfig(rootDir string) cfg.Config {
mapConfig.SetDefault("timeout_precommit", 1000)
mapConfig.SetDefault("timeout_precommit_delta", 500)
mapConfig.SetDefault("timeout_commit", 1000)
// make progress asap (no `timeout_commit`) on full precommit votes
mapConfig.SetDefault("skip_timeout_commit", false)
mapConfig.SetDefault("mempool_recheck", true)
mapConfig.SetDefault("mempool_recheck_empty", true)
mapConfig.SetDefault("mempool_broadcast", true)


+ 1
- 0
config/tendermint_test/config.go View File

@ -98,6 +98,7 @@ func ResetConfig(localPath string) cfg.Config {
mapConfig.SetDefault("timeout_precommit", 10)
mapConfig.SetDefault("timeout_precommit_delta", 1)
mapConfig.SetDefault("timeout_commit", 10)
mapConfig.SetDefault("skip_timeout_commit", true)
mapConfig.SetDefault("mempool_recheck", true)
mapConfig.SetDefault("mempool_recheck_empty", true)
mapConfig.SetDefault("mempool_broadcast", true)


+ 44
- 0
consensus/reactor_test.go View File

@ -149,6 +149,7 @@ func TestValidatorSetChanges(t *testing.T) {
nPeers := 8
nVals := 4
css := randConsensusNetWithPeers(nVals, nPeers, "consensus_val_set_changes_test", newMockTickerFunc(true), newPersistentDummy)
reactors := make([]*ConsensusReactor, nPeers)
eventChans := make([]chan interface{}, nPeers)
for i := 0; i < nPeers; i++ {
@ -261,6 +262,49 @@ func TestValidatorSetChanges(t *testing.T) {
waitForAndValidateBlock(t, nPeers, activeVals, eventChans, css)
}
// Check we can make blocks with skip_timeout_commit=false
func TestReactorWithTimeoutCommit(t *testing.T) {
N := 4
css := randConsensusNet(N, "consensus_reactor_with_timeout_commit_test", newMockTickerFunc(false))
// override default SkipTimeoutCommit == true for tests
for i := 0; i < N; i++ {
css[i].timeoutParams.SkipTimeoutCommit = false
}
reactors := make([]*ConsensusReactor, N-1)
eventChans := make([]chan interface{}, N-1)
for i := 0; i < N-1; i++ {
reactors[i] = NewConsensusReactor(css[i], true) // so we dont start the consensus states
eventSwitch := events.NewEventSwitch()
_, err := eventSwitch.Start()
if err != nil {
t.Fatalf("Failed to start switch: %v", err)
}
reactors[i].SetEventSwitch(eventSwitch)
eventChans[i] = subscribeToEvent(eventSwitch, "tester", types.EventStringNewBlock(), 1)
}
// make connected switches and start all reactors
p2p.MakeConnectedSwitches(N-1, func(i int, s *p2p.Switch) *p2p.Switch {
s.AddReactor("CONSENSUS", reactors[i])
return s
}, p2p.Connect2Switches)
// start the state machines
for i := 0; i < N-1; i++ {
s := reactors[i].conS.GetState()
reactors[i].SwitchToConsensus(s)
}
// wait till everyone makes the first new block
timeoutWaitGroup(t, N-1, func(wg *sync.WaitGroup, j int) {
<-eventChans[j]
wg.Done()
})
}
func waitForAndValidateBlock(t *testing.T, n int, activeVals map[string]struct{}, eventChans []chan interface{}, css []*ConsensusState, txs ...[]byte) {
timeoutWaitGroup(t, n, func(wg *sync.WaitGroup, j int) {
newBlockI := <-eventChans[j]


+ 22
- 19
consensus/state.go View File

@ -24,15 +24,17 @@ import (
//-----------------------------------------------------------------------------
// Timeout Parameters
// All in milliseconds
// TimeoutParams holds timeouts and deltas for each round step.
// All timeouts and deltas in milliseconds.
type TimeoutParams struct {
Propose0 int
ProposeDelta int
Prevote0 int
PrevoteDelta int
Precommit0 int
PrecommitDelta int
Commit0 int
Propose0 int
ProposeDelta int
Prevote0 int
PrevoteDelta int
Precommit0 int
PrecommitDelta int
Commit0 int
SkipTimeoutCommit bool
}
// Wait this long for a proposal
@ -55,16 +57,17 @@ func (tp *TimeoutParams) Commit(t time.Time) time.Time {
return t.Add(time.Duration(tp.Commit0) * time.Millisecond)
}
// Initialize parameters from config
// InitTimeoutParamsFromConfig initializes parameters from config
func InitTimeoutParamsFromConfig(config cfg.Config) *TimeoutParams {
return &TimeoutParams{
Propose0: config.GetInt("timeout_propose"),
ProposeDelta: config.GetInt("timeout_propose_delta"),
Prevote0: config.GetInt("timeout_prevote"),
PrevoteDelta: config.GetInt("timeout_prevote_delta"),
Precommit0: config.GetInt("timeout_precommit"),
PrecommitDelta: config.GetInt("timeout_precommit_delta"),
Commit0: config.GetInt("timeout_commit"),
Propose0: config.GetInt("timeout_propose"),
ProposeDelta: config.GetInt("timeout_propose_delta"),
Prevote0: config.GetInt("timeout_prevote"),
PrevoteDelta: config.GetInt("timeout_prevote_delta"),
Precommit0: config.GetInt("timeout_precommit"),
PrecommitDelta: config.GetInt("timeout_precommit_delta"),
Commit0: config.GetInt("timeout_commit"),
SkipTimeoutCommit: config.GetBool("skip_timeout_commit"),
}
}
@ -1388,8 +1391,8 @@ func (cs *ConsensusState) addVote(vote *types.Vote, peerKey string) (added bool,
log.Info(Fmt("Added to lastPrecommits: %v", cs.LastCommit.StringShort()))
types.FireEventVote(cs.evsw, types.EventDataVote{vote})
if cs.LastCommit.HasAll() {
// if we have all the votes now,
// if we can skip timeoutCommit and have all the votes now,
if cs.timeoutParams.SkipTimeoutCommit && cs.LastCommit.HasAll() {
// go straight to new round (skip timeout commit)
// cs.scheduleTimeout(time.Duration(0), cs.Height, 0, RoundStepNewHeight)
cs.enterNewRound(cs.Height, 0)
@ -1452,7 +1455,7 @@ func (cs *ConsensusState) addVote(vote *types.Vote, peerKey string) (added bool,
cs.enterPrecommit(height, vote.Round)
cs.enterCommit(height, vote.Round)
if precommits.HasAll() {
if cs.timeoutParams.SkipTimeoutCommit && cs.LastCommit.HasAll() {
// if we have all the votes now,
// go straight to new round (skip timeout commit)
// cs.scheduleTimeout(time.Duration(0), cs.Height, 0, RoundStepNewHeight)


Loading…
Cancel
Save