add pragueSigner

This commit is contained in:
Hadrien Croubois 2024-03-07 15:05:04 +01:00
parent 947a5383ef
commit 0efbc0b794

View file

@ -40,6 +40,8 @@ type sigCache struct {
func MakeSigner(config *params.ChainConfig, blockNumber *big.Int, blockTime uint64) Signer { func MakeSigner(config *params.ChainConfig, blockNumber *big.Int, blockTime uint64) Signer {
var signer Signer var signer Signer
switch { switch {
case config.IsPrague(blockNumber, blockTime):
signer = NewPragueSigner(config.ChainID)
case config.IsCancun(blockNumber, blockTime): case config.IsCancun(blockNumber, blockTime):
signer = NewCancunSigner(config.ChainID) signer = NewCancunSigner(config.ChainID)
case config.IsLondon(blockNumber): case config.IsLondon(blockNumber):
@ -65,6 +67,9 @@ func MakeSigner(config *params.ChainConfig, blockNumber *big.Int, blockTime uint
// have the current block number available, use MakeSigner instead. // have the current block number available, use MakeSigner instead.
func LatestSigner(config *params.ChainConfig) Signer { func LatestSigner(config *params.ChainConfig) Signer {
if config.ChainID != nil { if config.ChainID != nil {
if config.PragueTime != nil {
return NewPragueSigner(config.ChainID)
}
if config.CancunTime != nil { if config.CancunTime != nil {
return NewCancunSigner(config.ChainID) return NewCancunSigner(config.ChainID)
} }
@ -92,7 +97,7 @@ func LatestSignerForChainID(chainID *big.Int) Signer {
if chainID == nil { if chainID == nil {
return HomesteadSigner{} return HomesteadSigner{}
} }
return NewCancunSigner(chainID) return NewPragueSigner(chainID)
} }
// SignTx signs the transaction using the given signer and private key. // SignTx signs the transaction using the given signer and private key.
@ -169,6 +174,73 @@ type Signer interface {
Equal(Signer) bool Equal(Signer) bool
} }
type pragueSigner struct{ cancunSigner }
// NewPragueSigner returns a signer that accepts
// - EIP-5806 delegate transactions
// - EIP-4844 blob transactions
// - EIP-1559 dynamic fee transactions
// - EIP-2930 access list transactions,
// - EIP-155 replay protected transactions, and
// - legacy Homestead transactions.
func NewPragueSigner(chainId *big.Int) Signer {
return pragueSigner{cancunSigner{londonSigner{eip2930Signer{NewEIP155Signer(chainId)}}}}
}
func (s pragueSigner) Sender(tx *Transaction) (common.Address, error) {
if tx.Type() != DelegateTxType {
return s.cancunSigner.Sender(tx)
}
V, R, S := tx.RawSignatureValues()
// Delegate 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))
if tx.ChainId().Cmp(s.chainId) != 0 {
return common.Address{}, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, tx.ChainId(), s.chainId)
}
return recoverPlain(s.Hash(tx), R, S, V, true)
}
func (s pragueSigner) Equal(s2 Signer) bool {
x, ok := s2.(cancunSigner)
return ok && x.chainId.Cmp(s.chainId) == 0
}
func (s pragueSigner) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big.Int, err error) {
txdata, ok := tx.inner.(*DelegateTx)
if !ok {
return s.cancunSigner.SignatureValues(tx, sig)
}
// Check that chain ID of tx matches the signer. We also accept ID zero here,
// because it indicates that the chain ID was not specified in the tx.
if txdata.ChainID.Sign() != 0 && txdata.ChainID.Cmp(s.chainId) != 0 {
return nil, nil, nil, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, txdata.ChainID, s.chainId)
}
R, S, _ = decodeSignature(sig)
V = big.NewInt(int64(sig[64]))
return R, S, V, nil
}
// Hash returns the hash to be signed by the sender.
// It does not uniquely identify the transaction.
func (s pragueSigner) Hash(tx *Transaction) common.Hash {
if tx.Type() != DelegateTxType {
return s.cancunSigner.Hash(tx)
}
return prefixedRlpHash(
tx.Type(),
[]interface{}{
s.chainId,
tx.Nonce(),
tx.GasTipCap(),
tx.GasFeeCap(),
tx.Gas(),
tx.To(),
tx.Data(),
tx.AccessList(),
})
}
type cancunSigner struct{ londonSigner } type cancunSigner struct{ londonSigner }
// NewCancunSigner returns a signer that accepts // NewCancunSigner returns a signer that accepts