Skip to content

Commit 6c9c1e6

Browse files
committed
core, core/types: refactored tx chain id checking
Refactored explicit chain id checking in to the Sender deriviation method
1 parent ca73dea commit 6c9c1e6

File tree

4 files changed

+48
-12
lines changed

4 files changed

+48
-12
lines changed

core/blockchain_test.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,11 +1226,8 @@ func TestEIP155Transition(t *testing.T) {
12261226
block.AddTx(tx)
12271227
}
12281228
})
1229-
errExp := "Invalid transaction chain id. Current chain id: 1 tx chain id: 2"
12301229
_, err := blockchain.InsertChain(blocks)
1231-
if err == nil {
1232-
t.Error("expected transaction chain id error")
1233-
} else if err.Error() != errExp {
1234-
t.Error("expected:", errExp, "got:", err)
1230+
if err != types.ErrInvalidChainId {
1231+
t.Error("expected error:", types.ErrInvalidChainId)
12351232
}
12361233
}

core/state_processor.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package core
1818

1919
import (
20-
"fmt"
2120
"math/big"
2221

2322
"github.com/ethereum/go-ethereum/core/state"
@@ -73,10 +72,6 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
7372
}
7473
// Iterate over and process the individual transactions
7574
for i, tx := range block.Transactions() {
76-
if tx.Protected() && tx.ChainId().Cmp(p.config.ChainId) != 0 {
77-
return nil, nil, nil, fmt.Errorf("Invalid transaction chain id. Current chain id: %v tx chain id: %v", p.config.ChainId, tx.ChainId())
78-
}
79-
8075
statedb.StartRecord(tx.Hash(), block.Hash(), i)
8176
receipt, logs, _, err := ApplyTransaction(p.config, p.bc, gp, statedb, header, tx, totalUsedGas, cfg)
8277
if err != nil {

core/types/transaction_signing.go

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
3334
type 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+
124132
func (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.
201213
type 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).
205222
func (hs HomesteadSigner) WithSignature(tx *Transaction, sig []byte) (*Transaction, error) {
@@ -251,6 +268,11 @@ func (hs HomesteadSigner) PublicKey(tx *Transaction) ([]byte, error) {
251268

252269
type 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).
256278
func (fs FrontierSigner) WithSignature(tx *Transaction, sig []byte) (*Transaction, error) {

core/types/transaction_signing_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,3 +114,25 @@ func TestEIP155SigningVitalik(t *testing.T) {
114114

115115
}
116116
}
117+
118+
func TestChainId(t *testing.T) {
119+
key, _ := defaultTestKey()
120+
121+
tx := NewTransaction(0, common.Address{}, new(big.Int), new(big.Int), new(big.Int), nil)
122+
123+
var err error
124+
tx, err = tx.SignECDSA(NewEIP155Signer(big.NewInt(1)), key)
125+
if err != nil {
126+
t.Fatal(err)
127+
}
128+
129+
_, err = Sender(NewEIP155Signer(big.NewInt(2)), tx)
130+
if err != ErrInvalidChainId {
131+
t.Error("expected error:", ErrInvalidChainId)
132+
}
133+
134+
_, err = Sender(NewEIP155Signer(big.NewInt(1)), tx)
135+
if err != nil {
136+
t.Error("expected no error")
137+
}
138+
}

0 commit comments

Comments
 (0)