accounts/abi faster unpacking of int256 (#20850)

This commit is contained in:
Marius van der Wijden 2020-04-01 18:46:53 +02:00 committed by GitHub
parent bf35e27ea7
commit f15849cf00
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 10 additions and 14 deletions

View File

@ -27,13 +27,9 @@ import (
var ( var (
// MaxUint256 is the maximum value that can be represented by a uint256 // MaxUint256 is the maximum value that can be represented by a uint256
MaxUint256 = big.NewInt(0).Add( MaxUint256 = new(big.Int).Sub(new(big.Int).Lsh(common.Big1, 256), common.Big1)
big.NewInt(0).Exp(big.NewInt(2), big.NewInt(256), nil),
big.NewInt(-1))
// MaxInt256 is the maximum value that can be represented by a int256 // MaxInt256 is the maximum value that can be represented by a int256
MaxInt256 = big.NewInt(0).Add( MaxInt256 = new(big.Int).Sub(new(big.Int).Lsh(common.Big1, 255), common.Big1)
big.NewInt(0).Exp(big.NewInt(2), big.NewInt(255), nil),
big.NewInt(-1))
) )
// ReadInteger reads the integer based on its kind and returns the appropriate value // ReadInteger reads the integer based on its kind and returns the appropriate value
@ -56,17 +52,17 @@ func ReadInteger(typ byte, kind reflect.Kind, b []byte) interface{} {
case reflect.Int64: case reflect.Int64:
return int64(binary.BigEndian.Uint64(b[len(b)-8:])) return int64(binary.BigEndian.Uint64(b[len(b)-8:]))
default: default:
// the only case lefts for integer is int256/uint256. // the only case left for integer is int256/uint256.
// big.SetBytes can't tell if a number is negative, positive on itself.
// On EVM, if the returned number > max int256, it is negative.
ret := new(big.Int).SetBytes(b) ret := new(big.Int).SetBytes(b)
if typ == UintTy { if typ == UintTy {
return ret return ret
} }
// big.SetBytes can't tell if a number is negative or positive in itself.
if ret.Cmp(MaxInt256) > 0 { // On EVM, if the returned number > max int256, it is negative.
ret.Add(MaxUint256, big.NewInt(0).Neg(ret)) // A number is > max int256 if the bit at position 255 is set.
ret.Add(ret, big.NewInt(1)) if ret.Bit(255) == 1 {
ret.Add(MaxUint256, new(big.Int).Neg(ret))
ret.Add(ret, common.Big1)
ret.Neg(ret) ret.Neg(ret)
} }
return ret return ret

View File

@ -1009,7 +1009,7 @@ func TestUnpackTuple(t *testing.T) {
t.Errorf("unexpected value unpacked: want %x, got %x", 1, v.A) t.Errorf("unexpected value unpacked: want %x, got %x", 1, v.A)
} }
if v.B.Cmp(big.NewInt(-1)) != 0 { if v.B.Cmp(big.NewInt(-1)) != 0 {
t.Errorf("unexpected value unpacked: want %x, got %x", v.B, -1) t.Errorf("unexpected value unpacked: want %x, got %x", -1, v.B)
} }
} }