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
This commit is contained in:
Emmanuel T Odeke 2023-10-28 06:14:42 -07:00
parent 233db64cc1
commit 13f233c0e4
No known key found for this signature in database
GPG key ID: 410DDC670CF9BFD7
7 changed files with 28 additions and 17 deletions

View file

@ -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) {

View file

@ -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++ {

View file

@ -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)
}

View file

@ -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
}

View file

@ -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)
}
}

View file

@ -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

View file

@ -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