From d569fe01e670a8d05050ecc039f84c5db43754b6 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Wed, 9 Nov 2022 10:20:44 +0300 Subject: [PATCH] rpcbinding: initial support for iterators, see #2768 Already better than stackitem.Item. --- cli/smartcontract/testdata/nameservice/nns.go | 11 ++++++----- docs/compiler.md | 5 ++++- pkg/smartcontract/rpcbinding/binding.go | 14 +++++++++++--- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/cli/smartcontract/testdata/nameservice/nns.go b/cli/smartcontract/testdata/nameservice/nns.go index 5c849b8e7..daf1e6842 100644 --- a/cli/smartcontract/testdata/nameservice/nns.go +++ b/cli/smartcontract/testdata/nameservice/nns.go @@ -2,12 +2,13 @@ package nameservice import ( + "github.com/google/uuid" "github.com/nspcc-dev/neo-go/pkg/core/transaction" + "github.com/nspcc-dev/neo-go/pkg/neorpc/result" "github.com/nspcc-dev/neo-go/pkg/rpcclient/nep11" "github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap" "github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/util" - "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" "math/big" ) @@ -59,8 +60,8 @@ func New(actor Actor) *Contract { // Roots invokes `roots` method of contract. -func (c *ContractReader) Roots() (stackitem.Item, error) { - return unwrap.Item(c.invoker.Call(Hash, "roots")) +func (c *ContractReader) Roots() (uuid.UUID, result.Iterator, error) { + return unwrap.SessionIterator(c.invoker.Call(Hash, "roots")) } // GetPrice invokes `getPrice` method of contract. @@ -79,8 +80,8 @@ func (c *ContractReader) GetRecord(name string, typev *big.Int) (string, error) } // GetAllRecords invokes `getAllRecords` method of contract. -func (c *ContractReader) GetAllRecords(name string) (stackitem.Item, error) { - return unwrap.Item(c.invoker.Call(Hash, "getAllRecords", name)) +func (c *ContractReader) GetAllRecords(name string) (uuid.UUID, result.Iterator, error) { + return unwrap.SessionIterator(c.invoker.Call(Hash, "getAllRecords", name)) } // Resolve invokes `resolve` method of contract. diff --git a/docs/compiler.md b/docs/compiler.md index ab1358b7e..78e6d0416 100644 --- a/docs/compiler.md +++ b/docs/compiler.md @@ -449,7 +449,10 @@ returns false. If your contract is NEP-11 or NEP-17 that's autodetected and an appropriate package is included as well. Notice that the type data available in the manifest is limited, so in some cases the interface generated may use generic -stackitem types. Iterators are not supported yet. +stackitem types. Any InteropInterface returned from a method is treated as +iterator and an appropriate unwrapper is used with UUID and iterator structure +result. This pair can then be used in Invoker `TraverseIterator` method to +retrieve actual resulting items. ``` $ ./bin/neo-go contract generate-rpcwrapper --manifest manifest.json --out rpcwrapper.go --hash 0x1b4357bff5a01bdf2a6581247cf9ed1e24629176 diff --git a/pkg/smartcontract/rpcbinding/binding.go b/pkg/smartcontract/rpcbinding/binding.go index d3e9bb507..8fdc4d26a 100644 --- a/pkg/smartcontract/rpcbinding/binding.go +++ b/pkg/smartcontract/rpcbinding/binding.go @@ -334,9 +334,17 @@ func scTemplateToRPC(cfg binding.Config, ctr ContractTmpl, imports map[string]st for i := range ctr.SafeMethods { switch ctr.SafeMethods[i].ReturnType { case "interface{}": - imports["github.com/nspcc-dev/neo-go/pkg/vm/stackitem"] = struct{}{} - ctr.SafeMethods[i].ReturnType = "stackitem.Item" - ctr.SafeMethods[i].CallFlag = "Item" + abim := cfg.Manifest.ABI.GetMethod(ctr.SafeMethods[i].NameABI, len(ctr.SafeMethods[i].Arguments)) + if abim.ReturnType == smartcontract.InteropInterfaceType { + imports["github.com/google/uuid"] = struct{}{} + imports["github.com/nspcc-dev/neo-go/pkg/neorpc/result"] = struct{}{} + ctr.SafeMethods[i].ReturnType = "uuid.UUID, result.Iterator" + ctr.SafeMethods[i].CallFlag = "SessionIterator" + } else { + imports["github.com/nspcc-dev/neo-go/pkg/vm/stackitem"] = struct{}{} + ctr.SafeMethods[i].ReturnType = "stackitem.Item" + ctr.SafeMethods[i].CallFlag = "Item" + } case "bool": ctr.SafeMethods[i].CallFlag = "Bool" case "*big.Int":