github.com/ZuluSpl0it/Sia@v1.3.7/modules/wallet/scan_test.go (about)

     1  package wallet
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/NebulousLabs/Sia/build"
     7  	"github.com/NebulousLabs/Sia/crypto"
     8  	"github.com/NebulousLabs/Sia/modules"
     9  	"github.com/NebulousLabs/Sia/types"
    10  	"github.com/NebulousLabs/fastrand"
    11  )
    12  
    13  // TestScanLargeIndex tests the limits of the seedScanner.scan function.
    14  func TestScanLargeIndex(t *testing.T) {
    15  	if testing.Short() {
    16  		t.SkipNow()
    17  	}
    18  
    19  	// create an empty wallet
    20  	wt, err := createBlankWalletTester("TestScanLargeIndex")
    21  	if err != nil {
    22  		t.Fatal(err)
    23  	}
    24  	defer wt.closeWt()
    25  	var masterKey crypto.TwofishKey
    26  	fastrand.Read(masterKey[:])
    27  	_, err = wt.wallet.Encrypt(masterKey)
    28  	if err != nil {
    29  		t.Fatal(err)
    30  	}
    31  	err = wt.wallet.Unlock(masterKey)
    32  	if err != nil {
    33  		t.Fatal(err)
    34  	}
    35  
    36  	// set the wallet's seed progress to a high number and then mine some coins.
    37  	wt.wallet.mu.Lock()
    38  	dbPutPrimarySeedProgress(wt.wallet.dbTx, numInitialKeys+1)
    39  	wt.wallet.mu.Unlock()
    40  	if err != nil {
    41  		t.Fatal(err)
    42  	}
    43  	for i := types.BlockHeight(0); i <= types.MaturityDelay; i++ {
    44  		_, err = wt.miner.AddBlock()
    45  		if err != nil {
    46  			t.Fatal(err)
    47  		}
    48  
    49  	}
    50  
    51  	// send money to ourselves so that we sweep a real output (instead of just
    52  	// a miner payout)
    53  	uc, err := wt.wallet.NextAddress()
    54  	if err != nil {
    55  		t.Fatal(err)
    56  	}
    57  	_, err = wt.wallet.SendSiacoins(types.SiacoinPrecision, uc.UnlockHash())
    58  	if err != nil {
    59  		t.Fatal(err)
    60  	}
    61  	_, err = wt.miner.AddBlock()
    62  	if err != nil {
    63  		t.Fatal(err)
    64  	}
    65  
    66  	// create seed scanner and scan the block
    67  	seed, _, _ := wt.wallet.PrimarySeed()
    68  	ss := newSeedScanner(seed, wt.wallet.log)
    69  	err = ss.scan(wt.cs, wt.wallet.tg.StopChan())
    70  	if err != nil {
    71  		t.Fatal(err)
    72  	}
    73  
    74  	// no outputs should have been added
    75  	if len(ss.siacoinOutputs) != 0 {
    76  		t.Error("expected 0 outputs, got", len(ss.siacoinOutputs))
    77  		for _, o := range ss.siacoinOutputs {
    78  			t.Log(o.seedIndex, o.value)
    79  		}
    80  	}
    81  	if ss.largestIndexSeen != 0 {
    82  		t.Error("expected no index to be seen, got", ss.largestIndexSeen)
    83  	}
    84  }
    85  
    86  // TestScanLoop tests that the scan loop will continue to run as long as it
    87  // finds indices in the upper half of the last set of generated keys.
    88  func TestScanLoop(t *testing.T) {
    89  	if testing.Short() || !build.VLONG {
    90  		t.SkipNow()
    91  	}
    92  
    93  	// create a wallet
    94  	wt, err := createWalletTester("TestScanLoop", modules.ProdDependencies)
    95  	if err != nil {
    96  		t.Fatal(err)
    97  	}
    98  	defer wt.closeWt()
    99  
   100  	// send money to ourselves at four specific indices. This should cause the
   101  	// scanner to loop exactly three times.
   102  	indices := []uint64{500, 2500, 8000, 100000}
   103  	for _, index := range indices {
   104  		wt.wallet.mu.Lock()
   105  		dbPutPrimarySeedProgress(wt.wallet.dbTx, index)
   106  		wt.wallet.mu.Unlock()
   107  		if err != nil {
   108  			t.Fatal(err)
   109  		}
   110  
   111  		uc, err := wt.wallet.NextAddress()
   112  		if err != nil {
   113  			t.Fatal(err)
   114  		}
   115  		_, err = wt.wallet.SendSiacoins(types.SiacoinPrecision, uc.UnlockHash())
   116  		if err != nil {
   117  			t.Fatal(err)
   118  		}
   119  	}
   120  	_, err = wt.miner.AddBlock()
   121  	if err != nil {
   122  		t.Fatal(err)
   123  	}
   124  
   125  	// create seed scanner and scan the block
   126  	seed, _, _ := wt.wallet.PrimarySeed()
   127  	ss := newSeedScanner(seed, wt.wallet.log)
   128  	err = ss.scan(wt.cs, wt.wallet.tg.StopChan())
   129  	if err != nil {
   130  		t.Fatal(err)
   131  	}
   132  
   133  	// the scanner should have generated a specific number of keys
   134  	expected := numInitialKeys + (numInitialKeys * scanMultiplier) + (numInitialKeys * scanMultiplier * scanMultiplier)
   135  	if uint64(len(ss.keys)) != expected {
   136  		t.Errorf("expected %v keys, got %v", expected, len(ss.keys))
   137  	}
   138  	// the largest index seen should be the penultimate element (+2, since 2
   139  	// addresses are generated when sending coins). The last element should
   140  	// not be seen, because it was outside the scanning range.
   141  	if ss.largestIndexSeen != indices[len(indices)-2]+2 {
   142  		t.Errorf("expected largest index to be %v, got %v", indices[len(indices)-2]+2, ss.largestIndexSeen)
   143  	}
   144  }