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 }