Skip to content

Commit cfc91d6

Browse files
committed
eth/wallet,channel/test: Extend Transactor test to different tx types
Signed-off-by: Sebastian Stammler <seb@perun.network>
1 parent 24035e7 commit cfc91d6

File tree

4 files changed

+97
-54
lines changed

4 files changed

+97
-54
lines changed

backend/ethereum/channel/test/transactor.go

Lines changed: 57 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import (
2020
"testing"
2121

2222
"github.com/ethereum/go-ethereum/accounts"
23-
"github.com/ethereum/go-ethereum/common"
2423
"github.com/ethereum/go-ethereum/core/types"
2524
"github.com/ethereum/go-ethereum/crypto"
2625
"github.com/stretchr/testify/assert"
@@ -30,10 +29,19 @@ import (
3029
"perun.network/go-perun/backend/ethereum/wallet"
3130
)
3231

32+
type TxType int
33+
34+
const (
35+
LegacyTx TxType = iota
36+
EIP155Tx
37+
EIP1559Tx
38+
)
39+
3340
// TransactorSetup holds the setup for running generic tests on a transactor implementation.
3441
type TransactorSetup struct {
3542
Signer types.Signer
3643
ChainID int64
44+
TxType TxType // Transaction type to generate and check against this signer
3745
Tr channel.Transactor
3846
ValidAcc accounts.Account // wallet should contain key corresponding to this account.
3947
MissingAcc accounts.Account // wallet should not contain key corresponding to this account.
@@ -45,22 +53,37 @@ const signerTestDataMaxLength = 100
4553
// for the passed signer.
4654
func GenericSignerTest(t *testing.T, rng *rand.Rand, setup TransactorSetup) {
4755
t.Helper()
48-
signer := setup.Signer
49-
chainID := setup.ChainID
50-
data := make([]byte, rng.Int31n(signerTestDataMaxLength)+1)
51-
rng.Read(data)
56+
57+
newTx := func() *types.Transaction {
58+
data := make([]byte, rng.Int31n(signerTestDataMaxLength)+1)
59+
rng.Read(data)
60+
switch setup.TxType {
61+
case LegacyTx, EIP155Tx:
62+
return types.NewTx(&types.LegacyTx{
63+
Value: big.NewInt(rng.Int63()),
64+
Data: data,
65+
})
66+
case EIP1559Tx:
67+
return types.NewTx(&types.DynamicFeeTx{
68+
ChainID: big.NewInt(setup.ChainID),
69+
Value: big.NewInt(rng.Int63()),
70+
Data: data,
71+
})
72+
}
73+
panic("unsupported tx type")
74+
}
5275

5376
t.Run("happy", func(t *testing.T) {
5477
transactOpts, err := setup.Tr.NewTransactor(setup.ValidAcc)
5578
require.NoError(t, err)
56-
rawTx := types.NewTransaction(uint64(1), common.Address{}, big.NewInt(1), uint64(1), big.NewInt(1), data)
57-
signedTx, err := transactOpts.Signer(setup.ValidAcc.Address, rawTx)
79+
tx := newTx()
80+
signedTx, err := transactOpts.Signer(setup.ValidAcc.Address, tx)
5881
assert.NoError(t, err)
5982
require.NotNil(t, signedTx)
6083

61-
txHash := signer.Hash(rawTx).Bytes()
84+
txHash := setup.Signer.Hash(tx).Bytes()
6285
v, r, s := signedTx.RawSignatureValues()
63-
sig := sigFromRSV(t, r, s, v, chainID)
86+
sig := sigFromRSV(t, r, s, v, &setup)
6487
pk, err := crypto.SigToPub(txHash, sig)
6588
require.NoError(t, err)
6689
addr := crypto.PubkeyToAddress(*pk)
@@ -76,30 +99,38 @@ func GenericSignerTest(t *testing.T, rng *rand.Rand, setup TransactorSetup) {
7699
transactOpts, err := setup.Tr.NewTransactor(setup.ValidAcc)
77100
require.NoError(t, err)
78101

79-
rawTx := types.NewTransaction(uint64(1), common.Address{}, big.NewInt(1), uint64(1), big.NewInt(1), data)
80-
_, err = transactOpts.Signer(setup.MissingAcc.Address, rawTx)
102+
_, err = transactOpts.Signer(setup.MissingAcc.Address, newTx())
81103
assert.Error(t, err)
82104
})
83105
}
84106

85-
func sigFromRSV(t *testing.T, r, s, _v *big.Int, chainID int64) []byte {
107+
func sigFromRSV(t *testing.T, r, s, _v *big.Int, setup *TransactorSetup) []byte {
86108
t.Helper()
87109
const (
88-
elemLen = 32
89-
sigLen = elemLen*2 + 1
90-
sigVAdd = 35
91-
sigVSubtract = 27
110+
elemLen = 32
111+
sigVEIP155Shift = 35
112+
sigVLegacyShift = 27
113+
)
114+
var (
115+
sig = make([]byte, wallet.SigLen)
116+
rb = r.Bytes()
117+
sb = s.Bytes()
118+
v = byte(_v.Uint64()) // truncation anticipated for large ChainIDs
92119
)
93-
sig := make([]byte, wallet.SigLen)
94-
copy(sig[elemLen-len(r.Bytes()):elemLen], r.Bytes())
95-
copy(sig[elemLen*2-len(s.Bytes()):elemLen*2], s.Bytes())
96-
v := byte(_v.Uint64()) // Needed for chain ids > 110.
97-
98-
if chainID == 0 {
99-
sig[sigLen-1] = v - sigVSubtract
100-
} else {
101-
sig[sigLen-1] = v - byte(chainID*2+sigVAdd) // Underflow is ok here.
120+
copy(sig[elemLen-len(rb):elemLen], rb)
121+
copy(sig[elemLen*2-len(sb):elemLen*2], sb)
122+
123+
switch setup.TxType {
124+
case LegacyTx:
125+
v -= sigVLegacyShift
126+
case EIP155Tx:
127+
v -= byte(setup.ChainID*2 + sigVEIP155Shift) // underflow anticipated
102128
}
103-
require.Contains(t, []byte{0, 1}, sig[sigLen-1], "Invalid v")
129+
// EIP1559 transactions simply code the y-parity into v, so no correction
130+
// necessary.
131+
require.Containsf(t, []byte{0, 1}, v,
132+
"Invalid v (txType: %v; chainID: %d)", setup.TxType, setup.ChainID)
133+
134+
sig[wallet.SigLen-1] = v
104135
return sig
105136
}

backend/ethereum/wallet/hd/transactor_test.go

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,53 +47,56 @@ func TestTransactor(t *testing.T) {
4747
title string
4848
signer types.Signer
4949
chainID int64
50+
txType test.TxType
5051
hideSignHash bool
5152
}{
5253
{
53-
title: "FrontierSigner",
54-
signer: &types.FrontierSigner{},
55-
chainID: 0,
54+
title: "FrontierSigner",
55+
signer: &types.FrontierSigner{},
56+
txType: test.LegacyTx,
5657
},
5758
{
58-
title: "HomesteadSigner",
59-
signer: &types.HomesteadSigner{},
60-
chainID: 0,
59+
title: "HomesteadSigner",
60+
signer: &types.HomesteadSigner{},
61+
txType: test.LegacyTx,
6162
},
6263
{
6364
title: "FrontierSigner (hideSignHash)",
6465
signer: &types.FrontierSigner{},
65-
chainID: 0,
66+
txType: test.LegacyTx,
6667
hideSignHash: true,
6768
},
6869
{
6970
title: "HomesteadSigner (hideSignHash)",
7071
signer: &types.HomesteadSigner{},
71-
chainID: 0,
72+
txType: test.LegacyTx,
7273
hideSignHash: true,
7374
},
7475
{
7576
title: "EIP155Signer",
7677
signer: types.NewEIP155Signer(big.NewInt(chainID)),
78+
txType: test.EIP155Tx,
7779
chainID: chainID,
7880
},
7981
{
8082
title: "LatestSigner",
8183
signer: types.LatestSignerForChainID(big.NewInt(chainID)),
84+
txType: test.EIP1559Tx,
8285
chainID: chainID,
8386
},
8487
}
8588

8689
for _, _t := range tests {
8790
_t := _t
8891
t.Run(_t.title, func(t *testing.T) {
89-
s := newTransactorSetup(t, rng, _t.hideSignHash, _t.signer, _t.chainID)
92+
s := newTransactorSetup(t, rng, _t.hideSignHash, _t.signer, _t.chainID, _t.txType)
9093
test.GenericSignerTest(t, rng, s)
9194
})
9295
}
9396
}
9497

9598
// rand.Rand is preferred over io.Reader here.
96-
func newTransactorSetup(t *testing.T, prng *rand.Rand, hideSignHash bool, signer types.Signer, chainID int64) test.TransactorSetup {
99+
func newTransactorSetup(t *testing.T, prng *rand.Rand, hideSignHash bool, signer types.Signer, chainID int64, txType test.TxType) test.TransactorSetup {
97100
t.Helper()
98101
walletSeed := make([]byte, 20)
99102
prng.Read(walletSeed)
@@ -119,6 +122,7 @@ func newTransactorSetup(t *testing.T, prng *rand.Rand, hideSignHash bool, signer
119122
return test.TransactorSetup{
120123
Signer: signer,
121124
ChainID: chainID,
125+
TxType: txType,
122126
Tr: hd.NewTransactor(hdWallet.Wallet(), signer),
123127
ValidAcc: accounts.Account{Address: wallet.AsEthAddr(validAcc.Address())},
124128
MissingAcc: accounts.Account{Address: common.HexToAddress(missingAddr)},

backend/ethereum/wallet/keystore/transactor_test.go

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,53 +35,57 @@ import (
3535
// Random address for which key will not be contained in the wallet.
3636
const randomAddr = "0x1"
3737

38-
func TestTxOptsBackend(t *testing.T) {
38+
func TestTransactor(t *testing.T) {
3939
rng := pkgtest.Prng(t)
4040
chainID := rng.Int63()
4141

4242
tests := []struct {
4343
title string
4444
signer types.Signer
4545
chainID int64
46+
txType test.TxType
4647
}{
4748
{
48-
title: "FrontierSigner",
49-
signer: &types.FrontierSigner{},
50-
chainID: 0,
49+
title: "FrontierSigner",
50+
signer: &types.FrontierSigner{},
51+
txType: test.LegacyTx,
5152
},
5253
{
53-
title: "HomesteadSigner",
54-
signer: &types.HomesteadSigner{},
55-
chainID: 0,
54+
title: "HomesteadSigner",
55+
signer: &types.HomesteadSigner{},
56+
txType: test.LegacyTx,
5657
},
5758
{
5859
title: "EIP155Signer",
5960
signer: types.NewEIP155Signer(big.NewInt(chainID)),
61+
txType: test.EIP155Tx,
6062
chainID: chainID,
6163
},
6264
{
6365
title: "LatestSigner",
6466
signer: types.LatestSignerForChainID(big.NewInt(chainID)),
67+
txType: test.EIP1559Tx,
6568
chainID: chainID,
6669
},
6770
}
6871

6972
for _, _t := range tests {
7073
_t := _t
7174
t.Run(_t.title, func(t *testing.T) {
72-
s := newTransactorSetup(t, rng, _t.signer, _t.chainID)
75+
s := newTransactorSetup(t, rng, _t.signer, _t.chainID, _t.txType)
7376
test.GenericSignerTest(t, rng, s)
7477
})
7578
}
7679
}
7780

78-
func newTransactorSetup(t require.TestingT, prng *rand.Rand, signer types.Signer, chainID int64) test.TransactorSetup {
81+
func newTransactorSetup(t require.TestingT, prng *rand.Rand, signer types.Signer, chainID int64, txType test.TxType) test.TransactorSetup {
7982
ksWallet, ok := wallettest.RandomWallet().(*keystore.Wallet)
8083
require.Truef(t, ok, "random wallet in wallettest should be a keystore wallet")
8184
acc := wallettest.NewRandomAccount(prng)
8285
return test.TransactorSetup{
8386
Signer: signer,
8487
ChainID: chainID,
88+
TxType: txType,
8589
Tr: keystore.NewTransactor(*ksWallet, signer),
8690
ValidAcc: accounts.Account{Address: wallet.AsEthAddr(acc.Address())},
8791
MissingAcc: accounts.Account{Address: common.HexToAddress(randomAddr)},

backend/ethereum/wallet/simple/transactor_test.go

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,47 +33,50 @@ import (
3333
// Missing address for which key will not be contained in the wallet.
3434
const missingAddr = "0x1"
3535

36-
func TestTxOptsBackend(t *testing.T) {
36+
func TestTransactor(t *testing.T) {
3737
rng := pkgtest.Prng(t)
3838
chainID := rng.Int63()
3939

4040
tests := []struct {
4141
title string
4242
signer types.Signer
4343
chainID int64
44+
txType test.TxType
4445
}{
4546
{
46-
title: "FrontierSigner",
47-
signer: &types.FrontierSigner{},
48-
chainID: 0,
47+
title: "FrontierSigner",
48+
signer: &types.FrontierSigner{},
49+
txType: test.LegacyTx,
4950
},
5051
{
51-
title: "HomesteadSigner",
52-
signer: &types.HomesteadSigner{},
53-
chainID: 0,
52+
title: "HomesteadSigner",
53+
signer: &types.HomesteadSigner{},
54+
txType: test.LegacyTx,
5455
},
5556
{
5657
title: "EIP155Signer",
5758
signer: types.NewEIP155Signer(big.NewInt(chainID)),
59+
txType: test.EIP155Tx,
5860
chainID: chainID,
5961
},
6062
{
6163
title: "LatestSigner",
6264
signer: types.LatestSignerForChainID(big.NewInt(chainID)),
65+
txType: test.EIP1559Tx,
6366
chainID: chainID,
6467
},
6568
}
6669

6770
for _, _t := range tests {
6871
_t := _t
6972
t.Run(_t.title, func(t *testing.T) {
70-
s := newTransactorSetup(t, rng, _t.signer, _t.chainID)
73+
s := newTransactorSetup(t, rng, _t.signer, _t.chainID, _t.txType)
7174
test.GenericSignerTest(t, rng, s)
7275
})
7376
}
7477
}
7578

76-
func newTransactorSetup(t require.TestingT, prng *rand.Rand, signer types.Signer, chainID int64) test.TransactorSetup {
79+
func newTransactorSetup(t require.TestingT, prng *rand.Rand, signer types.Signer, chainID int64, txType test.TxType) test.TransactorSetup {
7780
simpleWallet := simple.NewWallet()
7881
require.NotNil(t, simpleWallet)
7982
validAcc := simpleWallet.NewRandomAccount(prng)
@@ -82,6 +85,7 @@ func newTransactorSetup(t require.TestingT, prng *rand.Rand, signer types.Signer
8285
return test.TransactorSetup{
8386
Signer: signer,
8487
ChainID: chainID,
88+
TxType: txType,
8589
Tr: simple.NewTransactor(simpleWallet, signer),
8690
ValidAcc: accounts.Account{Address: wallet.AsEthAddr(validAcc.Address())},
8791
MissingAcc: accounts.Account{Address: common.HexToAddress(missingAddr)},

0 commit comments

Comments
 (0)