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