From bee4c93a56c8f21f45796d516205022dbb9beafb Mon Sep 17 00:00:00 2001 From: Alexander Chuprov Date: Tue, 10 Sep 2024 15:49:15 +0300 Subject: [PATCH] [#108] nns: Add GetDomains Signed-off-by: Alexander Chuprov --- nns/config.yml | 2 +- nns/nns_contract.go | 11 +++++++++++ rpcclient/nns/client.go | 14 ++++++++++++++ tests/nns_test.go | 34 ++++++++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 1 deletion(-) diff --git a/nns/config.yml b/nns/config.yml index 9ae83cd..5090b40 100644 --- a/nns/config.yml +++ b/nns/config.yml @@ -2,7 +2,7 @@ name: "NameService" supportedstandards: ["NEP-11"] safemethods: ["balanceOf", "decimals", "symbol", "totalSupply", "tokensOf", "ownerOf", "tokens", "properties", "roots", "getPrice", "isAvailable", "getRecords", - "resolve", "version"] + "resolve", "version", "getDomains"] events: - name: RegisterDomain parameters: diff --git a/nns/nns_contract.go b/nns/nns_contract.go index 56dfb2c..1aef7f2 100644 --- a/nns/nns_contract.go +++ b/nns/nns_contract.go @@ -1070,3 +1070,14 @@ func getAllRecords(ctx storage.Context, name string) iterator.Iterator { recordsKey := getRecordsKey(tokenID, name) return storage.Find(ctx, recordsKey, storage.ValuesOnly|storage.DeserializeValues) } + +// GetDomains returns a iterator over all domains. +func GetDomains() iterator.Iterator { + ctx := storage.GetReadOnlyContext() + return getDomains(ctx) +} + +func getDomains(ctx storage.Context) iterator.Iterator { + it := storage.Find(ctx, []byte{prefixName}, storage.ValuesOnly|storage.DeserializeValues) + return it +} diff --git a/rpcclient/nns/client.go b/rpcclient/nns/client.go index b2cfa46..cc7d981 100644 --- a/rpcclient/nns/client.go +++ b/rpcclient/nns/client.go @@ -85,6 +85,20 @@ func New(actor Actor, hash util.Uint160) *Contract { return &Contract{ContractReader{nep11ndt.NonDivisibleReader, actor, hash}, nep11ndt.BaseWriter, actor, hash} } +// GetDomains invokes `getDomains` method of contract. +func (c *ContractReader) GetDomains() (uuid.UUID, result.Iterator, error) { + return unwrap.SessionIterator(c.invoker.Call(c.hash, "getDomains")) +} + +// GetDomainsExpanded is similar to GetDomains (uses the same contract +// method), but can be useful if the server used doesn't support sessions and +// doesn't expand iterators. It creates a script that will get the specified +// number of result items from the iterator right in the VM and return them to +// you. It's only limited by VM stack and GAS available for RPC invocations. +func (c *ContractReader) GetDomainsExpanded(_numOfIteratorItems int) ([]stackitem.Item, error) { + return unwrap.Array(c.invoker.CallAndExpandIterator(c.hash, "getDomains", _numOfIteratorItems)) +} + // GetPrice invokes `getPrice` method of contract. func (c *ContractReader) GetPrice() (*big.Int, error) { return unwrap.BigInt(c.invoker.Call(c.hash, "getPrice")) diff --git a/tests/nns_test.go b/tests/nns_test.go index 6c111b0..2ef623a 100644 --- a/tests/nns_test.go +++ b/tests/nns_test.go @@ -232,6 +232,40 @@ func TestGlobalDomain(t *testing.T) { c.InvokeFail(t, "global domain is already taken", "isAvailable", "dom.testdomain.com") } + +func TestGetDomains(t *testing.T) { + c := newNNSInvoker(t, false) + + accTop := c.NewAccount(t) + refresh, retry, expire, ttl := int64(101), int64(102), int64(103), int64(104) + c1 := c.WithSigners(c.Committee, accTop) + domains := make(map[string]*stackitem.Struct) + + c1.Invoke(t, true, "register", + "com", accTop.ScriptHash(), "myemail@frostfs.info", refresh, retry, expire, ttl) + domains["com"] = stackitem.NewStruct([]stackitem.Item{stackitem.Make(accTop.ScriptHash()), stackitem.Make("com"), stackitem.Make(big.Word(int64(c1.TopBlock(t).Timestamp) + expire*1000)), stackitem.Null{}}) + + c1.Invoke(t, true, "register", + "net", accTop.ScriptHash(), "myemail@frostfs.info", refresh, retry, expire, ttl) + domains["net"] = stackitem.NewStruct([]stackitem.Item{stackitem.Make(accTop.ScriptHash()), stackitem.Make("net"), stackitem.Make(big.Word(int64(c1.TopBlock(t).Timestamp) + expire*1000)), stackitem.Null{}}) + + c1.Invoke(t, true, "register", + "com.com", accTop.ScriptHash(), "myemail@frostfs.info", refresh, retry, expire, ttl) + domains["com.com"] = stackitem.NewStruct([]stackitem.Item{stackitem.Make(accTop.ScriptHash()), stackitem.Make("com.com"), stackitem.Make(big.Word(int64(c1.TopBlock(t).Timestamp) + expire*1000)), stackitem.Null{}}) + + stack, _ := c1.TestInvoke(t, "getDomains") + iter := stack.Pop().Value().(*storage.Iterator) + + require.True(t, iter.Next()) + require.Equal(t, domains["net"], iter.Value()) + + require.True(t, iter.Next()) + require.Equal(t, domains["com.com"], iter.Value()) + + require.True(t, iter.Next()) + require.Equal(t, domains["com"], iter.Value()) +} + func TestTLDRecord(t *testing.T) { c := newNNSInvoker(t, true) c.Invoke(t, stackitem.Null{}, "addRecord",