github.com/MetalBlockchain/subnet-evm@v0.6.3/core/rawdb/accessors_indexes_test.go (about)

     1  // Copyright 2018 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package rawdb
    18  
    19  import (
    20  	"bytes"
    21  	"math/big"
    22  	"testing"
    23  
    24  	"github.com/MetalBlockchain/subnet-evm/core/types"
    25  	"github.com/MetalBlockchain/subnet-evm/internal/blocktest"
    26  	"github.com/ethereum/go-ethereum/common"
    27  	"github.com/ethereum/go-ethereum/ethdb"
    28  	"github.com/ethereum/go-ethereum/rlp"
    29  )
    30  
    31  var newTestHasher = blocktest.NewHasher
    32  
    33  // Tests that positional lookup metadata can be stored and retrieved.
    34  func TestLookupStorage(t *testing.T) {
    35  	tests := []struct {
    36  		name                        string
    37  		writeTxLookupEntriesByBlock func(ethdb.Writer, *types.Block)
    38  	}{
    39  		{
    40  			"DatabaseV6",
    41  			func(db ethdb.Writer, block *types.Block) {
    42  				WriteTxLookupEntriesByBlock(db, block)
    43  			},
    44  		},
    45  		{
    46  			"DatabaseV4-V5",
    47  			func(db ethdb.Writer, block *types.Block) {
    48  				for _, tx := range block.Transactions() {
    49  					db.Put(txLookupKey(tx.Hash()), block.Hash().Bytes())
    50  				}
    51  			},
    52  		},
    53  		{
    54  			"DatabaseV3",
    55  			func(db ethdb.Writer, block *types.Block) {
    56  				for index, tx := range block.Transactions() {
    57  					entry := LegacyTxLookupEntry{
    58  						BlockHash:  block.Hash(),
    59  						BlockIndex: block.NumberU64(),
    60  						Index:      uint64(index),
    61  					}
    62  					data, _ := rlp.EncodeToBytes(entry)
    63  					db.Put(txLookupKey(tx.Hash()), data)
    64  				}
    65  			},
    66  		},
    67  	}
    68  
    69  	for _, tc := range tests {
    70  		t.Run(tc.name, func(t *testing.T) {
    71  			db := NewMemoryDatabase()
    72  
    73  			tx1 := types.NewTransaction(1, common.BytesToAddress([]byte{0x11}), big.NewInt(111), 1111, big.NewInt(11111), []byte{0x11, 0x11, 0x11})
    74  			tx2 := types.NewTransaction(2, common.BytesToAddress([]byte{0x22}), big.NewInt(222), 2222, big.NewInt(22222), []byte{0x22, 0x22, 0x22})
    75  			tx3 := types.NewTransaction(3, common.BytesToAddress([]byte{0x33}), big.NewInt(333), 3333, big.NewInt(33333), []byte{0x33, 0x33, 0x33})
    76  			txs := []*types.Transaction{tx1, tx2, tx3}
    77  
    78  			block := types.NewBlock(&types.Header{Number: big.NewInt(314)}, txs, nil, nil, newTestHasher())
    79  
    80  			// Check that no transactions entries are in a pristine database
    81  			for i, tx := range txs {
    82  				if txn, _, _, _ := ReadTransaction(db, tx.Hash()); txn != nil {
    83  					t.Fatalf("tx #%d [%x]: non existent transaction returned: %v", i, tx.Hash(), txn)
    84  				}
    85  			}
    86  			// Insert all the transactions into the database, and verify contents
    87  			WriteCanonicalHash(db, block.Hash(), block.NumberU64())
    88  			WriteBlock(db, block)
    89  			tc.writeTxLookupEntriesByBlock(db, block)
    90  
    91  			for i, tx := range txs {
    92  				if txn, hash, number, index := ReadTransaction(db, tx.Hash()); txn == nil {
    93  					t.Fatalf("tx #%d [%x]: transaction not found", i, tx.Hash())
    94  				} else {
    95  					if hash != block.Hash() || number != block.NumberU64() || index != uint64(i) {
    96  						t.Fatalf("tx #%d [%x]: positional metadata mismatch: have %x/%d/%d, want %x/%v/%v", i, tx.Hash(), hash, number, index, block.Hash(), block.NumberU64(), i)
    97  					}
    98  					if tx.Hash() != txn.Hash() {
    99  						t.Fatalf("tx #%d [%x]: transaction mismatch: have %v, want %v", i, tx.Hash(), txn, tx)
   100  					}
   101  				}
   102  			}
   103  			// Delete the transactions and check purge
   104  			for i, tx := range txs {
   105  				DeleteTxLookupEntry(db, tx.Hash())
   106  				if txn, _, _, _ := ReadTransaction(db, tx.Hash()); txn != nil {
   107  					t.Fatalf("tx #%d [%x]: deleted transaction returned: %v", i, tx.Hash(), txn)
   108  				}
   109  			}
   110  		})
   111  	}
   112  }
   113  
   114  func TestDeleteBloomBits(t *testing.T) {
   115  	// Prepare testing data
   116  	db := NewMemoryDatabase()
   117  
   118  	genesisHash0 := common.BytesToHash([]byte{1, 2, 3, 4, 5})
   119  	genesisHash1 := common.BytesToHash([]byte{5, 4, 3, 2, 1})
   120  	for i := uint(0); i < 2; i++ {
   121  		for s := uint64(0); s < 2; s++ {
   122  			WriteBloomBits(db, i, s, genesisHash0, []byte{0x01, 0x02})
   123  			WriteBloomBits(db, i, s, genesisHash1, []byte{0x01, 0x02})
   124  		}
   125  	}
   126  	check := func(bit uint, section uint64, head common.Hash, exist bool) {
   127  		bits, _ := ReadBloomBits(db, bit, section, head)
   128  		if exist && !bytes.Equal(bits, []byte{0x01, 0x02}) {
   129  			t.Fatalf("Bloombits mismatch")
   130  		}
   131  		if !exist && len(bits) > 0 {
   132  			t.Fatalf("Bloombits should be removed")
   133  		}
   134  	}
   135  	// Check the existence of written data.
   136  	check(0, 0, genesisHash0, true)
   137  	check(0, 0, genesisHash1, true)
   138  
   139  	// Check the existence of deleted data.
   140  	DeleteBloombits(db, 0, 0, 1)
   141  	check(0, 0, genesisHash0, false)
   142  	check(0, 0, genesisHash1, false)
   143  	check(0, 1, genesisHash0, true)
   144  	check(0, 1, genesisHash1, true)
   145  
   146  	// Check the existence of deleted data.
   147  	DeleteBloombits(db, 0, 0, 2)
   148  	check(0, 0, genesisHash0, false)
   149  	check(0, 0, genesisHash1, false)
   150  	check(0, 1, genesisHash0, false)
   151  	check(0, 1, genesisHash1, false)
   152  
   153  	// Bit1 shouldn't be affect.
   154  	check(1, 0, genesisHash0, true)
   155  	check(1, 0, genesisHash1, true)
   156  	check(1, 1, genesisHash0, true)
   157  	check(1, 1, genesisHash1, true)
   158  }