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