mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
add pragueSigner
This commit is contained in:
parent
947a5383ef
commit
0efbc0b794
1 changed files with 73 additions and 1 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue