github.com/hyperledger/burrow@v0.34.5-0.20220512172541-77f09336001d/consensus/abci/peers_filter.go (about)

     1  package abci
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	"github.com/hyperledger/burrow/consensus/tendermint/codes"
     8  	abciTypes "github.com/tendermint/tendermint/abci/types"
     9  )
    10  
    11  const (
    12  	peersFilterQueryPath = "/p2p/filter/"
    13  )
    14  
    15  func isPeersFilterQuery(query *abciTypes.RequestQuery) bool {
    16  	return strings.HasPrefix(query.Path, peersFilterQueryPath)
    17  }
    18  
    19  // AuthorizedPeers provides current authorized nodes id and/or addresses
    20  type AuthorizedPeers interface {
    21  	NumPeers() int
    22  	QueryPeerByID(id string) bool
    23  	QueryPeerByAddress(id string) bool
    24  }
    25  
    26  type PeerLists struct {
    27  	IDs       map[string]struct{}
    28  	Addresses map[string]struct{}
    29  }
    30  
    31  func NewPeerLists() *PeerLists {
    32  	return &PeerLists{
    33  		IDs:       make(map[string]struct{}),
    34  		Addresses: make(map[string]struct{}),
    35  	}
    36  }
    37  
    38  func (p PeerLists) QueryPeerByID(id string) bool {
    39  	_, ok := p.IDs[id]
    40  	return ok
    41  }
    42  
    43  func (p PeerLists) QueryPeerByAddress(id string) bool {
    44  	_, ok := p.Addresses[id]
    45  	return ok
    46  }
    47  
    48  func (p PeerLists) NumPeers() int {
    49  	return len(p.IDs)
    50  }
    51  
    52  func (app *App) peersFilter(reqQuery *abciTypes.RequestQuery, respQuery *abciTypes.ResponseQuery) {
    53  	app.logger.TraceMsg("abci.App/Query peers filter query", "query_path", reqQuery.Path)
    54  	path := strings.Split(reqQuery.Path, "/")
    55  	if len(path) != 5 {
    56  		panic(fmt.Errorf("invalid peers filter query path %v", reqQuery.Path))
    57  	}
    58  
    59  	filterType := path[3]
    60  	peer := path[4]
    61  
    62  	peerAuthorized := app.authorizedPeers.NumPeers() == 0
    63  	switch filterType {
    64  	case "id":
    65  		if ok := app.authorizedPeers.QueryPeerByID(peer); ok {
    66  			peerAuthorized = ok
    67  		}
    68  	case "addr":
    69  		if ok := app.authorizedPeers.QueryPeerByAddress(peer); ok {
    70  			peerAuthorized = ok
    71  		}
    72  	default:
    73  		panic(fmt.Errorf("invalid peers filter query type %v", reqQuery.Path))
    74  	}
    75  
    76  	if peerAuthorized {
    77  		app.logger.TraceMsg("Peer sync authorized", "peer", peer)
    78  		respQuery.Code = codes.PeerFilterAuthorizedCode
    79  	} else {
    80  		app.logger.InfoMsg("Peer sync forbidden", "peer", peer)
    81  		respQuery.Code = codes.PeerFilterForbiddenCode
    82  	}
    83  }