github.com/cryptotooltop/go-ethereum@v0.0.0-20231103184714-151d1922f3e5/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 "hash" 22 "math/big" 23 "testing" 24 25 "golang.org/x/crypto/sha3" 26 27 "github.com/scroll-tech/go-ethereum/common" 28 "github.com/scroll-tech/go-ethereum/core/types" 29 "github.com/scroll-tech/go-ethereum/ethdb" 30 "github.com/scroll-tech/go-ethereum/params" 31 "github.com/scroll-tech/go-ethereum/rlp" 32 ) 33 34 // testHasher is the helper tool for transaction/receipt list hashing. 35 // The original hasher is trie, in order to get rid of import cycle, 36 // use the testing hasher instead. 37 type testHasher struct { 38 hasher hash.Hash 39 } 40 41 func newHasher() *testHasher { 42 return &testHasher{hasher: sha3.NewLegacyKeccak256()} 43 } 44 45 func (h *testHasher) Reset() { 46 h.hasher.Reset() 47 } 48 49 func (h *testHasher) Update(key, val []byte) { 50 h.hasher.Write(key) 51 h.hasher.Write(val) 52 } 53 54 func (h *testHasher) Hash() common.Hash { 55 return common.BytesToHash(h.hasher.Sum(nil)) 56 } 57 58 // Tests that positional lookup metadata can be stored and retrieved. 59 func TestLookupStorage(t *testing.T) { 60 tests := []struct { 61 name string 62 writeTxLookupEntriesByBlock func(ethdb.Writer, *types.Block) 63 }{ 64 { 65 "DatabaseV6", 66 func(db ethdb.Writer, block *types.Block) { 67 WriteTxLookupEntriesByBlock(db, block) 68 }, 69 }, 70 { 71 "DatabaseV4-V5", 72 func(db ethdb.Writer, block *types.Block) { 73 for _, tx := range block.Transactions() { 74 db.Put(txLookupKey(tx.Hash()), block.Hash().Bytes()) 75 } 76 }, 77 }, 78 { 79 "DatabaseV3", 80 func(db ethdb.Writer, block *types.Block) { 81 for index, tx := range block.Transactions() { 82 entry := LegacyTxLookupEntry{ 83 BlockHash: block.Hash(), 84 BlockIndex: block.NumberU64(), 85 Index: uint64(index), 86 } 87 data, _ := rlp.EncodeToBytes(entry) 88 db.Put(txLookupKey(tx.Hash()), data) 89 } 90 }, 91 }, 92 } 93 94 for _, tc := range tests { 95 t.Run(tc.name, func(t *testing.T) { 96 db := NewMemoryDatabase() 97 98 tx1 := types.NewTransaction(1, common.BytesToAddress([]byte{0x11}), big.NewInt(111), 1111, big.NewInt(11111), []byte{0x11, 0x11, 0x11}) 99 tx2 := types.NewTransaction(2, common.BytesToAddress([]byte{0x22}), big.NewInt(222), 2222, big.NewInt(22222), []byte{0x22, 0x22, 0x22}) 100 tx3 := types.NewTransaction(3, common.BytesToAddress([]byte{0x33}), big.NewInt(333), 3333, big.NewInt(33333), []byte{0x33, 0x33, 0x33}) 101 txs := []*types.Transaction{tx1, tx2, tx3} 102 103 block := types.NewBlock(&types.Header{Number: big.NewInt(314)}, txs, nil, nil, newHasher()) 104 105 // Check that no transactions entries are in a pristine database 106 for i, tx := range txs { 107 if txn, _, _, _ := ReadTransaction(db, tx.Hash()); txn != nil { 108 t.Fatalf("tx #%d [%x]: non existent transaction returned: %v", i, tx.Hash(), txn) 109 } 110 } 111 // Insert all the transactions into the database, and verify contents 112 WriteCanonicalHash(db, block.Hash(), block.NumberU64()) 113 WriteBlock(db, block) 114 tc.writeTxLookupEntriesByBlock(db, block) 115 116 for i, tx := range txs { 117 if txn, hash, number, index := ReadTransaction(db, tx.Hash()); txn == nil { 118 t.Fatalf("tx #%d [%x]: transaction not found", i, tx.Hash()) 119 } else { 120 if hash != block.Hash() || number != block.NumberU64() || index != uint64(i) { 121 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) 122 } 123 if tx.Hash() != txn.Hash() { 124 t.Fatalf("tx #%d [%x]: transaction mismatch: have %v, want %v", i, tx.Hash(), txn, tx) 125 } 126 } 127 } 128 // Delete the transactions and check purge 129 for i, tx := range txs { 130 DeleteTxLookupEntry(db, tx.Hash()) 131 if txn, _, _, _ := ReadTransaction(db, tx.Hash()); txn != nil { 132 t.Fatalf("tx #%d [%x]: deleted transaction returned: %v", i, tx.Hash(), txn) 133 } 134 } 135 }) 136 } 137 } 138 139 func TestDeleteBloomBits(t *testing.T) { 140 // Prepare testing data 141 db := NewMemoryDatabase() 142 for i := uint(0); i < 2; i++ { 143 for s := uint64(0); s < 2; s++ { 144 WriteBloomBits(db, i, s, params.MainnetGenesisHash, []byte{0x01, 0x02}) 145 WriteBloomBits(db, i, s, params.RinkebyGenesisHash, []byte{0x01, 0x02}) 146 } 147 } 148 check := func(bit uint, section uint64, head common.Hash, exist bool) { 149 bits, _ := ReadBloomBits(db, bit, section, head) 150 if exist && !bytes.Equal(bits, []byte{0x01, 0x02}) { 151 t.Fatalf("Bloombits mismatch") 152 } 153 if !exist && len(bits) > 0 { 154 t.Fatalf("Bloombits should be removed") 155 } 156 } 157 // Check the existence of written data. 158 check(0, 0, params.MainnetGenesisHash, true) 159 check(0, 0, params.RinkebyGenesisHash, true) 160 161 // Check the existence of deleted data. 162 DeleteBloombits(db, 0, 0, 1) 163 check(0, 0, params.MainnetGenesisHash, false) 164 check(0, 0, params.RinkebyGenesisHash, false) 165 check(0, 1, params.MainnetGenesisHash, true) 166 check(0, 1, params.RinkebyGenesisHash, true) 167 168 // Check the existence of deleted data. 169 DeleteBloombits(db, 0, 0, 2) 170 check(0, 0, params.MainnetGenesisHash, false) 171 check(0, 0, params.RinkebyGenesisHash, false) 172 check(0, 1, params.MainnetGenesisHash, false) 173 check(0, 1, params.RinkebyGenesisHash, false) 174 175 // Bit1 shouldn't be affect. 176 check(1, 0, params.MainnetGenesisHash, true) 177 check(1, 0, params.RinkebyGenesisHash, true) 178 check(1, 1, params.MainnetGenesisHash, true) 179 check(1, 1, params.RinkebyGenesisHash, true) 180 }