mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-11-29 23:33:37 +00:00
unwrap: add a complete set of simple array unwrappers
Arrays of basic types should be covered completely.
This commit is contained in:
parent
f78231fd9c
commit
b5c79f4be3
2 changed files with 153 additions and 0 deletions
|
@ -196,6 +196,42 @@ func Array(r *result.Invoke, err error) ([]stackitem.Item, error) {
|
|||
return arr, nil
|
||||
}
|
||||
|
||||
// ArrayOfBools checks the result for correct state (HALT) and then extracts a
|
||||
// slice of boolean values from the returned stack item.
|
||||
func ArrayOfBools(r *result.Invoke, err error) ([]bool, error) {
|
||||
a, err := Array(r, err)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res := make([]bool, len(a))
|
||||
for i := range a {
|
||||
b, err := a[i].TryBool()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("element %d is not a boolean: %w", i, err)
|
||||
}
|
||||
res[i] = b
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// ArrayOfBigInts checks the result for correct state (HALT) and then extracts a
|
||||
// slice of (big) integer values from the returned stack item.
|
||||
func ArrayOfBigInts(r *result.Invoke, err error) ([]*big.Int, error) {
|
||||
a, err := Array(r, err)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res := make([]*big.Int, len(a))
|
||||
for i := range a {
|
||||
v, err := a[i].TryInteger()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("element %d is not an integer: %w", i, err)
|
||||
}
|
||||
res[i] = v
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// ArrayOfBytes checks the result for correct state (HALT) and then extracts a
|
||||
// slice of byte slices from the returned stack item.
|
||||
func ArrayOfBytes(r *result.Invoke, err error) ([][]byte, error) {
|
||||
|
@ -214,6 +250,27 @@ func ArrayOfBytes(r *result.Invoke, err error) ([][]byte, error) {
|
|||
return res, nil
|
||||
}
|
||||
|
||||
// ArrayOfUTB8Strings checks the result for correct state (HALT) and then extracts a
|
||||
// slice of UTF-8 strings from the returned stack item.
|
||||
func ArrayOfUTF8Strings(r *result.Invoke, err error) ([]string, error) {
|
||||
a, err := Array(r, err)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res := make([]string, len(a))
|
||||
for i := range a {
|
||||
b, err := a[i].TryBytes()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("element %d is not a byte string: %w", i, err)
|
||||
}
|
||||
if !utf8.Valid(b) {
|
||||
return nil, fmt.Errorf("element %d is not a UTF-8 string", i)
|
||||
}
|
||||
res[i] = string(b)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// ArrayOfUint160 checks the result for correct state (HALT) and then extracts a
|
||||
// slice of util.Uint160 from the returned stack item.
|
||||
func ArrayOfUint160(r *result.Invoke, err error) ([]util.Uint160, error) {
|
||||
|
@ -236,6 +293,28 @@ func ArrayOfUint160(r *result.Invoke, err error) ([]util.Uint160, error) {
|
|||
return res, nil
|
||||
}
|
||||
|
||||
// ArrayOfUint256 checks the result for correct state (HALT) and then extracts a
|
||||
// slice of util.Uint256 from the returned stack item.
|
||||
func ArrayOfUint256(r *result.Invoke, err error) ([]util.Uint256, error) {
|
||||
a, err := Array(r, err)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res := make([]util.Uint256, len(a))
|
||||
for i := range a {
|
||||
b, err := a[i].TryBytes()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("element %d is not a byte string: %w", i, err)
|
||||
}
|
||||
u, err := util.Uint256DecodeBytesBE(b)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("element %d is not a uint256: %w", i, err)
|
||||
}
|
||||
res[i] = u
|
||||
}
|
||||
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) {
|
||||
|
|
|
@ -53,9 +53,24 @@ func TestStdErrors(t *testing.T) {
|
|||
func(r *result.Invoke, err error) (interface{}, error) {
|
||||
return Array(r, err)
|
||||
},
|
||||
func(r *result.Invoke, err error) (interface{}, error) {
|
||||
return ArrayOfBools(r, err)
|
||||
},
|
||||
func(r *result.Invoke, err error) (interface{}, error) {
|
||||
return ArrayOfBigInts(r, err)
|
||||
},
|
||||
func(r *result.Invoke, err error) (interface{}, error) {
|
||||
return ArrayOfBytes(r, err)
|
||||
},
|
||||
func(r *result.Invoke, err error) (interface{}, error) {
|
||||
return ArrayOfUTF8Strings(r, err)
|
||||
},
|
||||
func(r *result.Invoke, err error) (interface{}, error) {
|
||||
return ArrayOfUint160(r, err)
|
||||
},
|
||||
func(r *result.Invoke, err error) (interface{}, error) {
|
||||
return ArrayOfUint256(r, err)
|
||||
},
|
||||
func(r *result.Invoke, err error) (interface{}, error) {
|
||||
return ArrayOfPublicKeys(r, err)
|
||||
},
|
||||
|
@ -233,6 +248,32 @@ func TestArray(t *testing.T) {
|
|||
require.Equal(t, stackitem.Make(42), a[0])
|
||||
}
|
||||
|
||||
func TestArrayOfBools(t *testing.T) {
|
||||
_, err := ArrayOfBools(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make(42)}}, nil)
|
||||
require.Error(t, err)
|
||||
|
||||
_, err = ArrayOfBools(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make([]stackitem.Item{stackitem.Make("reallybigstringthatcantbeanumberandthuscantbeconvertedtobool")})}}, nil)
|
||||
require.Error(t, err)
|
||||
|
||||
a, err := ArrayOfBools(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make([]stackitem.Item{stackitem.Make(true)})}}, nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(a))
|
||||
require.Equal(t, true, a[0])
|
||||
}
|
||||
|
||||
func TestArrayOfBigInts(t *testing.T) {
|
||||
_, err := ArrayOfBigInts(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make(42)}}, nil)
|
||||
require.Error(t, err)
|
||||
|
||||
_, err = ArrayOfBigInts(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make([]stackitem.Item{stackitem.Make([]stackitem.Item{})})}}, nil)
|
||||
require.Error(t, err)
|
||||
|
||||
a, err := ArrayOfBigInts(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make([]stackitem.Item{stackitem.Make(42)})}}, nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(a))
|
||||
require.Equal(t, big.NewInt(42), a[0])
|
||||
}
|
||||
|
||||
func TestArrayOfBytes(t *testing.T) {
|
||||
_, err := ArrayOfBytes(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make(42)}}, nil)
|
||||
require.Error(t, err)
|
||||
|
@ -246,6 +287,22 @@ func TestArrayOfBytes(t *testing.T) {
|
|||
require.Equal(t, []byte("some"), a[0])
|
||||
}
|
||||
|
||||
func TestArrayOfUTF8Strings(t *testing.T) {
|
||||
_, err := ArrayOfUTF8Strings(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make(42)}}, nil)
|
||||
require.Error(t, err)
|
||||
|
||||
_, err = ArrayOfUTF8Strings(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make([]stackitem.Item{stackitem.Make([]stackitem.Item{})})}}, nil)
|
||||
require.Error(t, err)
|
||||
|
||||
_, err = ArrayOfUTF8Strings(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make([]stackitem.Item{stackitem.Make([]byte{0, 0xff})})}}, nil)
|
||||
require.Error(t, err)
|
||||
|
||||
a, err := ArrayOfUTF8Strings(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make([]stackitem.Item{stackitem.Make("some")})}}, nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(a))
|
||||
require.Equal(t, "some", a[0])
|
||||
}
|
||||
|
||||
func TestArrayOfUint160(t *testing.T) {
|
||||
_, err := ArrayOfUint160(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make(42)}}, nil)
|
||||
require.Error(t, err)
|
||||
|
@ -263,6 +320,23 @@ func TestArrayOfUint160(t *testing.T) {
|
|||
require.Equal(t, u160, uints[0])
|
||||
}
|
||||
|
||||
func TestArrayOfUint256(t *testing.T) {
|
||||
_, err := ArrayOfUint256(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make(42)}}, nil)
|
||||
require.Error(t, err)
|
||||
|
||||
_, err = ArrayOfUint256(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make([]stackitem.Item{stackitem.Make([]stackitem.Item{})})}}, nil)
|
||||
require.Error(t, err)
|
||||
|
||||
_, err = ArrayOfUint256(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make([]stackitem.Item{stackitem.Make([]byte("some"))})}}, nil)
|
||||
require.Error(t, err)
|
||||
|
||||
u256 := util.Uint256{1, 2, 3}
|
||||
uints, err := ArrayOfUint256(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make([]stackitem.Item{stackitem.Make(u256.BytesBE())})}}, nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(uints))
|
||||
require.Equal(t, u256, uints[0])
|
||||
}
|
||||
|
||||
func TestArrayOfPublicKeys(t *testing.T) {
|
||||
_, err := ArrayOfPublicKeys(&result.Invoke{State: "HALT", Stack: []stackitem.Item{stackitem.Make(42)}}, nil)
|
||||
require.Error(t, err)
|
||||
|
|
Loading…
Reference in a new issue