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  }