node.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626
  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. // Package node represents the Ethereum protocol stack container.
  17. package node
  18. import (
  19. "errors"
  20. "net"
  21. "os"
  22. "path/filepath"
  23. "reflect"
  24. "sync"
  25. "syscall"
  26. "github.com/ethereum/go-ethereum/accounts"
  27. "github.com/ethereum/go-ethereum/event"
  28. "github.com/ethereum/go-ethereum/internal/debug"
  29. "github.com/ethereum/go-ethereum/logger"
  30. "github.com/ethereum/go-ethereum/logger/glog"
  31. "github.com/ethereum/go-ethereum/p2p"
  32. "github.com/ethereum/go-ethereum/rpc"
  33. )
  34. var (
  35. ErrDatadirUsed = errors.New("datadir already used")
  36. ErrNodeStopped = errors.New("node not started")
  37. ErrNodeRunning = errors.New("node already running")
  38. ErrServiceUnknown = errors.New("unknown service")
  39. datadirInUseErrnos = map[uint]bool{11: true, 32: true, 35: true}
  40. )
  41. // Node represents a P2P node into which arbitrary (uniquely typed) services might
  42. // be registered.
  43. type Node struct {
  44. datadir string // Path to the currently used data directory
  45. eventmux *event.TypeMux // Event multiplexer used between the services of a stack
  46. accman *accounts.Manager
  47. ephemeralKeystore string // if non-empty, the key directory that will be removed by Stop
  48. serverConfig p2p.Config
  49. server *p2p.Server // Currently running P2P networking layer
  50. serviceFuncs []ServiceConstructor // Service constructors (in dependency order)
  51. services map[reflect.Type]Service // Currently running services
  52. rpcAPIs []rpc.API // List of APIs currently provided by the node
  53. inprocHandler *rpc.Server // In-process RPC request handler to process the API requests
  54. ipcEndpoint string // IPC endpoint to listen at (empty = IPC disabled)
  55. ipcListener net.Listener // IPC RPC listener socket to serve API requests
  56. ipcHandler *rpc.Server // IPC RPC request handler to process the API requests
  57. httpHost string // HTTP hostname
  58. httpPort int // HTTP post
  59. httpEndpoint string // HTTP endpoint (interface + port) to listen at (empty = HTTP disabled)
  60. httpWhitelist []string // HTTP RPC modules to allow through this endpoint
  61. httpCors string // HTTP RPC Cross-Origin Resource Sharing header
  62. httpListener net.Listener // HTTP RPC listener socket to server API requests
  63. httpHandler *rpc.Server // HTTP RPC request handler to process the API requests
  64. wsHost string // Websocket host
  65. wsPort int // Websocket post
  66. wsEndpoint string // Websocket endpoint (interface + port) to listen at (empty = websocket disabled)
  67. wsWhitelist []string // Websocket RPC modules to allow through this endpoint
  68. wsOrigins string // Websocket RPC allowed origin domains
  69. wsListener net.Listener // Websocket RPC listener socket to server API requests
  70. wsHandler *rpc.Server // Websocket RPC request handler to process the API requests
  71. stop chan struct{} // Channel to wait for termination notifications
  72. lock sync.RWMutex
  73. }
  74. // New creates a new P2P node, ready for protocol registration.
  75. func New(conf *Config) (*Node, error) {
  76. // Ensure the data directory exists, failing if it cannot be created
  77. if conf.DataDir != "" {
  78. if err := os.MkdirAll(conf.DataDir, 0700); err != nil {
  79. return nil, err
  80. }
  81. }
  82. am, ephemeralKeystore, err := makeAccountManager(conf)
  83. if err != nil {
  84. return nil, err
  85. }
  86. // Assemble the networking layer and the node itself
  87. nodeDbPath := ""
  88. if conf.DataDir != "" {
  89. nodeDbPath = filepath.Join(conf.DataDir, datadirNodeDatabase)
  90. }
  91. return &Node{
  92. datadir: conf.DataDir,
  93. accman: am,
  94. ephemeralKeystore: ephemeralKeystore,
  95. serverConfig: p2p.Config{
  96. PrivateKey: conf.NodeKey(),
  97. Name: conf.Name,
  98. Discovery: !conf.NoDiscovery,
  99. BootstrapNodes: conf.BootstrapNodes,
  100. StaticNodes: conf.StaticNodes(),
  101. TrustedNodes: conf.TrusterNodes(),
  102. NodeDatabase: nodeDbPath,
  103. ListenAddr: conf.ListenAddr,
  104. NAT: conf.NAT,
  105. Dialer: conf.Dialer,
  106. NoDial: conf.NoDial,
  107. MaxPeers: conf.MaxPeers,
  108. MaxPendingPeers: conf.MaxPendingPeers,
  109. },
  110. serviceFuncs: []ServiceConstructor{},
  111. ipcEndpoint: conf.IPCEndpoint(),
  112. httpHost: conf.HTTPHost,
  113. httpPort: conf.HTTPPort,
  114. httpEndpoint: conf.HTTPEndpoint(),
  115. httpWhitelist: conf.HTTPModules,
  116. httpCors: conf.HTTPCors,
  117. wsHost: conf.WSHost,
  118. wsPort: conf.WSPort,
  119. wsEndpoint: conf.WSEndpoint(),
  120. wsWhitelist: conf.WSModules,
  121. wsOrigins: conf.WSOrigins,
  122. eventmux: new(event.TypeMux),
  123. }, nil
  124. }
  125. // Register injects a new service into the node's stack. The service created by
  126. // the passed constructor must be unique in its type with regard to sibling ones.
  127. func (n *Node) Register(constructor ServiceConstructor) error {
  128. n.lock.Lock()
  129. defer n.lock.Unlock()
  130. if n.server != nil {
  131. return ErrNodeRunning
  132. }
  133. n.serviceFuncs = append(n.serviceFuncs, constructor)
  134. return nil
  135. }
  136. // Start create a live P2P node and starts running it.
  137. func (n *Node) Start() error {
  138. n.lock.Lock()
  139. defer n.lock.Unlock()
  140. // Short circuit if the node's already running
  141. if n.server != nil {
  142. return ErrNodeRunning
  143. }
  144. // Otherwise copy and specialize the P2P configuration
  145. running := &p2p.Server{Config: n.serverConfig}
  146. services := make(map[reflect.Type]Service)
  147. for _, constructor := range n.serviceFuncs {
  148. // Create a new context for the particular service
  149. ctx := &ServiceContext{
  150. datadir: n.datadir,
  151. services: make(map[reflect.Type]Service),
  152. EventMux: n.eventmux,
  153. AccountManager: n.accman,
  154. }
  155. for kind, s := range services { // copy needed for threaded access
  156. ctx.services[kind] = s
  157. }
  158. // Construct and save the service
  159. service, err := constructor(ctx)
  160. if err != nil {
  161. return err
  162. }
  163. kind := reflect.TypeOf(service)
  164. if _, exists := services[kind]; exists {
  165. return &DuplicateServiceError{Kind: kind}
  166. }
  167. services[kind] = service
  168. }
  169. // Gather the protocols and start the freshly assembled P2P server
  170. for _, service := range services {
  171. running.Protocols = append(running.Protocols, service.Protocols()...)
  172. }
  173. if err := running.Start(); err != nil {
  174. if errno, ok := err.(syscall.Errno); ok && datadirInUseErrnos[uint(errno)] {
  175. return ErrDatadirUsed
  176. }
  177. return err
  178. }
  179. // Start each of the services
  180. started := []reflect.Type{}
  181. for kind, service := range services {
  182. // Start the next service, stopping all previous upon failure
  183. if err := service.Start(running); err != nil {
  184. for _, kind := range started {
  185. services[kind].Stop()
  186. }
  187. running.Stop()
  188. return err
  189. }
  190. // Mark the service started for potential cleanup
  191. started = append(started, kind)
  192. }
  193. // Lastly start the configured RPC interfaces
  194. if err := n.startRPC(services); err != nil {
  195. for _, service := range services {
  196. service.Stop()
  197. }
  198. running.Stop()
  199. return err
  200. }
  201. // Finish initializing the startup
  202. n.services = services
  203. n.server = running
  204. n.stop = make(chan struct{})
  205. return nil
  206. }
  207. // startRPC is a helper method to start all the various RPC endpoint during node
  208. // startup. It's not meant to be called at any time afterwards as it makes certain
  209. // assumptions about the state of the node.
  210. func (n *Node) startRPC(services map[reflect.Type]Service) error {
  211. // Gather all the possible APIs to surface
  212. apis := n.apis()
  213. for _, service := range services {
  214. apis = append(apis, service.APIs()...)
  215. }
  216. // Start the various API endpoints, terminating all in case of errors
  217. if err := n.startInProc(apis); err != nil {
  218. return err
  219. }
  220. if err := n.startIPC(apis); err != nil {
  221. n.stopInProc()
  222. return err
  223. }
  224. if err := n.startHTTP(n.httpEndpoint, apis, n.httpWhitelist, n.httpCors); err != nil {
  225. n.stopIPC()
  226. n.stopInProc()
  227. return err
  228. }
  229. if err := n.startWS(n.wsEndpoint, apis, n.wsWhitelist, n.wsOrigins); err != nil {
  230. n.stopHTTP()
  231. n.stopIPC()
  232. n.stopInProc()
  233. return err
  234. }
  235. // All API endpoints started successfully
  236. n.rpcAPIs = apis
  237. return nil
  238. }
  239. // startInProc initializes an in-process RPC endpoint.
  240. func (n *Node) startInProc(apis []rpc.API) error {
  241. // Register all the APIs exposed by the services
  242. handler := rpc.NewServer()
  243. for _, api := range apis {
  244. if err := handler.RegisterName(api.Namespace, api.Service); err != nil {
  245. return err
  246. }
  247. glog.V(logger.Debug).Infof("InProc registered %T under '%s'", api.Service, api.Namespace)
  248. }
  249. n.inprocHandler = handler
  250. return nil
  251. }
  252. // stopInProc terminates the in-process RPC endpoint.
  253. func (n *Node) stopInProc() {
  254. if n.inprocHandler != nil {
  255. n.inprocHandler.Stop()
  256. n.inprocHandler = nil
  257. }
  258. }
  259. // startIPC initializes and starts the IPC RPC endpoint.
  260. func (n *Node) startIPC(apis []rpc.API) error {
  261. // Short circuit if the IPC endpoint isn't being exposed
  262. if n.ipcEndpoint == "" {
  263. return nil
  264. }
  265. // Register all the APIs exposed by the services
  266. handler := rpc.NewServer()
  267. for _, api := range apis {
  268. if err := handler.RegisterName(api.Namespace, api.Service); err != nil {
  269. return err
  270. }
  271. glog.V(logger.Debug).Infof("IPC registered %T under '%s'", api.Service, api.Namespace)
  272. }
  273. // All APIs registered, start the IPC listener
  274. var (
  275. listener net.Listener
  276. err error
  277. )
  278. if listener, err = rpc.CreateIPCListener(n.ipcEndpoint); err != nil {
  279. return err
  280. }
  281. go func() {
  282. glog.V(logger.Info).Infof("IPC endpoint opened: %s", n.ipcEndpoint)
  283. for {
  284. conn, err := listener.Accept()
  285. if err != nil {
  286. // Terminate if the listener was closed
  287. n.lock.RLock()
  288. closed := n.ipcListener == nil
  289. n.lock.RUnlock()
  290. if closed {
  291. return
  292. }
  293. // Not closed, just some error; report and continue
  294. glog.V(logger.Error).Infof("IPC accept failed: %v", err)
  295. continue
  296. }
  297. go handler.ServeCodec(rpc.NewJSONCodec(conn), rpc.OptionMethodInvocation|rpc.OptionSubscriptions)
  298. }
  299. }()
  300. // All listeners booted successfully
  301. n.ipcListener = listener
  302. n.ipcHandler = handler
  303. return nil
  304. }
  305. // stopIPC terminates the IPC RPC endpoint.
  306. func (n *Node) stopIPC() {
  307. if n.ipcListener != nil {
  308. n.ipcListener.Close()
  309. n.ipcListener = nil
  310. glog.V(logger.Info).Infof("IPC endpoint closed: %s", n.ipcEndpoint)
  311. }
  312. if n.ipcHandler != nil {
  313. n.ipcHandler.Stop()
  314. n.ipcHandler = nil
  315. }
  316. }
  317. // startHTTP initializes and starts the HTTP RPC endpoint.
  318. func (n *Node) startHTTP(endpoint string, apis []rpc.API, modules []string, cors string) error {
  319. // Short circuit if the HTTP endpoint isn't being exposed
  320. if endpoint == "" {
  321. return nil
  322. }
  323. // Generate the whitelist based on the allowed modules
  324. whitelist := make(map[string]bool)
  325. for _, module := range modules {
  326. whitelist[module] = true
  327. }
  328. // Register all the APIs exposed by the services
  329. handler := rpc.NewServer()
  330. for _, api := range apis {
  331. if whitelist[api.Namespace] || (len(whitelist) == 0 && api.Public) {
  332. if err := handler.RegisterName(api.Namespace, api.Service); err != nil {
  333. return err
  334. }
  335. glog.V(logger.Debug).Infof("HTTP registered %T under '%s'", api.Service, api.Namespace)
  336. }
  337. }
  338. // All APIs registered, start the HTTP listener
  339. var (
  340. listener net.Listener
  341. err error
  342. )
  343. if listener, err = net.Listen("tcp", endpoint); err != nil {
  344. return err
  345. }
  346. go rpc.NewHTTPServer(cors, handler).Serve(listener)
  347. glog.V(logger.Info).Infof("HTTP endpoint opened: http://%s", endpoint)
  348. // All listeners booted successfully
  349. n.httpEndpoint = endpoint
  350. n.httpListener = listener
  351. n.httpHandler = handler
  352. n.httpCors = cors
  353. return nil
  354. }
  355. // stopHTTP terminates the HTTP RPC endpoint.
  356. func (n *Node) stopHTTP() {
  357. if n.httpListener != nil {
  358. n.httpListener.Close()
  359. n.httpListener = nil
  360. glog.V(logger.Info).Infof("HTTP endpoint closed: http://%s", n.httpEndpoint)
  361. }
  362. if n.httpHandler != nil {
  363. n.httpHandler.Stop()
  364. n.httpHandler = nil
  365. }
  366. }
  367. // startWS initializes and starts the websocket RPC endpoint.
  368. func (n *Node) startWS(endpoint string, apis []rpc.API, modules []string, wsOrigins string) error {
  369. // Short circuit if the WS endpoint isn't being exposed
  370. if endpoint == "" {
  371. return nil
  372. }
  373. // Generate the whitelist based on the allowed modules
  374. whitelist := make(map[string]bool)
  375. for _, module := range modules {
  376. whitelist[module] = true
  377. }
  378. // Register all the APIs exposed by the services
  379. handler := rpc.NewServer()
  380. for _, api := range apis {
  381. if whitelist[api.Namespace] || (len(whitelist) == 0 && api.Public) {
  382. if err := handler.RegisterName(api.Namespace, api.Service); err != nil {
  383. return err
  384. }
  385. glog.V(logger.Debug).Infof("WebSocket registered %T under '%s'", api.Service, api.Namespace)
  386. }
  387. }
  388. // All APIs registered, start the HTTP listener
  389. var (
  390. listener net.Listener
  391. err error
  392. )
  393. if listener, err = net.Listen("tcp", endpoint); err != nil {
  394. return err
  395. }
  396. go rpc.NewWSServer(wsOrigins, handler).Serve(listener)
  397. glog.V(logger.Info).Infof("WebSocket endpoint opened: ws://%s", endpoint)
  398. // All listeners booted successfully
  399. n.wsEndpoint = endpoint
  400. n.wsListener = listener
  401. n.wsHandler = handler
  402. n.wsOrigins = wsOrigins
  403. return nil
  404. }
  405. // stopWS terminates the websocket RPC endpoint.
  406. func (n *Node) stopWS() {
  407. if n.wsListener != nil {
  408. n.wsListener.Close()
  409. n.wsListener = nil
  410. glog.V(logger.Info).Infof("WebSocket endpoint closed: ws://%s", n.wsEndpoint)
  411. }
  412. if n.wsHandler != nil {
  413. n.wsHandler.Stop()
  414. n.wsHandler = nil
  415. }
  416. }
  417. // Stop terminates a running node along with all it's services. In the node was
  418. // not started, an error is returned.
  419. func (n *Node) Stop() error {
  420. n.lock.Lock()
  421. defer n.lock.Unlock()
  422. // Short circuit if the node's not running
  423. if n.server == nil {
  424. return ErrNodeStopped
  425. }
  426. // Otherwise terminate the API, all services and the P2P server too
  427. n.stopWS()
  428. n.stopHTTP()
  429. n.stopIPC()
  430. n.rpcAPIs = nil
  431. failure := &StopError{
  432. Services: make(map[reflect.Type]error),
  433. }
  434. for kind, service := range n.services {
  435. if err := service.Stop(); err != nil {
  436. failure.Services[kind] = err
  437. }
  438. }
  439. n.server.Stop()
  440. n.services = nil
  441. n.server = nil
  442. close(n.stop)
  443. // Remove the keystore if it was created ephemerally.
  444. var keystoreErr error
  445. if n.ephemeralKeystore != "" {
  446. keystoreErr = os.RemoveAll(n.ephemeralKeystore)
  447. }
  448. if len(failure.Services) > 0 {
  449. return failure
  450. }
  451. if keystoreErr != nil {
  452. return keystoreErr
  453. }
  454. return nil
  455. }
  456. // Wait blocks the thread until the node is stopped. If the node is not running
  457. // at the time of invocation, the method immediately returns.
  458. func (n *Node) Wait() {
  459. n.lock.RLock()
  460. if n.server == nil {
  461. return
  462. }
  463. stop := n.stop
  464. n.lock.RUnlock()
  465. <-stop
  466. }
  467. // Restart terminates a running node and boots up a new one in its place. If the
  468. // node isn't running, an error is returned.
  469. func (n *Node) Restart() error {
  470. if err := n.Stop(); err != nil {
  471. return err
  472. }
  473. if err := n.Start(); err != nil {
  474. return err
  475. }
  476. return nil
  477. }
  478. // Attach creates an RPC client attached to an in-process API handler.
  479. func (n *Node) Attach() (*rpc.Client, error) {
  480. n.lock.RLock()
  481. defer n.lock.RUnlock()
  482. if n.server == nil {
  483. return nil, ErrNodeStopped
  484. }
  485. return rpc.DialInProc(n.inprocHandler), nil
  486. }
  487. // Server retrieves the currently running P2P network layer. This method is meant
  488. // only to inspect fields of the currently running server, life cycle management
  489. // should be left to this Node entity.
  490. func (n *Node) Server() *p2p.Server {
  491. n.lock.RLock()
  492. defer n.lock.RUnlock()
  493. return n.server
  494. }
  495. // Service retrieves a currently running service registered of a specific type.
  496. func (n *Node) Service(service interface{}) error {
  497. n.lock.RLock()
  498. defer n.lock.RUnlock()
  499. // Short circuit if the node's not running
  500. if n.server == nil {
  501. return ErrNodeStopped
  502. }
  503. // Otherwise try to find the service to return
  504. element := reflect.ValueOf(service).Elem()
  505. if running, ok := n.services[element.Type()]; ok {
  506. element.Set(reflect.ValueOf(running))
  507. return nil
  508. }
  509. return ErrServiceUnknown
  510. }
  511. // DataDir retrieves the current datadir used by the protocol stack.
  512. func (n *Node) DataDir() string {
  513. return n.datadir
  514. }
  515. // AccountManager retrieves the account manager used by the protocol stack.
  516. func (n *Node) AccountManager() *accounts.Manager {
  517. return n.accman
  518. }
  519. // IPCEndpoint retrieves the current IPC endpoint used by the protocol stack.
  520. func (n *Node) IPCEndpoint() string {
  521. return n.ipcEndpoint
  522. }
  523. // HTTPEndpoint retrieves the current HTTP endpoint used by the protocol stack.
  524. func (n *Node) HTTPEndpoint() string {
  525. return n.httpEndpoint
  526. }
  527. // WSEndpoint retrieves the current WS endpoint used by the protocol stack.
  528. func (n *Node) WSEndpoint() string {
  529. return n.wsEndpoint
  530. }
  531. // EventMux retrieves the event multiplexer used by all the network services in
  532. // the current protocol stack.
  533. func (n *Node) EventMux() *event.TypeMux {
  534. return n.eventmux
  535. }
  536. // apis returns the collection of RPC descriptors this node offers.
  537. func (n *Node) apis() []rpc.API {
  538. return []rpc.API{
  539. {
  540. Namespace: "admin",
  541. Version: "1.0",
  542. Service: NewPrivateAdminAPI(n),
  543. }, {
  544. Namespace: "admin",
  545. Version: "1.0",
  546. Service: NewPublicAdminAPI(n),
  547. Public: true,
  548. }, {
  549. Namespace: "debug",
  550. Version: "1.0",
  551. Service: debug.Handler,
  552. }, {
  553. Namespace: "debug",
  554. Version: "1.0",
  555. Service: NewPublicDebugAPI(n),
  556. Public: true,
  557. }, {
  558. Namespace: "web3",
  559. Version: "1.0",
  560. Service: NewPublicWeb3API(n),
  561. Public: true,
  562. },
  563. }
  564. }