github.com/avahowell/sia@v0.5.1-beta.0.20160524050156-83dcc3d37c94/modules/transactionpool/persist_test.go (about) 1 package transactionpool 2 3 import ( 4 "os" 5 "path/filepath" 6 "testing" 7 8 "github.com/NebulousLabs/Sia/modules" 9 "github.com/NebulousLabs/Sia/persist" 10 "github.com/NebulousLabs/Sia/types" 11 12 "github.com/NebulousLabs/bolt" 13 ) 14 15 // TestRescan triggers a rescan in the transaction pool, verifying that the 16 // rescan code does not cause deadlocks or crashes. 17 func TestRescan(t *testing.T) { 18 tpt, err := createTpoolTester("TestRescan") 19 if err != nil { 20 t.Fatal(err) 21 } 22 if testing.Short() { 23 t.SkipNow() 24 } 25 26 // Create a valid transaction set using the wallet. 27 txns, err := tpt.wallet.SendSiacoins(types.NewCurrency64(100), types.UnlockHash{}) 28 if err != nil { 29 t.Fatal(err) 30 } 31 if len(tpt.tpool.transactionSets) != 1 { 32 t.Error("sending coins did not increase the transaction sets by 1") 33 } 34 // Mine the transaction into a block, so that it's in the consensus set. 35 _, err = tpt.miner.AddBlock() 36 if err != nil { 37 t.Fatal(err) 38 } 39 40 // Close the tpool, delete the persistence, then restart the tpool. The 41 // tpool should still recognize the transaction set as a duplicate. 42 persistDir := tpt.tpool.persistDir 43 err = tpt.tpool.Close() 44 if err != nil { 45 t.Fatal(err) 46 } 47 err = os.RemoveAll(persistDir) 48 if err != nil { 49 t.Fatal(err) 50 } 51 tpt.tpool, err = New(tpt.cs, tpt.gateway, persistDir) 52 if err != nil { 53 t.Fatal(err) 54 } 55 err = tpt.tpool.AcceptTransactionSet(txns) 56 if err != modules.ErrDuplicateTransactionSet { 57 t.Fatal("expecting modules.ErrDuplicateTransactionSet, got:", err) 58 } 59 60 // Close the tpool, corrupt the database, then restart the tpool. The tpool 61 // should still recognize the transaction set as a duplicate. 62 err = tpt.tpool.Close() 63 if err != nil { 64 t.Fatal(err) 65 } 66 db, err := persist.OpenDatabase(dbMetadata, filepath.Join(persistDir, dbFilename)) 67 if err != nil { 68 t.Fatal(err) 69 } 70 err = db.Update(func(tx *bolt.Tx) error { 71 ccBytes := tx.Bucket(bucketRecentConsensusChange).Get(fieldRecentConsensusChange) 72 // copy the bytes due to bolt's mmap. 73 newCCBytes := make([]byte, len(ccBytes)) 74 copy(newCCBytes, ccBytes) 75 newCCBytes[0]++ 76 return tx.Bucket(bucketRecentConsensusChange).Put(fieldRecentConsensusChange, newCCBytes) 77 }) 78 if err != nil { 79 t.Fatal(err) 80 } 81 err = db.Close() 82 if err != nil { 83 t.Fatal(err) 84 } 85 tpt.tpool, err = New(tpt.cs, tpt.gateway, persistDir) 86 if err != nil { 87 t.Fatal(err) 88 } 89 err = tpt.tpool.AcceptTransactionSet(txns) 90 if err != modules.ErrDuplicateTransactionSet { 91 t.Fatal("expecting modules.ErrDuplicateTransactionSet, got:", err) 92 } 93 }