github.com/cryptotooltop/go-ethereum@v0.0.0-20231103184714-151d1922f3e5/core/rawdb/accessors_skipped_txs_test.go (about)

     1  package rawdb
     2  
     3  import (
     4  	"math/big"
     5  	"sync"
     6  	"testing"
     7  
     8  	"github.com/scroll-tech/go-ethereum/common"
     9  	"github.com/scroll-tech/go-ethereum/core/types"
    10  )
    11  
    12  func TestReadWriteNumSkippedTransactions(t *testing.T) {
    13  	blockNumbers := []uint64{
    14  		1,
    15  		1 << 2,
    16  		1 << 8,
    17  		1 << 16,
    18  		1 << 32,
    19  	}
    20  
    21  	db := NewMemoryDatabase()
    22  	for _, num := range blockNumbers {
    23  		writeNumSkippedTransactions(db, num)
    24  		got := ReadNumSkippedTransactions(db)
    25  
    26  		if got != num {
    27  			t.Fatal("Num skipped transactions mismatch", "expected", num, "got", got)
    28  		}
    29  	}
    30  }
    31  
    32  func newTestTransaction(queueIndex uint64) *types.Transaction {
    33  	l1msg := types.L1MessageTx{
    34  		QueueIndex: queueIndex,
    35  		Gas:        0,
    36  		To:         &common.Address{},
    37  		Value:      big.NewInt(0),
    38  		Data:       nil,
    39  		Sender:     common.Address{},
    40  	}
    41  	return types.NewTx(&l1msg)
    42  }
    43  
    44  func TestReadWriteSkippedTransactionNoIndex(t *testing.T) {
    45  	tx := newTestTransaction(123)
    46  	db := NewMemoryDatabase()
    47  	writeSkippedTransaction(db, tx, nil, "random reason", 1, &common.Hash{1})
    48  	got := ReadSkippedTransaction(db, tx.Hash())
    49  	if got == nil || got.Tx.Hash() != tx.Hash() || got.Reason != "random reason" || got.BlockNumber != 1 || got.BlockHash == nil || *got.BlockHash != (common.Hash{1}) {
    50  		t.Fatal("Skipped transaction mismatch", "got", got)
    51  	}
    52  }
    53  
    54  func TestReadSkippedTransactionV1AsV2(t *testing.T) {
    55  	tx := newTestTransaction(123)
    56  	db := NewMemoryDatabase()
    57  	writeSkippedTransactionV1(db, tx, "random reason", 1, &common.Hash{1})
    58  	got := ReadSkippedTransaction(db, tx.Hash())
    59  	if got == nil || got.Tx.Hash() != tx.Hash() || got.Reason != "random reason" || got.BlockNumber != 1 || got.BlockHash == nil || *got.BlockHash != (common.Hash{1}) {
    60  		t.Fatal("Skipped transaction mismatch", "got", got)
    61  	}
    62  }
    63  
    64  func TestReadWriteSkippedTransaction(t *testing.T) {
    65  	tx := newTestTransaction(123)
    66  	db := NewMemoryDatabase()
    67  	WriteSkippedTransaction(db, tx, nil, "random reason", 1, &common.Hash{1})
    68  	got := ReadSkippedTransaction(db, tx.Hash())
    69  	if got == nil || got.Tx.Hash() != tx.Hash() || got.Reason != "random reason" || got.BlockNumber != 1 || got.BlockHash == nil || *got.BlockHash != (common.Hash{1}) {
    70  		t.Fatal("Skipped transaction mismatch", "got", got)
    71  	}
    72  	count := ReadNumSkippedTransactions(db)
    73  	if count != 1 {
    74  		t.Fatal("Skipped transaction count mismatch", "expected", 1, "got", count)
    75  	}
    76  	hash := ReadSkippedTransactionHash(db, 0)
    77  	if hash == nil || *hash != tx.Hash() {
    78  		t.Fatal("Skipped L1 message hash mismatch", "expected", tx.Hash(), "got", hash)
    79  	}
    80  }
    81  
    82  func TestSkippedTransactionConcurrentUpdate(t *testing.T) {
    83  	count := 20
    84  	tx := newTestTransaction(123)
    85  	db := NewMemoryDatabase()
    86  	var wg sync.WaitGroup
    87  	for ii := 0; ii < count; ii++ {
    88  		wg.Add(1)
    89  		go func() {
    90  			defer wg.Done()
    91  			WriteSkippedTransaction(db, tx, nil, "random reason", 1, &common.Hash{1})
    92  		}()
    93  	}
    94  	wg.Wait()
    95  	got := ReadNumSkippedTransactions(db)
    96  	if got != uint64(count) {
    97  		t.Fatal("Skipped transaction count mismatch", "expected", count, "got", got)
    98  	}
    99  }
   100  
   101  func TestIterateSkippedTransactions(t *testing.T) {
   102  	db := NewMemoryDatabase()
   103  
   104  	txs := []*types.Transaction{
   105  		newTestTransaction(1),
   106  		newTestTransaction(2),
   107  		newTestTransaction(3),
   108  		newTestTransaction(4),
   109  		newTestTransaction(5),
   110  	}
   111  
   112  	for _, tx := range txs {
   113  		WriteSkippedTransaction(db, tx, nil, "random reason", 1, &common.Hash{1})
   114  	}
   115  
   116  	// simulate skipped L2 tx that's not included in the index
   117  	l2tx := newTestTransaction(6)
   118  	writeSkippedTransaction(db, l2tx, nil, "random reason", 1, &common.Hash{1})
   119  
   120  	it := IterateSkippedTransactionsFrom(db, 2)
   121  	defer it.Release()
   122  
   123  	for ii := 2; ii < len(txs); ii++ {
   124  		finished := !it.Next()
   125  		if finished {
   126  			t.Fatal("Iterator terminated early", "ii", ii)
   127  		}
   128  
   129  		index := it.Index()
   130  		if index != uint64(ii) {
   131  			t.Fatal("Invalid skipped transaction index", "expected", ii, "got", index)
   132  		}
   133  
   134  		hash := it.TransactionHash()
   135  		if hash != txs[ii].Hash() {
   136  			t.Fatal("Invalid skipped transaction hash", "expected", txs[ii].Hash(), "got", hash)
   137  		}
   138  	}
   139  
   140  	finished := !it.Next()
   141  	if !finished {
   142  		t.Fatal("Iterator did not terminate")
   143  	}
   144  }