From 455fd952dd3174e0698eb390c3ea39f04df41ee5 Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Wed, 9 Jun 2021 18:49:10 +0300 Subject: [PATCH] [#414] ir: Serve ControlService Serve `ControlService` instance on configured endpoint (do not serve if not specified). Read allowed keys from config. Signed-off-by: Leonard Lyubich --- cmd/neofs-ir/defaults.go | 3 ++ pkg/innerring/innerring.go | 66 +++++++++++++++++++++++- pkg/services/control/ir/server/calls.go | 2 +- pkg/services/control/ir/server/prm.go | 6 +-- pkg/services/control/ir/server/server.go | 6 +-- 5 files changed, 73 insertions(+), 10 deletions(-) diff --git a/cmd/neofs-ir/defaults.go b/cmd/neofs-ir/defaults.go index dd4040d7..2913bde3 100644 --- a/cmd/neofs-ir/defaults.go +++ b/cmd/neofs-ir/defaults.go @@ -117,4 +117,7 @@ func defaultConfiguration(cfg *viper.Viper) { // extra fee values for working mode without notary contract cfg.SetDefault("fee.main_chain", 5000_0000) // 0.5 Fixed8 cfg.SetDefault("fee.side_chain", 2_0000_0000) // 2.0 Fixed8 + + cfg.SetDefault("control.authorized_keys", []string{}) + cfg.SetDefault("control.grpc.endpoint", "") } diff --git a/pkg/innerring/innerring.go b/pkg/innerring/innerring.go index 1d26e253..2e12e490 100644 --- a/pkg/innerring/innerring.go +++ b/pkg/innerring/innerring.go @@ -2,9 +2,11 @@ package innerring import ( "context" + "encoding/hex" "errors" "fmt" "io" + "net" "github.com/nspcc-dev/neo-go/pkg/core/block" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" @@ -32,6 +34,8 @@ import ( "github.com/nspcc-dev/neofs-node/pkg/morph/subscriber" "github.com/nspcc-dev/neofs-node/pkg/morph/timer" audittask "github.com/nspcc-dev/neofs-node/pkg/services/audit/taskmanager" + control "github.com/nspcc-dev/neofs-node/pkg/services/control/ir" + controlsrv "github.com/nspcc-dev/neofs-node/pkg/services/control/ir/server" util2 "github.com/nspcc-dev/neofs-node/pkg/util" utilConfig "github.com/nspcc-dev/neofs-node/pkg/util/config" "github.com/nspcc-dev/neofs-node/pkg/util/precision" @@ -39,6 +43,7 @@ import ( "github.com/spf13/viper" "go.uber.org/atomic" "go.uber.org/zap" + "google.golang.org/grpc" ) type ( @@ -91,6 +96,13 @@ type ( // // Errors are logged. closers []func() error + + // Set of component runners which + // should report start errors + // to the application. + // + // TODO: unify with workers. + runners []func(chan<- error) } contracts struct { @@ -152,7 +164,7 @@ func (s *Server) Start(ctx context.Context, intError chan<- error) (err error) { } } - err := s.initConfigFromBlockchain() + err = s.initConfigFromBlockchain() if err != nil { return err } @@ -210,6 +222,10 @@ func (s *Server) Start(ctx context.Context, intError chan<- error) (err error) { s.tickTimers() }) + for _, runner := range s.runners { + runner(intError) + } + go s.morphListener.ListenWithError(ctx, morphErr) // listen for neo:morph events go s.mainnetListener.ListenWithError(ctx, mainnnetErr) // listen for neo:mainnet events @@ -285,6 +301,8 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper) (*Server, error server.key = acc.PrivateKey() + fmt.Println(hex.EncodeToString(server.key.PublicKey().Bytes())) + // get all script hashes of contracts server.contracts, err = parseContracts(cfg) if err != nil { @@ -728,6 +746,52 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper) (*Server, error server.addBlockTimer(sideNotaryTimer) } + controlSvcEndpoint := cfg.GetString("control.grpc.endpoint") + if controlSvcEndpoint != "" { + authKeysStr := cfg.GetStringSlice("control.authorized_keys") + authKeys := make([][]byte, 0, len(authKeysStr)) + + for i := range authKeysStr { + key, err := hex.DecodeString(authKeysStr[i]) + if err != nil { + return nil, fmt.Errorf("could not parse Control authorized key %s: %w", + authKeysStr[i], + err, + ) + } + + authKeys = append(authKeys, key) + } + + var p controlsrv.Prm + + p.SetPrivateKey(*server.key) + p.SetHealthChecker(server) + + controlSvc := controlsrv.New(p, + controlsrv.WithAllowedKeys(authKeys), + ) + + grpcControlSrv := grpc.NewServer() + control.RegisterControlServiceServer(grpcControlSrv, controlSvc) + + server.runners = append(server.runners, func(ch chan<- error) { + lis, err := net.Listen("tcp", controlSvcEndpoint) + if err != nil { + ch <- err + return + } + + go func() { + ch <- grpcControlSrv.Serve(lis) + }() + }) + + server.registerNoErrCloser(grpcControlSrv.GracefulStop) + } else { + log.Info("no Control server endpoint specified, service is disabled") + } + return server, nil } diff --git a/pkg/services/control/ir/server/calls.go b/pkg/services/control/ir/server/calls.go index 11dbe851..c567eed7 100644 --- a/pkg/services/control/ir/server/calls.go +++ b/pkg/services/control/ir/server/calls.go @@ -26,7 +26,7 @@ func (s *Server) HealthCheck(_ context.Context, req *control.HealthCheckRequest) body.SetHealthStatus(s.prm.healthChecker.HealthStatus()) // sign the response - if err := SignMessage(s.prm.key, resp); err != nil { + if err := SignMessage(&s.prm.key.PrivateKey, resp); err != nil { return nil, status.Error(codes.Internal, err.Error()) } diff --git a/pkg/services/control/ir/server/prm.go b/pkg/services/control/ir/server/prm.go index a73a00c7..b4f1f251 100644 --- a/pkg/services/control/ir/server/prm.go +++ b/pkg/services/control/ir/server/prm.go @@ -1,19 +1,19 @@ package control import ( - "crypto/ecdsa" + "github.com/nspcc-dev/neo-go/pkg/crypto/keys" ) // Prm groups required parameters of // Server's constructor. type Prm struct { - key *ecdsa.PrivateKey + key keys.PrivateKey healthChecker HealthChecker } // SetPrivateKey sets private key to sign responses. -func (x *Prm) SetPrivateKey(key *ecdsa.PrivateKey) { +func (x *Prm) SetPrivateKey(key keys.PrivateKey) { x.key = key } diff --git a/pkg/services/control/ir/server/server.go b/pkg/services/control/ir/server/server.go index b22982b5..f0bfddf8 100644 --- a/pkg/services/control/ir/server/server.go +++ b/pkg/services/control/ir/server/server.go @@ -2,8 +2,6 @@ package control import ( "fmt" - - crypto "github.com/nspcc-dev/neofs-crypto" ) // Server is an entity that serves @@ -34,8 +32,6 @@ func panicOnPrmValue(n string, v interface{}) { func New(prm Prm, opts ...Option) *Server { // verify required parameters switch { - case prm.key == nil: - panicOnPrmValue("key", prm.key) case prm.healthChecker == nil: panicOnPrmValue("health checker", prm.healthChecker) } @@ -50,6 +46,6 @@ func New(prm Prm, opts ...Option) *Server { return &Server{ prm: prm, - allowedKeys: append(o.allowedKeys, crypto.MarshalPublicKey(&prm.key.PublicKey)), + allowedKeys: append(o.allowedKeys, prm.key.PublicKey().Bytes()), } }