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 }