hashcache_test.go raw

   1  package txscript
   2  
   3  import (
   4  	"math/rand"
   5  	"testing"
   6  	"time"
   7  	
   8  	"github.com/davecgh/go-spew/spew"
   9  	
  10  	"github.com/p9c/p9/pkg/wire"
  11  )
  12  
  13  // genTestTx creates a random transaction for uses within test cases.
  14  func genTestTx() (*wire.MsgTx, error) {
  15  	tx := wire.NewMsgTx(2)
  16  	tx.Version = rand.Int31()
  17  	numTxins := rand.Intn(11)
  18  	for i := 0; i < numTxins; i++ {
  19  		randTxIn := wire.TxIn{
  20  			PreviousOutPoint: wire.OutPoint{
  21  				Index: uint32(rand.Int31()),
  22  			},
  23  			Sequence: uint32(rand.Int31()),
  24  		}
  25  		_, e := rand.Read(randTxIn.PreviousOutPoint.Hash[:])
  26  		if e != nil {
  27  			return nil, e
  28  		}
  29  		tx.TxIn = append(tx.TxIn, &randTxIn)
  30  	}
  31  	numTxouts := rand.Intn(11)
  32  	for i := 0; i < numTxouts; i++ {
  33  		randTxOut := wire.TxOut{
  34  			Value:    rand.Int63(),
  35  			PkScript: make([]byte, rand.Intn(30)),
  36  		}
  37  		var e error
  38  		if _, e = rand.Read(randTxOut.PkScript); E.Chk(e) {
  39  			return nil, e
  40  		}
  41  		tx.TxOut = append(tx.TxOut, &randTxOut)
  42  	}
  43  	return tx, nil
  44  }
  45  
  46  // TestHashCacheAddContainsHashes tests that after items have been added to the hash cache, the ContainsHashes method
  47  // returns true for all the items inserted. Conversely, ContainsHashes should return false for any items _not_ in the
  48  // hash cache.
  49  func TestHashCacheAddContainsHashes(t *testing.T) {
  50  	t.Parallel()
  51  	rand.Seed(time.Now().Unix())
  52  	cache := NewHashCache(10)
  53  	var e error
  54  	// First, we'll generate 10 random transactions for use within our tests.
  55  	const numTxns = 10
  56  	txns := make([]*wire.MsgTx, numTxns)
  57  	for i := 0; i < numTxns; i++ {
  58  		txns[i], e = genTestTx()
  59  		if e != nil {
  60  			t.Fatalf("unable to generate test tx: %v", e)
  61  		}
  62  	}
  63  	// With the transactions generated, we'll add each of them to the hash cache.
  64  	for _, tx := range txns {
  65  		cache.AddSigHashes(tx)
  66  	}
  67  	// Next, we'll ensure that each of the transactions inserted into the cache are properly located by the
  68  	// ContainsHashes method.
  69  	for _, tx := range txns {
  70  		txid := tx.TxHash()
  71  		if ok := cache.ContainsHashes(&txid); !ok {
  72  			t.Fatalf("txid %v not found in cache but should be: ",
  73  				txid,
  74  			)
  75  		}
  76  	}
  77  	randTx, e := genTestTx()
  78  	if e != nil {
  79  		t.Fatalf("unable to generate tx: %v", e)
  80  	}
  81  	// Finally, we'll assert that a transaction that wasn't added to the cache won't be reported as being present by the
  82  	// ContainsHashes method.
  83  	randTxid := randTx.TxHash()
  84  	if ok := cache.ContainsHashes(&randTxid); ok {
  85  		t.Fatalf("txid %v wasn't inserted into cache but was found",
  86  			randTxid,
  87  		)
  88  	}
  89  }
  90  
  91  // TestHashCacheAddGet tests that the sighashes for a particular transaction are properly retrieved by the GetSigHashes
  92  // function.
  93  func TestHashCacheAddGet(t *testing.T) {
  94  	t.Parallel()
  95  	rand.Seed(time.Now().Unix())
  96  	cache := NewHashCache(10)
  97  	// To start, we'll generate a random transaction and compute the set of sighashes for the transaction.
  98  	randTx, e := genTestTx()
  99  	if e != nil {
 100  		t.Fatalf("unable to generate tx: %v", e)
 101  	}
 102  	sigHashes := NewTxSigHashes(randTx)
 103  	// Next, add the transaction to the hash cache.
 104  	cache.AddSigHashes(randTx)
 105  	// The transaction inserted into the cache above should be found.
 106  	txid := randTx.TxHash()
 107  	cacheHashes, ok := cache.GetSigHashes(&txid)
 108  	if !ok {
 109  		t.Fatalf("tx %v wasn't found in cache", txid)
 110  	}
 111  	// Finally, the sighashes retrieved should exactly match the sighash originally inserted into the cache.
 112  	if *sigHashes != *cacheHashes {
 113  		t.Fatalf("sighashes don't match: expected %v, got %v",
 114  			spew.Sdump(sigHashes), spew.Sdump(cacheHashes),
 115  		)
 116  	}
 117  }
 118  
 119  // TestHashCachePurge tests that items are able to be properly removed from the hash cache.
 120  func TestHashCachePurge(t *testing.T) {
 121  	t.Parallel()
 122  	rand.Seed(time.Now().Unix())
 123  	cache := NewHashCache(10)
 124  	var e error
 125  	// First we'll start by inserting numTxns transactions into the hash cache.
 126  	const numTxns = 10
 127  	txns := make([]*wire.MsgTx, numTxns)
 128  	for i := 0; i < numTxns; i++ {
 129  		txns[i], e = genTestTx()
 130  		if e != nil {
 131  			t.Fatalf("unable to generate test tx: %v", e)
 132  		}
 133  	}
 134  	for _, tx := range txns {
 135  		cache.AddSigHashes(tx)
 136  	}
 137  	// Once all the transactions have been inserted, we'll purge them from the hash cache.
 138  	for _, tx := range txns {
 139  		txid := tx.TxHash()
 140  		cache.PurgeSigHashes(&txid)
 141  	}
 142  	// At this point, none of the transactions inserted into the hash cache should be found within the cache.
 143  	for _, tx := range txns {
 144  		txid := tx.TxHash()
 145  		if ok := cache.ContainsHashes(&txid); ok {
 146  			t.Fatalf("tx %v found in cache but should have "+
 147  				"been purged: ", txid,
 148  			)
 149  		}
 150  	}
 151  }
 152