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  }