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 }