forked from TrueCloudLab/frostfs-node
[#496] morph/client: provide notary options on client creation
Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
parent
7cf0093012
commit
458fc4f5ae
5 changed files with 68 additions and 46 deletions
|
@ -327,19 +327,17 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper) (*Server, error
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// create morph client
|
// enable notary support in the client
|
||||||
server.morphClient, err = createClient(ctx, morphChain)
|
var morphNotaryOpts []client.NotaryOption
|
||||||
if err != nil {
|
if !server.sideNotaryConfig.disabled {
|
||||||
return nil, err
|
morphNotaryOpts = append(morphNotaryOpts, client.WithProxyContract(server.contracts.proxy))
|
||||||
}
|
}
|
||||||
|
|
||||||
// enable notary support in the client
|
// create morph client
|
||||||
if !server.sideNotaryConfig.disabled {
|
server.morphClient, err = createClient(ctx, morphChain, morphNotaryOpts...)
|
||||||
err = server.morphClient.EnableNotarySupport(server.contracts.proxy)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
withoutMainNet := cfg.GetBool("without_mainnet")
|
withoutMainNet := cfg.GetBool("without_mainnet")
|
||||||
|
|
||||||
|
@ -359,23 +357,20 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper) (*Server, error
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// create mainnet client
|
// enable notary support in the client
|
||||||
server.mainnetClient, err = createClient(ctx, mainnetChain)
|
var mainnetNotaryOpts []client.NotaryOption
|
||||||
if err != nil {
|
if !server.mainNotaryConfig.disabled {
|
||||||
return nil, err
|
mainnetNotaryOpts = append(mainnetNotaryOpts,
|
||||||
|
client.WithProxyContract(server.contracts.processing),
|
||||||
|
client.WithAlphabetSource(server.morphClient.Committee))
|
||||||
}
|
}
|
||||||
|
|
||||||
// enable notary support in the client
|
// create mainnet client
|
||||||
if !server.mainNotaryConfig.disabled {
|
server.mainnetClient, err = createClient(ctx, mainnetChain, mainnetNotaryOpts...)
|
||||||
err = server.mainnetClient.EnableNotarySupport(
|
|
||||||
server.contracts.processing,
|
|
||||||
client.WithAlphabetSource(server.morphClient.Committee),
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
server.pubKey = server.key.PublicKey().Bytes()
|
server.pubKey = server.key.PublicKey().Bytes()
|
||||||
|
|
||||||
|
@ -392,7 +387,7 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper) (*Server, error
|
||||||
|
|
||||||
fee := server.feeConfig.SideChainFee()
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -402,7 +397,7 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper) (*Server, error
|
||||||
return nil, err
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -811,13 +806,14 @@ func createListener(ctx context.Context, p *chainParams) (event.Listener, error)
|
||||||
return listener, err
|
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(
|
return client.New(
|
||||||
p.key,
|
p.key,
|
||||||
p.cfg.GetString(p.name+".endpoint.client"),
|
p.cfg.GetString(p.name+".endpoint.client"),
|
||||||
client.WithContext(ctx),
|
client.WithContext(ctx),
|
||||||
client.WithLogger(p.log),
|
client.WithLogger(p.log),
|
||||||
client.WithDialTimeout(p.cfg.GetDuration(p.name+".dial_timeout")),
|
client.WithDialTimeout(p.cfg.GetDuration(p.name+".dial_timeout")),
|
||||||
|
client.WithNotaryOptions(notaryOpts...),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,8 @@ import (
|
||||||
type ClientWrapper audit.Client
|
type ClientWrapper audit.Client
|
||||||
|
|
||||||
// NewFromMorph returns the wrapper instance from the raw morph client.
|
// NewFromMorph returns the wrapper instance from the raw morph client.
|
||||||
func NewFromMorph(cli *client.Client, contract util.Uint160, fee fixedn.Fixed8) (*ClientWrapper, error) {
|
func NewFromMorph(cli *client.Client, contract util.Uint160, fee fixedn.Fixed8, opts ...client.StaticClientOption) (*ClientWrapper, error) {
|
||||||
staticClient, err := client.NewStatic(cli, contract, fee)
|
staticClient, err := client.NewStatic(cli, contract, fee, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames"
|
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames"
|
||||||
|
@ -27,6 +28,8 @@ type cfg struct {
|
||||||
gas util.Uint160 // native gas script-hash
|
gas util.Uint160 // native gas script-hash
|
||||||
|
|
||||||
waitInterval time.Duration
|
waitInterval time.Duration
|
||||||
|
|
||||||
|
notaryOpts []NotaryOption
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -93,14 +96,22 @@ func New(key *keys.PrivateKey, endpoint string, opts ...Option) (*Client, error)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Client{
|
c := &Client{
|
||||||
logger: cfg.logger,
|
logger: cfg.logger,
|
||||||
client: cli,
|
client: cli,
|
||||||
acc: account,
|
acc: account,
|
||||||
gas: gas,
|
gas: gas,
|
||||||
designate: designate,
|
designate: designate,
|
||||||
waitInterval: cfg.waitInterval,
|
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
|
// 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -23,8 +23,8 @@ type Wrapper struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFromMorph returns the wrapper instance from the raw morph client.
|
// NewFromMorph returns the wrapper instance from the raw morph client.
|
||||||
func NewFromMorph(cli *client.Client, contract util.Uint160, fee fixedn.Fixed8) (*Wrapper, error) {
|
func NewFromMorph(cli *client.Client, contract util.Uint160, fee fixedn.Fixed8, opts ...client.StaticClientOption) (*Wrapper, error) {
|
||||||
staticClient, err := client.NewStatic(cli, contract, fee)
|
staticClient, err := client.NewStatic(cli, contract, fee, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("can't create netmap static client: %w", err)
|
return nil, fmt.Errorf("can't create netmap static client: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,8 @@ type (
|
||||||
}
|
}
|
||||||
|
|
||||||
notaryCfg struct {
|
notaryCfg struct {
|
||||||
|
proxy util.Uint160
|
||||||
|
|
||||||
txValidTime, roundTime, fallbackTime uint32
|
txValidTime, roundTime, fallbackTime uint32
|
||||||
|
|
||||||
alphabetSource AlphabetKeys
|
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
|
// ability for client to get alphabet keys from committee or provided source
|
||||||
// and use proxy contract script hash to create tx for notary contract.
|
// 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)
|
cfg := defaultNotaryConfig(c)
|
||||||
|
|
||||||
for _, opt := range opts {
|
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)
|
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{
|
c.notary = ¬ary{
|
||||||
notary: notaryContract,
|
notary: notaryContract,
|
||||||
proxy: proxy,
|
proxy: cfg.proxy,
|
||||||
txValidTime: cfg.txValidTime,
|
txValidTime: cfg.txValidTime,
|
||||||
roundTime: cfg.roundTime,
|
roundTime: cfg.roundTime,
|
||||||
fallbackTime: cfg.fallbackTime,
|
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
|
// 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 {
|
func (c *Client) NotaryEnabled() bool {
|
||||||
return c.notary != nil
|
return c.notary != nil
|
||||||
}
|
}
|
||||||
|
@ -102,8 +108,7 @@ func (c *Client) NotaryEnabled() bool {
|
||||||
// be called periodically. Notary support should be enabled in client to
|
// be called periodically. Notary support should be enabled in client to
|
||||||
// use this function.
|
// use this function.
|
||||||
//
|
//
|
||||||
// This function must be invoked after `EnableNotarySupport()` otherwise it
|
// This function must be invoked with notary enabled otherwise it throws panic.
|
||||||
// throws panic.
|
|
||||||
func (c *Client) DepositNotary(amount fixedn.Fixed8, delta uint32) (util.Uint256, error) {
|
func (c *Client) DepositNotary(amount fixedn.Fixed8, delta uint32) (util.Uint256, error) {
|
||||||
if c.notary == nil {
|
if c.notary == nil {
|
||||||
panic(notaryNotEnabledPanicMsg)
|
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.
|
// GetNotaryDeposit returns deposit of client's account in notary contract.
|
||||||
// Notary support should be enabled in client to use this function.
|
// Notary support should be enabled in client to use this function.
|
||||||
//
|
//
|
||||||
// This function must be invoked after `EnableNotarySupport()` otherwise it
|
// This function must be invoked with notary enabled otherwise it throws panic.
|
||||||
// throws panic.
|
|
||||||
func (c *Client) GetNotaryDeposit() (int64, error) {
|
func (c *Client) GetNotaryDeposit() (int64, error) {
|
||||||
if c.notary == nil {
|
if c.notary == nil {
|
||||||
panic(notaryNotEnabledPanicMsg)
|
panic(notaryNotEnabledPanicMsg)
|
||||||
|
@ -167,8 +171,7 @@ func (c *Client) GetNotaryDeposit() (int64, error) {
|
||||||
// UpdateNotaryList updates list of notary nodes in designate contract. Requires
|
// UpdateNotaryList updates list of notary nodes in designate contract. Requires
|
||||||
// committee multi signature.
|
// committee multi signature.
|
||||||
//
|
//
|
||||||
// This function must be invoked after `EnableNotarySupport()` otherwise it
|
// This function must be invoked with notary enabled otherwise it throws panic.
|
||||||
// throws panic.
|
|
||||||
func (c *Client) UpdateNotaryList(list keys.PublicKeys) error {
|
func (c *Client) UpdateNotaryList(list keys.PublicKeys) error {
|
||||||
if c.notary == nil {
|
if c.notary == nil {
|
||||||
panic(notaryNotEnabledPanicMsg)
|
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.
|
// As for side chain list should contain all inner ring nodes.
|
||||||
// Requires committee multi signature.
|
// Requires committee multi signature.
|
||||||
//
|
//
|
||||||
// This function must be invoked after `EnableNotarySupport()` otherwise it
|
// This function must be invoked with notary enabled otherwise it throws panic.
|
||||||
// throws panic.
|
|
||||||
func (c *Client) UpdateNeoFSAlphabetList(list keys.PublicKeys) error {
|
func (c *Client) UpdateNeoFSAlphabetList(list keys.PublicKeys) error {
|
||||||
if c.notary == nil {
|
if c.notary == nil {
|
||||||
panic(notaryNotEnabledPanicMsg)
|
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
|
// blockchain. Fallback tx is a `RET`. If Notary support is not enabled
|
||||||
// it fallbacks to a simple `Invoke()`.
|
// it fallbacks to a simple `Invoke()`.
|
||||||
//
|
//
|
||||||
// This function must be invoked after `EnableNotarySupport()` otherwise it
|
// This function must be invoked with notary enabled otherwise it throws panic.
|
||||||
// throws panic.
|
|
||||||
func (c *Client) NotaryInvoke(contract util.Uint160, fee fixedn.Fixed8, method string, args ...interface{}) error {
|
func (c *Client) NotaryInvoke(contract util.Uint160, fee fixedn.Fixed8, method string, args ...interface{}) error {
|
||||||
if c.notary == nil {
|
if c.notary == nil {
|
||||||
return c.Invoke(contract, fee, method, args...)
|
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"
|
const alreadyOnChainErrorMessage = "already on chain"
|
||||||
|
|
||||||
// Neo RPC node can return `core.ErrInvalidAttribute` error with
|
// Neo RPC node can return `core.ErrInvalidAttribute` error with
|
||||||
|
|
Loading…
Reference in a new issue