1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package derive
import (
"crypto/ecdsa"
"math/big"
"math/rand"
"testing"
"github.com/stretchr/testify/require"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum-optimism/optimism/op-service/testlog"
"github.com/ethereum-optimism/optimism/op-service/testutils"
)
type testTx struct {
to *common.Address
dataLen int
author *ecdsa.PrivateKey
good bool
value int
}
func (tx *testTx) Create(t *testing.T, signer types.Signer, rng *rand.Rand) *types.Transaction {
t.Helper()
out, err := types.SignNewTx(tx.author, signer, &types.DynamicFeeTx{
ChainID: signer.ChainID(),
Nonce: 0,
GasTipCap: big.NewInt(2 * params.GWei),
GasFeeCap: big.NewInt(30 * params.GWei),
Gas: 100_000,
To: tx.to,
Value: big.NewInt(int64(tx.value)),
Data: testutils.RandomData(rng, tx.dataLen),
})
require.NoError(t, err)
return out
}
type calldataTest struct {
name string
txs []testTx
}
// TestDataFromEVMTransactions creates some transactions from a specified template and asserts
// that DataFromEVMTransactions properly filters and returns the data from the authorized transactions
// inside the transaction set.
func TestDataFromEVMTransactions(t *testing.T) {
inboxPriv := testutils.RandomKey()
batcherPriv := testutils.RandomKey()
cfg := &rollup.Config{
L1ChainID: big.NewInt(100),
BatchInboxAddress: crypto.PubkeyToAddress(inboxPriv.PublicKey),
}
batcherAddr := crypto.PubkeyToAddress(batcherPriv.PublicKey)
altInbox := testutils.RandomAddress(rand.New(rand.NewSource(1234)))
altAuthor := testutils.RandomKey()
testCases := []calldataTest{
{
name: "simple",
txs: []testTx{{to: &cfg.BatchInboxAddress, dataLen: 1234, author: batcherPriv, good: true}},
},
{
name: "other inbox",
txs: []testTx{{to: &altInbox, dataLen: 1234, author: batcherPriv, good: false}}},
{
name: "other author",
txs: []testTx{{to: &cfg.BatchInboxAddress, dataLen: 1234, author: altAuthor, good: false}}},
{
name: "inbox is author",
txs: []testTx{{to: &cfg.BatchInboxAddress, dataLen: 1234, author: inboxPriv, good: false}}},
{
name: "author is inbox",
txs: []testTx{{to: &batcherAddr, dataLen: 1234, author: batcherPriv, good: false}}},
{
name: "unrelated",
txs: []testTx{{to: &altInbox, dataLen: 1234, author: altAuthor, good: false}}},
{
name: "contract creation",
txs: []testTx{{to: nil, dataLen: 1234, author: batcherPriv, good: false}}},
{
name: "empty tx",
txs: []testTx{{to: &cfg.BatchInboxAddress, dataLen: 0, author: batcherPriv, good: true}}},
{
name: "value tx",
txs: []testTx{{to: &cfg.BatchInboxAddress, dataLen: 1234, value: 42, author: batcherPriv, good: true}}},
{
name: "empty block", txs: []testTx{},
},
{
name: "mixed txs",
txs: []testTx{
{to: &cfg.BatchInboxAddress, dataLen: 1234, value: 42, author: batcherPriv, good: true},
{to: &cfg.BatchInboxAddress, dataLen: 3333, value: 32, author: altAuthor, good: false},
{to: &cfg.BatchInboxAddress, dataLen: 2000, value: 22, author: batcherPriv, good: true},
{to: &altInbox, dataLen: 2020, value: 12, author: batcherPriv, good: false},
},
},
// TODO: test with different batcher key, i.e. when it's changed from initial config value by L1 contract
}
for i, tc := range testCases {
rng := rand.New(rand.NewSource(int64(i)))
signer := cfg.L1Signer()
var expectedData []eth.Data
var txs []*types.Transaction
for i, tx := range tc.txs {
txs = append(txs, tx.Create(t, signer, rng))
if tx.good {
expectedData = append(expectedData, txs[i].Data())
}
}
out := DataFromEVMTransactions(DataSourceConfig{cfg.L1Signer(), cfg.BatchInboxAddress}, batcherAddr, txs, testlog.Logger(t, log.LvlCrit))
require.ElementsMatch(t, expectedData, out)
}
}