github.com/ethereum-optimism/optimism/l2geth@v0.0.0-20230612200230-50b04ade19e3/rollup/sync_service_test.go (about)

     1  package rollup
     2  
     3  import (
     4  	"context"
     5  	"crypto/rand"
     6  	"errors"
     7  	"fmt"
     8  	"math/big"
     9  	"reflect"
    10  	"sync"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/ethereum-optimism/optimism/l2geth/common"
    15  	"github.com/ethereum-optimism/optimism/l2geth/consensus/ethash"
    16  	"github.com/ethereum-optimism/optimism/l2geth/core"
    17  	"github.com/ethereum-optimism/optimism/l2geth/core/rawdb"
    18  	"github.com/ethereum-optimism/optimism/l2geth/core/types"
    19  	"github.com/ethereum-optimism/optimism/l2geth/core/vm"
    20  	"github.com/ethereum-optimism/optimism/l2geth/crypto"
    21  	"github.com/ethereum-optimism/optimism/l2geth/eth/gasprice"
    22  	"github.com/ethereum-optimism/optimism/l2geth/ethdb"
    23  	"github.com/ethereum-optimism/optimism/l2geth/event"
    24  	"github.com/ethereum-optimism/optimism/l2geth/params"
    25  	"github.com/ethereum-optimism/optimism/l2geth/rollup/rcfg"
    26  )
    27  
    28  // Test that the timestamps are updated correctly.
    29  // This impacts execution, for `block.timestamp`
    30  func TestSyncServiceTimestampUpdate(t *testing.T) {
    31  	service, txCh, _, err := newTestSyncService(false, nil)
    32  	if err != nil {
    33  		t.Fatal(err)
    34  	}
    35  
    36  	// Get the timestamp from the sync service
    37  	// It should be initialized to 0
    38  	ts := service.GetLatestL1Timestamp()
    39  	if ts != 0 {
    40  		t.Fatalf("Unexpected timestamp: %d", ts)
    41  	}
    42  
    43  	// Create a mock transaction and assert that its timestamp
    44  	// a value. This tests the case that the timestamp does
    45  	// not get malleated when it is set to a non zero value
    46  	timestamp := uint64(1)
    47  	tx1 := setMockTxL1Timestamp(mockTx(), timestamp)
    48  	if tx1.GetMeta().L1Timestamp != timestamp {
    49  		t.Fatalf("Expecting mock timestamp to be %d", timestamp)
    50  	}
    51  	if tx1.GetMeta().QueueOrigin != types.QueueOriginSequencer {
    52  		t.Fatalf("Expecting mock queue origin to be queue origin sequencer")
    53  	}
    54  
    55  	go func() {
    56  		err = service.applyTransactionToTip(tx1)
    57  	}()
    58  	event1 := <-txCh
    59  
    60  	// Ensure that the timestamp isn't malleated
    61  	if event1.Txs[0].GetMeta().L1Timestamp != timestamp {
    62  		t.Fatalf("Timestamp was malleated: %d", event1.Txs[0].GetMeta().L1Timestamp)
    63  	}
    64  	// Ensure that the timestamp in the sync service was updated
    65  	if service.GetLatestL1Timestamp() != timestamp {
    66  		t.Fatal("timestamp updated in sync service")
    67  	}
    68  
    69  	// Now test the case for when a transaction is malleated.
    70  	// If the timestamp is 0, then it should be malleated and set
    71  	// equal to whatever the latestL1Timestamp is
    72  	tx2 := mockTx()
    73  	if tx2.GetMeta().L1Timestamp != 0 {
    74  		t.Fatal("Expecting mock timestamp to be 0")
    75  	}
    76  	go func() {
    77  		err = service.applyTransactionToTip(tx2)
    78  	}()
    79  	event2 := <-txCh
    80  
    81  	// Ensure that the sync service timestamp is updated
    82  	if service.GetLatestL1Timestamp() == 0 {
    83  		t.Fatal("timestamp not updated")
    84  	}
    85  	// Ensure that the timestamp is malleated to be equal to what the sync
    86  	// service has as the latest timestamp
    87  	if event2.Txs[0].GetMeta().L1Timestamp != service.GetLatestL1Timestamp() {
    88  		t.Fatal("unexpected timestamp update")
    89  	}
    90  
    91  	// L1ToL2 transactions should have their timestamp malleated
    92  	// Be sure to set the timestamp to a non zero value so that
    93  	// its specifically testing the fact its a deposit tx
    94  	tx3 := setMockQueueOrigin(setMockTxL1Timestamp(mockTx(), 100), types.QueueOriginL1ToL2)
    95  	// Get a reference to the timestamp before transaction execution
    96  	ts3 := service.GetLatestL1Timestamp()
    97  
    98  	go func() {
    99  		err = service.applyTransactionToTip(tx3)
   100  	}()
   101  	event3 := <-txCh
   102  
   103  	if event3.Txs[0].GetMeta().L1Timestamp != ts3 {
   104  		t.Fatal("bad malleation")
   105  	}
   106  	// Ensure that the timestamp didn't change
   107  	if ts3 != service.GetLatestL1Timestamp() {
   108  		t.Fatal("timestamp updated when it shouldn't have")
   109  	}
   110  }
   111  
   112  // Test that the L1 blocknumber is updated correctly
   113  func TestSyncServiceL1BlockNumberUpdate(t *testing.T) {
   114  	service, txCh, _, err := newTestSyncService(false, nil)
   115  	if err != nil {
   116  		t.Fatal(err)
   117  	}
   118  
   119  	// Get the L1 blocknumber from the sync service
   120  	// It should be initialized to 0
   121  	bn := service.GetLatestL1BlockNumber()
   122  	if bn != 0 {
   123  		t.Fatalf("Unexpected timestamp: %d", bn)
   124  	}
   125  
   126  	tx1 := setMockTxL1BlockNumber(mockTx(), new(big.Int).SetUint64(1))
   127  	go func() {
   128  		err = service.applyTransactionToTip(tx1)
   129  	}()
   130  	event1 := <-txCh
   131  
   132  	// Ensure that the L1 blocknumber was not
   133  	// malleated
   134  	if event1.Txs[0].L1BlockNumber().Uint64() != 1 {
   135  		t.Fatal("wrong l1 blocknumber")
   136  	}
   137  
   138  	// Ensure that the latest L1 blocknumber was
   139  	// updated
   140  	if service.GetLatestL1BlockNumber() != 1 {
   141  		t.Fatal("sync service latest l1 blocknumber not updated")
   142  	}
   143  
   144  	// Ensure that a tx without a L1 blocknumber gets one
   145  	// assigned
   146  	tx2 := setMockTxL1BlockNumber(mockTx(), nil)
   147  	if tx2.L1BlockNumber() != nil {
   148  		t.Fatal("non nil l1 blocknumber")
   149  	}
   150  	go func() {
   151  		err = service.applyTransactionToTip(tx2)
   152  	}()
   153  	event2 := <-txCh
   154  
   155  	if event2.Txs[0].L1BlockNumber() == nil {
   156  		t.Fatal("tx not assigned an l1 blocknumber")
   157  	}
   158  	if event2.Txs[0].L1BlockNumber().Uint64() != service.GetLatestL1BlockNumber() {
   159  		t.Fatal("tx assigned incorrect l1 blocknumber")
   160  	}
   161  
   162  	// Ensure that the latest L1 blocknumber doesn't go backwards
   163  	latest := service.GetLatestL1BlockNumber()
   164  	tx3 := setMockTxL1BlockNumber(mockTx(), new(big.Int).SetUint64(latest-1))
   165  	go func() {
   166  		err = service.applyTransactionToTip(tx3)
   167  	}()
   168  	event3 := <-txCh
   169  	if service.GetLatestL1BlockNumber() != latest {
   170  		t.Fatal("block number went backwards")
   171  	}
   172  
   173  	if event3.Txs[0].L1BlockNumber().Uint64() != latest-1 {
   174  		t.Fatal("l1 block number was malleated")
   175  	}
   176  }
   177  
   178  // Test that the `RollupTransaction` ends up in the transaction cache
   179  // after the transaction enqueued event is emitted. Set `false` as
   180  // the argument to start as a sequencer
   181  func TestSyncServiceTransactionEnqueued(t *testing.T) {
   182  	service, txCh, _, err := newTestSyncService(false, nil)
   183  	if err != nil {
   184  		t.Fatal(err)
   185  	}
   186  
   187  	// The timestamp is in the rollup transaction
   188  	timestamp := uint64(24)
   189  	// The target is the `to` field on the transaction
   190  	target := common.HexToAddress("0x04668ec2f57cc15c381b461b9fedab5d451c8f7f")
   191  	// The layer one transaction origin is in the txmeta on the transaction
   192  	l1TxOrigin := common.HexToAddress("0xEA674fdDe714fd979de3EdF0F56AA9716B898ec8")
   193  	// The gasLimit is the `gasLimit` on the transaction
   194  	gasLimit := uint64(66)
   195  	// The data is the `data` on the transaction
   196  	data := []byte{0x02, 0x92}
   197  	// The L1 blocknumber for the transaction's evm context
   198  	l1BlockNumber := big.NewInt(100)
   199  	// The queue index of the L1 to L2 transaction
   200  	queueIndex := uint64(0)
   201  	// The index in the ctc
   202  	index := uint64(0)
   203  
   204  	tx := types.NewTransaction(0, target, big.NewInt(0), gasLimit, big.NewInt(0), data)
   205  	txMeta := types.NewTransactionMeta(
   206  		l1BlockNumber,
   207  		timestamp,
   208  		&l1TxOrigin,
   209  		types.QueueOriginL1ToL2,
   210  		&index,
   211  		&queueIndex,
   212  		nil,
   213  	)
   214  	tx.SetTransactionMeta(txMeta)
   215  
   216  	setupMockClient(service, map[string]interface{}{
   217  		"GetEnqueue": []*types.Transaction{
   218  			tx,
   219  		},
   220  	})
   221  
   222  	// Run an iteration of the eloop
   223  	err = nil
   224  	go func() {
   225  		err = service.syncQueueToTip()
   226  	}()
   227  	// Wait for the tx to be confirmed into the chain and then
   228  	// make sure it is the transactions that was set up with in the mockclient
   229  	event := <-txCh
   230  	if err != nil {
   231  		t.Fatal("sequencing failed", err)
   232  	}
   233  	if len(event.Txs) != 1 {
   234  		t.Fatal("Unexpected number of transactions")
   235  	}
   236  	confirmed := event.Txs[0]
   237  
   238  	if !reflect.DeepEqual(tx, confirmed) {
   239  		t.Fatal("different txs")
   240  	}
   241  }
   242  
   243  func TestTransactionToTipNoIndex(t *testing.T) {
   244  	service, txCh, _, err := newTestSyncService(false, nil)
   245  	if err != nil {
   246  		t.Fatal(err)
   247  	}
   248  
   249  	// Get a reference to the current next index to compare with the index that
   250  	// is set to the transaction that is ingested
   251  	nextIndex := service.GetNextIndex()
   252  
   253  	timestamp := uint64(24)
   254  	target := common.HexToAddress("0x04668ec2f57cc15c381b461b9fedab5d451c8f7f")
   255  	l1TxOrigin := common.HexToAddress("0xEA674fdDe714fd979de3EdF0F56AA9716B898ec8")
   256  	gasLimit := uint64(66)
   257  	data := []byte{0x02, 0x92}
   258  	l1BlockNumber := big.NewInt(100)
   259  
   260  	tx := types.NewTransaction(0, target, big.NewInt(0), gasLimit, big.NewInt(0), data)
   261  	meta := types.NewTransactionMeta(
   262  		l1BlockNumber,
   263  		timestamp,
   264  		&l1TxOrigin,
   265  		types.QueueOriginL1ToL2,
   266  		nil, // The index is `nil`, expect it to be set afterwards
   267  		nil,
   268  		nil,
   269  	)
   270  	tx.SetTransactionMeta(meta)
   271  
   272  	go func() {
   273  		err = service.applyTransactionToTip(tx)
   274  	}()
   275  	event := <-txCh
   276  	if err != nil {
   277  		t.Fatal("Cannot apply transaction to the tip")
   278  	}
   279  	confirmed := event.Txs[0]
   280  	// The transaction was applied without an index so the chain gave it the
   281  	// next index
   282  	index := confirmed.GetMeta().Index
   283  	if index == nil {
   284  		t.Fatal("Did not set index after applying tx to tip")
   285  	}
   286  	if *index != *service.GetLatestIndex() {
   287  		t.Fatal("Incorrect latest index")
   288  	}
   289  	if *index != nextIndex {
   290  		t.Fatal("Incorrect index")
   291  	}
   292  }
   293  
   294  func TestTransactionToTipTimestamps(t *testing.T) {
   295  	service, txCh, _, err := newTestSyncService(false, nil)
   296  	if err != nil {
   297  		t.Fatal(err)
   298  	}
   299  
   300  	// Create two mock transactions with `nil` indices. This will allow
   301  	// assertions around the indices being updated correctly. Set the timestamp
   302  	// to 1 and 2 and assert that the timestamps in the sync service are updated
   303  	// correctly
   304  	tx1 := setMockTxL1Timestamp(mockTx(), 1)
   305  	tx2 := setMockTxL1Timestamp(mockTx(), 2)
   306  
   307  	txs := []*types.Transaction{
   308  		tx1,
   309  		tx2,
   310  	}
   311  
   312  	for _, tx := range txs {
   313  		nextIndex := service.GetNextIndex()
   314  
   315  		go func() {
   316  			err = service.applyTransactionToTip(tx)
   317  		}()
   318  		event := <-txCh
   319  		if err != nil {
   320  			t.Fatal(err)
   321  		}
   322  
   323  		conf := event.Txs[0]
   324  		// The index should be set to the next
   325  		if conf.GetMeta().Index == nil {
   326  			t.Fatal("Index is nil")
   327  		}
   328  		// The index that the sync service is tracking should be updated
   329  		if *conf.GetMeta().Index != *service.GetLatestIndex() {
   330  			t.Fatal("index on the service was not updated")
   331  		}
   332  		// The indexes should be incrementing by 1
   333  		if *conf.GetMeta().Index != nextIndex {
   334  			t.Fatalf("Mismatched index: got %d, expect %d", *conf.GetMeta().Index, nextIndex)
   335  		}
   336  		// The tx timestamp should be setting the services timestamp
   337  		if conf.L1Timestamp() != service.GetLatestL1Timestamp() {
   338  			t.Fatal("Mismatched timestamp")
   339  		}
   340  	}
   341  
   342  	// Ensure that the timestamp was updated correctly
   343  	ts := service.GetLatestL1Timestamp()
   344  	if ts != tx2.L1Timestamp() {
   345  		t.Fatal("timestamp not updated correctly")
   346  	}
   347  
   348  	// Send a transaction with no timestamp and then let it be updated
   349  	// by the sync service. This will prevent monotonicity errors as well.
   350  	// as give timestamps to queue origin sequencer transactions
   351  	// Ensure that the timestamp is set to `time.Now`
   352  	// when it is not set.
   353  	tx3 := setMockTxL1Timestamp(mockTx(), 0)
   354  	now := time.Now()
   355  	go func() {
   356  		err = service.applyTransactionToTip(tx3)
   357  	}()
   358  	result := <-txCh
   359  	service.chainHeadCh <- core.ChainHeadEvent{}
   360  
   361  	if result.Txs[0].L1Timestamp() != uint64(now.Unix()) {
   362  		t.Fatal("Timestamp not updated correctly")
   363  	}
   364  
   365  	if service.GetLatestL1Timestamp() != uint64(now.Unix()) {
   366  		t.Fatal("latest timestamp not updated correctly")
   367  	}
   368  }
   369  
   370  func TestApplyIndexedTransaction(t *testing.T) {
   371  	service, txCh, _, err := newTestSyncService(true, nil)
   372  	if err != nil {
   373  		t.Fatal(err)
   374  	}
   375  
   376  	// Create three transactions, two of which have a duplicate index.
   377  	// The first two transactions can be ingested without a problem and the
   378  	// third transaction has a duplicate index so it will not be ingested.
   379  	// Expect an error for the third transaction and expect the SyncService
   380  	// global index to be updated with the first two transactions
   381  	tx0 := setMockTxIndex(mockTx(), 0)
   382  	tx1 := setMockTxIndex(mockTx(), 1)
   383  	tx1a := setMockTxIndex(mockTx(), 1)
   384  
   385  	go func() {
   386  		err = service.applyIndexedTransaction(tx0)
   387  	}()
   388  	<-txCh
   389  	if err != nil {
   390  		t.Fatal(err)
   391  	}
   392  	if *tx0.GetMeta().Index != *service.GetLatestIndex() {
   393  		t.Fatal("Latest index mismatch")
   394  	}
   395  
   396  	go func() {
   397  		err = service.applyIndexedTransaction(tx1)
   398  	}()
   399  	<-txCh
   400  	if err != nil {
   401  		t.Fatal(err)
   402  	}
   403  	if *tx1.GetMeta().Index != *service.GetLatestIndex() {
   404  		t.Fatal("Latest index mismatch")
   405  	}
   406  
   407  	err = service.applyIndexedTransaction(tx1a)
   408  	if err == nil {
   409  		t.Fatal(err)
   410  	}
   411  }
   412  
   413  func TestApplyBatchedTransaction(t *testing.T) {
   414  	service, txCh, _, err := newTestSyncService(true, nil)
   415  	if err != nil {
   416  		t.Fatal(err)
   417  	}
   418  
   419  	// Create a transactoin with the index of 0
   420  	tx0 := setMockTxIndex(mockTx(), 0)
   421  
   422  	// Ingest through applyBatchedTransaction which should set the latest
   423  	// verified index to the index of the transaction
   424  	go func() {
   425  		err = service.applyBatchedTransaction(tx0)
   426  	}()
   427  	service.chainHeadCh <- core.ChainHeadEvent{}
   428  	<-txCh
   429  
   430  	// Catch race conditions with the database write
   431  	wg := new(sync.WaitGroup)
   432  	wg.Add(1)
   433  	go func() {
   434  		for {
   435  			if service.GetLatestVerifiedIndex() != nil {
   436  				wg.Done()
   437  				return
   438  			}
   439  			time.Sleep(100 * time.Millisecond)
   440  		}
   441  	}()
   442  	wg.Wait()
   443  
   444  	// Assert that the verified index is the same as the transaction index
   445  	if *tx0.GetMeta().Index != *service.GetLatestVerifiedIndex() {
   446  		t.Fatal("Latest verified index mismatch")
   447  	}
   448  }
   449  
   450  func TestIsAtTip(t *testing.T) {
   451  	service, _, _, err := newTestSyncService(true, nil)
   452  	if err != nil {
   453  		t.Fatal(err)
   454  	}
   455  
   456  	data := []struct {
   457  		tip    *uint64
   458  		get    indexGetter
   459  		expect bool
   460  		err    error
   461  	}{
   462  		{
   463  			tip: newUint64(1),
   464  			get: func() (*uint64, error) {
   465  				return newUint64(1), nil
   466  			},
   467  			expect: true,
   468  			err:    nil,
   469  		},
   470  		{
   471  			tip: newUint64(0),
   472  			get: func() (*uint64, error) {
   473  				return newUint64(1), nil
   474  			},
   475  			expect: false,
   476  			err:    nil,
   477  		},
   478  		{
   479  			tip: newUint64(1),
   480  			get: func() (*uint64, error) {
   481  				return newUint64(0), nil
   482  			},
   483  			expect: false,
   484  			err:    errShortRemoteTip,
   485  		},
   486  		{
   487  			tip: nil,
   488  			get: func() (*uint64, error) {
   489  				return nil, nil
   490  			},
   491  			expect: true,
   492  			err:    nil,
   493  		},
   494  		{
   495  			tip: nil,
   496  			get: func() (*uint64, error) {
   497  				return nil, errElementNotFound
   498  			},
   499  			expect: true,
   500  			err:    nil,
   501  		},
   502  		{
   503  			tip: newUint64(0),
   504  			get: func() (*uint64, error) {
   505  				return nil, errElementNotFound
   506  			},
   507  			expect: false,
   508  			err:    nil,
   509  		},
   510  	}
   511  
   512  	for _, d := range data {
   513  		isAtTip, err := service.isAtTip(d.tip, d.get)
   514  		if isAtTip != d.expect {
   515  			t.Fatal("expected does not match")
   516  		}
   517  		if !errors.Is(err, d.err) {
   518  			t.Fatal("error no match")
   519  		}
   520  	}
   521  }
   522  
   523  func TestSyncQueue(t *testing.T) {
   524  	service, txCh, _, err := newTestSyncService(true, nil)
   525  	if err != nil {
   526  		t.Fatal(err)
   527  	}
   528  
   529  	setupMockClient(service, map[string]interface{}{
   530  		"GetEnqueue": []*types.Transaction{
   531  			setMockQueueIndex(mockTx(), 0),
   532  			setMockQueueIndex(mockTx(), 1),
   533  			setMockQueueIndex(mockTx(), 2),
   534  			setMockQueueIndex(mockTx(), 3),
   535  		},
   536  	})
   537  
   538  	var tip *uint64
   539  	go func() {
   540  		tip, err = service.syncQueue()
   541  	}()
   542  
   543  	for i := 0; i < 4; i++ {
   544  		service.chainHeadCh <- core.ChainHeadEvent{}
   545  		event := <-txCh
   546  		tx := event.Txs[0]
   547  		if *tx.GetMeta().QueueIndex != uint64(i) {
   548  			t.Fatal("queue index mismatch")
   549  		}
   550  	}
   551  
   552  	wg := new(sync.WaitGroup)
   553  	wg.Add(1)
   554  	go func() {
   555  		for {
   556  			if tip != nil {
   557  				wg.Done()
   558  				return
   559  			}
   560  			time.Sleep(100 * time.Millisecond)
   561  		}
   562  	}()
   563  	wg.Wait()
   564  	if tip == nil {
   565  		t.Fatal("tip is nil")
   566  	}
   567  	// There were a total of 4 transactions synced and the indexing starts at 0
   568  	if *service.GetLatestIndex() != 3 {
   569  		t.Fatalf("Latest index mismatch")
   570  	}
   571  	// All of the transactions are `enqueue()`s
   572  	if *service.GetLatestEnqueueIndex() != 3 {
   573  		t.Fatal("Latest queue index mismatch")
   574  	}
   575  	if *tip != 3 {
   576  		t.Fatal("Tip mismatch")
   577  	}
   578  }
   579  
   580  func TestSyncServiceL1GasPrice(t *testing.T) {
   581  	service, _, _, err := newTestSyncService(true, nil)
   582  	setupMockClient(service, map[string]interface{}{})
   583  
   584  	if err != nil {
   585  		t.Fatal(err)
   586  	}
   587  
   588  	gasBefore, err := service.RollupGpo.SuggestL1GasPrice(context.Background())
   589  	if err != nil {
   590  		t.Fatal(err)
   591  	}
   592  
   593  	if gasBefore.Cmp(big.NewInt(0)) != 0 {
   594  		t.Fatal("expected 0 gas price, got", gasBefore)
   595  	}
   596  
   597  	state, err := service.bc.State()
   598  	if err != nil {
   599  		t.Fatal("Cannot get state db")
   600  	}
   601  	l1GasPrice := big.NewInt(100000000000)
   602  	state.SetState(rcfg.L2GasPriceOracleAddress, rcfg.L1GasPriceSlot, common.BigToHash(l1GasPrice))
   603  	_, _ = state.Commit(false)
   604  
   605  	// Update the gas price
   606  	service.updateL1GasPrice(state)
   607  
   608  	gasAfter, err := service.RollupGpo.SuggestL1GasPrice(context.Background())
   609  	if err != nil {
   610  		t.Fatal(err)
   611  	}
   612  
   613  	if gasAfter.Cmp(l1GasPrice) != 0 {
   614  		t.Fatal("expected 100 gas price, got", gasAfter)
   615  	}
   616  }
   617  
   618  func TestSyncServiceL2GasPrice(t *testing.T) {
   619  	service, _, _, err := newTestSyncService(true, nil)
   620  	if err != nil {
   621  		t.Fatal(err)
   622  	}
   623  
   624  	price, err := service.RollupGpo.SuggestL2GasPrice(context.Background())
   625  	if err != nil {
   626  		t.Fatal("Cannot fetch execution price")
   627  	}
   628  
   629  	if price.Cmp(common.Big0) != 0 {
   630  		t.Fatal("Incorrect gas price")
   631  	}
   632  
   633  	state, err := service.bc.State()
   634  	if err != nil {
   635  		t.Fatal("Cannot get state db")
   636  	}
   637  	l2GasPrice := big.NewInt(100000000000)
   638  	state.SetState(rcfg.L2GasPriceOracleAddress, rcfg.L2GasPriceSlot, common.BigToHash(l2GasPrice))
   639  	_, _ = state.Commit(false)
   640  
   641  	service.updateL2GasPrice(state)
   642  
   643  	post, err := service.RollupGpo.SuggestL2GasPrice(context.Background())
   644  	if err != nil {
   645  		t.Fatal("Cannot fetch execution price")
   646  	}
   647  
   648  	if l2GasPrice.Cmp(post) != 0 {
   649  		t.Fatal("Gas price not updated")
   650  	}
   651  }
   652  
   653  func TestSyncServiceGasPriceOracleOwnerAddress(t *testing.T) {
   654  	service, _, _, err := newTestSyncService(true, nil)
   655  	if err != nil {
   656  		t.Fatal(err)
   657  	}
   658  	// newTestSyncService doesn't set the initial owner address
   659  	// so it initializes to the zero value
   660  	owner := service.GasPriceOracleOwnerAddress()
   661  	if *owner != (common.Address{}) {
   662  		t.Fatal("address not initialized to 0")
   663  	}
   664  
   665  	state, err := service.bc.State()
   666  	if err != nil {
   667  		t.Fatal("cannot get state db")
   668  	}
   669  
   670  	// Update the owner in the state to a non zero address
   671  	updatedOwner := common.HexToAddress("0xEA674fdDe714fd979de3EdF0F56AA9716B898ec8")
   672  	state.SetState(rcfg.L2GasPriceOracleAddress, rcfg.L2GasPriceOracleOwnerSlot, updatedOwner.Hash())
   673  	hash, _ := state.Commit(false)
   674  
   675  	// Update the cache based on the latest state root
   676  	if err := service.updateGasPriceOracleCache(&hash); err != nil {
   677  		t.Fatal(err)
   678  	}
   679  	got := service.GasPriceOracleOwnerAddress()
   680  	if *got != updatedOwner {
   681  		t.Fatalf("mismatch:\ngot %s\nexpected %s", got.Hex(), updatedOwner.Hex())
   682  	}
   683  }
   684  
   685  // Only the gas price oracle owner can send 0 gas price txs
   686  // when fees are enforced
   687  func TestFeeGasPriceOracleOwnerTransactions(t *testing.T) {
   688  	service, _, _, err := newTestSyncService(true, nil)
   689  	if err != nil {
   690  		t.Fatal(err)
   691  	}
   692  	signer := types.NewEIP155Signer(big.NewInt(420))
   693  
   694  	// Fees must be enforced for this test
   695  	service.enforceFees = true
   696  	// Generate a key
   697  	key, _ := crypto.GenerateKey()
   698  	owner := crypto.PubkeyToAddress(key.PublicKey)
   699  	// Set as the owner on the SyncService
   700  	service.gasPriceOracleOwnerAddress = owner
   701  	if owner != *service.GasPriceOracleOwnerAddress() {
   702  		t.Fatal("owner mismatch")
   703  	}
   704  	// Create a mock transaction and sign using the
   705  	// owner's key
   706  	tx := mockTx()
   707  	// Make sure the gas price is 0 on the dummy tx
   708  	if tx.GasPrice().Cmp(common.Big0) != 0 {
   709  		t.Fatal("gas price not 0")
   710  	}
   711  	// Sign the dummy tx with the owner key
   712  	signedTx, err := types.SignTx(tx, signer, key)
   713  	if err != nil {
   714  		t.Fatal(err)
   715  	}
   716  	// Verify the fee of the signed tx, ensure it does not error
   717  	if err := service.verifyFee(signedTx); err != nil {
   718  		t.Fatal(err)
   719  	}
   720  	// Generate a new random key that is not the owner
   721  	badKey, _ := crypto.GenerateKey()
   722  	// Ensure that it is not the owner
   723  	if owner == crypto.PubkeyToAddress(badKey.PublicKey) {
   724  		t.Fatal("key mismatch")
   725  	}
   726  	// Sign the transaction with the bad key
   727  	badSignedTx, err := types.SignTx(tx, signer, badKey)
   728  	if err != nil {
   729  		t.Fatal(err)
   730  	}
   731  	// Attempt to verify the fee of the bad tx
   732  	// It should error and be a errZeroGasPriceTx
   733  	if err := service.verifyFee(badSignedTx); err != nil {
   734  		if !errors.Is(errZeroGasPriceTx, err) {
   735  			t.Fatal(err)
   736  		}
   737  	} else {
   738  		t.Fatal("err is nil")
   739  	}
   740  }
   741  
   742  // Pass true to set as a verifier
   743  func TestSyncServiceSync(t *testing.T) {
   744  	service, txCh, sub, err := newTestSyncService(true, nil)
   745  	defer sub.Unsubscribe()
   746  	if err != nil {
   747  		t.Fatal(err)
   748  	}
   749  
   750  	timestamp := uint64(24)
   751  	target := common.HexToAddress("0x04668ec2f57cc15c381b461b9fedab5d451c8f7f")
   752  	l1TxOrigin := common.HexToAddress("0xEA674fdDe714fd979de3EdF0F56AA9716B898ec8")
   753  	gasLimit := uint64(66)
   754  	data := []byte{0x02, 0x92}
   755  	l1BlockNumber := big.NewInt(100)
   756  	queueIndex := uint64(0)
   757  	index := uint64(0)
   758  	tx := types.NewTransaction(0, target, big.NewInt(0), gasLimit, big.NewInt(0), data)
   759  	txMeta := types.NewTransactionMeta(
   760  		l1BlockNumber,
   761  		timestamp,
   762  		&l1TxOrigin,
   763  		types.QueueOriginL1ToL2,
   764  		&index,
   765  		&queueIndex,
   766  		nil,
   767  	)
   768  	tx.SetTransactionMeta(txMeta)
   769  
   770  	setupMockClient(service, map[string]interface{}{
   771  		"GetTransaction": []*types.Transaction{
   772  			tx,
   773  		},
   774  	})
   775  
   776  	err = nil
   777  	go func() {
   778  		err = service.syncTransactionsToTip()
   779  	}()
   780  	event := <-txCh
   781  	if err != nil {
   782  		t.Fatal("verification failed", err)
   783  	}
   784  
   785  	if len(event.Txs) != 1 {
   786  		t.Fatal("Unexpected number of transactions")
   787  	}
   788  	confirmed := event.Txs[0]
   789  
   790  	if !reflect.DeepEqual(tx, confirmed) {
   791  		t.Fatal("different txs")
   792  	}
   793  }
   794  
   795  func TestInitializeL1ContextPostGenesis(t *testing.T) {
   796  	service, _, _, err := newTestSyncService(true, nil)
   797  	if err != nil {
   798  		t.Fatal(err)
   799  	}
   800  
   801  	timestamp := uint64(24)
   802  	target := common.HexToAddress("0x04668ec2f57cc15c381b461b9fedab5d451c8f7f")
   803  	l1TxOrigin := common.HexToAddress("0xEA674fdDe714fd979de3EdF0F56AA9716B898ec8")
   804  	gasLimit := uint64(66)
   805  	data := []byte{0x02, 0x92}
   806  	l1BlockNumber := big.NewInt(100)
   807  	queueIndex := uint64(100)
   808  	index := uint64(120)
   809  	tx := types.NewTransaction(0, target, big.NewInt(0), gasLimit, big.NewInt(0), data)
   810  	txMeta := types.NewTransactionMeta(
   811  		l1BlockNumber,
   812  		timestamp,
   813  		&l1TxOrigin,
   814  		types.QueueOriginL1ToL2,
   815  		&index,
   816  		&queueIndex,
   817  		nil,
   818  	)
   819  	tx.SetTransactionMeta(txMeta)
   820  
   821  	setupMockClient(service, map[string]interface{}{
   822  		"GetEnqueue": []*types.Transaction{
   823  			tx,
   824  		},
   825  		"GetEthContext": []*EthContext{
   826  			{
   827  				BlockNumber: uint64(10),
   828  				BlockHash:   common.Hash{},
   829  				Timestamp:   timestamp,
   830  			},
   831  		},
   832  	})
   833  
   834  	header := types.Header{
   835  		Number: big.NewInt(0),
   836  		Time:   11,
   837  	}
   838  
   839  	number := uint64(10)
   840  	tx.SetL1Timestamp(timestamp)
   841  	tx.SetL1BlockNumber(number)
   842  	block := types.NewBlock(&header, []*types.Transaction{tx}, []*types.Header{}, []*types.Receipt{})
   843  	service.bc.SetCurrentBlock(block)
   844  
   845  	err = service.initializeLatestL1(big.NewInt(0))
   846  	if err != nil {
   847  		t.Fatal(err)
   848  	}
   849  
   850  	latestL1Timestamp := service.GetLatestL1Timestamp()
   851  	latestL1BlockNumber := service.GetLatestL1BlockNumber()
   852  	if number != latestL1BlockNumber {
   853  		t.Fatalf("number does not match, got %d, expected %d", latestL1BlockNumber, number)
   854  	}
   855  	if latestL1Timestamp != timestamp {
   856  		t.Fatal("timestamp does not match")
   857  	}
   858  }
   859  
   860  func TestBadFeeThresholds(t *testing.T) {
   861  	// Create the deps for the sync service
   862  	cfg, txPool, chain, db, err := newTestSyncServiceDeps(false, nil)
   863  	if err != nil {
   864  		t.Fatal(err)
   865  	}
   866  
   867  	tests := map[string]struct {
   868  		thresholdUp   *big.Float
   869  		thresholdDown *big.Float
   870  		err           error
   871  	}{
   872  		"nil-values": {
   873  			thresholdUp:   nil,
   874  			thresholdDown: nil,
   875  			err:           nil,
   876  		},
   877  		"good-values": {
   878  			thresholdUp:   new(big.Float).SetFloat64(2),
   879  			thresholdDown: new(big.Float).SetFloat64(0.8),
   880  			err:           nil,
   881  		},
   882  		"bad-value-up": {
   883  			thresholdUp:   new(big.Float).SetFloat64(0.8),
   884  			thresholdDown: nil,
   885  			err:           errBadConfig,
   886  		},
   887  		"bad-value-down": {
   888  			thresholdUp:   nil,
   889  			thresholdDown: new(big.Float).SetFloat64(1.1),
   890  			err:           errBadConfig,
   891  		},
   892  	}
   893  
   894  	for name, tt := range tests {
   895  		t.Run(name, func(t *testing.T) {
   896  			cfg.FeeThresholdDown = tt.thresholdDown
   897  			cfg.FeeThresholdUp = tt.thresholdUp
   898  
   899  			_, err := NewSyncService(context.Background(), cfg, txPool, chain, db)
   900  			if !errors.Is(err, tt.err) {
   901  				t.Fatalf("%s: %s", name, err)
   902  			}
   903  		})
   904  	}
   905  }
   906  
   907  func newTestSyncServiceDeps(isVerifier bool, alloc *common.Address) (Config, *core.TxPool, *core.BlockChain, ethdb.Database, error) {
   908  	chainCfg := params.AllEthashProtocolChanges
   909  	chainID := big.NewInt(420)
   910  	chainCfg.ChainID = chainID
   911  
   912  	engine := ethash.NewFaker()
   913  	db := rawdb.NewMemoryDatabase()
   914  	genesis := new(core.Genesis)
   915  	if alloc != nil {
   916  		genesis.Alloc = make(core.GenesisAlloc)
   917  		genesis.Alloc[*alloc] = core.GenesisAccount{
   918  			Balance: new(big.Int).SetUint64(100000000000000),
   919  		}
   920  	}
   921  	_ = genesis.MustCommit(db)
   922  	chain, err := core.NewBlockChain(db, nil, chainCfg, engine, vm.Config{}, nil)
   923  	if err != nil {
   924  		return Config{}, nil, nil, nil, fmt.Errorf("Cannot initialize blockchain: %w", err)
   925  	}
   926  	chaincfg := params.ChainConfig{ChainID: chainID}
   927  
   928  	txPool := core.NewTxPool(core.TxPoolConfig{PriceLimit: 0}, &chaincfg, chain)
   929  	cfg := Config{
   930  		CanonicalTransactionChainDeployHeight: big.NewInt(0),
   931  		IsVerifier:                            isVerifier,
   932  		// Set as an empty string as this is a dummy value anyways.
   933  		// The client needs to be mocked with a mockClient
   934  		RollupClientHttp: "",
   935  		Backend:          BackendL2,
   936  	}
   937  	return cfg, txPool, chain, db, nil
   938  }
   939  
   940  func newTestSyncService(isVerifier bool, alloc *common.Address) (*SyncService, chan core.NewTxsEvent, event.Subscription, error) {
   941  	cfg, txPool, chain, db, err := newTestSyncServiceDeps(isVerifier, alloc)
   942  	if err != nil {
   943  		return nil, nil, nil, fmt.Errorf("Cannot initialize syncservice: %w", err)
   944  	}
   945  	service, err := NewSyncService(context.Background(), cfg, txPool, chain, db)
   946  	if err != nil {
   947  		return nil, nil, nil, fmt.Errorf("Cannot initialize syncservice: %w", err)
   948  	}
   949  
   950  	service.RollupGpo = gasprice.NewRollupOracle()
   951  	txCh := make(chan core.NewTxsEvent, 1)
   952  	sub := service.SubscribeNewTxsEvent(txCh)
   953  
   954  	return service, txCh, sub, nil
   955  }
   956  
   957  type mockClient struct {
   958  	getEnqueueCallCount            int
   959  	getEnqueue                     []*types.Transaction
   960  	getRawTransactionCallCount     int
   961  	getRawTransaction              []*TransactionResponse
   962  	getTransactionCallCount        int
   963  	getTransaction                 []*types.Transaction
   964  	getEthContextCallCount         int
   965  	getEthContext                  []*EthContext
   966  	getLatestEthContext            *EthContext
   967  	getLatestEnqueueIndex          []func() (*uint64, error)
   968  	getLatestEnqueueIndexCallCount int
   969  }
   970  
   971  func setupMockClient(service *SyncService, responses map[string]interface{}) {
   972  	client := newMockClient(responses)
   973  	service.client = client
   974  	service.RollupGpo = gasprice.NewRollupOracle()
   975  }
   976  
   977  func newMockClient(responses map[string]interface{}) *mockClient {
   978  	getEnqueueResponses := []*types.Transaction{}
   979  	getRawTransactionResponses := []*TransactionResponse{}
   980  	getTransactionResponses := []*types.Transaction{}
   981  	getEthContextResponses := []*EthContext{}
   982  	getLatestEthContextResponse := &EthContext{}
   983  	getLatestEnqueueIndexResponses := []func() (*uint64, error){}
   984  
   985  	enqueue, ok := responses["GetEnqueue"]
   986  	if ok {
   987  		getEnqueueResponses = enqueue.([]*types.Transaction)
   988  	}
   989  	getRawTx, ok := responses["GetRawTransaction"]
   990  	if ok {
   991  		getRawTransactionResponses = getRawTx.([]*TransactionResponse)
   992  	}
   993  	getTx, ok := responses["GetTransaction"]
   994  	if ok {
   995  		getTransactionResponses = getTx.([]*types.Transaction)
   996  	}
   997  	getCtx, ok := responses["GetEthContext"]
   998  	if ok {
   999  		getEthContextResponses = getCtx.([]*EthContext)
  1000  	}
  1001  	getLatestCtx, ok := responses["GetLatestEthContext"]
  1002  	if ok {
  1003  		getLatestEthContextResponse = getLatestCtx.(*EthContext)
  1004  	}
  1005  	getLatestEnqueueIdx, ok := responses["GetLatestEnqueueIndex"]
  1006  	if ok {
  1007  		getLatestEnqueueIndexResponses = getLatestEnqueueIdx.([]func() (*uint64, error))
  1008  	}
  1009  
  1010  	return &mockClient{
  1011  		getEnqueue:            getEnqueueResponses,
  1012  		getRawTransaction:     getRawTransactionResponses,
  1013  		getTransaction:        getTransactionResponses,
  1014  		getEthContext:         getEthContextResponses,
  1015  		getLatestEthContext:   getLatestEthContextResponse,
  1016  		getLatestEnqueueIndex: getLatestEnqueueIndexResponses,
  1017  	}
  1018  }
  1019  
  1020  func (m *mockClient) GetEnqueue(index uint64) (*types.Transaction, error) {
  1021  	if m.getEnqueueCallCount < len(m.getEnqueue) {
  1022  		tx := m.getEnqueue[m.getEnqueueCallCount]
  1023  		m.getEnqueueCallCount++
  1024  		return tx, nil
  1025  	}
  1026  	return nil, errors.New("")
  1027  }
  1028  
  1029  func (m *mockClient) GetLatestEnqueue() (*types.Transaction, error) {
  1030  	if len(m.getEnqueue) == 0 {
  1031  		return &types.Transaction{}, errors.New("enqueue not found")
  1032  	}
  1033  	return m.getEnqueue[len(m.getEnqueue)-1], nil
  1034  }
  1035  
  1036  func (m *mockClient) GetRawTransaction(index uint64, backend Backend) (*TransactionResponse, error) {
  1037  	if m.getRawTransactionCallCount < len(m.getRawTransaction) {
  1038  		tx := m.getRawTransaction[m.getRawTransactionCallCount]
  1039  		m.getRawTransactionCallCount++
  1040  		return tx, nil
  1041  	}
  1042  	return nil, fmt.Errorf("Cannot get raw transaction: mocks (%d), call count (%d)", len(m.getRawTransaction), m.getRawTransactionCallCount)
  1043  }
  1044  
  1045  func (m *mockClient) GetTransaction(index uint64, backend Backend) (*types.Transaction, error) {
  1046  	if m.getTransactionCallCount < len(m.getTransaction) {
  1047  		tx := m.getTransaction[m.getTransactionCallCount]
  1048  		m.getTransactionCallCount++
  1049  		return tx, nil
  1050  	}
  1051  	return nil, fmt.Errorf("Cannot get transaction: mocks (%d), call count (%d)", len(m.getTransaction), m.getTransactionCallCount)
  1052  }
  1053  
  1054  func (m *mockClient) GetLatestTransaction(backend Backend) (*types.Transaction, error) {
  1055  	if len(m.getTransaction) == 0 {
  1056  		return nil, errors.New("No transactions")
  1057  	}
  1058  	return m.getTransaction[len(m.getTransaction)-1], nil
  1059  }
  1060  
  1061  func (m *mockClient) GetEthContext(index uint64) (*EthContext, error) {
  1062  	if m.getEthContextCallCount < len(m.getEthContext) {
  1063  		ctx := m.getEthContext[m.getEthContextCallCount]
  1064  		m.getEthContextCallCount++
  1065  		return ctx, nil
  1066  	}
  1067  	return nil, errors.New("Cannot get eth context")
  1068  }
  1069  
  1070  func (m *mockClient) GetLatestEthContext() (*EthContext, error) {
  1071  	return m.getLatestEthContext, nil
  1072  }
  1073  
  1074  func (m *mockClient) GetLastConfirmedEnqueue() (*types.Transaction, error) {
  1075  	return nil, errElementNotFound
  1076  }
  1077  
  1078  func (m *mockClient) GetLatestTransactionBatch() (*Batch, []*types.Transaction, error) {
  1079  	return nil, nil, nil
  1080  }
  1081  
  1082  func (m *mockClient) GetTransactionBatch(index uint64) (*Batch, []*types.Transaction, error) {
  1083  	return nil, nil, nil
  1084  }
  1085  
  1086  func (m *mockClient) SyncStatus(backend Backend) (*SyncStatus, error) {
  1087  	return &SyncStatus{
  1088  		Syncing: false,
  1089  	}, nil
  1090  }
  1091  
  1092  func (m *mockClient) GetLatestEnqueueIndex() (*uint64, error) {
  1093  	enqueue, err := m.GetLatestEnqueue()
  1094  	if err != nil {
  1095  		return nil, err
  1096  	}
  1097  	if enqueue == nil {
  1098  		return nil, errElementNotFound
  1099  	}
  1100  	return enqueue.GetMeta().QueueIndex, nil
  1101  }
  1102  
  1103  func (m *mockClient) GetLatestTransactionBatchIndex() (*uint64, error) {
  1104  	return nil, nil
  1105  }
  1106  
  1107  func (m *mockClient) GetLatestTransactionIndex(backend Backend) (*uint64, error) {
  1108  	tx, err := m.GetLatestTransaction(backend)
  1109  	if err != nil {
  1110  		return nil, err
  1111  	}
  1112  	return tx.GetMeta().Index, nil
  1113  }
  1114  
  1115  func mockTx() *types.Transaction {
  1116  	address := make([]byte, 20)
  1117  	rand.Read(address)
  1118  
  1119  	target := common.BytesToAddress(address)
  1120  	timestamp := uint64(0)
  1121  
  1122  	rand.Read(address)
  1123  	l1TxOrigin := common.BytesToAddress(address)
  1124  
  1125  	gasLimit := uint64(0)
  1126  	data := []byte{0x00, 0x00}
  1127  	l1BlockNumber := big.NewInt(0)
  1128  
  1129  	tx := types.NewTransaction(0, target, big.NewInt(0), gasLimit, big.NewInt(0), data)
  1130  	meta := types.NewTransactionMeta(
  1131  		l1BlockNumber,
  1132  		timestamp,
  1133  		&l1TxOrigin,
  1134  		types.QueueOriginSequencer,
  1135  		nil,
  1136  		nil,
  1137  		nil,
  1138  	)
  1139  	tx.SetTransactionMeta(meta)
  1140  	return tx
  1141  }
  1142  
  1143  func setMockTxL1Timestamp(tx *types.Transaction, ts uint64) *types.Transaction {
  1144  	meta := tx.GetMeta()
  1145  	meta.L1Timestamp = ts
  1146  	tx.SetTransactionMeta(meta)
  1147  	return tx
  1148  }
  1149  
  1150  func setMockTxL1BlockNumber(tx *types.Transaction, bn *big.Int) *types.Transaction {
  1151  	meta := tx.GetMeta()
  1152  	meta.L1BlockNumber = bn
  1153  	tx.SetTransactionMeta(meta)
  1154  	return tx
  1155  }
  1156  
  1157  func setMockTxIndex(tx *types.Transaction, index uint64) *types.Transaction {
  1158  	meta := tx.GetMeta()
  1159  	meta.Index = &index
  1160  	tx.SetTransactionMeta(meta)
  1161  	return tx
  1162  }
  1163  
  1164  func setMockQueueIndex(tx *types.Transaction, index uint64) *types.Transaction {
  1165  	meta := tx.GetMeta()
  1166  	meta.QueueIndex = &index
  1167  	tx.SetTransactionMeta(meta)
  1168  	return tx
  1169  }
  1170  
  1171  func setMockQueueOrigin(tx *types.Transaction, qo types.QueueOrigin) *types.Transaction {
  1172  	meta := tx.GetMeta()
  1173  	meta.QueueOrigin = qo
  1174  	tx.SetTransactionMeta(meta)
  1175  	return tx
  1176  }
  1177  
  1178  func newUint64(n uint64) *uint64 {
  1179  	return &n
  1180  }