hashcache_test.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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. package txscript
  5. import (
  6. "math/rand"
  7. "testing"
  8. "time"
  9. "github.com/pkt-cash/pktd/btcutil/er"
  10. "github.com/davecgh/go-spew/spew"
  11. "github.com/pkt-cash/pktd/wire"
  12. )
  13. // genTestTx creates a random transaction for uses within test cases.
  14. func genTestTx() (*wire.MsgTx, er.R) {
  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. _, err := rand.Read(randTxIn.PreviousOutPoint.Hash[:])
  26. if err != nil {
  27. return nil, er.E(err)
  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. if _, err := rand.Read(randTxOut.PkScript); err != nil {
  38. return nil, er.E(err)
  39. }
  40. tx.TxOut = append(tx.TxOut, &randTxOut)
  41. }
  42. return tx, nil
  43. }
  44. // TestHashCacheAddContainsHashes tests that after items have been added to the
  45. // hash cache, the ContainsHashes method returns true for all the items
  46. // inserted. Conversely, ContainsHashes should return false for any items
  47. // _not_ in the hash cache.
  48. func TestHashCacheAddContainsHashes(t *testing.T) {
  49. seed := time.Now().Unix()
  50. rand.Seed(seed)
  51. cache := NewHashCache(10)
  52. var err er.R
  53. // First, we'll generate 10 random transactions for use within our
  54. // tests.
  55. const numTxns = 10
  56. txns := make([]*wire.MsgTx, numTxns)
  57. for i := 0; i < numTxns; i++ {
  58. txns[i], err = genTestTx()
  59. if err != nil {
  60. t.Fatalf("unable to generate test tx: %v", err)
  61. }
  62. }
  63. // With the transactions generated, we'll add each of them to the hash
  64. // cache.
  65. for _, tx := range txns {
  66. cache.AddSigHashes(tx)
  67. }
  68. // Next, we'll ensure that each of the transactions inserted into the
  69. // cache are properly located by the ContainsHashes method.
  70. for _, tx := range txns {
  71. txid := tx.TxHash()
  72. if ok := cache.ContainsHashes(&txid); !ok {
  73. t.Fatalf("txid %v not found in cache but should be: ",
  74. txid)
  75. }
  76. }
  77. randTx, err := genTestTx()
  78. if err != nil {
  79. t.Fatalf("unable to generate tx: %v", err)
  80. }
  81. // Finally, we'll assert that a transaction that wasn't added to the
  82. // cache won't be reported as being present by the ContainsHashes
  83. // method.
  84. randTxid := randTx.TxHash()
  85. if ok := cache.ContainsHashes(&randTxid); ok {
  86. t.Fatalf("txid %v wasn't inserted into cache but was found",
  87. randTxid)
  88. }
  89. }
  90. // TestHashCacheAddGet tests that the sighashes for a particular transaction
  91. // are properly retrieved by the GetSigHashes function.
  92. func TestHashCacheAddGet(t *testing.T) {
  93. rand.Seed(time.Now().Unix())
  94. cache := NewHashCache(10)
  95. // To start, we'll generate a random transaction and compute the set of
  96. // sighashes for the transaction.
  97. randTx, err := genTestTx()
  98. if err != nil {
  99. t.Fatalf("unable to generate tx: %v", err)
  100. }
  101. sigHashes := NewTxSigHashes(randTx)
  102. // Next, add the transaction to the hash cache.
  103. cache.AddSigHashes(randTx)
  104. // The transaction inserted into the cache above should be found.
  105. txid := randTx.TxHash()
  106. cacheHashes, ok := cache.GetSigHashes(&txid)
  107. if !ok {
  108. t.Fatalf("tx %v wasn't found in cache", txid)
  109. }
  110. // Finally, the sighashes retrieved should exactly match the sighash
  111. // 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. // TestHashCachePurge tests that items are able to be properly removed from the
  118. // hash cache.
  119. func TestHashCachePurge(t *testing.T) {
  120. rand.Seed(time.Now().Unix())
  121. cache := NewHashCache(10)
  122. var err er.R
  123. // First we'll start by inserting numTxns transactions into the hash cache.
  124. const numTxns = 10
  125. txns := make([]*wire.MsgTx, numTxns)
  126. for i := 0; i < numTxns; i++ {
  127. txns[i], err = genTestTx()
  128. if err != nil {
  129. t.Fatalf("unable to generate test tx: %v", err)
  130. }
  131. }
  132. for _, tx := range txns {
  133. cache.AddSigHashes(tx)
  134. }
  135. // Once all the transactions have been inserted, we'll purge them from
  136. // the hash cache.
  137. for _, tx := range txns {
  138. txid := tx.TxHash()
  139. cache.PurgeSigHashes(&txid)
  140. }
  141. // At this point, none of the transactions inserted into the hash cache
  142. // 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. }