github.com/noirx94/tendermintmp@v0.0.1/behaviour/reporter.go (about) 1 package behaviour 2 3 import ( 4 "errors" 5 6 tmsync "github.com/tendermint/tendermint/libs/sync" 7 "github.com/tendermint/tendermint/p2p" 8 ) 9 10 // Reporter provides an interface for reactors to report the behaviour 11 // of peers synchronously to other components. 12 type Reporter interface { 13 Report(behaviour PeerBehaviour) error 14 } 15 16 // SwitchReporter reports peer behaviour to an internal Switch. 17 type SwitchReporter struct { 18 sw *p2p.Switch 19 } 20 21 // NewSwitchReporter return a new SwitchReporter instance which wraps the Switch. 22 func NewSwitchReporter(sw *p2p.Switch) *SwitchReporter { 23 return &SwitchReporter{ 24 sw: sw, 25 } 26 } 27 28 // Report reports the behaviour of a peer to the Switch. 29 func (spbr *SwitchReporter) Report(behaviour PeerBehaviour) error { 30 peer := spbr.sw.Peers().Get(behaviour.peerID) 31 if peer == nil { 32 return errors.New("peer not found") 33 } 34 35 switch reason := behaviour.reason.(type) { 36 case consensusVote, blockPart: 37 spbr.sw.MarkPeerAsGood(peer) 38 case badMessage: 39 spbr.sw.StopPeerForError(peer, reason.explanation) 40 case messageOutOfOrder: 41 spbr.sw.StopPeerForError(peer, reason.explanation) 42 default: 43 return errors.New("unknown reason reported") 44 } 45 46 return nil 47 } 48 49 // MockReporter is a concrete implementation of the Reporter 50 // interface used in reactor tests to ensure reactors report the correct 51 // behaviour in manufactured scenarios. 52 type MockReporter struct { 53 mtx tmsync.RWMutex 54 pb map[p2p.ID][]PeerBehaviour 55 } 56 57 // NewMockReporter returns a Reporter which records all reported 58 // behaviours in memory. 59 func NewMockReporter() *MockReporter { 60 return &MockReporter{ 61 pb: map[p2p.ID][]PeerBehaviour{}, 62 } 63 } 64 65 // Report stores the PeerBehaviour produced by the peer identified by peerID. 66 func (mpbr *MockReporter) Report(behaviour PeerBehaviour) error { 67 mpbr.mtx.Lock() 68 defer mpbr.mtx.Unlock() 69 mpbr.pb[behaviour.peerID] = append(mpbr.pb[behaviour.peerID], behaviour) 70 71 return nil 72 } 73 74 // GetBehaviours returns all behaviours reported on the peer identified by peerID. 75 func (mpbr *MockReporter) GetBehaviours(peerID p2p.ID) []PeerBehaviour { 76 mpbr.mtx.RLock() 77 defer mpbr.mtx.RUnlock() 78 if items, ok := mpbr.pb[peerID]; ok { 79 result := make([]PeerBehaviour, len(items)) 80 copy(result, items) 81 82 return result 83 } 84 85 return []PeerBehaviour{} 86 }