Skip to content

Commit

Permalink
fix sbft backlog issue (#2)
Browse files Browse the repository at this point in the history
Currently sbft backlog automatically places a message from a replica in
the backlog, if there is already in the backlog a message from that
replica. This is wrong and makes the new test TestBacklogReordering fail.

Change-Id: I4ae40552ad363e4005817e328857caee266588a2
Signed-off-by: Marko Vukolic <mvu@zurich.ibm.com>
  • Loading branch information
Marko Vukolic committed Nov 30, 2016
1 parent d148c38 commit 1cf8500
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 9 deletions.
8 changes: 0 additions & 8 deletions orderer/sbft/simplebft/backlog.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,6 @@ import "fmt"
const maxBacklogSeq = 4
const msgPerSeq = 3 // (pre)prepare, commit, checkpoint

func (s *SBFT) testBacklog(m *Msg, src uint64) bool {
if len(s.replicaState[src].backLog) > 0 {
return true
}

return s.testBacklogMessage(m, src)
}

func (s *SBFT) testBacklogMessage(m *Msg, src uint64) bool {
record := func(seq *SeqView) bool {
if !s.activeView {
Expand Down
2 changes: 1 addition & 1 deletion orderer/sbft/simplebft/simplebft.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ func (s *SBFT) Receive(m *Msg, src uint64) {
return
}

if s.testBacklog(m, src) {
if s.testBacklogMessage(m, src) {
log.Debugf("replica %d: message for future seq, storing for later", s.id)
s.recordBacklogMsg(m, src)
return
Expand Down
52 changes: 52 additions & 0 deletions orderer/sbft/simplebft/simplebft_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,58 @@ func TestMsgReordering(t *testing.T) {
}
}

func TestBacklogReordering(t *testing.T) {
N := uint64(4)
sys := newTestSystem(N)
var repls []*SBFT
var adapters []*testSystemAdapter
for i := uint64(0); i < N; i++ {
a := sys.NewAdapter(i)
s, err := New(i, &Config{N: N, F: 1, BatchDurationNsec: 2000000000, BatchSizeBytes: 1, RequestTimeoutNsec: 20000000000}, a)
if err != nil {
t.Fatal(err)
}
repls = append(repls, s)
adapters = append(adapters, a)
}

var preprep *testMsgEvent

// forcing pre-prepare from primary 0 to reach replica 1 after some delay
// effectivelly delivering pre-prepare instead of checkpoint
sys.filterFn = func(e testElem) (testElem, bool) {
if msg, ok := e.ev.(*testMsgEvent); ok {
if msg.src == 0 && msg.dst == 1 {
c := msg.msg.GetPreprepare()
if c != nil && c.Seq.View == 0 {
preprep = msg //memorizing pre-prepare
return e, false // but dropping it
}
d := msg.msg.GetCheckpoint()
if d != nil {
msg.msg = &Msg{&Msg_Preprepare{preprep.msg.GetPreprepare()}}
return e, true //and delivering it
}
return e, true //letting prepare and commit from 0 to 1 pass
}
}
return e, true
}

connectAll(sys)
r1 := []byte{1, 2, 3}
repls[0].Request(r1)
sys.Run()
for _, a := range adapters {
if len(a.batches) != 1 {
t.Fatal("expected execution of 1 batch")
}
if !reflect.DeepEqual([][]byte{r1}, a.batches[0].Payloads) {
t.Error("wrong request executed (1)")
}
}
}

func TestViewChangeWithRetransmission(t *testing.T) {
N := uint64(4)
sys := newTestSystem(N)
Expand Down

0 comments on commit 1cf8500

Please sign in to comment.