From 13f233c0e46c446875e5f1e93c694e57e8b13371 Mon Sep 17 00:00:00 2001 From: Emmanuel T Odeke Date: Sat, 28 Oct 2023 06:14:42 -0700 Subject: [PATCH] all: replace *2, /2 by Lsh, Rsh; reuse big.Int from constants This change aims to make more efficient usage of math/big.Int's operations with constant values such as: * Multiplying by 2^N: .Lsh(v, N) instead of .Mul(v, big.NewInt(2^N)) * Dividing by 2: .Rsh(v, 1) instead of .Div(v, 2) * Comparing against 0: .Sign() == 1 instead of .Cmp(big.NewInt(0)) * Adding constant derived values: extracting them into reusable globals --- consensus/ethash/consensus.go | 2 +- core/types/block_test.go | 1 + core/types/bloom9_test.go | 4 ++++ core/types/transaction_signing.go | 18 +++++++++++------- crypto/bn256/cloudflare/lattice.go | 4 +++- crypto/secp256k1/curve.go | 14 +++++++------- signer/fourbyte/validation.go | 2 +- 7 files changed, 28 insertions(+), 17 deletions(-) diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go index 8eb9863da1..1405c86ffc 100644 --- a/consensus/ethash/consensus.go +++ b/consensus/ethash/consensus.go @@ -260,7 +260,7 @@ func (ethash *Ethash) verifyHeader(chain consensus.ChainHeaderReader, header, pa return err } // Verify that the block number is parent's +1 - if diff := new(big.Int).Sub(header.Number, parent.Number); diff.Cmp(big.NewInt(1)) != 0 { + if diff := new(big.Int).Sub(header.Number, parent.Number); diff.Cmp(big1) != 0 { return consensus.ErrInvalidNumber } if chain.Config().IsShanghai(header.Number, header.Time) { diff --git a/core/types/block_test.go b/core/types/block_test.go index cf0b1dd85c..7d2d83a4e5 100644 --- a/core/types/block_test.go +++ b/core/types/block_test.go @@ -206,6 +206,7 @@ var benchBuffer = bytes.NewBuffer(make([]byte, 0, 32000)) func BenchmarkEncodeBlock(b *testing.B) { block := makeBenchBlock() + b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { diff --git a/core/types/bloom9_test.go b/core/types/bloom9_test.go index d3178d112e..0d236b0b2f 100644 --- a/core/types/bloom9_test.go +++ b/core/types/bloom9_test.go @@ -78,6 +78,8 @@ func TestBloomExtensively(t *testing.T) { func BenchmarkBloom9(b *testing.B) { test := []byte("testestestest") + b.ReportAllocs() + for i := 0; i < b.N; i++ { Bloom9(test) } @@ -86,6 +88,8 @@ func BenchmarkBloom9(b *testing.B) { func BenchmarkBloom9Lookup(b *testing.B) { toTest := []byte("testtest") bloom := new(Bloom) + b.ReportAllocs() + for i := 0; i < b.N; i++ { bloom.Test(toTest) } diff --git a/core/types/transaction_signing.go b/core/types/transaction_signing.go index 9e26642f75..27b6cb6cbd 100644 --- a/core/types/transaction_signing.go +++ b/core/types/transaction_signing.go @@ -194,7 +194,7 @@ func (s cancunSigner) Sender(tx *Transaction) (common.Address, error) { V, R, S := tx.RawSignatureValues() // Blob txs are defined to use 0 and 1 as their recovery // id, add 27 to become equivalent to unprotected Homestead signatures. - V = new(big.Int).Add(V, big.NewInt(27)) + V = new(big.Int).Add(V, big27) if tx.ChainId().Cmp(s.chainId) != 0 { return common.Address{}, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, tx.ChainId(), s.chainId) } @@ -262,7 +262,7 @@ func (s londonSigner) Sender(tx *Transaction) (common.Address, error) { V, R, S := tx.RawSignatureValues() // DynamicFee txs are defined to use 0 and 1 as their recovery // id, add 27 to become equivalent to unprotected Homestead signatures. - V = new(big.Int).Add(V, big.NewInt(27)) + V = new(big.Int).Add(V, big27) if tx.ChainId().Cmp(s.chainId) != 0 { return common.Address{}, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, tx.ChainId(), s.chainId) } @@ -335,7 +335,7 @@ func (s eip2930Signer) Sender(tx *Transaction) (common.Address, error) { case AccessListTxType: // AL txs are defined to use 0 and 1 as their recovery // id, add 27 to become equivalent to unprotected Homestead signatures. - V = new(big.Int).Add(V, big.NewInt(27)) + V = new(big.Int).Add(V, big27) default: return common.Address{}, ErrTxTypeNotSupported } @@ -403,7 +403,7 @@ func NewEIP155Signer(chainId *big.Int) EIP155Signer { } return EIP155Signer{ chainId: chainId, - chainIdMul: new(big.Int).Mul(chainId, big.NewInt(2)), + chainIdMul: new(big.Int).Lsh(chainId, 1), // chainId*2 } } @@ -416,7 +416,11 @@ func (s EIP155Signer) Equal(s2 Signer) bool { return ok && eip155.chainId.Cmp(s.chainId) == 0 } -var big8 = big.NewInt(8) +var ( + big8 = big.NewInt(8) + big27 = big.NewInt(27) + big35 = big.NewInt(35) +) func (s EIP155Signer) Sender(tx *Transaction) (common.Address, error) { if tx.Type() != LegacyTxType { @@ -579,6 +583,6 @@ func deriveChainId(v *big.Int) *big.Int { } return new(big.Int).SetUint64((v - 35) / 2) } - v = new(big.Int).Sub(v, big.NewInt(35)) - return v.Div(v, big.NewInt(2)) + v = new(big.Int).Sub(v, big35) + return v.Rsh(v, 1) // v/2 } diff --git a/crypto/bn256/cloudflare/lattice.go b/crypto/bn256/cloudflare/lattice.go index f9ace4d9fc..78613cf2e5 100644 --- a/crypto/bn256/cloudflare/lattice.go +++ b/crypto/bn256/cloudflare/lattice.go @@ -104,12 +104,14 @@ func (l *lattice) Multi(scalar *big.Int) []uint8 { return out } +var big1 = big.NewInt(1) + // round sets num to num/denom rounded to the nearest integer. func round(num, denom *big.Int) { r := new(big.Int) num.DivMod(num, denom, r) if r.Cmp(half) == 1 { - num.Add(num, big.NewInt(1)) + num.Add(num, big1) } } diff --git a/crypto/secp256k1/curve.go b/crypto/secp256k1/curve.go index 9b26ab2928..adb1853829 100644 --- a/crypto/secp256k1/curve.go +++ b/crypto/secp256k1/curve.go @@ -224,22 +224,22 @@ func (BitCurve *BitCurve) doubleJacobian(x, y, z *big.Int) (*big.Int, *big.Int, d.Mul(d, d) //(X1+B)² d.Sub(d, a) //(X1+B)²-A d.Sub(d, c) //(X1+B)²-A-C - d.Mul(d, big.NewInt(2)) //2*((X1+B)²-A-C) + d.Lsh(d, 1) //2*((X1+B)²-A-C) e := new(big.Int).Mul(big.NewInt(3), a) //3*A f := new(big.Int).Mul(e, e) //E² - x3 := new(big.Int).Mul(big.NewInt(2), d) //2*D - x3.Sub(f, x3) //F-2*D + x3 := new(big.Int).Lsh(d, 1) //2*D + x3.Sub(f, x3) //F-2*D x3.Mod(x3, BitCurve.P) - y3 := new(big.Int).Sub(d, x3) //D-X3 - y3.Mul(e, y3) //E*(D-X3) - y3.Sub(y3, new(big.Int).Mul(big.NewInt(8), c)) //E*(D-X3)-8*C + y3 := new(big.Int).Sub(d, x3) //D-X3 + y3.Mul(e, y3) //E*(D-X3) + y3.Sub(y3, new(big.Int).Lsh(c, 3)) //E*(D-X3)-8*C y3.Mod(y3, BitCurve.P) z3 := new(big.Int).Mul(y, z) //Y1*Z1 - z3.Mul(big.NewInt(2), z3) //3*Y1*Z1 + z3.Lsh(z3, 1) //3*Y1*Z1 z3.Mod(z3, BitCurve.P) return x3, y3, z3 diff --git a/signer/fourbyte/validation.go b/signer/fourbyte/validation.go index 58111e8e00..b6709afaa7 100644 --- a/signer/fourbyte/validation.go +++ b/signer/fourbyte/validation.go @@ -52,7 +52,7 @@ func (db *Database) ValidateTransaction(selector *string, tx *apitypes.SendTxArg // e.g. https://github.com/ethereum/go-ethereum/issues/16106. if len(data) == 0 { // Prevent sending ether into black hole (show stopper) - if tx.Value.ToInt().Cmp(big.NewInt(0)) > 0 { + if tx.Value.ToInt().Sign() == 1 { // Greater than 0 return nil, errors.New("transaction will create a contract with value but empty code") } // No value submitted at least, critically Warn, but don't blow up