github.com/annchain/OG@v0.0.9/consensus/bft_test/client_test.go (about)

     1  // Copyright © 2019 Annchain Authors <EMAIL ADDRESS>
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  package bft_test
    15  
    16  import (
    17  	"fmt"
    18  	"github.com/annchain/OG/consensus/bft"
    19  	"github.com/sirupsen/logrus"
    20  	"runtime"
    21  	"testing"
    22  	"time"
    23  )
    24  
    25  var BlockTime = time.Millisecond * 1
    26  
    27  func init() {
    28  	Formatter := new(logrus.TextFormatter)
    29  	//Formatter.ForceColors = false
    30  	Formatter.DisableColors = true
    31  	Formatter.TimestampFormat = "15:04:05.000000"
    32  	Formatter.FullTimestamp = true
    33  	logrus.SetLevel(logrus.DebugLevel)
    34  	logrus.SetFormatter(Formatter)
    35  	//logrus.SetReportCaller(true)
    36  
    37  	//filenameHook := filename.NewHook()
    38  	//filenameHook.Field = "line"
    39  	//logrus.AddHook(filenameHook)
    40  }
    41  
    42  func setupPeers(good int, bad int, bf ByzantineFeatures) []bft.BftPartner {
    43  	pg := &dummyProposalGenerator{}
    44  	pv := &dummyProposalValidator{}
    45  	dm := &dummyDecisionMaker{}
    46  
    47  	var peers []bft.BftPartner
    48  	var peerChans []chan *bft.BftMessageEvent
    49  	var peerInfo []bft.BftPeer
    50  
    51  	total := good + bad
    52  	i := 0
    53  
    54  	// prepare pipeIn channels
    55  	for ; i < total; i++ {
    56  		peerChans = append(peerChans, make(chan *bft.BftMessageEvent, 5))
    57  	}
    58  
    59  	// building communication channels
    60  	for i = 0; i < good; i++ {
    61  		peerInfo = append(peerInfo, bft.BftPeer{Id: i})
    62  	}
    63  	for ; i < total; i++ {
    64  		peerInfo = append(peerInfo, bft.BftPeer{Id: i})
    65  	}
    66  	for i = 0; i < good; i++ {
    67  		pc := NewLocalBftPeerCommunicator(i, peerChans[i], peerChans)
    68  		pc.Run()
    69  
    70  		peer := bft.NewDefaultBFTPartner(total, i, BlockTime, pc, pc, pg, pv, dm, peerInfo)
    71  
    72  		peers = append(peers, peer)
    73  	}
    74  
    75  	for ; i < total; i++ {
    76  		pc := NewDummyByzantineBftPeerCommunicator(i, peerChans[i], peerChans, bf)
    77  		pc.Run()
    78  		peer := bft.NewDefaultBFTPartner(total, i, BlockTime, pc, pc, pg, pv, dm, peerInfo)
    79  		peer.ProposalGenerator = pg
    80  		peer.ProposalValidator = pv
    81  		peer.DecisionMaker = dm
    82  		peers = append(peers, peer)
    83  
    84  	}
    85  	// build known peers
    86  	for i = 0; i < total; i++ {
    87  		peer := peers[i]
    88  		switch peer.(type) {
    89  		case *bft.DefaultBftPartner:
    90  			peer.(*bft.DefaultBftPartner).BftStatus.Peers = peerInfo
    91  		default:
    92  			panic("not supported")
    93  		}
    94  
    95  	}
    96  	return peers
    97  }
    98  
    99  func start(peers []bft.BftPartner, second int) {
   100  	logrus.Info("starting")
   101  	for _, peer := range peers {
   102  		peer.Start()
   103  	}
   104  	time.Sleep(time.Second * 2)
   105  	logrus.Info("starting new era")
   106  	for _, peer := range peers {
   107  		go peer.StartNewEra(0, 0)
   108  		break
   109  	}
   110  	time.Sleep(time.Second * time.Duration(second))
   111  
   112  	joinAllPeers(peers)
   113  }
   114  
   115  func joinAllPeers(peers []bft.BftPartner) {
   116  	for {
   117  		time.Sleep(time.Second * 2)
   118  		for _, peer := range peers {
   119  			peer.Stop()
   120  		}
   121  		fmt.Println(runtime.NumGoroutine())
   122  		return
   123  	}
   124  }
   125  
   126  func TestAllNonByzantine(t *testing.T) {
   127  	peers := setupPeers(4, 0, ByzantineFeatures{})
   128  	start(peers, 30)
   129  }
   130  
   131  func TestByzantineButOK(t *testing.T) {
   132  	peers := setupPeers(3, 1, ByzantineFeatures{
   133  		SilenceProposal:  true,
   134  		SilencePreVote:   true,
   135  		SilencePreCommit: true,
   136  	})
   137  	start(peers, 60)
   138  }
   139  
   140  func TestByzantineNotOK(t *testing.T) {
   141  	peers := setupPeers(2, 2, ByzantineFeatures{
   142  		SilenceProposal:  true,
   143  		SilencePreVote:   true,
   144  		SilencePreCommit: true,
   145  	})
   146  	start(peers, 60)
   147  }
   148  
   149  func TestBadByzantineOK(t *testing.T) {
   150  	peers := setupPeers(2, 2, ByzantineFeatures{
   151  		BadPreCommit: true,
   152  		BadPreVote:   true,
   153  		BadProposal:  true,
   154  	})
   155  	start(peers, 60)
   156  }
   157  
   158  func TestManyBadByzantineOK(t *testing.T) {
   159  	peers := setupPeers(15, 7, ByzantineFeatures{
   160  		BadPreCommit: true,
   161  		BadPreVote:   true,
   162  		BadProposal:  true,
   163  	})
   164  	start(peers, 60)
   165  }
   166  
   167  func TestGreatManyBadByzantineOK(t *testing.T) {
   168  	peers := setupPeers(201, 100, ByzantineFeatures{
   169  		BadPreCommit: true,
   170  		BadPreVote:   true,
   171  		BadProposal:  true,
   172  	})
   173  	start(peers, 60)
   174  }
   175  
   176  func TestByzantineButOKBUG(t *testing.T) {
   177  	peers := setupPeers(3, 3, ByzantineFeatures{
   178  		SilenceProposal:  true,
   179  		SilencePreVote:   true,
   180  		SilencePreCommit: true,
   181  	})
   182  	start(peers, 60)
   183  }