Unverified Commit e32ee6ac authored by Marius van der Wijden's avatar Marius van der Wijden Committed by GitHub

accounts/abi: added abi test cases, minor bug fixes (#20903)

* accounts/abi: added documentation

* accounts/abi: reduced usage of arguments.LengthNonIndexed

* accounts/abi: simplified reflection logic

* accounts/abi: moved testjson data into global declaration

* accounts/abi: removed duplicate test cases

* accounts/abi: reworked abi tests

* accounts/abi: added more tests for abi packing

* accounts/abi/bind: refactored base tests

* accounts/abi: run pack tests as subtests

* accounts/abi: removed duplicate tests

* accounts/abi: removed unnused arguments.LengthNonIndexed

Due to refactors to the code, we do not need the arguments.LengthNonIndexed function anymore.
You can still get the length by calling len(arguments.NonIndexed())

* accounts/abi: added type test

* accounts/abi: modified unpack test to pack test

* accounts/abi: length check on arrayTy

* accounts/abi: test invalid abi

* accounts/abi: fixed rebase error

* accounts/abi: fixed rebase errors

* accounts/abi: removed unused definition

* accounts/abi: merged packing/unpacking tests

* accounts/abi: fixed [][][32]bytes encoding

* accounts/abi: added tuple test cases

* accounts/abi: renamed getMockLog -> newMockLog

* accounts/abi: removed duplicate test

* accounts/abi: bools -> booleans
parent 40283d05
This diff is collapsed.
......@@ -59,18 +59,6 @@ func (argument *Argument) UnmarshalJSON(data []byte) error {
return nil
}
// LengthNonIndexed returns the number of arguments when not counting 'indexed' ones. Only events
// can ever have 'indexed' arguments, it should always be false on arguments for method input/output
func (arguments Arguments) LengthNonIndexed() int {
out := 0
for _, arg := range arguments {
if !arg.Indexed {
out++
}
}
return out
}
// NonIndexed returns the arguments with indexed arguments filtered out
func (arguments Arguments) NonIndexed() Arguments {
var ret []Argument
......@@ -205,10 +193,11 @@ func unpack(t *Type, dst interface{}, src interface{}) error {
// unpackAtomic unpacks ( hexdata -> go ) a single value
func (arguments Arguments) unpackAtomic(v interface{}, marshalledValues interface{}) error {
if arguments.LengthNonIndexed() == 0 {
nonIndexedArgs := arguments.NonIndexed()
if len(nonIndexedArgs) == 0 {
return nil
}
argument := arguments.NonIndexed()[0]
argument := nonIndexedArgs[0]
elem := reflect.ValueOf(v).Elem()
if elem.Kind() == reflect.Struct && argument.Type.T != TupleTy {
......@@ -282,9 +271,10 @@ func (arguments Arguments) unpackTuple(v interface{}, marshalledValues []interfa
// without supplying a struct to unpack into. Instead, this method returns a list containing the
// values. An atomic argument will be a list with one element.
func (arguments Arguments) UnpackValues(data []byte) ([]interface{}, error) {
retval := make([]interface{}, 0, arguments.LengthNonIndexed())
nonIndexedArgs := arguments.NonIndexed()
retval := make([]interface{}, 0, len(nonIndexedArgs))
virtualArgs := 0
for index, arg := range arguments.NonIndexed() {
for index, arg := range nonIndexedArgs {
marshalledValue, err := ToGoType((index+virtualArgs)*32, arg.Type, data)
if arg.Type.T == ArrayTy && !isDynamicType(arg.Type) {
// If we have a static array, like [3]uint256, these are coded as
......
This diff is collapsed.
......@@ -46,12 +46,10 @@ func sliceTypeCheck(t Type, val reflect.Value) error {
return typeErr(formatSliceString(t.Elem.Kind, t.Size), formatSliceString(val.Type().Elem().Kind(), val.Len()))
}
if t.Elem.T == SliceTy {
if t.Elem.T == SliceTy || t.Elem.T == ArrayTy {
if val.Len() > 0 {
return sliceTypeCheck(*t.Elem, val.Index(0))
}
} else if t.Elem.T == ArrayTy {
return sliceTypeCheck(*t.Elem, val.Index(0))
}
if elemKind := val.Type().Elem().Kind(); elemKind != t.Elem.Kind {
......
......@@ -39,6 +39,7 @@ var (
)
// U256 converts a big Int into a 256bit EVM number.
// This operation is destructive.
func U256(n *big.Int) []byte {
return math.PaddedBigBytes(math.U256(n), 32)
}
This diff is collapsed.
This diff is collapsed.
......@@ -42,26 +42,26 @@ func indirectInterfaceOrPtr(v reflect.Value) reflect.Value {
// reflectIntKind returns the reflect using the given size and
// unsignedness.
func reflectIntKindAndType(unsigned bool, size int) (reflect.Kind, reflect.Type) {
switch size {
case 8:
if unsigned {
if unsigned {
switch size {
case 8:
return reflect.Uint8, uint8T
case 16:
return reflect.Uint16, uint16T
case 32:
return reflect.Uint32, uint32T
case 64:
return reflect.Uint64, uint64T
}
}
switch size {
case 8:
return reflect.Int8, int8T
case 16:
if unsigned {
return reflect.Uint16, uint16T
}
return reflect.Int16, int16T
case 32:
if unsigned {
return reflect.Uint32, uint32T
}
return reflect.Int32, int32T
case 64:
if unsigned {
return reflect.Uint64, uint64T
}
return reflect.Int64, int64T
}
return reflect.Ptr, bigT
......@@ -88,8 +88,8 @@ func set(dst, src reflect.Value) error {
return set(dst.Elem(), src)
case srcType.AssignableTo(dstType) && dst.CanSet():
dst.Set(src)
case dstType.Kind() == reflect.Slice && srcType.Kind() == reflect.Slice:
return setSlice(dst, src)
case dstType.Kind() == reflect.Slice && srcType.Kind() == reflect.Slice && dst.CanSet():
setSlice(dst, src)
default:
return fmt.Errorf("abi: cannot unmarshal %v in to %v", src.Type(), dst.Type())
}
......@@ -98,15 +98,13 @@ func set(dst, src reflect.Value) error {
// setSlice attempts to assign src to dst when slices are not assignable by default
// e.g. src: [][]byte -> dst: [][15]byte
func setSlice(dst, src reflect.Value) error {
// setSlice ignores if we cannot copy all of src' elements.
func setSlice(dst, src reflect.Value) {
slice := reflect.MakeSlice(dst.Type(), src.Len(), src.Len())
for i := 0; i < src.Len(); i++ {
v := src.Index(i)
reflect.Copy(slice.Index(i), v)
reflect.Copy(slice.Index(i), src.Index(i))
}
dst.Set(slice)
return nil
}
// requireAssignable assures that `dest` is a pointer and it's not an interface.
......
......@@ -306,3 +306,28 @@ func TestTypeCheck(t *testing.T) {
}
}
}
func TestInternalType(t *testing.T) {
components := []ArgumentMarshaling{{Name: "a", Type: "int64"}}
internalType := "struct a.b[]"
kind := Type{
Kind: reflect.Struct,
T: TupleTy,
Type: reflect.TypeOf(struct {
A int64 `json:"a"`
}{}),
stringKind: "(int64)",
TupleRawName: "ab[]",
TupleElems: []*Type{{Kind: reflect.Int64, T: IntTy, Type: reflect.TypeOf(int64(0)), Size: 64, stringKind: "int64"}},
TupleRawNames: []string{"a"},
}
blob := "tuple"
typ, err := NewType(blob, internalType, components)
if err != nil {
t.Errorf("type %q: failed to parse type string: %v", blob, err)
}
if !reflect.DeepEqual(typ, kind) {
t.Errorf("type %q: parsed type mismatch:\nGOT %s\nWANT %s ", blob, spew.Sdump(typeWithoutStringer(typ)), spew.Sdump(typeWithoutStringer(kind)))
}
}
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment