@@ -21,13 +21,14 @@ import (
2121 "errors"
2222 "fmt"
2323 "math/big"
24- "reflect"
2524
2625 "github.com/ethereum/go-ethereum/common"
2726 "github.com/ethereum/go-ethereum/crypto"
2827 "github.com/ethereum/go-ethereum/params"
2928)
3029
30+ var ErrInvalidChainId = errors .New ("invalid chaid id for signer" )
31+
3132// sigCache is used to cache the derived sender and contains
3233// the signer used to derive it.
3334type sigCache struct {
@@ -75,7 +76,7 @@ func Sender(signer Signer, tx *Transaction) (common.Address, error) {
7576 // If the signer used to derive from in a previous
7677 // call is not the same as used current, invalidate
7778 // the cache.
78- if reflect . TypeOf ( sigCache .signer ) == reflect . TypeOf (signer ) {
79+ if sigCache .signer . Equal (signer ) {
7980 return sigCache .from , nil
8081 }
8182 }
@@ -104,6 +105,8 @@ type Signer interface {
104105 SignECDSA (tx * Transaction , prv * ecdsa.PrivateKey ) (* Transaction , error )
105106 // WithSignature returns a copy of the transaction with the given signature
106107 WithSignature (tx * Transaction , sig []byte ) (* Transaction , error )
108+ // Checks for equality on the signers
109+ Equal (Signer ) bool
107110}
108111
109112// EIP155Transaction implements TransactionInterface using the
@@ -121,6 +124,11 @@ func NewEIP155Signer(chainId *big.Int) EIP155Signer {
121124 }
122125}
123126
127+ func (s EIP155Signer ) Equal (s2 Signer ) bool {
128+ eip155 , ok := s2 .(EIP155Signer )
129+ return ok && eip155 .chainId .Cmp (s .chainId ) == 0
130+ }
131+
124132func (s EIP155Signer ) SignECDSA (tx * Transaction , prv * ecdsa.PrivateKey ) (* Transaction , error ) {
125133 return SignECDSA (s , tx , prv )
126134}
@@ -131,6 +139,10 @@ func (s EIP155Signer) PublicKey(tx *Transaction) ([]byte, error) {
131139 return (HomesteadSigner {}).PublicKey (tx )
132140 }
133141
142+ if tx .ChainId ().Cmp (s .chainId ) != 0 {
143+ return nil , ErrInvalidChainId
144+ }
145+
134146 V := normaliseV (s , tx .data .V )
135147 if ! crypto .ValidateSignatureValues (V , tx .data .R , tx .data .S , true ) {
136148 return nil , ErrInvalidSig
@@ -200,6 +212,11 @@ func (s EIP155Signer) SigECDSA(tx *Transaction, prv *ecdsa.PrivateKey) (*Transac
200212// homestead rules.
201213type HomesteadSigner struct { FrontierSigner }
202214
215+ func (s HomesteadSigner ) Equal (s2 Signer ) bool {
216+ _ , ok := s2 .(HomesteadSigner )
217+ return ok
218+ }
219+
203220// WithSignature returns a new transaction with the given snature.
204221// This snature needs to be formatted as described in the yellow paper (v+27).
205222func (hs HomesteadSigner ) WithSignature (tx * Transaction , sig []byte ) (* Transaction , error ) {
@@ -251,6 +268,11 @@ func (hs HomesteadSigner) PublicKey(tx *Transaction) ([]byte, error) {
251268
252269type FrontierSigner struct {}
253270
271+ func (s FrontierSigner ) Equal (s2 Signer ) bool {
272+ _ , ok := s2 .(FrontierSigner )
273+ return ok
274+ }
275+
254276// WithSignature returns a new transaction with the given snature.
255277// This snature needs to be formatted as described in the yellow paper (v+27).
256278func (fs FrontierSigner ) WithSignature (tx * Transaction , sig []byte ) (* Transaction , error ) {
0 commit comments