github.com/ethereumproject/go-ethereum@v5.5.2+incompatible/node/api.go (about) 1 // Copyright 2015 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum 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-ethereum 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-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package node 18 19 import ( 20 "fmt" 21 "strings" 22 23 "github.com/ethereumproject/go-ethereum/common" 24 "github.com/ethereumproject/go-ethereum/crypto" 25 "github.com/ethereumproject/go-ethereum/p2p" 26 "github.com/ethereumproject/go-ethereum/p2p/discover" 27 "github.com/ethereumproject/go-ethereum/rpc" 28 ) 29 30 // PrivateAdminAPI is the collection of administrative API methods exposed only 31 // over a secure RPC channel. 32 type PrivateAdminAPI struct { 33 node *Node // Node interfaced by this API 34 } 35 36 // NewPrivateAdminAPI creates a new API definition for the private admin methods 37 // of the node itself. 38 func NewPrivateAdminAPI(node *Node) *PrivateAdminAPI { 39 return &PrivateAdminAPI{node: node} 40 } 41 42 // AddPeer requests connecting to a remote node, and also maintaining the new 43 // connection at all times, even reconnecting if it is lost. 44 func (api *PrivateAdminAPI) AddPeer(url string) (bool, error) { 45 // Make sure the server is running, fail otherwise 46 server := api.node.Server() 47 if server == nil { 48 return false, ErrNodeStopped 49 } 50 // Try to add the url as a static peer and return 51 node, err := discover.ParseNode(url) 52 if err != nil { 53 return false, fmt.Errorf("invalid enode: %v", err) 54 } 55 server.AddPeer(node) 56 return true, nil 57 } 58 59 // StartRPC starts the HTTP RPC API server. 60 func (api *PrivateAdminAPI) StartRPC(host *string, port *rpc.HexNumber, cors *string, apis *string) (bool, error) { 61 api.node.lock.Lock() 62 defer api.node.lock.Unlock() 63 64 if api.node.httpHandler != nil { 65 return false, fmt.Errorf("HTTP RPC already running on %s", api.node.httpEndpoint) 66 } 67 68 if host == nil { 69 h := common.DefaultHTTPHost 70 if api.node.httpHost != "" { 71 h = api.node.httpHost 72 } 73 host = &h 74 } 75 if port == nil { 76 port = rpc.NewHexNumber(api.node.httpPort) 77 } 78 if cors == nil { 79 cors = &api.node.httpCors 80 } 81 82 modules := api.node.httpWhitelist 83 if apis != nil { 84 modules = nil 85 for _, m := range strings.Split(*apis, ",") { 86 modules = append(modules, strings.TrimSpace(m)) 87 } 88 } 89 90 if err := api.node.startHTTP(fmt.Sprintf("%s:%d", *host, port.Int()), api.node.rpcAPIs, modules, *cors); err != nil { 91 return false, err 92 } 93 return true, nil 94 } 95 96 // StopRPC terminates an already running HTTP RPC API endpoint. 97 func (api *PrivateAdminAPI) StopRPC() (bool, error) { 98 api.node.lock.Lock() 99 defer api.node.lock.Unlock() 100 101 if api.node.httpHandler == nil { 102 return false, fmt.Errorf("HTTP RPC not running") 103 } 104 api.node.stopHTTP() 105 return true, nil 106 } 107 108 // StartWS starts the websocket RPC API server. 109 func (api *PrivateAdminAPI) StartWS(host *string, port *rpc.HexNumber, allowedOrigins *string, apis *string) (bool, error) { 110 api.node.lock.Lock() 111 defer api.node.lock.Unlock() 112 113 if api.node.wsHandler != nil { 114 return false, fmt.Errorf("WebSocket RPC already running on %s", api.node.wsEndpoint) 115 } 116 117 if host == nil { 118 h := common.DefaultWSHost 119 if api.node.wsHost != "" { 120 h = api.node.wsHost 121 } 122 host = &h 123 } 124 if port == nil { 125 port = rpc.NewHexNumber(api.node.wsPort) 126 } 127 if allowedOrigins == nil { 128 allowedOrigins = &api.node.wsOrigins 129 } 130 131 modules := api.node.wsWhitelist 132 if apis != nil { 133 modules = nil 134 for _, m := range strings.Split(*apis, ",") { 135 modules = append(modules, strings.TrimSpace(m)) 136 } 137 } 138 139 if err := api.node.startWS(fmt.Sprintf("%s:%d", *host, port.Int()), api.node.rpcAPIs, modules, *allowedOrigins); err != nil { 140 return false, err 141 } 142 return true, nil 143 } 144 145 // StopRPC terminates an already running websocket RPC API endpoint. 146 func (api *PrivateAdminAPI) StopWS() (bool, error) { 147 api.node.lock.Lock() 148 defer api.node.lock.Unlock() 149 150 if api.node.wsHandler == nil { 151 return false, fmt.Errorf("WebSocket RPC not running") 152 } 153 api.node.stopWS() 154 return true, nil 155 } 156 157 // PublicAdminAPI is the collection of administrative API methods exposed over 158 // both secure and unsecure RPC channels. 159 type PublicAdminAPI struct { 160 node *Node // Node interfaced by this API 161 } 162 163 // NewPublicAdminAPI creates a new API definition for the public admin methods 164 // of the node itself. 165 func NewPublicAdminAPI(node *Node) *PublicAdminAPI { 166 return &PublicAdminAPI{node: node} 167 } 168 169 // Peers retrieves all the information we know about each individual peer at the 170 // protocol granularity. 171 func (api *PublicAdminAPI) Peers() ([]*p2p.PeerInfo, error) { 172 server := api.node.Server() 173 if server == nil { 174 return nil, ErrNodeStopped 175 } 176 return server.PeersInfo(), nil 177 } 178 179 // NodeInfo retrieves all the information we know about the host node at the 180 // protocol granularity. 181 func (api *PublicAdminAPI) NodeInfo() (*p2p.NodeInfo, error) { 182 server := api.node.Server() 183 if server == nil { 184 return nil, ErrNodeStopped 185 } 186 return server.NodeInfo(), nil 187 } 188 189 // Datadir retrieves the current data directory the node is using. 190 func (api *PublicAdminAPI) Datadir() string { 191 return api.node.DataDir() 192 } 193 194 // PublicWeb3API offers helper utils 195 type PublicWeb3API struct { 196 stack *Node 197 } 198 199 // NewPublicWeb3API creates a new Web3Service instance 200 func NewPublicWeb3API(stack *Node) *PublicWeb3API { 201 return &PublicWeb3API{stack} 202 } 203 204 // ClientVersion returns the node name 205 func (s *PublicWeb3API) ClientVersion() string { 206 return s.stack.Server().Name 207 } 208 209 // Sha3 applies the ethereum sha3 implementation on the input. 210 // It assumes the input is hex encoded. 211 func (s *PublicWeb3API) Sha3(input string) string { 212 return common.ToHex(crypto.Keccak256(common.FromHex(input))) 213 }