Skip to content

Commit dd892c0

Browse files
authored
Merge pull request #726 from gzliudan/fix-sa1019-node
upgrade package node
2 parents e499b40 + cec7dcb commit dd892c0

File tree

10 files changed

+154
-125
lines changed

10 files changed

+154
-125
lines changed

cmd/XDC/main.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,9 @@ var (
147147
utils.RPCGlobalGasCapFlag,
148148
utils.RPCListenAddrFlag,
149149
utils.RPCPortFlag,
150+
utils.RPCHttpReadTimeoutFlag,
150151
utils.RPCHttpWriteTimeoutFlag,
152+
utils.RPCHttpIdleTimeoutFlag,
151153
utils.RPCApiFlag,
152154
utils.WSEnabledFlag,
153155
utils.WSListenAddrFlag,

cmd/XDC/usage.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,9 @@ var AppHelpFlagGroups = []flagGroup{
147147
utils.RPCGlobalGasCapFlag,
148148
utils.RPCListenAddrFlag,
149149
utils.RPCPortFlag,
150+
utils.RPCHttpReadTimeoutFlag,
150151
utils.RPCHttpWriteTimeoutFlag,
152+
utils.RPCHttpIdleTimeoutFlag,
151153
utils.RPCApiFlag,
152154
utils.WSEnabledFlag,
153155
utils.WSListenAddrFlag,

cmd/utils/flags.go

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -435,10 +435,20 @@ var (
435435
Usage: "HTTP-RPC server listening port",
436436
Value: node.DefaultHTTPPort,
437437
}
438+
RPCHttpReadTimeoutFlag = cli.DurationFlag{
439+
Name: "rpcreadtimeout",
440+
Usage: "HTTP-RPC server read timeout",
441+
Value: rpc.DefaultHTTPTimeouts.ReadTimeout,
442+
}
438443
RPCHttpWriteTimeoutFlag = cli.DurationFlag{
439444
Name: "rpcwritetimeout",
440-
Usage: "HTTP-RPC server write timeout (default = 10s)",
441-
Value: node.DefaultHTTPWriteTimeOut,
445+
Usage: "HTTP-RPC server write timeout",
446+
Value: rpc.DefaultHTTPTimeouts.WriteTimeout,
447+
}
448+
RPCHttpIdleTimeoutFlag = cli.DurationFlag{
449+
Name: "rpcidletimeout",
450+
Usage: "HTTP-RPC server idle timeout",
451+
Value: rpc.DefaultHTTPTimeouts.IdleTimeout,
442452
}
443453
RPCCORSDomainFlag = cli.StringFlag{
444454
Name: "rpccorsdomain",
@@ -779,8 +789,14 @@ func setHTTP(ctx *cli.Context, cfg *node.Config) {
779789
if ctx.GlobalIsSet(RPCPortFlag.Name) {
780790
cfg.HTTPPort = ctx.GlobalInt(RPCPortFlag.Name)
781791
}
792+
if ctx.GlobalIsSet(RPCHttpReadTimeoutFlag.Name) {
793+
cfg.HTTPTimeouts.ReadTimeout = ctx.GlobalDuration(RPCHttpReadTimeoutFlag.Name)
794+
}
782795
if ctx.GlobalIsSet(RPCHttpWriteTimeoutFlag.Name) {
783-
cfg.HTTPWriteTimeout = ctx.GlobalDuration(RPCHttpWriteTimeoutFlag.Name)
796+
cfg.HTTPTimeouts.WriteTimeout = ctx.GlobalDuration(RPCHttpWriteTimeoutFlag.Name)
797+
}
798+
if ctx.GlobalIsSet(RPCHttpIdleTimeoutFlag.Name) {
799+
cfg.HTTPTimeouts.IdleTimeout = ctx.GlobalDuration(RPCHttpIdleTimeoutFlag.Name)
784800
}
785801
if ctx.GlobalIsSet(RPCCORSDomainFlag.Name) {
786802
cfg.HTTPCors = splitAndTrim(ctx.GlobalString(RPCCORSDomainFlag.Name))

node/api.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ func (api *PrivateAdminAPI) StartRPC(host *string, port *int, cors *string, apis
158158
}
159159
}
160160

161-
if err := api.node.startHTTP(fmt.Sprintf("%s:%d", *host, *port), api.node.rpcAPIs, modules, allowedOrigins, allowedVHosts); err != nil {
161+
if err := api.node.startHTTP(fmt.Sprintf("%s:%d", *host, *port), api.node.rpcAPIs, modules, allowedOrigins, allowedVHosts, api.node.config.HTTPTimeouts); err != nil {
162162
return false, err
163163
}
164164
return true, nil

node/config.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import (
2323
"path/filepath"
2424
"runtime"
2525
"strings"
26-
"time"
2726

2827
"github.com/XinFinOrg/XDPoSChain/accounts"
2928
"github.com/XinFinOrg/XDPoSChain/accounts/keystore"
@@ -33,6 +32,7 @@ import (
3332
"github.com/XinFinOrg/XDPoSChain/log"
3433
"github.com/XinFinOrg/XDPoSChain/p2p"
3534
"github.com/XinFinOrg/XDPoSChain/p2p/discover"
35+
"github.com/XinFinOrg/XDPoSChain/rpc"
3636
)
3737

3838
const (
@@ -100,9 +100,6 @@ type Config struct {
100100
// for ephemeral nodes).
101101
HTTPPort int `toml:",omitempty"`
102102

103-
// HTTPWriteTimeout is the write timeout for the HTTP RPC server.
104-
HTTPWriteTimeout time.Duration `toml:",omitempty"`
105-
106103
// HTTPCors is the Cross-Origin Resource Sharing header to send to requesting
107104
// clients. Please be aware that CORS is a browser enforced security, it's fully
108105
// useless for custom HTTP clients.
@@ -122,6 +119,10 @@ type Config struct {
122119
// exposed.
123120
HTTPModules []string `toml:",omitempty"`
124121

122+
// HTTPTimeouts allows for customization of the timeout values used by the HTTP RPC
123+
// interface.
124+
HTTPTimeouts rpc.HTTPTimeouts
125+
125126
// WSHost is the host interface on which to start the websocket RPC server. If
126127
// this field is empty, no websocket API endpoint will be started.
127128
WSHost string `toml:",omitempty"`

node/defaults.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,27 +21,26 @@ import (
2121
"os/user"
2222
"path/filepath"
2323
"runtime"
24-
"time"
2524

2625
"github.com/XinFinOrg/XDPoSChain/p2p"
2726
"github.com/XinFinOrg/XDPoSChain/p2p/nat"
27+
"github.com/XinFinOrg/XDPoSChain/rpc"
2828
)
2929

3030
const (
31-
DefaultHTTPHost = "localhost" // Default host interface for the HTTP RPC server
32-
DefaultHTTPPort = 8545 // Default TCP port for the HTTP RPC server
33-
DefaultHTTPWriteTimeOut = 10 * time.Second // Default write timeout for the HTTP RPC server
34-
DefaultWSHost = "localhost" // Default host interface for the websocket RPC server
35-
DefaultWSPort = 8546 // Default TCP port for the websocket RPC server
31+
DefaultHTTPHost = "localhost" // Default host interface for the HTTP RPC server
32+
DefaultHTTPPort = 8545 // Default TCP port for the HTTP RPC server
33+
DefaultWSHost = "localhost" // Default host interface for the websocket RPC server
34+
DefaultWSPort = 8546 // Default TCP port for the websocket RPC server
3635
)
3736

3837
// DefaultConfig contains reasonable default settings.
3938
var DefaultConfig = Config{
4039
DataDir: DefaultDataDir(),
4140
HTTPPort: DefaultHTTPPort,
42-
HTTPWriteTimeout: DefaultHTTPWriteTimeOut,
4341
HTTPModules: []string{"net", "web3"},
4442
HTTPVirtualHosts: []string{"localhost"},
43+
HTTPTimeouts: rpc.DefaultHTTPTimeouts,
4544
WSPort: DefaultWSPort,
4645
WSModules: []string{"net", "web3"},
4746
P2P: p2p.Config{

node/node.go

Lines changed: 33 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ func (n *Node) Register(constructor ServiceConstructor) error {
140140
return nil
141141
}
142142

143-
// Start create a live P2P node and starts running it.
143+
// Start creates a live P2P node and starts running it.
144144
func (n *Node) Start() error {
145145
n.lock.Lock()
146146
defer n.lock.Unlock()
@@ -203,7 +203,7 @@ func (n *Node) Start() error {
203203
return convertFileLockError(err)
204204
}
205205
// Start each of the services
206-
started := []reflect.Type{}
206+
var started []reflect.Type
207207
for kind, service := range services {
208208
// Start the next service, stopping all previous upon failure
209209
if err := service.Start(running); err != nil {
@@ -217,7 +217,7 @@ func (n *Node) Start() error {
217217
// Mark the service started for potential cleanup
218218
started = append(started, kind)
219219
}
220-
// Lastly start the configured RPC interfaces
220+
// Lastly, start the configured RPC interfaces
221221
if err := n.startRPC(services); err != nil {
222222
for _, service := range services {
223223
service.Stop()
@@ -252,7 +252,7 @@ func (n *Node) openDataDir() error {
252252
return nil
253253
}
254254

255-
// startRPC is a helper method to start all the various RPC endpoint during node
255+
// startRPC is a helper method to start all the various RPC endpoints during node
256256
// startup. It's not meant to be called at any time afterwards as it makes certain
257257
// assumptions about the state of the node.
258258
func (n *Node) startRPC(services map[reflect.Type]Service) error {
@@ -269,7 +269,7 @@ func (n *Node) startRPC(services map[reflect.Type]Service) error {
269269
n.stopInProc()
270270
return err
271271
}
272-
if err := n.startHTTP(n.httpEndpoint, apis, n.config.HTTPModules, n.config.HTTPCors, n.config.HTTPVirtualHosts); err != nil {
272+
if err := n.startHTTP(n.httpEndpoint, apis, n.config.HTTPModules, n.config.HTTPCors, n.config.HTTPVirtualHosts, n.config.HTTPTimeouts); err != nil {
273273
n.stopIPC()
274274
n.stopInProc()
275275
return err
@@ -293,7 +293,7 @@ func (n *Node) startInProc(apis []rpc.API) error {
293293
if err := handler.RegisterName(api.Namespace, api.Service); err != nil {
294294
return err
295295
}
296-
n.log.Debug("InProc registered", "service", api.Service, "namespace", api.Namespace)
296+
n.log.Debug("InProc registered", "namespace", api.Namespace)
297297
}
298298
n.inprocHandler = handler
299299
return nil
@@ -320,51 +320,16 @@ func (n *Node) RegisterAPIs(apis []rpc.API) {
320320

321321
// startIPC initializes and starts the IPC RPC endpoint.
322322
func (n *Node) startIPC(apis []rpc.API) error {
323-
// Short circuit if the IPC endpoint isn't being exposed
324323
if n.ipcEndpoint == "" {
325-
return nil
324+
return nil // IPC disabled.
326325
}
327-
// Register all the APIs exposed by the services
328-
handler := rpc.NewServer()
329-
for _, api := range apis {
330-
if err := handler.RegisterName(api.Namespace, api.Service); err != nil {
331-
return err
332-
}
333-
n.log.Debug("IPC registered", "service", api.Service, "namespace", api.Namespace)
334-
}
335-
// All APIs registered, start the IPC listener
336-
var (
337-
listener net.Listener
338-
err error
339-
)
340-
if listener, err = rpc.CreateIPCListener(n.ipcEndpoint); err != nil {
326+
listener, handler, err := rpc.StartIPCEndpoint(n.ipcEndpoint, apis)
327+
if err != nil {
341328
return err
342329
}
343-
go func() {
344-
n.log.Info("IPC endpoint opened", "url", n.ipcEndpoint)
345-
346-
for {
347-
conn, err := listener.Accept()
348-
if err != nil {
349-
// Terminate if the listener was closed
350-
n.lock.RLock()
351-
closed := n.ipcListener == nil
352-
n.lock.RUnlock()
353-
if closed {
354-
return
355-
}
356-
// Not closed, just some error; report and continue
357-
n.log.Error("IPC accept failed", "err", err)
358-
continue
359-
}
360-
log.Trace("Accepted RPC connection", "conn", conn.RemoteAddr())
361-
go handler.ServeCodec(rpc.NewCodec(conn), 0)
362-
}
363-
}()
364-
// All listeners booted successfully
365330
n.ipcListener = listener
366331
n.ipcHandler = handler
367-
332+
log.Info("IPC endpoint opened", "url", n.ipcEndpoint)
368333
return nil
369334
}
370335

@@ -374,7 +339,7 @@ func (n *Node) stopIPC() {
374339
n.ipcListener.Close()
375340
n.ipcListener = nil
376341

377-
n.log.Info("IPC endpoint closed", "endpoint", n.ipcEndpoint)
342+
n.log.Info("IPC endpoint closed", "url", n.ipcEndpoint)
378343
}
379344
if n.ipcHandler != nil {
380345
n.ipcHandler.Stop()
@@ -383,36 +348,18 @@ func (n *Node) stopIPC() {
383348
}
384349

385350
// startHTTP initializes and starts the HTTP RPC endpoint.
386-
func (n *Node) startHTTP(endpoint string, apis []rpc.API, modules []string, cors []string, vhosts []string) error {
351+
func (n *Node) startHTTP(endpoint string, apis []rpc.API, modules []string, cors []string, vhosts []string, timeouts rpc.HTTPTimeouts) error {
387352
// Short circuit if the HTTP endpoint isn't being exposed
388353
if endpoint == "" {
389354
return nil
390355
}
391-
// Generate the whitelist based on the allowed modules
392-
whitelist := make(map[string]bool)
393-
for _, module := range modules {
394-
whitelist[module] = true
395-
}
396-
// Register all the APIs exposed by the services
397-
handler := rpc.NewServer()
398-
for _, api := range apis {
399-
if whitelist[api.Namespace] || (len(whitelist) == 0 && api.Public) {
400-
if err := handler.RegisterName(api.Namespace, api.Service); err != nil {
401-
return err
402-
}
403-
n.log.Debug("HTTP registered", "service", api.Service, "namespace", api.Namespace)
404-
}
405-
}
406-
// All APIs registered, start the HTTP listener
407-
var (
408-
listener net.Listener
409-
err error
410-
)
411-
if listener, err = net.Listen("tcp", endpoint); err != nil {
356+
listener, handler, err := rpc.StartHTTPEndpoint(endpoint, apis, modules, cors, vhosts, timeouts)
357+
if err != nil {
412358
return err
413359
}
414-
go rpc.NewHTTPServer(cors, vhosts, handler, n.config.HTTPWriteTimeout).Serve(listener)
415-
n.log.Info("HTTP endpoint opened", "url", fmt.Sprintf("http://%s", endpoint), "cors", strings.Join(cors, ","), "vhosts", strings.Join(vhosts, ","))
360+
n.log.Info("HTTP endpoint opened", "url", fmt.Sprintf("http://%v/", listener.Addr()),
361+
"cors", strings.Join(cors, ","),
362+
"vhosts", strings.Join(vhosts, ","))
416363
// All listeners booted successfully
417364
n.httpEndpoint = endpoint
418365
n.httpListener = listener
@@ -424,10 +371,10 @@ func (n *Node) startHTTP(endpoint string, apis []rpc.API, modules []string, cors
424371
// stopHTTP terminates the HTTP RPC endpoint.
425372
func (n *Node) stopHTTP() {
426373
if n.httpListener != nil {
374+
url := fmt.Sprintf("http://%v/", n.httpListener.Addr())
427375
n.httpListener.Close()
428376
n.httpListener = nil
429-
430-
n.log.Info("HTTP endpoint closed", "url", fmt.Sprintf("http://%s", n.httpEndpoint))
377+
n.log.Info("HTTP endpoint closed", "url", url)
431378
}
432379
if n.httpHandler != nil {
433380
n.httpHandler.Stop()
@@ -441,32 +388,11 @@ func (n *Node) startWS(endpoint string, apis []rpc.API, modules []string, wsOrig
441388
if endpoint == "" {
442389
return nil
443390
}
444-
// Generate the whitelist based on the allowed modules
445-
whitelist := make(map[string]bool)
446-
for _, module := range modules {
447-
whitelist[module] = true
448-
}
449-
// Register all the APIs exposed by the services
450-
handler := rpc.NewServer()
451-
for _, api := range apis {
452-
if exposeAll || whitelist[api.Namespace] || (len(whitelist) == 0 && api.Public) {
453-
if err := handler.RegisterName(api.Namespace, api.Service); err != nil {
454-
return err
455-
}
456-
n.log.Debug("WebSocket registered", "service", api.Service, "namespace", api.Namespace)
457-
}
458-
}
459-
// All APIs registered, start the HTTP listener
460-
var (
461-
listener net.Listener
462-
err error
463-
)
464-
if listener, err = net.Listen("tcp", endpoint); err != nil {
391+
listener, handler, err := rpc.StartWSEndpoint(endpoint, apis, modules, wsOrigins, exposeAll)
392+
if err != nil {
465393
return err
466394
}
467-
go rpc.NewWSServer(wsOrigins, handler).Serve(listener)
468395
n.log.Info("WebSocket endpoint opened", "url", fmt.Sprintf("ws://%s", listener.Addr()))
469-
470396
// All listeners booted successfully
471397
n.wsEndpoint = endpoint
472398
n.wsListener = listener
@@ -645,11 +571,23 @@ func (n *Node) IPCEndpoint() string {
645571

646572
// HTTPEndpoint retrieves the current HTTP endpoint used by the protocol stack.
647573
func (n *Node) HTTPEndpoint() string {
574+
n.lock.Lock()
575+
defer n.lock.Unlock()
576+
577+
if n.httpListener != nil {
578+
return n.httpListener.Addr().String()
579+
}
648580
return n.httpEndpoint
649581
}
650582

651583
// WSEndpoint retrieves the current WS endpoint used by the protocol stack.
652584
func (n *Node) WSEndpoint() string {
585+
n.lock.Lock()
586+
defer n.lock.Unlock()
587+
588+
if n.wsListener != nil {
589+
return n.wsListener.Addr().String()
590+
}
653591
return n.wsEndpoint
654592
}
655593

0 commit comments

Comments
 (0)