rpcbinding: properly support maps
I'm not sure that map with a `*big.Int` key is a good one, but it can work this way.
This commit is contained in:
parent
8e0be6e7a5
commit
ce67e6795e
2 changed files with 98 additions and 15 deletions
|
@ -109,7 +109,7 @@ type ManagementGroup struct {
|
||||||
type ManagementManifest struct {
|
type ManagementManifest struct {
|
||||||
Name string
|
Name string
|
||||||
Groups []*ManagementGroup
|
Groups []*ManagementGroup
|
||||||
Features *stackitem.Map
|
Features map[string]string
|
||||||
SupportedStandards []string
|
SupportedStandards []string
|
||||||
ABI *ManagementABI
|
ABI *ManagementABI
|
||||||
Permissions []*ManagementPermission
|
Permissions []*ManagementPermission
|
||||||
|
@ -151,7 +151,7 @@ type StructsInternal struct {
|
||||||
Sign []byte
|
Sign []byte
|
||||||
ArrOfBytes [][]byte
|
ArrOfBytes [][]byte
|
||||||
ArrOfH160 []util.Uint160
|
ArrOfH160 []util.Uint160
|
||||||
Map *stackitem.Map
|
Map map[*big.Int]keys.PublicKeys
|
||||||
Struct *StructsInternal
|
Struct *StructsInternal
|
||||||
}
|
}
|
||||||
// Invoker is used by ContractReader to call various safe methods.
|
// Invoker is used by ContractReader to call various safe methods.
|
||||||
|
@ -959,11 +959,42 @@ func itemToManagementManifest(item stackitem.Item, err error) (*ManagementManife
|
||||||
}
|
}
|
||||||
|
|
||||||
index++
|
index++
|
||||||
res.Features, err = func (item stackitem.Item) (*stackitem.Map, error) {
|
res.Features, err = func (item stackitem.Item) (map[string]string, error) {
|
||||||
if t := item.Type(); t != stackitem.MapT {
|
m, ok := item.Value().([]stackitem.MapElement)
|
||||||
return nil, fmt.Errorf("%s is not a map", t.String())
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("%s is not a map", item.Type().String())
|
||||||
}
|
}
|
||||||
return item.(*stackitem.Map), nil
|
res := make(map[string]string)
|
||||||
|
for i := range m {
|
||||||
|
k, err := func (item stackitem.Item) (string, error) {
|
||||||
|
b, err := item.TryBytes()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if !utf8.Valid(b) {
|
||||||
|
return "", errors.New("not a UTF-8 string")
|
||||||
|
}
|
||||||
|
return string(b), nil
|
||||||
|
} (m[i].Key)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
v, err := func (item stackitem.Item) (string, error) {
|
||||||
|
b, err := item.TryBytes()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if !utf8.Valid(b) {
|
||||||
|
return "", errors.New("not a UTF-8 string")
|
||||||
|
}
|
||||||
|
return string(b), nil
|
||||||
|
} (m[i].Value)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
res[k] = v
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
} (arr[index])
|
} (arr[index])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -1402,11 +1433,47 @@ func itemToStructsInternal(item stackitem.Item, err error) (*StructsInternal, er
|
||||||
}
|
}
|
||||||
|
|
||||||
index++
|
index++
|
||||||
res.Map, err = func (item stackitem.Item) (*stackitem.Map, error) {
|
res.Map, err = func (item stackitem.Item) (map[*big.Int]keys.PublicKeys, error) {
|
||||||
if t := item.Type(); t != stackitem.MapT {
|
m, ok := item.Value().([]stackitem.MapElement)
|
||||||
return nil, fmt.Errorf("%s is not a map", t.String())
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("%s is not a map", item.Type().String())
|
||||||
}
|
}
|
||||||
return item.(*stackitem.Map), nil
|
res := make(map[*big.Int]keys.PublicKeys)
|
||||||
|
for i := range m {
|
||||||
|
k, err := m[i].Key.TryInteger()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
v, err := func (item stackitem.Item) (keys.PublicKeys, error) {
|
||||||
|
arr, ok := item.Value().([]stackitem.Item)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New("not an array")
|
||||||
|
}
|
||||||
|
res := make(keys.PublicKeys, len(arr))
|
||||||
|
for i := range res {
|
||||||
|
res[i], err = func (item stackitem.Item) (*keys.PublicKey, error) {
|
||||||
|
b, err := item.TryBytes()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
k, err := keys.NewPublicKeyFromBytes(b, elliptic.P256())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return k, nil
|
||||||
|
} (arr[i])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
} (m[i].Value)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
res[k] = v
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
} (arr[index])
|
} (arr[index])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -378,7 +378,9 @@ func extendedTypeToGo(et binding.ExtendedType, named map[string]binding.Extended
|
||||||
return "[]interface{}", ""
|
return "[]interface{}", ""
|
||||||
|
|
||||||
case smartcontract.MapType:
|
case smartcontract.MapType:
|
||||||
return "*stackitem.Map", "github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
kt, _ := extendedTypeToGo(binding.ExtendedType{Base: et.Key}, named)
|
||||||
|
vt, _ := extendedTypeToGo(*et.Value, named)
|
||||||
|
return "map[" + kt + "]" + vt, "github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
case smartcontract.InteropInterfaceType:
|
case smartcontract.InteropInterfaceType:
|
||||||
return "interface{}", ""
|
return "interface{}", ""
|
||||||
case smartcontract.VoidType:
|
case smartcontract.VoidType:
|
||||||
|
@ -472,11 +474,25 @@ func etTypeConverter(et binding.ExtendedType, v string) string {
|
||||||
}, v)
|
}, v)
|
||||||
|
|
||||||
case smartcontract.MapType:
|
case smartcontract.MapType:
|
||||||
return `func (item stackitem.Item) (*stackitem.Map, error) {
|
at, _ := extendedTypeToGo(et, nil)
|
||||||
if t := item.Type(); t != stackitem.MapT {
|
return `func (item stackitem.Item) (` + at + `, error) {
|
||||||
return nil, fmt.Errorf("%s is not a map", t.String())
|
m, ok := item.Value().([]stackitem.MapElement)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("%s is not a map", item.Type().String())
|
||||||
}
|
}
|
||||||
return item.(*stackitem.Map), nil
|
res := make(` + at + `)
|
||||||
|
for i := range m {
|
||||||
|
k, err := ` + strings.ReplaceAll(etTypeConverter(binding.ExtendedType{Base: et.Key}, "m[i].Key"), "\n", "\n\t\t") + `
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
v, err := ` + strings.ReplaceAll(etTypeConverter(*et.Value, "m[i].Value"), "\n", "\n\t\t") + `
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
res[k] = v
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
} (` + v + `)`
|
} (` + v + `)`
|
||||||
case smartcontract.InteropInterfaceType:
|
case smartcontract.InteropInterfaceType:
|
||||||
return "item.Value(), nil"
|
return "item.Value(), nil"
|
||||||
|
|
Loading…
Reference in a new issue