diff --git a/cmd/neofs-ir/defaults.go b/cmd/neofs-ir/defaults.go index eef6de78..c1383715 100644 --- a/cmd/neofs-ir/defaults.go +++ b/cmd/neofs-ir/defaults.go @@ -50,6 +50,7 @@ func defaultConfiguration(cfg *viper.Viper) { cfg.SetDefault("morph.endpoint.client", "") cfg.SetDefault("morph.endpoint.notification", "") cfg.SetDefault("morph.dial_timeout", "10s") + cfg.SetDefault("morph.validators", []string{}) cfg.SetDefault("mainnet.endpoint.client", "") cfg.SetDefault("mainnet.endpoint.notification", "") diff --git a/pkg/innerring/innerring.go b/pkg/innerring/innerring.go index 2036b6ae..7d46498c 100644 --- a/pkg/innerring/innerring.go +++ b/pkg/innerring/innerring.go @@ -4,6 +4,7 @@ import ( "context" "crypto/ecdsa" + "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/util" crypto "github.com/nspcc-dev/neofs-crypto" "github.com/nspcc-dev/neofs-node/pkg/innerring/invoke" @@ -42,8 +43,9 @@ type ( precision precision.Fixed8Converter // internal variables - key *ecdsa.PrivateKey - contracts *contracts + key *ecdsa.PrivateKey + contracts *contracts + predefinedValidators []keys.PublicKey } contracts struct { @@ -82,6 +84,14 @@ func (s *Server) Start(ctx context.Context, intError chan<- error) error { return err } + // vote for sidechain validator if it is prepared in config + err = s.voteForSidechainValidator(s.predefinedValidators) + if err != nil { + // we don't stop inner ring execution on this error + s.log.Warn("can't vote for prepared validators", + zap.String("error", err.Error())) + } + s.localTimers.Start(ctx) // local timers start ticking morphErr := make(chan error) @@ -128,6 +138,12 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper) (*Server, error return nil, err } + // parse default validators + server.predefinedValidators, err = parsePredefinedValidators(cfg) + if err != nil { + return nil, errors.Wrap(err, "ir: can't parse predefined validators list") + } + // create local timer instance server.localTimers = timers.New(&timers.Params{ Log: log, @@ -355,6 +371,29 @@ func parseContracts(cfg *viper.Viper) (*contracts, error) { return result, nil } +func parsePredefinedValidators(cfg *viper.Viper) ([]keys.PublicKey, error) { + publicKeyStrings := cfg.GetStringSlice("morph.validators") + + return ParsePublicKeysFromStrings(publicKeyStrings) +} + +// ParsePublicKeysFromStrings returns slice of neo public keys from slice +// of hex encoded strings. +func ParsePublicKeysFromStrings(pubKeys []string) ([]keys.PublicKey, error) { + publicKeys := make([]keys.PublicKey, 0, len(pubKeys)) + + for i := range pubKeys { + key, err := keys.NewPublicKeyFromString(pubKeys[i]) + if err != nil { + return nil, errors.Wrap(err, "can't decode public key") + } + + publicKeys = append(publicKeys, *key) + } + + return publicKeys, nil +} + func parseAlphabetContracts(cfg *viper.Viper) (res [7]util.Uint160, err error) { // list of glagolic script letters that represent alphabet contracts glagolic := []string{"az", "buky", "vedi", "glagoli", "dobro", "jest", "zhivete"}