github.com/adnan-c/fabric_e2e_couchdb@v0.6.1-preview.0.20170228180935-21ce6b23cf91/orderer/sbft/simplebft/simplebft_test.go (about)

     1  /*
     2  Copyright IBM Corp. 2016 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  		 http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package simplebft
    18  
    19  import (
    20  	"reflect"
    21  	"testing"
    22  	"time"
    23  
    24  	"math"
    25  
    26  	"fmt"
    27  	"strconv"
    28  
    29  	"github.com/golang/protobuf/proto"
    30  	"github.com/op/go-logging"
    31  )
    32  
    33  const chainId = "id"
    34  const lowN uint64 = 4   //keep lowN greater or equal to 4
    35  const highN uint64 = 10 //keep highN greater or equal to 10
    36  
    37  var testLog = logging.MustGetLogger("test")
    38  
    39  func init() {
    40  	// logging.SetLevel(logging.NOTICE, "")
    41  	// logging.SetLevel(logging.DEBUG, "test")
    42  	logging.SetLevel(logging.DEBUG, "sbft")
    43  }
    44  
    45  func skipInShortMode(t *testing.T) {
    46  	if testing.Short() {
    47  		t.Skip("Skipping test in short mode.")
    48  	}
    49  }
    50  
    51  func connectAll(sys *testSystem, chainIds []string) {
    52  	for _, chainId := range chainIds {
    53  		connectAllForChainId(sys, chainId)
    54  	}
    55  }
    56  
    57  func connectAllForDefaultChain(sys *testSystem) {
    58  	connectAllForChainId(sys, chainId)
    59  }
    60  
    61  func connectAllForChainId(sys *testSystem, chainId string) {
    62  	// map iteration is non-deterministic, so use linear iteration instead
    63  	max := uint64(0)
    64  	for _, a := range sys.adapters {
    65  		if a.id > max {
    66  			max = a.id
    67  		}
    68  	}
    69  
    70  	for i := uint64(0); i <= max; i++ {
    71  		a, ok := sys.adapters[i]
    72  		if !ok {
    73  			continue
    74  		}
    75  
    76  		for j := uint64(0); j <= max; j++ {
    77  			b, ok := sys.adapters[j]
    78  			if !ok {
    79  				continue
    80  			}
    81  			if a.id != b.id {
    82  				a.receivers[chainId].Connection(b.id)
    83  			}
    84  		}
    85  	}
    86  	sys.Run()
    87  }
    88  
    89  func TestMultiChain(t *testing.T) {
    90  	skipInShortMode(t)
    91  	N := lowN
    92  	M := uint64(5)
    93  	sys := newTestSystem(N)
    94  	chainIds := make([]string, 0, M)
    95  	var repls map[string][]*SBFT = map[string][]*SBFT{}
    96  	var adapters []*testSystemAdapter
    97  	for i := uint64(0); i < N; i++ {
    98  		a := sys.NewAdapter(i)
    99  		for j := uint64(0); j < M; j++ {
   100  			chainId := fmt.Sprintf("%d", j)
   101  			s, err := New(i, chainId, &Config{N: N, F: 0, BatchDurationNsec: 2000000000, BatchSizeBytes: 10, RequestTimeoutNsec: 20000000000}, a)
   102  			if err != nil {
   103  				t.Fatal(err)
   104  			}
   105  			repls[chainId] = append(repls[chainId], s)
   106  			if uint64(len(chainIds)) < M {
   107  				chainIds = append(chainIds, chainId)
   108  			}
   109  		}
   110  		adapters = append(adapters, a)
   111  	}
   112  	connectAll(sys, chainIds)
   113  	r1 := []byte{1, 2, 3}
   114  	for i := uint64(0); i < N; i++ {
   115  		for j := uint64(0); j < M; j++ {
   116  			if j%uint64(2) == 0 {
   117  				chainId := fmt.Sprintf("%d", j)
   118  				repls[chainId][i].Request(r1)
   119  			}
   120  		}
   121  	}
   122  	sys.Run()
   123  	for _, a := range adapters {
   124  		for chainId := range a.batches {
   125  			// we check that if this is a chain where we sent a req then the req
   126  			// was written to the "ledger"
   127  			j, _ := strconv.ParseInt(chainId, 10, 64)
   128  			if j%2 == 0 && len(a.batches[chainId]) != 1 {
   129  				t.Fatalf("expected one batches on chain %s", chainId)
   130  			}
   131  			// in other cases, we should have at most an empty ledger
   132  			if j%2 != 0 && len(a.batches[chainId]) != 0 {
   133  				t.Fatalf("expected one batches on chain %s", chainId)
   134  			}
   135  		}
   136  	}
   137  }
   138  
   139  func TestSBFT(t *testing.T) {
   140  	skipInShortMode(t)
   141  	N := lowN
   142  	sys := newTestSystem(N)
   143  	var repls []*SBFT
   144  	var adapters []*testSystemAdapter
   145  	for i := uint64(0); i < N; i++ {
   146  		a := sys.NewAdapter(i)
   147  		s, err := New(i, chainId, &Config{N: N, F: 1, BatchDurationNsec: 2000000000, BatchSizeBytes: 10, RequestTimeoutNsec: 20000000000}, a)
   148  		if err != nil {
   149  			t.Fatal(err)
   150  		}
   151  		repls = append(repls, s)
   152  		adapters = append(adapters, a)
   153  	}
   154  	connectAllForDefaultChain(sys)
   155  	r1 := []byte{1, 2, 3}
   156  	repls[0].Request(r1)
   157  	sys.Run()
   158  	r2 := []byte{3, 1, 2}
   159  	r3 := []byte{3, 5, 2}
   160  	repls[1].Request(r2)
   161  	repls[1].Request(r3)
   162  	sys.Run()
   163  	for _, a := range adapters {
   164  		if len(a.batches[chainId]) != 2 {
   165  			t.Fatal("expected execution of 2 batches")
   166  		}
   167  		if !reflect.DeepEqual([][]byte{r1}, a.batches[chainId][0].Payloads) {
   168  			t.Error("wrong request executed (1)")
   169  		}
   170  		if !reflect.DeepEqual([][]byte{r2, r3}, a.batches[chainId][1].Payloads) {
   171  			t.Error("wrong request executed (2)")
   172  		}
   173  	}
   174  }
   175  
   176  func TestQuorumSizes(t *testing.T) {
   177  	for N := uint64(1); N < 100; N++ {
   178  		for f := uint64(0); f <= uint64(math.Floor(float64(N-1)/float64(3))); f++ {
   179  			sys := newTestSystem(N)
   180  			a := sys.NewAdapter(0)
   181  			s, err := New(0, chainId, &Config{N: N, F: f, BatchDurationNsec: 2000000000, BatchSizeBytes: 10, RequestTimeoutNsec: 20000000000}, a)
   182  			if err != nil {
   183  				t.Fatal(err)
   184  			}
   185  			if uint64(2*s.commonCaseQuorum())-N < f+1 {
   186  				t.Fatal("insufficient intersection of two common case quorums", "N = ", N, " F = ", f)
   187  			}
   188  			if uint64(s.commonCaseQuorum()+s.viewChangeQuorum())-N < f+1 {
   189  				t.Fatal("insufficient intersection of common case and view change quorums", "N = ", N, " F = ", f)
   190  			}
   191  			if f < uint64(math.Floor(float64(N-1)/float64(3))) {
   192  				//end test for unoptimized f
   193  				continue
   194  			}
   195  			//test additionally when f is optimized
   196  			switch int(math.Mod(float64(N), float64(3))) {
   197  			case 1:
   198  				if s.commonCaseQuorum() != int(N-f) || s.viewChangeQuorum() != int(N-f) {
   199  					t.Fatal("quorum sizes are wrong in default case N mod 3 == 1")
   200  				}
   201  			case 2:
   202  				if s.viewChangeQuorum() >= s.commonCaseQuorum() || s.viewChangeQuorum() >= int(N-f) {
   203  					t.Fatal("view change quorums size not optimized when N mod 3 == 2")
   204  				}
   205  			case 3:
   206  				if s.commonCaseQuorum() >= int(N-f) || s.viewChangeQuorum() >= int(N-f) {
   207  					t.Fatal("quorum sizes not optimized when N mod 3 == 3")
   208  				}
   209  			}
   210  		}
   211  	}
   212  }
   213  
   214  func TestSBFTDelayed(t *testing.T) {
   215  	skipInShortMode(t)
   216  	N := lowN
   217  	BS := uint64(1)
   218  	sys := newTestSystemWithBatchSize(N, BS)
   219  	var repls []*SBFT
   220  	var adapters []*testSystemAdapter
   221  	for i := uint64(0); i < N; i++ {
   222  		a := sys.NewAdapter(i)
   223  		s, err := New(i, chainId, &Config{N: N, F: 1, BatchDurationNsec: 2000000000, BatchSizeBytes: BS, RequestTimeoutNsec: 20000000000}, a)
   224  		if err != nil {
   225  			t.Fatal(err)
   226  		}
   227  		repls = append(repls, s)
   228  		adapters = append(adapters, a)
   229  	}
   230  
   231  	// make replica 3 lag out against 1 and 2
   232  	for i := uint64(1); i < 3; i++ {
   233  		adapters[i].arrivals[3] = 200 * time.Millisecond
   234  		adapters[3].arrivals[i] = 200 * time.Millisecond
   235  	}
   236  
   237  	connectAllForDefaultChain(sys)
   238  	r1 := []byte{1, 2, 3}
   239  	r2 := []byte{3, 1, 2}
   240  	repls[0].Request(r1)
   241  	repls[1].Request(r2)
   242  	sys.Run()
   243  	for i, a := range adapters {
   244  		if len(a.batches[chainId]) != 2 {
   245  			t.Errorf("expected execution of 2 batches on %d", i)
   246  			continue
   247  		}
   248  		if !reflect.DeepEqual([][]byte{r1}, a.batches[chainId][0].Payloads) {
   249  			t.Error("wrong request executed (1)")
   250  		}
   251  		if !reflect.DeepEqual([][]byte{r2}, a.batches[chainId][1].Payloads) {
   252  			t.Error("wrong request executed (2)")
   253  		}
   254  	}
   255  }
   256  
   257  func TestN1(t *testing.T) {
   258  	skipInShortMode(t)
   259  	N := uint64(1)
   260  	sys := newTestSystem(N)
   261  	var repls []*SBFT
   262  	var adapters []*testSystemAdapter
   263  	for i := uint64(0); i < N; i++ {
   264  		a := sys.NewAdapter(i)
   265  		s, err := New(i, chainId, &Config{N: N, F: 0, BatchDurationNsec: 2000000000, BatchSizeBytes: 10, RequestTimeoutNsec: 20000000000}, a)
   266  		if err != nil {
   267  			t.Fatal(err)
   268  		}
   269  		repls = append(repls, s)
   270  		adapters = append(adapters, a)
   271  	}
   272  	connectAllForDefaultChain(sys)
   273  	r1 := []byte{1, 2, 3}
   274  	repls[0].Request(r1)
   275  	sys.Run()
   276  	for _, a := range adapters {
   277  		if len(a.batches[chainId]) != 1 {
   278  			t.Fatal("expected execution of 1 batches")
   279  		}
   280  		if !reflect.DeepEqual([][]byte{r1}, a.batches[chainId][0].Payloads) {
   281  			t.Error("wrong request executed (1)")
   282  		}
   283  	}
   284  }
   285  
   286  func TestMonotonicViews(t *testing.T) {
   287  	skipInShortMode(t)
   288  	N := lowN
   289  	sys := newTestSystem(N)
   290  	var repls []*SBFT
   291  	var adapters []*testSystemAdapter
   292  	for i := uint64(0); i < N; i++ {
   293  		a := sys.NewAdapter(i)
   294  		s, err := New(i, chainId, &Config{N: N, F: 1, BatchDurationNsec: 2000000000, BatchSizeBytes: 10, RequestTimeoutNsec: 20000000000}, a)
   295  		if err != nil {
   296  			t.Fatal(err)
   297  		}
   298  		repls = append(repls, s)
   299  		adapters = append(adapters, a)
   300  	}
   301  
   302  	repls[0].sendViewChange()
   303  	sys.Run()
   304  
   305  	view := repls[0].view
   306  	testLog.Notice("TEST: Replica 0 is in view ", view)
   307  	testLog.Notice("TEST: restarting replica 0")
   308  	repls[0], _ = New(0, chainId, &Config{N: N, F: 1, BatchDurationNsec: 2000000000, BatchSizeBytes: 10, RequestTimeoutNsec: 20000000000}, adapters[0])
   309  	for _, a := range adapters {
   310  		if a.id != 0 {
   311  			a.receivers[chainId].Connection(0)
   312  			adapters[0].receivers[chainId].Connection(a.id)
   313  		}
   314  	}
   315  	sys.Run()
   316  
   317  	if repls[0].view < view {
   318  		t.Fatalf("Replica 0 must be at least in view %d, but is in view %d", view, repls[0].view)
   319  	}
   320  }
   321  
   322  func TestByzPrimaryN4(t *testing.T) {
   323  	skipInShortMode(t)
   324  	N := uint64(4)
   325  	sys := newTestSystem(N)
   326  	var repls []*SBFT
   327  	var adapters []*testSystemAdapter
   328  	for i := uint64(0); i < N; i++ {
   329  		a := sys.NewAdapter(i)
   330  		s, err := New(i, chainId, &Config{N: N, F: 1, BatchDurationNsec: 2000000000, BatchSizeBytes: 1, RequestTimeoutNsec: 20000000000}, a)
   331  		if err != nil {
   332  			t.Fatal(err)
   333  		}
   334  		repls = append(repls, s)
   335  		adapters = append(adapters, a)
   336  	}
   337  
   338  	r1 := []byte{1, 2, 3}
   339  	r2 := []byte{5, 6, 7}
   340  
   341  	// change preprepare to 2, 3
   342  	sys.filterFn = func(e testElem) (testElem, bool) {
   343  		if msg, ok := e.ev.(*testMsgEvent); ok {
   344  			if pp := msg.msg.GetPreprepare(); pp != nil && msg.src == 0 && msg.dst >= 2 {
   345  				pp := *pp
   346  				batch := *pp.Batch
   347  				batch.Payloads = [][]byte{r2}
   348  				pp.Batch = &batch
   349  				h := merkleHashData(batch.Payloads)
   350  				bh := &BatchHeader{}
   351  				proto.Unmarshal(pp.Batch.Header, bh)
   352  				bh.DataHash = h
   353  				bhraw, _ := proto.Marshal(bh)
   354  				pp.Batch.Header = bhraw
   355  				msg.msg = &Msg{&Msg_Preprepare{&pp}}
   356  			}
   357  		}
   358  		return e, true
   359  	}
   360  
   361  	connectAllForDefaultChain(sys)
   362  	repls[0].Request(r1)
   363  	sys.Run()
   364  	for _, a := range adapters {
   365  		if len(a.batches[chainId]) != 2 {
   366  			t.Fatal("expected execution of 2 batches")
   367  		}
   368  		if !reflect.DeepEqual([][]byte{r2}, a.batches[chainId][0].Payloads) {
   369  			t.Error("wrong request executed first")
   370  		}
   371  		if !reflect.DeepEqual([][]byte{r1}, a.batches[chainId][1].Payloads) {
   372  			t.Error("wrong request executed second")
   373  		}
   374  	}
   375  }
   376  
   377  func TestNewPrimaryHandlingViewChange(t *testing.T) {
   378  	skipInShortMode(t)
   379  	N := uint64(7)
   380  	sys := newTestSystem(N)
   381  	var repls []*SBFT
   382  	var adapters []*testSystemAdapter
   383  	for i := uint64(0); i < N; i++ {
   384  		a := sys.NewAdapter(i)
   385  		s, err := New(i, chainId, &Config{N: N, F: 2, BatchDurationNsec: 2000000000, BatchSizeBytes: 1, RequestTimeoutNsec: 20000000000}, a)
   386  		if err != nil {
   387  			t.Fatal(err)
   388  		}
   389  		repls = append(repls, s)
   390  		adapters = append(adapters, a)
   391  	}
   392  
   393  	r1 := []byte{1, 2, 3}
   394  	r2 := []byte{5, 6, 7}
   395  
   396  	// change preprepare to 2-6
   397  	sys.filterFn = func(e testElem) (testElem, bool) {
   398  		if msg, ok := e.ev.(*testMsgEvent); ok {
   399  			if pp := msg.msg.GetPreprepare(); pp != nil && msg.src == 0 && msg.dst >= 2 {
   400  				pp := *pp
   401  				batch := *pp.Batch
   402  				batch.Payloads = [][]byte{r2}
   403  				pp.Batch = &batch
   404  				h := merkleHashData(batch.Payloads)
   405  				bh := &BatchHeader{}
   406  				proto.Unmarshal(pp.Batch.Header, bh)
   407  				bh.DataHash = h
   408  				bhraw, _ := proto.Marshal(bh)
   409  				pp.Batch.Header = bhraw
   410  				msg.msg = &Msg{&Msg_Preprepare{&pp}}
   411  			}
   412  		}
   413  		return e, true
   414  	}
   415  
   416  	connectAllForDefaultChain(sys)
   417  	repls[0].Request(r1)
   418  	sys.Run()
   419  	for _, a := range adapters {
   420  		if len(a.batches[chainId]) < 1 {
   421  			t.Fatal("expected execution of at least one batches")
   422  		}
   423  		if a.batches[chainId][0].Payloads != nil && !reflect.DeepEqual(adapters[2].batches[chainId][0].Payloads, a.batches[chainId][0].Payloads) {
   424  			t.Error("consensus violated on first batches at replica", a.id)
   425  		}
   426  	}
   427  }
   428  
   429  func TestByzPrimaryBullyingSingleReplica(t *testing.T) {
   430  	skipInShortMode(t)
   431  	N := highN
   432  	sys := newTestSystem(N)
   433  	var repls []*SBFT
   434  	var adapters []*testSystemAdapter
   435  	for i := uint64(0); i < N; i++ {
   436  		a := sys.NewAdapter(i)
   437  		s, err := New(i, chainId, &Config{N: N, F: 1, BatchDurationNsec: 2000000000, BatchSizeBytes: 1, RequestTimeoutNsec: 20000000000}, a)
   438  		if err != nil {
   439  			t.Fatal(err)
   440  		}
   441  		repls = append(repls, s)
   442  		adapters = append(adapters, a)
   443  	}
   444  
   445  	r1 := []byte{1, 2, 3}
   446  	r2 := []byte{5, 6, 7}
   447  
   448  	// change preprepare to 1
   449  	sys.filterFn = func(e testElem) (testElem, bool) {
   450  		if msg, ok := e.ev.(*testMsgEvent); ok {
   451  			if pp := msg.msg.GetPreprepare(); pp != nil && msg.src == 0 && msg.dst == 1 {
   452  				pp := *pp
   453  				batch := *pp.Batch
   454  				batch.Payloads = [][]byte{r2}
   455  				pp.Batch = &batch
   456  				h := merkleHashData(batch.Payloads)
   457  				bh := &BatchHeader{}
   458  				proto.Unmarshal(pp.Batch.Header, bh)
   459  				bh.DataHash = h
   460  				bhraw, _ := proto.Marshal(bh)
   461  				pp.Batch.Header = bhraw
   462  				msg.msg = &Msg{&Msg_Preprepare{&pp}}
   463  			}
   464  		}
   465  		return e, true
   466  	}
   467  
   468  	connectAllForDefaultChain(sys)
   469  	repls[0].Request(r1)
   470  	sys.Run()
   471  	for _, a := range adapters {
   472  		if a.id != 1 && len(a.batches[chainId]) != 1 {
   473  			t.Fatal("expected execution of 1 batches at all except replica 1")
   474  		}
   475  	}
   476  }
   477  
   478  func TestViewChange(t *testing.T) {
   479  	skipInShortMode(t)
   480  	N := lowN
   481  	sys := newTestSystem(N)
   482  	var repls []*SBFT
   483  	var adapters []*testSystemAdapter
   484  	for i := uint64(0); i < N; i++ {
   485  		a := sys.NewAdapter(i)
   486  		s, err := New(i, chainId, &Config{N: N, F: 1, BatchDurationNsec: 2000000000, BatchSizeBytes: 1, RequestTimeoutNsec: 20000000000}, a)
   487  		if err != nil {
   488  			t.Fatal(err)
   489  		}
   490  		repls = append(repls, s)
   491  		adapters = append(adapters, a)
   492  	}
   493  
   494  	// network outage after prepares are received
   495  	sys.filterFn = func(e testElem) (testElem, bool) {
   496  		if msg, ok := e.ev.(*testMsgEvent); ok {
   497  			if c := msg.msg.GetCommit(); c != nil && c.Seq.View == 0 {
   498  				return e, false
   499  			}
   500  		}
   501  		return e, true
   502  	}
   503  
   504  	connectAllForDefaultChain(sys)
   505  	r1 := []byte{1, 2, 3}
   506  	repls[0].Request(r1)
   507  	sys.Run()
   508  	for _, a := range adapters {
   509  		if len(a.batches[chainId]) != 1 {
   510  			t.Fatal("expected execution of 1 batches")
   511  		}
   512  		if !reflect.DeepEqual([][]byte{r1}, a.batches[chainId][0].Payloads) {
   513  			t.Error("wrong request executed (1)")
   514  		}
   515  	}
   516  }
   517  
   518  func TestMsgReordering(t *testing.T) {
   519  	skipInShortMode(t)
   520  	N := lowN
   521  	sys := newTestSystem(N)
   522  	var repls []*SBFT
   523  	var adapters []*testSystemAdapter
   524  	for i := uint64(0); i < N; i++ {
   525  		a := sys.NewAdapter(i)
   526  		s, err := New(i, chainId, &Config{N: N, F: 1, BatchDurationNsec: 2000000000, BatchSizeBytes: 1, RequestTimeoutNsec: 20000000000}, a)
   527  		if err != nil {
   528  			t.Fatal(err)
   529  		}
   530  		repls = append(repls, s)
   531  		adapters = append(adapters, a)
   532  	}
   533  
   534  	var preprep *testMsgEvent
   535  
   536  	// forcing pre-prepare from primary 0 to reach replica 1 after some delay
   537  	// effectivelly delivering pre-prepare instead of checkpoint
   538  	sys.filterFn = func(e testElem) (testElem, bool) {
   539  		if msg, ok := e.ev.(*testMsgEvent); ok {
   540  			if msg.src == 0 && msg.dst == 1 {
   541  				c := msg.msg.GetPreprepare()
   542  				if c != nil && c.Seq.View == 0 {
   543  					preprep = msg   //memorizing pre-prepare
   544  					return e, false // but dropping it
   545  				}
   546  				d := msg.msg.GetCheckpoint()
   547  				if d != nil {
   548  					msg.msg = &Msg{&Msg_Preprepare{preprep.msg.GetPreprepare()}}
   549  					return e, true //and delivering it
   550  				}
   551  				return e, false //droping other msgs from 0 to 1
   552  			}
   553  		}
   554  		return e, true
   555  	}
   556  
   557  	connectAllForDefaultChain(sys)
   558  	r1 := []byte{1, 2, 3}
   559  	repls[0].Request(r1)
   560  	sys.Run()
   561  	for _, a := range adapters {
   562  		if len(a.batches[chainId]) != 1 {
   563  			t.Fatal("expected execution of 1 batches")
   564  		}
   565  		if !reflect.DeepEqual([][]byte{r1}, a.batches[chainId][0].Payloads) {
   566  			t.Error("wrong request executed (1)")
   567  		}
   568  	}
   569  }
   570  
   571  func TestBacklogReordering(t *testing.T) {
   572  	skipInShortMode(t)
   573  	N := lowN
   574  	sys := newTestSystem(N)
   575  	var repls []*SBFT
   576  	var adapters []*testSystemAdapter
   577  	for i := uint64(0); i < N; i++ {
   578  		a := sys.NewAdapter(i)
   579  		s, err := New(i, chainId, &Config{N: N, F: 1, BatchDurationNsec: 2000000000, BatchSizeBytes: 1, RequestTimeoutNsec: 20000000000}, a)
   580  		if err != nil {
   581  			t.Fatal(err)
   582  		}
   583  		repls = append(repls, s)
   584  		adapters = append(adapters, a)
   585  	}
   586  
   587  	var preprep *testMsgEvent
   588  
   589  	// forcing pre-prepare from primary 0 to reach replica 1 after some delay
   590  	// effectivelly delivering pre-prepare instead of checkpoint
   591  	sys.filterFn = func(e testElem) (testElem, bool) {
   592  		if msg, ok := e.ev.(*testMsgEvent); ok {
   593  			if msg.src == 0 && msg.dst == 1 {
   594  				c := msg.msg.GetPreprepare()
   595  				if c != nil && c.Seq.View == 0 {
   596  					preprep = msg   //memorizing pre-prepare
   597  					return e, false // but dropping it
   598  				}
   599  				d := msg.msg.GetCheckpoint()
   600  				if d != nil {
   601  					msg.msg = &Msg{&Msg_Preprepare{preprep.msg.GetPreprepare()}}
   602  					return e, true //and delivering it
   603  				}
   604  				return e, true //letting prepare and commit from 0 to 1 pass
   605  			}
   606  		}
   607  		return e, true
   608  	}
   609  
   610  	connectAllForDefaultChain(sys)
   611  	r1 := []byte{1, 2, 3}
   612  	repls[0].Request(r1)
   613  	sys.Run()
   614  	for _, a := range adapters {
   615  		if len(a.batches[chainId]) != 1 {
   616  			t.Fatal("expected execution of 1 batches")
   617  		}
   618  		if !reflect.DeepEqual([][]byte{r1}, a.batches[chainId][0].Payloads) {
   619  			t.Error("wrong request executed (1)")
   620  		}
   621  	}
   622  }
   623  
   624  func TestViewChangeWithRetransmission(t *testing.T) {
   625  	skipInShortMode(t)
   626  	N := lowN
   627  	sys := newTestSystem(N)
   628  	var repls []*SBFT
   629  	var adapters []*testSystemAdapter
   630  	for i := uint64(0); i < N; i++ {
   631  		a := sys.NewAdapter(i)
   632  		s, err := New(i, chainId, &Config{N: N, F: 1, BatchDurationNsec: 2000000000, BatchSizeBytes: 1, RequestTimeoutNsec: 20000000000}, a)
   633  		if err != nil {
   634  			t.Fatal(err)
   635  		}
   636  		repls = append(repls, s)
   637  		adapters = append(adapters, a)
   638  	}
   639  
   640  	// network outage after prepares are received
   641  	sys.filterFn = func(e testElem) (testElem, bool) {
   642  		if msg, ok := e.ev.(*testMsgEvent); ok {
   643  			if c := msg.msg.GetPrepare(); c != nil && c.Seq.View == 0 {
   644  				return e, false
   645  			}
   646  		}
   647  		return e, true
   648  	}
   649  
   650  	connectAllForDefaultChain(sys)
   651  	r1 := []byte{1, 2, 3}
   652  	repls[0].Request(r1)
   653  	sys.Run()
   654  	for _, a := range adapters {
   655  		if len(a.batches[chainId]) != 1 {
   656  			t.Fatal("expected execution of 1 batches")
   657  		}
   658  		if !reflect.DeepEqual([][]byte{r1}, a.batches[chainId][0].Payloads) {
   659  			t.Error("wrong request executed (1)")
   660  		}
   661  	}
   662  }
   663  
   664  func TestViewChangeXset(t *testing.T) {
   665  	skipInShortMode(t)
   666  	N := lowN
   667  	sys := newTestSystem(N)
   668  	var repls []*SBFT
   669  	var adapters []*testSystemAdapter
   670  	for i := uint64(0); i < N; i++ {
   671  		a := sys.NewAdapter(i)
   672  		s, err := New(i, chainId, &Config{N: N, F: 1, BatchDurationNsec: 2000000000, BatchSizeBytes: 1, RequestTimeoutNsec: 20000000000}, a)
   673  		if err != nil {
   674  			t.Fatal(err)
   675  		}
   676  		repls = append(repls, s)
   677  		adapters = append(adapters, a)
   678  	}
   679  
   680  	phase := 1
   681  
   682  	// network outage after prepares are received
   683  	sys.filterFn = func(e testElem) (testElem, bool) {
   684  		if msg, ok := e.ev.(*testMsgEvent); ok {
   685  			if msg.src == msg.dst {
   686  				return e, true
   687  			}
   688  
   689  			switch phase {
   690  			case 1:
   691  				if p := msg.msg.GetPrepare(); p != nil && p.Seq.View == 0 {
   692  					return e, false
   693  				}
   694  			case 2:
   695  				if nv := msg.msg.GetNewView(); nv != nil {
   696  					phase = 3
   697  					return e, true
   698  				}
   699  				if msg.src == 3 || msg.dst == 3 {
   700  					return e, false
   701  				}
   702  				if c := msg.msg.GetCommit(); c != nil && c.Seq.View == 1 {
   703  					return e, false
   704  				}
   705  			case 3:
   706  				if msg.src == 3 || msg.dst == 3 {
   707  					return e, false
   708  				}
   709  			}
   710  		}
   711  		return e, true
   712  	}
   713  
   714  	connectAllForDefaultChain(sys)
   715  	r1 := []byte{1, 2, 3}
   716  	repls[0].Request(r1)
   717  	sys.Run()
   718  	phase = 2
   719  
   720  	r2 := []byte{5, 6, 7}
   721  	repls[1].Request(r2)
   722  	sys.Run()
   723  
   724  	for i, a := range adapters {
   725  		// 3 is disconnected
   726  		if i == 3 {
   727  			continue
   728  		}
   729  		if len(a.batches[chainId]) != 2 {
   730  			t.Fatalf("expected execution of 1 batches: %v", a.batches[chainId])
   731  		}
   732  		if !reflect.DeepEqual([][]byte{r1}, a.batches[chainId][0].Payloads) {
   733  			t.Error("wrong request executed first")
   734  		}
   735  		if !reflect.DeepEqual([][]byte{r2}, a.batches[chainId][1].Payloads) {
   736  			t.Error("wrong request executed second")
   737  		}
   738  	}
   739  }
   740  
   741  func TestRestart(t *testing.T) {
   742  	skipInShortMode(t)
   743  	N := lowN
   744  	sys := newTestSystem(N)
   745  	var repls []*SBFT
   746  	var adapters []*testSystemAdapter
   747  	for i := uint64(0); i < N; i++ {
   748  		a := sys.NewAdapter(i)
   749  		s, err := New(i, chainId, &Config{N: N, F: 1, BatchDurationNsec: 2000000000, BatchSizeBytes: 10, RequestTimeoutNsec: 20000000000}, a)
   750  		if err != nil {
   751  			t.Fatal(err)
   752  		}
   753  		repls = append(repls, s)
   754  		adapters = append(adapters, a)
   755  	}
   756  
   757  	connectAllForDefaultChain(sys)
   758  	// move to view 1
   759  	for _, r := range repls {
   760  		r.sendViewChange()
   761  	}
   762  	sys.Run()
   763  
   764  	r1 := []byte{1, 2, 3}
   765  	repls[0].Request(r1)
   766  	sys.Run()
   767  
   768  	testLog.Notice("restarting 0")
   769  	repls[0], _ = New(0, chainId, &Config{N: N, F: 1, BatchDurationNsec: 2000000000, BatchSizeBytes: 10, RequestTimeoutNsec: 20000000000}, adapters[0])
   770  	for _, a := range adapters {
   771  		if a.id != 0 {
   772  			a.receivers[chainId].Connection(0)
   773  			adapters[0].receivers[chainId].Connection(a.id)
   774  		}
   775  	}
   776  
   777  	r2 := []byte{3, 1, 2}
   778  	r3 := []byte{3, 5, 2}
   779  	repls[1].Request(r2)
   780  	repls[1].Request(r3)
   781  	sys.Run()
   782  	for _, a := range adapters {
   783  		if len(a.batches[chainId]) != 2 {
   784  			t.Fatalf("expected execution of 2 batches, %d got %v", a.id, a.batches)
   785  		}
   786  		if !reflect.DeepEqual([][]byte{r1}, a.batches[chainId][0].Payloads) {
   787  			t.Error("wrong request executed (1)")
   788  		}
   789  		if !reflect.DeepEqual([][]byte{r2, r3}, a.batches[chainId][1].Payloads) {
   790  			t.Error("wrong request executed (2)")
   791  		}
   792  	}
   793  }
   794  
   795  func TestAbdicatingPrimary(t *testing.T) {
   796  	skipInShortMode(t)
   797  	N := lowN
   798  	sys := newTestSystem(N)
   799  	var repls []*SBFT
   800  	var adapters []*testSystemAdapter
   801  	for i := uint64(0); i < N; i++ {
   802  		a := sys.NewAdapter(i)
   803  		s, err := New(i, chainId, &Config{N: N, F: 1, BatchDurationNsec: 2000000000, BatchSizeBytes: 10, RequestTimeoutNsec: 20000000000}, a)
   804  		if err != nil {
   805  			t.Fatal(err)
   806  		}
   807  		repls = append(repls, s)
   808  		adapters = append(adapters, a)
   809  	}
   810  
   811  	phase := 1
   812  	// Dropping all phase 1 msgs except requests and viewchange to 0
   813  	// (preprepare to primary 0 is automatically delivered)
   814  	sys.filterFn = func(e testElem) (testElem, bool) {
   815  		if phase == 1 {
   816  			if msg, ok := e.ev.(*testMsgEvent); ok {
   817  				if c := msg.msg.GetRequest(); c != nil {
   818  					return e, true
   819  				}
   820  				if c := msg.msg.GetViewChange(); c != nil && msg.dst == 0 {
   821  					return e, true
   822  				}
   823  				return e, false
   824  			}
   825  			return e, true
   826  		}
   827  		return e, true
   828  	}
   829  
   830  	connectAllForDefaultChain(sys)
   831  
   832  	r1 := []byte{1, 2, 3}
   833  	repls[0].Request(r1)
   834  	sys.Run()
   835  
   836  	phase = 2
   837  
   838  	testLog.Notice("TEST: restarting connections from 0")
   839  	for _, a := range adapters {
   840  		if a.id != 0 {
   841  			a.receivers[chainId].Connection(0)
   842  			adapters[0].receivers[chainId].Connection(a.id)
   843  		}
   844  	}
   845  
   846  	sys.Run()
   847  	for _, a := range adapters {
   848  		if len(a.batches[chainId]) != 1 {
   849  			t.Fatalf("expected execution of 1 batches, %d got %v", a.id, a.batches[chainId])
   850  		}
   851  	}
   852  }
   853  
   854  func TestRestartAfterPrepare(t *testing.T) {
   855  	skipInShortMode(t)
   856  	N := lowN
   857  	sys := newTestSystem(N)
   858  	var repls []*SBFT
   859  	var adapters []*testSystemAdapter
   860  	for i := uint64(0); i < N; i++ {
   861  		a := sys.NewAdapter(i)
   862  		s, err := New(i, chainId, &Config{N: N, F: 1, BatchDurationNsec: 2000000000, BatchSizeBytes: 10, RequestTimeoutNsec: 20000000000}, a)
   863  		if err != nil {
   864  			t.Fatal(err)
   865  		}
   866  		repls = append(repls, s)
   867  		adapters = append(adapters, a)
   868  	}
   869  
   870  	restarted := false
   871  
   872  	// network outage after prepares are received
   873  	sys.filterFn = func(e testElem) (testElem, bool) {
   874  		if msg, ok := e.ev.(*testMsgEvent); ok {
   875  			if msg.src == msg.dst || msg.src != 0 {
   876  				return e, true
   877  			}
   878  
   879  			if p := msg.msg.GetPrepare(); p != nil && p.Seq.Seq == 3 && !restarted {
   880  				restarted = true
   881  				testLog.Notice("restarting 0")
   882  				repls[0], _ = New(0, chainId, &Config{N: N, F: 1, BatchDurationNsec: 2000000000, BatchSizeBytes: 10, RequestTimeoutNsec: 20000000000}, adapters[0])
   883  				for _, a := range adapters {
   884  					if a.id != 0 {
   885  						a.receivers[chainId].Connection(0)
   886  						adapters[0].receivers[chainId].Connection(a.id)
   887  					}
   888  				}
   889  			}
   890  		}
   891  
   892  		return e, true
   893  	}
   894  
   895  	connectAllForDefaultChain(sys)
   896  	// move to view 1
   897  	for _, r := range repls {
   898  		r.sendViewChange()
   899  	}
   900  	sys.Run()
   901  
   902  	r1 := []byte{1, 2, 3}
   903  	repls[0].Request(r1)
   904  	sys.Run()
   905  
   906  	r2 := []byte{3, 1, 2}
   907  	r3 := []byte{3, 5, 2}
   908  	repls[1].Request(r2)
   909  	repls[1].Request(r3)
   910  	sys.Run()
   911  	for _, a := range adapters {
   912  		if len(a.batches[chainId]) != 2 {
   913  			t.Fatal("expected execution of 2 batches")
   914  		}
   915  		if !reflect.DeepEqual([][]byte{r1}, a.batches[chainId][0].Payloads) {
   916  			t.Error("wrong request executed (1)")
   917  		}
   918  		if !reflect.DeepEqual([][]byte{r2, r3}, a.batches[chainId][1].Payloads) {
   919  			t.Error("wrong request executed (2)")
   920  		}
   921  	}
   922  }
   923  
   924  func TestRestartAfterCommit(t *testing.T) {
   925  	skipInShortMode(t)
   926  	N := lowN
   927  	sys := newTestSystem(N)
   928  	var repls []*SBFT
   929  	var adapters []*testSystemAdapter
   930  	for i := uint64(0); i < N; i++ {
   931  		a := sys.NewAdapter(i)
   932  		s, err := New(i, chainId, &Config{N: N, F: 1, BatchDurationNsec: 2000000000, BatchSizeBytes: 10, RequestTimeoutNsec: 20000000000}, a)
   933  		if err != nil {
   934  			t.Fatal(err)
   935  		}
   936  		repls = append(repls, s)
   937  		adapters = append(adapters, a)
   938  	}
   939  
   940  	restarted := false
   941  
   942  	// network outage after prepares are received
   943  	sys.filterFn = func(e testElem) (testElem, bool) {
   944  		if msg, ok := e.ev.(*testMsgEvent); ok {
   945  			if msg.src == msg.dst || msg.src != 0 {
   946  				return e, true
   947  			}
   948  
   949  			if c := msg.msg.GetCommit(); c != nil && c.Seq.Seq == 3 && !restarted {
   950  				restarted = true
   951  				testLog.Notice("restarting 0")
   952  				repls[0], _ = New(0, chainId, &Config{N: N, F: 1, BatchDurationNsec: 2000000000, BatchSizeBytes: 10, RequestTimeoutNsec: 20000000000}, adapters[0])
   953  				for _, a := range adapters {
   954  					if a.id != 0 {
   955  						a.receivers[chainId].Connection(0)
   956  						adapters[0].receivers[chainId].Connection(a.id)
   957  					}
   958  				}
   959  			}
   960  		}
   961  
   962  		return e, true
   963  	}
   964  
   965  	connectAllForDefaultChain(sys)
   966  	// move to view 1
   967  	for _, r := range repls {
   968  		r.sendViewChange()
   969  	}
   970  	sys.Run()
   971  
   972  	r1 := []byte{1, 2, 3}
   973  	repls[0].Request(r1)
   974  	sys.Run()
   975  
   976  	r2 := []byte{3, 1, 2}
   977  	r3 := []byte{3, 5, 2}
   978  	repls[1].Request(r2)
   979  	repls[1].Request(r3)
   980  	sys.Run()
   981  	for _, a := range adapters {
   982  		if len(a.batches[chainId]) != 2 {
   983  			t.Fatal("expected execution of 2 batches")
   984  		}
   985  		if !reflect.DeepEqual([][]byte{r1}, a.batches[chainId][0].Payloads) {
   986  			t.Error("wrong request executed (1)")
   987  		}
   988  		if !reflect.DeepEqual([][]byte{r2, r3}, a.batches[chainId][1].Payloads) {
   989  			t.Error("wrong request executed (2)")
   990  		}
   991  	}
   992  }
   993  
   994  func TestRestartAfterCheckpoint(t *testing.T) {
   995  	skipInShortMode(t)
   996  	N := lowN
   997  	sys := newTestSystem(N)
   998  	var repls []*SBFT
   999  	var adapters []*testSystemAdapter
  1000  	for i := uint64(0); i < N; i++ {
  1001  		a := sys.NewAdapter(i)
  1002  		s, err := New(i, chainId, &Config{N: N, F: 1, BatchDurationNsec: 2000000000, BatchSizeBytes: 10, RequestTimeoutNsec: 20000000000}, a)
  1003  		if err != nil {
  1004  			t.Fatal(err)
  1005  		}
  1006  		repls = append(repls, s)
  1007  		adapters = append(adapters, a)
  1008  	}
  1009  
  1010  	restarted := false
  1011  
  1012  	// network outage after prepares are received
  1013  	sys.filterFn = func(e testElem) (testElem, bool) {
  1014  		if msg, ok := e.ev.(*testMsgEvent); ok {
  1015  			if msg.src == msg.dst || msg.src != 0 {
  1016  				return e, true
  1017  			}
  1018  
  1019  			if c := msg.msg.GetCheckpoint(); c != nil && c.Seq == 3 && !restarted {
  1020  				restarted = true
  1021  				testLog.Notice("restarting 0")
  1022  				repls[0], _ = New(0, chainId, &Config{N: N, F: 1, BatchDurationNsec: 2000000000, BatchSizeBytes: 10, RequestTimeoutNsec: 20000000000}, adapters[0])
  1023  				for _, a := range adapters {
  1024  					if a.id != 0 {
  1025  						a.receivers[chainId].Connection(0)
  1026  						adapters[0].receivers[chainId].Connection(a.id)
  1027  					}
  1028  				}
  1029  			}
  1030  		}
  1031  
  1032  		return e, true
  1033  	}
  1034  
  1035  	connectAllForDefaultChain(sys)
  1036  	// move to view 1
  1037  	for _, r := range repls {
  1038  		r.sendViewChange()
  1039  	}
  1040  	sys.Run()
  1041  
  1042  	r1 := []byte{1, 2, 3}
  1043  	repls[0].Request(r1)
  1044  	sys.Run()
  1045  
  1046  	r2 := []byte{3, 1, 2}
  1047  	r3 := []byte{3, 5, 2}
  1048  	repls[1].Request(r2)
  1049  	repls[1].Request(r3)
  1050  	sys.Run()
  1051  	for _, a := range adapters {
  1052  		if len(a.batches[chainId]) != 2 {
  1053  			t.Fatal("expected execution of 2 batches")
  1054  		}
  1055  		if !reflect.DeepEqual([][]byte{r1}, a.batches[chainId][0].Payloads) {
  1056  			t.Error("wrong request executed (1)")
  1057  		}
  1058  		if !reflect.DeepEqual([][]byte{r2, r3}, a.batches[chainId][1].Payloads) {
  1059  			t.Error("wrong request executed (2)")
  1060  		}
  1061  	}
  1062  }
  1063  
  1064  func TestErroneousViewChange(t *testing.T) {
  1065  	skipInShortMode(t)
  1066  	N := lowN
  1067  	sys := newTestSystem(N)
  1068  	var repls []*SBFT
  1069  	var adapters []*testSystemAdapter
  1070  	for i := uint64(0); i < N; i++ {
  1071  		a := sys.NewAdapter(i)
  1072  		s, err := New(i, chainId, &Config{N: N, F: 1, BatchDurationNsec: 2000000000, BatchSizeBytes: 10, RequestTimeoutNsec: 20000000000}, a)
  1073  		if err != nil {
  1074  			t.Fatal(err)
  1075  		}
  1076  		repls = append(repls, s)
  1077  		adapters = append(adapters, a)
  1078  	}
  1079  
  1080  	restarted := false
  1081  
  1082  	// network outage after prepares are received
  1083  	sys.filterFn = func(e testElem) (testElem, bool) {
  1084  		if msg, ok := e.ev.(*testMsgEvent); ok {
  1085  			if msg.src == msg.dst || msg.src != 0 {
  1086  				return e, true
  1087  			}
  1088  
  1089  			if c := msg.msg.GetCheckpoint(); c != nil && c.Seq == 3 && !restarted {
  1090  				restarted = true
  1091  				testLog.Notice("restarting 0")
  1092  				repls[0], _ = New(0, chainId, &Config{N: N, F: 1, BatchDurationNsec: 2000000000, BatchSizeBytes: 10, RequestTimeoutNsec: 20000000000}, adapters[0])
  1093  				for _, a := range adapters {
  1094  					if a.id != 0 {
  1095  						a.receivers[chainId].Connection(0)
  1096  						adapters[0].receivers[chainId].Connection(a.id)
  1097  					}
  1098  				}
  1099  			}
  1100  		}
  1101  
  1102  		return e, true
  1103  	}
  1104  
  1105  	// iteration order here is essential to trigger the bug
  1106  	outer := []uint64{2, 3, 0, 1}
  1107  	inner := []uint64{0, 1, 2, 3}
  1108  	for _, i := range outer {
  1109  		a, ok := sys.adapters[i]
  1110  		if !ok {
  1111  			continue
  1112  		}
  1113  
  1114  		for _, j := range inner {
  1115  			b, ok := sys.adapters[j]
  1116  			if !ok {
  1117  				continue
  1118  			}
  1119  			if a.id != b.id {
  1120  				a.receivers[chainId].Connection(b.id)
  1121  			}
  1122  		}
  1123  	}
  1124  	sys.Run()
  1125  
  1126  	// move to view 1
  1127  	for _, r := range repls {
  1128  		r.sendViewChange()
  1129  	}
  1130  	sys.Run()
  1131  
  1132  	r1 := []byte{1, 2, 3}
  1133  	repls[0].Request(r1)
  1134  	sys.Run()
  1135  
  1136  	r2 := []byte{3, 1, 2}
  1137  	r3 := []byte{3, 5, 2}
  1138  	repls[1].Request(r2)
  1139  	repls[1].Request(r3)
  1140  	sys.Run()
  1141  	for _, a := range adapters {
  1142  		if len(a.batches[chainId]) != 2 {
  1143  			t.Fatal("expected execution of 2 batches")
  1144  		}
  1145  		if !reflect.DeepEqual([][]byte{r1}, a.batches[chainId][0].Payloads) {
  1146  			t.Error("wrong request executed (1)")
  1147  		}
  1148  		if !reflect.DeepEqual([][]byte{r2, r3}, a.batches[chainId][1].Payloads) {
  1149  			t.Error("wrong request executed (2)")
  1150  		}
  1151  	}
  1152  }
  1153  
  1154  func TestRestartMissedViewChange(t *testing.T) {
  1155  	skipInShortMode(t)
  1156  	N := lowN
  1157  	sys := newTestSystem(N)
  1158  	var repls []*SBFT
  1159  	var adapters []*testSystemAdapter
  1160  	for i := uint64(0); i < N; i++ {
  1161  		a := sys.NewAdapter(i)
  1162  		s, err := New(i, chainId, &Config{N: N, F: 1, BatchDurationNsec: 2000000000, BatchSizeBytes: 10, RequestTimeoutNsec: 20000000000}, a)
  1163  		if err != nil {
  1164  			t.Fatal(err)
  1165  		}
  1166  		repls = append(repls, s)
  1167  		adapters = append(adapters, a)
  1168  	}
  1169  
  1170  	disconnect := false
  1171  
  1172  	// network outage after prepares are received
  1173  	sys.filterFn = func(e testElem) (testElem, bool) {
  1174  		if msg, ok := e.ev.(*testMsgEvent); ok {
  1175  			if disconnect && (msg.src == 0 || msg.dst == 0) {
  1176  				return e, false
  1177  			}
  1178  		}
  1179  
  1180  		return e, true
  1181  	}
  1182  
  1183  	connectAllForDefaultChain(sys)
  1184  
  1185  	r1 := []byte{1, 2, 3}
  1186  	repls[0].Request(r1)
  1187  	sys.Run()
  1188  
  1189  	disconnect = true
  1190  	// move to view 1
  1191  	for _, r := range repls {
  1192  		if r.id != 0 {
  1193  			r.sendViewChange()
  1194  		}
  1195  	}
  1196  	sys.Run()
  1197  
  1198  	r2 := []byte{3, 1, 2}
  1199  	repls[1].Request(r2)
  1200  	sys.Run()
  1201  
  1202  	disconnect = false
  1203  	testLog.Notice("restarting 0")
  1204  	repls[0], _ = New(0, chainId, &Config{N: N, F: 1, BatchDurationNsec: 2000000000, BatchSizeBytes: 10, RequestTimeoutNsec: 20000000000}, adapters[0])
  1205  	for _, a := range adapters {
  1206  		if a.id != 0 {
  1207  			a.receivers[chainId].Connection(0)
  1208  			adapters[0].receivers[chainId].Connection(a.id)
  1209  		}
  1210  	}
  1211  
  1212  	r3 := []byte{3, 5, 2}
  1213  	repls[1].Request(r3)
  1214  
  1215  	sys.Run()
  1216  
  1217  	for _, a := range adapters {
  1218  		if len(a.batches[chainId]) == 0 {
  1219  			t.Fatalf("expected execution of some batches on %d", a.id)
  1220  		}
  1221  
  1222  		if !reflect.DeepEqual([][]byte{r3}, a.batches[chainId][len(a.batches[chainId])-1].Payloads) {
  1223  			t.Errorf("wrong request executed on %d: %v", a.id, a.batches[chainId][2])
  1224  		}
  1225  	}
  1226  }
  1227  
  1228  func TestFullBacklog(t *testing.T) {
  1229  	skipInShortMode(t)
  1230  	N := lowN
  1231  	BS := uint64(1)
  1232  	sys := newTestSystemWithBatchSize(N, BS)
  1233  	var repls []*SBFT
  1234  	var adapters []*testSystemAdapter
  1235  	for i := uint64(0); i < N; i++ {
  1236  		a := sys.NewAdapter(i)
  1237  		s, err := New(i, chainId, &Config{N: N, F: 1, BatchDurationNsec: 2000000000, BatchSizeBytes: BS, RequestTimeoutNsec: 20000000000}, a)
  1238  		if err != nil {
  1239  			t.Fatal(err)
  1240  		}
  1241  		repls = append(repls, s)
  1242  		adapters = append(adapters, a)
  1243  	}
  1244  
  1245  	r1 := []byte{1, 2, 3}
  1246  
  1247  	connectAllForDefaultChain(sys)
  1248  	sys.enqueue(200*time.Millisecond, &testTimer{id: 999, tf: func() {
  1249  		repls[0].sys.Send(chainId, &Msg{&Msg_Prepare{&Subject{Seq: &SeqView{Seq: 100}}}}, 1)
  1250  	}})
  1251  	for i := 0; i < 10; i++ {
  1252  		sys.enqueue(time.Duration(i)*100*time.Millisecond, &testTimer{id: 999, tf: func() {
  1253  			repls[0].Request(r1)
  1254  		}})
  1255  	}
  1256  	sys.Run()
  1257  	if len(repls[1].replicaState[2].backLog) > 4*3 {
  1258  		t.Errorf("backlog too long: %d", len(repls[1].replicaState[0].backLog))
  1259  	}
  1260  	for _, a := range adapters {
  1261  		if len(a.batches[chainId]) == 0 {
  1262  			t.Fatalf("expected execution of batches on %d", a.id)
  1263  		}
  1264  		bh := a.batches[chainId][len(a.batches[chainId])-1].DecodeHeader()
  1265  		if bh.Seq != 10 {
  1266  			t.Errorf("wrong request executed on %d: %v", a.id, bh)
  1267  		}
  1268  	}
  1269  }
  1270  
  1271  func TestHelloMsg(t *testing.T) {
  1272  	skipInShortMode(t)
  1273  	N := lowN
  1274  	BS := uint64(1)
  1275  	sys := newTestSystemWOTimersWithBatchSize(N, BS)
  1276  	var repls []*SBFT
  1277  	var adapters []*testSystemAdapter
  1278  	for i := uint64(0); i < N; i++ {
  1279  		a := sys.NewAdapter(i)
  1280  		s, err := New(i, chainId, &Config{N: N, F: 1, BatchDurationNsec: 2000000000, BatchSizeBytes: uint64(BS), RequestTimeoutNsec: 20000000000}, a)
  1281  		if err != nil {
  1282  			t.Fatal(err)
  1283  		}
  1284  		repls = append(repls, s)
  1285  		adapters = append(adapters, a)
  1286  	}
  1287  
  1288  	phase := 1
  1289  
  1290  	// We are going to deliver only pre-prepare of the first request to replica 1
  1291  	// other messages pertaining to first request, destined to 1 will be dropped
  1292  	sys.filterFn = func(e testElem) (testElem, bool) {
  1293  		if msg, ok := e.ev.(*testMsgEvent); ok {
  1294  			if msg.dst == 1 {
  1295  				c := msg.msg.GetPreprepare()
  1296  				if c != nil && c.Seq.View == 0 && phase == 1 {
  1297  					return e, true // letting the first pre-prepare be delivered to 1
  1298  				}
  1299  				if phase > 1 {
  1300  					return e, true //letting msgs outside phase 1 through
  1301  				}
  1302  				return e, false //dropping other phase 1 msgs
  1303  			}
  1304  		}
  1305  		return e, true
  1306  	}
  1307  
  1308  	connectAllForDefaultChain(sys)
  1309  	r1 := []byte{1, 2, 3}
  1310  	repls[0].Request(r1)
  1311  	sys.Run()
  1312  
  1313  	phase = 2 //start delivering msgs to replica 1
  1314  
  1315  	testLog.Notice("restarting replica 1")
  1316  	repls[1], _ = New(1, chainId, &Config{N: N, F: 1, BatchDurationNsec: 2000000000, BatchSizeBytes: BS, RequestTimeoutNsec: 20000000000}, adapters[1])
  1317  	for _, a := range adapters {
  1318  		if a.id != 1 {
  1319  			a.receivers[chainId].Connection(1)
  1320  			adapters[1].receivers[chainId].Connection(a.id)
  1321  		}
  1322  	}
  1323  
  1324  	sys.Run()
  1325  
  1326  	phase = 3
  1327  
  1328  	r3 := []byte{3, 5, 2}
  1329  	repls[1].Request(r3)
  1330  	sys.Run()
  1331  
  1332  	for i, a := range adapters {
  1333  		if len(a.batches[chainId]) != 2 {
  1334  			t.Fatalf("expected execution of 2 batches but executed %d     %d", len(a.batches[chainId]), i)
  1335  		}
  1336  	}
  1337  }
  1338  
  1339  func TestViewChangeTimer(t *testing.T) {
  1340  	skipInShortMode(t)
  1341  	N := lowN
  1342  	sys := newTestSystem(N)
  1343  	var repls []*SBFT
  1344  	var adapters []*testSystemAdapter
  1345  	for i := uint64(0); i < N; i++ {
  1346  		a := sys.NewAdapter(i)
  1347  		s, err := New(i, chainId, &Config{N: N, F: 1, BatchDurationNsec: 2000000000, BatchSizeBytes: 10, RequestTimeoutNsec: 20000000000}, a)
  1348  		if err != nil {
  1349  			t.Fatal(err)
  1350  		}
  1351  		repls = append(repls, s)
  1352  		adapters = append(adapters, a)
  1353  	}
  1354  
  1355  	phase := 1
  1356  
  1357  	// network outage after prepares are received
  1358  	sys.filterFn = func(e testElem) (testElem, bool) {
  1359  		if msg, ok := e.ev.(*testMsgEvent); ok {
  1360  			if msg.dst == msg.src {
  1361  				return e, true
  1362  			} else if msg.src == 1 && phase == 2 {
  1363  				return e, false
  1364  			}
  1365  			testLog.Debugf("passing msg from %d to %d, phase %d", msg.src, msg.dst, phase)
  1366  		}
  1367  
  1368  		return e, true
  1369  	}
  1370  
  1371  	connectAllForDefaultChain(sys)
  1372  	r1 := []byte{1, 2, 3}
  1373  	repls[0].Request(r1)
  1374  
  1375  	repls[3].sendViewChange()
  1376  
  1377  	sys.enqueue(10*time.Minute, &testTimer{id: 999, tf: func() {
  1378  		if repls[3].view != 1 {
  1379  			t.Fatalf("expected view not to advance past 1, we are in %d", repls[3].view)
  1380  		}
  1381  	}})
  1382  
  1383  	sys.enqueue(11*time.Minute, &testTimer{id: 999, tf: func() {
  1384  		phase = 2
  1385  		repls[2].sendViewChange()
  1386  	}})
  1387  
  1388  	sys.enqueue(12*time.Minute, &testTimer{id: 999, tf: func() {
  1389  		if repls[3].view != 2 {
  1390  			t.Fatalf("expected view not to advance past 2, 3 is in %d", repls[3].view)
  1391  		}
  1392  	}})
  1393  
  1394  	sys.enqueue(20*time.Minute, &testTimer{id: 999, tf: func() {
  1395  		for _, r := range repls {
  1396  			if r.view > 4 {
  1397  				t.Fatalf("expected view not to advance too much, we are in %d", r.view)
  1398  			}
  1399  		}
  1400  	}})
  1401  
  1402  	sys.Run()
  1403  	r2 := []byte{3, 1, 2}
  1404  	r3 := []byte{3, 5, 2}
  1405  	repls[2].Request(r2)
  1406  	repls[2].Request(r3)
  1407  	sys.Run()
  1408  	for _, a := range adapters {
  1409  		if len(a.batches[chainId]) != 2 {
  1410  			t.Fatalf("%d: expected execution of 2 batches: %v", a.id, a.batches[chainId])
  1411  		}
  1412  		if a.id != 3 {
  1413  			if !reflect.DeepEqual([][]byte{r1}, a.batches[chainId][0].Payloads) {
  1414  				t.Errorf("%d: wrong request executed (1): %v", a.id, a.batches[chainId])
  1415  			}
  1416  		}
  1417  		if !reflect.DeepEqual([][]byte{r2, r3}, a.batches[chainId][1].Payloads) {
  1418  			t.Errorf("%d: wrong request executed (2): %v", a.id, a.batches[chainId])
  1419  		}
  1420  	}
  1421  }
  1422  
  1423  func TestResendViewChange(t *testing.T) {
  1424  	skipInShortMode(t)
  1425  	N := lowN
  1426  	sys := newTestSystem(N)
  1427  	var repls []*SBFT
  1428  	var adapters []*testSystemAdapter
  1429  	for i := uint64(0); i < N; i++ {
  1430  		a := sys.NewAdapter(i)
  1431  		s, err := New(i, chainId, &Config{N: N, F: 1, BatchDurationNsec: 2000000000, BatchSizeBytes: 10, RequestTimeoutNsec: 20000000000}, a)
  1432  		if err != nil {
  1433  			t.Fatal(err)
  1434  		}
  1435  		repls = append(repls, s)
  1436  		adapters = append(adapters, a)
  1437  	}
  1438  
  1439  	phase := make(map[uint64]int)
  1440  
  1441  	// prevent first view change from being delivered
  1442  	sys.filterFn = func(e testElem) (testElem, bool) {
  1443  		if msg, ok := e.ev.(*testMsgEvent); ok {
  1444  			if msg.dst == msg.src {
  1445  				return e, true
  1446  			} else if phase[msg.src] == 0 && msg.msg.GetViewChange() != nil {
  1447  				return e, false
  1448  			} else if msg.msg.GetHello() != nil {
  1449  				phase[msg.src] = 1
  1450  			}
  1451  		}
  1452  
  1453  		return e, true
  1454  	}
  1455  
  1456  	for _, r := range repls {
  1457  		r.sendViewChange()
  1458  	}
  1459  	sys.Run()
  1460  
  1461  	connectAllForDefaultChain(sys)
  1462  	r1 := []byte{1, 2, 3}
  1463  	repls[0].Request(r1)
  1464  	sys.Run()
  1465  	r2 := []byte{3, 1, 2}
  1466  	r3 := []byte{3, 5, 2}
  1467  	repls[1].Request(r2)
  1468  	repls[1].Request(r3)
  1469  	sys.Run()
  1470  	for _, a := range adapters {
  1471  		if len(a.batches[chainId]) != 2 {
  1472  			t.Fatal("expected execution of 2 batches")
  1473  		}
  1474  		if !reflect.DeepEqual([][]byte{r1}, a.batches[chainId][0].Payloads) {
  1475  			t.Error("wrong request executed (1)")
  1476  		}
  1477  		if !reflect.DeepEqual([][]byte{r2, r3}, a.batches[chainId][1].Payloads) {
  1478  			t.Error("wrong request executed (2)")
  1479  		}
  1480  	}
  1481  }
  1482  
  1483  func TestTenReplicasBombedWithRequests(t *testing.T) {
  1484  	skipInShortMode(t)
  1485  	N := highN
  1486  	requestNumber := 11
  1487  	sys := newTestSystem(N)
  1488  	var repls []*SBFT
  1489  	var adapters []*testSystemAdapter
  1490  	for i := uint64(0); i < N; i++ {
  1491  		a := sys.NewAdapter(i)
  1492  		s, err := New(i, chainId, &Config{N: N, F: 3, BatchDurationNsec: 2000000000, BatchSizeBytes: 3, RequestTimeoutNsec: 20000000000}, a)
  1493  		if err != nil {
  1494  			t.Fatal(err)
  1495  		}
  1496  		repls = append(repls, s)
  1497  		adapters = append(adapters, a)
  1498  	}
  1499  
  1500  	connectAllForDefaultChain(sys)
  1501  	for i := 0; i < requestNumber; i++ {
  1502  		r := []byte{byte(i), 2, 3}
  1503  		repls[2].Request(r)
  1504  	}
  1505  	sys.Run()
  1506  	for _, a := range adapters {
  1507  		i := 0
  1508  		for _, b := range a.batches[chainId] {
  1509  			i = i + len(b.Payloads)
  1510  		}
  1511  		if i != requestNumber {
  1512  			t.Fatalf("expected execution of %d requests but: %d", requestNumber, i)
  1513  		}
  1514  	}
  1515  }