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

     1  package bft_test
     2  
     3  import (
     4  	"github.com/annchain/OG/consensus/bft"
     5  	"github.com/sirupsen/logrus"
     6  )
     7  
     8  type ByzantineFeatures struct {
     9  	SilenceProposal  bool
    10  	SilencePreVote   bool
    11  	SilencePreCommit bool
    12  	BadProposal      bool
    13  	BadPreVote       bool
    14  	BadPreCommit     bool
    15  }
    16  
    17  type dummyByzantineBftPeerCommunicator struct {
    18  	Myid              int
    19  	PeerPipeIns       []chan *bft.BftMessageEvent
    20  	pipeIn            chan *bft.BftMessageEvent
    21  	pipeOut           chan *bft.BftMessageEvent
    22  	ByzantineFeatures ByzantineFeatures
    23  }
    24  
    25  func (d *dummyByzantineBftPeerCommunicator) HandleIncomingMessage(msgEvent *bft.BftMessageEvent) {
    26  	d.pipeIn <- msgEvent
    27  }
    28  
    29  func (d *dummyByzantineBftPeerCommunicator) Run() {
    30  	go func() {
    31  		for {
    32  			v := <-d.pipeIn
    33  			//vv := v.Message.(bft.BftMessage)
    34  			d.pipeOut <- v
    35  		}
    36  	}()
    37  }
    38  
    39  func (d *dummyByzantineBftPeerCommunicator) Broadcast(msg bft.BftMessage, peers []bft.BftPeer) {
    40  	msg, toSend := d.doBadThings(msg)
    41  	if !toSend {
    42  		// don't send it
    43  		logrus.WithFields(logrus.Fields{
    44  			"IM---BAD": d.Myid,
    45  			"from":     d.Myid,
    46  			"msg":      msg.String(),
    47  		}).Info("Eat broadcast message")
    48  		return
    49  	}
    50  	for _, peer := range peers {
    51  		go func(peer bft.BftPeer) {
    52  			d.PeerPipeIns[peer.Id] <- &bft.BftMessageEvent{
    53  				Message: msg,
    54  				Peer:    peer,
    55  			}
    56  		}(peer)
    57  	}
    58  }
    59  
    60  func (d *dummyByzantineBftPeerCommunicator) Unicast(msg bft.BftMessage, peer bft.BftPeer) {
    61  	msg, toSend := d.doBadThings(msg)
    62  	if !toSend {
    63  		// don't send it
    64  		logrus.WithFields(logrus.Fields{
    65  			"IM---BAD": d.Myid,
    66  			"from":     d.Myid,
    67  			"to":       peer.Id,
    68  			"msg":      msg.String(),
    69  		}).Info("Eat unicast message")
    70  		return
    71  	}
    72  	go func() {
    73  		d.PeerPipeIns[peer.Id] <- &bft.BftMessageEvent{
    74  			Message: msg,
    75  			Peer:    peer,
    76  		}
    77  	}()
    78  }
    79  
    80  func (d *dummyByzantineBftPeerCommunicator) GetPipeIn() chan *bft.BftMessageEvent {
    81  	return d.pipeIn
    82  }
    83  
    84  func (d *dummyByzantineBftPeerCommunicator) GetPipeOut() chan *bft.BftMessageEvent {
    85  	return d.pipeOut
    86  }
    87  
    88  func NewDummyByzantineBftPeerCommunicator(myid int, incoming chan *bft.BftMessageEvent, peers []chan *bft.BftMessageEvent,
    89  	byzantineFeatures ByzantineFeatures) *dummyByzantineBftPeerCommunicator {
    90  	d := &dummyByzantineBftPeerCommunicator{
    91  		PeerPipeIns:       peers,
    92  		Myid:              myid,
    93  		pipeIn:            incoming,
    94  		pipeOut:           make(chan *bft.BftMessageEvent),
    95  		ByzantineFeatures: byzantineFeatures,
    96  	}
    97  	return d
    98  }
    99  
   100  func (p *dummyByzantineBftPeerCommunicator) doBadThings(msg bft.BftMessage) (updatedMessage bft.BftMessage, toSend bool) {
   101  	updatedMessage = msg
   102  	toSend = true
   103  	switch msg.GetType() {
   104  	case bft.BftMessageTypeProposal:
   105  		if p.ByzantineFeatures.SilenceProposal {
   106  			toSend = false
   107  		} else if p.ByzantineFeatures.BadProposal {
   108  			v := updatedMessage.(*bft.BftMessageProposal)
   109  			v.HeightRound.Round++
   110  			updatedMessage = v
   111  		}
   112  
   113  	case bft.BftMessageTypePreVote:
   114  		if p.ByzantineFeatures.SilencePreVote {
   115  			toSend = false
   116  		} else if p.ByzantineFeatures.BadPreVote {
   117  			v := updatedMessage.(*bft.BftMessagePreVote)
   118  			v.HeightRound.Round++
   119  			updatedMessage = v
   120  		}
   121  	case bft.BftMessageTypePreCommit:
   122  		if p.ByzantineFeatures.SilencePreCommit {
   123  			toSend = false
   124  		} else if p.ByzantineFeatures.BadPreCommit {
   125  			v := updatedMessage.(*bft.BftMessagePreCommit)
   126  			v.HeightRound.Round++
   127  			updatedMessage = v
   128  		}
   129  
   130  	}
   131  	return
   132  }