github.com/project-88388/tendermint-v0.34.14-terra.2@v1.0.0/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  }