[release/1.4.7] accounts/abi: fix uint64 upper range encoding.
(cherry picked from commit 0f9539e1e3
)
This commit is contained in:
parent
f7fdfa4eac
commit
bc6c4a337c
|
@ -56,27 +56,21 @@ var (
|
||||||
big_ts = reflect.TypeOf([]*big.Int(nil))
|
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 {
|
func U256(n *big.Int) []byte {
|
||||||
return common.LeftPadBytes(common.U256(n).Bytes(), 32)
|
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
|
// packNum packs the given number (using the reflect value) and will cast it to appropriate number representation
|
||||||
func packNum(value reflect.Value) []byte {
|
func packNum(value reflect.Value) []byte {
|
||||||
switch kind := value.Kind(); kind {
|
switch kind := value.Kind(); kind {
|
||||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
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:
|
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:
|
case reflect.Ptr:
|
||||||
return U256(value.Interface().(*big.Int))
|
return U256(value.Interface().(*big.Int))
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ package abi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"math"
|
||||||
"math/big"
|
"math/big"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -34,21 +35,38 @@ func TestNumberTypes(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPackNumber(t *testing.T) {
|
func TestPackNumber(t *testing.T) {
|
||||||
ubytes := make([]byte, 32)
|
tests := []struct {
|
||||||
ubytes[31] = 1
|
value reflect.Value
|
||||||
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}
|
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))
|
// Type corner cases
|
||||||
if !bytes.Equal(packed, ubytes) {
|
{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}},
|
||||||
t.Errorf("expected %x got %x", ubytes, packed)
|
{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}},
|
||||||
packed = packNum(reflect.ValueOf(-1))
|
{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}},
|
||||||
if !bytes.Equal(packed, maxunsigned) {
|
|
||||||
t.Errorf("expected %x got %x", maxunsigned, packed)
|
|
||||||
}
|
|
||||||
|
|
||||||
packed = packNum(reflect.ValueOf("string"))
|
{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}},
|
||||||
if packed != nil {
|
{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)
|
t.Errorf("expected 'string' to pack to nil. got %x instead", packed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue