Skip to content

Commit 061020b

Browse files
corecodeSimon Schubert
authored and
Simon Schubert
committed
sbft: run viewchange timer once we have a quorum
Once we have a quorum of view changes, we run the view change timer. Change-Id: If129246592bb7bf95cc30dd0fb0fad56474cc556 Signed-off-by: Simon Schubert <[email protected]>
1 parent 9d3abd1 commit 061020b

File tree

2 files changed

+103
-5
lines changed

2 files changed

+103
-5
lines changed

orderer/sbft/simplebft/simplebft_test.go

+93
Original file line numberDiff line numberDiff line change
@@ -787,3 +787,96 @@ func TestFullBacklog(t *testing.T) {
787787
}
788788
}
789789
}
790+
791+
func TestViewChangeTimer(t *testing.T) {
792+
t.Skip()
793+
N := uint64(4)
794+
sys := newTestSystem(N)
795+
var repls []*SBFT
796+
var adapters []*testSystemAdapter
797+
for i := uint64(0); i < N; i++ {
798+
a := sys.NewAdapter(i)
799+
s, err := New(i, &Config{N: N, F: 1, BatchDurationNsec: 2000000000, BatchSizeBytes: 10, RequestTimeoutNsec: 20000000000}, a)
800+
if err != nil {
801+
t.Fatal(err)
802+
}
803+
repls = append(repls, s)
804+
adapters = append(adapters, a)
805+
}
806+
807+
phase := 1
808+
809+
// network outage after prepares are received
810+
sys.filterFn = func(e testElem) (testElem, bool) {
811+
if msg, ok := e.ev.(*testMsgEvent); ok {
812+
if msg.dst == msg.src {
813+
return e, true
814+
} else if msg.src == 1 && phase == 2 {
815+
return e, false
816+
}
817+
testLog.Debugf("passing msg from %d to %d, phase %d", msg.src, msg.dst, phase)
818+
}
819+
820+
return e, true
821+
}
822+
823+
connectAll(sys)
824+
r1 := []byte{1, 2, 3}
825+
repls[0].Request(r1)
826+
827+
repls[3].sendViewChange()
828+
829+
sys.enqueue(10*time.Minute, &testTimer{id: 999, tf: func() {
830+
if repls[3].view != 1 {
831+
t.Fatalf("expected view not to advance past 1, we are in %d", repls[3].view)
832+
}
833+
}})
834+
835+
sys.enqueue(11*time.Minute, &testTimer{id: 999, tf: func() {
836+
phase = 2
837+
repls[2].sendViewChange()
838+
}})
839+
840+
sys.enqueue(12*time.Minute, &testTimer{id: 999, tf: func() {
841+
if repls[3].view != 2 {
842+
t.Fatalf("expected view not to advance past 2, 3 is in %d", repls[3].view)
843+
}
844+
}})
845+
846+
sys.enqueue(20*time.Minute, &testTimer{id: 999, tf: func() {
847+
for _, r := range repls {
848+
if r.view > 4 {
849+
t.Fatalf("expected view not to advance too much, we are in %d", r.view)
850+
}
851+
}
852+
}})
853+
854+
sys.Run()
855+
r2 := []byte{3, 1, 2}
856+
r3 := []byte{3, 5, 2}
857+
repls[2].Request(r2)
858+
repls[2].Request(r3)
859+
sys.Run()
860+
for _, a := range adapters {
861+
offs := 0
862+
if a.id != 3 {
863+
if len(a.batches) != 3 {
864+
t.Fatalf("%d: expected execution of 3 batches: %v", a.id, a.batches)
865+
}
866+
if !reflect.DeepEqual([][]byte{r1}, a.batches[0].Payloads) {
867+
t.Errorf("%d: wrong request executed (1): %v", a.id, a.batches)
868+
}
869+
} else {
870+
offs = -1
871+
if len(a.batches) != 2 {
872+
t.Fatalf("%d: expected execution of 3 batches: %v", a.id, a.batches)
873+
}
874+
}
875+
if len(a.batches[1+offs].Payloads) != 0 {
876+
t.Errorf("%d: not a null request: %v", a.id, a.batches[1])
877+
}
878+
if !reflect.DeepEqual([][]byte{r2, r3}, a.batches[2+offs].Payloads) {
879+
t.Errorf("%d: wrong request executed (2): %v", a.id, a.batches)
880+
}
881+
}
882+
}

orderer/sbft/simplebft/viewchange.go

+10-5
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,7 @@ func (s *SBFT) sendViewChange() {
4646
}
4747
svc := s.sign(vc)
4848
s.viewChangeTimer.Cancel()
49-
s.viewChangeTimer = s.sys.Timer(s.viewChangeTimeout, func() {
50-
s.viewChangeTimeout *= 2
51-
log.Notice("view change timed out, sending next")
52-
s.sendViewChange()
53-
})
49+
s.cur.timeout.Cancel()
5450
s.broadcast(&Msg{&Msg_ViewChange{svc}})
5551

5652
s.processNewView()
@@ -102,6 +98,15 @@ func (s *SBFT) handleViewChange(svc *Signed, src uint64) {
10298
}
10399
}
104100

101+
if quorum == s.noFaultyQuorum() {
102+
log.Notice("received 2f+1 view change messages, starting view change timer")
103+
s.viewChangeTimer = s.sys.Timer(s.viewChangeTimeout, func() {
104+
s.viewChangeTimeout *= 2
105+
log.Notice("view change timed out, sending next")
106+
s.sendViewChange()
107+
})
108+
}
109+
105110
if s.isPrimary() {
106111
s.maybeSendNewView()
107112
}

0 commit comments

Comments
 (0)