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
|
||||
}
|
||||
|
||||
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
|
||||
// a non-nil Client pointer, but received 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/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/wallet"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/util/logger"
|
||||
|
@ -30,6 +31,8 @@ type cfg struct {
|
|||
signer *transaction.Signer
|
||||
|
||||
extraEndpoints []string
|
||||
|
||||
singleCli *client.Client // neo-go client for single client mode
|
||||
}
|
||||
|
||||
const (
|
||||
|
@ -77,6 +80,12 @@ func New(key *keys.PrivateKey, endpoint string, opts ...Option) (*Client, error)
|
|||
opt(cfg)
|
||||
}
|
||||
|
||||
if cfg.singleCli != nil {
|
||||
return &Client{
|
||||
singleClient: blankSingleClient(cfg.singleCli, wallet.NewAccountFromPrivateKey(key), cfg),
|
||||
}, nil
|
||||
}
|
||||
|
||||
endpoints := append(cfg.extraEndpoints, endpoint)
|
||||
|
||||
return &Client{
|
||||
|
@ -92,7 +101,8 @@ func New(key *keys.PrivateKey, endpoint string, opts ...Option) (*Client, error)
|
|||
// WithContext returns a client constructor option that
|
||||
// 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.
|
||||
func WithContext(ctx context.Context) Option {
|
||||
|
@ -106,7 +116,8 @@ func WithContext(ctx context.Context) Option {
|
|||
// WithDialTimeout returns a client constructor option
|
||||
// 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.
|
||||
func WithDialTimeout(dur time.Duration) Option {
|
||||
|
@ -147,8 +158,21 @@ func WithSigner(signer *transaction.Signer) Option {
|
|||
|
||||
// WithExtraEndpoints returns a client constructor option
|
||||
// that specifies additional Neo rpc endpoints.
|
||||
//
|
||||
// Has no effect if WithSingleClient is provided.
|
||||
func WithExtraEndpoints(endpoints []string) Option {
|
||||
return func(c *cfg) {
|
||||
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
|
||||
}
|
||||
|
||||
sCli := blankSingleClient(cli, x.account, &x.cfg)
|
||||
sCli.notary = x.sharedNotary
|
||||
|
||||
c := &Client{
|
||||
singleClient: &singleClient{
|
||||
logger: x.cfg.logger,
|
||||
client: cli,
|
||||
acc: x.account,
|
||||
waitInterval: x.cfg.waitInterval,
|
||||
signer: x.cfg.signer,
|
||||
notary: x.sharedNotary,
|
||||
},
|
||||
singleClient: sCli,
|
||||
}
|
||||
|
||||
x.clients[addr] = c
|
||||
|
|
|
@ -80,22 +80,7 @@ func (c *Client) EnableNotarySupport(opts ...NotaryOption) error {
|
|||
return errors.New("proxy contract hash is missing")
|
||||
}
|
||||
|
||||
var (
|
||||
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,
|
||||
notaryCfg := ¬ary{
|
||||
proxy: cfg.proxy,
|
||||
txValidTime: cfg.txValidTime,
|
||||
roundTime: cfg.roundTime,
|
||||
|
@ -103,6 +88,39 @@ func (c *Client) EnableNotarySupport(opts ...NotaryOption) error {
|
|||
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
|
||||
for _, cached := range c.clients {
|
||||
cached.notary = c.sharedNotary
|
||||
|
|
Loading…
Reference in a new issue