github.com/Bytom/bytom@v1.1.2-0.20210127130405-ae40204c0b09/database/store_test.go (about)

     1  package database
     2  
     3  import (
     4  	"os"
     5  	"testing"
     6  
     7  	"github.com/bytom/bytom/config"
     8  	"github.com/bytom/bytom/database/storage"
     9  	"github.com/bytom/bytom/protocol"
    10  	"github.com/bytom/bytom/protocol/bc"
    11  	"github.com/bytom/bytom/protocol/bc/types"
    12  	"github.com/bytom/bytom/protocol/state"
    13  	"github.com/bytom/bytom/testutil"
    14  	dbm "github.com/bytom/bytom/database/leveldb"
    15  )
    16  
    17  func TestLoadBlockIndex(t *testing.T) {
    18  	defer os.RemoveAll("temp")
    19  	testDB := dbm.NewDB("testdb", "leveldb", "temp")
    20  	store := NewStore(testDB)
    21  
    22  	block := config.GenesisBlock()
    23  	txStatus := bc.NewTransactionStatus()
    24  
    25  	if err := store.SaveBlock(block, txStatus); err != nil {
    26  		t.Fatal(err)
    27  	}
    28  
    29  	for block.Height <= 128 {
    30  		preHash := block.Hash()
    31  		block.PreviousBlockHash = preHash
    32  		block.Height++
    33  		if err := store.SaveBlock(block, txStatus); err != nil {
    34  			t.Fatal(err)
    35  		}
    36  
    37  		if block.Height%32 != 0 {
    38  			continue
    39  		}
    40  
    41  		for i := uint64(0); i < block.Height/32; i++ {
    42  			block.Nonce++
    43  			if err := store.SaveBlock(block, txStatus); err != nil {
    44  				t.Fatal(err)
    45  			}
    46  		}
    47  	}
    48  
    49  	if _, err := store.LoadBlockIndex(128); err != nil {
    50  		t.Fatal(err)
    51  	}
    52  }
    53  
    54  func TestLoadBlockIndexBestHeight(t *testing.T) {
    55  	cases := []struct {
    56  		blockBestHeight uint64
    57  		stateBestHeight uint64
    58  	}{
    59  		{
    60  			blockBestHeight: 100,
    61  			stateBestHeight: 90,
    62  		},
    63  		{
    64  			blockBestHeight: 100,
    65  			stateBestHeight: 0,
    66  		},
    67  		{
    68  			blockBestHeight: 100,
    69  			stateBestHeight: 100,
    70  		},
    71  	}
    72  
    73  	defer os.RemoveAll("temp")
    74  	testDB := dbm.NewDB("testdb", "leveldb", "temp")
    75  	store := NewStore(testDB)
    76  	var savedBlocks []types.Block
    77  
    78  	for _, c := range cases {
    79  		block := config.GenesisBlock()
    80  		txStatus := bc.NewTransactionStatus()
    81  
    82  		for i := uint64(0); i < c.blockBestHeight; i++ {
    83  			if err := store.SaveBlock(block, txStatus); err != nil {
    84  				t.Fatal(err)
    85  			}
    86  
    87  			savedBlocks = append(savedBlocks, *block)
    88  			block.PreviousBlockHash = block.Hash()
    89  			block.Height++
    90  		}
    91  
    92  		index, err := store.LoadBlockIndex(c.stateBestHeight)
    93  		if err != nil {
    94  			t.Fatal(err)
    95  		}
    96  
    97  		for _, block := range savedBlocks {
    98  			blockHash := block.Hash()
    99  			if block.Height <= c.stateBestHeight != index.BlockExist(&blockHash) {
   100  				t.Errorf("Error in load block index")
   101  			}
   102  		}
   103  	}
   104  }
   105  
   106  func TestLoadBlockIndexEquals(t *testing.T) {
   107  	defer os.RemoveAll("temp")
   108  	testDB := dbm.NewDB("testdb", "leveldb", "temp")
   109  	store := NewStore(testDB)
   110  
   111  	block := config.GenesisBlock()
   112  	txStatus := bc.NewTransactionStatus()
   113  	expectBlockIndex := state.NewBlockIndex()
   114  	var parent *state.BlockNode
   115  
   116  	for block.Height <= 100 {
   117  		if err := store.SaveBlock(block, txStatus); err != nil {
   118  			t.Fatal(err)
   119  		}
   120  
   121  		if block.Height != 0 {
   122  			parent = expectBlockIndex.GetNode(&block.PreviousBlockHash)
   123  		}
   124  
   125  		node, err := state.NewBlockNode(&block.BlockHeader, parent)
   126  		if err != nil {
   127  			t.Fatal(err)
   128  		}
   129  
   130  		expectBlockIndex.AddNode(node)
   131  		block.PreviousBlockHash = block.Hash()
   132  		block.Height++
   133  	}
   134  
   135  	index, err := store.LoadBlockIndex(100)
   136  	if err != nil {
   137  		t.Fatal(err)
   138  	}
   139  
   140  	if !testutil.DeepEqual(expectBlockIndex, index) {
   141  		t.Errorf("got block index:%v, expect block index:%v", index, expectBlockIndex)
   142  	}
   143  }
   144  func TestSaveChainStatus(t *testing.T) {
   145  	defer os.RemoveAll("temp")
   146  	testDB := dbm.NewDB("testdb", "leveldb", "temp")
   147  	store := NewStore(testDB)
   148  
   149  	node := &state.BlockNode{Height: 100, Hash: bc.Hash{V0: 0, V1: 1, V2: 2, V3: 3}}
   150  	view := &state.UtxoViewpoint{
   151  		Entries: map[bc.Hash]*storage.UtxoEntry{
   152  			bc.Hash{V0: 1, V1: 2, V2: 3, V3: 4}: &storage.UtxoEntry{IsCoinBase: false, BlockHeight: 100, Spent: false},
   153  			bc.Hash{V0: 1, V1: 2, V2: 3, V3: 4}: &storage.UtxoEntry{IsCoinBase: true, BlockHeight: 100, Spent: true},
   154  			bc.Hash{V0: 1, V1: 1, V2: 3, V3: 4}: &storage.UtxoEntry{IsCoinBase: false, BlockHeight: 100, Spent: true},
   155  		},
   156  	}
   157  
   158  	if err := store.SaveChainStatus(node, view); err != nil {
   159  		t.Fatal(err)
   160  	}
   161  
   162  	expectStatus := &protocol.BlockStoreState{Height: node.Height, Hash: &node.Hash}
   163  	if !testutil.DeepEqual(store.GetStoreStatus(), expectStatus) {
   164  		t.Errorf("got block status:%v, expect block status:%v", store.GetStoreStatus(), expectStatus)
   165  	}
   166  
   167  	for hash, utxo := range view.Entries {
   168  		if utxo.Spent && !utxo.IsCoinBase {
   169  			continue
   170  		}
   171  
   172  		gotUtxo, err := store.GetUtxo(&hash)
   173  		if err != nil {
   174  			t.Fatal(err)
   175  		}
   176  
   177  		if !testutil.DeepEqual(utxo, gotUtxo) {
   178  			t.Errorf("got utxo entry:%v, expect utxo entry:%v", gotUtxo, utxo)
   179  		}
   180  	}
   181  }
   182  
   183  func TestSaveBlock(t *testing.T) {
   184  	defer os.RemoveAll("temp")
   185  	testDB := dbm.NewDB("testdb", "leveldb", "temp")
   186  	store := NewStore(testDB)
   187  
   188  	block := config.GenesisBlock()
   189  	status := &bc.TransactionStatus{VerifyStatus: []*bc.TxVerifyResult{{StatusFail: true}}}
   190  	if err := store.SaveBlock(block, status); err != nil {
   191  		t.Fatal(err)
   192  	}
   193  
   194  	blockHash := block.Hash()
   195  	gotBlock, err := store.GetBlock(&blockHash)
   196  	if err != nil {
   197  		t.Fatal(err)
   198  	}
   199  
   200  	gotBlock.Transactions[0].Tx.SerializedSize = 0
   201  	gotBlock.Transactions[0].SerializedSize = 0
   202  	if !testutil.DeepEqual(block, gotBlock) {
   203  		t.Errorf("got block:%v, expect block:%v", gotBlock, block)
   204  	}
   205  
   206  	gotStatus, err := store.GetTransactionStatus(&blockHash)
   207  	if err != nil {
   208  		t.Fatal(err)
   209  	}
   210  
   211  	if !testutil.DeepEqual(status, gotStatus) {
   212  		t.Errorf("got status:%v, expect status:%v", gotStatus, status)
   213  	}
   214  
   215  	data := store.db.Get(CalcBlockHeaderKey(block.Height, &blockHash))
   216  	gotBlockHeader := types.BlockHeader{}
   217  	if err := gotBlockHeader.UnmarshalText(data); err != nil {
   218  		t.Fatal(err)
   219  	}
   220  
   221  	if !testutil.DeepEqual(block.BlockHeader, gotBlockHeader) {
   222  		t.Errorf("got block header:%v, expect block header:%v", gotBlockHeader, block.BlockHeader)
   223  	}
   224  }