@@ -21,13 +21,14 @@ import (
21
21
"errors"
22
22
"fmt"
23
23
"math/big"
24
- "reflect"
25
24
26
25
"github.com/ethereum/go-ethereum/common"
27
26
"github.com/ethereum/go-ethereum/crypto"
28
27
"github.com/ethereum/go-ethereum/params"
29
28
)
30
29
30
+ var ErrInvalidChainId = errors .New ("invalid chaid id for signer" )
31
+
31
32
// sigCache is used to cache the derived sender and contains
32
33
// the signer used to derive it.
33
34
type sigCache struct {
@@ -75,7 +76,7 @@ func Sender(signer Signer, tx *Transaction) (common.Address, error) {
75
76
// If the signer used to derive from in a previous
76
77
// call is not the same as used current, invalidate
77
78
// the cache.
78
- if reflect . TypeOf ( sigCache .signer ) == reflect . TypeOf (signer ) {
79
+ if sigCache .signer . Equal (signer ) {
79
80
return sigCache .from , nil
80
81
}
81
82
}
@@ -104,6 +105,8 @@ type Signer interface {
104
105
SignECDSA (tx * Transaction , prv * ecdsa.PrivateKey ) (* Transaction , error )
105
106
// WithSignature returns a copy of the transaction with the given signature
106
107
WithSignature (tx * Transaction , sig []byte ) (* Transaction , error )
108
+ // Checks for equality on the signers
109
+ Equal (Signer ) bool
107
110
}
108
111
109
112
// EIP155Transaction implements TransactionInterface using the
@@ -121,6 +124,11 @@ func NewEIP155Signer(chainId *big.Int) EIP155Signer {
121
124
}
122
125
}
123
126
127
+ func (s EIP155Signer ) Equal (s2 Signer ) bool {
128
+ eip155 , ok := s2 .(EIP155Signer )
129
+ return ok && eip155 .chainId .Cmp (s .chainId ) == 0
130
+ }
131
+
124
132
func (s EIP155Signer ) SignECDSA (tx * Transaction , prv * ecdsa.PrivateKey ) (* Transaction , error ) {
125
133
return SignECDSA (s , tx , prv )
126
134
}
@@ -131,6 +139,10 @@ func (s EIP155Signer) PublicKey(tx *Transaction) ([]byte, error) {
131
139
return (HomesteadSigner {}).PublicKey (tx )
132
140
}
133
141
142
+ if tx .ChainId ().Cmp (s .chainId ) != 0 {
143
+ return nil , ErrInvalidChainId
144
+ }
145
+
134
146
V := normaliseV (s , tx .data .V )
135
147
if ! crypto .ValidateSignatureValues (V , tx .data .R , tx .data .S , true ) {
136
148
return nil , ErrInvalidSig
@@ -200,6 +212,11 @@ func (s EIP155Signer) SigECDSA(tx *Transaction, prv *ecdsa.PrivateKey) (*Transac
200
212
// homestead rules.
201
213
type HomesteadSigner struct { FrontierSigner }
202
214
215
+ func (s HomesteadSigner ) Equal (s2 Signer ) bool {
216
+ _ , ok := s2 .(HomesteadSigner )
217
+ return ok
218
+ }
219
+
203
220
// WithSignature returns a new transaction with the given snature.
204
221
// This snature needs to be formatted as described in the yellow paper (v+27).
205
222
func (hs HomesteadSigner ) WithSignature (tx * Transaction , sig []byte ) (* Transaction , error ) {
@@ -251,6 +268,11 @@ func (hs HomesteadSigner) PublicKey(tx *Transaction) ([]byte, error) {
251
268
252
269
type FrontierSigner struct {}
253
270
271
+ func (s FrontierSigner ) Equal (s2 Signer ) bool {
272
+ _ , ok := s2 .(FrontierSigner )
273
+ return ok
274
+ }
275
+
254
276
// WithSignature returns a new transaction with the given snature.
255
277
// This snature needs to be formatted as described in the yellow paper (v+27).
256
278
func (fs FrontierSigner ) WithSignature (tx * Transaction , sig []byte ) (* Transaction , error ) {
0 commit comments