node.go 21 KB

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