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 }