diff --git a/core/types/transaction.go b/core/types/transaction.go index 6af960b8c3..6257580733 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -52,6 +52,26 @@ const ( SetCodeTxType = 0x04 ) +type TxTypeBitVec [(SetCodeTxType + 1 + 7) / 8]byte + +func (v *TxTypeBitVec) Set(txType byte) { + if txType >= byte(len(v)*8) { + panic("tx type out of range") + } + v[txType/8] |= 1 << (txType % 8) +} + +func (v *TxTypeBitVec) Has(txType byte) bool { + if txType >= byte(len(v)*8) { + return false + } + return v[txType/8]&(1<<(txType%8)) != 0 +} + +func (v *TxTypeBitVec) Equals(o *TxTypeBitVec) bool { + return *v == *o +} + // Transaction is an Ethereum transaction. type Transaction struct { inner TxData // Consensus contents of a transaction diff --git a/core/types/transaction_signing.go b/core/types/transaction_signing.go index 01aa67c6ba..6c56c588d8 100644 --- a/core/types/transaction_signing.go +++ b/core/types/transaction_signing.go @@ -20,7 +20,6 @@ import ( "crypto/ecdsa" "errors" "fmt" - "maps" "math/big" "github.com/ethereum/go-ethereum/common" @@ -183,9 +182,9 @@ 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{} - chainID *big.Int - legacy Signer + txTypeBitVec TxTypeBitVec + chainID *big.Int + legacy Signer } func newModernSigner(chainID *big.Int, fork forks.Fork) Signer { @@ -194,7 +193,6 @@ func newModernSigner(chainID *big.Int, fork forks.Fork) Signer { } s := &modernSigner{ chainID: chainID, - txtypes: make(map[byte]struct{}, 4), } // configure legacy signer switch { @@ -205,19 +203,19 @@ func newModernSigner(chainID *big.Int, fork forks.Fork) Signer { default: s.legacy = FrontierSigner{} } - s.txtypes[LegacyTxType] = struct{}{} + s.txTypeBitVec.Set(LegacyTxType) // configure tx types if fork >= forks.Berlin { - s.txtypes[AccessListTxType] = struct{}{} + s.txTypeBitVec.Set(AccessListTxType) } if fork >= forks.London { - s.txtypes[DynamicFeeTxType] = struct{}{} + s.txTypeBitVec.Set(DynamicFeeTxType) } if fork >= forks.Cancun { - s.txtypes[BlobTxType] = struct{}{} + s.txTypeBitVec.Set(BlobTxType) } if fork >= forks.Prague { - s.txtypes[SetCodeTxType] = struct{}{} + s.txTypeBitVec.Set(SetCodeTxType) } return s } @@ -228,7 +226,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.txTypeBitVec.Equals(&other.txTypeBitVec) && s.legacy.Equal(other.legacy) } func (s *modernSigner) Hash(tx *Transaction) common.Hash { @@ -236,8 +234,7 @@ func (s *modernSigner) Hash(tx *Transaction) common.Hash { } func (s *modernSigner) supportsType(txtype byte) bool { - _, ok := s.txtypes[txtype] - return ok + return s.txTypeBitVec.Has(txtype) } func (s *modernSigner) Sender(tx *Transaction) (common.Address, error) {