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  }