@@ -27,17 +27,58 @@ import (
2727 "github.com/stretchr/testify/require"
2828)
2929
30+ const (
31+ UintStepLength = 8
32+ UintBegin = 8
33+ UintEnd = 512
34+ UintRandomTestPoints = 1000
35+ UintTestCaseCount = 200
36+ UfixedPrecision = 160
37+ UfixedRandomTestPoints = 20
38+ TupleMaxLength = 10
39+ ByteTestCaseCount = 1 << 8
40+ BoolTestCaseCount = 2
41+ AddressTestCaseCount = 300
42+ StringTestCaseCount = 10
43+ StringTestCaseSpecLenCount = 5
44+ TakeNum = 10
45+ TupleTestCaseCount = 100
46+ )
47+
48+ /*
49+ The set of parameters ensure that the error of byte length >= 2^16 is eliminated.
50+
51+ i. Consider uint512[] with length 10, the ABI encoding length is: 64 x 10 + 2
52+ (2 is introduced from dynamic array length encoding)
53+ The motivation here is that, forall ABI type that is non-array/non-tuple like,
54+ uint512 gives the longest byte length in ABI encoding
55+ (utf-8 string's byte length is at most 42, address byte length is at most 32)
56+
57+ ii. Consider a tuple of length 10, with all elements uint512[] of length 10.
58+ The ABI encoding length is: 10 x 2 + 10 x 642 == 6440
59+ (2 is for tuple index to keep track of dynamic type encoding)
60+
61+ iii. Consider a tuple of length 10, with all elements of tuples mentioned in (ii).
62+ The ABI encoding length is: 10 x 2 + 10 x 6440 == 64420
63+ This is the end of the generation of nested-tuple test case,
64+ no more layers of random tuples will be produced.
65+
66+ This gives an upper bound for the produced ABI encoding byte length in this test script,
67+ and noticing that length 64420 mentioned in (iii) is less than 2^16 == 65536.
68+ Assuming that ABI implementation is correct, then the flaky test should not happen again.
69+ */
70+
3071func TestEncodeValid (t * testing.T ) {
3172 partitiontest .PartitionTest (t )
3273
3374 // encoding test for uint type, iterating through all uint sizes
3475 // randomly pick 1000 valid uint values and check if encoded value match with expected
35- for intSize := 8 ; intSize <= 512 ; intSize += 8 {
76+ for intSize := UintBegin ; intSize <= UintEnd ; intSize += UintStepLength {
3677 upperLimit := big .NewInt (0 ).Lsh (big .NewInt (1 ), uint (intSize ))
3778 uintType , err := makeUintType (intSize )
3879 require .NoError (t , err , "make uint type fail" )
3980
40- for i := 0 ; i < 1000 ; i ++ {
81+ for i := 0 ; i < UintRandomTestPoints ; i ++ {
4182 randomInt , err := rand .Int (rand .Reader , upperLimit )
4283 require .NoError (t , err , "cryptographic random int init fail" )
4384
@@ -64,17 +105,17 @@ func TestEncodeValid(t *testing.T) {
64105 // encoding test for ufixed, iterating through all the valid ufixed bitSize and precision
65106 // randomly generate 10 big int values for ufixed numerator and check if encoded value match with expected
66107 // also check if ufixed can fit max numerator (2^bitSize - 1) under specific byte bitSize
67- for size := 8 ; size <= 512 ; size += 8 {
108+ for size := UintBegin ; size <= UintEnd ; size += UintStepLength {
68109 upperLimit := big .NewInt (0 ).Lsh (big .NewInt (1 ), uint (size ))
69110 largest := big .NewInt (0 ).Add (
70111 upperLimit ,
71112 big .NewInt (1 ).Neg (big .NewInt (1 )),
72113 )
73- for precision := 1 ; precision <= 160 ; precision ++ {
114+ for precision := 1 ; precision <= UfixedPrecision ; precision ++ {
74115 typeUfixed , err := makeUfixedType (size , precision )
75116 require .NoError (t , err , "make ufixed type fail" )
76117
77- for i := 0 ; i < 10 ; i ++ {
118+ for i := 0 ; i < UfixedRandomTestPoints ; i ++ {
78119 randomInt , err := rand .Int (rand .Reader , upperLimit )
79120 require .NoError (t , err , "cryptographic random int init fail" )
80121
@@ -96,13 +137,13 @@ func TestEncodeValid(t *testing.T) {
96137
97138 // encoding test for address, since address is 32 byte, it can be considered as 256 bit uint
98139 // randomly generate 1000 uint256 and make address values, check if encoded value match with expected
99- upperLimit := big .NewInt (0 ).Lsh (big .NewInt (1 ), 256 )
100- for i := 0 ; i < 1000 ; i ++ {
140+ upperLimit := big .NewInt (0 ).Lsh (big .NewInt (1 ), addressByteSize << 3 )
141+ for i := 0 ; i < UintRandomTestPoints ; i ++ {
101142 randomAddrInt , err := rand .Int (rand .Reader , upperLimit )
102143 require .NoError (t , err , "cryptographic random int init fail" )
103144
104145 rand256Bytes := randomAddrInt .Bytes ()
105- addrBytesExpected := make ([]byte , 32 - len (rand256Bytes ))
146+ addrBytesExpected := make ([]byte , addressByteSize - len (rand256Bytes ))
106147 addrBytesExpected = append (addrBytesExpected , rand256Bytes ... )
107148
108149 addrBytesActual , err := addressType .Encode (addrBytesExpected )
@@ -111,7 +152,7 @@ func TestEncodeValid(t *testing.T) {
111152 }
112153
113154 // encoding test for bool values
114- for i := 0 ; i < 2 ; i ++ {
155+ for i := 0 ; i < BoolTestCaseCount ; i ++ {
115156 boolEncode , err := boolType .Encode (i == 1 )
116157 require .NoError (t , err , "bool encode fail" )
117158 expected := []byte {0x00 }
@@ -122,7 +163,7 @@ func TestEncodeValid(t *testing.T) {
122163 }
123164
124165 // encoding test for byte values
125- for i := 0 ; i < ( 1 << 8 ) ; i ++ {
166+ for i := 0 ; i < ByteTestCaseCount ; i ++ {
126167 byteEncode , err := byteType .Encode (byte (i ))
127168 require .NoError (t , err , "byte encode fail" )
128169 expected := []byte {byte (i )}
@@ -133,8 +174,8 @@ func TestEncodeValid(t *testing.T) {
133174 // we use `gobberish` to generate random utf-8 symbols
134175 // randomly generate utf-8 str from length 1 to 100, each length draw 10 random strs
135176 // check if encoded ABI str match with expected value
136- for length := 1 ; length <= 100 ; length ++ {
137- for i := 0 ; i < 10 ; i ++ {
177+ for length := 1 ; length <= StringTestCaseCount ; length ++ {
178+ for i := 0 ; i < StringTestCaseSpecLenCount ; i ++ {
138179 // generate utf8 strings from `gobberish` at some length
139180 utf8Str := gobberish .GenerateString (length )
140181 // since string is just type alias of `byte[]`, we need to store number of bytes in encoding
@@ -828,35 +869,48 @@ type testUnit struct {
828869func categorySelfRoundTripTest (t * testing.T , category []testUnit ) {
829870 for _ , testObj := range category {
830871 abiType , err := TypeOf (testObj .serializedType )
831- require .NoError (t , err , "failure to deserialize type" )
872+ require .NoError (t , err , "failure to deserialize type: " + testObj . serializedType )
832873 encodedValue , err := abiType .Encode (testObj .value )
833- require .NoError (t , err , "failure to encode value" )
874+ require .NoError (t , err ,
875+ "failure to encode value %#v over type %s" , testObj .value , testObj .serializedType ,
876+ )
834877 actual , err := abiType .Decode (encodedValue )
835- require .NoError (t , err , "failure to decode value" )
836- require .Equal (t , testObj .value , actual , "decoded value not equal to expected" )
878+ require .NoError (t , err ,
879+ "failure to decode value %#v for type %s" , encodedValue , testObj .serializedType ,
880+ )
881+ require .Equal (t , testObj .value , actual ,
882+ "decoded value %#v not equal to expected value %#v" , actual , testObj .value ,
883+ )
837884 jsonEncodedValue , err := abiType .MarshalToJSON (testObj .value )
838- require .NoError (t , err , "failure to encode value to JSON type" )
885+ require .NoError (t , err ,
886+ "failure to encode value %#v to JSON type" , testObj .value ,
887+ )
839888 jsonActual , err := abiType .UnmarshalFromJSON (jsonEncodedValue )
840- require .NoError (t , err , "failure to decode JSON value back" )
841- require .Equal (t , testObj .value , jsonActual , "decode JSON value not equal to expected" )
889+ require .NoError (t , err ,
890+ "failure to decode JSON value %s back for type %s" ,
891+ string (jsonEncodedValue ), testObj .serializedType ,
892+ )
893+ require .Equal (t , testObj .value , jsonActual ,
894+ "decode JSON value %s not equal to expected %s" , jsonActual , testObj .value ,
895+ )
842896 }
843897}
844898
845899func addPrimitiveRandomValues (t * testing.T , pool * map [BaseType ][]testUnit ) {
846- (* pool )[Uint ] = make ([]testUnit , 200 * 64 )
847- (* pool )[Ufixed ] = make ([]testUnit , 160 * 64 )
900+ (* pool )[Uint ] = make ([]testUnit , UintTestCaseCount * UintEnd / UintStepLength )
901+ (* pool )[Ufixed ] = make ([]testUnit , UfixedPrecision * UintEnd / UintStepLength )
848902
849903 uintIndex := 0
850904 ufixedIndex := 0
851905
852- for bitSize := 8 ; bitSize <= 512 ; bitSize += 8 {
906+ for bitSize := UintBegin ; bitSize <= UintEnd ; bitSize += UintStepLength {
853907 max := new (big.Int ).Lsh (big .NewInt (1 ), uint (bitSize ))
854908
855909 uintT , err := makeUintType (bitSize )
856910 require .NoError (t , err , "make uint type failure" )
857911 uintTstr := uintT .String ()
858912
859- for j := 0 ; j < 200 ; j ++ {
913+ for j := 0 ; j < UintTestCaseCount ; j ++ {
860914 randVal , err := rand .Int (rand .Reader , max )
861915 require .NoError (t , err , "generate random uint, should be no error" )
862916
@@ -867,7 +921,7 @@ func addPrimitiveRandomValues(t *testing.T, pool *map[BaseType][]testUnit) {
867921 uintIndex ++
868922 }
869923
870- for precision := 1 ; precision <= 160 ; precision ++ {
924+ for precision := 1 ; precision <= UfixedPrecision ; precision ++ {
871925 randVal , err := rand .Int (rand .Reader , max )
872926 require .NoError (t , err , "generate random ufixed, should be no error" )
873927
@@ -884,33 +938,33 @@ func addPrimitiveRandomValues(t *testing.T, pool *map[BaseType][]testUnit) {
884938 categorySelfRoundTripTest (t , (* pool )[Uint ])
885939 categorySelfRoundTripTest (t , (* pool )[Ufixed ])
886940
887- (* pool )[Byte ] = make ([]testUnit , 1 << 8 )
888- for i := 0 ; i < ( 1 << 8 ) ; i ++ {
941+ (* pool )[Byte ] = make ([]testUnit , ByteTestCaseCount )
942+ for i := 0 ; i < ByteTestCaseCount ; i ++ {
889943 (* pool )[Byte ][i ] = testUnit {serializedType : byteType .String (), value : byte (i )}
890944 }
891945 categorySelfRoundTripTest (t , (* pool )[Byte ])
892946
893- (* pool )[Bool ] = make ([]testUnit , 2 )
947+ (* pool )[Bool ] = make ([]testUnit , BoolTestCaseCount )
894948 (* pool )[Bool ][0 ] = testUnit {serializedType : boolType .String (), value : false }
895949 (* pool )[Bool ][1 ] = testUnit {serializedType : boolType .String (), value : true }
896950 categorySelfRoundTripTest (t , (* pool )[Bool ])
897951
898- maxAddress := new (big.Int ).Lsh (big .NewInt (1 ), 256 )
899- (* pool )[Address ] = make ([]testUnit , 300 )
900- for i := 0 ; i < 300 ; i ++ {
952+ maxAddress := new (big.Int ).Lsh (big .NewInt (1 ), addressByteSize << 3 )
953+ (* pool )[Address ] = make ([]testUnit , AddressTestCaseCount )
954+ for i := 0 ; i < AddressTestCaseCount ; i ++ {
901955 randAddrVal , err := rand .Int (rand .Reader , maxAddress )
902956 require .NoError (t , err , "generate random value for address, should be no error" )
903957 addrBytes := randAddrVal .Bytes ()
904- remainBytes := make ([]byte , 32 - len (addrBytes ))
958+ remainBytes := make ([]byte , addressByteSize - len (addrBytes ))
905959 addrBytes = append (remainBytes , addrBytes ... )
906960 (* pool )[Address ][i ] = testUnit {serializedType : addressType .String (), value : addrBytes }
907961 }
908962 categorySelfRoundTripTest (t , (* pool )[Address ])
909963
910- (* pool )[String ] = make ([]testUnit , 400 )
964+ (* pool )[String ] = make ([]testUnit , StringTestCaseCount * StringTestCaseSpecLenCount )
911965 stringIndex := 0
912- for length := 1 ; length <= 100 ; length ++ {
913- for i := 0 ; i < 4 ; i ++ {
966+ for length := 1 ; length <= StringTestCaseCount ; length ++ {
967+ for i := 0 ; i < StringTestCaseSpecLenCount ; i ++ {
914968 (* pool )[String ][stringIndex ] = testUnit {
915969 serializedType : stringType .String (),
916970 value : gobberish .GenerateString (length ),
@@ -945,21 +999,21 @@ func takeSomeFromCategoryAndGenerateArray(
945999}
9461000
9471001func addArrayRandomValues (t * testing.T , pool * map [BaseType ][]testUnit ) {
948- for intIndex := 0 ; intIndex < len ((* pool )[Uint ]); intIndex += 200 {
949- takeSomeFromCategoryAndGenerateArray (t , Uint , intIndex , 20 , pool )
1002+ for intIndex := 0 ; intIndex < len ((* pool )[Uint ]); intIndex += UintTestCaseCount {
1003+ takeSomeFromCategoryAndGenerateArray (t , Uint , intIndex , TakeNum , pool )
9501004 }
951- takeSomeFromCategoryAndGenerateArray (t , Byte , 0 , 20 , pool )
952- takeSomeFromCategoryAndGenerateArray (t , Address , 0 , 20 , pool )
953- takeSomeFromCategoryAndGenerateArray (t , String , 0 , 20 , pool )
954- takeSomeFromCategoryAndGenerateArray (t , Bool , 0 , 20 , pool )
1005+ takeSomeFromCategoryAndGenerateArray (t , Byte , 0 , TakeNum , pool )
1006+ takeSomeFromCategoryAndGenerateArray (t , Address , 0 , TakeNum , pool )
1007+ takeSomeFromCategoryAndGenerateArray (t , String , 0 , TakeNum , pool )
1008+ takeSomeFromCategoryAndGenerateArray (t , Bool , 0 , TakeNum , pool )
9551009
9561010 categorySelfRoundTripTest (t , (* pool )[ArrayStatic ])
9571011 categorySelfRoundTripTest (t , (* pool )[ArrayDynamic ])
9581012}
9591013
9601014func addTupleRandomValues (t * testing.T , slotRange BaseType , pool * map [BaseType ][]testUnit ) {
961- for i := 0 ; i < 100 ; i ++ {
962- tupleLenBig , err := rand .Int (rand .Reader , big .NewInt (20 ))
1015+ for i := 0 ; i < TupleTestCaseCount ; i ++ {
1016+ tupleLenBig , err := rand .Int (rand .Reader , big .NewInt (TupleMaxLength ))
9631017 require .NoError (t , err , "generate random tuple length should not return error" )
9641018 tupleLen := tupleLenBig .Int64 () + 1
9651019 testUnits := make ([]testUnit , tupleLen )
0 commit comments