Merge pull request #3533 from karalabe/modum-io-develop-2
accounts/abi: support custom int slice types
This commit is contained in:
		
						commit
						88cc1ca55a
					
				| @ -91,8 +91,30 @@ func toGoSlice(i int, t Argument, output []byte) (interface{}, error) { | ||||
| 	// first we need to create a slice of the type
 | ||||
| 	var refSlice reflect.Value | ||||
| 	switch elem.T { | ||||
| 	case IntTy, UintTy, BoolTy: // int, uint, bool can all be of type big int.
 | ||||
| 		refSlice = reflect.ValueOf([]*big.Int(nil)) | ||||
| 	case IntTy, UintTy, BoolTy: | ||||
| 		// create a new reference slice matching the element type
 | ||||
| 		switch t.Type.Kind { | ||||
| 		case reflect.Bool: | ||||
| 			refSlice = reflect.ValueOf([]bool(nil)) | ||||
| 		case reflect.Uint8: | ||||
| 			refSlice = reflect.ValueOf([]uint8(nil)) | ||||
| 		case reflect.Uint16: | ||||
| 			refSlice = reflect.ValueOf([]uint16(nil)) | ||||
| 		case reflect.Uint32: | ||||
| 			refSlice = reflect.ValueOf([]uint32(nil)) | ||||
| 		case reflect.Uint64: | ||||
| 			refSlice = reflect.ValueOf([]uint64(nil)) | ||||
| 		case reflect.Int8: | ||||
| 			refSlice = reflect.ValueOf([]int8(nil)) | ||||
| 		case reflect.Int16: | ||||
| 			refSlice = reflect.ValueOf([]int16(nil)) | ||||
| 		case reflect.Int32: | ||||
| 			refSlice = reflect.ValueOf([]int32(nil)) | ||||
| 		case reflect.Int64: | ||||
| 			refSlice = reflect.ValueOf([]int64(nil)) | ||||
| 		default: | ||||
| 			refSlice = reflect.ValueOf([]*big.Int(nil)) | ||||
| 		} | ||||
| 	case AddressTy: // address must be of slice Address
 | ||||
| 		refSlice = reflect.ValueOf([]common.Address(nil)) | ||||
| 	case HashTy: // hash must be of slice hash
 | ||||
| @ -147,7 +169,27 @@ func toGoSlice(i int, t Argument, output []byte) (interface{}, error) { | ||||
| 		// set inter to the correct type (cast)
 | ||||
| 		switch elem.T { | ||||
| 		case IntTy, UintTy: | ||||
| 			inter = common.BytesToBig(returnOutput) | ||||
| 			bigNum := common.BytesToBig(returnOutput) | ||||
| 			switch t.Type.Kind { | ||||
| 			case reflect.Uint8: | ||||
| 				inter = uint8(bigNum.Uint64()) | ||||
| 			case reflect.Uint16: | ||||
| 				inter = uint16(bigNum.Uint64()) | ||||
| 			case reflect.Uint32: | ||||
| 				inter = uint32(bigNum.Uint64()) | ||||
| 			case reflect.Uint64: | ||||
| 				inter = bigNum.Uint64() | ||||
| 			case reflect.Int8: | ||||
| 				inter = int8(bigNum.Int64()) | ||||
| 			case reflect.Int16: | ||||
| 				inter = int16(bigNum.Int64()) | ||||
| 			case reflect.Int32: | ||||
| 				inter = int32(bigNum.Int64()) | ||||
| 			case reflect.Int64: | ||||
| 				inter = bigNum.Int64() | ||||
| 			default: | ||||
| 				inter = common.BytesToBig(returnOutput) | ||||
| 			} | ||||
| 		case BoolTy: | ||||
| 			inter = common.BytesToBig(returnOutput).Uint64() > 0 | ||||
| 		case AddressTy: | ||||
|  | ||||
| @ -332,6 +332,30 @@ func TestUnpackSetInterfaceSlice(t *testing.T) { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func TestUnpackSetInterfaceArrayOutput(t *testing.T) { | ||||
| 	var ( | ||||
| 		var1 = new([1]uint32) | ||||
| 		var2 = new([1]uint32) | ||||
| 	) | ||||
| 	out := []interface{}{var1, var2} | ||||
| 	abi, err := JSON(strings.NewReader(`[{"type":"function", "name":"ints", "outputs":[{"type":"uint32[1]"}, {"type":"uint32[1]"}]}]`)) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	marshalledReturn := append(pad([]byte{1}, 32, true), pad([]byte{2}, 32, true)...) | ||||
| 	err = abi.Unpack(&out, "ints", marshalledReturn) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 
 | ||||
| 	if *var1 != [1]uint32{1} { | ||||
| 		t.Error("expected var1 to be [1], got", *var1) | ||||
| 	} | ||||
| 	if *var2 != [1]uint32{2} { | ||||
| 		t.Error("expected var2 to be [2], got", *var2) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func TestPack(t *testing.T) { | ||||
| 	for i, test := range []struct { | ||||
| 		typ string | ||||
|  | ||||
| @ -91,7 +91,12 @@ func NewType(t string) (typ Type, err error) { | ||||
| 		} | ||||
| 		typ.Elem = &sliceType | ||||
| 		typ.stringKind = sliceType.stringKind + t[len(res[1]):] | ||||
| 		return typ, nil | ||||
| 		// Altough we know that this is an array, we cannot return
 | ||||
| 		// as we don't know the type of the element, however, if it
 | ||||
| 		// is still an array, then don't determine the type.
 | ||||
| 		if typ.Elem.IsArray || typ.Elem.IsSlice { | ||||
| 			return typ, nil | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// parse the type and size of the abi-type.
 | ||||
| @ -112,7 +117,12 @@ func NewType(t string) (typ Type, err error) { | ||||
| 		varSize = 256 | ||||
| 		t += "256" | ||||
| 	} | ||||
| 	typ.stringKind = t | ||||
| 
 | ||||
| 	// only set stringKind if not array or slice, as for those,
 | ||||
| 	// the correct string type has been set
 | ||||
| 	if !(typ.IsArray || typ.IsSlice) { | ||||
| 		typ.stringKind = t | ||||
| 	} | ||||
| 
 | ||||
| 	switch varType { | ||||
| 	case "int": | ||||
|  | ||||
| @ -34,17 +34,17 @@ func TestTypeRegexp(t *testing.T) { | ||||
| 		{"int", Type{Kind: reflect.Ptr, Type: big_t, Size: 256, T: IntTy, stringKind: "int256"}}, | ||||
| 		{"int8", Type{Kind: reflect.Int8, Type: big_t, Size: 8, T: IntTy, stringKind: "int8"}}, | ||||
| 		{"int256", Type{Kind: reflect.Ptr, Type: big_t, Size: 256, T: IntTy, stringKind: "int256"}}, | ||||
| 		{"int[]", Type{IsSlice: true, SliceSize: -1, Elem: &Type{Kind: reflect.Ptr, Type: big_t, Size: 256, T: IntTy, stringKind: "int256"}, stringKind: "int256[]"}}, | ||||
| 		{"int[2]", Type{IsArray: true, SliceSize: 2, Elem: &Type{Kind: reflect.Ptr, Type: big_t, Size: 256, T: IntTy, stringKind: "int256"}, stringKind: "int256[2]"}}, | ||||
| 		{"int32[]", Type{IsSlice: true, SliceSize: -1, Elem: &Type{Kind: reflect.Int32, Type: big_t, Size: 32, T: IntTy, stringKind: "int32"}, stringKind: "int32[]"}}, | ||||
| 		{"int32[2]", Type{IsArray: true, SliceSize: 2, Elem: &Type{Kind: reflect.Int32, Type: big_t, Size: 32, T: IntTy, stringKind: "int32"}, stringKind: "int32[2]"}}, | ||||
| 		{"int[]", Type{IsSlice: true, SliceSize: -1, Kind: reflect.Ptr, Type: big_t, Size: 256, T: IntTy, Elem: &Type{Kind: reflect.Ptr, Type: big_t, Size: 256, T: IntTy, stringKind: "int256"}, stringKind: "int256[]"}}, | ||||
| 		{"int[2]", Type{IsArray: true, SliceSize: 2, Kind: reflect.Ptr, Type: big_t, Size: 256, T: IntTy, Elem: &Type{Kind: reflect.Ptr, Type: big_t, Size: 256, T: IntTy, stringKind: "int256"}, stringKind: "int256[2]"}}, | ||||
| 		{"int32[]", Type{IsSlice: true, SliceSize: -1, Kind: reflect.Int32, Type: big_t, Size: 32, T: IntTy, Elem: &Type{Kind: reflect.Int32, Type: big_t, Size: 32, T: IntTy, stringKind: "int32"}, stringKind: "int32[]"}}, | ||||
| 		{"int32[2]", Type{IsArray: true, SliceSize: 2, Kind: reflect.Int32, Type: big_t, Size: 32, T: IntTy, Elem: &Type{Kind: reflect.Int32, Type: big_t, Size: 32, T: IntTy, stringKind: "int32"}, stringKind: "int32[2]"}}, | ||||
| 		{"uint", Type{Kind: reflect.Ptr, Type: ubig_t, Size: 256, T: UintTy, stringKind: "uint256"}}, | ||||
| 		{"uint8", Type{Kind: reflect.Uint8, Type: ubig_t, Size: 8, T: UintTy, stringKind: "uint8"}}, | ||||
| 		{"uint256", Type{Kind: reflect.Ptr, Type: ubig_t, Size: 256, T: UintTy, stringKind: "uint256"}}, | ||||
| 		{"uint[]", Type{IsSlice: true, SliceSize: -1, Elem: &Type{Kind: reflect.Ptr, Type: ubig_t, Size: 256, T: UintTy, stringKind: "uint256"}, stringKind: "uint256[]"}}, | ||||
| 		{"uint[2]", Type{IsArray: true, SliceSize: 2, Elem: &Type{Kind: reflect.Ptr, Type: ubig_t, Size: 256, T: UintTy, stringKind: "uint256"}, stringKind: "uint256[2]"}}, | ||||
| 		{"uint32[]", Type{IsSlice: true, SliceSize: -1, Elem: &Type{Kind: reflect.Uint32, Type: big_t, Size: 32, T: UintTy, stringKind: "uint32"}, stringKind: "uint32[]"}}, | ||||
| 		{"uint32[2]", Type{IsArray: true, SliceSize: 2, Elem: &Type{Kind: reflect.Uint32, Type: big_t, Size: 32, T: UintTy, stringKind: "uint32"}, stringKind: "uint32[2]"}}, | ||||
| 		{"uint[]", Type{IsSlice: true, SliceSize: -1, Kind: reflect.Ptr, Type: ubig_t, Size: 256, T: UintTy, Elem: &Type{Kind: reflect.Ptr, Type: ubig_t, Size: 256, T: UintTy, stringKind: "uint256"}, stringKind: "uint256[]"}}, | ||||
| 		{"uint[2]", Type{IsArray: true, SliceSize: 2, Kind: reflect.Ptr, Type: ubig_t, Size: 256, T: UintTy, Elem: &Type{Kind: reflect.Ptr, Type: ubig_t, Size: 256, T: UintTy, stringKind: "uint256"}, stringKind: "uint256[2]"}}, | ||||
| 		{"uint32[]", Type{IsSlice: true, SliceSize: -1, Kind: reflect.Uint32, Type: ubig_t, Size: 32, T: UintTy, Elem: &Type{Kind: reflect.Uint32, Type: big_t, Size: 32, T: UintTy, stringKind: "uint32"}, stringKind: "uint32[]"}}, | ||||
| 		{"uint32[2]", Type{IsArray: true, SliceSize: 2, Kind: reflect.Uint32, Type: ubig_t, Size: 32, T: UintTy, Elem: &Type{Kind: reflect.Uint32, Type: big_t, Size: 32, T: UintTy, stringKind: "uint32"}, stringKind: "uint32[2]"}}, | ||||
| 		{"bytes", Type{IsSlice: true, SliceSize: -1, Elem: &Type{Kind: reflect.Uint8, Type: ubig_t, Size: 8, T: UintTy, stringKind: "uint8"}, T: BytesTy, stringKind: "bytes"}}, | ||||
| 		{"bytes32", Type{IsArray: true, SliceSize: 32, Elem: &Type{Kind: reflect.Uint8, Type: ubig_t, Size: 8, T: UintTy, stringKind: "uint8"}, T: FixedBytesTy, stringKind: "bytes32"}}, | ||||
| 		{"bytes[]", Type{IsSlice: true, SliceSize: -1, Elem: &Type{IsSlice: true, SliceSize: -1, Elem: &Type{Kind: reflect.Uint8, Type: ubig_t, Size: 8, T: UintTy, stringKind: "uint8"}, T: BytesTy, stringKind: "bytes"}, stringKind: "bytes[]"}}, | ||||
| @ -52,11 +52,11 @@ func TestTypeRegexp(t *testing.T) { | ||||
| 		{"bytes32[]", Type{IsSlice: true, SliceSize: -1, Elem: &Type{IsArray: true, SliceSize: 32, Elem: &Type{Kind: reflect.Uint8, Type: ubig_t, Size: 8, T: UintTy, stringKind: "uint8"}, T: FixedBytesTy, stringKind: "bytes32"}, stringKind: "bytes32[]"}}, | ||||
| 		{"bytes32[2]", Type{IsArray: true, SliceSize: 2, Elem: &Type{IsArray: true, SliceSize: 32, Elem: &Type{Kind: reflect.Uint8, Type: ubig_t, Size: 8, T: UintTy, stringKind: "uint8"}, T: FixedBytesTy, stringKind: "bytes32"}, stringKind: "bytes32[2]"}}, | ||||
| 		{"string", Type{Kind: reflect.String, Size: -1, T: StringTy, stringKind: "string"}}, | ||||
| 		{"string[]", Type{IsSlice: true, SliceSize: -1, Elem: &Type{Kind: reflect.String, Size: -1, T: StringTy, stringKind: "string"}, stringKind: "string[]"}}, | ||||
| 		{"string[2]", Type{IsArray: true, SliceSize: 2, Elem: &Type{Kind: reflect.String, Size: -1, T: StringTy, stringKind: "string"}, stringKind: "string[2]"}}, | ||||
| 		{"string[]", Type{IsSlice: true, SliceSize: -1, Kind: reflect.String, T: StringTy, Size: -1, Elem: &Type{Kind: reflect.String, T: StringTy, Size: -1, stringKind: "string"}, stringKind: "string[]"}}, | ||||
| 		{"string[2]", Type{IsArray: true, SliceSize: 2, Kind: reflect.String, T: StringTy, Size: -1, Elem: &Type{Kind: reflect.String, T: StringTy, Size: -1, stringKind: "string"}, stringKind: "string[2]"}}, | ||||
| 		{"address", Type{Kind: reflect.Array, Type: address_t, Size: 20, T: AddressTy, stringKind: "address"}}, | ||||
| 		{"address[]", Type{IsSlice: true, SliceSize: -1, Elem: &Type{Kind: reflect.Array, Type: address_t, Size: 20, T: AddressTy, stringKind: "address"}, stringKind: "address[]"}}, | ||||
| 		{"address[2]", Type{IsArray: true, SliceSize: 2, Elem: &Type{Kind: reflect.Array, Type: address_t, Size: 20, T: AddressTy, stringKind: "address"}, stringKind: "address[2]"}}, | ||||
| 		{"address[]", Type{IsSlice: true, SliceSize: -1,Kind: reflect.Array, Type:address_t, T: AddressTy, Size:20, Elem: &Type{Kind: reflect.Array, Type: address_t, Size: 20, T: AddressTy, stringKind: "address"}, stringKind: "address[]"}}, | ||||
| 		{"address[2]", Type{IsArray: true, SliceSize: 2,Kind: reflect.Array, Type:address_t, T: AddressTy, Size:20, Elem: &Type{Kind: reflect.Array, Type: address_t, Size: 20, T: AddressTy, stringKind: "address"}, stringKind: "address[2]"}}, | ||||
| 
 | ||||
| 		// TODO when fixed types are implemented properly
 | ||||
| 		// {"fixed", Type{}},
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user