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