diff --git a/internal/frostfs/frostfsid/frostfsid.go b/internal/frostfs/frostfsid/frostfsid.go index 4a89502..0f8bdd4 100644 --- a/internal/frostfs/frostfsid/frostfsid.go +++ b/internal/frostfs/frostfsid/frostfsid.go @@ -6,7 +6,8 @@ import ( "strings" "git.frostfs.info/TrueCloudLab/frostfs-contract/frostfsid/client" - "git.frostfs.info/TrueCloudLab/frostfs-http-gw/resolver" + "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container" + "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/ns" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/rpcclient" "github.com/nspcc-dev/neo-go/pkg/util" @@ -31,12 +32,7 @@ type Config struct { // New creates new FrostfsID contract wrapper that implements auth.FrostFSID interface. func New(ctx context.Context, cfg Config) (*FrostFSID, error) { - rpcCli, err := rpcclient.New(ctx, cfg.RPCAddress, rpcclient.Options{}) - if err != nil { - return nil, fmt.Errorf("init rpc client: %w", err) - } - - contractHash, err := fetchContractHash(rpcCli, cfg.Contract) + contractHash, err := fetchContractHash(cfg) if err != nil { return nil, fmt.Errorf("resolve frostfs contract hash: %w", err) } @@ -48,6 +44,11 @@ func New(ctx context.Context, cfg Config) (*FrostFSID, error) { } } + rpcCli, err := rpcclient.New(ctx, cfg.RPCAddress, rpcclient.Options{}) + if err != nil { + return nil, fmt.Errorf("init rpc client: %w", err) + } + cli, err := client.New(rpcCli, wallet.NewAccountFromPrivateKey(key), contractHash, nil) if err != nil { return nil, fmt.Errorf("init frostfsid client: %w", err) @@ -63,15 +64,24 @@ func (f *FrostFSID) ValidatePublicKey(key *keys.PublicKey) error { return err } -func fetchContractHash(rpcCli *rpcclient.Client, contractName string) (util.Uint160, error) { - if hash, err := util.Uint160DecodeStringLE(contractName); err == nil { +func fetchContractHash(cfg Config) (util.Uint160, error) { + if hash, err := util.Uint160DecodeStringLE(cfg.Contract); err == nil { return hash, nil } - splitName := strings.Split(contractName, ".") + splitName := strings.Split(cfg.Contract, ".") if len(splitName) != 2 { - return util.Uint160{}, fmt.Errorf("invalid contract name: '%s'", contractName) + return util.Uint160{}, fmt.Errorf("invalid contract name: '%s'", cfg.Contract) } - return resolver.ResolveHash(rpcCli, contractName) + var domain container.Domain + domain.SetName(splitName[0]) + domain.SetZone(splitName[1]) + + var nns ns.NNS + if err := nns.Dial(cfg.RPCAddress); err != nil { + return util.Uint160{}, fmt.Errorf("dial nns %s: %w", cfg.RPCAddress, err) + } + + return nns.ResolveContractHash(domain) } diff --git a/resolver/nns.go b/resolver/nns.go deleted file mode 100644 index 5b6f342..0000000 --- a/resolver/nns.go +++ /dev/null @@ -1,62 +0,0 @@ -package resolver - -import ( - "errors" - "fmt" - - "git.frostfs.info/TrueCloudLab/frostfs-contract/nns" - "github.com/nspcc-dev/neo-go/pkg/encoding/address" - "github.com/nspcc-dev/neo-go/pkg/rpcclient" - "github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker" - "github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap" - "github.com/nspcc-dev/neo-go/pkg/util" - "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" -) - -// ResolveHash resolves contract hash. -func ResolveHash(cli *rpcclient.Client, domain string) (util.Uint160, error) { - nnsCs, err := cli.GetContractStateByID(1) - if err != nil { - return util.Uint160{}, fmt.Errorf("get NNS contract by id: %w", err) - } - - item, err := nnsResolve(invoker.New(cli, nil), nnsCs.Hash, domain) - if err != nil { - return util.Uint160{}, err - } - return parseNNSResolveResult(item) -} - -func nnsResolve(inv *invoker.Invoker, nnsHash util.Uint160, domain string) (stackitem.Item, error) { - return unwrap.Item(inv.Call(nnsHash, "resolve", domain, int64(nns.TXT))) -} - -// parseNNSResolveResult parses the result of resolving NNS record. -// It works with multiple formats (corresponding to multiple NNS versions). -// If array of hashes is provided, it returns only the first one. -func parseNNSResolveResult(res stackitem.Item) (util.Uint160, error) { - arr, ok := res.Value().([]stackitem.Item) - if !ok { - arr = []stackitem.Item{res} - } - if _, ok := res.Value().(stackitem.Null); ok || len(arr) == 0 { - return util.Uint160{}, errors.New("NNS record is missing") - } - for i := range arr { - bs, err := arr[i].TryBytes() - if err != nil { - continue - } - - h, err := address.StringToUint160(string(bs)) - if err == nil { - return h, nil - } - - h, err = util.Uint160DecodeStringLE(string(bs)) - if err == nil { - return h, nil - } - } - return util.Uint160{}, errors.New("no valid hashes are found") -}