sigcache_test.go raw

   1  package txscript
   2  
   3  import (
   4  	"crypto/rand"
   5  	"testing"
   6  	
   7  	"github.com/p9c/p9/pkg/chainhash"
   8  	"github.com/p9c/p9/pkg/ecc"
   9  )
  10  
  11  // genRandomSig returns a random message, a signature of the message under the public key and the public key. This
  12  // function is used to generate randomized test data.
  13  func genRandomSig() (*chainhash.Hash, *ecc.Signature, *ecc.PublicKey, error) {
  14  	privKey, e := ecc.NewPrivateKey(ecc.S256())
  15  	if e != nil {
  16  		return nil, nil, nil, e
  17  	}
  18  	var msgHash chainhash.Hash
  19  	if _, e = rand.Read(msgHash[:]); E.Chk(e) {
  20  		return nil, nil, nil, e
  21  	}
  22  	sig, e := privKey.Sign(msgHash[:])
  23  	if e != nil {
  24  		return nil, nil, nil, e
  25  	}
  26  	return &msgHash, sig, privKey.PubKey(), nil
  27  }
  28  
  29  // TestSigCacheAddExists tests the ability to add, and later check the existence of a signature triplet in the signature
  30  // cache.
  31  func TestSigCacheAddExists(t *testing.T) {
  32  	sigCache := NewSigCache(200)
  33  	// Generate a random sigCache entry triplet.
  34  	msg1, sig1, key1, e := genRandomSig()
  35  	if e != nil {
  36  		t.Fatalf("unable to generate random signature test data")
  37  	}
  38  	// Add the triplet to the signature cache.
  39  	sigCache.Add(*msg1, sig1, key1)
  40  	// The previously added triplet should now be found within the sigcache.
  41  	sig1Copy, _ := ecc.ParseSignature(sig1.Serialize(), ecc.S256())
  42  	key1Copy, _ := ecc.ParsePubKey(key1.SerializeCompressed(), ecc.S256())
  43  	if !sigCache.Exists(*msg1, sig1Copy, key1Copy) {
  44  		t.Errorf("previously added item not found in signature cache")
  45  	}
  46  }
  47  
  48  // TestSigCacheAddEvictEntry tests the eviction case where a new signature triplet is added to a full signature cache
  49  // which should trigger randomized eviction, followed by adding the new element to the cache.
  50  func TestSigCacheAddEvictEntry(t *testing.T) {
  51  	// Create a sigcache that can hold up to 100 entries.
  52  	sigCacheSize := uint(100)
  53  	sigCache := NewSigCache(sigCacheSize)
  54  	// Fill the sigcache up with some random sig triplets.
  55  	for i := uint(0); i < sigCacheSize; i++ {
  56  		msg, sig, key, e := genRandomSig()
  57  		if e != nil {
  58  			t.Fatalf("unable to generate random signature test data")
  59  		}
  60  		sigCache.Add(*msg, sig, key)
  61  		sigCopy, _ := ecc.ParseSignature(sig.Serialize(), ecc.S256())
  62  		keyCopy, _ := ecc.ParsePubKey(key.SerializeCompressed(), ecc.S256())
  63  		if !sigCache.Exists(*msg, sigCopy, keyCopy) {
  64  			t.Errorf("previously added item not found in signature" +
  65  				"cache",
  66  			)
  67  		}
  68  	}
  69  	// The sigcache should now have sigCacheSize entries within it.
  70  	if uint(len(sigCache.validSigs)) != sigCacheSize {
  71  		t.Fatalf("sigcache should now have %v entries, instead it has %v",
  72  			sigCacheSize, len(sigCache.validSigs),
  73  		)
  74  	}
  75  	// Add a new entry, this should cause eviction of a randomly chosen previous entry.
  76  	msgNew, sigNew, keyNew, e := genRandomSig()
  77  	if e != nil {
  78  		t.Fatalf("unable to generate random signature test data")
  79  	}
  80  	sigCache.Add(*msgNew, sigNew, keyNew)
  81  	// The sigcache should still have sigCache entries.
  82  	if uint(len(sigCache.validSigs)) != sigCacheSize {
  83  		t.Fatalf("sigcache should now have %v entries, instead it has %v",
  84  			sigCacheSize, len(sigCache.validSigs),
  85  		)
  86  	}
  87  	// The entry added above should be found within the sigcache.
  88  	sigNewCopy, _ := ecc.ParseSignature(sigNew.Serialize(), ecc.S256())
  89  	keyNewCopy, _ := ecc.ParsePubKey(keyNew.SerializeCompressed(), ecc.S256())
  90  	if !sigCache.Exists(*msgNew, sigNewCopy, keyNewCopy) {
  91  		t.Fatalf("previously added item not found in signature cache")
  92  	}
  93  }
  94  
  95  // TestSigCacheAddMaxEntriesZeroOrNegative tests that if a sigCache is created with a max size <= 0, then no entries are
  96  // added to the sigcache at all.
  97  func TestSigCacheAddMaxEntriesZeroOrNegative(t *testing.T) {
  98  	// Create a sigcache that can hold up to 0 entries.
  99  	sigCache := NewSigCache(0)
 100  	// Generate a random sigCache entry triplet.
 101  	msg1, sig1, key1, e := genRandomSig()
 102  	if e != nil {
 103  		t.Fatalf("unable to generate random signature test data")
 104  	}
 105  	// Add the triplet to the signature cache.
 106  	sigCache.Add(*msg1, sig1, key1)
 107  	// The generated triplet should not be found.
 108  	sig1Copy, _ := ecc.ParseSignature(sig1.Serialize(), ecc.S256())
 109  	key1Copy, _ := ecc.ParsePubKey(key1.SerializeCompressed(), ecc.S256())
 110  	if sigCache.Exists(*msg1, sig1Copy, key1Copy) {
 111  		t.Errorf("previously added signature found in sigcache, but" +
 112  			"shouldn't have been",
 113  		)
 114  	}
 115  	// There shouldn't be any entries in the sigCache.
 116  	if len(sigCache.validSigs) != 0 {
 117  		t.Errorf("%v items found in sigcache, no items should have"+
 118  			"been added", len(sigCache.validSigs),
 119  		)
 120  	}
 121  }
 122