github.com/qri-io/qri@v0.10.1-0.20220104210721-c771715036cb/config/p2p.go (about) 1 package config 2 3 import ( 4 "fmt" 5 "reflect" 6 7 peer "github.com/libp2p/go-libp2p-core/peer" 8 ma "github.com/multiformats/go-multiaddr" 9 10 "github.com/qri-io/jsonschema" 11 ) 12 13 // P2P encapsulates configuration options for qri peer-2-peer communication 14 type P2P struct { 15 // Enabled is a flag for weather this node should connect 16 // to the distributed network 17 Enabled bool `json:"enabled"` 18 19 // PeerID is this nodes peer identifier 20 PeerID string `json:"peerid"` 21 22 PrivKey string `json:"privkey"` 23 24 // Port default port to bind a tcp listener to 25 // ignored if Addrs is supplied 26 Port int `json:"port"` 27 28 // List of multiaddresses to listen on 29 Addrs []ma.Multiaddr `json:"addrs"` 30 31 // QriBootstrapAddrs lists addresses to bootstrap qri node from 32 QriBootstrapAddrs []string `json:"qribootstrapaddrs"` 33 34 // list of addresses to bootsrap qri peers on 35 BootstrapAddrs []string `json:"bootstrapaddrs"` 36 37 // Enable AutoNAT service. unless you're hosting a server, leave this as false 38 AutoNAT bool `json:"autoNAT"` 39 } 40 41 // SetArbitrary is an interface implementation of base/fill/struct in order to safely 42 // consume config files that have definitions beyond those specified in the struct. 43 // This simply ignores all additional fields at read time. 44 func (cfg *P2P) SetArbitrary(key string, val interface{}) error { 45 return nil 46 } 47 48 // DefaultP2P generates a p2p struct with only bootstrap addresses set 49 func DefaultP2P() *P2P { 50 p2p := &P2P{ 51 Enabled: true, 52 // DefaultBootstrapAddresses follows the pattern of IPFS boostrapping off known "gateways". 53 // This boostrapping is specific to finding qri peers, which are IPFS peers that also 54 // support the qri protocol. 55 // (we also perform standard IPFS boostrapping when IPFS networking is enabled, and it's almost always enabled). 56 // These are addresses to public qri nodes hosted by qri, inc. 57 // One day it would be super nice to bootstrap from a stored history & only 58 // use these for first-round bootstrapping. 59 QriBootstrapAddrs: []string{ 60 "/ip4/35.231.230.13/tcp/4001/ipfs/QmdpGkbqDYRPCcwLYnEm8oYGz2G9aUZn9WwPjqvqw3XUAc", // red 61 "/ip4/34.75.40.163/tcp/4001/ipfs/QmTRqTLbKndFC2rp6VzpyApxHCLrFV35setF1DQZaRWPVf", // orange 62 "/ip4/35.237.172.74/tcp/4001/ipfs/QmegNYmwHUQFc3v3eemsYUVf3WiSg4RcMrh3hovA5LncJ2", // yellow 63 "/ip4/35.231.155.111/tcp/4001/ipfs/QmessbA6uGLJ7HTwbUJ2niE49WbdPfzi27tdYXdAaGRB4G", // green 64 "/ip4/35.237.232.64/tcp/4001/ipfs/Qmc353gHY5Wx5iHKHPYj3QDqHP4hVA1MpoSsT6hwSyVx3r", // blue 65 "/ip4/35.185.20.61/tcp/4001/ipfs/QmT9YHJF2YkysLqWhhiVTL5526VFtavic3bVueF9rCsjVi", // indigo 66 "/ip4/35.231.246.50/tcp/4001/ipfs/QmQS2ryqZrjJtPKDy9VTkdPwdUSpTi1TdpGUaqAVwfxcNh", // violet 67 }, 68 } 69 return p2p 70 } 71 72 // DecodePeerID takes P2P.ID (a string), and decodes it into a peer.ID 73 func (cfg *P2P) DecodePeerID() (peer.ID, error) { 74 if string(cfg.PeerID) == "" { 75 return peer.ID(""), fmt.Errorf("empty string for peer ID") 76 } 77 return peer.IDB58Decode(cfg.PeerID) 78 } 79 80 // Validate validates all fields of p2p returning all errors found. 81 func (cfg P2P) Validate() error { 82 schema := jsonschema.Must(`{ 83 "$schema": "http://json-schema.org/draft-06/schema#", 84 "title": "P2P", 85 "description": "Config for the p2p", 86 "type": "object", 87 "required": ["enabled", "peerid", "privkey", "port", "addrs", "qribootstrapaddrs"], 88 "properties": { 89 "enabled": { 90 "description": "When true, peer to peer communication is allowed", 91 "type": "boolean" 92 }, 93 "peerid": { 94 "description": "The peerid is this nodes peer identifier", 95 "type": "string" 96 }, 97 "privkey": { 98 "description": "", 99 "type": "string" 100 }, 101 "port": { 102 "description": "Port to bind a tcp lister to. Field is ignored if addrs is supplied", 103 "type": "integer" 104 }, 105 "addrs": { 106 "description": "List of multiaddresses to listen on", 107 "anyOf": [ 108 {"type": "array"}, 109 {"type": "null"} 110 ], 111 "items": { 112 "type": "string" 113 } 114 }, 115 "qribootstrapaddrs": { 116 "description": "List of addresses to bootstrap the qri node from", 117 "type": "array", 118 "items": { 119 "type": "string" 120 } 121 }, 122 "bootstrapaddrs": { 123 "description": "List of addresses to bootstrap qri peers on", 124 "anyOf": [ 125 {"type": "array"}, 126 {"type": "null"} 127 ], 128 "items": { 129 "type": "string" 130 } 131 } 132 } 133 }`) 134 return validate(schema, &cfg) 135 } 136 137 // Copy returns a deep copy of a p2p struct 138 func (cfg *P2P) Copy() *P2P { 139 res := &P2P{ 140 Enabled: cfg.Enabled, 141 PeerID: cfg.PeerID, 142 PrivKey: cfg.PrivKey, 143 Port: cfg.Port, 144 } 145 146 if cfg.QriBootstrapAddrs != nil { 147 res.QriBootstrapAddrs = make([]string, len(cfg.QriBootstrapAddrs)) 148 reflect.Copy(reflect.ValueOf(res.QriBootstrapAddrs), reflect.ValueOf(cfg.QriBootstrapAddrs)) 149 } 150 151 if cfg.BootstrapAddrs != nil { 152 res.BootstrapAddrs = make([]string, len(cfg.BootstrapAddrs)) 153 reflect.Copy(reflect.ValueOf(res.BootstrapAddrs), reflect.ValueOf(cfg.BootstrapAddrs)) 154 } 155 156 return res 157 }