Skip to content

Commit eb71cfe

Browse files
author
Marko Vukolic
committed
sbft basic request retransmission
sbft was so far losing request in some cases during view change (e.g., new test TestViewChangeWithRetransmission in simplebft_test.go). Two tests were modified as they were expecting lost requests. This is a basic implementation that will be replaced by a fix to FAB-474. Change-Id: I366881d71fdd4ac69b7ab6dc88229d2bc2ec18c3 Signed-off-by: Marko Vukolic <[email protected]>
1 parent f046f3c commit eb71cfe

File tree

6 files changed

+75
-10
lines changed

6 files changed

+75
-10
lines changed

orderer/sbft/simplebft/checkpoint.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ func (s *SBFT) handleCheckpoint(c *Checkpoint, src uint64) {
9797
// ignore null requests
9898
batch := *s.cur.preprep.Batch
9999
batch.Signatures = cpset
100-
s.sys.Deliver(&batch)
100+
s.deliverBatch(&batch)
101101

102102
s.cur.timeout.Cancel()
103103
log.Infof("request %s %s completed on %d", s.cur.subject.Seq, hash2str(s.cur.subject.Digest), s.id)

orderer/sbft/simplebft/connection.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ func (s *SBFT) handleHello(h *Hello, src uint64) {
7272
}
7373

7474
if s.sys.LastBatch().DecodeHeader().Seq < bh.Seq {
75-
s.sys.Deliver(h.Batch)
75+
s.deliverBatch(h.Batch)
7676
}
7777

7878
if h.NewView != nil {

orderer/sbft/simplebft/newview.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,6 @@ func (s *SBFT) maybeDeliverUsingXset(nv *NewView) {
200200
prevBatch.Payloads = s.cur.preprep.Batch.Payloads
201201
}
202202
s.cur.checkpointDone = true
203-
s.sys.Deliver(prevBatch)
203+
s.deliverBatch(prevBatch)
204204
}
205205
}

orderer/sbft/simplebft/request.go

+9-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ func (s *SBFT) Request(req []byte) {
2424
}
2525

2626
func (s *SBFT) handleRequest(req *Request, src uint64) {
27+
key := hash2str(hash(req.Payload))
28+
log.Infof("replica %d inserting %x into pending", s.id, key)
29+
s.pending[key] = req
2730
if s.isPrimary() && s.activeView {
2831
s.batch = append(s.batch, req)
2932
if s.batchSize() >= s.config.BatchSizeBytes {
@@ -65,7 +68,12 @@ func (s *SBFT) maybeSendNextBatch() {
6568
}
6669

6770
if len(s.batch) == 0 {
68-
return
71+
for _, req := range s.pending {
72+
s.batch = append(s.batch, req)
73+
}
74+
if len(s.batch) == 0 {
75+
return
76+
}
6977
}
7078

7179
batch := s.batch

orderer/sbft/simplebft/simplebft.go

+12
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ type SBFT struct {
6666
viewChangeTimeout time.Duration
6767
viewChangeTimer Canceller
6868
replicaState []replicaInfo
69+
pending map[string]*Request
6970
}
7071

7172
type reqInfo struct {
@@ -106,6 +107,7 @@ func New(id uint64, config *Config, sys System) (*SBFT, error) {
106107
id: id,
107108
viewChangeTimer: dummyCanceller{},
108109
replicaState: make([]replicaInfo, config.N),
110+
pending: make(map[string]*Request),
109111
}
110112
s.sys.SetReceiver(s)
111113

@@ -226,3 +228,13 @@ func (s *SBFT) handleQueueableMessage(m *Msg, src uint64) {
226228

227229
log.Warningf("received invalid message from %d", src)
228230
}
231+
232+
func (s *SBFT) deliverBatch(batch *Batch) {
233+
s.sys.Deliver(batch)
234+
235+
for _, req := range batch.Payloads {
236+
key := hash2str(hash(req))
237+
log.Infof("replica %d attempting to remove %x from pending", s.id, key)
238+
delete(s.pending, key)
239+
}
240+
}

orderer/sbft/simplebft/simplebft_test.go

+51-6
Original file line numberDiff line numberDiff line change
@@ -208,11 +208,14 @@ func TestByzPrimary(t *testing.T) {
208208
repls[0].Request(r1)
209209
sys.Run()
210210
for _, a := range adapters {
211-
if len(a.batches) != 1 {
212-
t.Fatal("expected execution of 1 batch")
211+
if len(a.batches) != 2 {
212+
t.Fatal("expected execution of 2 batches")
213213
}
214214
if !reflect.DeepEqual([][]byte{r2}, a.batches[0].Payloads) {
215-
t.Error("wrong request executed")
215+
t.Error("wrong request executed first")
216+
}
217+
if !reflect.DeepEqual([][]byte{r1}, a.batches[1].Payloads) {
218+
t.Error("wrong request executed second")
216219
}
217220
}
218221
}
@@ -256,6 +259,45 @@ func TestViewChange(t *testing.T) {
256259
}
257260
}
258261

262+
func TestViewChangeWithRetransmission(t *testing.T) {
263+
N := uint64(4)
264+
sys := newTestSystem(N)
265+
var repls []*SBFT
266+
var adapters []*testSystemAdapter
267+
for i := uint64(0); i < N; i++ {
268+
a := sys.NewAdapter(i)
269+
s, err := New(i, &Config{N: N, F: 1, BatchDurationNsec: 2000000000, BatchSizeBytes: 1, RequestTimeoutNsec: 20000000000}, a)
270+
if err != nil {
271+
t.Fatal(err)
272+
}
273+
repls = append(repls, s)
274+
adapters = append(adapters, a)
275+
}
276+
277+
// network outage after prepares are received
278+
sys.filterFn = func(e testElem) (testElem, bool) {
279+
if msg, ok := e.ev.(*testMsgEvent); ok {
280+
if c := msg.msg.GetPrepare(); c != nil && c.Seq.View == 0 {
281+
return e, false
282+
}
283+
}
284+
return e, true
285+
}
286+
287+
connectAll(sys)
288+
r1 := []byte{1, 2, 3}
289+
repls[0].Request(r1)
290+
sys.Run()
291+
for _, a := range adapters {
292+
if len(a.batches) != 1 {
293+
t.Fatal("expected execution of 1 batch")
294+
}
295+
if !reflect.DeepEqual([][]byte{r1}, a.batches[0].Payloads) {
296+
t.Error("wrong request executed (1)")
297+
}
298+
}
299+
}
300+
259301
func TestViewChangeXset(t *testing.T) {
260302
N := uint64(4)
261303
sys := newTestSystem(N)
@@ -320,11 +362,14 @@ func TestViewChangeXset(t *testing.T) {
320362
if i == 3 {
321363
continue
322364
}
323-
if len(a.batches) != 1 {
365+
if len(a.batches) != 2 {
324366
t.Fatalf("expected execution of 1 batch: %v", a.batches)
325367
}
326-
if !reflect.DeepEqual([][]byte{r2}, a.batches[0].Payloads) {
327-
t.Error("wrong request executed")
368+
if !reflect.DeepEqual([][]byte{r1}, a.batches[0].Payloads) {
369+
t.Error("wrong request executed first")
370+
}
371+
if !reflect.DeepEqual([][]byte{r2}, a.batches[1].Payloads) {
372+
t.Error("wrong request executed second")
328373
}
329374
}
330375
}

0 commit comments

Comments
 (0)