github.com/BlockABC/godash@v0.0.0-20191112120524-f4aa3a32c566/txscript/sigcache_test.go (about)

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