From 5ca23eb17aa0b06cc3748ec0b1befc96beec1fe6 Mon Sep 17 00:00:00 2001 From: colinlyguo Date: Mon, 5 Feb 2024 00:24:18 +0800 Subject: [PATCH] add unit tests --- common/testdata/blockTrace_04.json | 2 +- .../controller/watcher/chunk_proposer_test.go | 2 +- rollup/internal/orm/l2_block.go | 74 +++++++++++++++++++ rollup/internal/orm/orm_test.go | 51 ++++++++----- 4 files changed, 108 insertions(+), 21 deletions(-) diff --git a/common/testdata/blockTrace_04.json b/common/testdata/blockTrace_04.json index 84da2946c3..5595540685 100644 --- a/common/testdata/blockTrace_04.json +++ b/common/testdata/blockTrace_04.json @@ -16,7 +16,7 @@ "receiptsRoot": "0x7ad169feb178baf74f7c0a12a28570bd69bd10e616acad2caea09a55fd1fb541", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "difficulty": "0x2", - "number": "0xd", + "number": "0x3", "gasLimit": "0x7a1200", "gasUsed": "0x5dc0", "timestamp": "0x646b6e13", diff --git a/rollup/internal/controller/watcher/chunk_proposer_test.go b/rollup/internal/controller/watcher/chunk_proposer_test.go index a733682aaf..0df93ad8e2 100644 --- a/rollup/internal/controller/watcher/chunk_proposer_test.go +++ b/rollup/internal/controller/watcher/chunk_proposer_test.go @@ -170,7 +170,7 @@ func testChunkProposerLimits(t *testing.T) { if len(chunks) > 0 { blockOrm := orm.NewL2Block(db) - blocks, err := blockOrm.GetL2Blocks(context.Background(), map[string]interface{}{}, []string{"number ASC"}, tt.expectedBlocksInFirstChunk) + blocks, err := blockOrm.GetL2Blocks(context.Background(), nil, nil, 0) assert.NoError(t, err) assert.Len(t, blocks, tt.expectedBlocksInFirstChunk) for _, block := range blocks { diff --git a/rollup/internal/orm/l2_block.go b/rollup/internal/orm/l2_block.go index 6aedee5548..7a68e04b3f 100644 --- a/rollup/internal/orm/l2_block.go +++ b/rollup/internal/orm/l2_block.go @@ -124,6 +124,7 @@ func (o *L2Block) GetL2WrappedBlocksGEHeight(ctx context.Context, height uint64, // GetL2Blocks retrieves selected L2Blocks from the database. // The returned L2Blocks are sorted in ascending order by their block number. +// only used for unit tests. func (o *L2Block) GetL2Blocks(ctx context.Context, fields map[string]interface{}, orderByList []string, limit int) ([]*L2Block, error) { db := o.db.WithContext(ctx) db = db.Model(&L2Block{}) @@ -299,6 +300,7 @@ type TransactionData struct { S *hexutil.Big `json:"s"` } +// This is used for backward compatibility. func decodeTransactionDataJSON(encodedTx []byte) ([]*gethTypes.Transaction, error) { var txData []*TransactionData if jsonErr := json.Unmarshal(encodedTx, &txData); jsonErr != nil { @@ -346,3 +348,75 @@ func decodeTransactionDataJSON(encodedTx []byte) ([]*gethTypes.Transaction, erro return transactions, nil } + +// newTransactionData returns a transaction that will serialize to the trace +// representation, with the given location metadata set (if available). +// only used for unit tests. +func newTransactionData(tx *gethTypes.Transaction) *TransactionData { + v, r, s := tx.RawSignatureValues() + + nonce := tx.Nonce() + if tx.IsL1MessageTx() { + nonce = tx.L1MessageQueueIndex() + } + + result := &TransactionData{ + Type: tx.Type(), + Nonce: nonce, + Gas: tx.Gas(), + GasPrice: (*hexutil.Big)(tx.GasPrice()), + To: tx.To(), + Value: (*hexutil.Big)(tx.Value()), + Data: hexutil.Encode(tx.Data()), + V: (*hexutil.Big)(v), + R: (*hexutil.Big)(r), + S: (*hexutil.Big)(s), + } + + if tx.IsL1MessageTx() { + result.From = tx.AsL1MessageTx().Sender + } + + return result +} + +// only used for unit tests. +func (o *L2Block) updateTransactions(ctx context.Context) error { + l2Blocks, err := o.GetL2Blocks(ctx, nil, nil, 0) + if err != nil { + return fmt.Errorf("failed to get L2Blocks: %w", err) + } + + for _, block := range l2Blocks { + var transactions []*gethTypes.Transaction + err := rlp.DecodeBytes(block.TransactionsRLP, &transactions) + if err != nil { + return fmt.Errorf("L2Block.GetL2BlocksInRange: failed to decode transactions_rlp, err: %w", err) + } + + var txDataSlice []*TransactionData + for _, tx := range transactions { + txData := newTransactionData(tx) + txDataSlice = append(txDataSlice, txData) + } + + txDataJSON, err := json.Marshal(txDataSlice) + if err != nil { + return fmt.Errorf("failed to JSON encode transactions for block %d: %w", block.Number, err) + } + + updateMap := map[string]interface{}{ + "transactions": string(txDataJSON), + "transactions_rlp": "", + } + + db := o.db.WithContext(ctx) + db = db.Model(&L2Block{}) + db = db.Where("hash", block.Hash) + if err := db.Updates(updateMap).Error; err != nil { + return fmt.Errorf("failed to update transactions JSON and clear transactions for block %d: %w", block.Number, err) + } + } + + return nil +} diff --git a/rollup/internal/orm/orm_test.go b/rollup/internal/orm/orm_test.go index c350f31580..6451aba87d 100644 --- a/rollup/internal/orm/orm_test.go +++ b/rollup/internal/orm/orm_test.go @@ -71,7 +71,7 @@ func setupEnv(t *testing.T) { err = json.Unmarshal(templateBlockTrace, wrappedBlock1) assert.NoError(t, err) - templateBlockTrace, err = os.ReadFile("../../../common/testdata/blockTrace_03.json") + templateBlockTrace, err = os.ReadFile("../../../common/testdata/blockTrace_04.json") assert.NoError(t, err) wrappedBlock2 = &rollupTypes.WrappedBlock{} err = json.Unmarshal(templateBlockTrace, wrappedBlock2) @@ -152,38 +152,51 @@ func TestL2BlockOrm(t *testing.T) { assert.NoError(t, err) assert.Equal(t, uint64(3), height) - blocks, err := l2BlockOrm.GetL2Blocks(context.Background(), map[string]interface{}{}, []string{}, 0) + blocks, err := l2BlockOrm.GetL2Blocks(context.Background(), nil, nil, 0) assert.NoError(t, err) assert.Len(t, blocks, 2) assert.Equal(t, "", blocks[0].ChunkHash) assert.Equal(t, "", blocks[1].ChunkHash) - wrappedBlocks, err := l2BlockOrm.GetL2BlocksInRange(context.Background(), 2, 3) + wrappedBlocks1, err := l2BlockOrm.GetL2BlocksInRange(context.Background(), 2, 3) assert.NoError(t, err) - assert.Len(t, blocks, 2) - assert.Equal(t, wrappedBlock1.Header, wrappedBlocks[0].Header) - assert.Equal(t, wrappedBlock1.RowConsumption, wrappedBlocks[0].RowConsumption) - assert.Equal(t, wrappedBlock1.WithdrawRoot, wrappedBlocks[0].WithdrawRoot) - assert.Equal(t, len(wrappedBlock1.Transactions), len(wrappedBlocks[0].Transactions)) - for i := range wrappedBlock1.Transactions { - assert.Equal(t, wrappedBlock1.Transactions[i].Hash(), wrappedBlocks[0].Transactions[i].Hash()) - } - assert.Equal(t, wrappedBlock2.Header, wrappedBlocks[1].Header) - assert.Equal(t, wrappedBlock2.RowConsumption, wrappedBlocks[1].RowConsumption) - assert.Equal(t, wrappedBlock2.WithdrawRoot, wrappedBlocks[1].WithdrawRoot) - assert.Equal(t, len(wrappedBlock2.Transactions), len(wrappedBlocks[1].Transactions)) - for i := range wrappedBlock2.Transactions { - assert.Equal(t, wrappedBlock2.Transactions[i].Hash(), wrappedBlocks[1].Transactions[i].Hash()) - } + assertWrappedBlockEquality(t, []*rollupTypes.WrappedBlock{wrappedBlock1, wrappedBlock2}, wrappedBlocks1) + + wrappedBlocks2, err := l2BlockOrm.GetL2WrappedBlocksGEHeight(context.Background(), 0, 2) + assert.NoError(t, err) + assertWrappedBlockEquality(t, []*rollupTypes.WrappedBlock{wrappedBlock1, wrappedBlock2}, wrappedBlocks2) err = l2BlockOrm.UpdateChunkHashInRange(context.Background(), 2, 2, "test hash") assert.NoError(t, err) - blocks, err = l2BlockOrm.GetL2Blocks(context.Background(), map[string]interface{}{}, []string{}, 0) + blocks, err = l2BlockOrm.GetL2Blocks(context.Background(), nil, nil, 0) assert.NoError(t, err) assert.Len(t, blocks, 2) assert.Equal(t, "test hash", blocks[0].ChunkHash) assert.Equal(t, "", blocks[1].ChunkHash) + + err = l2BlockOrm.updateTransactions(context.Background()) + assert.NoError(t, err) + + wrappedBlocks1, err = l2BlockOrm.GetL2BlocksInRange(context.Background(), 2, 3) + assertWrappedBlockEquality(t, []*rollupTypes.WrappedBlock{wrappedBlock1, wrappedBlock2}, wrappedBlocks1) + + wrappedBlocks2, err = l2BlockOrm.GetL2WrappedBlocksGEHeight(context.Background(), 0, 2) + assert.NoError(t, err) + assertWrappedBlockEquality(t, []*rollupTypes.WrappedBlock{wrappedBlock1, wrappedBlock2}, wrappedBlocks2) +} + +func assertWrappedBlockEquality(t *testing.T, expected, actual []*rollupTypes.WrappedBlock) { + assert.Len(t, actual, len(expected)) + for i := range expected { + assert.Equal(t, expected[i].Header, actual[i].Header) + assert.Equal(t, expected[i].RowConsumption, actual[i].RowConsumption) + assert.Equal(t, expected[i].WithdrawRoot, actual[i].WithdrawRoot) + assert.Equal(t, len(expected[i].Transactions), len(actual[i].Transactions)) + for j := range expected[i].Transactions { + assert.Equal(t, expected[i].Transactions[j].Hash(), actual[i].Transactions[j].Hash()) + } + } } func TestChunkOrm(t *testing.T) {