rpc: add resolve and isAvailable NNS API to RPC client

This commit is contained in:
Anna Shaleva 2021-03-24 13:12:33 +03:00
parent f955589370
commit 626ec8a82b
2 changed files with 88 additions and 0 deletions

View file

@ -3,9 +3,11 @@ package client
// Various non-policy things from native contracts.
import (
"errors"
"fmt"
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames"
"github.com/nspcc-dev/neo-go/pkg/core/native/nnsrecords"
"github.com/nspcc-dev/neo-go/pkg/core/native/noderoles"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
@ -63,3 +65,54 @@ func (c *Client) GetDesignatedByRole(role noderoles.Role, index uint32) (keys.Pu
}
return topPublicKeysFromStack(result.Stack)
}
// NNSResolve invokes `resolve` method on a native NameService contract.
func (c *Client) NNSResolve(name string, typ nnsrecords.Type) (string, error) {
if typ == nnsrecords.CNAME {
return "", errors.New("can't resolve CNAME record type")
}
rmHash, err := c.GetNativeContractHash(nativenames.NameService)
if err != nil {
return "", fmt.Errorf("failed to get native NameService hash: %w", err)
}
result, err := c.InvokeFunction(rmHash, "resolve", []smartcontract.Parameter{
{
Type: smartcontract.StringType,
Value: name,
},
{
Type: smartcontract.IntegerType,
Value: int64(typ),
},
}, nil)
if err != nil {
return "", err
}
err = getInvocationError(result)
if err != nil {
return "", fmt.Errorf("`resolve`: %w", err)
}
return topStringFromStack(result.Stack)
}
// NNSIsAvailable invokes `isAvailable` method on a native NameService contract.
func (c *Client) NNSIsAvailable(name string) (bool, error) {
rmHash, err := c.GetNativeContractHash(nativenames.NameService)
if err != nil {
return false, fmt.Errorf("failed to get native NameService hash: %w", err)
}
result, err := c.InvokeFunction(rmHash, "isAvailable", []smartcontract.Parameter{
{
Type: smartcontract.StringType,
Value: name,
},
}, nil)
if err != nil {
return false, err
}
err = getInvocationError(result)
if err != nil {
return false, fmt.Errorf("`isAvailable`: %w", err)
}
return topBoolFromStack(result.Stack)
}

View file

@ -8,6 +8,7 @@ import (
"github.com/nspcc-dev/neo-go/internal/testchain"
"github.com/nspcc-dev/neo-go/pkg/core/fee"
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames"
"github.com/nspcc-dev/neo-go/pkg/core/native/nnsrecords"
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
@ -532,3 +533,37 @@ func TestClient_NEP11(t *testing.T) {
require.NoError(t, err)
})
}
func TestClient_NNS(t *testing.T) {
chain, rpcSrv, httpSrv := initServerWithInMemoryChain(t)
defer chain.Close()
defer rpcSrv.Shutdown()
c, err := client.New(context.Background(), httpSrv.URL, client.Options{})
require.NoError(t, err)
require.NoError(t, c.Init())
t.Run("NNSIsAvailable, false", func(t *testing.T) {
b, err := c.NNSIsAvailable("neo.com")
require.NoError(t, err)
require.Equal(t, false, b)
})
t.Run("NNSIsAvailable, true", func(t *testing.T) {
b, err := c.NNSIsAvailable("neogo.com")
require.NoError(t, err)
require.Equal(t, true, b)
})
t.Run("NNSResolve, good", func(t *testing.T) {
b, err := c.NNSResolve("neo.com", nnsrecords.A)
require.NoError(t, err)
require.Equal(t, "1.2.3.4", b)
})
t.Run("NNSResolve, bad", func(t *testing.T) {
_, err := c.NNSResolve("neogo.com", nnsrecords.A)
require.Error(t, err)
})
t.Run("NNSResolve, forbidden", func(t *testing.T) {
_, err := c.NNSResolve("neogo.com", nnsrecords.CNAME)
require.Error(t, err)
})
}