neoneo-go/cli/server/server.go
dauTT 1360e1de68 Added rpc unit tests (#107)
* Fixed small incosistencies related to comments and variable name

* For testing purposes we have to move the method newBlockchain from the cli/server/server.go to  pkg/core/blockchain.go. In addition we have to rename it to NewBlockchainLevelDB in order to be able to export it and avoid naming conflicts. In future we still need to think how to switch between different blockchain implementation easily but for the time being this is not possible.

* Added unit tests for the rpc server

* Added unit_testnet chain fixture

* fixed port number

* Added errors handling

* move unit_testnet chain from 'cli/chains' to 'pkg/rpc/chains'
2019-01-22 13:14:52 +01:00

108 lines
2.4 KiB
Go

package server
import (
"fmt"
"os"
"os/signal"
"github.com/CityOfZion/neo-go/config"
"github.com/CityOfZion/neo-go/pkg/core"
"github.com/CityOfZion/neo-go/pkg/network"
"github.com/CityOfZion/neo-go/pkg/rpc"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
"github.com/urfave/cli"
)
// NewCommand creates a new Node command.
func NewCommand() cli.Command {
return cli.Command{
Name: "node",
Usage: "start a NEO node",
Action: startServer,
Flags: []cli.Flag{
cli.StringFlag{Name: "config-path"},
cli.BoolFlag{Name: "privnet, p"},
cli.BoolFlag{Name: "mainnet, m"},
cli.BoolFlag{Name: "testnet, t"},
cli.BoolFlag{Name: "debug, d"},
},
}
}
func startServer(ctx *cli.Context) error {
net := config.ModePrivNet
if ctx.Bool("testnet") {
net = config.ModeTestNet
}
if ctx.Bool("mainnet") {
net = config.ModeMainNet
}
configPath := "../config"
if argCp := ctx.String("config-path"); argCp != "" {
configPath = argCp
}
cfg, err := config.Load(configPath, net)
if err != nil {
return cli.NewExitError(err, 1)
}
interruptChan := make(chan os.Signal, 1)
signal.Notify(interruptChan, os.Interrupt)
serverConfig := network.NewServerConfig(cfg)
chain, err := core.NewBlockchainLevelDB(cfg)
if err != nil {
err = fmt.Errorf("could not initialize blockchain: %s", err)
return cli.NewExitError(err, 1)
}
if ctx.Bool("debug") {
log.SetLevel(log.DebugLevel)
}
server := network.NewServer(serverConfig, chain)
rpcServer := rpc.NewServer(chain, cfg.ApplicationConfiguration.RPCPort, server)
errChan := make(chan error)
go server.Start(errChan)
go rpcServer.Start(errChan)
fmt.Println(logo())
fmt.Println(server.UserAgent)
fmt.Println()
var shutdownErr error
Main:
for {
select {
case err := <-errChan:
shutdownErr = errors.Wrap(err, "Error encountered by server")
interruptChan <- os.Kill
case <-interruptChan:
server.Shutdown()
if serverErr := rpcServer.Shutdown(); serverErr != nil {
shutdownErr = errors.Wrap(serverErr, "Error encountered whilst shutting down server")
}
break Main
}
}
if shutdownErr != nil {
return cli.NewExitError(shutdownErr, 1)
}
return nil
}
func logo() string {
return `
_ ____________ __________
/ | / / ____/ __ \ / ____/ __ \
/ |/ / __/ / / / /_____/ / __/ / / /
/ /| / /___/ /_/ /_____/ /_/ / /_/ /
/_/ |_/_____/\____/ \____/\____/
`
}