Skip to content

Commit

Permalink
Fix hash calculation for dynamic fee and access list transactions (#253)
Browse files Browse the repository at this point in the history
* Simplify and make signing more readable

* Include Dynamic fee transactions signing in the test

* Hash using provided chain id instead the one from transaction

* Change transaction type to uint8 data type
  • Loading branch information
Stefan-Ethernal committed Aug 10, 2023
1 parent b501468 commit c9c19bc
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 19 deletions.
2 changes: 1 addition & 1 deletion structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ func (b *Block) Copy() *Block {
return bb
}

type TransactionType int
type TransactionType uint8

const (
TransactionLegacy TransactionType = 0
Expand Down
20 changes: 8 additions & 12 deletions wallet/signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,13 @@ func (e *EIP1155Signer) SignTx(tx *ethgo.Transaction, key ethgo.Key) (*ethgo.Tra

func signHash(tx *ethgo.Transaction, chainID uint64) []byte {
a := fastrlp.DefaultArenaPool.Get()
defer fastrlp.DefaultArenaPool.Put(a)

v := a.NewArray()

if tx.Type != 0 {
if tx.Type != ethgo.TransactionLegacy {
// either dynamic and access type
v.Set(a.NewBigInt(tx.ChainID))
v.Set(a.NewBigInt(new(big.Int).SetUint64(chainID)))
}

v.Set(a.NewUint(tx.Nonce))
Expand All @@ -103,7 +104,7 @@ func signHash(tx *ethgo.Transaction, chainID uint64) []byte {
v.Set(a.NewBigInt(tx.Value))
v.Set(a.NewCopyBytes(tx.Input))

if tx.Type != 0 {
if tx.Type != ethgo.TransactionLegacy {
// either dynamic and access type
accessList, err := tx.AccessList.MarshalRLPWith(a)
if err != nil {
Expand All @@ -113,7 +114,7 @@ func signHash(tx *ethgo.Transaction, chainID uint64) []byte {
}

// EIP155
if chainID != 0 && tx.Type == 0 {
if chainID != 0 && tx.Type == ethgo.TransactionLegacy {
v.Set(a.NewUint(chainID))
v.Set(a.NewUint(0))
v.Set(a.NewUint(0))
Expand All @@ -122,15 +123,10 @@ func signHash(tx *ethgo.Transaction, chainID uint64) []byte {
dst := v.MarshalTo(nil)

// append the tx type byte
if tx.Type == ethgo.TransactionAccessList {
dst = append([]byte{0x1}, dst...)
} else if tx.Type == ethgo.TransactionDynamicFee {
dst = append([]byte{0x2}, dst...)
if tx.Type != ethgo.TransactionLegacy {
dst = append([]byte{byte(tx.Type)}, dst...)
}

hash := ethgo.Keccak256(dst)
fastrlp.DefaultArenaPool.Put(a)
return hash
return ethgo.Keccak256(dst)
}

func encodeSignature(R, S []byte, V byte) ([]byte, error) {
Expand Down
19 changes: 13 additions & 6 deletions wallet/signer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ import (

func TestSigner_SignAndRecover(t *testing.T) {
rapid.Check(t, func(t *rapid.T) {
istyped := rapid.Bool().Draw(t, "istyped")

// fill in common types for a transaction
txn := &ethgo.Transaction{}

Expand All @@ -22,15 +20,24 @@ func TestSigner_SignAndRecover(t *testing.T) {
txn.To = &to
}

txType := rapid.IntRange(0, 2).Draw(t, "tx type")

// fill in specific fields depending on the type
// of the transaction.
if istyped {
txn.Type = ethgo.TransactionAccessList
txn.Type = ethgo.TransactionType(txType)
if txn.Type == ethgo.TransactionDynamicFee {
maxFeePerGas := rapid.Int64Range(1, 1000000000).Draw(t, "maxFeePerGas")
txn.MaxFeePerGas = big.NewInt(maxFeePerGas)
maxPriorityFeePerGas := rapid.Int64Range(1, 1000000000).Draw(t, "maxPriorityFeePerGas")
txn.MaxPriorityFeePerGas = big.NewInt(maxPriorityFeePerGas)
} else {
gasPrice := rapid.Uint64Range(1, 1000000000).Draw(t, "gasPrice")
txn.GasPrice = gasPrice
}

// signer is from a random chain
chainid := rapid.Uint64().Draw(t, "chainid")
signer := NewEIP155Signer(chainid)
chainId := rapid.Uint64().Draw(t, "chainId")
signer := NewEIP155Signer(chainId)

key, err := GenerateKey()
require.NoError(t, err)
Expand Down

0 comments on commit c9c19bc

Please sign in to comment.