github.com/aergoio/aergo@v1.3.1/p2p/p2putil/util.go (about)

     1  /*
     2   * @file
     3   * @copyright defined in aergo/LICENSE.txt
     4   */
     5  
     6  package p2putil
     7  
     8  import (
     9  	"errors"
    10  	"fmt"
    11  	"net"
    12  	"reflect"
    13  
    14  	"github.com/aergoio/aergo/internal/enc"
    15  	"github.com/aergoio/aergo/message"
    16  	"github.com/aergoio/aergo/types"
    17  	"github.com/gofrs/uuid"
    18  )
    19  
    20  // frequently used constants for indicating p2p log category
    21  const (
    22  	LogPeerID     = "peer_id"
    23  	LogFullID     = "full_id" // LogFullID is Full qualified peer id
    24  	LogPeerName   = "peer_nm"
    25  	LogProtoID    = "protocol_id"
    26  	LogMsgID      = "msg_id"
    27  	LogOrgReqID   = "req_id" // LogOrgReqID is msgid of request from remote peer
    28  	LogBlkHash    = types.LogBlkHash
    29  	LogBlkNo      = types.LogBlkNo
    30  	LogBlkCount   = "blk_cnt"
    31  	LogTxHash     = "tx_hash"
    32  	LogTxCount    = "tx_cnt"
    33  	LogRespStatus = types.LogRespStatus
    34  	LogRaftMsg    = "raftMsg"
    35  )
    36  
    37  func ExtractBlockFromRequest(rawResponse interface{}, err error) (*types.Block, error) {
    38  	if err != nil {
    39  		return nil, err
    40  	}
    41  	var blockRsp *message.GetBlockRsp
    42  	switch v := rawResponse.(type) {
    43  	case message.GetBlockRsp:
    44  		blockRsp = &v
    45  	case message.GetBestBlockRsp:
    46  		blockRsp = (*message.GetBlockRsp)(&v)
    47  	case message.GetBlockByNoRsp:
    48  		blockRsp = (*message.GetBlockRsp)(&v)
    49  	default:
    50  		panic("unexpected data type " + reflect.TypeOf(rawResponse).Name() + "is passed. check if there is a bug. ")
    51  	}
    52  	return extractBlock(blockRsp)
    53  }
    54  
    55  func extractBlock(from *message.GetBlockRsp) (*types.Block, error) {
    56  	if nil != from.Err {
    57  		return nil, from.Err
    58  	}
    59  	return from.Block, nil
    60  
    61  }
    62  
    63  func extractTXsFromRequest(rawResponse interface{}, err error) ([]*types.Tx, error) {
    64  	if err != nil {
    65  		return nil, err
    66  	}
    67  	var response *message.MemPoolGetRsp
    68  	switch v := rawResponse.(type) {
    69  	case *message.MemPoolGetRsp:
    70  		response = v
    71  	case message.MemPoolGetRsp:
    72  		response = &v
    73  	default:
    74  		panic("unexpected data type " + reflect.TypeOf(rawResponse).Name() + "is passed. check if there is a bug. ")
    75  	}
    76  	return extractTXs(response)
    77  }
    78  
    79  func extractTXs(from *message.MemPoolGetRsp) ([]*types.Tx, error) {
    80  	if from.Err != nil {
    81  		return nil, from.Err
    82  	}
    83  	txs := make([]*types.Tx, 0)
    84  	for _, x := range from.Txs {
    85  		txs = append(txs, x.GetTx())
    86  	}
    87  	return txs, nil
    88  }
    89  
    90  func setIP(a *types.PeerAddress, ipAddress net.IP) {
    91  	a.Address = ipAddress.String()
    92  }
    93  
    94  // RandomUUID generate random UUID and return in form of string
    95  func RandomUUID() string {
    96  	return uuid.Must(uuid.NewV4()).String()
    97  }
    98  
    99  func ExternalIP() (net.IP, error) {
   100  	ifaces, err := net.Interfaces()
   101  	if err != nil {
   102  		return nil, err
   103  	}
   104  	for _, iface := range ifaces {
   105  		if iface.Flags&net.FlagUp == 0 {
   106  			continue // interface down
   107  		}
   108  		if iface.Flags&net.FlagLoopback != 0 {
   109  			continue // loopback interface
   110  		}
   111  		addrs, err := iface.Addrs()
   112  		if err != nil {
   113  			return nil, err
   114  		}
   115  		for _, addr := range addrs {
   116  			var ip net.IP
   117  			switch v := addr.(type) {
   118  			case *net.IPNet:
   119  				ip = v.IP
   120  			case *net.IPAddr:
   121  				ip = v.IP
   122  			}
   123  			if ip == nil || ip.IsLoopback() {
   124  				continue
   125  			}
   126  			ip = ip.To4()
   127  			if ip == nil {
   128  				continue // not an ipv4 address
   129  			}
   130  			return ip, nil
   131  		}
   132  	}
   133  	return nil, errors.New("no external ip address found")
   134  }
   135  
   136  // ComparePeerID do byte-wise compare of two peerIDs,
   137  func ComparePeerID(pid1, pid2 types.PeerID) int {
   138  	p1 := []byte(string(pid1))
   139  	p2 := []byte(string(pid2))
   140  	l1 := len(p1)
   141  	l2 := len(p2)
   142  	compLen := l1
   143  	if l1 > l2 {
   144  		compLen = l2
   145  	}
   146  
   147  	// check bytes
   148  	for i := 0; i < compLen; i++ {
   149  		if comp := p1[i] - p2[i]; comp != 0 {
   150  			if (comp & 0x80) == 0 {
   151  				return int(comp)
   152  			}
   153  			return -1
   154  		}
   155  	}
   156  	// check which is longer
   157  	return l1 - l2
   158  }
   159  
   160  func PrintHashList(blocks []*types.Block) string {
   161  	l := len(blocks)
   162  	switch l {
   163  	case 0:
   164  		return "blk_cnt=0"
   165  	case 1:
   166  		return fmt.Sprintf("blk_cnt=1,hash=%s(num %d)", enc.ToString(blocks[0].Hash), blocks[0].Header.BlockNo)
   167  	default:
   168  		return fmt.Sprintf("blk_cnt=%d,firstHash=%s(num %d),lastHash=%s(num %d)", l, enc.ToString(blocks[0].Hash), blocks[0].Header.BlockNo, enc.ToString(blocks[l-1].Hash), blocks[l-1].Header.BlockNo)
   169  	}
   170  
   171  }