github.com/ethereum-optimism/optimism@v1.7.2/op-node/rollup/derive/calldata_source_test.go (about)

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