aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix Lange <fjl@users.noreply.github.com>2017-02-28 22:09:11 +0800
committerJeffrey Wilcke <jeffrey@ethereum.org>2017-02-28 22:09:11 +0800
commit5f7826270c9e87509fd7731ec64953a5e4761de0 (patch)
tree0d3187b115a0e10afcce1bb38ed8ba977d8bf44f
parentd4f60d362b8fcf82db1accf89c146a2a71375841 (diff)
downloaddexon-5f7826270c9e87509fd7731ec64953a5e4761de0.tar
dexon-5f7826270c9e87509fd7731ec64953a5e4761de0.tar.gz
dexon-5f7826270c9e87509fd7731ec64953a5e4761de0.tar.bz2
dexon-5f7826270c9e87509fd7731ec64953a5e4761de0.tar.lz
dexon-5f7826270c9e87509fd7731ec64953a5e4761de0.tar.xz
dexon-5f7826270c9e87509fd7731ec64953a5e4761de0.tar.zst
dexon-5f7826270c9e87509fd7731ec64953a5e4761de0.zip
all: unify big.Int zero checks, use common/math in more places (#3716)
* common/math: optimize PaddedBigBytes, use it more name old time/op new time/op delta PaddedBigBytes-8 71.1ns ± 5% 46.1ns ± 1% -35.15% (p=0.000 n=20+19) name old alloc/op new alloc/op delta PaddedBigBytes-8 48.0B ± 0% 32.0B ± 0% -33.33% (p=0.000 n=20+20) * all: unify big.Int zero checks Various checks were in use. This commit replaces them all with Int.Sign, which is cheaper and less code. eg templates: func before(x *big.Int) bool { return x.BitLen() == 0 } func after(x *big.Int) bool { return x.Sign() == 0 } func before(x *big.Int) bool { return x.BitLen() > 0 } func after(x *big.Int) bool { return x.Sign() != 0 } func before(x *big.Int) int { return x.Cmp(common.Big0) } func after(x *big.Int) int { return x.Sign() } * common/math, crypto/secp256k1: make ReadBits public in package math
-rw-r--r--accounts/abi/bind/backends/simulated.go2
-rw-r--r--accounts/abi/numbers.go2
-rw-r--r--accounts/abi/packing.go5
-rw-r--r--accounts/keystore/keystore_passphrase.go4
-rw-r--r--accounts/usbwallet/ledger_wallet.go2
-rw-r--r--common/math/big.go33
-rw-r--r--common/math/big_test.go23
-rw-r--r--contracts/chequebook/cheque.go6
-rw-r--r--contracts/chequebook/cheque_test.go2
-rw-r--r--core/headerchain.go2
-rw-r--r--core/state/state_object.go6
-rw-r--r--core/tx_pool.go2
-rw-r--r--core/types/transaction.go2
-rw-r--r--core/types/transaction_signing.go2
-rw-r--r--core/types/transaction_signing_test.go2
-rw-r--r--core/vm/common.go2
-rw-r--r--core/vm/evm.go2
-rw-r--r--core/vm/gas_table.go6
-rw-r--r--core/vm/instructions.go23
-rw-r--r--core/vm/logger.go3
-rw-r--r--crypto/secp256k1/curve.go6
-rw-r--r--crypto/secp256k1/curve_test.go39
-rw-r--r--crypto/secp256k1/secp256.go14
-rw-r--r--crypto/secp256k1/secp256_test.go5
-rw-r--r--crypto/signature_cgo.go4
-rw-r--r--internal/ethapi/api.go8
-rw-r--r--light/state_object.go2
-rw-r--r--light/txpool.go2
-rw-r--r--swarm/services/swap/swap/swap.go5
-rw-r--r--tests/util.go2
30 files changed, 104 insertions, 114 deletions
diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go
index 5e2fcbae7..e21ffe1f8 100644
--- a/accounts/abi/bind/backends/simulated.go
+++ b/accounts/abi/bind/backends/simulated.go
@@ -237,7 +237,7 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM
if call.GasPrice == nil {
call.GasPrice = big.NewInt(1)
}
- if call.Gas == nil || call.Gas.BitLen() == 0 {
+ if call.Gas == nil || call.Gas.Sign() == 0 {
call.Gas = big.NewInt(50000000)
}
if call.Value == nil {
diff --git a/accounts/abi/numbers.go b/accounts/abi/numbers.go
index 36fb6705e..10afa6511 100644
--- a/accounts/abi/numbers.go
+++ b/accounts/abi/numbers.go
@@ -59,7 +59,7 @@ var (
// U256 converts a big Int into a 256bit EVM number.
func U256(n *big.Int) []byte {
- return common.LeftPadBytes(math.U256(n).Bytes(), 32)
+ return math.PaddedBigBytes(math.U256(n), 32)
}
// packNum packs the given number (using the reflect value) and will cast it to appropriate number representation
diff --git a/accounts/abi/packing.go b/accounts/abi/packing.go
index 5054dcf13..1d7f85e2b 100644
--- a/accounts/abi/packing.go
+++ b/accounts/abi/packing.go
@@ -20,6 +20,7 @@ import (
"reflect"
"github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/common/math"
)
// packBytesSlice packs the given bytes as [L, V] as the canonical representation
@@ -45,9 +46,9 @@ func packElement(t Type, reflectValue reflect.Value) []byte {
return common.LeftPadBytes(reflectValue.Bytes(), 32)
case BoolTy:
if reflectValue.Bool() {
- return common.LeftPadBytes(common.Big1.Bytes(), 32)
+ return math.PaddedBigBytes(common.Big1, 32)
} else {
- return common.LeftPadBytes(common.Big0.Bytes(), 32)
+ return math.PaddedBigBytes(common.Big0, 32)
}
case BytesTy:
if reflectValue.Kind() == reflect.Array {
diff --git a/accounts/keystore/keystore_passphrase.go b/accounts/keystore/keystore_passphrase.go
index 8ef510fcf..2eae25841 100644
--- a/accounts/keystore/keystore_passphrase.go
+++ b/accounts/keystore/keystore_passphrase.go
@@ -36,6 +36,7 @@ import (
"path/filepath"
"github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/crypto/randentropy"
"github.com/pborman/uuid"
@@ -115,8 +116,7 @@ func EncryptKey(key *Key, auth string, scryptN, scryptP int) ([]byte, error) {
return nil, err
}
encryptKey := derivedKey[:16]
- keyBytes0 := crypto.FromECDSA(key.PrivateKey)
- keyBytes := common.LeftPadBytes(keyBytes0, 32)
+ keyBytes := math.PaddedBigBytes(key.PrivateKey.D, 32)
iv := randentropy.GetEntropyCSPRNG(aes.BlockSize) // 16
cipherText, err := aesCTRXOR(encryptKey, keyBytes, iv)
diff --git a/accounts/usbwallet/ledger_wallet.go b/accounts/usbwallet/ledger_wallet.go
index 37e04e598..99d0b21d1 100644
--- a/accounts/usbwallet/ledger_wallet.go
+++ b/accounts/usbwallet/ledger_wallet.go
@@ -416,7 +416,7 @@ func (w *ledgerWallet) selfDerive() {
break
}
// If the next account is empty, stop self-derivation, but add it nonetheless
- if balance.BitLen() == 0 && nonce == 0 {
+ if balance.Sign() == 0 && nonce == 0 {
empty = true
}
// We've just self-derived a new account, start tracking it locally
diff --git a/common/math/big.go b/common/math/big.go
index c0508c102..704ca40a9 100644
--- a/common/math/big.go
+++ b/common/math/big.go
@@ -28,6 +28,13 @@ var (
MaxBig256 = new(big.Int).Set(tt256m1)
)
+const (
+ // number of bits in a big.Word
+ wordBits = 32 << (uint64(^big.Word(0)) >> 63)
+ // number of bytes in a big.Word
+ wordBytes = wordBits / 8
+)
+
// ParseBig256 parses s as a 256 bit integer in decimal or hexadecimal syntax.
// Leading zeros are accepted. The empty string parses as zero.
func ParseBig256(s string) (*big.Int, bool) {
@@ -91,12 +98,25 @@ func FirstBitSet(v *big.Int) int {
// PaddedBigBytes encodes a big integer as a big-endian byte slice. The length
// of the slice is at least n bytes.
func PaddedBigBytes(bigint *big.Int, n int) []byte {
- bytes := bigint.Bytes()
- if len(bytes) >= n {
- return bytes
+ if bigint.BitLen()/8 >= n {
+ return bigint.Bytes()
}
ret := make([]byte, n)
- return append(ret[:len(ret)-len(bytes)], bytes...)
+ ReadBits(bigint, ret)
+ return ret
+}
+
+// ReadBits encodes the absolute value of bigint as big-endian bytes. Callers must ensure
+// that buf has enough space. If buf is too short the result will be incomplete.
+func ReadBits(bigint *big.Int, buf []byte) {
+ i := len(buf)
+ for _, d := range bigint.Bits() {
+ for j := 0; j < wordBytes && i > 0; j++ {
+ i--
+ buf[i] = byte(d)
+ d >>= 8
+ }
+ }
}
// U256 encodes as a 256 bit two's complement number. This operation is destructive.
@@ -119,9 +139,6 @@ func S256(x *big.Int) *big.Int {
}
}
-// wordSize is the size number of bits in a big.Word.
-const wordSize = 32 << (uint64(^big.Word(0)) >> 63)
-
// Exp implements exponentiation by squaring.
// Exp returns a newly-allocated big integer and does not change
// base or exponent. The result is truncated to 256 bits.
@@ -131,7 +148,7 @@ func Exp(base, exponent *big.Int) *big.Int {
result := big.NewInt(1)
for _, word := range exponent.Bits() {
- for i := 0; i < wordSize; i++ {
+ for i := 0; i < wordBits; i++ {
if word&1 == 1 {
U256(result.Mul(result, base))
}
diff --git a/common/math/big_test.go b/common/math/big_test.go
index a0f48a8eb..6eb13f4f1 100644
--- a/common/math/big_test.go
+++ b/common/math/big_test.go
@@ -18,6 +18,7 @@ package math
import (
"bytes"
+ "encoding/hex"
"math/big"
"testing"
)
@@ -131,6 +132,28 @@ func TestPaddedBigBytes(t *testing.T) {
}
}
+func BenchmarkPaddedBigBytes(b *testing.B) {
+ bigint := MustParseBig256("123456789123456789123456789123456789")
+ for i := 0; i < b.N; i++ {
+ PaddedBigBytes(bigint, 32)
+ }
+}
+
+func TestReadBits(t *testing.T) {
+ check := func(input string) {
+ want, _ := hex.DecodeString(input)
+ int, _ := new(big.Int).SetString(input, 16)
+ buf := make([]byte, len(want))
+ ReadBits(int, buf)
+ if !bytes.Equal(buf, want) {
+ t.Errorf("have: %x\nwant: %x", buf, want)
+ }
+ }
+ check("000000000000000000000000000000000000000000000000000000FEFCF3F8F0")
+ check("0000000000012345000000000000000000000000000000000000FEFCF3F8F0")
+ check("18F8F8F1000111000110011100222004330052300000000000000000FEFCF3F8F0")
+}
+
func TestU256(t *testing.T) {
tests := []struct{ x, y *big.Int }{
{x: big.NewInt(0), y: big.NewInt(0)},
diff --git a/contracts/chequebook/cheque.go b/contracts/chequebook/cheque.go
index 9a2a5a2a6..bae6f3393 100644
--- a/contracts/chequebook/cheque.go
+++ b/contracts/chequebook/cheque.go
@@ -247,7 +247,7 @@ func (self *Chequebook) Issue(beneficiary common.Address, amount *big.Int) (ch *
defer self.lock.Unlock()
self.lock.Lock()
- if amount.Cmp(common.Big0) <= 0 {
+ if amount.Sign() <= 0 {
return nil, fmt.Errorf("amount must be greater than zero (%v)", amount)
}
if self.balance.Cmp(amount) < 0 {
@@ -515,7 +515,7 @@ func (self *Inbox) autoCash(cashInterval time.Duration) {
self.quit = nil
}
// if maxUncashed is set to 0, then autocash on receipt
- if cashInterval == time.Duration(0) || self.maxUncashed != nil && self.maxUncashed.Cmp(common.Big0) == 0 {
+ if cashInterval == time.Duration(0) || self.maxUncashed != nil && self.maxUncashed.Sign() == 0 {
return
}
@@ -597,7 +597,7 @@ func (self *Cheque) Verify(signerKey *ecdsa.PublicKey, contract, beneficiary com
amount := new(big.Int).Set(self.Amount)
if sum != nil {
amount.Sub(amount, sum)
- if amount.Cmp(common.Big0) <= 0 {
+ if amount.Sign() <= 0 {
return nil, fmt.Errorf("incorrect amount: %v <= 0", amount)
}
}
diff --git a/contracts/chequebook/cheque_test.go b/contracts/chequebook/cheque_test.go
index 85d923109..4029fd549 100644
--- a/contracts/chequebook/cheque_test.go
+++ b/contracts/chequebook/cheque_test.go
@@ -88,7 +88,7 @@ func TestIssueAndReceive(t *testing.T) {
t.Fatalf("expected no error, got %v", err)
}
- if chbook.Balance().Cmp(common.Big0) != 0 {
+ if chbook.Balance().Sign() != 0 {
t.Errorf("expected: %v, got %v", "0", chbook.Balance())
}
diff --git a/core/headerchain.go b/core/headerchain.go
index a0550a428..046275933 100644
--- a/core/headerchain.go
+++ b/core/headerchain.go
@@ -359,7 +359,7 @@ func (hc *HeaderChain) GetBlockHashesFromHash(hash common.Hash, max uint64) []co
break
}
chain = append(chain, next)
- if header.Number.Cmp(common.Big0) == 0 {
+ if header.Number.Sign() == 0 {
break
}
}
diff --git a/core/state/state_object.go b/core/state/state_object.go
index ebb103806..17726dd0c 100644
--- a/core/state/state_object.go
+++ b/core/state/state_object.go
@@ -93,7 +93,7 @@ type stateObject struct {
// empty returns whether the account is considered empty.
func (s *stateObject) empty() bool {
- return s.data.Nonce == 0 && s.data.Balance.BitLen() == 0 && bytes.Equal(s.data.CodeHash, emptyCodeHash)
+ return s.data.Nonce == 0 && s.data.Balance.Sign() == 0 && bytes.Equal(s.data.CodeHash, emptyCodeHash)
}
// Account is the Ethereum consensus representation of accounts.
@@ -243,7 +243,7 @@ func (self *stateObject) CommitTrie(db trie.Database, dbw trie.DatabaseWriter) e
func (c *stateObject) AddBalance(amount *big.Int) {
// EIP158: We must check emptiness for the objects such that the account
// clearing (0,0,0 objects) can take effect.
- if amount.Cmp(common.Big0) == 0 {
+ if amount.Sign() == 0 {
if c.empty() {
c.touch()
}
@@ -260,7 +260,7 @@ func (c *stateObject) AddBalance(amount *big.Int) {
// SubBalance removes amount from c's balance.
// It is used to remove funds from the origin account of a transfer.
func (c *stateObject) SubBalance(amount *big.Int) {
- if amount.Cmp(common.Big0) == 0 {
+ if amount.Sign() == 0 {
return
}
c.SetBalance(new(big.Int).Sub(c.Balance(), amount))
diff --git a/core/tx_pool.go b/core/tx_pool.go
index b0a8eea0f..e8d93d20e 100644
--- a/core/tx_pool.go
+++ b/core/tx_pool.go
@@ -299,7 +299,7 @@ func (pool *TxPool) validateTx(tx *types.Transaction) error {
// Transactions can't be negative. This may never happen
// using RLP decoded transactions but may occur if you create
// a transaction using the RPC for example.
- if tx.Value().Cmp(common.Big0) < 0 {
+ if tx.Value().Sign() < 0 {
return ErrNegativeValue
}
diff --git a/core/types/transaction.go b/core/types/transaction.go
index 9382acb70..ab0bba4dc 100644
--- a/core/types/transaction.go
+++ b/core/types/transaction.go
@@ -42,7 +42,7 @@ var (
// deriveSigner makes a *best* guess about which signer to use.
func deriveSigner(V *big.Int) Signer {
- if V.BitLen() > 0 && isProtectedV(V) {
+ if V.Sign() != 0 && isProtectedV(V) {
return EIP155Signer{chainId: deriveChainId(V)}
} else {
return HomesteadSigner{}
diff --git a/core/types/transaction_signing.go b/core/types/transaction_signing.go
index 7d7b63e9f..e7eb7c5f0 100644
--- a/core/types/transaction_signing.go
+++ b/core/types/transaction_signing.go
@@ -167,7 +167,7 @@ func (s EIP155Signer) WithSignature(tx *Transaction, sig []byte) (*Transaction,
cpy.data.R = new(big.Int).SetBytes(sig[:32])
cpy.data.S = new(big.Int).SetBytes(sig[32:64])
cpy.data.V = new(big.Int).SetBytes([]byte{sig[64]})
- if s.chainId.BitLen() > 0 {
+ if s.chainId.Sign() != 0 {
cpy.data.V = big.NewInt(int64(sig[64] + 35))
cpy.data.V.Add(cpy.data.V, s.chainIdMul)
}
diff --git a/core/types/transaction_signing_test.go b/core/types/transaction_signing_test.go
index 3216fcfad..7f799fb10 100644
--- a/core/types/transaction_signing_test.go
+++ b/core/types/transaction_signing_test.go
@@ -71,7 +71,7 @@ func TestEIP155ChainId(t *testing.T) {
t.Error("didn't expect tx to be protected")
}
- if tx.ChainId().BitLen() > 0 {
+ if tx.ChainId().Sign() != 0 {
t.Error("expected chain id to be 0 got", tx.ChainId())
}
}
diff --git a/core/vm/common.go b/core/vm/common.go
index ef40c4a95..779cee006 100644
--- a/core/vm/common.go
+++ b/core/vm/common.go
@@ -25,7 +25,7 @@ import (
// calculates the memory size required for a step
func calcMemSize(off, l *big.Int) *big.Int {
- if l.Cmp(common.Big0) == 0 {
+ if l.Sign() == 0 {
return common.Big0
}
diff --git a/core/vm/evm.go b/core/vm/evm.go
index d1fac6c10..71efcfa45 100644
--- a/core/vm/evm.go
+++ b/core/vm/evm.go
@@ -120,7 +120,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
snapshot = evm.StateDB.Snapshot()
)
if !evm.StateDB.Exist(addr) {
- if PrecompiledContracts[addr] == nil && evm.ChainConfig().IsEIP158(evm.BlockNumber) && value.BitLen() == 0 {
+ if PrecompiledContracts[addr] == nil && evm.ChainConfig().IsEIP158(evm.BlockNumber) && value.Sign() == 0 {
return nil, gas, nil
}
diff --git a/core/vm/gas_table.go b/core/vm/gas_table.go
index fba1eb066..f1c62df8e 100644
--- a/core/vm/gas_table.go
+++ b/core/vm/gas_table.go
@@ -273,7 +273,7 @@ func gasExp(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem
func gasCall(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
var (
gas = gt.Calls
- transfersValue = stack.Back(2).BitLen() > 0
+ transfersValue = stack.Back(2).Sign() != 0
address = common.BigToAddress(stack.Back(1))
eip158 = evm.ChainConfig().IsEIP158(evm.BlockNumber)
)
@@ -316,7 +316,7 @@ func gasCall(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem
func gasCallCode(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
gas := gt.Calls
- if stack.Back(2).BitLen() > 0 {
+ if stack.Back(2).Sign() != 0 {
gas += params.CallValueTransferGas
}
memoryGas, err := memoryGasCost(mem, memorySize)
@@ -362,7 +362,7 @@ func gasSuicide(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack,
if eip158 {
// if empty and transfers value
- if evm.StateDB.Empty(address) && evm.StateDB.GetBalance(contract.Address()).BitLen() > 0 {
+ if evm.StateDB.Empty(address) && evm.StateDB.GetBalance(contract.Address()).Sign() != 0 {
gas += gt.CreateBySuicide
}
} else if !evm.StateDB.Exist(address) {
diff --git a/core/vm/instructions.go b/core/vm/instructions.go
index 8b7bcc4d6..bfc0a668e 100644
--- a/core/vm/instructions.go
+++ b/core/vm/instructions.go
@@ -58,7 +58,7 @@ func opMul(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stac
func opDiv(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
x, y := stack.pop(), stack.pop()
- if y.Cmp(common.Big0) != 0 {
+ if y.Sign() != 0 {
stack.push(math.U256(x.Div(x, y)))
} else {
stack.push(new(big.Int))
@@ -71,12 +71,12 @@ func opDiv(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stac
func opSdiv(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
x, y := math.S256(stack.pop()), math.S256(stack.pop())
- if y.Cmp(common.Big0) == 0 {
+ if y.Sign() == 0 {
stack.push(new(big.Int))
return nil, nil
} else {
n := new(big.Int)
- if evm.interpreter.intPool.get().Mul(x, y).Cmp(common.Big0) < 0 {
+ if evm.interpreter.intPool.get().Mul(x, y).Sign() < 0 {
n.SetInt64(-1)
} else {
n.SetInt64(1)
@@ -93,7 +93,7 @@ func opSdiv(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Sta
func opMod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
x, y := stack.pop(), stack.pop()
- if y.Cmp(common.Big0) == 0 {
+ if y.Sign() == 0 {
stack.push(new(big.Int))
} else {
stack.push(math.U256(x.Mod(x, y)))
@@ -105,11 +105,11 @@ func opMod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stac
func opSmod(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
x, y := math.S256(stack.pop()), math.S256(stack.pop())
- if y.Cmp(common.Big0) == 0 {
+ if y.Sign() == 0 {
stack.push(new(big.Int))
} else {
n := new(big.Int)
- if x.Cmp(common.Big0) < 0 {
+ if x.Sign() < 0 {
n.SetInt64(-1)
} else {
n.SetInt64(1)
@@ -221,7 +221,7 @@ func opEq(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack
func opIszero(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
x := stack.pop()
- if x.Cmp(common.Big0) > 0 {
+ if x.Sign() > 0 {
stack.push(new(big.Int))
} else {
stack.push(evm.interpreter.intPool.get().SetUint64(1))
@@ -252,10 +252,11 @@ func opXor(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stac
evm.interpreter.intPool.put(y)
return nil, nil
}
+
func opByte(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
th, val := stack.pop(), stack.pop()
if th.Cmp(big.NewInt(32)) < 0 {
- byte := evm.interpreter.intPool.get().SetInt64(int64(common.LeftPadBytes(val.Bytes(), 32)[th.Int64()]))
+ byte := evm.interpreter.intPool.get().SetInt64(int64(math.PaddedBigBytes(val, 32)[th.Int64()]))
stack.push(byte)
} else {
stack.push(new(big.Int))
@@ -505,7 +506,7 @@ func opJump(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Sta
}
func opJumpi(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
pos, cond := stack.pop(), stack.pop()
- if cond.BitLen() > 0 {
+ if cond.Sign() != 0 {
if !contract.jumpdests.has(contract.CodeHash, contract.Code, pos) {
nop := contract.GetOp(pos.Uint64())
return nil, fmt.Errorf("invalid jump destination (%v) %v", nop, pos)
@@ -583,7 +584,7 @@ func opCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Sta
// Get the arguments from the memory
args := memory.Get(inOffset.Int64(), inSize.Int64())
- if value.BitLen() > 0 {
+ if value.Sign() != 0 {
gas += params.CallStipend
}
@@ -616,7 +617,7 @@ func opCallCode(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack
// Get the arguments from the memory
args := memory.Get(inOffset.Int64(), inSize.Int64())
- if value.BitLen() > 0 {
+ if value.Sign() != 0 {
gas += params.CallStipend
}
diff --git a/core/vm/logger.go b/core/vm/logger.go
index 3845b1073..102a215c7 100644
--- a/core/vm/logger.go
+++ b/core/vm/logger.go
@@ -23,6 +23,7 @@ import (
"unicode"
"github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/common/math"
)
type Storage map[common.Hash]common.Hash
@@ -180,7 +181,7 @@ func StdErrFormat(logs []StructLog) {
fmt.Fprintln(os.Stderr, "STACK =", len(log.Stack))
for i := len(log.Stack) - 1; i >= 0; i-- {
- fmt.Fprintf(os.Stderr, "%04d: %x\n", len(log.Stack)-i-1, common.LeftPadBytes(log.Stack[i].Bytes(), 32))
+ fmt.Fprintf(os.Stderr, "%04d: %x\n", len(log.Stack)-i-1, math.PaddedBigBytes(log.Stack[i], 32))
}
const maxMem = 10
diff --git a/crypto/secp256k1/curve.go b/crypto/secp256k1/curve.go
index 61cad5463..ec6d266ce 100644
--- a/crypto/secp256k1/curve.go
+++ b/crypto/secp256k1/curve.go
@@ -36,6 +36,8 @@ import (
"math/big"
"sync"
"unsafe"
+
+ "github.com/ethereum/go-ethereum/common/math"
)
/*
@@ -230,8 +232,8 @@ func (BitCurve *BitCurve) ScalarMult(Bx, By *big.Int, scalar []byte) (*big.Int,
// Do the multiplication in C, updating point.
point := make([]byte, 64)
- readBits(point[:32], Bx)
- readBits(point[32:], By)
+ math.ReadBits(Bx, point[:32])
+ math.ReadBits(By, point[32:])
pointPtr := (*C.uchar)(unsafe.Pointer(&point[0]))
scalarPtr := (*C.uchar)(unsafe.Pointer(&scalar[0]))
res := C.secp256k1_pubkey_scalar_mul(context, pointPtr, scalarPtr)
diff --git a/crypto/secp256k1/curve_test.go b/crypto/secp256k1/curve_test.go
deleted file mode 100644
index d915ee852..000000000
--- a/crypto/secp256k1/curve_test.go
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2015 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
-
-package secp256k1
-
-import (
- "bytes"
- "encoding/hex"
- "math/big"
- "testing"
-)
-
-func TestReadBits(t *testing.T) {
- check := func(input string) {
- want, _ := hex.DecodeString(input)
- int, _ := new(big.Int).SetString(input, 16)
- buf := make([]byte, len(want))
- readBits(buf, int)
- if !bytes.Equal(buf, want) {
- t.Errorf("have: %x\nwant: %x", buf, want)
- }
- }
- check("000000000000000000000000000000000000000000000000000000FEFCF3F8F0")
- check("0000000000012345000000000000000000000000000000000000FEFCF3F8F0")
- check("18F8F8F1000111000110011100222004330052300000000000000000FEFCF3F8F0")
-}
diff --git a/crypto/secp256k1/secp256.go b/crypto/secp256k1/secp256.go
index 1a152a670..0ffa04fe0 100644
--- a/crypto/secp256k1/secp256.go
+++ b/crypto/secp256k1/secp256.go
@@ -38,7 +38,6 @@ import "C"
import (
"errors"
- "math/big"
"unsafe"
)
@@ -129,16 +128,3 @@ func checkSignature(sig []byte) error {
}
return nil
}
-
-// reads num into buf as big-endian bytes.
-func readBits(buf []byte, num *big.Int) {
- const wordLen = int(unsafe.Sizeof(big.Word(0)))
- i := len(buf)
- for _, d := range num.Bits() {
- for j := 0; j < wordLen && i > 0; j++ {
- i--
- buf[i] = byte(d)
- d >>= 8
- }
- }
-}
diff --git a/crypto/secp256k1/secp256_test.go b/crypto/secp256k1/secp256_test.go
index 287ab512e..f6582ecd5 100644
--- a/crypto/secp256k1/secp256_test.go
+++ b/crypto/secp256k1/secp256_test.go
@@ -24,6 +24,7 @@ import (
"encoding/hex"
"testing"
+ "github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/crypto/randentropy"
)
@@ -35,9 +36,7 @@ func generateKeyPair() (pubkey, privkey []byte) {
panic(err)
}
pubkey = elliptic.Marshal(S256(), key.X, key.Y)
- privkey = make([]byte, 32)
- readBits(privkey, key.D)
- return pubkey, privkey
+ return pubkey, math.PaddedBigBytes(key.D, 32)
}
func randSig() []byte {
diff --git a/crypto/signature_cgo.go b/crypto/signature_cgo.go
index 5faa6061f..d1485de08 100644
--- a/crypto/signature_cgo.go
+++ b/crypto/signature_cgo.go
@@ -23,7 +23,7 @@ import (
"crypto/elliptic"
"fmt"
- "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/crypto/secp256k1"
)
@@ -53,7 +53,7 @@ func Sign(hash []byte, prv *ecdsa.PrivateKey) (sig []byte, err error) {
if len(hash) != 32 {
return nil, fmt.Errorf("hash is required to be exactly 32 bytes (%d)", len(hash))
}
- seckey := common.LeftPadBytes(prv.D.Bytes(), prv.Params().BitSize/8)
+ seckey := math.PaddedBigBytes(prv.D, prv.Params().BitSize/8)
defer zeroBytes(seckey)
return secp256k1.Sign(hash, seckey)
}
diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go
index 08e9c7370..5b7115e44 100644
--- a/internal/ethapi/api.go
+++ b/internal/ethapi/api.go
@@ -596,10 +596,10 @@ func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr
}
// Set default gas & gas price if none were set
gas, gasPrice := args.Gas.ToInt(), args.GasPrice.ToInt()
- if gas.BitLen() == 0 {
+ if gas.Sign() == 0 {
gas = big.NewInt(50000000)
}
- if gasPrice.BitLen() == 0 {
+ if gasPrice.Sign() == 0 {
gasPrice = new(big.Int).SetUint64(defaultGasPrice)
}
@@ -653,7 +653,7 @@ func (s *PublicBlockChainAPI) Call(ctx context.Context, args CallArgs, blockNr r
func (s *PublicBlockChainAPI) EstimateGas(ctx context.Context, args CallArgs) (*hexutil.Big, error) {
// Binary search the gas requirement, as it may be higher than the amount used
var lo, hi uint64
- if (*big.Int)(&args.Gas).BitLen() > 0 {
+ if (*big.Int)(&args.Gas).Sign() != 0 {
hi = (*big.Int)(&args.Gas).Uint64()
} else {
// Retrieve the current pending block to act as the gas ceiling
@@ -720,7 +720,7 @@ func FormatLogs(structLogs []vm.StructLog) []StructLogRes {
}
for i, stackValue := range trace.Stack {
- formattedStructLogs[index].Stack[i] = fmt.Sprintf("%x", common.LeftPadBytes(stackValue.Bytes(), 32))
+ formattedStructLogs[index].Stack[i] = fmt.Sprintf("%x", math.PaddedBigBytes(stackValue, 32))
}
for i := 0; i+32 <= len(trace.Memory); i += 32 {
diff --git a/light/state_object.go b/light/state_object.go
index 03d4868cd..d023270d5 100644
--- a/light/state_object.go
+++ b/light/state_object.go
@@ -202,7 +202,7 @@ func (self *StateObject) Copy() *StateObject {
// empty returns whether the account is considered empty.
func (self *StateObject) empty() bool {
- return self.nonce == 0 && self.balance.BitLen() == 0 && bytes.Equal(self.codeHash, emptyCodeHash)
+ return self.nonce == 0 && self.balance.Sign() == 0 && bytes.Equal(self.codeHash, emptyCodeHash)
}
// Balance returns the account balance
diff --git a/light/txpool.go b/light/txpool.go
index 365f02d25..ecd6cfa26 100644
--- a/light/txpool.go
+++ b/light/txpool.go
@@ -365,7 +365,7 @@ func (pool *TxPool) validateTx(ctx context.Context, tx *types.Transaction) error
// Transactions can't be negative. This may never happen
// using RLP decoded transactions but may occur if you create
// a transaction using the RPC for example.
- if tx.Value().Cmp(common.Big0) < 0 {
+ if tx.Value().Sign() < 0 {
return core.ErrNegativeValue
}
diff --git a/swarm/services/swap/swap/swap.go b/swarm/services/swap/swap/swap.go
index d04194960..a78f1f0e2 100644
--- a/swarm/services/swap/swap/swap.go
+++ b/swarm/services/swap/swap/swap.go
@@ -22,7 +22,6 @@ import (
"sync"
"time"
- "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
)
@@ -120,11 +119,11 @@ func (self *Swap) SetRemote(remote *Profile) {
self.lock.Lock()
self.remote = remote
- if self.Sells && (remote.BuyAt.Cmp(common.Big0) <= 0 || self.local.SellAt.Cmp(common.Big0) <= 0 || remote.BuyAt.Cmp(self.local.SellAt) < 0) {
+ if self.Sells && (remote.BuyAt.Sign() <= 0 || self.local.SellAt.Sign() <= 0 || remote.BuyAt.Cmp(self.local.SellAt) < 0) {
self.Out.Stop()
self.Sells = false
}
- if self.Buys && (remote.SellAt.Cmp(common.Big0) <= 0 || self.local.BuyAt.Cmp(common.Big0) <= 0 || self.local.BuyAt.Cmp(self.remote.SellAt) < 0) {
+ if self.Buys && (remote.SellAt.Sign() <= 0 || self.local.BuyAt.Sign() <= 0 || self.local.BuyAt.Cmp(self.remote.SellAt) < 0) {
self.In.Stop()
self.Buys = false
}
diff --git a/tests/util.go b/tests/util.go
index 78bb06d06..7a08e5ed8 100644
--- a/tests/util.go
+++ b/tests/util.go
@@ -71,7 +71,7 @@ func checkLogs(tlog []Log, logs []*types.Log) error {
}
}
}
- genBloom := common.LeftPadBytes(types.LogsBloom([]*types.Log{logs[i]}).Bytes(), 256)
+ genBloom := math.PaddedBigBytes(types.LogsBloom([]*types.Log{logs[i]}), 256)
if !bytes.Equal(genBloom, common.Hex2Bytes(log.BloomF)) {
return fmt.Errorf("bloom mismatch")