From 458fc4f5aee6469ca7de5720856923007e98ef2d Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Tue, 1 Jun 2021 12:29:32 +0300 Subject: [PATCH] [#496] morph/client: provide notary options on client creation Signed-off-by: Evgenii Stratonikov --- pkg/innerring/innerring.go | 48 ++++++++++------------ pkg/morph/client/audit/wrapper/wrapper.go | 4 +- pkg/morph/client/constructor.go | 22 +++++++++- pkg/morph/client/netmap/wrapper/wrapper.go | 4 +- pkg/morph/client/notary.go | 36 +++++++++------- 5 files changed, 68 insertions(+), 46 deletions(-) diff --git a/pkg/innerring/innerring.go b/pkg/innerring/innerring.go index 150fb3ab2..f8f6ced88 100644 --- a/pkg/innerring/innerring.go +++ b/pkg/innerring/innerring.go @@ -327,18 +327,16 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper) (*Server, error return nil, err } - // create morph client - server.morphClient, err = createClient(ctx, morphChain) - if err != nil { - return nil, err + // enable notary support in the client + var morphNotaryOpts []client.NotaryOption + if !server.sideNotaryConfig.disabled { + morphNotaryOpts = append(morphNotaryOpts, client.WithProxyContract(server.contracts.proxy)) } - // enable notary support in the client - if !server.sideNotaryConfig.disabled { - err = server.morphClient.EnableNotarySupport(server.contracts.proxy) - if err != nil { - return nil, err - } + // create morph client + server.morphClient, err = createClient(ctx, morphChain, morphNotaryOpts...) + if err != nil { + return nil, err } withoutMainNet := cfg.GetBool("without_mainnet") @@ -359,21 +357,18 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper) (*Server, error return nil, err } - // create mainnet client - server.mainnetClient, err = createClient(ctx, mainnetChain) - if err != nil { - return nil, err + // enable notary support in the client + var mainnetNotaryOpts []client.NotaryOption + if !server.mainNotaryConfig.disabled { + mainnetNotaryOpts = append(mainnetNotaryOpts, + client.WithProxyContract(server.contracts.processing), + client.WithAlphabetSource(server.morphClient.Committee)) } - // enable notary support in the client - if !server.mainNotaryConfig.disabled { - err = server.mainnetClient.EnableNotarySupport( - server.contracts.processing, - client.WithAlphabetSource(server.morphClient.Committee), - ) - if err != nil { - return nil, err - } + // create mainnet client + server.mainnetClient, err = createClient(ctx, mainnetChain, mainnetNotaryOpts...) + if err != nil { + return nil, err } } @@ -392,7 +387,7 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper) (*Server, error fee := server.feeConfig.SideChainFee() - server.auditClient, err = auditWrapper.NewFromMorph(server.morphClient, server.contracts.audit, fee) + server.auditClient, err = auditWrapper.NewFromMorph(server.morphClient, server.contracts.audit, fee, client.TryNotary()) if err != nil { return nil, err } @@ -402,7 +397,7 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper) (*Server, error return nil, err } - server.netmapClient, err = nmWrapper.NewFromMorph(server.morphClient, server.contracts.netmap, fee) + server.netmapClient, err = nmWrapper.NewFromMorph(server.morphClient, server.contracts.netmap, fee, client.TryNotary()) if err != nil { return nil, err } @@ -811,13 +806,14 @@ func createListener(ctx context.Context, p *chainParams) (event.Listener, error) return listener, err } -func createClient(ctx context.Context, p *chainParams) (*client.Client, error) { +func createClient(ctx context.Context, p *chainParams, notaryOpts ...client.NotaryOption) (*client.Client, error) { return client.New( p.key, p.cfg.GetString(p.name+".endpoint.client"), client.WithContext(ctx), client.WithLogger(p.log), client.WithDialTimeout(p.cfg.GetDuration(p.name+".dial_timeout")), + client.WithNotaryOptions(notaryOpts...), ) } diff --git a/pkg/morph/client/audit/wrapper/wrapper.go b/pkg/morph/client/audit/wrapper/wrapper.go index 18ed37325..c46a85912 100644 --- a/pkg/morph/client/audit/wrapper/wrapper.go +++ b/pkg/morph/client/audit/wrapper/wrapper.go @@ -12,8 +12,8 @@ import ( type ClientWrapper audit.Client // NewFromMorph returns the wrapper instance from the raw morph client. -func NewFromMorph(cli *client.Client, contract util.Uint160, fee fixedn.Fixed8) (*ClientWrapper, error) { - staticClient, err := client.NewStatic(cli, contract, fee) +func NewFromMorph(cli *client.Client, contract util.Uint160, fee fixedn.Fixed8, opts ...client.StaticClientOption) (*ClientWrapper, error) { + staticClient, err := client.NewStatic(cli, contract, fee, opts...) if err != nil { return nil, err } diff --git a/pkg/morph/client/constructor.go b/pkg/morph/client/constructor.go index e2d89f4ba..7d8726168 100644 --- a/pkg/morph/client/constructor.go +++ b/pkg/morph/client/constructor.go @@ -2,6 +2,7 @@ package client import ( "context" + "fmt" "time" "github.com/nspcc-dev/neo-go/pkg/core/native/nativenames" @@ -27,6 +28,8 @@ type cfg struct { gas util.Uint160 // native gas script-hash waitInterval time.Duration + + notaryOpts []NotaryOption } const ( @@ -93,14 +96,22 @@ func New(key *keys.PrivateKey, endpoint string, opts ...Option) (*Client, error) return nil, err } - return &Client{ + c := &Client{ logger: cfg.logger, client: cli, acc: account, gas: gas, designate: designate, waitInterval: cfg.waitInterval, - }, nil + } + + if len(cfg.notaryOpts) != 0 { + if err := c.enableNotarySupport(cfg.notaryOpts...); err != nil { + return nil, fmt.Errorf("can't enable notary support: %w", err) + } + } + + return c, nil } // WithContext returns a client constructor option that @@ -144,3 +155,10 @@ func WithLogger(logger *logger.Logger) Option { } } } + +// WithNotaryOptions enables notary support and sets notary options for the client. +func WithNotaryOptions(opts ...NotaryOption) Option { + return func(c *cfg) { + c.notaryOpts = opts + } +} diff --git a/pkg/morph/client/netmap/wrapper/wrapper.go b/pkg/morph/client/netmap/wrapper/wrapper.go index 9310eeb17..a05c92476 100644 --- a/pkg/morph/client/netmap/wrapper/wrapper.go +++ b/pkg/morph/client/netmap/wrapper/wrapper.go @@ -23,8 +23,8 @@ type Wrapper struct { } // NewFromMorph returns the wrapper instance from the raw morph client. -func NewFromMorph(cli *client.Client, contract util.Uint160, fee fixedn.Fixed8) (*Wrapper, error) { - staticClient, err := client.NewStatic(cli, contract, fee) +func NewFromMorph(cli *client.Client, contract util.Uint160, fee fixedn.Fixed8, opts ...client.StaticClientOption) (*Wrapper, error) { + staticClient, err := client.NewStatic(cli, contract, fee, opts...) if err != nil { return nil, fmt.Errorf("can't create netmap static client: %w", err) } diff --git a/pkg/morph/client/notary.go b/pkg/morph/client/notary.go index ea5dfe831..f4355ec47 100644 --- a/pkg/morph/client/notary.go +++ b/pkg/morph/client/notary.go @@ -31,6 +31,8 @@ type ( } notaryCfg struct { + proxy util.Uint160 + txValidTime, roundTime, fallbackTime uint32 alphabetSource AlphabetKeys @@ -63,10 +65,10 @@ func defaultNotaryConfig(c *Client) *notaryCfg { } } -// EnableNotarySupport creates notary structure in client that provides +// enableNotarySupport creates notary structure in client that provides // ability for client to get alphabet keys from committee or provided source // and use proxy contract script hash to create tx for notary contract. -func (c *Client) EnableNotarySupport(proxy util.Uint160, opts ...NotaryOption) error { +func (c *Client) enableNotarySupport(opts ...NotaryOption) error { cfg := defaultNotaryConfig(c) for _, opt := range opts { @@ -78,9 +80,13 @@ func (c *Client) EnableNotarySupport(proxy util.Uint160, opts ...NotaryOption) e return fmt.Errorf("can't get notary contract script hash: %w", err) } + if cfg.proxy.Equals(util.Uint160{}) { + return errors.New("proxy contract hash is missing") + } + c.notary = ¬ary{ notary: notaryContract, - proxy: proxy, + proxy: cfg.proxy, txValidTime: cfg.txValidTime, roundTime: cfg.roundTime, fallbackTime: cfg.fallbackTime, @@ -91,7 +97,7 @@ func (c *Client) EnableNotarySupport(proxy util.Uint160, opts ...NotaryOption) e } // NotaryEnabled returns true if notary support was enabled in this instance -// of client by calling `EnableNotarySupport()`. Otherwise returns false. +// of client by providing notary options on client creation. Otherwise returns false. func (c *Client) NotaryEnabled() bool { return c.notary != nil } @@ -102,8 +108,7 @@ func (c *Client) NotaryEnabled() bool { // be called periodically. Notary support should be enabled in client to // use this function. // -// This function must be invoked after `EnableNotarySupport()` otherwise it -// throws panic. +// This function must be invoked with notary enabled otherwise it throws panic. func (c *Client) DepositNotary(amount fixedn.Fixed8, delta uint32) (util.Uint256, error) { if c.notary == nil { panic(notaryNotEnabledPanicMsg) @@ -138,8 +143,7 @@ func (c *Client) DepositNotary(amount fixedn.Fixed8, delta uint32) (util.Uint256 // GetNotaryDeposit returns deposit of client's account in notary contract. // Notary support should be enabled in client to use this function. // -// This function must be invoked after `EnableNotarySupport()` otherwise it -// throws panic. +// This function must be invoked with notary enabled otherwise it throws panic. func (c *Client) GetNotaryDeposit() (int64, error) { if c.notary == nil { panic(notaryNotEnabledPanicMsg) @@ -167,8 +171,7 @@ func (c *Client) GetNotaryDeposit() (int64, error) { // UpdateNotaryList updates list of notary nodes in designate contract. Requires // committee multi signature. // -// This function must be invoked after `EnableNotarySupport()` otherwise it -// throws panic. +// This function must be invoked with notary enabled otherwise it throws panic. func (c *Client) UpdateNotaryList(list keys.PublicKeys) error { if c.notary == nil { panic(notaryNotEnabledPanicMsg) @@ -185,8 +188,7 @@ func (c *Client) UpdateNotaryList(list keys.PublicKeys) error { // As for side chain list should contain all inner ring nodes. // Requires committee multi signature. // -// This function must be invoked after `EnableNotarySupport()` otherwise it -// throws panic. +// This function must be invoked with notary enabled otherwise it throws panic. func (c *Client) UpdateNeoFSAlphabetList(list keys.PublicKeys) error { if c.notary == nil { panic(notaryNotEnabledPanicMsg) @@ -203,8 +205,7 @@ func (c *Client) UpdateNeoFSAlphabetList(list keys.PublicKeys) error { // blockchain. Fallback tx is a `RET`. If Notary support is not enabled // it fallbacks to a simple `Invoke()`. // -// This function must be invoked after `EnableNotarySupport()` otherwise it -// throws panic. +// This function must be invoked with notary enabled otherwise it throws panic. func (c *Client) NotaryInvoke(contract util.Uint160, fee fixedn.Fixed8, method string, args ...interface{}) error { if c.notary == nil { return c.Invoke(contract, fee, method, args...) @@ -497,6 +498,13 @@ func WithAlphabetSource(t AlphabetKeys) NotaryOption { } } +// WithProxyContract sets proxy contract hash. +func WithProxyContract(h util.Uint160) NotaryOption { + return func(c *notaryCfg) { + c.proxy = h + } +} + const alreadyOnChainErrorMessage = "already on chain" // Neo RPC node can return `core.ErrInvalidAttribute` error with