summaryrefslogtreecommitdiff
path: root/data/abi/abi_encode_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'data/abi/abi_encode_test.go')
-rw-r--r--data/abi/abi_encode_test.go876
1 files changed, 338 insertions, 538 deletions
diff --git a/data/abi/abi_encode_test.go b/data/abi/abi_encode_test.go
index 22d37c553..c585564c6 100644
--- a/data/abi/abi_encode_test.go
+++ b/data/abi/abi_encode_test.go
@@ -34,6 +34,9 @@ func TestEncodeValid(t *testing.T) {
// randomly pick 1000 valid uint values and check if encoded value match with expected
for intSize := 8; intSize <= 512; intSize += 8 {
upperLimit := big.NewInt(0).Lsh(big.NewInt(1), uint(intSize))
+ uintType, err := makeUintType(intSize)
+ require.NoError(t, err, "make uint type fail")
+
for i := 0; i < 1000; i++ {
randomInt, err := rand.Int(rand.Reader, upperLimit)
require.NoError(t, err, "cryptographic random int init fail")
@@ -42,12 +45,10 @@ func TestEncodeValid(t *testing.T) {
expected := make([]byte, intSize/8-len(randomIntByte))
expected = append(expected, randomIntByte...)
- uintValue, err := MakeUint(randomInt, uint16(intSize))
- require.NoError(t, err, "makeUint Fail")
- uintBytesActual, err := uintValue.Encode()
+ uintEncode, err := uintType.Encode(randomInt)
+ require.NoError(t, err, "encoding from uint type fail")
- require.NoError(t, err, "uint encode fail")
- require.Equal(t, expected, uintBytesActual, "encode uint not match with expected")
+ require.Equal(t, expected, uintEncode, "encode uint not match with expected")
}
// 2^[bitSize] - 1 test
// check if uint<bitSize> can contain max uint value (2^bitSize - 1)
@@ -55,9 +56,7 @@ func TestEncodeValid(t *testing.T) {
upperLimit,
big.NewInt(1).Neg(big.NewInt(1)),
)
- valueLargest, err := MakeUint(largest, uint16(intSize))
- require.NoError(t, err, "make largest uint fail")
- encoded, err := valueLargest.Encode()
+ encoded, err := uintType.Encode(largest)
require.NoError(t, err, "largest uint encode error")
require.Equal(t, largest.Bytes(), encoded, "encode uint largest do not match with expected")
}
@@ -72,14 +71,14 @@ func TestEncodeValid(t *testing.T) {
big.NewInt(1).Neg(big.NewInt(1)),
)
for precision := 1; precision <= 160; precision++ {
+ typeUfixed, err := makeUfixedType(size, precision)
+ require.NoError(t, err, "make ufixed type fail")
+
for i := 0; i < 10; i++ {
randomInt, err := rand.Int(rand.Reader, upperLimit)
require.NoError(t, err, "cryptographic random int init fail")
- valueUfixed, err := MakeUfixed(randomInt, uint16(size), uint16(precision))
- require.NoError(t, err, "makeUfixed Fail")
-
- encodedUfixed, err := valueUfixed.Encode()
+ encodedUfixed, err := typeUfixed.Encode(randomInt)
require.NoError(t, err, "ufixed encode fail")
randomBytes := randomInt.Bytes()
@@ -88,9 +87,7 @@ func TestEncodeValid(t *testing.T) {
require.Equal(t, buffer, encodedUfixed, "encode ufixed not match with expected")
}
// (2^[bitSize] - 1) / (10^[precision]) test
- ufixedLargestValue, err := MakeUfixed(largest, uint16(size), uint16(precision))
- require.NoError(t, err, "make largest ufixed fail")
- ufixedLargestEncode, err := ufixedLargestValue.Encode()
+ ufixedLargestEncode, err := typeUfixed.Encode(largest)
require.NoError(t, err, "largest ufixed encode error")
require.Equal(t, largest.Bytes(), ufixedLargestEncode,
"encode ufixed largest do not match with expected")
@@ -108,19 +105,14 @@ func TestEncodeValid(t *testing.T) {
addrBytesExpected := make([]byte, 32-len(rand256Bytes))
addrBytesExpected = append(addrBytesExpected, rand256Bytes...)
- var addrBytes [32]byte
- copy(addrBytes[:], addrBytesExpected[:32])
-
- addressValue := MakeAddress(addrBytes)
- addrBytesActual, err := addressValue.Encode()
+ addrBytesActual, err := addressType.Encode(addrBytesExpected)
require.NoError(t, err, "address encode fail")
require.Equal(t, addrBytesExpected, addrBytesActual, "encode addr not match with expected")
}
// encoding test for bool values
for i := 0; i < 2; i++ {
- boolValue := MakeBool(i == 1)
- boolEncode, err := boolValue.Encode()
+ boolEncode, err := boolType.Encode(i == 1)
require.NoError(t, err, "bool encode fail")
expected := []byte{0x00}
if i == 1 {
@@ -131,8 +123,7 @@ func TestEncodeValid(t *testing.T) {
// encoding test for byte values
for i := 0; i < (1 << 8); i++ {
- byteValue := MakeByte(byte(i))
- byteEncode, err := byteValue.Encode()
+ byteEncode, err := byteType.Encode(byte(i))
require.NoError(t, err, "byte encode fail")
expected := []byte{byte(i)}
require.Equal(t, expected, byteEncode, "encode byte not match with expected")
@@ -146,14 +137,13 @@ func TestEncodeValid(t *testing.T) {
for i := 0; i < 10; i++ {
// generate utf8 strings from `gobberish` at some length
utf8Str := gobberish.GenerateString(length)
- strValue := MakeString(utf8Str)
// since string is just type alias of `byte[]`, we need to store number of bytes in encoding
utf8ByteLen := len([]byte(utf8Str))
lengthBytes := make([]byte, 2)
binary.BigEndian.PutUint16(lengthBytes, uint16(utf8ByteLen))
expected := append(lengthBytes, []byte(utf8Str)...)
- strEncode, err := strValue.Encode()
+ strEncode, err := stringType.Encode(utf8Str)
require.NoError(t, err, "string encode fail")
require.Equal(t, expected, strEncode, "encode string not match with expected")
}
@@ -162,54 +152,39 @@ func TestEncodeValid(t *testing.T) {
// encoding test for static bool array, the expected behavior of encoding is to
// compress multiple bool into a single byte.
// input: {T, F, F, T, T}, encode expected: {0b10011000}
+ staticBoolArrType := makeStaticArrayType(boolType, 5)
t.Run("static bool array encoding", func(t *testing.T) {
inputBase := []bool{true, false, false, true, true}
- arrayElems := make([]Value, len(inputBase))
- for index, bVal := range inputBase {
- arrayElems[index] = MakeBool(bVal)
- }
expected := []byte{
0b10011000,
}
- boolArr, err := MakeStaticArray(arrayElems)
- require.NoError(t, err, "make static array should not return error")
- boolArrEncode, err := boolArr.Encode()
+ boolArrEncode, err := staticBoolArrType.Encode(inputBase)
require.NoError(t, err, "static bool array encoding should not return error")
require.Equal(t, expected, boolArrEncode, "static bool array encode not match expected")
})
// encoding test for static bool array
// input: {F, F, F, T, T, F, T, F, T, F, T}, encode expected: {0b00011010, 0b10100000}
+ staticBoolArrType = makeStaticArrayType(boolType, 11)
t.Run("static bool array encoding", func(t *testing.T) {
inputBase := []bool{false, false, false, true, true, false, true, false, true, false, true}
- arrayElems := make([]Value, len(inputBase))
- for index, bVal := range inputBase {
- arrayElems[index] = MakeBool(bVal)
- }
expected := []byte{
0b00011010, 0b10100000,
}
- boolArr, err := MakeStaticArray(arrayElems)
- require.NoError(t, err, "make static array should not return error")
- boolArrEncode, err := boolArr.Encode()
+ boolArrEncode, err := staticBoolArrType.Encode(inputBase)
require.NoError(t, err, "static bool array encoding should not return error")
require.Equal(t, expected, boolArrEncode, "static bool array encode not match expected")
})
// encoding test for dynamic bool array
// input: {F, T, F, T, F, T, F, T, F, T}, encode expected: {0b01010101, 0b01000000}
+ dynamicBoolArrayType := makeDynamicArrayType(boolType)
t.Run("dynamic bool array encoding", func(t *testing.T) {
inputBase := []bool{false, true, false, true, false, true, false, true, false, true}
- arrayElems := make([]Value, len(inputBase))
- for index, bVal := range inputBase {
- arrayElems[index] = MakeBool(bVal)
- }
expected := []byte{
0x00, 0x0A, 0b01010101, 0b01000000,
}
- boolArr, err := MakeDynamicArray(arrayElems, MakeBoolType())
- require.NoError(t, err, "make dynamic array should not return error")
- boolArrEncode, err := boolArr.Encode()
+ boolArrEncode, err := dynamicBoolArrayType.Encode(inputBase)
require.NoError(t, err, "dynamic bool array encoding should not return error")
require.Equal(t, expected, boolArrEncode, "dynamic bool array encode not match expected")
})
@@ -227,29 +202,18 @@ func TestEncodeValid(t *testing.T) {
0x00, 0x03 (second string byte length 3)
byte('D'), byte('E'), byte('F') (second string encoded bytes)
*/
+ tupleType, err := TypeOf("(string,bool,bool,bool,bool,string)")
+ require.NoError(t, err, "type from string for dynamic tuple type should not return error")
t.Run("dynamic tuple encoding", func(t *testing.T) {
inputBase := []interface{}{
"ABC", true, false, true, false, "DEF",
}
- tupleElems := make([]Value, len(inputBase))
- // make tuple element values
- for index, bVal := range inputBase {
- temp, ok := bVal.(string)
- if ok {
- tupleElems[index] = MakeString(temp)
- } else {
- temp := bVal.(bool)
- tupleElems[index] = MakeBool(temp)
- }
- }
expected := []byte{
0x00, 0x05, 0b10100000, 0x00, 0x0A,
0x00, 0x03, byte('A'), byte('B'), byte('C'),
0x00, 0x03, byte('D'), byte('E'), byte('F'),
}
- stringTuple, err := MakeTuple(tupleElems)
- require.NoError(t, err, "make string tuple should not return error")
- stringTupleEncode, err := stringTuple.Encode()
+ stringTupleEncode, err := tupleType.Encode(inputBase)
require.NoError(t, err, "string tuple encoding should not return error")
require.Equal(t, expected, stringTupleEncode, "string tuple encoding not match expected")
})
@@ -262,21 +226,17 @@ func TestEncodeValid(t *testing.T) {
0b11000000 (first static bool array)
0b11000000 (second static bool array)
*/
+ tupleType, err = TypeOf("(bool[2],bool[2])")
+ require.NoError(t, err, "type from string for tuple type should not return error")
t.Run("static bool array tuple encoding", func(t *testing.T) {
- boolArr := []bool{true, true}
- boolValArr := make([]Value, 2)
- for i := 0; i < 2; i++ {
- boolValArr[i] = MakeBool(boolArr[i])
- }
- boolArrVal, err := MakeStaticArray(boolValArr)
- require.NoError(t, err, "make bool static array should not return error")
- tupleVal, err := MakeTuple([]Value{boolArrVal, boolArrVal})
- require.NoError(t, err, "make tuple value should not return error")
expected := []byte{
0b11000000,
0b11000000,
}
- actual, err := tupleVal.Encode()
+ actual, err := tupleType.Encode([]interface{}{
+ []bool{true, true},
+ []bool{true, true},
+ })
require.NoError(t, err, "encode tuple value should not return error")
require.Equal(t, expected, actual, "encode static bool tuple should be equal")
})
@@ -291,24 +251,18 @@ func TestEncodeValid(t *testing.T) {
0x00, 0x02 (dynamic bool array length 2)
0b11000000 (second static bool array)
*/
+ tupleType, err = TypeOf("(bool[2],bool[])")
+ require.NoError(t, err, "type from string for tuple type should not return error")
t.Run("static/dynamic bool array tuple encoding", func(t *testing.T) {
- boolArr := []bool{true, true}
- boolValArr := make([]Value, 2)
- for i := 0; i < 2; i++ {
- boolValArr[i] = MakeBool(boolArr[i])
- }
- boolArrStaticVal, err := MakeStaticArray(boolValArr)
- require.NoError(t, err, "make static bool array should not return error")
- boolArrDynamicVal, err := MakeDynamicArray(boolValArr, MakeBoolType())
- require.NoError(t, err, "make dynamic bool array should not return error")
- tupleVal, err := MakeTuple([]Value{boolArrStaticVal, boolArrDynamicVal})
- require.NoError(t, err, "make tuple for static/dynamic bool array should not return error")
expected := []byte{
0b11000000,
0x00, 0x03,
0x00, 0x02, 0b11000000,
}
- actual, err := tupleVal.Encode()
+ actual, err := tupleType.Encode([]interface{}{
+ []bool{true, true},
+ []bool{true, true},
+ })
require.NoError(t, err, "tuple value encoding should not return error")
require.Equal(t, expected, actual, "encode static/dynamic bool array tuple should not return error")
})
@@ -323,27 +277,27 @@ func TestEncodeValid(t *testing.T) {
0x00, 0x00 (first dynamic bool array length 0)
0x00, 0x00 (second dynamic bool array length 0)
*/
+ tupleType, err = TypeOf("(bool[],bool[])")
+ require.NoError(t, err, "type from string for tuple type should not return error")
t.Run("empty dynamic array tuple encoding", func(t *testing.T) {
- emptyDynamicArray, err := MakeDynamicArray([]Value{}, MakeBoolType())
- require.NoError(t, err, "make empty dynamic array should not return error")
- tupleVal, err := MakeTuple([]Value{emptyDynamicArray, emptyDynamicArray})
- require.NoError(t, err, "make empty dynamic array tuple should not return error")
expected := []byte{
0x00, 0x04, 0x00, 0x06,
0x00, 0x00, 0x00, 0x00,
}
- actual, err := tupleVal.Encode()
+ actual, err := tupleType.Encode([]interface{}{
+ []bool{}, []bool{},
+ })
require.NoError(t, err, "encode empty dynamic array tuple should not return error")
require.Equal(t, expected, actual, "encode empty dynamic array tuple does not match with expected")
})
// encoding test for empty tuple
// input: (), expected encoding: ""
+ tupleType, err = TypeOf("()")
+ require.NoError(t, err, "type from string for tuple type should not return error")
t.Run("empty tuple encoding", func(t *testing.T) {
- emptyTuple, err := MakeTuple([]Value{})
- require.NoError(t, err, "make empty tuple should not return error")
expected := make([]byte, 0)
- actual, err := emptyTuple.Encode()
+ actual, err := tupleType.Encode([]interface{}{})
require.NoError(t, err, "encode empty tuple should not return error")
require.Equal(t, expected, actual, "empty tuple encode should not return error")
})
@@ -356,17 +310,29 @@ func TestDecodeValid(t *testing.T) {
// generate bytes from random uint values and decode bytes with additional type information
for intSize := 8; intSize <= 512; intSize += 8 {
upperLimit := big.NewInt(0).Lsh(big.NewInt(1), uint(intSize))
+ uintType, err := makeUintType(intSize)
+ require.NoError(t, err, "make uint type failure")
for i := 0; i < 1000; i++ {
- randomInt, err := rand.Int(rand.Reader, upperLimit)
+ randBig, err := rand.Int(rand.Reader, upperLimit)
require.NoError(t, err, "cryptographic random int init fail")
- expected, err := MakeUint(randomInt, uint16(intSize))
- require.NoError(t, err, "makeUint Fail")
- encodedUint, err := expected.Encode()
+
+ var expected interface{}
+ if intSize <= 64 && intSize > 32 {
+ expected = randBig.Uint64()
+ } else if intSize <= 32 && intSize > 16 {
+ expected = uint32(randBig.Uint64())
+ } else if intSize == 16 {
+ expected = uint16(randBig.Uint64())
+ } else if intSize == 8 {
+ expected = uint8(randBig.Uint64())
+ } else {
+ expected = randBig
+ }
+
+ encodedUint, err := uintType.Encode(expected)
require.NoError(t, err, "uint encode fail")
- // attempt to decode from given bytes: encodedUint
- uintType, err := MakeUintType(uint16(intSize))
- require.NoError(t, err, "uint type make fail")
- actual, err := Decode(encodedUint, uintType)
+
+ actual, err := uintType.Decode(encodedUint)
require.NoError(t, err, "decoding uint should not return error")
require.Equal(t, expected, actual, "decode uint fail to match expected value")
}
@@ -378,22 +344,32 @@ func TestDecodeValid(t *testing.T) {
for size := 8; size <= 512; size += 8 {
upperLimit := big.NewInt(0).Lsh(big.NewInt(1), uint(size))
for precision := 1; precision <= 160; precision++ {
+ ufixedType, err := makeUfixedType(size, precision)
+ require.NoError(t, err, "make ufixed type failure")
for i := 0; i < 10; i++ {
- randomInt, err := rand.Int(rand.Reader, upperLimit)
+ randBig, err := rand.Int(rand.Reader, upperLimit)
require.NoError(t, err, "cryptographic random int init fail")
- valueUfixed, err := MakeUfixed(randomInt, uint16(size), uint16(precision))
- require.NoError(t, err, "makeUfixed Fail")
-
- encodedUfixed, err := valueUfixed.Encode()
+ var expected interface{}
+ if size <= 64 && size > 32 {
+ expected = randBig.Uint64()
+ } else if size <= 32 && size > 16 {
+ expected = uint32(randBig.Uint64())
+ } else if size == 16 {
+ expected = uint16(randBig.Uint64())
+ } else if size == 8 {
+ expected = uint8(randBig.Uint64())
+ } else {
+ expected = randBig
+ }
+
+ encodedUfixed, err := ufixedType.Encode(expected)
require.NoError(t, err, "ufixed encode fail")
+ require.NoError(t, err, "cast big integer to expected value should not return error")
- ufixedType, err := MakeUfixedType(uint16(size), uint16(precision))
- require.NoError(t, err, "ufixed type make fail")
-
- decodedUfixed, err := Decode(encodedUfixed, ufixedType)
+ actual, err := ufixedType.Decode(encodedUfixed)
require.NoError(t, err, "decoding ufixed should not return error")
- require.Equal(t, valueUfixed, decodedUfixed, "decode ufixed fail to match expected value")
+ require.Equal(t, expected, actual, "decode ufixed fail to match expected value")
}
}
}
@@ -407,39 +383,30 @@ func TestDecodeValid(t *testing.T) {
require.NoError(t, err, "cryptographic random int init fail")
addressBytes := randomAddrInt.Bytes()
- address := make([]byte, 32-len(addressBytes))
- address = append(address, addressBytes...)
-
- var addrBytes [32]byte
- copy(addrBytes[:], address[:32])
+ expected := make([]byte, 32-len(addressBytes))
+ expected = append(expected, addressBytes...)
- addressValue := MakeAddress(addrBytes)
- addrEncode, err := addressValue.Encode()
- require.NoError(t, err, "address encode fail")
-
- addressDecoded, err := Decode(addrEncode, MakeAddressType())
+ actual, err := addressType.Decode(expected)
require.NoError(t, err, "decoding address should not return error")
- require.Equal(t, addressValue, addressDecoded, "decode addr not match with expected")
+ require.Equal(t, expected, actual, "decode addr not match with expected")
}
// bool value decoding test
for i := 0; i < 2; i++ {
- boolValue := MakeBool(i == 1)
- boolEncode, err := boolValue.Encode()
+ boolEncode, err := boolType.Encode(i == 1)
require.NoError(t, err, "bool encode fail")
- boolDecode, err := Decode(boolEncode, MakeBoolType())
+ actual, err := boolType.Decode(boolEncode)
require.NoError(t, err, "decoding bool should not return error")
- require.Equal(t, boolValue, boolDecode, "decode bool not match with expected")
+ require.Equal(t, i == 1, actual, "decode bool not match with expected")
}
// byte value decoding test, iterating through 256 valid byte value
for i := 0; i < (1 << 8); i++ {
- byteValue := MakeByte(byte(i))
- byteEncode, err := byteValue.Encode()
+ byteEncode, err := byteType.Encode(byte(i))
require.NoError(t, err, "byte encode fail")
- byteDecode, err := Decode(byteEncode, MakeByteType())
+ actual, err := byteType.Decode(byteEncode)
require.NoError(t, err, "decoding byte should not return error")
- require.Equal(t, byteValue, byteDecode, "decode byte not match with expected")
+ require.Equal(t, byte(i), actual, "decode byte not match with expected")
}
// string value decoding test, test from utf string length 1 to 100
@@ -447,13 +414,12 @@ func TestDecodeValid(t *testing.T) {
// decode the encoded expected value and check if they match
for length := 1; length <= 100; length++ {
for i := 0; i < 10; i++ {
- utf8Str := gobberish.GenerateString(length)
- strValue := MakeString(utf8Str)
- strEncode, err := strValue.Encode()
+ expected := gobberish.GenerateString(length)
+ strEncode, err := stringType.Encode(expected)
require.NoError(t, err, "string encode fail")
- strDecode, err := Decode(strEncode, MakeStringType())
+ actual, err := stringType.Decode(strEncode)
require.NoError(t, err, "decoding string should not return error")
- require.Equal(t, strValue, strDecode, "encode string not match with expected")
+ require.Equal(t, expected, actual, "encode string not match with expected")
}
}
@@ -461,17 +427,10 @@ func TestDecodeValid(t *testing.T) {
// expected value: bool[5]: {T, F, F, T, T}
// input: 0b10011000
t.Run("static bool array decode", func(t *testing.T) {
- inputBase := []bool{true, false, false, true, true}
- arrayElems := make([]Value, len(inputBase))
- for index, bVal := range inputBase {
- arrayElems[index] = MakeBool(bVal)
- }
- expected, err := MakeStaticArray(arrayElems)
- require.NoError(t, err, "make expected value should not return error")
- actual, err := Decode(
- []byte{0b10011000},
- MakeStaticArrayType(MakeBoolType(), uint16(len(inputBase))),
- )
+ staticBoolArrT, err := TypeOf("bool[5]")
+ require.NoError(t, err, "make static bool array type failure")
+ expected := []interface{}{true, false, false, true, true}
+ actual, err := staticBoolArrT.Decode([]byte{0b10011000})
require.NoError(t, err, "decoding static bool array should not return error")
require.Equal(t, expected, actual, "static bool array decode do not match expected")
})
@@ -480,19 +439,10 @@ func TestDecodeValid(t *testing.T) {
// expected value: bool[11]: F, F, F, T, T, F, T, F, T, F, T
// input: 0b00011010, 0b10100000
t.Run("static bool array decode", func(t *testing.T) {
- inputBase := []bool{false, false, false, true, true, false, true, false, true, false, true}
- arrayElems := make([]Value, len(inputBase))
- for index, bVal := range inputBase {
- arrayElems[index] = MakeBool(bVal)
- }
- expected, err := MakeStaticArray(arrayElems)
- require.NoError(t, err, "make expected value should not return error")
- actual, err := Decode(
- []byte{
- 0b00011010, 0b10100000,
- },
- MakeStaticArrayType(MakeBoolType(), uint16(len(inputBase))),
- )
+ staticBoolArrT, err := TypeOf("bool[11]")
+ require.NoError(t, err, "make static bool array type failure")
+ expected := []interface{}{false, false, false, true, true, false, true, false, true, false, true}
+ actual, err := staticBoolArrT.Decode([]byte{0b00011010, 0b10100000})
require.NoError(t, err, "decoding static bool array should not return error")
require.Equal(t, expected, actual, "static bool array decode do not match expected")
})
@@ -510,20 +460,19 @@ func TestDecodeValid(t *testing.T) {
0, 0, 0, 0, 0, 0, 0, 8 (encoding for uint64 8)
*/
t.Run("static uint array decode", func(t *testing.T) {
- inputUint := []uint64{1, 2, 3, 4, 5, 6, 7, 8}
- arrayElems := make([]Value, len(inputUint))
- for index, uintVal := range inputUint {
- arrayElems[index] = MakeUint64(uintVal)
- }
- uintT, err := MakeUintType(64)
- require.NoError(t, err, "make uint64 type should not return error")
- expected, err := MakeStaticArray(arrayElems)
- require.NoError(t, err, "make uint64 static array should not return error")
- arrayEncoded, err := expected.Encode()
+ staticUintArrT, err := TypeOf("uint64[8]")
+ require.NoError(t, err, "make static uint array type failure")
+ expected := []interface{}{
+ uint64(1), uint64(2),
+ uint64(3), uint64(4),
+ uint64(5), uint64(6),
+ uint64(7), uint64(8),
+ }
+ arrayEncoded, err := staticUintArrT.Encode(expected)
require.NoError(t, err, "uint64 static array encode should not return error")
- arrayDecoded, err := Decode(arrayEncoded, MakeStaticArrayType(uintT, uint16(len(inputUint))))
+ actual, err := staticUintArrT.Decode(arrayEncoded)
require.NoError(t, err, "uint64 static array decode should not return error")
- require.Equal(t, expected, arrayDecoded, "uint64 static array decode do not match with expected value")
+ require.Equal(t, expected, actual, "uint64 static array decode do not match with expected value")
})
// decoding test for dynamic bool array
@@ -533,17 +482,13 @@ func TestDecodeValid(t *testing.T) {
0b01010101, 0b01000000 (dynamic bool array encoding)
*/
t.Run("dynamic bool array decode", func(t *testing.T) {
- inputBool := []bool{false, true, false, true, false, true, false, true, false, true}
- arrayElems := make([]Value, len(inputBool))
- for index, bVal := range inputBool {
- arrayElems[index] = MakeBool(bVal)
- }
- expected, err := MakeDynamicArray(arrayElems, MakeBoolType())
- require.NoError(t, err, "make expected value should not return error")
+ dynamicBoolArrT, err := TypeOf("bool[]")
+ require.NoError(t, err, "make dynamic bool array type failure")
+ expected := []interface{}{false, true, false, true, false, true, false, true, false, true}
inputEncoded := []byte{
0x00, 0x0A, 0b01010101, 0b01000000,
}
- actual, err := Decode(inputEncoded, MakeDynamicArrayType(MakeBoolType()))
+ actual, err := dynamicBoolArrT.Decode(inputEncoded)
require.NoError(t, err, "decode dynamic array should not return error")
require.Equal(t, expected, actual, "decode dynamic array do not match expected")
})
@@ -562,38 +507,17 @@ func TestDecodeValid(t *testing.T) {
byte('D'), byte('E'), byte('F') (second string encoded bytes)
*/
t.Run("dynamic tuple decoding", func(t *testing.T) {
+ tupleT, err := TypeOf("(string,bool,bool,bool,bool,string)")
+ require.NoError(t, err, "make tuple type failure")
inputEncode := []byte{
0x00, 0x05, 0b10100000, 0x00, 0x0A,
0x00, 0x03, byte('A'), byte('B'), byte('C'),
0x00, 0x03, byte('D'), byte('E'), byte('F'),
}
- expectedBase := []interface{}{
+ expected := []interface{}{
"ABC", true, false, true, false, "DEF",
}
- tupleElems := make([]Value, len(expectedBase))
- for index, bVal := range expectedBase {
- temp, ok := bVal.(string)
- if ok {
- tupleElems[index] = MakeString(temp)
- } else {
- temp := bVal.(bool)
- tupleElems[index] = MakeBool(temp)
- }
- }
- expected, err := MakeTuple(tupleElems)
- require.NoError(t, err, "make expected value should not return error")
- actual, err := Decode(
- inputEncode,
- Type{
- abiTypeID: Tuple,
- childTypes: []Type{
- MakeStringType(),
- MakeBoolType(), MakeBoolType(), MakeBoolType(), MakeBoolType(),
- MakeStringType(),
- },
- staticLength: 6,
- },
- )
+ actual, err := tupleT.Decode(inputEncode)
require.NoError(t, err, "decoding dynamic tuple should not return error")
require.Equal(t, expected, actual, "dynamic tuple not match with expected")
})
@@ -607,37 +531,19 @@ func TestDecodeValid(t *testing.T) {
0b11000000 (second static bool array)
*/
t.Run("static bool array tuple decoding", func(t *testing.T) {
- boolArr := []bool{true, true}
- boolValArr := make([]Value, 2)
- for i := 0; i < 2; i++ {
- boolValArr[i] = MakeBool(boolArr[i])
+ tupleT, err := TypeOf("(bool[2],bool[2])")
+ require.NoError(t, err, "make tuple type failure")
+ expected := []interface{}{
+ []interface{}{true, true},
+ []interface{}{true, true},
}
- boolArrVal, err := MakeStaticArray(boolValArr)
- require.NoError(t, err, "make bool static array should not return error")
- tupleVal, err := MakeTuple([]Value{boolArrVal, boolArrVal})
- require.NoError(t, err, "make tuple value should not return error")
encodedInput := []byte{
0b11000000,
0b11000000,
}
- decoded, err := Decode(encodedInput, Type{
- abiTypeID: Tuple,
- staticLength: 2,
- childTypes: []Type{
- {
- abiTypeID: ArrayStatic,
- staticLength: 2,
- childTypes: []Type{MakeBoolType()},
- },
- {
- abiTypeID: ArrayStatic,
- staticLength: 2,
- childTypes: []Type{MakeBoolType()},
- },
- },
- })
+ actual, err := tupleT.Decode(encodedInput)
require.NoError(t, err, "decode tuple value should not return error")
- require.Equal(t, tupleVal, decoded, "decoded tuple value do not match with expected")
+ require.Equal(t, expected, actual, "decoded tuple value do not match with expected")
})
// decoding test for tuple with static and dynamic bool array
@@ -651,39 +557,20 @@ func TestDecodeValid(t *testing.T) {
0b11000000 (second static bool array)
*/
t.Run("static/dynamic bool array tuple decoding", func(t *testing.T) {
- boolArr := []bool{true, true}
- boolValArr := make([]Value, 2)
- for i := 0; i < 2; i++ {
- boolValArr[i] = MakeBool(boolArr[i])
+ tupleT, err := TypeOf("(bool[2],bool[])")
+ require.NoError(t, err, "make tuple type failure")
+ expected := []interface{}{
+ []interface{}{true, true},
+ []interface{}{true, true},
}
- boolArrStaticVal, err := MakeStaticArray(boolValArr)
- require.NoError(t, err, "make static bool array should not return error")
- boolArrDynamicVal, err := MakeDynamicArray(boolValArr, MakeBoolType())
- require.NoError(t, err, "make dynamic bool array should not return error")
- tupleVal, err := MakeTuple([]Value{boolArrStaticVal, boolArrDynamicVal})
- require.NoError(t, err, "make tuple for static/dynamic bool array should not return error")
encodedInput := []byte{
0b11000000,
0x00, 0x03,
0x00, 0x02, 0b11000000,
}
- decoded, err := Decode(encodedInput, Type{
- abiTypeID: Tuple,
- staticLength: 2,
- childTypes: []Type{
- {
- abiTypeID: ArrayStatic,
- staticLength: 2,
- childTypes: []Type{MakeBoolType()},
- },
- {
- abiTypeID: ArrayDynamic,
- childTypes: []Type{MakeBoolType()},
- },
- },
- })
+ actual, err := tupleT.Decode(encodedInput)
require.NoError(t, err, "decode tuple for static/dynamic bool array should not return error")
- require.Equal(t, tupleVal, decoded, "decoded tuple value do not match with expected")
+ require.Equal(t, expected, actual, "decoded tuple value do not match with expected")
})
// decoding test for tuple with all dynamic bool array
@@ -697,46 +584,29 @@ func TestDecodeValid(t *testing.T) {
0x00, 0x00 (second dynamic bool array length 0)
*/
t.Run("empty dynamic array tuple decoding", func(t *testing.T) {
- emptyDynamicArray, err := MakeDynamicArray([]Value{}, MakeBoolType())
- require.NoError(t, err, "make empty dynamic array should not return error")
- tupleVal, err := MakeTuple([]Value{emptyDynamicArray, emptyDynamicArray})
- require.NoError(t, err, "make empty dynamic array tuple should not return error")
+ tupleT, err := TypeOf("(bool[],bool[])")
+ require.NoError(t, err, "make tuple type failure")
+ expected := []interface{}{
+ []interface{}{}, []interface{}{},
+ }
encodedInput := []byte{
0x00, 0x04, 0x00, 0x06,
0x00, 0x00, 0x00, 0x00,
}
- decoded, err := Decode(encodedInput, Type{
- abiTypeID: Tuple,
- staticLength: 2,
- childTypes: []Type{
- {
- abiTypeID: ArrayDynamic,
- childTypes: []Type{MakeBoolType()},
- },
- {
- abiTypeID: ArrayDynamic,
- childTypes: []Type{MakeBoolType()},
- },
- },
- })
+ actual, err := tupleT.Decode(encodedInput)
require.NoError(t, err, "decode tuple for empty dynamic array should not return error")
- require.Equal(t, tupleVal, decoded, "decoded tuple value do not match with expected")
+ require.Equal(t, expected, actual, "decoded tuple value do not match with expected")
})
// decoding test for empty tuple
// expected value: ()
// byte input: ""
t.Run("empty tuple decoding", func(t *testing.T) {
- emptyTuple, err := MakeTuple([]Value{})
- require.NoError(t, err, "make empty tuple should not return error")
- encodedInput := make([]byte, 0)
- decoded, err := Decode(encodedInput, Type{
- abiTypeID: Tuple,
- staticLength: 0,
- childTypes: []Type{},
- })
+ tupleT, err := TypeOf("()")
+ require.NoError(t, err, "make empty tuple type should not return error")
+ actual, err := tupleT.Decode([]byte{})
require.NoError(t, err, "decode empty tuple should not return error")
- require.Equal(t, emptyTuple, decoded, "empty tuple encode should not return error")
+ require.Equal(t, []interface{}{}, actual, "empty tuple encode should not return error")
})
}
@@ -748,8 +618,8 @@ func TestDecodeInvalid(t *testing.T) {
// should throw error
t.Run("corrupted static bool array decode", func(t *testing.T) {
inputBase := []byte{0b11111111}
- arrayType := MakeStaticArrayType(MakeBoolType(), 9)
- _, err := Decode(inputBase, arrayType)
+ arrayType := makeStaticArrayType(boolType, 9)
+ _, err := arrayType.Decode(inputBase)
require.Error(t, err, "decoding corrupted static bool array should return error")
})
@@ -759,8 +629,8 @@ func TestDecodeInvalid(t *testing.T) {
// should throw error
t.Run("corrupted static bool array decode", func(t *testing.T) {
inputBase := []byte{0b01001011, 0b00000000}
- arrayType := MakeStaticArrayType(MakeBoolType(), 8)
- _, err := Decode(inputBase, arrayType)
+ arrayType := makeStaticArrayType(boolType, 8)
+ _, err := arrayType.Decode(inputBase)
require.Error(t, err, "decoding corrupted static bool array should return error")
})
@@ -778,10 +648,9 @@ func TestDecodeInvalid(t *testing.T) {
0, 0, 0, 0, 0, 0, 0, 5,
0, 0, 0, 0, 0, 0, 0, 6,
}
- uintT, err := MakeUintType(64)
- require.NoError(t, err, "make uint64 type should not return error")
- uintTArray := MakeStaticArrayType(uintT, 8)
- _, err = Decode(inputBase, uintTArray)
+ uintTArray, err := TypeOf("uint64[8]")
+ require.NoError(t, err, "make uint64 static array type should not return error")
+ _, err = uintTArray.Decode(inputBase)
require.Error(t, err, "corrupted uint64 static array decode should return error")
})
@@ -800,10 +669,9 @@ func TestDecodeInvalid(t *testing.T) {
0, 0, 0, 0, 0, 0, 0, 6,
0, 0, 0, 0, 0, 0, 0, 7,
}
- uintT, err := MakeUintType(64)
- require.NoError(t, err, "make uint64 type should not return error")
- uintTArray := MakeStaticArrayType(uintT, 7)
- _, err = Decode(inputBase, uintTArray)
+ uintTArray, err := TypeOf("uint64[7]")
+ require.NoError(t, err, "make uint64 static array type should not return error")
+ _, err = uintTArray.Decode(inputBase)
require.Error(t, err, "corrupted uint64 static array decode should return error")
})
@@ -815,8 +683,8 @@ func TestDecodeInvalid(t *testing.T) {
inputBase := []byte{
0x00, 0x0A, 0b10101010,
}
- dynamicT := MakeDynamicArrayType(MakeBoolType())
- _, err := Decode(inputBase, dynamicT)
+ dynamicT := makeDynamicArrayType(boolType)
+ _, err := dynamicT.Decode(inputBase)
require.Error(t, err, "decode corrupted dynamic array should return error")
})
@@ -828,8 +696,8 @@ func TestDecodeInvalid(t *testing.T) {
inputBase := []byte{
0x00, 0x07, 0b10101010, 0b00000000,
}
- dynamicT := MakeDynamicArrayType(MakeBoolType())
- _, err := Decode(inputBase, dynamicT)
+ dynamicT := makeDynamicArrayType(boolType)
+ _, err := dynamicT.Decode(inputBase)
require.Error(t, err, "decode corrupted dynamic array should return error")
})
@@ -855,30 +723,9 @@ func TestDecodeInvalid(t *testing.T) {
0x00, 0x03, byte('A'), byte('B'), byte('C'),
0x00, 0x03, byte('D'), byte('E'), byte('F'),
}
- expectedBase := []interface{}{
- "ABC", true, false, true, false, "DEF",
- }
- tupleElems := make([]Value, len(expectedBase))
- for index, bVal := range expectedBase {
- temp, ok := bVal.(string)
- if ok {
- tupleElems[index] = MakeString(temp)
- } else {
- temp := bVal.(bool)
- tupleElems[index] = MakeBool(temp)
- }
- }
- _, err := Decode(
- inputEncode,
- Type{
- abiTypeID: Tuple,
- childTypes: []Type{
- MakeStringType(),
- MakeBoolType(), MakeBoolType(), MakeBoolType(), MakeBoolType(),
- MakeStringType(),
- },
- },
- )
+ tupleT, err := TypeOf("(string,bool,bool,bool,bool,string)")
+ require.NoError(t, err, "make tuple type failure")
+ _, err = tupleT.Decode(inputEncode)
require.Error(t, err, "corrupted decoding dynamic tuple should return error")
})
@@ -896,35 +743,20 @@ func TestDecodeInvalid(t *testing.T) {
<- corrupted byte, 1 byte missing
*/
t.Run("corrupted static bool array tuple decoding", func(t *testing.T) {
- expectedType := Type{
- abiTypeID: Tuple,
- staticLength: 2,
- childTypes: []Type{
- {
- abiTypeID: ArrayStatic,
- staticLength: 2,
- childTypes: []Type{MakeBoolType()},
- },
- {
- abiTypeID: ArrayStatic,
- staticLength: 2,
- childTypes: []Type{MakeBoolType()},
- },
- },
- }
-
+ expectedType, err := TypeOf("(bool[2],bool[2])")
+ require.NoError(t, err, "make tuple type failure")
encodedInput0 := []byte{
0b11000000,
0b11000000,
0b00000000,
}
- _, err := Decode(encodedInput0, expectedType)
+ _, err = expectedType.Decode(encodedInput0)
require.Error(t, err, "decode corrupted tuple value should return error")
encodedInput1 := []byte{
0b11000000,
}
- _, err = Decode(encodedInput1, expectedType)
+ _, err = expectedType.Decode(encodedInput1)
require.Error(t, err, "decode corrupted tuple value should return error")
})
@@ -944,21 +776,9 @@ func TestDecodeInvalid(t *testing.T) {
0x03,
0x00, 0x02, 0b11000000,
}
- _, err := Decode(encodedInput, Type{
- abiTypeID: Tuple,
- staticLength: 2,
- childTypes: []Type{
- {
- abiTypeID: ArrayStatic,
- staticLength: 2,
- childTypes: []Type{MakeBoolType()},
- },
- {
- abiTypeID: ArrayDynamic,
- childTypes: []Type{MakeBoolType()},
- },
- },
- })
+ tupleT, err := TypeOf("(bool[2],bool[])")
+ require.NoError(t, err, "make tuple type failure")
+ _, err = tupleT.Decode(encodedInput)
require.Error(t, err, "decode corrupted tuple for static/dynamic bool array should return error")
})
@@ -981,20 +801,9 @@ func TestDecodeInvalid(t *testing.T) {
0x00, 0x04, 0x00, 0x07,
0x00, 0x00, 0x00, 0x00,
}
- _, err := Decode(encodedInput, Type{
- abiTypeID: Tuple,
- staticLength: 2,
- childTypes: []Type{
- {
- abiTypeID: ArrayDynamic,
- childTypes: []Type{MakeBoolType()},
- },
- {
- abiTypeID: ArrayDynamic,
- childTypes: []Type{MakeBoolType()},
- },
- },
- })
+ tupleT, err := TypeOf("(bool[],bool[])")
+ require.NoError(t, err, "make tuple type failure")
+ _, err = tupleT.Decode(encodedInput)
require.Error(t, err, "decode corrupted tuple for empty dynamic array should return error")
})
@@ -1004,200 +813,191 @@ func TestDecodeInvalid(t *testing.T) {
// should return error
t.Run("corrupted empty tuple decoding", func(t *testing.T) {
encodedInput := []byte{0xFF}
- _, err := Decode(encodedInput, Type{
- abiTypeID: Tuple,
- staticLength: 0,
- childTypes: []Type{},
- })
+ tupleT, err := TypeOf("()")
+ require.NoError(t, err, "make tuple type failure")
+ _, err = tupleT.Decode(encodedInput)
require.Error(t, err, "decode corrupted empty tuple should return error")
})
}
-func generateStaticArray(t *testing.T, testValuePool *[][]Value) {
- // int
- for intIndex := 0; intIndex < len((*testValuePool)[Uint]); intIndex += 200 {
- staticArrayList := make([]Value, 20)
- for i := 0; i < 20; i++ {
- staticArrayList[i] = (*testValuePool)[Uint][intIndex+i]
- }
- staticArray, err := MakeStaticArray(staticArrayList)
- require.NoError(t, err, "make static array for uint should not return error")
- (*testValuePool)[ArrayStatic] = append((*testValuePool)[ArrayStatic], staticArray)
+type testUnit struct {
+ serializedType string
+ value interface{}
+}
+
+func categorySelfRoundTripTest(t *testing.T, category []testUnit) {
+ for _, testObj := range category {
+ abiType, err := TypeOf(testObj.serializedType)
+ require.NoError(t, err, "failure to deserialize type")
+ encodedValue, err := abiType.Encode(testObj.value)
+ require.NoError(t, err, "failure to encode value")
+ actual, err := abiType.Decode(encodedValue)
+ require.NoError(t, err, "failure to decode value")
+ require.Equal(t, testObj.value, actual, "decoded value not equal to expected")
+ jsonEncodedValue, err := abiType.MarshalToJSON(testObj.value)
+ require.NoError(t, err, "failure to encode value to JSON type")
+ jsonActual, err := abiType.UnmarshalFromJSON(jsonEncodedValue)
+ require.NoError(t, err, "failure to decode JSON value back")
+ require.Equal(t, testObj.value, jsonActual, "decode JSON value not equal to expected")
}
- // byte
- byteArrayList := make([]Value, 20)
- for byteIndex := 0; byteIndex < 20; byteIndex++ {
- byteArrayList[byteIndex] = (*testValuePool)[Byte][byteIndex]
+}
+
+func addPrimitiveRandomValues(t *testing.T, pool *map[BaseType][]testUnit) {
+ (*pool)[Uint] = make([]testUnit, 200*64)
+ (*pool)[Ufixed] = make([]testUnit, 160*64)
+
+ uintIndex := 0
+ ufixedIndex := 0
+
+ for bitSize := 8; bitSize <= 512; bitSize += 8 {
+ max := new(big.Int).Lsh(big.NewInt(1), uint(bitSize))
+
+ uintT, err := makeUintType(bitSize)
+ require.NoError(t, err, "make uint type failure")
+ uintTstr := uintT.String()
+
+ for j := 0; j < 200; j++ {
+ randVal, err := rand.Int(rand.Reader, max)
+ require.NoError(t, err, "generate random uint, should be no error")
+
+ narrowest, err := castBigIntToNearestPrimitive(randVal, uint16(bitSize))
+ require.NoError(t, err, "cast random uint to nearest primitive failure")
+
+ (*pool)[Uint][uintIndex] = testUnit{serializedType: uintTstr, value: narrowest}
+ uintIndex++
+ }
+
+ for precision := 1; precision <= 160; precision++ {
+ randVal, err := rand.Int(rand.Reader, max)
+ require.NoError(t, err, "generate random ufixed, should be no error")
+
+ narrowest, err := castBigIntToNearestPrimitive(randVal, uint16(bitSize))
+ require.NoError(t, err, "cast random uint to nearest primitive failure")
+
+ ufixedT, err := makeUfixedType(bitSize, precision)
+ require.NoError(t, err, "make ufixed type failure")
+ ufixedTstr := ufixedT.String()
+ (*pool)[Ufixed][ufixedIndex] = testUnit{serializedType: ufixedTstr, value: narrowest}
+ ufixedIndex++
+ }
}
- byteStaticArray, err := MakeStaticArray(byteArrayList)
- require.NoError(t, err, "make static array for byte should not return error")
- (*testValuePool)[ArrayStatic] = append((*testValuePool)[ArrayStatic], byteStaticArray)
- // address
- addressArrayList := make([]Value, 20)
- for addrIndex := 0; addrIndex < 20; addrIndex++ {
- addressArrayList[addrIndex] = (*testValuePool)[Address][addrIndex]
+ categorySelfRoundTripTest(t, (*pool)[Uint])
+ categorySelfRoundTripTest(t, (*pool)[Ufixed])
+
+ (*pool)[Byte] = make([]testUnit, 1<<8)
+ for i := 0; i < (1 << 8); i++ {
+ (*pool)[Byte][i] = testUnit{serializedType: byteType.String(), value: byte(i)}
}
- addressStaticArray, err := MakeStaticArray(addressArrayList)
- require.NoError(t, err, "make static array for address should not return error")
- (*testValuePool)[ArrayStatic] = append((*testValuePool)[ArrayStatic], addressStaticArray)
- // string
- stringArrayList := make([]Value, 20)
- for strIndex := 0; strIndex < 20; strIndex++ {
- stringArrayList[strIndex] = (*testValuePool)[String][strIndex]
+ categorySelfRoundTripTest(t, (*pool)[Byte])
+
+ (*pool)[Bool] = make([]testUnit, 2)
+ (*pool)[Bool][0] = testUnit{serializedType: boolType.String(), value: false}
+ (*pool)[Bool][1] = testUnit{serializedType: boolType.String(), value: true}
+ categorySelfRoundTripTest(t, (*pool)[Bool])
+
+ maxAddress := new(big.Int).Lsh(big.NewInt(1), 256)
+ (*pool)[Address] = make([]testUnit, 300)
+ for i := 0; i < 300; i++ {
+ randAddrVal, err := rand.Int(rand.Reader, maxAddress)
+ require.NoError(t, err, "generate random value for address, should be no error")
+ addrBytes := randAddrVal.Bytes()
+ remainBytes := make([]byte, 32-len(addrBytes))
+ addrBytes = append(remainBytes, addrBytes...)
+ (*pool)[Address][i] = testUnit{serializedType: addressType.String(), value: addrBytes}
}
- stringStaticArray, err := MakeStaticArray(stringArrayList)
- require.NoError(t, err, "make static array for string should not return error")
- (*testValuePool)[ArrayStatic] = append((*testValuePool)[ArrayStatic], stringStaticArray)
- // bool
- boolArrayList := make([]Value, 20)
- for boolIndex := 0; boolIndex < 20; boolIndex++ {
- valBig, err := rand.Int(rand.Reader, big.NewInt(2))
- require.NoError(t, err, "generate random bool index should not return error")
- valIndex := valBig.Int64()
- boolArrayList[boolIndex] = (*testValuePool)[Bool][valIndex]
+ categorySelfRoundTripTest(t, (*pool)[Address])
+
+ (*pool)[String] = make([]testUnit, 400)
+ stringIndex := 0
+ for length := 1; length <= 100; length++ {
+ for i := 0; i < 4; i++ {
+ (*pool)[String][stringIndex] = testUnit{
+ serializedType: stringType.String(),
+ value: gobberish.GenerateString(length),
+ }
+ stringIndex++
+ }
}
- boolStaticArray, err := MakeStaticArray(boolArrayList)
- require.NoError(t, err, "make static array for bool should not return error")
- (*testValuePool)[ArrayStatic] = append((*testValuePool)[ArrayStatic], boolStaticArray)
+ categorySelfRoundTripTest(t, (*pool)[String])
}
-func generateDynamicArray(t *testing.T, testValuePool *[][]Value) {
- // int
- for intIndex := 0; intIndex < len((*testValuePool)[Uint]); intIndex += 200 {
- dynamicArrayList := make([]Value, 20)
- for i := 0; i < 20; i++ {
- dynamicArrayList[i] = (*testValuePool)[Uint][intIndex+i]
+func takeSomeFromCategoryAndGenerateArray(
+ t *testing.T, abiT BaseType, srtIndex int, takeNum uint16, pool *map[BaseType][]testUnit) {
+
+ tempArray := make([]interface{}, takeNum)
+ for i := 0; i < int(takeNum); i++ {
+ index := srtIndex + i
+ if index >= len((*pool)[abiT]) {
+ index = srtIndex
}
- dynamicArray, err := MakeDynamicArray(dynamicArrayList, dynamicArrayList[0].ABIType)
- require.NoError(t, err, "make static array for uint should not return error")
- (*testValuePool)[ArrayDynamic] = append((*testValuePool)[ArrayDynamic], dynamicArray)
- }
- // byte
- byteArrayList := make([]Value, 20)
- for byteIndex := 0; byteIndex < 20; byteIndex++ {
- byteArrayList[byteIndex] = (*testValuePool)[Byte][byteIndex]
- }
- byteDynamicArray, err := MakeDynamicArray(byteArrayList, byteArrayList[0].ABIType)
- require.NoError(t, err, "make dynamic array for byte should not return error")
- (*testValuePool)[ArrayDynamic] = append((*testValuePool)[ArrayDynamic], byteDynamicArray)
- // address
- addressArrayList := make([]Value, 20)
- for addrIndex := 0; addrIndex < 20; addrIndex++ {
- addressArrayList[addrIndex] = (*testValuePool)[Address][addrIndex]
- }
- addressDynamicArray, err := MakeDynamicArray(addressArrayList, MakeAddressType())
- require.NoError(t, err, "make dynamic array for address should not return error")
- (*testValuePool)[ArrayDynamic] = append((*testValuePool)[ArrayDynamic], addressDynamicArray)
- // string
- stringArrayList := make([]Value, 20)
- for strIndex := 0; strIndex < 20; strIndex++ {
- stringArrayList[strIndex] = (*testValuePool)[String][strIndex]
+ tempArray[i] = (*pool)[abiT][index].value
}
- stringDynamicArray, err := MakeDynamicArray(stringArrayList, MakeStringType())
- require.NoError(t, err, "make dynamic array for string should not return error")
- (*testValuePool)[ArrayDynamic] = append((*testValuePool)[ArrayDynamic], stringDynamicArray)
- // bool
- boolArrayList := make([]Value, 20)
- for boolIndex := 0; boolIndex < 20; boolIndex++ {
- valBig, err := rand.Int(rand.Reader, big.NewInt(2))
- require.NoError(t, err, "generate random bool index should not return error")
- valIndex := valBig.Int64()
- boolArrayList[boolIndex] = (*testValuePool)[Bool][valIndex]
+ tempT, err := TypeOf((*pool)[abiT][srtIndex].serializedType)
+ require.NoError(t, err, "type in test uint cannot be deserialized")
+ (*pool)[ArrayStatic] = append((*pool)[ArrayStatic], testUnit{
+ serializedType: makeStaticArrayType(tempT, takeNum).String(),
+ value: tempArray,
+ })
+ (*pool)[ArrayDynamic] = append((*pool)[ArrayDynamic], testUnit{
+ serializedType: makeDynamicArrayType(tempT).String(),
+ value: tempArray,
+ })
+}
+
+func addArrayRandomValues(t *testing.T, pool *map[BaseType][]testUnit) {
+ for intIndex := 0; intIndex < len((*pool)[Uint]); intIndex += 200 {
+ takeSomeFromCategoryAndGenerateArray(t, Uint, intIndex, 20, pool)
}
- boolDynamicArray, err := MakeDynamicArray(boolArrayList, MakeBoolType())
- require.NoError(t, err, "make dynamic array for bool should not return error")
- (*testValuePool)[ArrayDynamic] = append((*testValuePool)[ArrayDynamic], boolDynamicArray)
+ takeSomeFromCategoryAndGenerateArray(t, Byte, 0, 20, pool)
+ takeSomeFromCategoryAndGenerateArray(t, Address, 0, 20, pool)
+ takeSomeFromCategoryAndGenerateArray(t, String, 0, 20, pool)
+ takeSomeFromCategoryAndGenerateArray(t, Bool, 0, 20, pool)
+
+ categorySelfRoundTripTest(t, (*pool)[ArrayStatic])
+ categorySelfRoundTripTest(t, (*pool)[ArrayDynamic])
}
-func generateTuples(t *testing.T, testValuePool *[][]Value, slotRange int) {
+func addTupleRandomValues(t *testing.T, slotRange BaseType, pool *map[BaseType][]testUnit) {
for i := 0; i < 100; i++ {
- tupleLenBig, err := rand.Int(rand.Reader, big.NewInt(2))
+ tupleLenBig, err := rand.Int(rand.Reader, big.NewInt(20))
require.NoError(t, err, "generate random tuple length should not return error")
- tupleLen := 1 + tupleLenBig.Int64()
- tupleValList := make([]Value, tupleLen)
- for tupleElemIndex := 0; tupleElemIndex < int(tupleLen); tupleElemIndex++ {
- tupleTypeIndexBig, err := rand.Int(rand.Reader, big.NewInt(int64(slotRange)))
+ tupleLen := tupleLenBig.Int64() + 1
+ testUnits := make([]testUnit, tupleLen)
+ for index := 0; index < int(tupleLen); index++ {
+ tupleTypeIndexBig, err := rand.Int(rand.Reader, big.NewInt(int64(slotRange)+1))
require.NoError(t, err, "generate random tuple element type index should not return error")
- tupleTypeIndex := tupleTypeIndexBig.Int64()
- tupleElemChoiceRange := len((*testValuePool)[tupleTypeIndex])
+ tupleTypeIndex := BaseType(tupleTypeIndexBig.Int64())
+ tupleElemChoiceRange := len((*pool)[tupleTypeIndex])
tupleElemRangeIndexBig, err := rand.Int(rand.Reader, big.NewInt(int64(tupleElemChoiceRange)))
require.NoError(t, err, "generate random tuple element index in test pool should not return error")
tupleElemRangeIndex := tupleElemRangeIndexBig.Int64()
- tupleElem := (*testValuePool)[tupleTypeIndex][tupleElemRangeIndex]
- tupleValList[tupleElemIndex] = tupleElem
- }
- tupleVal, err := MakeTuple(tupleValList)
- require.NoError(t, err, "make tuple should not return error")
- (*testValuePool)[Tuple] = append((*testValuePool)[Tuple], tupleVal)
+ tupleElem := (*pool)[tupleTypeIndex][tupleElemRangeIndex]
+ testUnits[index] = tupleElem
+ }
+ elemValues := make([]interface{}, tupleLen)
+ elemTypes := make([]Type, tupleLen)
+ for index := 0; index < int(tupleLen); index++ {
+ elemValues[index] = testUnits[index].value
+ abiT, err := TypeOf(testUnits[index].serializedType)
+ require.NoError(t, err, "deserialize type failure for tuple elements")
+ elemTypes[index] = abiT
+ }
+ tupleT, err := MakeTupleType(elemTypes)
+ require.NoError(t, err, "make tuple type failure")
+ (*pool)[Tuple] = append((*pool)[Tuple], testUnit{
+ serializedType: tupleT.String(),
+ value: elemValues,
+ })
}
}
-// round-trip test for random tuple elements
-// first we generate base type elements to each slot of testValuePool
-// then we generate static/dynamic array based on the pre-generated random values
-// we generate base tuples based on base-type elements/static arrays/dynamic arrays
-// we also generate cascaded tuples (tuples with tuple elements)
-func TestEncodeDecodeRandomTuple(t *testing.T) {
+func TestRandomABIEncodeDecodeRoundTrip(t *testing.T) {
partitiontest.PartitionTest(t)
- // test pool for 9 distinct types
- testValuePool := make([][]Value, 9)
- for i := 8; i <= 512; i += 8 {
- max := big.NewInt(1).Lsh(big.NewInt(1), uint(i))
- for j := 0; j < 200; j++ {
- randVal, err := rand.Int(rand.Reader, max)
- require.NoError(t, err, "generate largest number bound, should be no error")
- uintTemp, err := MakeUint(randVal, uint16(i))
- require.NoError(t, err, "generate random ABI uint should not return error")
- testValuePool[Uint] = append(testValuePool[Uint], uintTemp)
- }
- for j := 1; j < 160; j++ {
- randVal, err := rand.Int(rand.Reader, max)
- require.NoError(t, err, "generate largest number bound, should be no error")
- ufixedTemp, err := MakeUfixed(randVal, uint16(i), uint16(j))
- require.NoError(t, err, "generate random ABI ufixed should not return error")
- testValuePool[Ufixed] = append(testValuePool[Ufixed], ufixedTemp)
- }
- }
- for i := 0; i < (1 << 8); i++ {
- testValuePool[Byte] = append(testValuePool[Byte], MakeByte(byte(i)))
- }
- for i := 0; i < 2; i++ {
- testValuePool[Bool] = append(testValuePool[Bool], MakeBool(i == 1))
- }
- for i := 0; i < 500; i++ {
- max := big.NewInt(1).Lsh(big.NewInt(1), 256)
- randVal, err := rand.Int(rand.Reader, max)
- require.NoError(t, err, "generate largest number bound, should be no error")
- addrBytes := randVal.Bytes()
- remainBytes := make([]byte, 32-len(addrBytes))
- addrBytes = append(remainBytes, addrBytes...)
- var addrBytesToMake [32]byte
- copy(addrBytesToMake[:], addrBytes)
- testValuePool[Address] = append(testValuePool[Address], MakeAddress(addrBytesToMake))
- }
- for i := 1; i <= 100; i++ {
- for j := 0; j < 4; j++ {
- abiString := MakeString(gobberish.GenerateString(i))
- testValuePool[String] = append(testValuePool[String], abiString)
- }
- }
- // Array static
- generateStaticArray(t, &testValuePool)
- // Array dynamic
- generateDynamicArray(t, &testValuePool)
- // tuple generation
- generateTuples(t, &testValuePool, 8)
- // generate cascaded tuples
- generateTuples(t, &testValuePool, 9)
- // test tuple encode-decode round-trip
- for _, tuple := range testValuePool[Tuple] {
- t.Run("random tuple encode-decode test", func(t *testing.T) {
- encoded, err := tuple.Encode()
- require.NoError(t, err, "encode tuple should not have error")
- decoded, err := Decode(encoded, tuple.ABIType)
- require.NoError(t, err, "decode tuple should not have error")
- require.Equal(t, tuple, decoded, "encoded-decoded tuple should match with expected")
- })
- }
+ testValuePool := make(map[BaseType][]testUnit)
+ addPrimitiveRandomValues(t, &testValuePool)
+ addArrayRandomValues(t, &testValuePool)
+ addTupleRandomValues(t, String, &testValuePool)
+ addTupleRandomValues(t, Tuple, &testValuePool)
+ categorySelfRoundTripTest(t, testValuePool[Tuple])
}