github.com/turingchain2020/turingchain@v1.1.21/blockchain/blockstore_test.go (about) 1 package blockchain 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "os" 7 "testing" 8 9 "github.com/stretchr/testify/mock" 10 11 "github.com/turingchain2020/turingchain/util" 12 13 "github.com/turingchain2020/turingchain/common" 14 dbm "github.com/turingchain2020/turingchain/common/db" 15 "github.com/turingchain2020/turingchain/queue" 16 qmocks "github.com/turingchain2020/turingchain/queue/mocks" 17 "github.com/turingchain2020/turingchain/types" 18 "github.com/stretchr/testify/assert" 19 "github.com/stretchr/testify/require" 20 ) 21 22 func InitEnv() *BlockChain { 23 cfg := types.NewTuringchainConfig(types.GetDefaultCfgstring()) 24 q := queue.New("channel") 25 q.SetConfig(cfg) 26 chain := New(cfg) 27 chain.client = q.Client() 28 return chain 29 } 30 31 func TestGetStoreUpgradeMeta(t *testing.T) { 32 dir, err := ioutil.TempDir("", "example") 33 assert.Nil(t, err) 34 defer os.RemoveAll(dir) // clean up 35 os.RemoveAll(dir) //删除已存在目录 36 37 blockStoreDB := dbm.NewDB("blockchain", "leveldb", dir, 100) 38 39 chain := InitEnv() 40 blockStore := NewBlockStore(chain, blockStoreDB, nil) 41 require.NotNil(t, blockStore) 42 43 meta, err := blockStore.GetStoreUpgradeMeta() 44 require.NoError(t, err) 45 require.Equal(t, meta.Version, "0.0.0") 46 47 meta.Version = "1.0.0" 48 err = blockStore.SetStoreUpgradeMeta(meta) 49 require.NoError(t, err) 50 meta, err = blockStore.GetStoreUpgradeMeta() 51 require.NoError(t, err) 52 require.Equal(t, meta.Version, "1.0.0") 53 } 54 55 func TestSeqSaveAndGet(t *testing.T) { 56 dir, err := ioutil.TempDir("", "example") 57 assert.Nil(t, err) 58 defer os.RemoveAll(dir) // clean up 59 os.RemoveAll(dir) //删除已存在目录 60 61 blockStoreDB := dbm.NewDB("blockchain", "leveldb", dir, 100) 62 63 chain := InitEnv() 64 blockStore := NewBlockStore(chain, blockStoreDB, nil) 65 assert.NotNil(t, blockStore) 66 blockStore.saveSequence = true 67 blockStore.isParaChain = false 68 69 newBatch := blockStore.NewBatch(true) 70 seq, err := blockStore.saveBlockSequence(newBatch, []byte("s0"), 0, 1, 0) 71 assert.Nil(t, err) 72 assert.Equal(t, int64(0), seq) 73 err = newBatch.Write() 74 assert.Nil(t, err) 75 76 newBatch = blockStore.NewBatch(true) 77 seq, err = blockStore.saveBlockSequence(newBatch, []byte("s1"), 1, 1, 0) 78 assert.Nil(t, err) 79 assert.Equal(t, int64(1), seq) 80 err = newBatch.Write() 81 assert.Nil(t, err) 82 83 s, err := blockStore.LoadBlockLastSequence() 84 assert.Nil(t, err) 85 assert.Equal(t, int64(1), s) 86 87 s2, err := blockStore.GetBlockSequence(s) 88 assert.Nil(t, err) 89 assert.Equal(t, []byte("s1"), s2.Hash) 90 91 s3, err := blockStore.GetSequenceByHash([]byte("s1")) 92 assert.Nil(t, err) 93 assert.Equal(t, int64(1), s3) 94 } 95 96 func TestParaSeqSaveAndGet(t *testing.T) { 97 dir, err := ioutil.TempDir("", "example") 98 assert.Nil(t, err) 99 defer os.RemoveAll(dir) // clean up 100 os.RemoveAll(dir) //删除已存在目录 101 102 blockStoreDB := dbm.NewDB("blockchain", "leveldb", dir, 100) 103 104 bchain := InitEnv() 105 blockStore := NewBlockStore(bchain, blockStoreDB, nil) 106 assert.NotNil(t, blockStore) 107 blockStore.saveSequence = true 108 blockStore.isParaChain = true 109 110 newBatch := blockStore.NewBatch(true) 111 seq, err := blockStore.saveBlockSequence(newBatch, []byte("s0"), 0, 1, 1) 112 assert.Nil(t, err) 113 assert.Equal(t, int64(0), seq) 114 err = newBatch.Write() 115 assert.Nil(t, err) 116 117 newBatch = blockStore.NewBatch(true) 118 seq, err = blockStore.saveBlockSequence(newBatch, []byte("s1"), 1, 1, 10) 119 assert.Nil(t, err) 120 assert.Equal(t, int64(1), seq) 121 err = newBatch.Write() 122 assert.Nil(t, err) 123 124 s, err := blockStore.LoadBlockLastSequence() 125 assert.Nil(t, err) 126 assert.Equal(t, int64(1), s) 127 128 s2, err := blockStore.GetBlockSequence(s) 129 assert.Nil(t, err) 130 assert.Equal(t, []byte("s1"), s2.Hash) 131 132 s3, err := blockStore.GetSequenceByHash([]byte("s1")) 133 assert.Nil(t, err) 134 assert.Equal(t, int64(1), s3) 135 136 s4, err := blockStore.GetMainSequenceByHash([]byte("s1")) 137 assert.Nil(t, err) 138 assert.Equal(t, int64(10), s4) 139 140 s5, err := blockStore.LoadBlockLastMainSequence() 141 assert.Nil(t, err) 142 assert.Equal(t, int64(10), s5) 143 144 s6, err := blockStore.GetBlockByMainSequence(1) 145 assert.Nil(t, err) 146 assert.Equal(t, []byte("s0"), s6.Hash) 147 148 chain := &BlockChain{ 149 blockStore: blockStore, 150 } 151 s7, err := chain.ProcGetMainSeqByHash([]byte("s0")) 152 assert.Nil(t, err) 153 assert.Equal(t, int64(1), s7) 154 155 _, err = chain.ProcGetMainSeqByHash([]byte("s0-not-exist")) 156 assert.NotNil(t, err) 157 } 158 159 func TestSeqCreateAndDelete(t *testing.T) { 160 dir, err := ioutil.TempDir("", "example") 161 assert.Nil(t, err) 162 defer os.RemoveAll(dir) // clean up 163 os.RemoveAll(dir) //删除已存在目录 164 165 blockStoreDB := dbm.NewDB("blockchain", "leveldb", dir, 100) 166 167 chain := InitEnv() 168 blockStore := NewBlockStore(chain, blockStoreDB, nil) 169 assert.NotNil(t, blockStore) 170 blockStore.saveSequence = false 171 blockStore.isParaChain = true 172 173 batch := blockStore.NewBatch(true) 174 for i := 0; i <= 100; i++ { 175 var header types.Header 176 header.Height = int64(i) 177 header.Hash = []byte(fmt.Sprintf("%d", i)) 178 headerkvs, err := saveHeaderTable(blockStore.db, &header) 179 assert.Nil(t, err) 180 for _, kv := range headerkvs { 181 batch.Set(kv.GetKey(), kv.GetValue()) 182 } 183 batch.Set(calcHeightToHashKey(int64(i)), []byte(fmt.Sprintf("%d", i))) 184 } 185 blockStore.height = 100 186 batch.Write() 187 188 blockStore.saveSequence = true 189 blockStore.CreateSequences(10) 190 seq, err := blockStore.LoadBlockLastSequence() 191 assert.Nil(t, err) 192 assert.Equal(t, int64(100), seq) 193 194 seq, err = blockStore.GetSequenceByHash([]byte("1")) 195 assert.Nil(t, err) 196 assert.Equal(t, int64(1), seq) 197 198 seq, err = blockStore.GetSequenceByHash([]byte("0")) 199 assert.Nil(t, err) 200 assert.Equal(t, int64(0), seq) 201 } 202 203 func TestHasTx(t *testing.T) { 204 dir, err := ioutil.TempDir("", "example") 205 assert.Nil(t, err) 206 defer os.RemoveAll(dir) // clean up 207 os.RemoveAll(dir) //删除已存在目录 208 209 blockStoreDB := dbm.NewDB("blockchain", "leveldb", dir, 100) 210 211 chain := InitEnv() 212 cfg := chain.client.GetConfig() 213 blockStore := NewBlockStore(chain, blockStoreDB, chain.client) 214 assert.NotNil(t, blockStore) 215 blockStore.saveSequence = false 216 blockStore.isParaChain = false 217 cfg.S("quickIndex", true) 218 219 //txstring1 和txstring2的短hash是一样的,但是全hash是不一样的 220 txstring1 := "0xaf095d11326ebb97d142fdb0e0138ef28524470c121b4811bdd05857b2d06764" 221 txstring2 := "0xaf095d11326ebb97d142fdb0e0138ef28524470c121b4811bdd05857b2d06765" 222 txstring3 := "0x8fac317e02ee25b1bbc5bd5a8570962b482928b014d14817b3c7a4e6aeddb3c6" 223 txstring4 := "0x6522279c4fae53965e7bfbd35651dcd68813a50c65bf7af20b02c9bfe3d2ce8b" 224 225 txhash1, err := common.FromHex(txstring1) 226 assert.Nil(t, err) 227 txhash2, err := common.FromHex(txstring2) 228 assert.Nil(t, err) 229 txhash3, err := common.FromHex(txstring3) 230 assert.Nil(t, err) 231 txhash4, err := common.FromHex(txstring4) 232 assert.Nil(t, err) 233 234 batch := blockStore.NewBatch(true) 235 236 var txresult types.TxResult 237 txresult.Height = 1 238 txresult.Index = int32(1) 239 batch.Set(cfg.CalcTxKey(txhash1), types.Encode(&txresult)) 240 batch.Set(types.CalcTxShortKey(txhash1), []byte("1")) 241 242 txresult.Height = 3 243 txresult.Index = int32(3) 244 batch.Set(cfg.CalcTxKey(txhash3), types.Encode(&txresult)) 245 batch.Set(types.CalcTxShortKey(txhash3), []byte("1")) 246 247 batch.Write() 248 249 has, _ := blockStore.HasTx(txhash1) 250 assert.Equal(t, has, true) 251 252 has, _ = blockStore.HasTx(txhash2) 253 assert.Equal(t, has, false) 254 255 has, _ = blockStore.HasTx(txhash3) 256 assert.Equal(t, has, true) 257 258 has, _ = blockStore.HasTx(txhash4) 259 assert.Equal(t, has, false) 260 } 261 262 func TestGetRealTxResult(t *testing.T) { 263 dir, err := ioutil.TempDir("", "example") 264 assert.Nil(t, err) 265 defer os.RemoveAll(dir) // clean up 266 os.RemoveAll(dir) //删除已存在目录 267 blockStoreDB := dbm.NewDB("blockchain", "leveldb", dir, 100) 268 chain := InitEnv() 269 cfg := chain.client.GetConfig() 270 blockStore := NewBlockStore(chain, blockStoreDB, chain.client) 271 assert.NotNil(t, blockStore) 272 273 // generate blockdetail 274 txs := util.GenCoinsTxs(cfg, util.HexToPrivkey("4257D8692EF7FE13C68B65D6A52F03933DB2FA5CE8FAF210B5B8B80C721CED01"), 10) 275 block := &types.Block{Txs: txs} 276 block.MainHash = block.Hash(cfg) 277 block.Height = 0 278 blockdetail := &types.BlockDetail{ 279 Block: block, 280 Receipts: []*types.ReceiptData{ 281 {Ty: 0, Logs: []*types.ReceiptLog{{Ty: 0, Log: []byte("000")}, {Ty: 0, Log: []byte("0000")}}}, 282 {Ty: 1, Logs: []*types.ReceiptLog{{Ty: 111, Log: []byte("111")}, {Ty: 1111, Log: []byte("1111")}}}, 283 {Ty: 2, Logs: []*types.ReceiptLog{{Ty: 222, Log: []byte("222")}, {Ty: 2222, Log: []byte("2222")}}}, 284 {Ty: 3, Logs: []*types.ReceiptLog{{Ty: 333, Log: []byte("333")}, {Ty: 3333, Log: []byte("3333")}}}, 285 }, 286 KV: []*types.KeyValue{{Key: []byte("000"), Value: []byte("000")}, {Key: []byte("111"), Value: []byte("111")}}, 287 } 288 289 // save blockdetail 290 newbatch := blockStore.NewBatch(true) 291 _, err = blockStore.SaveBlock(newbatch, blockdetail, 0) 292 assert.NoError(t, err) 293 newbatch.Write() 294 295 // check 296 cfg.S("reduceLocaldb", true) 297 txr := &types.TxResult{ 298 Height: 0, 299 Index: 0, 300 } 301 blockStore.getRealTxResult(txr) 302 assert.Equal(t, txr.Tx.Nonce, txs[0].Nonce) 303 assert.Equal(t, txr.Receiptdate.Ty, blockdetail.Receipts[0].Ty) 304 } 305 306 func TestMustSaveKvset(t *testing.T) { 307 kvset := types.LocalDBSet{ 308 KV: []*types.KeyValue{ 309 {Key: []byte("000"), Value: []byte("000")}, 310 {Key: []byte("111"), Value: []byte("111")}, 311 {Key: []byte("222"), Value: nil}, 312 }, 313 } 314 315 dir, err := ioutil.TempDir("", "example") 316 assert.Nil(t, err) 317 defer os.RemoveAll(dir) // clean up 318 os.RemoveAll(dir) //删除已存在目录 319 blockStoreDB := dbm.NewDB("blockchain", "leveldb", dir, 100) 320 321 chain := InitEnv() 322 blockStore := NewBlockStore(chain, blockStoreDB, chain.client) 323 assert.NotNil(t, blockStore) 324 blockStore.Set([]byte("222"), []byte("222")) 325 326 blockStore.mustSaveKvset(&kvset) 327 328 v, err := blockStoreDB.Get([]byte("000")) 329 assert.Nil(t, err) 330 assert.Equal(t, []byte("000"), v) 331 332 v, err = blockStoreDB.Get([]byte("111")) 333 assert.Nil(t, err) 334 assert.Equal(t, []byte("111"), v) 335 336 _, err = blockStoreDB.Get([]byte("222")) 337 assert.Equal(t, types.ErrNotFound, err) 338 } 339 340 func TestGetCurChunkNumAndRecvChunkHash(t *testing.T) { 341 dir, err := ioutil.TempDir("", "example") 342 assert.Nil(t, err) 343 defer os.RemoveAll(dir) // clean up 344 os.RemoveAll(dir) //删除已存在目录 345 blockStoreDB := dbm.NewDB("blockchain", "leveldb", dir, 100) 346 347 chain := InitEnv() 348 blockStore := NewBlockStore(chain, blockStoreDB, chain.client) 349 assert.NotNil(t, blockStore) 350 height := blockStore.getCurChunkNum(ChunkNumToHash) 351 assert.Equal(t, height, int64(-1)) 352 height = blockStore.getCurChunkNum(RecvChunkNumToHash) 353 assert.Equal(t, height, int64(-1)) 354 blockStore.Set(calcChunkNumToHash(1), []byte("1111")) 355 blockStore.Set(calcChunkNumToHash(8), []byte("8888")) 356 height = blockStore.getCurChunkNum(ChunkNumToHash) 357 assert.Equal(t, height, int64(8)) 358 blockStore.Set(calcRecvChunkNumToHash(1), []byte("1111")) 359 blockStore.Set(calcRecvChunkNumToHash(8), []byte("1111")) 360 height = blockStore.getCurChunkNum(RecvChunkNumToHash) 361 assert.Equal(t, height, int64(8)) 362 363 blockStore.Set(append(ChunkNumToHash, []byte("jfakjl")...), []byte("8888")) 364 height = blockStore.getCurChunkNum(ChunkNumToHash) 365 assert.Equal(t, height, int64(-1)) 366 367 // test getRecvChunkHash 368 _, err = blockStore.getRecvChunkHash(15) 369 assert.Equal(t, err, types.ErrNotFound) 370 hash := []byte("11111111111111111") 371 blockStore.Set(calcRecvChunkNumToHash(15), types.Encode(&types.ChunkInfo{ 372 ChunkNum: 1, 373 ChunkHash: hash, 374 Start: 1, 375 End: 2, 376 })) 377 v, err := blockStore.getRecvChunkHash(15) 378 assert.Nil(t, err) 379 assert.Equal(t, v, hash) 380 } 381 382 func TestGetSetSerialChunkNum(t *testing.T) { 383 dir, err := ioutil.TempDir("", "example") 384 assert.Nil(t, err) 385 defer os.RemoveAll(dir) // clean up 386 os.RemoveAll(dir) //删除已存在目录 387 blockStoreDB := dbm.NewDB("blockchain", "leveldb", dir, 100) 388 389 chain := InitEnv() 390 blockStore := NewBlockStore(chain, blockStoreDB, chain.client) 391 392 height := blockStore.GetMaxSerialChunkNum() 393 assert.Equal(t, height, int64(-1)) 394 395 err = blockStore.SetMaxSerialChunkNum(10) 396 assert.Nil(t, err) 397 height = blockStore.GetMaxSerialChunkNum() 398 assert.Equal(t, height, int64(10)) 399 } 400 401 func TestGetBodyFromP2Pstore(t *testing.T) { 402 cfg := types.NewTuringchainConfig(types.GetDefaultCfgstring()) 403 q := queue.New("channel") 404 q.SetConfig(cfg) 405 chain := New(cfg) 406 client := &qmocks.Client{} 407 chain.client = client 408 409 dir, err := ioutil.TempDir("", "example") 410 assert.Nil(t, err) 411 defer os.RemoveAll(dir) // clean up 412 os.RemoveAll(dir) //删除已存在目录 413 blockStoreDB := dbm.NewDB("blockchain", "leveldb", dir, 100) 414 415 client.On("GetConfig").Return(cfg) 416 client.On("NewMessage", mock.Anything, mock.Anything, mock.Anything).Return(&queue.Message{}) 417 blockStore := NewBlockStore(chain, blockStoreDB, chain.client) 418 blockStore.UpdateHeight2(100000) 419 client.On("Send", mock.Anything, mock.Anything).Return(nil) 420 rspMsg := &queue.Message{Data: &types.BlockBodys{Items: []*types.BlockBody{{}, {}}}} 421 client.On("WaitTimeout", mock.Anything, mock.Anything).Return(rspMsg, nil) 422 423 blockHash := []byte("111111111111111") 424 chunkHash := []byte("222222222222222") 425 chunkInfo := types.ChunkInfo{ 426 ChunkHash: chunkHash, 427 Start: 0, 428 End: 999, 429 } 430 blockStoreDB.Set(calcChunkNumToHash(0), types.Encode(&chunkInfo)) 431 bodys, err := blockStore.getBodyFromP2Pstore(blockHash, 1, 10) 432 assert.Nil(t, err) 433 assert.Equal(t, len(bodys.Items), 2) 434 435 blockheader := &types.Header{ 436 Hash: blockHash, 437 Height: 1, 438 } 439 body, err := blockStore.multiGetBody(blockheader, "", calcHeightHashKey(1, blockHash), nil) 440 assert.Nil(t, body) 441 assert.Equal(t, err, types.ErrHashNotExist) 442 bcConfig := cfg.GetModuleConfig().BlockChain 443 bcConfig.EnableFetchP2pstore = true 444 body, err = blockStore.multiGetBody(blockheader, "", calcHeightHashKey(1, blockHash), nil) 445 assert.Nil(t, err) 446 assert.NotNil(t, body) 447 }