|
@@ -21,13 +21,14 @@ import (
|
|
|
"errors"
|
|
"errors"
|
|
|
"fmt"
|
|
"fmt"
|
|
|
"math/big"
|
|
"math/big"
|
|
|
- "reflect"
|
|
|
|
|
|
|
|
|
|
"github.com/ethereum/go-ethereum/common"
|
|
"github.com/ethereum/go-ethereum/common"
|
|
|
"github.com/ethereum/go-ethereum/crypto"
|
|
"github.com/ethereum/go-ethereum/crypto"
|
|
|
"github.com/ethereum/go-ethereum/params"
|
|
"github.com/ethereum/go-ethereum/params"
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
|
|
+var ErrInvalidChainId = errors.New("invalid chaid id for signer")
|
|
|
|
|
+
|
|
|
// sigCache is used to cache the derived sender and contains
|
|
// sigCache is used to cache the derived sender and contains
|
|
|
// the signer used to derive it.
|
|
// the signer used to derive it.
|
|
|
type sigCache struct {
|
|
type sigCache struct {
|
|
@@ -75,7 +76,7 @@ func Sender(signer Signer, tx *Transaction) (common.Address, error) {
|
|
|
// If the signer used to derive from in a previous
|
|
// If the signer used to derive from in a previous
|
|
|
// call is not the same as used current, invalidate
|
|
// call is not the same as used current, invalidate
|
|
|
// the cache.
|
|
// the cache.
|
|
|
- if reflect.TypeOf(sigCache.signer) == reflect.TypeOf(signer) {
|
|
|
|
|
|
|
+ if sigCache.signer.Equal(signer) {
|
|
|
return sigCache.from, nil
|
|
return sigCache.from, nil
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -104,6 +105,8 @@ type Signer interface {
|
|
|
SignECDSA(tx *Transaction, prv *ecdsa.PrivateKey) (*Transaction, error)
|
|
SignECDSA(tx *Transaction, prv *ecdsa.PrivateKey) (*Transaction, error)
|
|
|
// WithSignature returns a copy of the transaction with the given signature
|
|
// WithSignature returns a copy of the transaction with the given signature
|
|
|
WithSignature(tx *Transaction, sig []byte) (*Transaction, error)
|
|
WithSignature(tx *Transaction, sig []byte) (*Transaction, error)
|
|
|
|
|
+ // Checks for equality on the signers
|
|
|
|
|
+ Equal(Signer) bool
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// EIP155Transaction implements TransactionInterface using the
|
|
// EIP155Transaction implements TransactionInterface using the
|
|
@@ -121,6 +124,11 @@ func NewEIP155Signer(chainId *big.Int) EIP155Signer {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+func (s EIP155Signer) Equal(s2 Signer) bool {
|
|
|
|
|
+ eip155, ok := s2.(EIP155Signer)
|
|
|
|
|
+ return ok && eip155.chainId.Cmp(s.chainId) == 0
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
func (s EIP155Signer) SignECDSA(tx *Transaction, prv *ecdsa.PrivateKey) (*Transaction, error) {
|
|
func (s EIP155Signer) SignECDSA(tx *Transaction, prv *ecdsa.PrivateKey) (*Transaction, error) {
|
|
|
return SignECDSA(s, tx, prv)
|
|
return SignECDSA(s, tx, prv)
|
|
|
}
|
|
}
|
|
@@ -131,6 +139,10 @@ func (s EIP155Signer) PublicKey(tx *Transaction) ([]byte, error) {
|
|
|
return (HomesteadSigner{}).PublicKey(tx)
|
|
return (HomesteadSigner{}).PublicKey(tx)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ if tx.ChainId().Cmp(s.chainId) != 0 {
|
|
|
|
|
+ return nil, ErrInvalidChainId
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
V := normaliseV(s, tx.data.V)
|
|
V := normaliseV(s, tx.data.V)
|
|
|
if !crypto.ValidateSignatureValues(V, tx.data.R, tx.data.S, true) {
|
|
if !crypto.ValidateSignatureValues(V, tx.data.R, tx.data.S, true) {
|
|
|
return nil, ErrInvalidSig
|
|
return nil, ErrInvalidSig
|
|
@@ -200,6 +212,11 @@ func (s EIP155Signer) SigECDSA(tx *Transaction, prv *ecdsa.PrivateKey) (*Transac
|
|
|
// homestead rules.
|
|
// homestead rules.
|
|
|
type HomesteadSigner struct{ FrontierSigner }
|
|
type HomesteadSigner struct{ FrontierSigner }
|
|
|
|
|
|
|
|
|
|
+func (s HomesteadSigner) Equal(s2 Signer) bool {
|
|
|
|
|
+ _, ok := s2.(HomesteadSigner)
|
|
|
|
|
+ return ok
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// WithSignature returns a new transaction with the given snature.
|
|
// WithSignature returns a new transaction with the given snature.
|
|
|
// This snature needs to be formatted as described in the yellow paper (v+27).
|
|
// This snature needs to be formatted as described in the yellow paper (v+27).
|
|
|
func (hs HomesteadSigner) WithSignature(tx *Transaction, sig []byte) (*Transaction, error) {
|
|
func (hs HomesteadSigner) WithSignature(tx *Transaction, sig []byte) (*Transaction, error) {
|
|
@@ -251,6 +268,11 @@ func (hs HomesteadSigner) PublicKey(tx *Transaction) ([]byte, error) {
|
|
|
|
|
|
|
|
type FrontierSigner struct{}
|
|
type FrontierSigner struct{}
|
|
|
|
|
|
|
|
|
|
+func (s FrontierSigner) Equal(s2 Signer) bool {
|
|
|
|
|
+ _, ok := s2.(FrontierSigner)
|
|
|
|
|
+ return ok
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// WithSignature returns a new transaction with the given snature.
|
|
// WithSignature returns a new transaction with the given snature.
|
|
|
// This snature needs to be formatted as described in the yellow paper (v+27).
|
|
// This snature needs to be formatted as described in the yellow paper (v+27).
|
|
|
func (fs FrontierSigner) WithSignature(tx *Transaction, sig []byte) (*Transaction, error) {
|
|
func (fs FrontierSigner) WithSignature(tx *Transaction, sig []byte) (*Transaction, error) {
|