diff --git a/cli/server/server.go b/cli/server/server.go index 4700c49ae..1526b52f3 100644 --- a/cli/server/server.go +++ b/cli/server/server.go @@ -506,9 +506,12 @@ func startServer(ctx *cli.Context) error { } errChan := make(chan error) rpcServer := server.New(chain, cfg.ApplicationConfiguration.RPC, serv, oracleSrv, log, errChan) + serv.AddService(&rpcServer) go serv.Start(errChan) - rpcServer.Start() + if !cfg.ApplicationConfiguration.RPC.StartWhenSynchronized { + rpcServer.Start() + } sighupCh := make(chan os.Signal, 1) signal.Notify(sighupCh, syscall.SIGHUP) @@ -530,12 +533,14 @@ Main: log.Info("SIGHUP received, restarting rpc-server") rpcServer.Shutdown() rpcServer = server.New(chain, cfg.ApplicationConfiguration.RPC, serv, oracleSrv, log, errChan) - rpcServer.Start() + serv.AddService(&rpcServer) // Replaces old one by service name. + if !cfg.ApplicationConfiguration.RPC.StartWhenSynchronized || serv.IsInSync() { + rpcServer.Start() + } } case <-grace.Done(): signal.Stop(sighupCh) serv.Shutdown() - rpcServer.Shutdown() break Main } } diff --git a/docs/cli.md b/docs/cli.md index dce0bd573..b63b586d1 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -55,6 +55,17 @@ Or specify a different network with appropriate flag like this: By default, the node will run in foreground using current standard output for logging. + +### Node synchronization + +Most of the services (state validation, oracle, consensus and RPC if +configured with `StartWhenSynchronized` option) are only started after the +node is completely synchronizaed because running them before that is either +pointless or even dangerous. The node considers itself to be fully +synchronized with the network if it has more than `MinPeers` neighbours and if +at least 2/3 of them are known to have a height less than or equal to the +current height of the node. + ### Restarting node services To restart some node services without full node restart, send the SIGHUP diff --git a/docs/node-configuration.md b/docs/node-configuration.md index 9591981ba..d8f2dc506 100644 --- a/docs/node-configuration.md +++ b/docs/node-configuration.md @@ -136,6 +136,7 @@ RPC: MaxFindResultItems: 100 MaxNEP11Tokens: 100 Port: 10332 + StartWhenSynchronized: false TLSConfig: Address: "" CertFile: serv.crt @@ -158,6 +159,10 @@ where: - `MaxNEP11Tokens` - limit for the number of tokens returned from `getnep11balances` call. - `Port` is an RPC server port it should be bound to. +- `StartWhenSynchronized` controls when RPC server will be started, by default + (`false` setting) it's started immediately and RPC is availabe during node + synchronization. Setting it to `true` will make the node start RPC service only + after full synchronization. - `TLS` section configures TLS protocol. ### State Root Configuration diff --git a/pkg/rpc/rpc_config.go b/pkg/rpc/rpc_config.go index 6e241701f..cc0cdee9b 100644 --- a/pkg/rpc/rpc_config.go +++ b/pkg/rpc/rpc_config.go @@ -17,6 +17,7 @@ type ( MaxFindResultItems int `yaml:"MaxFindResultItems"` MaxNEP11Tokens int `yaml:"MaxNEP11Tokens"` Port uint16 `yaml:"Port"` + StartWhenSynchronized bool `yaml:"StartWhenSynchronized"` TLSConfig TLSConfig `yaml:"TLSConfig"` } diff --git a/pkg/rpc/server/server.go b/pkg/rpc/server/server.go index 7e83dc68d..3bb1f23ca 100644 --- a/pkg/rpc/server/server.go +++ b/pkg/rpc/server/server.go @@ -260,6 +260,9 @@ func (s *Server) Start() { func (s *Server) Shutdown() { var httpsErr error + if !s.started.Load() { + return + } // Signal to websocket writer routines and handleSubEvents. close(s.shutdown)