github.com/aergoio/aergo@v1.3.1/p2p/subproto/addrs.go (about)

     1  /**
     2   *  @file
     3   *  @copyright defined in aergo/LICENSE.txt
     4   */
     5  
     6  package subproto
     7  
     8  import (
     9  	"github.com/aergoio/aergo-lib/log"
    10  	"github.com/aergoio/aergo/internal/network"
    11  	"github.com/aergoio/aergo/p2p/p2pcommon"
    12  	"github.com/aergoio/aergo/p2p/p2putil"
    13  	"github.com/aergoio/aergo/types"
    14  )
    15  
    16  type addressesRequestHandler struct {
    17  	BaseMsgHandler
    18  }
    19  
    20  var _ p2pcommon.MessageHandler = (*addressesRequestHandler)(nil)
    21  
    22  type addressesResponseHandler struct {
    23  	BaseMsgHandler
    24  }
    25  
    26  var _ p2pcommon.MessageHandler = (*addressesResponseHandler)(nil)
    27  
    28  // newAddressesReqHandler creates handler for PingRequest
    29  func NewAddressesReqHandler(pm p2pcommon.PeerManager, peer p2pcommon.RemotePeer, logger *log.Logger, actor p2pcommon.ActorService) *addressesRequestHandler {
    30  	ph := &addressesRequestHandler{BaseMsgHandler{protocol: p2pcommon.AddressesRequest, pm: pm, peer: peer, actor: actor, logger: logger}}
    31  	return ph
    32  }
    33  
    34  func (ph *addressesRequestHandler) ParsePayload(rawbytes []byte) (p2pcommon.MessageBody, error) {
    35  	return p2putil.UnmarshalAndReturn(rawbytes, &types.AddressesRequest{})
    36  }
    37  
    38  func (ph *addressesRequestHandler) Handle(msg p2pcommon.Message, msgBody p2pcommon.MessageBody) {
    39  	peerID := ph.peer.ID()
    40  	remotePeer := ph.peer
    41  	data := msgBody.(*types.AddressesRequest)
    42  	p2putil.DebugLogReceive(ph.logger, ph.protocol, msg.ID().String(), remotePeer, nil)
    43  
    44  	// check sender
    45  	maxPeers := data.MaxSize
    46  
    47  	// generate response message
    48  	resp := &types.AddressesResponse{}
    49  	var addrList = make([]*types.PeerAddress, 0, len(ph.pm.GetPeers()))
    50  	addrCount := uint32(0)
    51  	for _, aPeer := range ph.pm.GetPeers() {
    52  		// exclude not running peer and requesting peer itself
    53  		// TODO: apply peer status after fix status management bug
    54  		if aPeer.ID() == peerID {
    55  			continue
    56  		}
    57  		if aPeer.Meta().Hidden {
    58  			continue
    59  		}
    60  
    61  		pAddr := aPeer.Meta().ToPeerAddress()
    62  		addrList = append(addrList, &pAddr)
    63  		addrCount++
    64  		if addrCount >= maxPeers {
    65  			break
    66  		}
    67  	}
    68  	resp.Peers = addrList
    69  	// send response
    70  	remotePeer.SendMessage(remotePeer.MF().NewMsgResponseOrder(msg.ID(), p2pcommon.AddressesResponse, resp))
    71  }
    72  
    73  // TODO need refactoring. This code is not bounded to a specific peer but rather whole peer pool, and cause code duplication in p2p.go
    74  func (ph *addressesResponseHandler) checkAndAddPeerAddresses(peers []*types.PeerAddress) {
    75  	selfPeerID := ph.pm.SelfNodeID()
    76  	peerMetas := make([]p2pcommon.PeerMeta, 0, len(peers))
    77  	for _, rPeerAddr := range peers {
    78  		rPeerID := types.PeerID(rPeerAddr.PeerID)
    79  		if selfPeerID == rPeerID {
    80  			continue
    81  		}
    82  		if network.CheckAddressType(rPeerAddr.Address) == network.AddressTypeError {
    83  			continue
    84  		}
    85  		meta := p2pcommon.FromPeerAddress(rPeerAddr)
    86  		peerMetas = append(peerMetas, meta)
    87  	}
    88  	if len(peerMetas) > 0 {
    89  		ph.pm.NotifyPeerAddressReceived(peerMetas)
    90  	}
    91  }
    92  
    93  // newAddressesRespHandler creates handler for PingRequest
    94  func NewAddressesRespHandler(pm p2pcommon.PeerManager, peer p2pcommon.RemotePeer, logger *log.Logger, actor p2pcommon.ActorService) *addressesResponseHandler {
    95  	ph := &addressesResponseHandler{BaseMsgHandler{protocol: p2pcommon.AddressesResponse, pm: pm, peer: peer, actor: actor, logger: logger}}
    96  	return ph
    97  }
    98  
    99  func (ph *addressesResponseHandler) ParsePayload(rawbytes []byte) (p2pcommon.MessageBody, error) {
   100  	return p2putil.UnmarshalAndReturn(rawbytes, &types.AddressesResponse{})
   101  }
   102  
   103  func (ph *addressesResponseHandler) Handle(msg p2pcommon.Message, msgBody p2pcommon.MessageBody) {
   104  	remotePeer := ph.peer
   105  	data := msgBody.(*types.AddressesResponse)
   106  	p2putil.DebugLogReceiveResponse(ph.logger, ph.protocol, msg.ID().String(), msg.OriginalID().String(), remotePeer, data)
   107  
   108  	remotePeer.ConsumeRequest(msg.OriginalID())
   109  	if len(data.GetPeers()) > 0 {
   110  		ph.checkAndAddPeerAddresses(data.GetPeers())
   111  	}
   112  }