accounts/abi: fix uint64 upper range encoding.
This commit is contained in:
		
							parent
							
								
									63d1d145e2
								
							
						
					
					
						commit
						0f9539e1e3
					
				| @ -56,27 +56,21 @@ var ( | ||||
| 	big_ts   = reflect.TypeOf([]*big.Int(nil)) | ||||
| ) | ||||
| 
 | ||||
| // U256 will ensure unsigned 256bit on big nums
 | ||||
| // U256 converts a big Int into a 256bit EVM number.
 | ||||
| func U256(n *big.Int) []byte { | ||||
| 	return common.LeftPadBytes(common.U256(n).Bytes(), 32) | ||||
| } | ||||
| 
 | ||||
| // S256 will ensure signed 256bit on big nums
 | ||||
| func U2U256(n uint64) []byte { | ||||
| 	return U256(big.NewInt(int64(n))) | ||||
| } | ||||
| 
 | ||||
| // packNum packs the given number (using the reflect value) and will cast it to appropriate number representation
 | ||||
| func packNum(value reflect.Value) []byte { | ||||
| 	switch kind := value.Kind(); kind { | ||||
| 	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: | ||||
| 		return U2U256(value.Uint()) | ||||
| 		return U256(new(big.Int).SetUint64(value.Uint())) | ||||
| 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: | ||||
| 		return U2U256(uint64(value.Int())) | ||||
| 		return U256(big.NewInt(value.Int())) | ||||
| 	case reflect.Ptr: | ||||
| 		return U256(value.Interface().(*big.Int)) | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -18,6 +18,7 @@ package abi | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"math" | ||||
| 	"math/big" | ||||
| 	"reflect" | ||||
| 	"testing" | ||||
| @ -34,21 +35,38 @@ func TestNumberTypes(t *testing.T) { | ||||
| } | ||||
| 
 | ||||
| func TestPackNumber(t *testing.T) { | ||||
| 	ubytes := make([]byte, 32) | ||||
| 	ubytes[31] = 1 | ||||
| 	maxunsigned := []byte{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255} | ||||
| 	tests := []struct { | ||||
| 		value  reflect.Value | ||||
| 		packed []byte | ||||
| 	}{ | ||||
| 		// Protocol limits
 | ||||
| 		{reflect.ValueOf(0), []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, | ||||
| 		{reflect.ValueOf(1), []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}}, | ||||
| 		{reflect.ValueOf(-1), []byte{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}}, | ||||
| 
 | ||||
| 	packed := packNum(reflect.ValueOf(1)) | ||||
| 	if !bytes.Equal(packed, ubytes) { | ||||
| 		t.Errorf("expected %x got %x", ubytes, packed) | ||||
| 	} | ||||
| 	packed = packNum(reflect.ValueOf(-1)) | ||||
| 	if !bytes.Equal(packed, maxunsigned) { | ||||
| 		t.Errorf("expected %x got %x", maxunsigned, packed) | ||||
| 	} | ||||
| 		// Type corner cases
 | ||||
| 		{reflect.ValueOf(uint8(math.MaxUint8)), []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255}}, | ||||
| 		{reflect.ValueOf(uint16(math.MaxUint16)), []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255}}, | ||||
| 		{reflect.ValueOf(uint32(math.MaxUint32)), []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255}}, | ||||
| 		{reflect.ValueOf(uint64(math.MaxUint64)), []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255}}, | ||||
| 
 | ||||
| 	packed = packNum(reflect.ValueOf("string")) | ||||
| 	if packed != nil { | ||||
| 		{reflect.ValueOf(int8(math.MaxInt8)), []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127}}, | ||||
| 		{reflect.ValueOf(int16(math.MaxInt16)), []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 255}}, | ||||
| 		{reflect.ValueOf(int32(math.MaxInt32)), []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 255, 255, 255}}, | ||||
| 		{reflect.ValueOf(int64(math.MaxInt64)), []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 255, 255, 255, 255, 255, 255, 255}}, | ||||
| 
 | ||||
| 		{reflect.ValueOf(int8(math.MinInt8)), []byte{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 128}}, | ||||
| 		{reflect.ValueOf(int16(math.MinInt16)), []byte{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 128, 0}}, | ||||
| 		{reflect.ValueOf(int32(math.MinInt32)), []byte{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 128, 0, 0, 0}}, | ||||
| 		{reflect.ValueOf(int64(math.MinInt64)), []byte{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 128, 0, 0, 0, 0, 0, 0, 0}}, | ||||
| 	} | ||||
| 	for i, tt := range tests { | ||||
| 		packed := packNum(tt.value) | ||||
| 		if !bytes.Equal(packed, tt.packed) { | ||||
| 			t.Errorf("test %d: pack mismatch: have %x, want %x", i, packed, tt.packed) | ||||
| 		} | ||||
| 	} | ||||
| 	if packed := packNum(reflect.ValueOf("string")); packed != nil { | ||||
| 		t.Errorf("expected 'string' to pack to nil. got %x instead", packed) | ||||
| 	} | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user