forked from TrueCloudLab/frostfs-node
[#837] morph: Add WithSingleClient
client constructor option
`WithSingleClient` allows Morph client creation with existing raw neo-go client. Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
This commit is contained in:
parent
264ab489bb
commit
5e74830c38
4 changed files with 74 additions and 26 deletions
|
@ -54,6 +54,16 @@ type singleClient struct {
|
||||||
notary *notary
|
notary *notary
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func blankSingleClient(cli *client.Client, w *wallet.Account, cfg *cfg) *singleClient {
|
||||||
|
return &singleClient{
|
||||||
|
logger: cfg.logger,
|
||||||
|
client: cli,
|
||||||
|
acc: w,
|
||||||
|
waitInterval: cfg.waitInterval,
|
||||||
|
signer: cfg.signer,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ErrNilClient is returned by functions that expect
|
// ErrNilClient is returned by functions that expect
|
||||||
// a non-nil Client pointer, but received nil.
|
// a non-nil Client pointer, but received nil.
|
||||||
var ErrNilClient = errors.New("client is nil")
|
var ErrNilClient = errors.New("client is nil")
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/rpc/client"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/util/logger"
|
"github.com/nspcc-dev/neofs-node/pkg/util/logger"
|
||||||
|
@ -30,6 +31,8 @@ type cfg struct {
|
||||||
signer *transaction.Signer
|
signer *transaction.Signer
|
||||||
|
|
||||||
extraEndpoints []string
|
extraEndpoints []string
|
||||||
|
|
||||||
|
singleCli *client.Client // neo-go client for single client mode
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -77,6 +80,12 @@ func New(key *keys.PrivateKey, endpoint string, opts ...Option) (*Client, error)
|
||||||
opt(cfg)
|
opt(cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if cfg.singleCli != nil {
|
||||||
|
return &Client{
|
||||||
|
singleClient: blankSingleClient(cfg.singleCli, wallet.NewAccountFromPrivateKey(key), cfg),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
endpoints := append(cfg.extraEndpoints, endpoint)
|
endpoints := append(cfg.extraEndpoints, endpoint)
|
||||||
|
|
||||||
return &Client{
|
return &Client{
|
||||||
|
@ -92,7 +101,8 @@ func New(key *keys.PrivateKey, endpoint string, opts ...Option) (*Client, error)
|
||||||
// WithContext returns a client constructor option that
|
// WithContext returns a client constructor option that
|
||||||
// specifies the neo-go client context.
|
// specifies the neo-go client context.
|
||||||
//
|
//
|
||||||
// Ignores nil value.
|
// Ignores nil value. Has no effect if WithSingleClient
|
||||||
|
// is provided.
|
||||||
//
|
//
|
||||||
// If option not provided, context.Background() is used.
|
// If option not provided, context.Background() is used.
|
||||||
func WithContext(ctx context.Context) Option {
|
func WithContext(ctx context.Context) Option {
|
||||||
|
@ -106,7 +116,8 @@ func WithContext(ctx context.Context) Option {
|
||||||
// WithDialTimeout returns a client constructor option
|
// WithDialTimeout returns a client constructor option
|
||||||
// that specifies neo-go client dial timeout duration.
|
// that specifies neo-go client dial timeout duration.
|
||||||
//
|
//
|
||||||
// Ignores non-positive value.
|
// Ignores non-positive value. Has no effect if WithSingleClient
|
||||||
|
// is provided.
|
||||||
//
|
//
|
||||||
// If option not provided, 5s timeout is used.
|
// If option not provided, 5s timeout is used.
|
||||||
func WithDialTimeout(dur time.Duration) Option {
|
func WithDialTimeout(dur time.Duration) Option {
|
||||||
|
@ -147,8 +158,21 @@ func WithSigner(signer *transaction.Signer) Option {
|
||||||
|
|
||||||
// WithExtraEndpoints returns a client constructor option
|
// WithExtraEndpoints returns a client constructor option
|
||||||
// that specifies additional Neo rpc endpoints.
|
// that specifies additional Neo rpc endpoints.
|
||||||
|
//
|
||||||
|
// Has no effect if WithSingleClient is provided.
|
||||||
func WithExtraEndpoints(endpoints []string) Option {
|
func WithExtraEndpoints(endpoints []string) Option {
|
||||||
return func(c *cfg) {
|
return func(c *cfg) {
|
||||||
c.extraEndpoints = append(c.extraEndpoints, endpoints...)
|
c.extraEndpoints = append(c.extraEndpoints, endpoints...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithSingleClient returns a client constructor option
|
||||||
|
// that specifies single neo-go client and forces Client
|
||||||
|
// to use it and only it for requests.
|
||||||
|
//
|
||||||
|
// Passed client must already be initialized.
|
||||||
|
func WithSingleClient(cli *client.Client) Option {
|
||||||
|
return func(c *cfg) {
|
||||||
|
c.singleCli = cli
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -36,15 +36,11 @@ func (x *multiClient) createForAddress(addr string) (*Client, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sCli := blankSingleClient(cli, x.account, &x.cfg)
|
||||||
|
sCli.notary = x.sharedNotary
|
||||||
|
|
||||||
c := &Client{
|
c := &Client{
|
||||||
singleClient: &singleClient{
|
singleClient: sCli,
|
||||||
logger: x.cfg.logger,
|
|
||||||
client: cli,
|
|
||||||
acc: x.account,
|
|
||||||
waitInterval: x.cfg.waitInterval,
|
|
||||||
signer: x.cfg.signer,
|
|
||||||
notary: x.sharedNotary,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
x.clients[addr] = c
|
x.clients[addr] = c
|
||||||
|
|
|
@ -80,22 +80,7 @@ func (c *Client) EnableNotarySupport(opts ...NotaryOption) error {
|
||||||
return errors.New("proxy contract hash is missing")
|
return errors.New("proxy contract hash is missing")
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
notaryCfg := ¬ary{
|
||||||
notaryContract util.Uint160
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
|
|
||||||
if err = c.iterateClients(func(c *Client) error {
|
|
||||||
notaryContract, err = c.client.GetNativeContractHash(nativenames.Notary)
|
|
||||||
return err
|
|
||||||
}); err != nil {
|
|
||||||
return fmt.Errorf("can't get notary contract script hash: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
c.clientsMtx.Lock()
|
|
||||||
|
|
||||||
c.sharedNotary = ¬ary{
|
|
||||||
notary: notaryContract,
|
|
||||||
proxy: cfg.proxy,
|
proxy: cfg.proxy,
|
||||||
txValidTime: cfg.txValidTime,
|
txValidTime: cfg.txValidTime,
|
||||||
roundTime: cfg.roundTime,
|
roundTime: cfg.roundTime,
|
||||||
|
@ -103,6 +88,39 @@ func (c *Client) EnableNotarySupport(opts ...NotaryOption) error {
|
||||||
alphabetSource: cfg.alphabetSource,
|
alphabetSource: cfg.alphabetSource,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
|
||||||
|
getNotaryHashFunc := func(c *Client) error {
|
||||||
|
notaryCfg.notary, err = c.client.GetNativeContractHash(nativenames.Notary)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("can't get notary contract script hash: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.multiClient == nil {
|
||||||
|
// single client case
|
||||||
|
err = getNotaryHashFunc(c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
c.notary = notaryCfg
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// multi client case
|
||||||
|
|
||||||
|
if err = c.iterateClients(getNotaryHashFunc); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
c.clientsMtx.Lock()
|
||||||
|
|
||||||
|
c.sharedNotary = notaryCfg
|
||||||
|
|
||||||
// update client cache
|
// update client cache
|
||||||
for _, cached := range c.clients {
|
for _, cached := range c.clients {
|
||||||
cached.notary = c.sharedNotary
|
cached.notary = c.sharedNotary
|
||||||
|
|
Loading…
Reference in a new issue