github.com/hyperion-hyn/go-ethereum@v2.4.0+incompatible/raft/peer.go (about)

     1  package raft
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"log"
     7  	"net"
     8  
     9  	"github.com/ethereum/go-ethereum/p2p/enode"
    10  	"github.com/ethereum/go-ethereum/p2p/enr"
    11  	"github.com/ethereum/go-ethereum/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  }
    34  
    35  func newAddress(raftId uint16, raftPort int, node *enode.Node, withHostname bool) *Address {
    36  	// derive 64 byte nodeID from 128 byte enodeID
    37  	id, err := enode.RaftHexID(node.EnodeID())
    38  	if err != nil {
    39  		panic(err)
    40  	}
    41  	if withHostname {
    42  		return &Address{
    43  			RaftId:   raftId,
    44  			NodeId:   id,
    45  			Ip:       nil,
    46  			P2pPort:  enr.TCP(node.TCP()),
    47  			RaftPort: enr.RaftPort(raftPort),
    48  			Hostname: node.Host(),
    49  		}
    50  	}
    51  	return &Address{
    52  		RaftId:   raftId,
    53  		NodeId:   id,
    54  		Ip:       nil,
    55  		P2pPort:  enr.TCP(node.TCP()),
    56  		RaftPort: enr.RaftPort(raftPort),
    57  		Hostname: node.IP().String(),
    58  	}
    59  }
    60  
    61  // A peer that we're connected to via both raft's http transport, and ethereum p2p
    62  type Peer struct {
    63  	address *Address    // For raft transport
    64  	p2pNode *enode.Node // For ethereum transport
    65  }
    66  
    67  // RLP Address encoding, for transport over raft and storage in LevelDB.
    68  func (addr *Address) toBytes(withHostname bool) []byte {
    69  	var toEncode interface{}
    70  
    71  	if withHostname {
    72  		toEncode = addr
    73  	} else {
    74  		toEncode = []interface{}{addr.RaftId, addr.NodeId, net.ParseIP(addr.Hostname), addr.P2pPort, addr.RaftPort}
    75  	}
    76  
    77  	buffer, err := rlp.EncodeToBytes(toEncode)
    78  	if err != nil {
    79  		panic(fmt.Sprintf("error: failed to RLP-encode Address: %s", err.Error()))
    80  	}
    81  	return buffer
    82  }
    83  
    84  func bytesToAddress(input []byte) *Address {
    85  	//try the new format first
    86  	addr := new(Address)
    87  	streamNew := rlp.NewStream(bytes.NewReader(input), 0)
    88  	if err := streamNew.Decode(addr); err == nil {
    89  		return addr
    90  	}
    91  
    92  	//else try the old format
    93  	var temp struct {
    94  		RaftId   uint16
    95  		NodeId   enode.EnodeID
    96  		Ip       net.IP
    97  		P2pPort  enr.TCP
    98  		RaftPort enr.RaftPort
    99  	}
   100  
   101  	streamOld := rlp.NewStream(bytes.NewReader(input), 0)
   102  	if err := streamOld.Decode(&temp); err != nil {
   103  		log.Fatalf("failed to RLP-decode Address: %v", err)
   104  	}
   105  
   106  	return &Address{
   107  		RaftId:   temp.RaftId,
   108  		NodeId:   temp.NodeId,
   109  		Ip:       nil,
   110  		P2pPort:  temp.P2pPort,
   111  		RaftPort: temp.RaftPort,
   112  		Hostname: temp.Ip.String(),
   113  	}
   114  }