github.com/aergoio/aergo@v1.3.1/p2p/p2putil/libp2putil.go (about) 1 /* 2 * @file 3 * @copyright defined in aergo/LICENSE.txt 4 */ 5 6 package p2putil 7 8 import ( 9 "bytes" 10 "fmt" 11 "github.com/aergoio/aergo/internal/network" 12 "github.com/aergoio/aergo/p2p/p2pcommon" 13 "github.com/aergoio/aergo/types" 14 "github.com/libp2p/go-libp2p-core" 15 "github.com/libp2p/go-libp2p-core/crypto" 16 "github.com/libp2p/go-libp2p-core/test" 17 "github.com/multiformats/go-multiaddr" 18 "io/ioutil" 19 "net" 20 "os" 21 "path/filepath" 22 "strconv" 23 "strings" 24 ) 25 26 27 // NOTE use only in test 28 func RandomPeerID() types.PeerID { 29 id,_ := test.RandPeerID() 30 return id 31 } 32 // PeerMetaToMultiAddr make libp2p compatible Multiaddr object from peermeta 33 func PeerMetaToMultiAddr(m p2pcommon.PeerMeta) (multiaddr.Multiaddr, error) { 34 ipAddr, err := network.GetSingleIPAddress(m.IPAddress) 35 if err != nil { 36 return nil, err 37 } 38 return types.ToMultiAddr(ipAddr, m.Port) 39 } 40 41 func FromMultiAddr(targetAddr multiaddr.Multiaddr) (p2pcommon.PeerMeta, error) { 42 meta := p2pcommon.PeerMeta{} 43 split := strings.Split(targetAddr.String(), "/") 44 if len(split) != 7 { 45 return meta, fmt.Errorf("invalid NPAddPeer addr format %s", targetAddr.String()) 46 } 47 addrType := split[1] 48 if addrType != "ip4" && addrType != "ip6" { 49 return meta, fmt.Errorf("invalid NPAddPeer addr type %s", addrType) 50 } 51 peerAddrString := split[2] 52 peerPortString := split[4] 53 peerPort, err := strconv.Atoi(peerPortString) 54 if err != nil { 55 return meta, fmt.Errorf("invalid Peer port %s", peerPortString) 56 } 57 peerIDString := split[6] 58 peerID, err := types.IDB58Decode(peerIDString) 59 if err != nil { 60 return meta, fmt.Errorf("invalid PeerID %s", peerIDString) 61 } 62 meta = p2pcommon.PeerMeta{ 63 ID: peerID, 64 Port: uint32(peerPort), 65 IPAddress: peerAddrString, 66 } 67 return meta, nil 68 } 69 70 func FromMultiAddrString(str string) (p2pcommon.PeerMeta, error) { 71 ma, err := types.ParseMultiaddrWithResolve(str) 72 if err != nil { 73 return p2pcommon.PeerMeta{}, err 74 } 75 return FromMultiAddr(ma) 76 } 77 78 79 func FromMultiAddrStringWithPID(str string, id types.PeerID) (p2pcommon.PeerMeta, error) { 80 addr1, err := types.ParseMultiaddrWithResolve(str) 81 if err != nil { 82 return p2pcommon.PeerMeta{}, err 83 } 84 pidAddr, err := multiaddr.NewComponent(multiaddr.ProtocolWithCode(multiaddr.P_P2P).Name, id.Pretty()) 85 if err != nil { 86 return p2pcommon.PeerMeta{}, err 87 } 88 ma := multiaddr.Join(addr1, pidAddr) 89 return FromMultiAddr(ma) 90 } 91 92 // ExtractIPAddress returns ip address from multiaddr. it return null if ma has no ip field. 93 func ExtractIPAddress(ma multiaddr.Multiaddr) net.IP { 94 ipStr, err := ma.ValueForProtocol(multiaddr.P_IP4) 95 if err == nil { 96 return net.ParseIP(ipStr) 97 } 98 ipStr, err = ma.ValueForProtocol(multiaddr.P_IP6) 99 if err == nil { 100 return net.ParseIP(ipStr) 101 } 102 return nil 103 } 104 105 func LoadKeyFile(keyFile string) (crypto.PrivKey, crypto.PubKey, error) { 106 dat, err := ioutil.ReadFile(keyFile) 107 if err == nil { 108 priv, err := crypto.UnmarshalPrivateKey(dat) 109 if err != nil { 110 return nil,nil, fmt.Errorf("invalid keyfile. It's not private key file") 111 } 112 return priv, priv.GetPublic(), nil 113 } else { 114 return nil, nil, fmt.Errorf("Invalid keyfile path '"+ keyFile +"'. Check the key file exists.") 115 } 116 } 117 118 func GenerateKeyFile(dir, prefix string) (crypto.PrivKey, crypto.PubKey, error) { 119 // invariant: key file must not exists. 120 if _, err2 := os.Stat(dir); os.IsNotExist(err2) { 121 mkdirErr := os.MkdirAll(dir, os.ModePerm) 122 if mkdirErr != nil { 123 return nil, nil, mkdirErr 124 } 125 } 126 // file not exist and create new file 127 priv, pub, err := crypto.GenerateKeyPair(crypto.Secp256k1, 256) 128 if err != nil { 129 return nil, nil, err 130 } 131 err = writeToKeyFiles(priv, pub, dir, prefix) 132 if err != nil { 133 return nil, nil, fmt.Errorf("Failed to generate files %s.{key,id}: %v", prefix, err.Error()) 134 } 135 136 return priv, priv.GetPublic(), nil 137 } 138 139 140 func writeToKeyFiles(priv crypto.PrivKey, pub crypto.PubKey, dir, prefix string) error { 141 142 pkFile := filepath.Join(dir, prefix+p2pcommon.DefaultPkKeyExt) 143 // pubFile := filepath.Join(dir, prefix+".pub") 144 idFile := filepath.Join(dir, prefix+p2pcommon.DefaultPeerIDExt) 145 146 // Write private key file 147 pkf, err := os.Create(pkFile) 148 if err != nil { 149 return err 150 } 151 pkBytes, err := priv.Bytes() 152 if err != nil { 153 return err 154 } 155 pkf.Write(pkBytes) 156 pkf.Sync() 157 158 // Write id file 159 idf, err := os.Create(idFile) 160 if err != nil { 161 return err 162 } 163 pid, _ := types.IDFromPublicKey(pub) 164 idBytes := []byte(types.IDB58Encode(pid)) 165 idf.Write(idBytes) 166 idf.Sync() 167 return nil 168 } 169 170 func ProtocolIDsToString(sli []core.ProtocolID) string { 171 sb := bytes.NewBuffer(nil) 172 sb.WriteByte('[') 173 if len(sli) > 0 { 174 stop := len(sli)-1 175 for i:=0 ; i<stop; i++ { 176 sb.WriteString(string(sli[i])) 177 sb.WriteByte(',') 178 } 179 sb.WriteString(string(sli[stop])) 180 } 181 sb.WriteByte(']') 182 return sb.String() 183 }