forked from TrueCloudLab/neoneo-go
unwrap: add ArrayOfPublicKeys()
This type of result is also popular in the NEO contract.
This commit is contained in:
parent
cdc2a762a1
commit
37619743ad
3 changed files with 47 additions and 19 deletions
|
@ -7,9 +7,6 @@ various methods to perform the only RoleManagement state-changing call.
|
||||||
package rolemgmt
|
package rolemgmt
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/elliptic"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames"
|
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/native/noderoles"
|
"github.com/nspcc-dev/neo-go/pkg/core/native/noderoles"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||||
|
@ -78,22 +75,7 @@ func New(actor Actor) *Contract {
|
||||||
// given role at the given height. The list can be empty if no keys are
|
// given role at the given height. The list can be empty if no keys are
|
||||||
// configured for this role/height.
|
// configured for this role/height.
|
||||||
func (c *ContractReader) GetDesignatedByRole(role noderoles.Role, index uint32) (keys.PublicKeys, error) {
|
func (c *ContractReader) GetDesignatedByRole(role noderoles.Role, index uint32) (keys.PublicKeys, error) {
|
||||||
arr, err := unwrap.Array(c.invoker.Call(Hash, "getDesignatedByRole", int64(role), index))
|
return unwrap.ArrayOfPublicKeys(c.invoker.Call(Hash, "getDesignatedByRole", int64(role), index))
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
pks := make(keys.PublicKeys, len(arr))
|
|
||||||
for i, item := range arr {
|
|
||||||
val, err := item.TryBytes()
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("invalid array element #%d: %s", i, item.Type())
|
|
||||||
}
|
|
||||||
pks[i], err = keys.NewPublicKeyFromBytes(val, elliptic.P256())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return pks, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DesignateAsRole creates and sends a transaction that sets the keys used for
|
// DesignateAsRole creates and sends a transaction that sets the keys used for
|
||||||
|
|
|
@ -11,12 +11,14 @@ contract-specific packages.
|
||||||
package unwrap
|
package unwrap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/elliptic"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
|
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
|
@ -190,6 +192,27 @@ func ArrayOfBytes(r *result.Invoke, err error) ([][]byte, error) {
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ArrayOfPublicKeys checks the result for correct state (HALT) and then
|
||||||
|
// extracts a slice of public keys from the returned stack item.
|
||||||
|
func ArrayOfPublicKeys(r *result.Invoke, err error) (keys.PublicKeys, error) {
|
||||||
|
arr, err := Array(r, err)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
pks := make(keys.PublicKeys, len(arr))
|
||||||
|
for i, item := range arr {
|
||||||
|
val, err := item.TryBytes()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("invalid array element #%d: %s", i, item.Type())
|
||||||
|
}
|
||||||
|
pks[i], err = keys.NewPublicKeyFromBytes(val, elliptic.P256())
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("array element #%d in not a key: %w", i, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pks, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Map expects correct execution (HALT state) with a single stack item
|
// Map expects correct execution (HALT state) with a single stack item
|
||||||
// returned. A stackitem.Map is extracted from this item and returned.
|
// returned. A stackitem.Map is extracted from this item and returned.
|
||||||
func Map(r *result.Invoke, err error) (*stackitem.Map, error) {
|
func Map(r *result.Invoke, err error) (*stackitem.Map, error) {
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
|
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
|
@ -52,6 +53,9 @@ func TestStdErrors(t *testing.T) {
|
||||||
func(r *result.Invoke, err error) (interface{}, error) {
|
func(r *result.Invoke, err error) (interface{}, error) {
|
||||||
return ArrayOfBytes(r, err)
|
return ArrayOfBytes(r, err)
|
||||||
},
|
},
|
||||||
|
func(r *result.Invoke, err error) (interface{}, error) {
|
||||||
|
return ArrayOfPublicKeys(r, err)
|
||||||
|
},
|
||||||
func(r *result.Invoke, err error) (interface{}, error) {
|
func(r *result.Invoke, err error) (interface{}, error) {
|
||||||
return Map(r, err)
|
return Map(r, err)
|
||||||
},
|
},
|
||||||
|
@ -224,6 +228,25 @@ func TestArrayOfBytes(t *testing.T) {
|
||||||
require.Equal(t, []byte("some"), a[0])
|
require.Equal(t, []byte("some"), a[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestArrayOfPublicKeys(t *testing.T) {
|
||||||
|
_, err := ArrayOfPublicKeys(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make(42)}}, nil)
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
_, err = ArrayOfPublicKeys(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make([]stackitem.Item{stackitem.Make([]stackitem.Item{})})}}, nil)
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
_, err = ArrayOfPublicKeys(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make([]stackitem.Item{stackitem.Make([]byte("some"))})}}, nil)
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
k, err := keys.NewPrivateKey()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
pks, err := ArrayOfPublicKeys(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make([]stackitem.Item{stackitem.Make(k.PublicKey().Bytes())})}}, nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, 1, len(pks))
|
||||||
|
require.Equal(t, k.PublicKey(), pks[0])
|
||||||
|
}
|
||||||
|
|
||||||
func TestMap(t *testing.T) {
|
func TestMap(t *testing.T) {
|
||||||
_, err := Map(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make(42)}}, nil)
|
_, err := Map(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make(42)}}, nil)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
|
|
Loading…
Reference in a new issue