mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-02-26 15:47:21 +00:00
core/types: optimize modernSigner.Equal (#32971)
Equal is called every time the transaction sender is accessed, even when the sender is cached, so it is worth optimizing. --------- Co-authored-by: Felix Lange <fjl@twurst.com>
This commit is contained in:
parent
447b5f7e19
commit
33dbd64a23
2 changed files with 34 additions and 11 deletions
|
|
@ -20,7 +20,6 @@ import (
|
|||
"crypto/ecdsa"
|
||||
"errors"
|
||||
"fmt"
|
||||
"maps"
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
|
|
@ -183,18 +182,31 @@ type Signer interface {
|
|||
// modernSigner is the signer implementation that handles non-legacy transaction types.
|
||||
// For legacy transactions, it defers to one of the legacy signers (frontier, homestead, eip155).
|
||||
type modernSigner struct {
|
||||
txtypes map[byte]struct{}
|
||||
txtypes txtypeSet
|
||||
chainID *big.Int
|
||||
legacy Signer
|
||||
}
|
||||
|
||||
// txtypeSet is a bitmap for transaction types.
|
||||
type txtypeSet [2]uint64
|
||||
|
||||
func (v *txtypeSet) set(txType byte) {
|
||||
v[txType/64] |= 1 << (txType % 64)
|
||||
}
|
||||
|
||||
func (v *txtypeSet) has(txType byte) bool {
|
||||
if txType >= byte(len(v)*64) {
|
||||
return false
|
||||
}
|
||||
return v[txType/64]&(1<<(txType%64)) != 0
|
||||
}
|
||||
|
||||
func newModernSigner(chainID *big.Int, fork forks.Fork) Signer {
|
||||
if chainID == nil || chainID.Sign() <= 0 {
|
||||
panic(fmt.Sprintf("invalid chainID %v", chainID))
|
||||
}
|
||||
s := &modernSigner{
|
||||
chainID: chainID,
|
||||
txtypes: make(map[byte]struct{}, 4),
|
||||
}
|
||||
// configure legacy signer
|
||||
switch {
|
||||
|
|
@ -205,19 +217,19 @@ func newModernSigner(chainID *big.Int, fork forks.Fork) Signer {
|
|||
default:
|
||||
s.legacy = FrontierSigner{}
|
||||
}
|
||||
s.txtypes[LegacyTxType] = struct{}{}
|
||||
s.txtypes.set(LegacyTxType)
|
||||
// configure tx types
|
||||
if fork >= forks.Berlin {
|
||||
s.txtypes[AccessListTxType] = struct{}{}
|
||||
s.txtypes.set(AccessListTxType)
|
||||
}
|
||||
if fork >= forks.London {
|
||||
s.txtypes[DynamicFeeTxType] = struct{}{}
|
||||
s.txtypes.set(DynamicFeeTxType)
|
||||
}
|
||||
if fork >= forks.Cancun {
|
||||
s.txtypes[BlobTxType] = struct{}{}
|
||||
s.txtypes.set(BlobTxType)
|
||||
}
|
||||
if fork >= forks.Prague {
|
||||
s.txtypes[SetCodeTxType] = struct{}{}
|
||||
s.txtypes.set(SetCodeTxType)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
|
@ -228,7 +240,7 @@ func (s *modernSigner) ChainID() *big.Int {
|
|||
|
||||
func (s *modernSigner) Equal(s2 Signer) bool {
|
||||
other, ok := s2.(*modernSigner)
|
||||
return ok && s.chainID.Cmp(other.chainID) == 0 && maps.Equal(s.txtypes, other.txtypes) && s.legacy.Equal(other.legacy)
|
||||
return ok && s.chainID.Cmp(other.chainID) == 0 && s.txtypes == other.txtypes && s.legacy.Equal(other.legacy)
|
||||
}
|
||||
|
||||
func (s *modernSigner) Hash(tx *Transaction) common.Hash {
|
||||
|
|
@ -236,8 +248,7 @@ func (s *modernSigner) Hash(tx *Transaction) common.Hash {
|
|||
}
|
||||
|
||||
func (s *modernSigner) supportsType(txtype byte) bool {
|
||||
_, ok := s.txtypes[txtype]
|
||||
return ok
|
||||
return s.txtypes.has(txtype)
|
||||
}
|
||||
|
||||
func (s *modernSigner) Sender(tx *Transaction) (common.Address, error) {
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"github.com/ethereum/go-ethereum/params/forks"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
)
|
||||
|
||||
|
|
@ -188,3 +189,14 @@ func createTestLegacyTxInner() *LegacyTx {
|
|||
Data: nil,
|
||||
}
|
||||
}
|
||||
|
||||
func Benchmark_modernSigner_Equal(b *testing.B) {
|
||||
signer1 := newModernSigner(big.NewInt(1), forks.Amsterdam)
|
||||
signer2 := newModernSigner(big.NewInt(1), forks.Amsterdam)
|
||||
|
||||
for b.Loop() {
|
||||
if !signer1.Equal(signer2) {
|
||||
b.Fatal("expected signers to be equal")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue