[#28] Make storage node configurable

To run storage node at dev-env environment it should have
configurable parameters. To keep `cfg` structures we can
read configuration from env and yml config file with viper
and parse values such as script hashes, fees, keys into
`cfg` structures.

Signed-off-by: Alex Vanin <alexey@nspcc.ru>
This commit is contained in:
Alex Vanin 2020-09-16 10:45:08 +03:00
parent 001a23eb31
commit 86b9aefcae
8 changed files with 121 additions and 46 deletions

View file

@ -1,7 +1,6 @@
package main package main
import ( import (
"github.com/nspcc-dev/neo-go/pkg/util"
accountingGRPC "github.com/nspcc-dev/neofs-api-go/v2/accounting/grpc" accountingGRPC "github.com/nspcc-dev/neofs-api-go/v2/accounting/grpc"
"github.com/nspcc-dev/neofs-api-go/v2/session" "github.com/nspcc-dev/neofs-api-go/v2/session"
"github.com/nspcc-dev/neofs-node/pkg/morph/client" "github.com/nspcc-dev/neofs-node/pkg/morph/client"
@ -17,10 +16,11 @@ func initAccountingService(c *cfg) {
initMorphComponents(c) initMorphComponents(c)
} }
u160, err := util.Uint160DecodeStringLE(c.cfgAccounting.scriptHash) staticClient, err := client.NewStatic(
fatalOnErr(err) c.cfgMorph.client,
c.cfgAccounting.scriptHash,
staticClient, err := client.NewStatic(c.cfgMorph.client, u160, c.cfgAccounting.fee) c.cfgAccounting.fee,
)
fatalOnErr(err) fatalOnErr(err)
balanceClient, err := balance.New(staticClient) balanceClient, err := balance.New(staticClient)

View file

@ -4,18 +4,47 @@ import (
"context" "context"
"crypto/ecdsa" "crypto/ecdsa"
"net" "net"
"strings"
"sync" "sync"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
crypto "github.com/nspcc-dev/neofs-crypto" crypto "github.com/nspcc-dev/neofs-crypto"
"github.com/nspcc-dev/neofs-node/misc"
"github.com/nspcc-dev/neofs-node/pkg/morph/client" "github.com/nspcc-dev/neofs-node/pkg/morph/client"
tokenStorage "github.com/nspcc-dev/neofs-node/pkg/services/session/storage" tokenStorage "github.com/nspcc-dev/neofs-node/pkg/services/session/storage"
"github.com/spf13/viper"
"google.golang.org/grpc" "google.golang.org/grpc"
) )
const (
// config keys for cfgNodeInfo
cfgNodeKey = "node.key"
cfgBootstrapAddress = "node.address"
// config keys for cfgGRPC
cfgListenAddress = "grpc.endpoint"
// config keys for cfgMorph
cfgMorphRPCAddress = "morph.endpoint"
// config keys for cfgAccounting
cfgAccountingContract = "accounting.scripthash"
cfgAccountingFee = "accounting.fee"
// config keys for cfgNetmap
cfgNetmapContract = "netmap.scripthash"
cfgNetmapFee = "netmap.fee"
// config keys for cfgContainer
cfgContainerContract = "container.scripthash"
cfgContainerFee = "container.fee"
)
type cfg struct { type cfg struct {
ctx context.Context ctx context.Context
viper *viper.Viper
wg *sync.WaitGroup wg *sync.WaitGroup
key *ecdsa.PrivateKey key *ecdsa.PrivateKey
@ -36,33 +65,29 @@ type cfg struct {
} }
type cfgGRPC struct { type cfgGRPC struct {
endpoint string
listener net.Listener listener net.Listener
server *grpc.Server server *grpc.Server
} }
type cfgMorph struct { type cfgMorph struct {
endpoint string
client *client.Client client *client.Client
} }
type cfgAccounting struct { type cfgAccounting struct {
scriptHash string scriptHash util.Uint160
fee util.Fixed8 fee util.Fixed8
} }
type cfgContainer struct { type cfgContainer struct {
scriptHash string scriptHash util.Uint160
fee util.Fixed8 fee util.Fixed8
} }
type cfgNetmap struct { type cfgNetmap struct {
scriptHash string scriptHash util.Uint160
fee util.Fixed8 fee util.Fixed8
} }
@ -71,8 +96,6 @@ type BootstrapType uint32
type cfgNodeInfo struct { type cfgNodeInfo struct {
bootType BootstrapType bootType BootstrapType
address string
} }
const ( const (
@ -81,34 +104,82 @@ const (
RelayNode RelayNode
) )
func defaultCfg() *cfg { func initCfg(path string) *cfg {
key, err := crypto.LoadPrivateKey("Kwk6k2eC3L3QuPvD8aiaNyoSXgQ2YL1bwS5CP1oKoA9waeAze97s") viperCfg := initViper(path)
key, err := crypto.LoadPrivateKey(viperCfg.GetString(cfgNodeKey))
fatalOnErr(err)
u160Accounting, err := util.Uint160DecodeStringLE(
viperCfg.GetString(cfgAccountingContract))
fatalOnErr(err)
u160Netmap, err := util.Uint160DecodeStringLE(
viperCfg.GetString(cfgNetmapContract))
fatalOnErr(err)
u160Container, err := util.Uint160DecodeStringLE(
viperCfg.GetString(cfgContainerContract))
fatalOnErr(err) fatalOnErr(err)
return &cfg{ return &cfg{
ctx: context.Background(), ctx: context.Background(),
wg: new(sync.WaitGroup), viper: viperCfg,
key: key, wg: new(sync.WaitGroup),
cfgGRPC: cfgGRPC{ key: key,
endpoint: "127.0.0.1:50501",
},
cfgMorph: cfgMorph{
endpoint: "http://morph_chain.localtest.nspcc.ru:30333/",
},
cfgAccounting: cfgAccounting{ cfgAccounting: cfgAccounting{
scriptHash: "1aeefe1d0dfade49740fff779c02cd4a0538ffb1", scriptHash: u160Accounting,
fee: util.Fixed8(1), fee: util.Fixed8(viperCfg.GetInt(cfgAccountingFee)),
}, },
cfgContainer: cfgContainer{ cfgContainer: cfgContainer{
scriptHash: "9d2ca84d7fb88213c4baced5a6ed4dc402309039", scriptHash: u160Container,
fee: util.Fixed8(1), fee: util.Fixed8(viperCfg.GetInt(cfgContainerFee)),
}, },
cfgNetmap: cfgNetmap{ cfgNetmap: cfgNetmap{
scriptHash: "75194459637323ea8837d2afe8225ec74a5658c3", scriptHash: u160Netmap,
fee: util.Fixed8(1), fee: util.Fixed8(viperCfg.GetInt(cfgNetmapFee)),
}, },
cfgNodeInfo: cfgNodeInfo{ cfgNodeInfo: cfgNodeInfo{
bootType: StorageNode, bootType: StorageNode,
}, },
} }
} }
func initViper(path string) *viper.Viper {
v := viper.New()
v.SetEnvPrefix(misc.Prefix)
v.AutomaticEnv()
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
v.SetDefault("app.name", misc.NodeName)
v.SetDefault("app.version", misc.Version)
defaultConfiguration(v)
if path != "" {
v.SetConfigFile(path)
v.SetConfigType("yml")
fatalOnErr(v.ReadInConfig())
}
return v
}
func defaultConfiguration(v *viper.Viper) {
// fixme: all hardcoded private keys must be removed
v.SetDefault(cfgNodeKey, "Kwk6k2eC3L3QuPvD8aiaNyoSXgQ2YL1bwS5CP1oKoA9waeAze97s")
v.SetDefault(cfgBootstrapAddress, "") // address to bootstrap with
v.SetDefault(cfgMorphRPCAddress, "http://morph_chain.localtest.nspcc.ru:30333/")
v.SetDefault(cfgListenAddress, "127.0.0.1:50501") // listen address
v.SetDefault(cfgAccountingContract, "1aeefe1d0dfade49740fff779c02cd4a0538ffb1")
v.SetDefault(cfgAccountingFee, "1")
v.SetDefault(cfgContainerContract, "9d2ca84d7fb88213c4baced5a6ed4dc402309039")
v.SetDefault(cfgContainerFee, "1")
v.SetDefault(cfgNetmapContract, "75194459637323ea8837d2afe8225ec74a5658c3")
v.SetDefault(cfgNetmapFee, "1")
}

View file

@ -1,7 +1,6 @@
package main package main
import ( import (
"github.com/nspcc-dev/neo-go/pkg/util"
containerGRPC "github.com/nspcc-dev/neofs-api-go/v2/container/grpc" containerGRPC "github.com/nspcc-dev/neofs-api-go/v2/container/grpc"
"github.com/nspcc-dev/neofs-api-go/v2/session" "github.com/nspcc-dev/neofs-api-go/v2/session"
"github.com/nspcc-dev/neofs-node/pkg/morph/client" "github.com/nspcc-dev/neofs-node/pkg/morph/client"
@ -12,10 +11,11 @@ import (
) )
func initContainerService(c *cfg) { func initContainerService(c *cfg) {
u160, err := util.Uint160DecodeStringLE(c.cfgContainer.scriptHash) staticClient, err := client.NewStatic(
fatalOnErr(err) c.cfgMorph.client,
c.cfgContainer.scriptHash,
staticClient, err := client.NewStatic(c.cfgMorph.client, u160, c.cfgContainer.fee) c.cfgContainer.fee,
)
fatalOnErr(err) fatalOnErr(err)
cnrClient, err := container.New(staticClient) cnrClient, err := container.New(staticClient)

View file

@ -10,7 +10,7 @@ import (
func initGRPC(c *cfg) { func initGRPC(c *cfg) {
var err error var err error
c.cfgGRPC.listener, err = net.Listen("tcp", c.cfgGRPC.endpoint) c.cfgGRPC.listener, err = net.Listen("tcp", c.viper.GetString(cfgListenAddress))
fatalOnErr(err) fatalOnErr(err)
c.cfgGRPC.server = grpc.NewServer() c.cfgGRPC.server = grpc.NewServer()

View file

@ -1,6 +1,7 @@
package main package main
import ( import (
"flag"
"fmt" "fmt"
"log" "log"
@ -14,7 +15,10 @@ func fatalOnErr(err error) {
} }
func main() { func main() {
c := defaultCfg() configFile := flag.String("config", "", "path to config")
flag.Parse()
c := initCfg(*configFile)
init_(c) init_(c)

View file

@ -1,7 +1,6 @@
package main package main
import ( import (
"github.com/nspcc-dev/neo-go/pkg/util"
crypto "github.com/nspcc-dev/neofs-crypto" crypto "github.com/nspcc-dev/neofs-crypto"
"github.com/nspcc-dev/neofs-node/pkg/morph/client" "github.com/nspcc-dev/neofs-node/pkg/morph/client"
"github.com/nspcc-dev/neofs-node/pkg/morph/client/netmap" "github.com/nspcc-dev/neofs-node/pkg/morph/client/netmap"
@ -11,16 +10,17 @@ import (
func initMorphComponents(c *cfg) { func initMorphComponents(c *cfg) {
var err error var err error
c.cfgMorph.client, err = client.New(c.key, c.cfgMorph.endpoint) c.cfgMorph.client, err = client.New(c.key, c.viper.GetString(cfgMorphRPCAddress))
fatalOnErr(err) fatalOnErr(err)
} }
func bootstrapNode(c *cfg) { func bootstrapNode(c *cfg) {
if c.cfgNodeInfo.bootType == StorageNode { if c.cfgNodeInfo.bootType == StorageNode {
u160, err := util.Uint160DecodeStringLE(c.cfgNetmap.scriptHash) staticClient, err := client.NewStatic(
fatalOnErr(err) c.cfgMorph.client,
c.cfgNetmap.scriptHash,
staticClient, err := client.NewStatic(c.cfgMorph.client, u160, c.cfgContainer.fee) c.cfgContainer.fee,
)
fatalOnErr(err) fatalOnErr(err)
cli, err := netmap.New(staticClient) cli, err := netmap.New(staticClient)
@ -30,7 +30,7 @@ func bootstrapNode(c *cfg) {
fatalOnErr(err) fatalOnErr(err)
peerInfo := new(netmap.NodeInfo) peerInfo := new(netmap.NodeInfo)
peerInfo.SetAddress(c.cfgNodeInfo.address) peerInfo.SetAddress(c.viper.GetString(cfgBootstrapAddress))
peerInfo.SetPublicKey(crypto.MarshalPublicKey(&c.key.PublicKey)) peerInfo.SetPublicKey(crypto.MarshalPublicKey(&c.key.PublicKey))
// todo: add attributes as opts // todo: add attributes as opts

2
go.mod
View file

@ -35,4 +35,4 @@ require (
) )
// Used for debug reasons // Used for debug reasons
replace github.com/nspcc-dev/neofs-api-go => ../neofs-api-go // replace github.com/nspcc-dev/neofs-api-go => ../neofs-api-go

BIN
go.sum

Binary file not shown.