[#16] frostfsid: Fix client invocation
All checks were successful
/ DCO (pull_request) Successful in 50s
/ Vulncheck (pull_request) Successful in 1m4s
/ Builds (1.21) (pull_request) Successful in 1m11s
/ Builds (1.22) (pull_request) Successful in 1m9s
/ Lint (pull_request) Successful in 2m7s
/ Tests (1.21) (pull_request) Successful in 1m16s
/ Tests (1.22) (pull_request) Successful in 1m14s
All checks were successful
/ DCO (pull_request) Successful in 50s
/ Vulncheck (pull_request) Successful in 1m4s
/ Builds (1.21) (pull_request) Successful in 1m11s
/ Builds (1.22) (pull_request) Successful in 1m9s
/ Lint (pull_request) Successful in 2m7s
/ Tests (1.21) (pull_request) Successful in 1m16s
/ Tests (1.22) (pull_request) Successful in 1m14s
Previously we cannot switch to new client after connection was lost Signed-off-by: Denis Kirillov <d.kirillov@yadro.com>
This commit is contained in:
parent
aaa652de67
commit
b3677cefbb
1 changed files with 40 additions and 31 deletions
|
@ -2,21 +2,19 @@ package contract
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"sync"
|
||||
"fmt"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-contract/frostfsid/client"
|
||||
morphclient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-s3-lifecycler/internal/morph"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
)
|
||||
|
||||
type FrostFSID struct {
|
||||
morphClient *morph.Client
|
||||
contractHash util.Uint160
|
||||
|
||||
mu sync.RWMutex
|
||||
cli *client.Client
|
||||
}
|
||||
|
||||
type FrostFSIDConfig struct {
|
||||
|
@ -32,7 +30,6 @@ func NewFrostFSID(cfg FrostFSIDConfig) *FrostFSID {
|
|||
ffsid := &FrostFSID{
|
||||
morphClient: cfg.Client,
|
||||
contractHash: cfg.ContractHash,
|
||||
cli: client.NewSimple(cfg.Client.Client().GetActor(), cfg.ContractHash),
|
||||
}
|
||||
|
||||
return ffsid
|
||||
|
@ -40,10 +37,21 @@ func NewFrostFSID(cfg FrostFSIDConfig) *FrostFSID {
|
|||
|
||||
func (f *FrostFSID) Users() ([]util.Uint160, error) {
|
||||
var res []util.Uint160
|
||||
err := f.requestWithRetryOnConnectionLost(func(c *client.Client) error {
|
||||
var inErr error
|
||||
res, inErr = c.ListSubjects()
|
||||
return inErr
|
||||
err := f.requestWithRetryOnConnectionLost(func() error {
|
||||
return f.morphClient.Client().TestInvokeIterator(func(item stackitem.Item) error {
|
||||
raw, err := item.TryBytes()
|
||||
if err != nil {
|
||||
return fmt.Errorf("trye item bytes: %w", err)
|
||||
}
|
||||
|
||||
userHash, err := util.Uint160DecodeBytesBE(raw)
|
||||
if err != nil {
|
||||
return fmt.Errorf("decode user hash: %w", err)
|
||||
}
|
||||
res = append(res, userHash)
|
||||
|
||||
return nil
|
||||
}, 100, f.contractHash, "listSubjects")
|
||||
})
|
||||
|
||||
return res, err
|
||||
|
@ -51,10 +59,26 @@ func (f *FrostFSID) Users() ([]util.Uint160, error) {
|
|||
|
||||
func (f *FrostFSID) UserKey(hash util.Uint160) (*keys.PublicKey, error) {
|
||||
var res *client.Subject
|
||||
err := f.requestWithRetryOnConnectionLost(func(c *client.Client) error {
|
||||
var inErr error
|
||||
res, inErr = c.GetSubject(hash)
|
||||
return inErr
|
||||
err := f.requestWithRetryOnConnectionLost(func() error {
|
||||
resItems, err := f.morphClient.Client().TestInvoke(f.contractHash, "getSubject", hash)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invoke getSubject: %w", err)
|
||||
}
|
||||
|
||||
if len(resItems) != 1 {
|
||||
return fmt.Errorf("length getSubject stack unexpected: %d", len(resItems))
|
||||
}
|
||||
|
||||
arr, ok := resItems[0].Value().([]stackitem.Item)
|
||||
if !ok {
|
||||
return errors.New("not an array")
|
||||
}
|
||||
|
||||
if res, err = client.ParseSubject(arr); err != nil {
|
||||
return fmt.Errorf("parse subject: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -63,8 +87,8 @@ func (f *FrostFSID) UserKey(hash util.Uint160) (*keys.PublicKey, error) {
|
|||
return res.PrimaryKey, nil
|
||||
}
|
||||
|
||||
func (f *FrostFSID) requestWithRetryOnConnectionLost(fn func(c *client.Client) error) error {
|
||||
err := fn(f.client())
|
||||
func (f *FrostFSID) requestWithRetryOnConnectionLost(fn func() error) error {
|
||||
err := fn()
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -73,20 +97,5 @@ func (f *FrostFSID) requestWithRetryOnConnectionLost(fn func(c *client.Client) e
|
|||
return err
|
||||
}
|
||||
|
||||
f.initNewClient()
|
||||
|
||||
return fn(f.client())
|
||||
}
|
||||
|
||||
func (f *FrostFSID) initNewClient() {
|
||||
f.mu.Lock()
|
||||
f.cli = client.NewSimple(f.morphClient.Client().GetActor(), f.contractHash)
|
||||
f.mu.Unlock()
|
||||
}
|
||||
|
||||
func (f *FrostFSID) client() *client.Client {
|
||||
f.mu.RLock()
|
||||
defer f.mu.RUnlock()
|
||||
|
||||
return f.cli
|
||||
return fn()
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue