github.com/kisexp/xdchain@v0.0.0-20211206025815-490d6b732aa7/raft/peer.go (about)

     1  package raft
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"log"
     7  	"net"
     8  
     9  	"github.com/kisexp/xdchain/p2p/enode"
    10  	"github.com/kisexp/xdchain/p2p/enr"
    11  	"github.com/kisexp/xdchain/rlp"
    12  )
    13  
    14  // Serializable information about a Peer. Sufficient to build `etcdRaft.Peer`
    15  // or `enode.Node`.
    16  // As NodeId is mainly used to derive the `ecdsa.pubkey` to build `enode.Node` it is kept as [64]byte instead of ID [32]byte used by `enode.Node`.
    17  type Address struct {
    18  	RaftId   uint16        `json:"raftId"`
    19  	NodeId   enode.EnodeID `json:"nodeId"`
    20  	Ip       net.IP        `json:"-"`
    21  	P2pPort  enr.TCP       `json:"p2pPort"`
    22  	RaftPort enr.RaftPort  `json:"raftPort"`
    23  
    24  	Hostname string `json:"hostname"`
    25  
    26  	// Ignore additional fields (for forward compatibility).
    27  	Rest []rlp.RawValue `json:"-" rlp:"tail"`
    28  }
    29  
    30  type ClusterInfo struct {
    31  	Address
    32  	Role       string `json:"role"`
    33  	NodeActive bool   `json:"nodeActive"`
    34  }
    35  
    36  func newAddress(raftId uint16, raftPort int, node *enode.Node, useDns bool) *Address {
    37  	// derive 64 byte nodeID from 128 byte enodeID
    38  	id, err := enode.RaftHexID(node.EnodeID())
    39  	if err != nil {
    40  		panic(err)
    41  	}
    42  	if useDns && node.Host() != "" {
    43  		return &Address{
    44  			RaftId:   raftId,
    45  			NodeId:   id,
    46  			Ip:       nil,
    47  			P2pPort:  enr.TCP(node.TCP()),
    48  			RaftPort: enr.RaftPort(raftPort),
    49  			Hostname: node.Host(),
    50  		}
    51  	}
    52  	return &Address{
    53  		RaftId:   raftId,
    54  		NodeId:   id,
    55  		Ip:       nil,
    56  		P2pPort:  enr.TCP(node.TCP()),
    57  		RaftPort: enr.RaftPort(raftPort),
    58  		Hostname: node.IP().String(),
    59  	}
    60  }
    61  
    62  // A peer that we're connected to via both raft's http transport, and ethereum p2p
    63  type Peer struct {
    64  	address *Address    // For raft transport
    65  	p2pNode *enode.Node // For ethereum transport
    66  }
    67  
    68  // RLP Address encoding, for transport over raft and storage in LevelDB.
    69  func (addr *Address) toBytes() []byte {
    70  	var toEncode interface{}
    71  
    72  	// need to check if addr.Hostname is hostname/ip
    73  	if ip := net.ParseIP(addr.Hostname); ip == nil {
    74  		toEncode = addr
    75  	} else {
    76  		toEncode = []interface{}{addr.RaftId, addr.NodeId, ip, addr.P2pPort, addr.RaftPort}
    77  	}
    78  
    79  	buffer, err := rlp.EncodeToBytes(toEncode)
    80  	if err != nil {
    81  		panic(fmt.Sprintf("error: failed to RLP-encode Address: %s", err.Error()))
    82  	}
    83  	return buffer
    84  }
    85  
    86  func bytesToAddress(input []byte) *Address {
    87  	// try the new format first
    88  	addr := new(Address)
    89  	streamNew := rlp.NewStream(bytes.NewReader(input), 0)
    90  	if err := streamNew.Decode(addr); err == nil {
    91  		return addr
    92  	}
    93  
    94  	// else try the old format
    95  	var temp struct {
    96  		RaftId   uint16
    97  		NodeId   enode.EnodeID
    98  		Ip       net.IP
    99  		P2pPort  enr.TCP
   100  		RaftPort enr.RaftPort
   101  	}
   102  
   103  	streamOld := rlp.NewStream(bytes.NewReader(input), 0)
   104  	if err := streamOld.Decode(&temp); err != nil {
   105  		log.Fatalf("failed to RLP-decode Address: %v", err)
   106  	}
   107  
   108  	return &Address{
   109  		RaftId:   temp.RaftId,
   110  		NodeId:   temp.NodeId,
   111  		Ip:       nil,
   112  		P2pPort:  temp.P2pPort,
   113  		RaftPort: temp.RaftPort,
   114  		Hostname: temp.Ip.String(),
   115  	}
   116  }