github.com/lbryio/lbcd@v0.22.119/txscript/hashcache_test.go (about)

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