github.com/shrimpyuk/bor@v0.2.15-0.20220224151350-fb4ec6020bae/core/rawdb/accessors_chain_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  	"encoding/hex"
    22  	"fmt"
    23  	"io/ioutil"
    24  	"math/big"
    25  	"math/rand"
    26  	"os"
    27  	"reflect"
    28  	"testing"
    29  
    30  	"github.com/ethereum/go-ethereum/common"
    31  	"github.com/ethereum/go-ethereum/core/types"
    32  	"github.com/ethereum/go-ethereum/crypto"
    33  	"github.com/ethereum/go-ethereum/params"
    34  	"github.com/ethereum/go-ethereum/rlp"
    35  	"golang.org/x/crypto/sha3"
    36  )
    37  
    38  // Tests block header storage and retrieval operations.
    39  func TestHeaderStorage(t *testing.T) {
    40  	db := NewMemoryDatabase()
    41  
    42  	// Create a test header to move around the database and make sure it's really new
    43  	header := &types.Header{Number: big.NewInt(42), Extra: []byte("test header")}
    44  	if entry := ReadHeader(db, header.Hash(), header.Number.Uint64()); entry != nil {
    45  		t.Fatalf("Non existent header returned: %v", entry)
    46  	}
    47  	// Write and verify the header in the database
    48  	WriteHeader(db, header)
    49  	if entry := ReadHeader(db, header.Hash(), header.Number.Uint64()); entry == nil {
    50  		t.Fatalf("Stored header not found")
    51  	} else if entry.Hash() != header.Hash() {
    52  		t.Fatalf("Retrieved header mismatch: have %v, want %v", entry, header)
    53  	}
    54  	if entry := ReadHeaderRLP(db, header.Hash(), header.Number.Uint64()); entry == nil {
    55  		t.Fatalf("Stored header RLP not found")
    56  	} else {
    57  		hasher := sha3.NewLegacyKeccak256()
    58  		hasher.Write(entry)
    59  
    60  		if hash := common.BytesToHash(hasher.Sum(nil)); hash != header.Hash() {
    61  			t.Fatalf("Retrieved RLP header mismatch: have %v, want %v", entry, header)
    62  		}
    63  	}
    64  	// Delete the header and verify the execution
    65  	DeleteHeader(db, header.Hash(), header.Number.Uint64())
    66  	if entry := ReadHeader(db, header.Hash(), header.Number.Uint64()); entry != nil {
    67  		t.Fatalf("Deleted header returned: %v", entry)
    68  	}
    69  }
    70  
    71  // Tests block body storage and retrieval operations.
    72  func TestBodyStorage(t *testing.T) {
    73  	db := NewMemoryDatabase()
    74  
    75  	// Create a test body to move around the database and make sure it's really new
    76  	body := &types.Body{Uncles: []*types.Header{{Extra: []byte("test header")}}}
    77  
    78  	hasher := sha3.NewLegacyKeccak256()
    79  	rlp.Encode(hasher, body)
    80  	hash := common.BytesToHash(hasher.Sum(nil))
    81  
    82  	if entry := ReadBody(db, hash, 0); entry != nil {
    83  		t.Fatalf("Non existent body returned: %v", entry)
    84  	}
    85  	// Write and verify the body in the database
    86  	WriteBody(db, hash, 0, body)
    87  	if entry := ReadBody(db, hash, 0); entry == nil {
    88  		t.Fatalf("Stored body not found")
    89  	} else if types.DeriveSha(types.Transactions(entry.Transactions), newHasher()) != types.DeriveSha(types.Transactions(body.Transactions), newHasher()) || types.CalcUncleHash(entry.Uncles) != types.CalcUncleHash(body.Uncles) {
    90  		t.Fatalf("Retrieved body mismatch: have %v, want %v", entry, body)
    91  	}
    92  	if entry := ReadBodyRLP(db, hash, 0); entry == nil {
    93  		t.Fatalf("Stored body RLP not found")
    94  	} else {
    95  		hasher := sha3.NewLegacyKeccak256()
    96  		hasher.Write(entry)
    97  
    98  		if calc := common.BytesToHash(hasher.Sum(nil)); calc != hash {
    99  			t.Fatalf("Retrieved RLP body mismatch: have %v, want %v", entry, body)
   100  		}
   101  	}
   102  	// Delete the body and verify the execution
   103  	DeleteBody(db, hash, 0)
   104  	if entry := ReadBody(db, hash, 0); entry != nil {
   105  		t.Fatalf("Deleted body returned: %v", entry)
   106  	}
   107  }
   108  
   109  // Tests block storage and retrieval operations.
   110  func TestBlockStorage(t *testing.T) {
   111  	db := NewMemoryDatabase()
   112  
   113  	// Create a test block to move around the database and make sure it's really new
   114  	block := types.NewBlockWithHeader(&types.Header{
   115  		Extra:       []byte("test block"),
   116  		UncleHash:   types.EmptyUncleHash,
   117  		TxHash:      types.EmptyRootHash,
   118  		ReceiptHash: types.EmptyRootHash,
   119  	})
   120  	if entry := ReadBlock(db, block.Hash(), block.NumberU64()); entry != nil {
   121  		t.Fatalf("Non existent block returned: %v", entry)
   122  	}
   123  	if entry := ReadHeader(db, block.Hash(), block.NumberU64()); entry != nil {
   124  		t.Fatalf("Non existent header returned: %v", entry)
   125  	}
   126  	if entry := ReadBody(db, block.Hash(), block.NumberU64()); entry != nil {
   127  		t.Fatalf("Non existent body returned: %v", entry)
   128  	}
   129  	// Write and verify the block in the database
   130  	WriteBlock(db, block)
   131  	if entry := ReadBlock(db, block.Hash(), block.NumberU64()); entry == nil {
   132  		t.Fatalf("Stored block not found")
   133  	} else if entry.Hash() != block.Hash() {
   134  		t.Fatalf("Retrieved block mismatch: have %v, want %v", entry, block)
   135  	}
   136  	if entry := ReadHeader(db, block.Hash(), block.NumberU64()); entry == nil {
   137  		t.Fatalf("Stored header not found")
   138  	} else if entry.Hash() != block.Header().Hash() {
   139  		t.Fatalf("Retrieved header mismatch: have %v, want %v", entry, block.Header())
   140  	}
   141  	if entry := ReadBody(db, block.Hash(), block.NumberU64()); entry == nil {
   142  		t.Fatalf("Stored body not found")
   143  	} else if types.DeriveSha(types.Transactions(entry.Transactions), newHasher()) != types.DeriveSha(block.Transactions(), newHasher()) || types.CalcUncleHash(entry.Uncles) != types.CalcUncleHash(block.Uncles()) {
   144  		t.Fatalf("Retrieved body mismatch: have %v, want %v", entry, block.Body())
   145  	}
   146  	// Delete the block and verify the execution
   147  	DeleteBlock(db, block.Hash(), block.NumberU64())
   148  	if entry := ReadBlock(db, block.Hash(), block.NumberU64()); entry != nil {
   149  		t.Fatalf("Deleted block returned: %v", entry)
   150  	}
   151  	if entry := ReadHeader(db, block.Hash(), block.NumberU64()); entry != nil {
   152  		t.Fatalf("Deleted header returned: %v", entry)
   153  	}
   154  	if entry := ReadBody(db, block.Hash(), block.NumberU64()); entry != nil {
   155  		t.Fatalf("Deleted body returned: %v", entry)
   156  	}
   157  }
   158  
   159  // Tests that partial block contents don't get reassembled into full blocks.
   160  func TestPartialBlockStorage(t *testing.T) {
   161  	db := NewMemoryDatabase()
   162  	block := types.NewBlockWithHeader(&types.Header{
   163  		Extra:       []byte("test block"),
   164  		UncleHash:   types.EmptyUncleHash,
   165  		TxHash:      types.EmptyRootHash,
   166  		ReceiptHash: types.EmptyRootHash,
   167  	})
   168  	// Store a header and check that it's not recognized as a block
   169  	WriteHeader(db, block.Header())
   170  	if entry := ReadBlock(db, block.Hash(), block.NumberU64()); entry != nil {
   171  		t.Fatalf("Non existent block returned: %v", entry)
   172  	}
   173  	DeleteHeader(db, block.Hash(), block.NumberU64())
   174  
   175  	// Store a body and check that it's not recognized as a block
   176  	WriteBody(db, block.Hash(), block.NumberU64(), block.Body())
   177  	if entry := ReadBlock(db, block.Hash(), block.NumberU64()); entry != nil {
   178  		t.Fatalf("Non existent block returned: %v", entry)
   179  	}
   180  	DeleteBody(db, block.Hash(), block.NumberU64())
   181  
   182  	// Store a header and a body separately and check reassembly
   183  	WriteHeader(db, block.Header())
   184  	WriteBody(db, block.Hash(), block.NumberU64(), block.Body())
   185  
   186  	if entry := ReadBlock(db, block.Hash(), block.NumberU64()); entry == nil {
   187  		t.Fatalf("Stored block not found")
   188  	} else if entry.Hash() != block.Hash() {
   189  		t.Fatalf("Retrieved block mismatch: have %v, want %v", entry, block)
   190  	}
   191  }
   192  
   193  // Tests block storage and retrieval operations.
   194  func TestBadBlockStorage(t *testing.T) {
   195  	db := NewMemoryDatabase()
   196  
   197  	// Create a test block to move around the database and make sure it's really new
   198  	block := types.NewBlockWithHeader(&types.Header{
   199  		Number:      big.NewInt(1),
   200  		Extra:       []byte("bad block"),
   201  		UncleHash:   types.EmptyUncleHash,
   202  		TxHash:      types.EmptyRootHash,
   203  		ReceiptHash: types.EmptyRootHash,
   204  	})
   205  	if entry := ReadBadBlock(db, block.Hash()); entry != nil {
   206  		t.Fatalf("Non existent block returned: %v", entry)
   207  	}
   208  	// Write and verify the block in the database
   209  	WriteBadBlock(db, block)
   210  	if entry := ReadBadBlock(db, block.Hash()); entry == nil {
   211  		t.Fatalf("Stored block not found")
   212  	} else if entry.Hash() != block.Hash() {
   213  		t.Fatalf("Retrieved block mismatch: have %v, want %v", entry, block)
   214  	}
   215  	// Write one more bad block
   216  	blockTwo := types.NewBlockWithHeader(&types.Header{
   217  		Number:      big.NewInt(2),
   218  		Extra:       []byte("bad block two"),
   219  		UncleHash:   types.EmptyUncleHash,
   220  		TxHash:      types.EmptyRootHash,
   221  		ReceiptHash: types.EmptyRootHash,
   222  	})
   223  	WriteBadBlock(db, blockTwo)
   224  
   225  	// Write the block one again, should be filtered out.
   226  	WriteBadBlock(db, block)
   227  	badBlocks := ReadAllBadBlocks(db)
   228  	if len(badBlocks) != 2 {
   229  		t.Fatalf("Failed to load all bad blocks")
   230  	}
   231  
   232  	// Write a bunch of bad blocks, all the blocks are should sorted
   233  	// in reverse order. The extra blocks should be truncated.
   234  	for _, n := range rand.Perm(100) {
   235  		block := types.NewBlockWithHeader(&types.Header{
   236  			Number:      big.NewInt(int64(n)),
   237  			Extra:       []byte("bad block"),
   238  			UncleHash:   types.EmptyUncleHash,
   239  			TxHash:      types.EmptyRootHash,
   240  			ReceiptHash: types.EmptyRootHash,
   241  		})
   242  		WriteBadBlock(db, block)
   243  	}
   244  	badBlocks = ReadAllBadBlocks(db)
   245  	if len(badBlocks) != badBlockToKeep {
   246  		t.Fatalf("The number of persised bad blocks in incorrect %d", len(badBlocks))
   247  	}
   248  	for i := 0; i < len(badBlocks)-1; i++ {
   249  		if badBlocks[i].NumberU64() < badBlocks[i+1].NumberU64() {
   250  			t.Fatalf("The bad blocks are not sorted #[%d](%d) < #[%d](%d)", i, i+1, badBlocks[i].NumberU64(), badBlocks[i+1].NumberU64())
   251  		}
   252  	}
   253  
   254  	// Delete all bad blocks
   255  	DeleteBadBlocks(db)
   256  	badBlocks = ReadAllBadBlocks(db)
   257  	if len(badBlocks) != 0 {
   258  		t.Fatalf("Failed to delete bad blocks")
   259  	}
   260  }
   261  
   262  // Tests block total difficulty storage and retrieval operations.
   263  func TestTdStorage(t *testing.T) {
   264  	db := NewMemoryDatabase()
   265  
   266  	// Create a test TD to move around the database and make sure it's really new
   267  	hash, td := common.Hash{}, big.NewInt(314)
   268  	if entry := ReadTd(db, hash, 0); entry != nil {
   269  		t.Fatalf("Non existent TD returned: %v", entry)
   270  	}
   271  	// Write and verify the TD in the database
   272  	WriteTd(db, hash, 0, td)
   273  	if entry := ReadTd(db, hash, 0); entry == nil {
   274  		t.Fatalf("Stored TD not found")
   275  	} else if entry.Cmp(td) != 0 {
   276  		t.Fatalf("Retrieved TD mismatch: have %v, want %v", entry, td)
   277  	}
   278  	// Delete the TD and verify the execution
   279  	DeleteTd(db, hash, 0)
   280  	if entry := ReadTd(db, hash, 0); entry != nil {
   281  		t.Fatalf("Deleted TD returned: %v", entry)
   282  	}
   283  }
   284  
   285  // Tests that canonical numbers can be mapped to hashes and retrieved.
   286  func TestCanonicalMappingStorage(t *testing.T) {
   287  	db := NewMemoryDatabase()
   288  
   289  	// Create a test canonical number and assinged hash to move around
   290  	hash, number := common.Hash{0: 0xff}, uint64(314)
   291  	if entry := ReadCanonicalHash(db, number); entry != (common.Hash{}) {
   292  		t.Fatalf("Non existent canonical mapping returned: %v", entry)
   293  	}
   294  	// Write and verify the TD in the database
   295  	WriteCanonicalHash(db, hash, number)
   296  	if entry := ReadCanonicalHash(db, number); entry == (common.Hash{}) {
   297  		t.Fatalf("Stored canonical mapping not found")
   298  	} else if entry != hash {
   299  		t.Fatalf("Retrieved canonical mapping mismatch: have %v, want %v", entry, hash)
   300  	}
   301  	// Delete the TD and verify the execution
   302  	DeleteCanonicalHash(db, number)
   303  	if entry := ReadCanonicalHash(db, number); entry != (common.Hash{}) {
   304  		t.Fatalf("Deleted canonical mapping returned: %v", entry)
   305  	}
   306  }
   307  
   308  // Tests that head headers and head blocks can be assigned, individually.
   309  func TestHeadStorage(t *testing.T) {
   310  	db := NewMemoryDatabase()
   311  
   312  	blockHead := types.NewBlockWithHeader(&types.Header{Extra: []byte("test block header")})
   313  	blockFull := types.NewBlockWithHeader(&types.Header{Extra: []byte("test block full")})
   314  	blockFast := types.NewBlockWithHeader(&types.Header{Extra: []byte("test block fast")})
   315  
   316  	// Check that no head entries are in a pristine database
   317  	if entry := ReadHeadHeaderHash(db); entry != (common.Hash{}) {
   318  		t.Fatalf("Non head header entry returned: %v", entry)
   319  	}
   320  	if entry := ReadHeadBlockHash(db); entry != (common.Hash{}) {
   321  		t.Fatalf("Non head block entry returned: %v", entry)
   322  	}
   323  	if entry := ReadHeadFastBlockHash(db); entry != (common.Hash{}) {
   324  		t.Fatalf("Non fast head block entry returned: %v", entry)
   325  	}
   326  	// Assign separate entries for the head header and block
   327  	WriteHeadHeaderHash(db, blockHead.Hash())
   328  	WriteHeadBlockHash(db, blockFull.Hash())
   329  	WriteHeadFastBlockHash(db, blockFast.Hash())
   330  
   331  	// Check that both heads are present, and different (i.e. two heads maintained)
   332  	if entry := ReadHeadHeaderHash(db); entry != blockHead.Hash() {
   333  		t.Fatalf("Head header hash mismatch: have %v, want %v", entry, blockHead.Hash())
   334  	}
   335  	if entry := ReadHeadBlockHash(db); entry != blockFull.Hash() {
   336  		t.Fatalf("Head block hash mismatch: have %v, want %v", entry, blockFull.Hash())
   337  	}
   338  	if entry := ReadHeadFastBlockHash(db); entry != blockFast.Hash() {
   339  		t.Fatalf("Fast head block hash mismatch: have %v, want %v", entry, blockFast.Hash())
   340  	}
   341  }
   342  
   343  // Tests that receipts associated with a single block can be stored and retrieved.
   344  func TestBlockReceiptStorage(t *testing.T) {
   345  	db := NewMemoryDatabase()
   346  
   347  	// Create a live block since we need metadata to reconstruct the receipt
   348  	tx1 := types.NewTransaction(1, common.HexToAddress("0x1"), big.NewInt(1), 1, big.NewInt(1), nil)
   349  	tx2 := types.NewTransaction(2, common.HexToAddress("0x2"), big.NewInt(2), 2, big.NewInt(2), nil)
   350  
   351  	body := &types.Body{Transactions: types.Transactions{tx1, tx2}}
   352  
   353  	// Create the two receipts to manage afterwards
   354  	receipt1 := &types.Receipt{
   355  		Status:            types.ReceiptStatusFailed,
   356  		CumulativeGasUsed: 1,
   357  		Logs: []*types.Log{
   358  			{Address: common.BytesToAddress([]byte{0x11})},
   359  			{Address: common.BytesToAddress([]byte{0x01, 0x11})},
   360  		},
   361  		TxHash:          tx1.Hash(),
   362  		ContractAddress: common.BytesToAddress([]byte{0x01, 0x11, 0x11}),
   363  		GasUsed:         111111,
   364  	}
   365  	receipt1.Bloom = types.CreateBloom(types.Receipts{receipt1})
   366  
   367  	receipt2 := &types.Receipt{
   368  		PostState:         common.Hash{2}.Bytes(),
   369  		CumulativeGasUsed: 2,
   370  		Logs: []*types.Log{
   371  			{Address: common.BytesToAddress([]byte{0x22})},
   372  			{Address: common.BytesToAddress([]byte{0x02, 0x22})},
   373  		},
   374  		TxHash:          tx2.Hash(),
   375  		ContractAddress: common.BytesToAddress([]byte{0x02, 0x22, 0x22}),
   376  		GasUsed:         222222,
   377  	}
   378  	receipt2.Bloom = types.CreateBloom(types.Receipts{receipt2})
   379  	receipts := []*types.Receipt{receipt1, receipt2}
   380  
   381  	// Check that no receipt entries are in a pristine database
   382  	hash := common.BytesToHash([]byte{0x03, 0x14})
   383  	if rs := ReadReceipts(db, hash, 0, params.TestChainConfig); len(rs) != 0 {
   384  		t.Fatalf("non existent receipts returned: %v", rs)
   385  	}
   386  	// Insert the body that corresponds to the receipts
   387  	WriteBody(db, hash, 0, body)
   388  
   389  	// Insert the receipt slice into the database and check presence
   390  	WriteReceipts(db, hash, 0, receipts)
   391  	if rs := ReadReceipts(db, hash, 0, params.TestChainConfig); len(rs) == 0 {
   392  		t.Fatalf("no receipts returned")
   393  	} else {
   394  		if err := checkReceiptsRLP(rs, receipts); err != nil {
   395  			t.Fatalf(err.Error())
   396  		}
   397  	}
   398  	// Delete the body and ensure that the receipts are no longer returned (metadata can't be recomputed)
   399  	DeleteBody(db, hash, 0)
   400  	if rs := ReadReceipts(db, hash, 0, params.TestChainConfig); rs != nil {
   401  		t.Fatalf("receipts returned when body was deleted: %v", rs)
   402  	}
   403  	// Ensure that receipts without metadata can be returned without the block body too
   404  	if err := checkReceiptsRLP(ReadRawReceipts(db, hash, 0), receipts); err != nil {
   405  		t.Fatalf(err.Error())
   406  	}
   407  	// Sanity check that body alone without the receipt is a full purge
   408  	WriteBody(db, hash, 0, body)
   409  
   410  	DeleteReceipts(db, hash, 0)
   411  	if rs := ReadReceipts(db, hash, 0, params.TestChainConfig); len(rs) != 0 {
   412  		t.Fatalf("deleted receipts returned: %v", rs)
   413  	}
   414  }
   415  
   416  func checkReceiptsRLP(have, want types.Receipts) error {
   417  	if len(have) != len(want) {
   418  		return fmt.Errorf("receipts sizes mismatch: have %d, want %d", len(have), len(want))
   419  	}
   420  	for i := 0; i < len(want); i++ {
   421  		rlpHave, err := rlp.EncodeToBytes(have[i])
   422  		if err != nil {
   423  			return err
   424  		}
   425  		rlpWant, err := rlp.EncodeToBytes(want[i])
   426  		if err != nil {
   427  			return err
   428  		}
   429  		if !bytes.Equal(rlpHave, rlpWant) {
   430  			return fmt.Errorf("receipt #%d: receipt mismatch: have %s, want %s", i, hex.EncodeToString(rlpHave), hex.EncodeToString(rlpWant))
   431  		}
   432  	}
   433  	return nil
   434  }
   435  
   436  func TestAncientStorage(t *testing.T) {
   437  	// Freezer style fast import the chain.
   438  	frdir, err := ioutil.TempDir("", "")
   439  	if err != nil {
   440  		t.Fatalf("failed to create temp freezer dir: %v", err)
   441  	}
   442  	defer os.RemoveAll(frdir)
   443  
   444  	db, err := NewDatabaseWithFreezer(NewMemoryDatabase(), frdir, "", false)
   445  	if err != nil {
   446  		t.Fatalf("failed to create database with ancient backend")
   447  	}
   448  	defer db.Close()
   449  	// Create a test block
   450  	block := types.NewBlockWithHeader(&types.Header{
   451  		Number:      big.NewInt(0),
   452  		Extra:       []byte("test block"),
   453  		UncleHash:   types.EmptyUncleHash,
   454  		TxHash:      types.EmptyRootHash,
   455  		ReceiptHash: types.EmptyRootHash,
   456  	})
   457  	// Ensure nothing non-existent will be read
   458  	hash, number := block.Hash(), block.NumberU64()
   459  	if blob := ReadHeaderRLP(db, hash, number); len(blob) > 0 {
   460  		t.Fatalf("non existent header returned")
   461  	}
   462  	if blob := ReadBodyRLP(db, hash, number); len(blob) > 0 {
   463  		t.Fatalf("non existent body returned")
   464  	}
   465  	if blob := ReadReceiptsRLP(db, hash, number); len(blob) > 0 {
   466  		t.Fatalf("non existent receipts returned")
   467  	}
   468  	if blob := ReadTdRLP(db, hash, number); len(blob) > 0 {
   469  		t.Fatalf("non existent td returned")
   470  	}
   471  
   472  	// Write and verify the header in the database
   473  	WriteAncientBlocks(db, []*types.Block{block}, []types.Receipts{nil}, []types.Receipts{nil}, big.NewInt(100))
   474  
   475  	if blob := ReadHeaderRLP(db, hash, number); len(blob) == 0 {
   476  		t.Fatalf("no header returned")
   477  	}
   478  	if blob := ReadBodyRLP(db, hash, number); len(blob) == 0 {
   479  		t.Fatalf("no body returned")
   480  	}
   481  	if blob := ReadReceiptsRLP(db, hash, number); len(blob) == 0 {
   482  		t.Fatalf("no receipts returned")
   483  	}
   484  	if blob := ReadTdRLP(db, hash, number); len(blob) == 0 {
   485  		t.Fatalf("no td returned")
   486  	}
   487  
   488  	// Use a fake hash for data retrieval, nothing should be returned.
   489  	fakeHash := common.BytesToHash([]byte{0x01, 0x02, 0x03})
   490  	if blob := ReadHeaderRLP(db, fakeHash, number); len(blob) != 0 {
   491  		t.Fatalf("invalid header returned")
   492  	}
   493  	if blob := ReadBodyRLP(db, fakeHash, number); len(blob) != 0 {
   494  		t.Fatalf("invalid body returned")
   495  	}
   496  	if blob := ReadReceiptsRLP(db, fakeHash, number); len(blob) != 0 {
   497  		t.Fatalf("invalid receipts returned")
   498  	}
   499  	if blob := ReadTdRLP(db, fakeHash, number); len(blob) != 0 {
   500  		t.Fatalf("invalid td returned")
   501  	}
   502  }
   503  
   504  func TestCanonicalHashIteration(t *testing.T) {
   505  	var cases = []struct {
   506  		from, to uint64
   507  		limit    int
   508  		expect   []uint64
   509  	}{
   510  		{1, 8, 0, nil},
   511  		{1, 8, 1, []uint64{1}},
   512  		{1, 8, 10, []uint64{1, 2, 3, 4, 5, 6, 7}},
   513  		{1, 9, 10, []uint64{1, 2, 3, 4, 5, 6, 7, 8}},
   514  		{2, 9, 10, []uint64{2, 3, 4, 5, 6, 7, 8}},
   515  		{9, 10, 10, nil},
   516  	}
   517  	// Test empty db iteration
   518  	db := NewMemoryDatabase()
   519  	numbers, _ := ReadAllCanonicalHashes(db, 0, 10, 10)
   520  	if len(numbers) != 0 {
   521  		t.Fatalf("No entry should be returned to iterate an empty db")
   522  	}
   523  	// Fill database with testing data.
   524  	for i := uint64(1); i <= 8; i++ {
   525  		WriteCanonicalHash(db, common.Hash{}, i)
   526  		WriteTd(db, common.Hash{}, i, big.NewInt(10)) // Write some interferential data
   527  	}
   528  	for i, c := range cases {
   529  		numbers, _ := ReadAllCanonicalHashes(db, c.from, c.to, c.limit)
   530  		if !reflect.DeepEqual(numbers, c.expect) {
   531  			t.Fatalf("Case %d failed, want %v, got %v", i, c.expect, numbers)
   532  		}
   533  	}
   534  }
   535  
   536  func TestHashesInRange(t *testing.T) {
   537  	mkHeader := func(number, seq int) *types.Header {
   538  		h := types.Header{
   539  			Difficulty: new(big.Int),
   540  			Number:     big.NewInt(int64(number)),
   541  			GasLimit:   uint64(seq),
   542  		}
   543  		return &h
   544  	}
   545  	db := NewMemoryDatabase()
   546  	// For each number, write N versions of that particular number
   547  	total := 0
   548  	for i := 0; i < 15; i++ {
   549  		for ii := 0; ii < i; ii++ {
   550  			WriteHeader(db, mkHeader(i, ii))
   551  			total++
   552  		}
   553  	}
   554  	if have, want := len(ReadAllHashesInRange(db, 10, 10)), 10; have != want {
   555  		t.Fatalf("Wrong number of hashes read, want %d, got %d", want, have)
   556  	}
   557  	if have, want := len(ReadAllHashesInRange(db, 10, 9)), 0; have != want {
   558  		t.Fatalf("Wrong number of hashes read, want %d, got %d", want, have)
   559  	}
   560  	if have, want := len(ReadAllHashesInRange(db, 0, 100)), total; have != want {
   561  		t.Fatalf("Wrong number of hashes read, want %d, got %d", want, have)
   562  	}
   563  	if have, want := len(ReadAllHashesInRange(db, 9, 10)), 9+10; have != want {
   564  		t.Fatalf("Wrong number of hashes read, want %d, got %d", want, have)
   565  	}
   566  	if have, want := len(ReadAllHashes(db, 10)), 10; have != want {
   567  		t.Fatalf("Wrong number of hashes read, want %d, got %d", want, have)
   568  	}
   569  	if have, want := len(ReadAllHashes(db, 16)), 0; have != want {
   570  		t.Fatalf("Wrong number of hashes read, want %d, got %d", want, have)
   571  	}
   572  	if have, want := len(ReadAllHashes(db, 1)), 1; have != want {
   573  		t.Fatalf("Wrong number of hashes read, want %d, got %d", want, have)
   574  	}
   575  }
   576  
   577  // This measures the write speed of the WriteAncientBlocks operation.
   578  func BenchmarkWriteAncientBlocks(b *testing.B) {
   579  	// Open freezer database.
   580  	frdir, err := ioutil.TempDir("", "")
   581  	if err != nil {
   582  		b.Fatalf("failed to create temp freezer dir: %v", err)
   583  	}
   584  	defer os.RemoveAll(frdir)
   585  	db, err := NewDatabaseWithFreezer(NewMemoryDatabase(), frdir, "", false)
   586  	if err != nil {
   587  		b.Fatalf("failed to create database with ancient backend")
   588  	}
   589  
   590  	// Create the data to insert. The blocks must have consecutive numbers, so we create
   591  	// all of them ahead of time. However, there is no need to create receipts
   592  	// individually for each block, just make one batch here and reuse it for all writes.
   593  	const batchSize = 128
   594  	const blockTxs = 20
   595  	allBlocks := makeTestBlocks(b.N, blockTxs)
   596  	batchReceipts := makeTestReceipts(batchSize, blockTxs)
   597  	b.ResetTimer()
   598  
   599  	// The benchmark loop writes batches of blocks, but note that the total block count is
   600  	// b.N. This means the resulting ns/op measurement is the time it takes to write a
   601  	// single block and its associated data.
   602  	var td = big.NewInt(55)
   603  	var totalSize int64
   604  	for i := 0; i < b.N; i += batchSize {
   605  		length := batchSize
   606  		if i+batchSize > b.N {
   607  			length = b.N - i
   608  		}
   609  
   610  		blocks := allBlocks[i : i+length]
   611  		receipts := batchReceipts[:length]
   612  		writeSize, err := WriteAncientBlocks(db, blocks, receipts, []types.Receipts{nil}, td)
   613  		if err != nil {
   614  			b.Fatal(err)
   615  		}
   616  		totalSize += writeSize
   617  	}
   618  
   619  	// Enable MB/s reporting.
   620  	b.SetBytes(totalSize / int64(b.N))
   621  }
   622  
   623  // makeTestBlocks creates fake blocks for the ancient write benchmark.
   624  func makeTestBlocks(nblock int, txsPerBlock int) []*types.Block {
   625  	key, _ := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   626  	signer := types.LatestSignerForChainID(big.NewInt(8))
   627  
   628  	// Create transactions.
   629  	txs := make([]*types.Transaction, txsPerBlock)
   630  	for i := 0; i < len(txs); i++ {
   631  		var err error
   632  		to := common.Address{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
   633  		txs[i], err = types.SignNewTx(key, signer, &types.LegacyTx{
   634  			Nonce:    2,
   635  			GasPrice: big.NewInt(30000),
   636  			Gas:      0x45454545,
   637  			To:       &to,
   638  		})
   639  		if err != nil {
   640  			panic(err)
   641  		}
   642  	}
   643  
   644  	// Create the blocks.
   645  	blocks := make([]*types.Block, nblock)
   646  	for i := 0; i < nblock; i++ {
   647  		header := &types.Header{
   648  			Number: big.NewInt(int64(i)),
   649  			Extra:  []byte("test block"),
   650  		}
   651  		blocks[i] = types.NewBlockWithHeader(header).WithBody(txs, nil)
   652  		blocks[i].Hash() // pre-cache the block hash
   653  	}
   654  	return blocks
   655  }
   656  
   657  // makeTestReceipts creates fake receipts for the ancient write benchmark.
   658  func makeTestReceipts(n int, nPerBlock int) []types.Receipts {
   659  	receipts := make([]*types.Receipt, nPerBlock)
   660  	for i := 0; i < len(receipts); i++ {
   661  		receipts[i] = &types.Receipt{
   662  			Status:            types.ReceiptStatusSuccessful,
   663  			CumulativeGasUsed: 0x888888888,
   664  			Logs:              make([]*types.Log, 5),
   665  		}
   666  	}
   667  	allReceipts := make([]types.Receipts, n)
   668  	for i := 0; i < n; i++ {
   669  		allReceipts[i] = receipts
   670  	}
   671  	return allReceipts
   672  }
   673  
   674  type fullLogRLP struct {
   675  	Address     common.Address
   676  	Topics      []common.Hash
   677  	Data        []byte
   678  	BlockNumber uint64
   679  	TxHash      common.Hash
   680  	TxIndex     uint
   681  	BlockHash   common.Hash
   682  	Index       uint
   683  }
   684  
   685  func newFullLogRLP(l *types.Log) *fullLogRLP {
   686  	return &fullLogRLP{
   687  		Address:     l.Address,
   688  		Topics:      l.Topics,
   689  		Data:        l.Data,
   690  		BlockNumber: l.BlockNumber,
   691  		TxHash:      l.TxHash,
   692  		TxIndex:     l.TxIndex,
   693  		BlockHash:   l.BlockHash,
   694  		Index:       l.Index,
   695  	}
   696  }
   697  
   698  // Tests that logs associated with a single block can be retrieved.
   699  func TestReadLogs(t *testing.T) {
   700  	db := NewMemoryDatabase()
   701  
   702  	// Create a live block since we need metadata to reconstruct the receipt
   703  	tx1 := types.NewTransaction(1, common.HexToAddress("0x1"), big.NewInt(1), 1, big.NewInt(1), nil)
   704  	tx2 := types.NewTransaction(2, common.HexToAddress("0x2"), big.NewInt(2), 2, big.NewInt(2), nil)
   705  
   706  	body := &types.Body{Transactions: types.Transactions{tx1, tx2}}
   707  
   708  	// Create the two receipts to manage afterwards
   709  	receipt1 := &types.Receipt{
   710  		Status:            types.ReceiptStatusFailed,
   711  		CumulativeGasUsed: 1,
   712  		Logs: []*types.Log{
   713  			{Address: common.BytesToAddress([]byte{0x11})},
   714  			{Address: common.BytesToAddress([]byte{0x01, 0x11})},
   715  		},
   716  		TxHash:          tx1.Hash(),
   717  		ContractAddress: common.BytesToAddress([]byte{0x01, 0x11, 0x11}),
   718  		GasUsed:         111111,
   719  	}
   720  	receipt1.Bloom = types.CreateBloom(types.Receipts{receipt1})
   721  
   722  	receipt2 := &types.Receipt{
   723  		PostState:         common.Hash{2}.Bytes(),
   724  		CumulativeGasUsed: 2,
   725  		Logs: []*types.Log{
   726  			{Address: common.BytesToAddress([]byte{0x22})},
   727  			{Address: common.BytesToAddress([]byte{0x02, 0x22})},
   728  		},
   729  		TxHash:          tx2.Hash(),
   730  		ContractAddress: common.BytesToAddress([]byte{0x02, 0x22, 0x22}),
   731  		GasUsed:         222222,
   732  	}
   733  	receipt2.Bloom = types.CreateBloom(types.Receipts{receipt2})
   734  	receipts := []*types.Receipt{receipt1, receipt2}
   735  
   736  	hash := common.BytesToHash([]byte{0x03, 0x14})
   737  	// Check that no receipt entries are in a pristine database
   738  	if rs := ReadReceipts(db, hash, 0, params.TestChainConfig); len(rs) != 0 {
   739  		t.Fatalf("non existent receipts returned: %v", rs)
   740  	}
   741  	// Insert the body that corresponds to the receipts
   742  	WriteBody(db, hash, 0, body)
   743  
   744  	// Insert the receipt slice into the database and check presence
   745  	WriteReceipts(db, hash, 0, receipts)
   746  
   747  	logs := ReadLogs(db, hash, 0)
   748  	if len(logs) == 0 {
   749  		t.Fatalf("no logs returned")
   750  	}
   751  	if have, want := len(logs), 2; have != want {
   752  		t.Fatalf("unexpected number of logs returned, have %d want %d", have, want)
   753  	}
   754  	if have, want := len(logs[0]), 2; have != want {
   755  		t.Fatalf("unexpected number of logs[0] returned, have %d want %d", have, want)
   756  	}
   757  	if have, want := len(logs[1]), 2; have != want {
   758  		t.Fatalf("unexpected number of logs[1] returned, have %d want %d", have, want)
   759  	}
   760  
   761  	// Fill in log fields so we can compare their rlp encoding
   762  	if err := types.Receipts(receipts).DeriveFields(params.TestChainConfig, hash, 0, body.Transactions); err != nil {
   763  		t.Fatal(err)
   764  	}
   765  	for i, pr := range receipts {
   766  		for j, pl := range pr.Logs {
   767  			rlpHave, err := rlp.EncodeToBytes(newFullLogRLP(logs[i][j]))
   768  			if err != nil {
   769  				t.Fatal(err)
   770  			}
   771  			rlpWant, err := rlp.EncodeToBytes(newFullLogRLP(pl))
   772  			if err != nil {
   773  				t.Fatal(err)
   774  			}
   775  			if !bytes.Equal(rlpHave, rlpWant) {
   776  				t.Fatalf("receipt #%d: receipt mismatch: have %s, want %s", i, hex.EncodeToString(rlpHave), hex.EncodeToString(rlpWant))
   777  			}
   778  		}
   779  	}
   780  }
   781  
   782  func TestDeriveLogFields(t *testing.T) {
   783  	// Create a few transactions to have receipts for
   784  	to2 := common.HexToAddress("0x2")
   785  	to3 := common.HexToAddress("0x3")
   786  	txs := types.Transactions{
   787  		types.NewTx(&types.LegacyTx{
   788  			Nonce:    1,
   789  			Value:    big.NewInt(1),
   790  			Gas:      1,
   791  			GasPrice: big.NewInt(1),
   792  		}),
   793  		types.NewTx(&types.LegacyTx{
   794  			To:       &to2,
   795  			Nonce:    2,
   796  			Value:    big.NewInt(2),
   797  			Gas:      2,
   798  			GasPrice: big.NewInt(2),
   799  		}),
   800  		types.NewTx(&types.AccessListTx{
   801  			To:       &to3,
   802  			Nonce:    3,
   803  			Value:    big.NewInt(3),
   804  			Gas:      3,
   805  			GasPrice: big.NewInt(3),
   806  		}),
   807  	}
   808  	// Create the corresponding receipts
   809  	receipts := []*receiptLogs{
   810  		{
   811  			Logs: []*types.Log{
   812  				{Address: common.BytesToAddress([]byte{0x11})},
   813  				{Address: common.BytesToAddress([]byte{0x01, 0x11})},
   814  			},
   815  		},
   816  		{
   817  			Logs: []*types.Log{
   818  				{Address: common.BytesToAddress([]byte{0x22})},
   819  				{Address: common.BytesToAddress([]byte{0x02, 0x22})},
   820  			},
   821  		},
   822  		{
   823  			Logs: []*types.Log{
   824  				{Address: common.BytesToAddress([]byte{0x33})},
   825  				{Address: common.BytesToAddress([]byte{0x03, 0x33})},
   826  			},
   827  		},
   828  	}
   829  
   830  	// Derive log metadata fields
   831  	number := big.NewInt(1)
   832  	hash := common.BytesToHash([]byte{0x03, 0x14})
   833  	if err := deriveLogFields(receipts, hash, number.Uint64(), txs); err != nil {
   834  		t.Fatal(err)
   835  	}
   836  
   837  	// Iterate over all the computed fields and check that they're correct
   838  	logIndex := uint(0)
   839  	for i := range receipts {
   840  		for j := range receipts[i].Logs {
   841  			if receipts[i].Logs[j].BlockNumber != number.Uint64() {
   842  				t.Errorf("receipts[%d].Logs[%d].BlockNumber = %d, want %d", i, j, receipts[i].Logs[j].BlockNumber, number.Uint64())
   843  			}
   844  			if receipts[i].Logs[j].BlockHash != hash {
   845  				t.Errorf("receipts[%d].Logs[%d].BlockHash = %s, want %s", i, j, receipts[i].Logs[j].BlockHash.String(), hash.String())
   846  			}
   847  			if receipts[i].Logs[j].TxHash != txs[i].Hash() {
   848  				t.Errorf("receipts[%d].Logs[%d].TxHash = %s, want %s", i, j, receipts[i].Logs[j].TxHash.String(), txs[i].Hash().String())
   849  			}
   850  			if receipts[i].Logs[j].TxIndex != uint(i) {
   851  				t.Errorf("receipts[%d].Logs[%d].TransactionIndex = %d, want %d", i, j, receipts[i].Logs[j].TxIndex, i)
   852  			}
   853  			if receipts[i].Logs[j].Index != logIndex {
   854  				t.Errorf("receipts[%d].Logs[%d].Index = %d, want %d", i, j, receipts[i].Logs[j].Index, logIndex)
   855  			}
   856  			logIndex++
   857  		}
   858  	}
   859  }
   860  
   861  func BenchmarkDecodeRLPLogs(b *testing.B) {
   862  	// Encoded receipts from block 0x14ee094309fbe8f70b65f45ebcc08fb33f126942d97464aad5eb91cfd1e2d269
   863  	buf, err := ioutil.ReadFile("testdata/stored_receipts.bin")
   864  	if err != nil {
   865  		b.Fatal(err)
   866  	}
   867  	b.Run("ReceiptForStorage", func(b *testing.B) {
   868  		b.ReportAllocs()
   869  		var r []*types.ReceiptForStorage
   870  		for i := 0; i < b.N; i++ {
   871  			if err := rlp.DecodeBytes(buf, &r); err != nil {
   872  				b.Fatal(err)
   873  			}
   874  		}
   875  	})
   876  	b.Run("rlpLogs", func(b *testing.B) {
   877  		b.ReportAllocs()
   878  		var r []*receiptLogs
   879  		for i := 0; i < b.N; i++ {
   880  			if err := rlp.DecodeBytes(buf, &r); err != nil {
   881  				b.Fatal(err)
   882  			}
   883  		}
   884  	})
   885  }