Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend accepted parameters #3583

Merged
merged 2 commits into from
Sep 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 58 additions & 27 deletions pkg/smartcontract/parameter.go
Original file line number Diff line number Diff line change
Expand Up @@ -342,36 +342,55 @@ func NewParameterFromValue(value any) (Parameter, error) {
case *keys.PublicKey:
result.Type = PublicKeyType
result.Value = v.Bytes()
case [][]byte:
arr := make([]Parameter, 0, len(v))
for i := range v {
// We know the type exactly, so error is not possible.
elem, _ := NewParameterFromValue(v[i])
arr = append(arr, elem)
}
result.Type = ArrayType
result.Value = arr
case []Parameter:
result.Type = ArrayType
result.Value = slices.Clone(v)
case [][]byte:
return newArrayParameter(v)
case []string:
return newArrayParameter(v)
case []bool:
return newArrayParameter(v)
case []*big.Int:
return newArrayParameter(v)
case []int8:
return newArrayParameter(v)
case []int16:
return newArrayParameter(v)
case []uint16:
return newArrayParameter(v)
case []int32:
return newArrayParameter(v)
case []uint32:
return newArrayParameter(v)
case []int:
return newArrayParameter(v)
case []uint:
return newArrayParameter(v)
case []int64:
return newArrayParameter(v)
case []uint64:
return newArrayParameter(v)
case []*Parameter:
return newArrayParameter(v)
case []Convertible:
return newArrayParameter(v)
case []util.Uint160:
return newArrayParameter(v)
case []util.Uint256:
return newArrayParameter(v)
case []*util.Uint160:
return newArrayParameter(v)
case []*util.Uint256:
return newArrayParameter(v)
case []keys.PublicKey:
return newArrayParameter(v)
case []*keys.PublicKey:
return NewParameterFromValue(keys.PublicKeys(v))
return newArrayParameter(v)
case keys.PublicKeys:
arr := make([]Parameter, 0, len(v))
for i := range v {
// We know the type exactly, so error is not possible.
elem, _ := NewParameterFromValue(v[i])
arr = append(arr, elem)
}
result.Type = ArrayType
result.Value = arr
return newArrayParameter(v)
case []any:
arr, err := NewParametersFromValues(v...)
if err != nil {
return result, err
}
result.Type = ArrayType
result.Value = arr
return newArrayParameter(v)
case nil:
result.Type = AnyType
default:
Expand All @@ -381,9 +400,15 @@ func NewParameterFromValue(value any) (Parameter, error) {
return result, nil
}

// NewParametersFromValues is similar to NewParameterFromValue except that it
// works with multiple values and returns a simple slice of Parameter.
func NewParametersFromValues(values ...any) ([]Parameter, error) {
func newArrayParameter[E any, S ~[]E](values S) (Parameter, error) {
arr, err := newArrayOfParameters(values)
if err != nil {
return Parameter{}, err
}
return Parameter{Type: ArrayType, Value: arr}, nil
}

func newArrayOfParameters[E any, S ~[]E](values S) ([]Parameter, error) {
res := make([]Parameter, 0, len(values))
for i := range values {
elem, err := NewParameterFromValue(values[i])
Expand All @@ -395,6 +420,12 @@ func NewParametersFromValues(values ...any) ([]Parameter, error) {
return res, nil
}

// NewParametersFromValues is similar to NewParameterFromValue except that it
// works with multiple values and returns a simple slice of Parameter.
func NewParametersFromValues(values ...any) ([]Parameter, error) {
return newArrayOfParameters(values)
}

// ExpandParameterToEmitable converts a parameter to a type which can be handled as
// an array item by emit.Array. It correlates with the way an RPC server handles
// FuncParams for invoke* calls inside the request.ExpandArrayIntoScript function.
Expand Down
121 changes: 111 additions & 10 deletions pkg/smartcontract/parameter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,11 @@ func TestParameterFromValue(t *testing.T) {
expType: ByteArrayType,
expVal: []byte{1, 2, 3},
},
{
value: testConvertible{i: 123},
expType: IntegerType,
expVal: 123,
},
{
value: util.Uint160{1, 2, 3},
expType: Hash160Type,
Expand Down Expand Up @@ -712,22 +717,107 @@ func TestParameterFromValue(t *testing.T) {
expVal: pk2.PublicKey().Bytes(),
},
{
value: nil,
expType: AnyType,
expVal: nil,
value: []Parameter{{ByteArrayType, []byte{1, 2, 3}}, {ByteArrayType, []byte{3, 2, 1}}},
expType: ArrayType,
expVal: []Parameter{{ByteArrayType, []byte{1, 2, 3}}, {ByteArrayType, []byte{3, 2, 1}}},
},
{
value: [][]byte{{1, 2, 3}, {3, 2, 1}},
expType: ArrayType,
expVal: []Parameter{{ByteArrayType, []byte{1, 2, 3}}, {ByteArrayType, []byte{3, 2, 1}}},
},
{
value: []Parameter{{ByteArrayType, []byte{1, 2, 3}}, {ByteArrayType, []byte{3, 2, 1}}},
value: []string{"qwe", "asd"},
expType: ArrayType,
expVal: []Parameter{{StringType, "qwe"}, {StringType, "asd"}},
},
{
value: []bool{false, true},
expType: ArrayType,
expVal: []Parameter{{BoolType, false}, {BoolType, true}},
},
{
value: []*big.Int{big.NewInt(100), big.NewInt(42)},
expType: ArrayType,
expVal: []Parameter{{IntegerType, big.NewInt(100)}, {IntegerType, big.NewInt(42)}},
},
{
value: []int8{100, 42},
expType: ArrayType,
expVal: []Parameter{{IntegerType, big.NewInt(100)}, {IntegerType, big.NewInt(42)}},
},
{
value: []int16{100, 42},
expType: ArrayType,
expVal: []Parameter{{IntegerType, big.NewInt(100)}, {IntegerType, big.NewInt(42)}},
},
{
value: []uint16{100, 42},
expType: ArrayType,
expVal: []Parameter{{IntegerType, big.NewInt(100)}, {IntegerType, big.NewInt(42)}},
},
{
value: []int32{100, 42},
expType: ArrayType,
expVal: []Parameter{{IntegerType, big.NewInt(100)}, {IntegerType, big.NewInt(42)}},
},
{
value: []uint32{100, 42},
expType: ArrayType,
expVal: []Parameter{{IntegerType, big.NewInt(100)}, {IntegerType, big.NewInt(42)}},
},
{
value: []int{100, 42},
expType: ArrayType,
expVal: []Parameter{{IntegerType, big.NewInt(100)}, {IntegerType, big.NewInt(42)}},
},
{
value: []uint{100, 42},
expType: ArrayType,
expVal: []Parameter{{IntegerType, big.NewInt(100)}, {IntegerType, big.NewInt(42)}},
},
{
value: []int64{100, 42},
expType: ArrayType,
expVal: []Parameter{{IntegerType, big.NewInt(100)}, {IntegerType, big.NewInt(42)}},
},
{
value: []uint64{100, 42},
expType: ArrayType,
expVal: []Parameter{{IntegerType, big.NewInt(100)}, {IntegerType, big.NewInt(42)}},
},
{
value: []*Parameter{{ByteArrayType, []byte{1, 2, 3}}, {ByteArrayType, []byte{3, 2, 1}}},
expType: ArrayType,
expVal: []Parameter{{ByteArrayType, []byte{1, 2, 3}}, {ByteArrayType, []byte{3, 2, 1}}},
},
{
value: []*keys.PublicKey{pk1.PublicKey(), pk2.PublicKey()},
value: []Convertible{testConvertible{i: 123}, testConvertible{i: 321}},
expType: ArrayType,
expVal: []Parameter{{IntegerType, 123}, {IntegerType, 321}},
},
{
value: []util.Uint160{{1, 2, 3}, {3, 2, 1}},
expType: ArrayType,
expVal: []Parameter{{Hash160Type, util.Uint160{1, 2, 3}}, {Hash160Type, util.Uint160{3, 2, 1}}},
},
{
value: []util.Uint256{{1, 2, 3}, {3, 2, 1}},
expType: ArrayType,
expVal: []Parameter{{Hash256Type, util.Uint256{1, 2, 3}}, {Hash256Type, util.Uint256{3, 2, 1}}},
},
{
value: []*util.Uint160{{1, 2, 3}, nil, {3, 2, 1}},
expType: ArrayType,
expVal: []Parameter{{Hash160Type, util.Uint160{1, 2, 3}}, {AnyType, nil}, {Hash160Type, util.Uint160{3, 2, 1}}},
},
{
value: []*util.Uint256{{1, 2, 3}, nil, {3, 2, 1}},
expType: ArrayType,
expVal: []Parameter{{Hash256Type, util.Uint256{1, 2, 3}}, {AnyType, nil}, {Hash256Type, util.Uint256{3, 2, 1}}},
},
{
value: []keys.PublicKey{*pk1.PublicKey(), *pk2.PublicKey()},
expType: ArrayType,
expVal: []Parameter{{
Type: PublicKeyType,
Expand All @@ -748,6 +838,17 @@ func TestParameterFromValue(t *testing.T) {
Value: pk2.PublicKey().Bytes(),
}},
},
{
value: []*keys.PublicKey{pk1.PublicKey(), pk2.PublicKey()},
expType: ArrayType,
expVal: []Parameter{{
Type: PublicKeyType,
Value: pk1.PublicKey().Bytes(),
}, {
Type: PublicKeyType,
Value: pk2.PublicKey().Bytes(),
}},
},
{
value: []any{-42, "random", []byte{1, 2, 3}},
expType: ArrayType,
Expand All @@ -762,11 +863,6 @@ func TestParameterFromValue(t *testing.T) {
Value: []byte{1, 2, 3},
}},
},
{
value: testConvertible{i: 123},
expType: IntegerType,
expVal: 123,
},
{
value: []any{1, testConvertible{i: 123}},
expType: ArrayType,
Expand All @@ -781,6 +877,11 @@ func TestParameterFromValue(t *testing.T) {
},
},
},
{
value: nil,
expType: AnyType,
expVal: nil,
},
{
value: testConvertible{err: "invalid i value"},
err: "invalid i value",
Expand Down
Loading