github.com/decred/dcrlnd@v0.7.6/channeldb/witness_cache_test.go (about) 1 package channeldb 2 3 import ( 4 "crypto/sha256" 5 "testing" 6 7 "github.com/decred/dcrlnd/lntypes" 8 ) 9 10 // TestWitnessCacheSha256Retrieval tests that we're able to add and lookup new 11 // sha256 preimages to the witness cache. 12 func TestWitnessCacheSha256Retrieval(t *testing.T) { 13 t.Parallel() 14 15 cdb, cleanUp, err := MakeTestDB() 16 if err != nil { 17 t.Fatalf("unable to make test database: %v", err) 18 } 19 defer cleanUp() 20 21 wCache := cdb.NewWitnessCache() 22 23 // We'll be attempting to add then lookup two simple sha256 preimages 24 // within this test. 25 preimage1 := lntypes.Preimage(rev) 26 preimage2 := lntypes.Preimage(key) 27 28 preimages := []lntypes.Preimage{preimage1, preimage2} 29 hashes := []lntypes.Hash{preimage1.Hash(), preimage2.Hash()} 30 31 // First, we'll attempt to add the preimages to the database. 32 err = wCache.AddSha256Witnesses(preimages...) 33 if err != nil { 34 t.Fatalf("unable to add witness: %v", err) 35 } 36 37 // With the preimages stored, we'll now attempt to look them up. 38 for i, hash := range hashes { 39 preimage := preimages[i] 40 41 // We should get back the *exact* same preimage as we originally 42 // stored. 43 dbPreimage, err := wCache.LookupSha256Witness(hash) 44 if err != nil { 45 t.Fatalf("unable to look up witness: %v", err) 46 } 47 48 if preimage != dbPreimage { 49 t.Fatalf("witnesses don't match: expected %x, got %x", 50 preimage[:], dbPreimage[:]) 51 } 52 } 53 } 54 55 // TestWitnessCacheSha256Deletion tests that we're able to delete a single 56 // sha256 preimage, and also a class of witnesses from the cache. 57 func TestWitnessCacheSha256Deletion(t *testing.T) { 58 t.Parallel() 59 60 cdb, cleanUp, err := MakeTestDB() 61 if err != nil { 62 t.Fatalf("unable to make test database: %v", err) 63 } 64 defer cleanUp() 65 66 wCache := cdb.NewWitnessCache() 67 68 // We'll start by adding two preimages to the cache. 69 preimage1 := lntypes.Preimage(key) 70 hash1 := preimage1.Hash() 71 72 preimage2 := lntypes.Preimage(rev) 73 hash2 := preimage2.Hash() 74 75 if err := wCache.AddSha256Witnesses(preimage1); err != nil { 76 t.Fatalf("unable to add witness: %v", err) 77 } 78 79 if err := wCache.AddSha256Witnesses(preimage2); err != nil { 80 t.Fatalf("unable to add witness: %v", err) 81 } 82 83 // We'll now delete the first preimage. If we attempt to look it up, we 84 // should get ErrNoWitnesses. 85 err = wCache.DeleteSha256Witness(hash1) 86 if err != nil { 87 t.Fatalf("unable to delete witness: %v", err) 88 } 89 _, err = wCache.LookupSha256Witness(hash1) 90 if err != ErrNoWitnesses { 91 t.Fatalf("expected ErrNoWitnesses instead got: %v", err) 92 } 93 94 // Next, we'll attempt to delete the entire witness class itself. When 95 // we try to lookup the second preimage, we should again get 96 // ErrNoWitnesses. 97 if err := wCache.DeleteWitnessClass(Sha256HashWitness); err != nil { 98 t.Fatalf("unable to delete witness class: %v", err) 99 } 100 _, err = wCache.LookupSha256Witness(hash2) 101 if err != ErrNoWitnesses { 102 t.Fatalf("expected ErrNoWitnesses instead got: %v", err) 103 } 104 } 105 106 // TestWitnessCacheUnknownWitness tests that we get an error if we attempt to 107 // query/add/delete an unknown witness. 108 func TestWitnessCacheUnknownWitness(t *testing.T) { 109 t.Parallel() 110 111 cdb, cleanUp, err := MakeTestDB() 112 if err != nil { 113 t.Fatalf("unable to make test database: %v", err) 114 } 115 defer cleanUp() 116 117 wCache := cdb.NewWitnessCache() 118 119 // We'll attempt to add a new, undefined witness type to the database. 120 // We should get an error. 121 err = wCache.legacyAddWitnesses(234, key[:]) 122 if err != ErrUnknownWitnessType { 123 t.Fatalf("expected ErrUnknownWitnessType, got %v", err) 124 } 125 } 126 127 // TestAddSha256Witnesses tests that insertion using AddSha256Witnesses behaves 128 // identically to the insertion via the generalized interface. 129 func TestAddSha256Witnesses(t *testing.T) { 130 cdb, cleanUp, err := MakeTestDB() 131 if err != nil { 132 t.Fatalf("unable to make test database: %v", err) 133 } 134 defer cleanUp() 135 136 wCache := cdb.NewWitnessCache() 137 138 // We'll start by adding a witnesses to the cache using the generic 139 // AddWitnesses method. 140 witness1 := rev[:] 141 preimage1 := lntypes.Preimage(rev) 142 hash1 := preimage1.Hash() 143 144 witness2 := key[:] 145 preimage2 := lntypes.Preimage(key) 146 hash2 := preimage2.Hash() 147 148 var ( 149 witnesses = [][]byte{witness1, witness2} 150 preimages = []lntypes.Preimage{preimage1, preimage2} 151 hashes = []lntypes.Hash{hash1, hash2} 152 ) 153 154 err = wCache.legacyAddWitnesses(Sha256HashWitness, witnesses...) 155 if err != nil { 156 t.Fatalf("unable to add witness: %v", err) 157 } 158 159 for i, hash := range hashes { 160 preimage := preimages[i] 161 162 dbPreimage, err := wCache.LookupSha256Witness(hash) 163 if err != nil { 164 t.Fatalf("unable to lookup witness: %v", err) 165 } 166 167 // Assert that the retrieved witness matches the original. 168 if dbPreimage != preimage { 169 t.Fatalf("retrieved witness mismatch, want: %x, "+ 170 "got: %x", preimage, dbPreimage) 171 } 172 173 // We'll now delete the witness, as we'll be reinserting it 174 // using the specialized AddSha256Witnesses method. 175 err = wCache.DeleteSha256Witness(hash) 176 if err != nil { 177 t.Fatalf("unable to delete witness: %v", err) 178 } 179 } 180 181 // Now, add the same witnesses using the type-safe interface for 182 // lntypes.Preimages.. 183 err = wCache.AddSha256Witnesses(preimages...) 184 if err != nil { 185 t.Fatalf("unable to add chainhash preimage: %v", err) 186 } 187 188 // Finally, iterate over the keys and assert that the returned witnesses 189 // match the original witnesses. This asserts that the specialized 190 // insertion method behaves identically to the generalized interface. 191 for i, hash := range hashes { 192 preimage := preimages[i] 193 194 dbPreimage, err := wCache.LookupSha256Witness(hash) 195 if err != nil { 196 t.Fatalf("unable to lookup witness: %v", err) 197 } 198 199 // Assert that the retrieved witness matches the original. 200 if dbPreimage != preimage { 201 t.Fatalf("retrieved witness mismatch, want: %x, "+ 202 "got: %x", preimage, dbPreimage) 203 } 204 } 205 } 206 207 // legacyAddWitnesses adds a batch of new witnesses of wType to the witness 208 // cache. The type of the witness will be used to map each witness to the key 209 // that will be used to look it up. All witnesses should be of the same 210 // WitnessType. 211 // 212 // NOTE: Previously this method exposed a generic interface for adding 213 // witnesses, which has since been deprecated in favor of a strongly typed 214 // interface for each witness class. We keep this method around to assert the 215 // correctness of specialized witness adding methods. 216 func (w *WitnessCache) legacyAddWitnesses(wType WitnessType, 217 witnesses ...[]byte) error { 218 219 // Optimistically compute the witness keys before attempting to start 220 // the db transaction. 221 entries := make([]witnessEntry, 0, len(witnesses)) 222 for _, witness := range witnesses { 223 // Map each witness to its key by applying the appropriate 224 // transformation for the given witness type. 225 switch wType { 226 case Sha256HashWitness: 227 key := sha256.Sum256(witness) 228 entries = append(entries, witnessEntry{ 229 key: key[:], 230 witness: witness, 231 }) 232 default: 233 return ErrUnknownWitnessType 234 } 235 } 236 237 return w.addWitnessEntries(wType, entries) 238 }