node.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717
  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
  17. import (
  18. "context"
  19. "errors"
  20. "fmt"
  21. "net"
  22. "net/http"
  23. "os"
  24. "path/filepath"
  25. "reflect"
  26. "strings"
  27. "sync"
  28. "github.com/ethereum/go-ethereum/accounts"
  29. "github.com/ethereum/go-ethereum/core/rawdb"
  30. "github.com/ethereum/go-ethereum/ethdb"
  31. "github.com/ethereum/go-ethereum/event"
  32. "github.com/ethereum/go-ethereum/internal/debug"
  33. "github.com/ethereum/go-ethereum/log"
  34. "github.com/ethereum/go-ethereum/p2p"
  35. "github.com/ethereum/go-ethereum/rpc"
  36. "github.com/prometheus/tsdb/fileutil"
  37. )
  38. // Node is a container on which services can be registered.
  39. type Node struct {
  40. eventmux *event.TypeMux // Event multiplexer used between the services of a stack
  41. config *Config
  42. accman *accounts.Manager
  43. ephemeralKeystore string // if non-empty, the key directory that will be removed by Stop
  44. instanceDirLock fileutil.Releaser // prevents concurrent use of instance directory
  45. serverConfig p2p.Config
  46. server *p2p.Server // Currently running P2P networking layer
  47. serviceFuncs []ServiceConstructor // Service constructors (in dependency order)
  48. services map[reflect.Type]Service // Currently running services
  49. rpcAPIs []rpc.API // List of APIs currently provided by the node
  50. inprocHandler *rpc.Server // In-process RPC request handler to process the API requests
  51. ipcEndpoint string // IPC endpoint to listen at (empty = IPC disabled)
  52. ipcListener net.Listener // IPC RPC listener socket to serve API requests
  53. ipcHandler *rpc.Server // IPC RPC request handler to process the API requests
  54. httpEndpoint string // HTTP endpoint (interface + port) to listen at (empty = HTTP disabled)
  55. httpWhitelist []string // HTTP RPC modules to allow through this endpoint
  56. httpListenerAddr net.Addr // Address of HTTP RPC listener socket serving API requests
  57. httpServer *http.Server // HTTP RPC HTTP server
  58. httpHandler *rpc.Server // HTTP RPC request handler to process the API requests
  59. wsEndpoint string // WebSocket endpoint (interface + port) to listen at (empty = WebSocket disabled)
  60. wsListenerAddr net.Addr // Address of WebSocket RPC listener socket serving API requests
  61. wsHTTPServer *http.Server // WebSocket RPC HTTP server
  62. wsHandler *rpc.Server // WebSocket RPC request handler to process the API requests
  63. stop chan struct{} // Channel to wait for termination notifications
  64. lock sync.RWMutex
  65. log log.Logger
  66. }
  67. // New creates a new P2P node, ready for protocol registration.
  68. func New(conf *Config) (*Node, error) {
  69. // Copy config and resolve the datadir so future changes to the current
  70. // working directory don't affect the node.
  71. confCopy := *conf
  72. conf = &confCopy
  73. if conf.DataDir != "" {
  74. absdatadir, err := filepath.Abs(conf.DataDir)
  75. if err != nil {
  76. return nil, err
  77. }
  78. conf.DataDir = absdatadir
  79. }
  80. // Ensure that the instance name doesn't cause weird conflicts with
  81. // other files in the data directory.
  82. if strings.ContainsAny(conf.Name, `/\`) {
  83. return nil, errors.New(`Config.Name must not contain '/' or '\'`)
  84. }
  85. if conf.Name == datadirDefaultKeyStore {
  86. return nil, errors.New(`Config.Name cannot be "` + datadirDefaultKeyStore + `"`)
  87. }
  88. if strings.HasSuffix(conf.Name, ".ipc") {
  89. return nil, errors.New(`Config.Name cannot end in ".ipc"`)
  90. }
  91. // Ensure that the AccountManager method works before the node has started.
  92. // We rely on this in cmd/geth.
  93. am, ephemeralKeystore, err := makeAccountManager(conf)
  94. if err != nil {
  95. return nil, err
  96. }
  97. if conf.Logger == nil {
  98. conf.Logger = log.New()
  99. }
  100. // Note: any interaction with Config that would create/touch files
  101. // in the data directory or instance directory is delayed until Start.
  102. return &Node{
  103. accman: am,
  104. ephemeralKeystore: ephemeralKeystore,
  105. config: conf,
  106. serviceFuncs: []ServiceConstructor{},
  107. ipcEndpoint: conf.IPCEndpoint(),
  108. httpEndpoint: conf.HTTPEndpoint(),
  109. wsEndpoint: conf.WSEndpoint(),
  110. eventmux: new(event.TypeMux),
  111. log: conf.Logger,
  112. }, nil
  113. }
  114. // Close stops the Node and releases resources acquired in
  115. // Node constructor New.
  116. func (n *Node) Close() error {
  117. var errs []error
  118. // Terminate all subsystems and collect any errors
  119. if err := n.Stop(); err != nil && err != ErrNodeStopped {
  120. errs = append(errs, err)
  121. }
  122. if err := n.accman.Close(); err != nil {
  123. errs = append(errs, err)
  124. }
  125. // Report any errors that might have occurred
  126. switch len(errs) {
  127. case 0:
  128. return nil
  129. case 1:
  130. return errs[0]
  131. default:
  132. return fmt.Errorf("%v", errs)
  133. }
  134. }
  135. // Register injects a new service into the node's stack. The service created by
  136. // the passed constructor must be unique in its type with regard to sibling ones.
  137. func (n *Node) Register(constructor ServiceConstructor) error {
  138. n.lock.Lock()
  139. defer n.lock.Unlock()
  140. if n.server != nil {
  141. return ErrNodeRunning
  142. }
  143. n.serviceFuncs = append(n.serviceFuncs, constructor)
  144. return nil
  145. }
  146. // Start creates a live P2P node and starts running it.
  147. func (n *Node) Start() error {
  148. n.lock.Lock()
  149. defer n.lock.Unlock()
  150. // Short circuit if the node's already running
  151. if n.server != nil {
  152. return ErrNodeRunning
  153. }
  154. if err := n.openDataDir(); err != nil {
  155. return err
  156. }
  157. // Initialize the p2p server. This creates the node key and
  158. // discovery databases.
  159. n.serverConfig = n.config.P2P
  160. n.serverConfig.PrivateKey = n.config.NodeKey()
  161. n.serverConfig.Name = n.config.NodeName()
  162. n.serverConfig.Logger = n.log
  163. if n.serverConfig.StaticNodes == nil {
  164. n.serverConfig.StaticNodes = n.config.StaticNodes()
  165. }
  166. if n.serverConfig.TrustedNodes == nil {
  167. n.serverConfig.TrustedNodes = n.config.TrustedNodes()
  168. }
  169. if n.serverConfig.NodeDatabase == "" {
  170. n.serverConfig.NodeDatabase = n.config.NodeDB()
  171. }
  172. running := &p2p.Server{Config: n.serverConfig}
  173. n.log.Info("Starting peer-to-peer node", "instance", n.serverConfig.Name)
  174. // Otherwise copy and specialize the P2P configuration
  175. services := make(map[reflect.Type]Service)
  176. for _, constructor := range n.serviceFuncs {
  177. // Create a new context for the particular service
  178. ctx := &ServiceContext{
  179. Config: *n.config,
  180. services: make(map[reflect.Type]Service),
  181. EventMux: n.eventmux,
  182. AccountManager: n.accman,
  183. }
  184. for kind, s := range services { // copy needed for threaded access
  185. ctx.services[kind] = s
  186. }
  187. // Construct and save the service
  188. service, err := constructor(ctx)
  189. if err != nil {
  190. return err
  191. }
  192. kind := reflect.TypeOf(service)
  193. if _, exists := services[kind]; exists {
  194. return &DuplicateServiceError{Kind: kind}
  195. }
  196. services[kind] = service
  197. }
  198. // Gather the protocols and start the freshly assembled P2P server
  199. for _, service := range services {
  200. running.Protocols = append(running.Protocols, service.Protocols()...)
  201. }
  202. if err := running.Start(); err != nil {
  203. return convertFileLockError(err)
  204. }
  205. // Start each of the services
  206. var started []reflect.Type
  207. for kind, service := range services {
  208. // Start the next service, stopping all previous upon failure
  209. if err := service.Start(running); err != nil {
  210. for _, kind := range started {
  211. services[kind].Stop()
  212. }
  213. running.Stop()
  214. return err
  215. }
  216. // Mark the service started for potential cleanup
  217. started = append(started, kind)
  218. }
  219. // Lastly, start the configured RPC interfaces
  220. if err := n.startRPC(services); err != nil {
  221. for _, service := range services {
  222. service.Stop()
  223. }
  224. running.Stop()
  225. return err
  226. }
  227. // Finish initializing the startup
  228. n.services = services
  229. n.server = running
  230. n.stop = make(chan struct{})
  231. return nil
  232. }
  233. // Config returns the configuration of node.
  234. func (n *Node) Config() *Config {
  235. return n.config
  236. }
  237. func (n *Node) openDataDir() error {
  238. if n.config.DataDir == "" {
  239. return nil // ephemeral
  240. }
  241. instdir := filepath.Join(n.config.DataDir, n.config.name())
  242. if err := os.MkdirAll(instdir, 0700); err != nil {
  243. return err
  244. }
  245. // Lock the instance directory to prevent concurrent use by another instance as well as
  246. // accidental use of the instance directory as a database.
  247. release, _, err := fileutil.Flock(filepath.Join(instdir, "LOCK"))
  248. if err != nil {
  249. return convertFileLockError(err)
  250. }
  251. n.instanceDirLock = release
  252. return nil
  253. }
  254. // startRPC is a helper method to start all the various RPC endpoints during node
  255. // startup. It's not meant to be called at any time afterwards as it makes certain
  256. // assumptions about the state of the node.
  257. func (n *Node) startRPC(services map[reflect.Type]Service) error {
  258. // Gather all the possible APIs to surface
  259. apis := n.apis()
  260. for _, service := range services {
  261. apis = append(apis, service.APIs()...)
  262. }
  263. // Start the various API endpoints, terminating all in case of errors
  264. if err := n.startInProc(apis); err != nil {
  265. return err
  266. }
  267. if err := n.startIPC(apis); err != nil {
  268. n.stopInProc()
  269. return err
  270. }
  271. if err := n.startHTTP(n.httpEndpoint, apis, n.config.HTTPModules, n.config.HTTPCors, n.config.HTTPVirtualHosts, n.config.HTTPTimeouts, n.config.WSOrigins); err != nil {
  272. n.stopIPC()
  273. n.stopInProc()
  274. return err
  275. }
  276. // if endpoints are not the same, start separate servers
  277. if n.httpEndpoint != n.wsEndpoint {
  278. if err := n.startWS(n.wsEndpoint, apis, n.config.WSModules, n.config.WSOrigins, n.config.WSExposeAll); err != nil {
  279. n.stopHTTP()
  280. n.stopIPC()
  281. n.stopInProc()
  282. return err
  283. }
  284. }
  285. // All API endpoints started successfully
  286. n.rpcAPIs = apis
  287. return nil
  288. }
  289. // startInProc initializes an in-process RPC endpoint.
  290. func (n *Node) startInProc(apis []rpc.API) error {
  291. // Register all the APIs exposed by the services
  292. handler := rpc.NewServer()
  293. for _, api := range apis {
  294. if err := handler.RegisterName(api.Namespace, api.Service); err != nil {
  295. return err
  296. }
  297. n.log.Debug("InProc registered", "namespace", api.Namespace)
  298. }
  299. n.inprocHandler = handler
  300. return nil
  301. }
  302. // stopInProc terminates the in-process RPC endpoint.
  303. func (n *Node) stopInProc() {
  304. if n.inprocHandler != nil {
  305. n.inprocHandler.Stop()
  306. n.inprocHandler = nil
  307. }
  308. }
  309. // startIPC initializes and starts the IPC RPC endpoint.
  310. func (n *Node) startIPC(apis []rpc.API) error {
  311. if n.ipcEndpoint == "" {
  312. return nil // IPC disabled.
  313. }
  314. listener, handler, err := rpc.StartIPCEndpoint(n.ipcEndpoint, apis)
  315. if err != nil {
  316. return err
  317. }
  318. n.ipcListener = listener
  319. n.ipcHandler = handler
  320. n.log.Info("IPC endpoint opened", "url", n.ipcEndpoint)
  321. return nil
  322. }
  323. // stopIPC terminates the IPC RPC endpoint.
  324. func (n *Node) stopIPC() {
  325. if n.ipcListener != nil {
  326. n.ipcListener.Close()
  327. n.ipcListener = nil
  328. n.log.Info("IPC endpoint closed", "url", n.ipcEndpoint)
  329. }
  330. if n.ipcHandler != nil {
  331. n.ipcHandler.Stop()
  332. n.ipcHandler = nil
  333. }
  334. }
  335. // startHTTP initializes and starts the HTTP RPC endpoint.
  336. func (n *Node) startHTTP(endpoint string, apis []rpc.API, modules []string, cors []string, vhosts []string, timeouts rpc.HTTPTimeouts, wsOrigins []string) error {
  337. // Short circuit if the HTTP endpoint isn't being exposed
  338. if endpoint == "" {
  339. return nil
  340. }
  341. // register apis and create handler stack
  342. srv := rpc.NewServer()
  343. err := RegisterApisFromWhitelist(apis, modules, srv, false)
  344. if err != nil {
  345. return err
  346. }
  347. handler := NewHTTPHandlerStack(srv, cors, vhosts)
  348. // wrap handler in WebSocket handler only if WebSocket port is the same as http rpc
  349. if n.httpEndpoint == n.wsEndpoint {
  350. handler = NewWebsocketUpgradeHandler(handler, srv.WebsocketHandler(wsOrigins))
  351. }
  352. httpServer, addr, err := StartHTTPEndpoint(endpoint, timeouts, handler)
  353. if err != nil {
  354. return err
  355. }
  356. n.log.Info("HTTP endpoint opened", "url", fmt.Sprintf("http://%v/", addr),
  357. "cors", strings.Join(cors, ","),
  358. "vhosts", strings.Join(vhosts, ","))
  359. if n.httpEndpoint == n.wsEndpoint {
  360. n.log.Info("WebSocket endpoint opened", "url", fmt.Sprintf("ws://%v", addr))
  361. }
  362. // All listeners booted successfully
  363. n.httpEndpoint = endpoint
  364. n.httpListenerAddr = addr
  365. n.httpServer = httpServer
  366. n.httpHandler = srv
  367. return nil
  368. }
  369. // stopHTTP terminates the HTTP RPC endpoint.
  370. func (n *Node) stopHTTP() {
  371. if n.httpServer != nil {
  372. // Don't bother imposing a timeout here.
  373. n.httpServer.Shutdown(context.Background())
  374. n.log.Info("HTTP endpoint closed", "url", fmt.Sprintf("http://%v/", n.httpListenerAddr))
  375. }
  376. if n.httpHandler != nil {
  377. n.httpHandler.Stop()
  378. n.httpHandler = nil
  379. }
  380. }
  381. // startWS initializes and starts the WebSocket RPC endpoint.
  382. func (n *Node) startWS(endpoint string, apis []rpc.API, modules []string, wsOrigins []string, exposeAll bool) error {
  383. // Short circuit if the WS endpoint isn't being exposed
  384. if endpoint == "" {
  385. return nil
  386. }
  387. srv := rpc.NewServer()
  388. handler := srv.WebsocketHandler(wsOrigins)
  389. err := RegisterApisFromWhitelist(apis, modules, srv, exposeAll)
  390. if err != nil {
  391. return err
  392. }
  393. httpServer, addr, err := startWSEndpoint(endpoint, handler)
  394. if err != nil {
  395. return err
  396. }
  397. n.log.Info("WebSocket endpoint opened", "url", fmt.Sprintf("ws://%v", addr))
  398. // All listeners booted successfully
  399. n.wsEndpoint = endpoint
  400. n.wsListenerAddr = addr
  401. n.wsHTTPServer = httpServer
  402. n.wsHandler = srv
  403. return nil
  404. }
  405. // stopWS terminates the WebSocket RPC endpoint.
  406. func (n *Node) stopWS() {
  407. if n.wsHTTPServer != nil {
  408. // Don't bother imposing a timeout here.
  409. n.wsHTTPServer.Shutdown(context.Background())
  410. n.log.Info("WebSocket endpoint closed", "url", fmt.Sprintf("ws://%v", n.wsListenerAddr))
  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. // Terminate the API, services and the p2p server.
  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. // Release instance directory lock.
  443. if n.instanceDirLock != nil {
  444. if err := n.instanceDirLock.Release(); err != nil {
  445. n.log.Error("Can't release datadir lock", "err", err)
  446. }
  447. n.instanceDirLock = nil
  448. }
  449. // unblock n.Wait
  450. close(n.stop)
  451. // Remove the keystore if it was created ephemerally.
  452. var keystoreErr error
  453. if n.ephemeralKeystore != "" {
  454. keystoreErr = os.RemoveAll(n.ephemeralKeystore)
  455. }
  456. if len(failure.Services) > 0 {
  457. return failure
  458. }
  459. if keystoreErr != nil {
  460. return keystoreErr
  461. }
  462. return nil
  463. }
  464. // Wait blocks the thread until the node is stopped. If the node is not running
  465. // at the time of invocation, the method immediately returns.
  466. func (n *Node) Wait() {
  467. n.lock.RLock()
  468. if n.server == nil {
  469. n.lock.RUnlock()
  470. return
  471. }
  472. stop := n.stop
  473. n.lock.RUnlock()
  474. <-stop
  475. }
  476. // Restart terminates a running node and boots up a new one in its place. If the
  477. // node isn't running, an error is returned.
  478. func (n *Node) Restart() error {
  479. if err := n.Stop(); err != nil {
  480. return err
  481. }
  482. if err := n.Start(); err != nil {
  483. return err
  484. }
  485. return nil
  486. }
  487. // Attach creates an RPC client attached to an in-process API handler.
  488. func (n *Node) Attach() (*rpc.Client, error) {
  489. n.lock.RLock()
  490. defer n.lock.RUnlock()
  491. if n.server == nil {
  492. return nil, ErrNodeStopped
  493. }
  494. return rpc.DialInProc(n.inprocHandler), nil
  495. }
  496. // RPCHandler returns the in-process RPC request handler.
  497. func (n *Node) RPCHandler() (*rpc.Server, error) {
  498. n.lock.RLock()
  499. defer n.lock.RUnlock()
  500. if n.inprocHandler == nil {
  501. return nil, ErrNodeStopped
  502. }
  503. return n.inprocHandler, nil
  504. }
  505. // Server retrieves the currently running P2P network layer. This method is meant
  506. // only to inspect fields of the currently running server, life cycle management
  507. // should be left to this Node entity.
  508. func (n *Node) Server() *p2p.Server {
  509. n.lock.RLock()
  510. defer n.lock.RUnlock()
  511. return n.server
  512. }
  513. // Service retrieves a currently running service registered of a specific type.
  514. func (n *Node) Service(service interface{}) error {
  515. n.lock.RLock()
  516. defer n.lock.RUnlock()
  517. // Short circuit if the node's not running
  518. if n.server == nil {
  519. return ErrNodeStopped
  520. }
  521. // Otherwise try to find the service to return
  522. element := reflect.ValueOf(service).Elem()
  523. if running, ok := n.services[element.Type()]; ok {
  524. element.Set(reflect.ValueOf(running))
  525. return nil
  526. }
  527. return ErrServiceUnknown
  528. }
  529. // DataDir retrieves the current datadir used by the protocol stack.
  530. // Deprecated: No files should be stored in this directory, use InstanceDir instead.
  531. func (n *Node) DataDir() string {
  532. return n.config.DataDir
  533. }
  534. // InstanceDir retrieves the instance directory used by the protocol stack.
  535. func (n *Node) InstanceDir() string {
  536. return n.config.instanceDir()
  537. }
  538. // AccountManager retrieves the account manager used by the protocol stack.
  539. func (n *Node) AccountManager() *accounts.Manager {
  540. return n.accman
  541. }
  542. // IPCEndpoint retrieves the current IPC endpoint used by the protocol stack.
  543. func (n *Node) IPCEndpoint() string {
  544. return n.ipcEndpoint
  545. }
  546. // HTTPEndpoint retrieves the current HTTP endpoint used by the protocol stack.
  547. func (n *Node) HTTPEndpoint() string {
  548. n.lock.Lock()
  549. defer n.lock.Unlock()
  550. if n.httpListenerAddr != nil {
  551. return n.httpListenerAddr.String()
  552. }
  553. return n.httpEndpoint
  554. }
  555. // WSEndpoint retrieves the current WS endpoint used by the protocol stack.
  556. func (n *Node) WSEndpoint() string {
  557. n.lock.Lock()
  558. defer n.lock.Unlock()
  559. if n.wsListenerAddr != nil {
  560. return n.wsListenerAddr.String()
  561. }
  562. return n.wsEndpoint
  563. }
  564. // EventMux retrieves the event multiplexer used by all the network services in
  565. // the current protocol stack.
  566. func (n *Node) EventMux() *event.TypeMux {
  567. return n.eventmux
  568. }
  569. // OpenDatabase opens an existing database with the given name (or creates one if no
  570. // previous can be found) from within the node's instance directory. If the node is
  571. // ephemeral, a memory database is returned.
  572. func (n *Node) OpenDatabase(name string, cache, handles int, namespace string) (ethdb.Database, error) {
  573. if n.config.DataDir == "" {
  574. return rawdb.NewMemoryDatabase(), nil
  575. }
  576. return rawdb.NewLevelDBDatabase(n.config.ResolvePath(name), cache, handles, namespace)
  577. }
  578. // OpenDatabaseWithFreezer opens an existing database with the given name (or
  579. // creates one if no previous can be found) from within the node's data directory,
  580. // also attaching a chain freezer to it that moves ancient chain data from the
  581. // database to immutable append-only files. If the node is an ephemeral one, a
  582. // memory database is returned.
  583. func (n *Node) OpenDatabaseWithFreezer(name string, cache, handles int, freezer, namespace string) (ethdb.Database, error) {
  584. if n.config.DataDir == "" {
  585. return rawdb.NewMemoryDatabase(), nil
  586. }
  587. root := n.config.ResolvePath(name)
  588. switch {
  589. case freezer == "":
  590. freezer = filepath.Join(root, "ancient")
  591. case !filepath.IsAbs(freezer):
  592. freezer = n.config.ResolvePath(freezer)
  593. }
  594. return rawdb.NewLevelDBDatabaseWithFreezer(root, cache, handles, freezer, namespace)
  595. }
  596. // ResolvePath returns the absolute path of a resource in the instance directory.
  597. func (n *Node) ResolvePath(x string) string {
  598. return n.config.ResolvePath(x)
  599. }
  600. // apis returns the collection of RPC descriptors this node offers.
  601. func (n *Node) apis() []rpc.API {
  602. return []rpc.API{
  603. {
  604. Namespace: "admin",
  605. Version: "1.0",
  606. Service: NewPrivateAdminAPI(n),
  607. }, {
  608. Namespace: "admin",
  609. Version: "1.0",
  610. Service: NewPublicAdminAPI(n),
  611. Public: true,
  612. }, {
  613. Namespace: "debug",
  614. Version: "1.0",
  615. Service: debug.Handler,
  616. }, {
  617. Namespace: "web3",
  618. Version: "1.0",
  619. Service: NewPublicWeb3API(n),
  620. Public: true,
  621. },
  622. }
  623. }
  624. // RegisterApisFromWhitelist checks the given modules' availability, generates a whitelist based on the allowed modules,
  625. // and then registers all of the APIs exposed by the services.
  626. func RegisterApisFromWhitelist(apis []rpc.API, modules []string, srv *rpc.Server, exposeAll bool) error {
  627. if bad, available := checkModuleAvailability(modules, apis); len(bad) > 0 {
  628. log.Error("Unavailable modules in HTTP API list", "unavailable", bad, "available", available)
  629. }
  630. // Generate the whitelist based on the allowed modules
  631. whitelist := make(map[string]bool)
  632. for _, module := range modules {
  633. whitelist[module] = true
  634. }
  635. // Register all the APIs exposed by the services
  636. for _, api := range apis {
  637. if exposeAll || whitelist[api.Namespace] || (len(whitelist) == 0 && api.Public) {
  638. if err := srv.RegisterName(api.Namespace, api.Service); err != nil {
  639. return err
  640. }
  641. }
  642. }
  643. return nil
  644. }