Server configuration (#43)

* Adds struct for config settings

* Bumps version

* Move settings around

* Only push version tag up not whole branch as well

* Move config into own path and add test and main nets

* Update config for timeouts

* Convert to yaml
This commit is contained in:
Steven Jack 2018-03-15 20:45:37 +00:00 committed by Anthony De Meulemeester
parent aa4bc1b6e8
commit b41e14e0f0
13 changed files with 309 additions and 132 deletions

26
Gopkg.lock generated
View file

@ -20,22 +20,10 @@
version = "v1.1.0" version = "v1.1.0"
[[projects]] [[projects]]
name = "github.com/go-kit/kit" name = "github.com/go-yaml/yaml"
packages = ["log"]
revision = "4dc7be5d2d12881735283bcab7352178e190fc71"
version = "v0.6.0"
[[projects]]
name = "github.com/go-logfmt/logfmt"
packages = ["."] packages = ["."]
revision = "390ab7935ee28ec6b286364bba9b4dd6410cb3d5" revision = "7f97868eec74b32b0982dd158a51a446d1da7eb5"
version = "v0.3.0" version = "v2.1.1"
[[projects]]
name = "github.com/go-stack/stack"
packages = ["."]
revision = "259ab82a6cad3992b4e21ff5cac294ccb06474bc"
version = "v1.7.0"
[[projects]] [[projects]]
branch = "master" branch = "master"
@ -44,10 +32,10 @@
revision = "553a641470496b2327abcac10b36396bd98e45c9" revision = "553a641470496b2327abcac10b36396bd98e45c9"
[[projects]] [[projects]]
branch = "master" name = "github.com/pkg/errors"
name = "github.com/kr/logfmt"
packages = ["."] packages = ["."]
revision = "b84e30acd515aadc4b783ad4ff83aff3299bdfe0" revision = "645ef00459ed84a119197bfb8d8205042c6df63d"
version = "v0.8.0"
[[projects]] [[projects]]
name = "github.com/pmezard/go-difflib" name = "github.com/pmezard/go-difflib"
@ -138,6 +126,6 @@
[solve-meta] [solve-meta]
analyzer-name = "dep" analyzer-name = "dep"
analyzer-version = 1 analyzer-version = 1
inputs-digest = "333dfa54a358d83b266025eff7f15854652631d90e18e61fa75723c5a030778b" inputs-digest = "7e6d4161196284974f07ba9655d21ee9b4fe1478ef0e054e159df73aeec1343a"
solver-name = "gps-cdcl" solver-name = "gps-cdcl"
solver-version = 1 solver-version = 1

View file

@ -55,3 +55,11 @@
[[constraint]] [[constraint]]
name = "github.com/sirupsen/logrus" name = "github.com/sirupsen/logrus"
version = "1.0.5" version = "1.0.5"
[[constraint]]
name = "github.com/pkg/errors"
version = "0.8.0"
[[constraint]]
name = "github.com/go-yaml/yaml"
version = "2.1.1"

View file

@ -1,11 +1,10 @@
BRANCH = "master" BRANCH = "master"
BUILD_TIME = "$(shell date -u +\"%Y-%m-%dT%H:%M:%SZ\")"
VERSION = $(shell cat ./VERSION) VERSION = $(shell cat ./VERSION)
SEEDS ?= "127.0.0.1:20333" NETMODE ?= "privnet"
PORT ?= "3000"
DBFILE ?= "chain"
build: build:
@go build -o ./bin/neo-go ./cli/main.go @go build -ldflags "-X github.com/CityOfZion/neo-go/pkg/network.Version=${VERSION}-dev -X github.com/CityOfZion/neo-go/pkg/network.BuildTime=${BUILD_TIME}" -o ./bin/neo-go ./cli/main.go
check-version: check-version:
git fetch && (! git rev-list ${VERSION}) git fetch && (! git rev-list ${VERSION})
@ -17,10 +16,10 @@ push-tag:
git checkout ${BRANCH} git checkout ${BRANCH}
git pull origin ${BRANCH} git pull origin ${BRANCH}
git tag ${VERSION} git tag ${VERSION}
git push origin ${BRANCH} --tags git push origin ${VERSION}
run: build run: build
./bin/neo-go node -seed ${SEEDS} -tcp ${PORT} -dbfile ${DBFILE} --relay true ./bin/neo-go node -config-path ./config -${NETMODE}
test: test:
@go test ./... -cover @go test ./... -cover

View file

@ -1 +1 @@
0.29.0 0.30.0

View file

@ -4,17 +4,18 @@ jobs:
working_directory: /go/src/github.com/CityOfZion/neo-go working_directory: /go/src/github.com/CityOfZion/neo-go
docker: docker:
- image: vidsyhq/go-builder:latest - image: vidsyhq/go-builder:latest
environment:
BUILD: false
steps: steps:
- checkout - checkout
- run: go get -u github.com/golang/dep/cmd/dep
- run: dep ensure
- restore_cache: - restore_cache:
key: dependency-cache-{{ .Revision }} key: dependency-cache-{{ checksum "Gopkg.toml" }}-{{ checksum "VERSION" }}
- run: BUILD=false /scripts/build.sh - run: /scripts/build.sh
- save_cache: - save_cache:
key: dependency-cache-{{ .Revision }} key: dependency-cache-{{ checksum "Gopkg.toml" }}-{{ checksum "VERSION" }}
paths: paths:
- vendor - vendor
- /go/pkg
test: test:
working_directory: /go/src/github.com/CityOfZion/neo-go working_directory: /go/src/github.com/CityOfZion/neo-go
docker: docker:
@ -22,7 +23,7 @@ jobs:
steps: steps:
- checkout - checkout
- restore_cache: - restore_cache:
key: dependency-cache-{{ .Revision }} key: dependency-cache-{{ checksum "Gopkg.toml" }}-{{ checksum "VERSION" }}
- run: make test - run: make test
vet: vet:
working_directory: /go/src/github.com/CityOfZion/neo-go working_directory: /go/src/github.com/CityOfZion/neo-go
@ -31,7 +32,7 @@ jobs:
steps: steps:
- checkout - checkout
- restore_cache: - restore_cache:
key: dependency-cache-{{ .Revision }} key: dependency-cache-{{ checksum "Gopkg.toml" }}-{{ checksum "VERSION" }}
- run: make vet - run: make vet
check_version: check_version:
working_directory: /go/src/github.com/CityOfZion/neo-go working_directory: /go/src/github.com/CityOfZion/neo-go
@ -46,8 +47,8 @@ jobs:
- image: vidsyhq/go-builder:latest - image: vidsyhq/go-builder:latest
steps: steps:
- checkout - checkout
- run: go get -u github.com/golang/dep/cmd/dep - restore_cache:
- run: dep ensure key: dependency-cache-{{ checksum "Gopkg.toml" }}-{{ checksum "VERSION" }}
- run: make build - run: make build
workflows: workflows:
@ -79,4 +80,4 @@ workflows:
- install_deps - install_deps
filters: filters:
tags: tags:
only: /[0-9]+\.[0-9]+\.[0-9]+/ only: /[0-9]+\.[0-9]+\.[0-9]+/

View file

@ -2,7 +2,6 @@ package server
import ( import (
"fmt" "fmt"
"strings"
"github.com/CityOfZion/neo-go/pkg/core" "github.com/CityOfZion/neo-go/pkg/core"
"github.com/CityOfZion/neo-go/pkg/network" "github.com/CityOfZion/neo-go/pkg/network"
@ -17,11 +16,7 @@ func NewCommand() cli.Command {
Usage: "start a NEO node", Usage: "start a NEO node",
Action: startServer, Action: startServer,
Flags: []cli.Flag{ Flags: []cli.Flag{
cli.IntFlag{Name: "tcp"}, cli.StringFlag{Name: "config-path"},
cli.IntFlag{Name: "rpc"},
cli.BoolFlag{Name: "relay, r"},
cli.StringFlag{Name: "seed"},
cli.StringFlag{Name: "dbfile"},
cli.BoolFlag{Name: "privnet, p"}, cli.BoolFlag{Name: "privnet, p"},
cli.BoolFlag{Name: "mainnet, m"}, cli.BoolFlag{Name: "mainnet, m"},
cli.BoolFlag{Name: "testnet, t"}, cli.BoolFlag{Name: "testnet, t"},
@ -38,21 +33,21 @@ func startServer(ctx *cli.Context) error {
net = network.ModeMainNet net = network.ModeMainNet
} }
cfg := network.Config{ configPath := "./config"
UserAgent: "/NEO-GO:0.26.0/", configPath = ctx.String("config-path")
ListenTCP: uint16(ctx.Int("tcp")), config, err := network.LoadConfig(configPath, net)
Seeds: parseSeeds(ctx.String("seed")), if err != nil {
Net: net, return err
Relay: ctx.Bool("relay"),
} }
chain, err := newBlockchain(net, ctx.String("dbfile")) serverConfig := network.NewServerConfig(config)
chain, err := newBlockchain(net, config.ApplicationConfiguration.DataDirectoryPath)
if err != nil { if err != nil {
err = fmt.Errorf("could not initialize blockhain: %s", err) err = fmt.Errorf("could not initialize blockhain: %s", err)
return cli.NewExitError(err, 1) return cli.NewExitError(err, 1)
} }
s := network.NewServer(cfg, chain) s := network.NewServer(serverConfig, chain)
s.Start() s.Start()
return nil return nil
} }
@ -80,14 +75,3 @@ func newBlockchain(net network.NetMode, path string) (*core.Blockchain, error) {
startHash, startHash,
), nil ), nil
} }
func parseSeeds(s string) []string {
if len(s) == 0 {
return nil
}
seeds := strings.Split(s, ",")
if len(seeds) == 0 {
return nil
}
return seeds
}

View file

@ -0,0 +1,32 @@
ProtocolConfiguration:
Magic: 7630401
AddressVersion: 23
StandbyValidators:
- 03b209fd4f53a7170ea4444e0cb0a6bb6a53c2bd016926989cf85f9b0fba17a70c
- 02df48f60e8f3e01c48ff40b9b7f1310d7a8b2a193188befe1c2e3df740e895093
- 03b8d9d5771d8f513aa0869b9cc8d50986403b78c6da36890638c3d46a5adce04a
- 02ca0e27697b9c248f6f16e085fd0061e26f44da85b58ee835c110caa5ec3ba554
- 024c7b7fb6c310fccf1ba33b082519d82964ea93868d676662d4a59ad548df0e7d
- 02aaec38470f6aad0042c6e877cfd8087d2676b0f516fddd362801b9bd3936399e
- 02486fd15702c4490a26703112a5cc1d0923fd697a33406bd5a1c00e0013b09a70
SeedList:
- seed1.neo.org:10333
- seed2.neo.org:10333
- seed3.neo.org:10333
- seed4.neo.org:10333
- seed5.neo.org:10333
SystemFee:
EnrollmentTransaction: 1000
IssueTransaction: 500
PublishTransaction: 500
RegisterTransaction: 10000
ApplicationConfiguration:
DataDirectoryPath: "./chains/mainnet"
RPCPort: 20332
NodePort: 20333
Relay: true
DialTimeout: 3
ProtoTickInterval: 10
MaxPeers: 50

View file

@ -0,0 +1,27 @@
ProtocolConfiguration:
Magic: 56753
AddressVersion: 23
StandbyValidators:
- 02b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc2
- 02103a7f7dd016558597f7960d27c516a4394fd968b9e65155eb4b013e4040406e
- 03d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699
- 02a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd62
SeedList:
- 127.0.0.1:20333
- 127.0.0.1:20334
- 127.0.0.1:20335
- 127.0.0.1:20336
SystemFee:
EnrollmentTransaction: 1000
IssueTransaction: 500
PublishTransaction: 500
RegisterTransaction: 10000
ApplicationConfiguration:
DataDirectoryPath: "./chains/privnet"
RPCPort: 20332
NodePort: 20333
Relay: true
DialTimeout: 3
ProtoTickInterval: 10
MaxPeers: 50

View file

@ -0,0 +1,31 @@
ProtocolConfiguration:
Magic: 1953787457
AddressVersion: 23
StandbyValidators:
- 0327da12b5c40200e9f65569476bbff2218da4f32548ff43b6387ec1416a231ee8
- 026ce35b29147ad09e4afe4ec4a7319095f08198fa8babbe3c56e970b143528d22
- 0209e7fd41dfb5c2f8dc72eb30358ac100ea8c72da18847befe06eade68cebfcb9
- 039dafd8571a641058ccc832c5e2111ea39b09c0bde36050914384f7a48bce9bf9
- 038dddc06ce687677a53d54f096d2591ba2302068cf123c1f2d75c2dddc5425579
- 02d02b1873a0863cd042cc717da31cea0d7cf9db32b74d4c72c01b0011503e2e22
- 034ff5ceeac41acf22cd5ed2da17a6df4dd8358fcb2bfb1a43208ad0feaab2746b
SeedList:
- 18.218.97.227:20333
- 18.219.30.120:20333
- 18.219.13.91:20333
- 13.59.116.121:20333
- 18.218.255.178:20333
SystemFee:
EnrollmentTransaction: 10
IssueTransaction: 5
PublishTransaction: 5
RegisterTransaction: 100
ApplicationConfiguration:
DataDirectoryPath: "./chains/testnet"
RPCPort: 20332
NodePort: 20333
Relay: true
DialTimeout: 3
ProtoTickInterval: 10
MaxPeers: 50

95
pkg/network/config.go Normal file
View file

@ -0,0 +1,95 @@
package network
import (
"fmt"
"io/ioutil"
"os"
"time"
"github.com/go-yaml/yaml"
"github.com/pkg/errors"
)
const (
userAgentFormat = "/NEO-GO:%s/"
)
var (
// Version the version of the node, set at build time.
Version string
// BuildTime the time and date the current version of the node built,
// set at build time.
BuildTime string
)
type (
// Config top level struct representing the config
// for the node.
Config struct {
ProtocolConfiguration ProtocolConfiguration `yaml:"ProtocolConfiguration"`
ApplicationConfiguration ApplicationConfiguration `yaml:"ApplicationConfiguration"`
}
// ProtocolConfiguration represents the protolcol config.
ProtocolConfiguration struct {
Magic NetMode `yaml:"Magic"`
AddressVersion int64 `yaml:"AddressVersion"`
MaxTransactionsPerBlock int64 `yaml:"MaxTransactionsPerBlock"`
StandbyValidators []string `yaml:"StandbyValidators"`
SeedList []string `yaml:"SeedList"`
SystemFee SystemFee `yaml:"SystemFee"`
}
// SystemFee fees related to system.
SystemFee struct {
EnrollmentTransaction int64 `yaml:"EnrollmentTransaction"`
IssueTransaction int64 `yaml:"IssueTransaction"`
PublishTransaction int64 `yaml:"PublishTransaction"`
RegisterTransaction int64 `yaml:"RegisterTransaction"`
}
// ApplicationConfiguration config specific to the node.
ApplicationConfiguration struct {
DataDirectoryPath string `yaml:"DataDirectoryPath"`
RPCPort uint16 `yaml:"RPCPort"`
NodePort uint16 `yaml:"NodePort"`
Relay bool `yaml:"Relay"`
DialTimeout time.Duration `yaml:"DialTimeout"`
ProtoTickInterval time.Duration `yaml:"ProtoTickInterval"`
MaxPeers int `yaml:"MaxPeers"`
}
)
// GenerateUserAgent creates user agent string based on build time environment.
func (c Config) GenerateUserAgent() string {
return fmt.Sprintf(userAgentFormat, Version)
}
// LoadConfig attempts to load the config from the give
// path and netMode.
func LoadConfig(path string, netMode NetMode) (Config, error) {
configPath := fmt.Sprintf("%s/protocol.%s.yml", path, netMode)
if _, err := os.Stat(configPath); os.IsNotExist(err) {
return Config{}, errors.Wrap(err, "Unable to load config")
}
configData, err := ioutil.ReadFile(configPath)
if err != nil {
return Config{}, errors.Wrap(err, "Unable to read config")
}
config := Config{
ProtocolConfiguration: ProtocolConfiguration{
SystemFee: SystemFee{},
},
ApplicationConfiguration: ApplicationConfiguration{},
}
err = yaml.Unmarshal([]byte(configData), &config)
if err != nil {
return Config{}, errors.Wrap(err, "Problem unmarshaling config json data")
}
return config, nil
}

View file

@ -92,15 +92,15 @@ func (p *localPeer) Version() *payload.Version {
func newTestServer() *Server { func newTestServer() *Server {
return &Server{ return &Server{
Config: Config{}, ServerConfig: ServerConfig{},
chain: testChain{}, chain: testChain{},
transport: localTransport{}, transport: localTransport{},
discovery: testDiscovery{}, discovery: testDiscovery{},
id: util.RandUint32(1000000, 9999999), id: util.RandUint32(1000000, 9999999),
quit: make(chan struct{}), quit: make(chan struct{}),
register: make(chan Peer), register: make(chan Peer),
unregister: make(chan peerDrop), unregister: make(chan peerDrop),
peers: make(map[Peer]bool), peers: make(map[Peer]bool),
} }
} }

View file

@ -13,16 +13,12 @@ import (
) )
const ( const (
maxPeers = 50
minPeers = 5 minPeers = 5
maxBlockBatch = 200 maxBlockBatch = 200
minPoolCount = 30 minPoolCount = 30
) )
var ( var (
protoTickInterval = 10 * time.Second
dialTimeout = 3 * time.Second
errPortMismatch = errors.New("port mismatch") errPortMismatch = errors.New("port mismatch")
errIdenticalID = errors.New("identical node id") errIdenticalID = errors.New("identical node id")
errInvalidHandshake = errors.New("invalid handshake") errInvalidHandshake = errors.New("invalid handshake")
@ -31,47 +27,12 @@ var (
errInvalidInvType = errors.New("invalid inventory type") errInvalidInvType = errors.New("invalid inventory type")
) )
// Config holds the server configuration.
type Config struct {
// MaxPeers it the maximum numbers of peers that can
// be connected to the server.
MaxPeers int
// The user agent of the server.
UserAgent string
// The listen address of the TCP server.
ListenTCP uint16
// The network mode the server will operate on.
// ModePrivNet docker private network.
// ModeTestNet NEO test network.
// ModeMainNet NEO main network.
Net NetMode
// Relay determins whether the server is forwarding its inventory.
Relay bool
// Seeds are a list of initial nodes used to establish connectivity.
Seeds []string
// Maximum duration a single dial may take.
DialTimeout time.Duration
// The duration between protocol ticks with each connected peer.
// When this is 0, the default interval of 5 seconds will be used.
ProtoTickInterval time.Duration
// Level of the internal logger.
LogLevel log.Level
}
type ( type (
// Server represents the local Node in the network. Its transport could // Server represents the local Node in the network. Its transport could
// be of any kind. // be of any kind.
Server struct { Server struct {
// Config holds the Server configuration. // ServerConfig holds the Server configuration.
Config ServerConfig
// id also known as the nonce of te server. // id also known as the nonce of te server.
id uint32 id uint32
@ -102,29 +63,18 @@ type (
) )
// NewServer returns a new Server, initialized with the given configuration. // NewServer returns a new Server, initialized with the given configuration.
func NewServer(cfg Config, chain *core.Blockchain) *Server { func NewServer(config ServerConfig, chain *core.Blockchain) *Server {
if cfg.ProtoTickInterval == 0 {
cfg.ProtoTickInterval = protoTickInterval
}
if cfg.DialTimeout == 0 {
cfg.DialTimeout = dialTimeout
}
if cfg.MaxPeers == 0 {
cfg.MaxPeers = maxPeers
}
log.SetLevel(log.DebugLevel)
s := &Server{ s := &Server{
Config: cfg, ServerConfig: config,
chain: chain, chain: chain,
id: util.RandUint32(1000000, 9999999), id: util.RandUint32(1000000, 9999999),
quit: make(chan struct{}), quit: make(chan struct{}),
register: make(chan Peer), register: make(chan Peer),
unregister: make(chan peerDrop), unregister: make(chan peerDrop),
peers: make(map[Peer]bool), peers: make(map[Peer]bool),
} }
s.transport = NewTCPTransport(s, fmt.Sprintf(":%d", cfg.ListenTCP)) s.transport = NewTCPTransport(s, fmt.Sprintf(":%d", config.ListenTCP))
s.proto = s.transport.Consumer() s.proto = s.transport.Consumer()
s.discovery = NewDefaultDiscovery( s.discovery = NewDefaultDiscovery(
s.DialTimeout, s.DialTimeout,
@ -163,7 +113,7 @@ func (s *Server) run() {
} }
case <-s.quit: case <-s.quit:
s.transport.Close() s.transport.Close()
for p, _ := range s.peers { for p := range s.peers {
p.Disconnect(errServerShutdown) p.Disconnect(errServerShutdown)
} }
return return

View file

@ -0,0 +1,62 @@
package network
import (
"time"
log "github.com/sirupsen/logrus"
)
type (
// ServerConfig holds the server configuration.
ServerConfig struct {
// MaxPeers it the maximum numbers of peers that can
// be connected to the server.
MaxPeers int
// The user agent of the server.
UserAgent string
// The listen address of the TCP server.
ListenTCP uint16
// The network mode the server will operate on.
// ModePrivNet docker private network.
// ModeTestNet NEO test network.
// ModeMainNet NEO main network.
Net NetMode
// Relay determins whether the server is forwarding its inventory.
Relay bool
// Seeds are a list of initial nodes used to establish connectivity.
Seeds []string
// Maximum duration a single dial may take.
DialTimeout time.Duration
// The duration between protocol ticks with each connected peer.
// When this is 0, the default interval of 5 seconds will be used.
ProtoTickInterval time.Duration
// Level of the internal logger.
LogLevel log.Level
}
)
// NewServerConfig creates a new ServerConfig struct
// using the main applications config.
func NewServerConfig(config Config) ServerConfig {
appConfig := config.ApplicationConfiguration
protoConfig := config.ProtocolConfiguration
return ServerConfig{
UserAgent: config.GenerateUserAgent(),
ListenTCP: appConfig.NodePort,
Net: protoConfig.Magic,
Relay: appConfig.Relay,
Seeds: protoConfig.SeedList,
DialTimeout: (appConfig.DialTimeout * time.Second),
ProtoTickInterval: (appConfig.ProtoTickInterval * time.Second),
MaxPeers: appConfig.MaxPeers,
}
}