github.com/n1ghtfa1l/go-vnt@v0.6.4-alpha.6/vntp2p/node.go (about)

     1  // Copyright 2019 The go-vnt Authors
     2  // This file is part of the go-vnt library.
     3  //
     4  // The go-vnt library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-vnt library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-vnt library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package vntp2p
    18  
    19  import (
    20  	"crypto/ecdsa"
    21  	"encoding/hex"
    22  	"fmt"
    23  	"net"
    24  	"strconv"
    25  	"strings"
    26  
    27  	peer "github.com/libp2p/go-libp2p-peer"
    28  	ma "github.com/multiformats/go-multiaddr"
    29  )
    30  
    31  // 包内都用peerID,对外方法使用NodeID
    32  const NodeIDBits = 512
    33  
    34  type NodeID [NodeIDBits / 8]byte
    35  
    36  // type Node struct {
    37  // 	IP       net.IP // len 4 for IPv4 or 16 for IPv6
    38  // 	UDP, TCP uint16 // port numbers
    39  // 	ID       NodeID // the node's public key
    40  
    41  // 	sha common.Hash
    42  
    43  // 	// Time when the node was added to the table.
    44  // 	addedAt time.Time
    45  // }
    46  
    47  type Node struct {
    48  	Addr ma.Multiaddr
    49  	Id   peer.ID
    50  }
    51  
    52  func (n *Node) String() string {
    53  	return n.Addr.String() + "/ipfs/" + n.Id.ToString()
    54  }
    55  
    56  func NewNode(id peer.ID, ip net.IP, udpPort, tcpPort uint16) *Node {
    57  	peerid := id
    58  	target := ""
    59  	if ipv4 := ip.To4(); ipv4 != nil {
    60  		target += "/ip4/" + ip.String() + "/tcp/" + strconv.Itoa(int(tcpPort)) + "/ipfs/" + peerid.ToString()
    61  	} else {
    62  		target += "/ip6/" + ip.String() + "/tcp/" + strconv.Itoa(int(tcpPort)) + "/ipfs/" + peerid.ToString()
    63  	}
    64  
    65  	targetAddr, peerid, err := GetAddr(target)
    66  	if err != nil {
    67  		return nil
    68  	}
    69  
    70  	return &Node{Addr: targetAddr, Id: peerid}
    71  }
    72  
    73  func ParseNode(url string) (*Node, error) {
    74  	addr, peerid, err := GetAddr(url)
    75  	if err != nil {
    76  		// log
    77  		return nil, err
    78  	}
    79  
    80  	return &Node{Addr: addr, Id: peerid}, nil
    81  }
    82  
    83  func MustParseNode(rawurl string) *Node {
    84  	n, err := ParseNode(rawurl)
    85  	if err != nil {
    86  		panic("invalid node URL: " + err.Error())
    87  	}
    88  	return n
    89  }
    90  
    91  // for toml unmarshal
    92  func (n *Node) UnmarshalText(data []byte) error {
    93  	var err error
    94  	var nd *Node
    95  
    96  	nd, err = ParseNode(string(data))
    97  	n.Addr = nd.Addr
    98  	n.Id = nd.Id
    99  
   100  	return err
   101  }
   102  
   103  // for toml marshal
   104  func (n *Node) MarshalText() ([]byte, error) {
   105  	url := n.String()
   106  	ret := make([]byte, len(url))
   107  	copy(ret, url)
   108  
   109  	return ret, nil
   110  }
   111  
   112  /* func PubkeyID(pub *ecdsa.PublicKey) NodeID {
   113  	// var id NodeID
   114  	// pbytes := elliptic.Marshal(pub.Curve, pub.X, pub.Y)
   115  	// if len(pbytes)-1 != len(id) {
   116  	// 	panic(fmt.Errorf("need %d bit pubkey, got %d bits", (len(id)+1)*8, len(pbytes)))
   117  	// }
   118  	// copy(id[:], pbytes[1:])
   119  	// return id
   120  	id, err := peer.IDFromPublicKey(pub)
   121  	if err != nil {
   122  		panic("wrong publick key")
   123  	}
   124  	return PeerIDtoNodeID(id)
   125  } */
   126  
   127  func PeerIDtoNodeID(n peer.ID) NodeID {
   128  	var id NodeID
   129  	copy(id[:], []byte(n))
   130  	return id
   131  }
   132  
   133  func (n NodeID) PeerID() peer.ID {
   134  	return peer.ID(n.Bytes())
   135  }
   136  
   137  func (n NodeID) Pubkey() (*ecdsa.PublicKey, error) {
   138  	// 通过ID如何生成公钥
   139  
   140  	return n.PeerID().ExtractPublicKey()
   141  }
   142  
   143  func (n NodeID) Bytes() []byte {
   144  	return n[:]
   145  }
   146  
   147  // NodeID prints as a long hexadecimal number.
   148  func (n NodeID) String() string {
   149  	return string(n.Bytes())
   150  }
   151  
   152  // The Go syntax representation of a NodeID is a call to HexID.
   153  func (n NodeID) GoString() string {
   154  	return fmt.Sprintf("discover.HexID(\"%x\")", n.Bytes())
   155  }
   156  
   157  // TerminalString returns a shortened hex string for terminal logging.
   158  func (n NodeID) TerminalString() string {
   159  	return hex.EncodeToString(n.Bytes()[:8])
   160  }
   161  
   162  // MarshalText implements the encoding.TextMarshaler interface.
   163  func (n NodeID) MarshalText() ([]byte, error) {
   164  	return []byte(hex.EncodeToString(n.Bytes())), nil
   165  }
   166  
   167  // UnmarshalText implements the encoding.TextUnmarshaler interface.
   168  func (n *NodeID) UnmarshalText(text []byte) error {
   169  	id, err := HexID(string(text))
   170  	if err != nil {
   171  		return err
   172  	}
   173  	*n = id
   174  	return nil
   175  }
   176  
   177  func HexID(in string) (NodeID, error) {
   178  	var id NodeID
   179  	b, err := hex.DecodeString(strings.TrimPrefix(in, "0x"))
   180  	if err != nil {
   181  		return id, err
   182  	} else if len(b) != len(id) {
   183  		return id, fmt.Errorf("wrong length, want %d hex chars", len(id)*2)
   184  	}
   185  	copy(id[:], b)
   186  	return id, nil
   187  }