From 6c9c1e6712d684e782a8920dac0173b49257fa1f Mon Sep 17 00:00:00 2001 From: Jeffrey Wilcke Date: Mon, 14 Nov 2016 15:59:31 +0100 Subject: [PATCH 1/2] core, core/types: refactored tx chain id checking Refactored explicit chain id checking in to the Sender deriviation method --- core/blockchain_test.go | 7 ++----- core/state_processor.go | 5 ----- core/types/transaction_signing.go | 26 ++++++++++++++++++++++++-- core/types/transaction_signing_test.go | 22 ++++++++++++++++++++++ 4 files changed, 48 insertions(+), 12 deletions(-) diff --git a/core/blockchain_test.go b/core/blockchain_test.go index dae857f011..934ae74e1a 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -1226,11 +1226,8 @@ func TestEIP155Transition(t *testing.T) { block.AddTx(tx) } }) - errExp := "Invalid transaction chain id. Current chain id: 1 tx chain id: 2" _, err := blockchain.InsertChain(blocks) - if err == nil { - t.Error("expected transaction chain id error") - } else if err.Error() != errExp { - t.Error("expected:", errExp, "got:", err) + if err != types.ErrInvalidChainId { + t.Error("expected error:", types.ErrInvalidChainId) } } diff --git a/core/state_processor.go b/core/state_processor.go index 46c5db0ee7..375b317f12 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -17,7 +17,6 @@ package core import ( - "fmt" "math/big" "github.com/ethereum/go-ethereum/core/state" @@ -73,10 +72,6 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg } // Iterate over and process the individual transactions for i, tx := range block.Transactions() { - if tx.Protected() && tx.ChainId().Cmp(p.config.ChainId) != 0 { - return nil, nil, nil, fmt.Errorf("Invalid transaction chain id. Current chain id: %v tx chain id: %v", p.config.ChainId, tx.ChainId()) - } - statedb.StartRecord(tx.Hash(), block.Hash(), i) receipt, logs, _, err := ApplyTransaction(p.config, p.bc, gp, statedb, header, tx, totalUsedGas, cfg) if err != nil { diff --git a/core/types/transaction_signing.go b/core/types/transaction_signing.go index 48209e2d8e..7d571643f2 100644 --- a/core/types/transaction_signing.go +++ b/core/types/transaction_signing.go @@ -21,13 +21,14 @@ import ( "errors" "fmt" "math/big" - "reflect" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "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 // the signer used to derive it. 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 // call is not the same as used current, invalidate // the cache. - if reflect.TypeOf(sigCache.signer) == reflect.TypeOf(signer) { + if sigCache.signer.Equal(signer) { return sigCache.from, nil } } @@ -104,6 +105,8 @@ type Signer interface { SignECDSA(tx *Transaction, prv *ecdsa.PrivateKey) (*Transaction, error) // WithSignature returns a copy of the transaction with the given signature WithSignature(tx *Transaction, sig []byte) (*Transaction, error) + // Checks for equality on the signers + Equal(Signer) bool } // 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) { return SignECDSA(s, tx, prv) } @@ -131,6 +139,10 @@ func (s EIP155Signer) PublicKey(tx *Transaction) ([]byte, error) { return (HomesteadSigner{}).PublicKey(tx) } + if tx.ChainId().Cmp(s.chainId) != 0 { + return nil, ErrInvalidChainId + } + V := normaliseV(s, tx.data.V) if !crypto.ValidateSignatureValues(V, tx.data.R, tx.data.S, true) { return nil, ErrInvalidSig @@ -200,6 +212,11 @@ func (s EIP155Signer) SigECDSA(tx *Transaction, prv *ecdsa.PrivateKey) (*Transac // homestead rules. 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. // This snature needs to be formatted as described in the yellow paper (v+27). 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{} +func (s FrontierSigner) Equal(s2 Signer) bool { + _, ok := s2.(FrontierSigner) + return ok +} + // WithSignature returns a new transaction with the given snature. // This snature needs to be formatted as described in the yellow paper (v+27). func (fs FrontierSigner) WithSignature(tx *Transaction, sig []byte) (*Transaction, error) { diff --git a/core/types/transaction_signing_test.go b/core/types/transaction_signing_test.go index 89c5902629..dc618e5703 100644 --- a/core/types/transaction_signing_test.go +++ b/core/types/transaction_signing_test.go @@ -114,3 +114,25 @@ func TestEIP155SigningVitalik(t *testing.T) { } } + +func TestChainId(t *testing.T) { + key, _ := defaultTestKey() + + tx := NewTransaction(0, common.Address{}, new(big.Int), new(big.Int), new(big.Int), nil) + + var err error + tx, err = tx.SignECDSA(NewEIP155Signer(big.NewInt(1)), key) + if err != nil { + t.Fatal(err) + } + + _, err = Sender(NewEIP155Signer(big.NewInt(2)), tx) + if err != ErrInvalidChainId { + t.Error("expected error:", ErrInvalidChainId) + } + + _, err = Sender(NewEIP155Signer(big.NewInt(1)), tx) + if err != nil { + t.Error("expected no error") + } +} From 7a6c6ec9469722abca93f94c4a3725f026ab09bc Mon Sep 17 00:00:00 2001 From: Jeffrey Wilcke Date: Mon, 14 Nov 2016 17:23:39 +0100 Subject: [PATCH 2/2] cmd/utils, params: define chain ids --- cmd/utils/flags.go | 7 +++++++ params/util.go | 3 +++ 2 files changed, 10 insertions(+) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 2d6bb4f5bd..f86fc37f50 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -881,6 +881,13 @@ func MakeChainConfigFromDb(ctx *cli.Context, db ethdb.Database) *params.ChainCon config.EIP158Block = params.MainNetSpuriousDragon } } + if config.ChainId.BitLen() == 0 { + if ctx.GlobalBool(TestNetFlag.Name) { + config.ChainId = params.TestNetChainID + } else { + config.ChainId = params.MainNetChainID + } + } config.DAOForkSupport = true } diff --git a/params/util.go b/params/util.go index 377f4ce7c9..b96f33da27 100644 --- a/params/util.go +++ b/params/util.go @@ -37,4 +37,7 @@ var ( TestNetSpuriousDragon = big.NewInt(3000000) MainNetSpuriousDragon = big.NewInt(3000000) + + TestNetChainID = big.NewInt(2) // Test net default chain ID + MainNetChainID = big.NewInt(1) // main net default chain ID )