[#1689] morph/client: Reuse auto-generated wrappers for NNS

Make code simpler, remove unused methods.

Change-Id: I18807f2c14b5a96e533e5e3fc153e23c742c66c1
Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
This commit is contained in:
Evgenii Stratonikov 2025-03-21 15:56:11 +03:00 committed by Dmitrii Stepanov
parent ccdd6cb767
commit 3bb1fb744a
2 changed files with 19 additions and 81 deletions

View file

@ -9,6 +9,7 @@ import (
"sync/atomic" "sync/atomic"
"time" "time"
nnsClient "git.frostfs.info/TrueCloudLab/frostfs-contract/rpcclient/nns"
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs" "git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/metrics" "git.frostfs.info/TrueCloudLab/frostfs-node/internal/metrics"
morphmetrics "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/metrics" morphmetrics "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/metrics"
@ -62,6 +63,8 @@ type Client struct {
rolemgmt *rolemgmt.Contract // neo-go Designation contract wrapper rolemgmt *rolemgmt.Contract // neo-go Designation contract wrapper
nnsHash util.Uint160 // NNS contract hash nnsHash util.Uint160 // NNS contract hash
nnsReader *nnsClient.ContractReader // NNS contract wrapper
acc *wallet.Account // neo account acc *wallet.Account // neo account
accAddr util.Uint160 // account's address accAddr util.Uint160 // account's address
@ -576,6 +579,7 @@ func (c *Client) setActor(act *actor.Actor) {
c.rpcActor = act c.rpcActor = act
c.gasToken = nep17.New(act, gas.Hash) c.gasToken = nep17.New(act, gas.Hash)
c.rolemgmt = rolemgmt.New(act) c.rolemgmt = rolemgmt.New(act)
c.nnsReader = nnsClient.NewReader(act, c.nnsHash)
} }
func (c *Client) GetActor() *actor.Actor { func (c *Client) GetActor() *actor.Actor {

View file

@ -8,14 +8,12 @@ import (
"time" "time"
"git.frostfs.info/TrueCloudLab/frostfs-contract/nns" "git.frostfs.info/TrueCloudLab/frostfs-contract/nns"
nnsClient "git.frostfs.info/TrueCloudLab/frostfs-contract/rpcclient/nns"
"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/encoding/address" "github.com/nspcc-dev/neo-go/pkg/encoding/address"
"github.com/nspcc-dev/neo-go/pkg/rpcclient"
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
"github.com/nspcc-dev/neo-go/pkg/vm/vmstate"
) )
const ( const (
@ -37,12 +35,8 @@ const (
NNSPolicyContractName = "policy.frostfs" NNSPolicyContractName = "policy.frostfs"
) )
var ( // ErrNNSRecordNotFound means that there is no such record in NNS contract.
// ErrNNSRecordNotFound means that there is no such record in NNS contract. var ErrNNSRecordNotFound = errors.New("record has not been found in NNS contract")
ErrNNSRecordNotFound = errors.New("record has not been found in NNS contract")
errEmptyResultStack = errors.New("returned result stack is empty")
)
// NNSAlphabetContractName returns contract name of the alphabet contract in NNS // NNSAlphabetContractName returns contract name of the alphabet contract in NNS
// based on alphabet index. // based on alphabet index.
@ -61,67 +55,36 @@ func (c *Client) NNSContractAddress(name string) (sh util.Uint160, err error) {
return util.Uint160{}, ErrConnectionLost return util.Uint160{}, ErrConnectionLost
} }
nnsHash := c.NNSHash() sh, err = nnsResolve(c.nnsReader, name)
sh, err = nnsResolve(c.client, nnsHash, name)
if err != nil { if err != nil {
return sh, fmt.Errorf("NNS.resolve: %w", err) return sh, fmt.Errorf("NNS.resolve: %w", err)
} }
return sh, nil return sh, nil
} }
// NNSHash returns NNS contract hash. func nnsResolveItem(r *nnsClient.ContractReader, domain string) ([]stackitem.Item, error) {
func (c *Client) NNSHash() util.Uint160 { available, err := r.IsAvailable(domain)
return c.nnsHash
}
func nnsResolveItem(c *rpcclient.WSClient, nnsHash util.Uint160, domain string) (stackitem.Item, error) {
found, err := exists(c, nnsHash, domain)
if err != nil { if err != nil {
return nil, fmt.Errorf("check presence in NNS contract for %s: %w", domain, err) return nil, fmt.Errorf("check presence in NNS contract for %s: %w", domain, err)
} }
if !found { if available {
return nil, ErrNNSRecordNotFound return nil, ErrNNSRecordNotFound
} }
result, err := c.InvokeFunction(nnsHash, "resolve", []smartcontract.Parameter{ return r.Resolve(domain, big.NewInt(int64(nns.TXT)))
{
Type: smartcontract.StringType,
Value: domain,
},
{
Type: smartcontract.IntegerType,
Value: big.NewInt(int64(nns.TXT)),
},
}, nil)
if err != nil {
return nil, err
}
if result.State != vmstate.Halt.String() {
return nil, fmt.Errorf("invocation failed: %s", result.FaultException)
}
if len(result.Stack) == 0 {
return nil, errEmptyResultStack
}
return result.Stack[0], nil
} }
func nnsResolve(c *rpcclient.WSClient, nnsHash util.Uint160, domain string) (util.Uint160, error) { func nnsResolve(r *nnsClient.ContractReader, domain string) (util.Uint160, error) {
res, err := nnsResolveItem(c, nnsHash, domain) arr, err := nnsResolveItem(r, domain)
if err != nil { if err != nil {
return util.Uint160{}, err return util.Uint160{}, err
} }
// Parse the result of resolving NNS record. if len(arr) == 0 {
// It works with multiple formats (corresponding to multiple NNS versions). return util.Uint160{}, errors.New("NNS record is missing")
// If array of hashes is provided, it returns only the first one.
if arr, ok := res.Value().([]stackitem.Item); ok {
if len(arr) == 0 {
return util.Uint160{}, errors.New("NNS record is missing")
}
res = arr[0]
} }
bs, err := res.TryBytes() bs, err := arr[0].TryBytes()
if err != nil { if err != nil {
return util.Uint160{}, fmt.Errorf("malformed response: %w", err) return util.Uint160{}, fmt.Errorf("malformed response: %w", err)
} }
@ -141,33 +104,6 @@ func nnsResolve(c *rpcclient.WSClient, nnsHash util.Uint160, domain string) (uti
return util.Uint160{}, errors.New("no valid hashes are found") return util.Uint160{}, errors.New("no valid hashes are found")
} }
func exists(c *rpcclient.WSClient, nnsHash util.Uint160, domain string) (bool, error) {
result, err := c.InvokeFunction(nnsHash, "isAvailable", []smartcontract.Parameter{
{
Type: smartcontract.StringType,
Value: domain,
},
}, nil)
if err != nil {
return false, err
}
if len(result.Stack) == 0 {
return false, errEmptyResultStack
}
res := result.Stack[0]
available, err := res.TryBool()
if err != nil {
return false, fmt.Errorf("malformed response: %w", err)
}
// not available means that it is taken
// and, therefore, exists
return !available, nil
}
// SetGroupSignerScope makes the default signer scope include all FrostFS contracts. // SetGroupSignerScope makes the default signer scope include all FrostFS contracts.
// Should be called for side-chain client only. // Should be called for side-chain client only.
func (c *Client) SetGroupSignerScope() error { func (c *Client) SetGroupSignerScope() error {
@ -211,14 +147,12 @@ func (c *Client) contractGroupKey() (*keys.PublicKey, error) {
return gKey, nil return gKey, nil
} }
nnsHash := c.NNSHash() arr, err := nnsResolveItem(c.nnsReader, NNSGroupKeyName)
item, err := nnsResolveItem(c.client, nnsHash, NNSGroupKeyName)
if err != nil { if err != nil {
return nil, err return nil, err
} }
arr, ok := item.Value().([]stackitem.Item) if len(arr) == 0 {
if !ok || len(arr) == 0 {
return nil, errors.New("NNS record is missing") return nil, errors.New("NNS record is missing")
} }