github.com/badrootd/celestia-core@v0.0.0-20240305091328-aa4207a4b25d/rpc/core/net.go (about) 1 package core 2 3 import ( 4 "errors" 5 "fmt" 6 "strings" 7 8 "github.com/badrootd/celestia-core/p2p" 9 ctypes "github.com/badrootd/celestia-core/rpc/core/types" 10 rpctypes "github.com/badrootd/celestia-core/rpc/jsonrpc/types" 11 ) 12 13 // NetInfo returns network info. 14 // More: https://docs.cometbft.com/v0.34/rpc/#/Info/net_info 15 func NetInfo(ctx *rpctypes.Context) (*ctypes.ResultNetInfo, error) { 16 env := GetEnvironment() 17 peersList := env.P2PPeers.Peers().List() 18 peers := make([]ctypes.Peer, 0, len(peersList)) 19 for _, peer := range peersList { 20 nodeInfo, ok := peer.NodeInfo().(p2p.DefaultNodeInfo) 21 if !ok { 22 return nil, fmt.Errorf("peer.NodeInfo() is not DefaultNodeInfo") 23 } 24 peers = append(peers, ctypes.Peer{ 25 NodeInfo: nodeInfo, 26 IsOutbound: peer.IsOutbound(), 27 ConnectionStatus: peer.Status(), 28 RemoteIP: peer.RemoteIP().String(), 29 }) 30 } 31 // TODO: Should we include PersistentPeers and Seeds in here? 32 // PRO: useful info 33 // CON: privacy 34 return &ctypes.ResultNetInfo{ 35 Listening: env.P2PTransport.IsListening(), 36 Listeners: env.P2PTransport.Listeners(), 37 NPeers: len(peers), 38 Peers: peers, 39 }, nil 40 } 41 42 // UnsafeDialSeeds dials the given seeds (comma-separated id@IP:PORT). 43 func UnsafeDialSeeds(ctx *rpctypes.Context, seeds []string) (*ctypes.ResultDialSeeds, error) { 44 if len(seeds) == 0 { 45 return &ctypes.ResultDialSeeds{}, errors.New("no seeds provided") 46 } 47 env := GetEnvironment() 48 env.Logger.Info("DialSeeds", "seeds", seeds) 49 if err := env.P2PPeers.DialPeersAsync(seeds); err != nil { 50 return &ctypes.ResultDialSeeds{}, err 51 } 52 return &ctypes.ResultDialSeeds{Log: "Dialing seeds in progress. See /net_info for details"}, nil 53 } 54 55 // UnsafeDialPeers dials the given peers (comma-separated id@IP:PORT), 56 // optionally making them persistent. 57 func UnsafeDialPeers(ctx *rpctypes.Context, peers []string, persistent, unconditional, private bool) ( 58 *ctypes.ResultDialPeers, error) { 59 if len(peers) == 0 { 60 return &ctypes.ResultDialPeers{}, errors.New("no peers provided") 61 } 62 63 ids, err := getIDs(peers) 64 if err != nil { 65 return &ctypes.ResultDialPeers{}, err 66 } 67 68 env := GetEnvironment() 69 env.Logger.Info("DialPeers", "peers", peers, "persistent", 70 persistent, "unconditional", unconditional, "private", private) 71 72 if persistent { 73 if err := env.P2PPeers.AddPersistentPeers(peers); err != nil { 74 return &ctypes.ResultDialPeers{}, err 75 } 76 } 77 78 if private { 79 if err := env.P2PPeers.AddPrivatePeerIDs(ids); err != nil { 80 return &ctypes.ResultDialPeers{}, err 81 } 82 } 83 84 if unconditional { 85 if err := env.P2PPeers.AddUnconditionalPeerIDs(ids); err != nil { 86 return &ctypes.ResultDialPeers{}, err 87 } 88 } 89 90 if err := env.P2PPeers.DialPeersAsync(peers); err != nil { 91 return &ctypes.ResultDialPeers{}, err 92 } 93 94 return &ctypes.ResultDialPeers{Log: "Dialing peers in progress. See /net_info for details"}, nil 95 } 96 97 // Genesis returns genesis file. 98 // More: https://docs.cometbft.com/v0.34/rpc/#/Info/genesis 99 func Genesis(ctx *rpctypes.Context) (*ctypes.ResultGenesis, error) { 100 env := GetEnvironment() 101 if len(env.genChunks) > 1 { 102 return nil, errors.New("genesis response is large, please use the genesis_chunked API instead") 103 } 104 105 return &ctypes.ResultGenesis{Genesis: env.GenDoc}, nil 106 } 107 108 func GenesisChunked(ctx *rpctypes.Context, chunk uint) (*ctypes.ResultGenesisChunk, error) { 109 env := GetEnvironment() 110 if env.genChunks == nil { 111 return nil, fmt.Errorf("service configuration error, genesis chunks are not initialized") 112 } 113 114 if len(env.genChunks) == 0 { 115 return nil, fmt.Errorf("service configuration error, there are no chunks") 116 } 117 118 id := int(chunk) 119 120 if id > len(env.genChunks)-1 { 121 return nil, fmt.Errorf("there are %d chunks, %d is invalid", len(env.genChunks)-1, id) 122 } 123 124 return &ctypes.ResultGenesisChunk{ 125 TotalChunks: len(env.genChunks), 126 ChunkNumber: id, 127 Data: env.genChunks[id], 128 }, nil 129 } 130 131 func getIDs(peers []string) ([]string, error) { 132 ids := make([]string, 0, len(peers)) 133 134 for _, peer := range peers { 135 136 spl := strings.Split(peer, "@") 137 if len(spl) != 2 { 138 return nil, p2p.ErrNetAddressNoID{Addr: peer} 139 } 140 ids = append(ids, spl[0]) 141 142 } 143 return ids, nil 144 }