@@ -212,57 +212,63 @@ impl<Pk: MiniscriptKey> Tr<Pk> {
212
212
{
213
213
// If the value is already cache, read it
214
214
// read only panics if the lock is poisoned (meaning other thread having a lock panicked)
215
- if let Some ( spend_info) = & * self . spend_info . read ( ) . expect ( "Lock poisoned" ) {
216
- return Arc :: clone ( spend_info) ;
217
- } else {
218
- // Get a new secp context
219
- // This would be cheap operation after static context support from upstream
220
- let secp = secp256k1:: Secp256k1 :: verification_only ( ) ;
221
- // Key spend path with no merkle root
222
- let data = if self . tree . is_none ( ) {
223
- TaprootSpendInfo :: new_key_spend ( & secp, self . internal_key . to_x_only_pubkey ( ) , None )
224
- } else {
225
- let mut builder = TaprootBuilder :: new ( ) ;
226
- for ( depth, ms) in self . iter_scripts ( ) {
227
- let script = ms. encode ( ) ;
228
- builder = builder
229
- . add_leaf ( depth, script)
230
- . expect ( "Computing spend data on a valid Tree should always succeed" ) ;
231
- }
232
- // Assert builder cannot error here because we have a well formed descriptor
233
- match builder. finalize ( & secp, self . internal_key . to_x_only_pubkey ( ) ) {
234
- Ok ( data) => data,
235
- Err ( e) => match e {
236
- TaprootBuilderError :: InvalidMerkleTreeDepth ( _) => {
237
- unreachable ! ( "Depth checked in struct construction" )
238
- }
239
- TaprootBuilderError :: NodeNotInDfsOrder => {
240
- unreachable ! ( "Insertion is called in DFS order" )
241
- }
242
- TaprootBuilderError :: OverCompleteTree => {
243
- unreachable ! ( "Taptree is a well formed tree" )
244
- }
245
- TaprootBuilderError :: InvalidInternalKey ( _) => {
246
- unreachable ! ( "Internal key checked for validity" )
247
- }
248
- TaprootBuilderError :: IncompleteTree => {
249
- unreachable ! ( "Taptree is a well formed tree" )
250
- }
251
- TaprootBuilderError :: EmptyTree => {
252
- unreachable ! ( "Taptree is a well formed tree with atleast 1 element" )
253
- }
254
- } ,
255
- }
256
- } ;
257
- * self . spend_info . write ( ) . expect ( "Lock poisoned" ) = Some ( Arc :: new ( data) ) ;
258
- // Fetch the cached value
259
- Arc :: clone (
260
- self . spend_info
261
- . read ( )
262
- . expect ( "Lock poisoned" )
263
- . as_ref ( ) // deref from RwLockReadGuard to Option<TaprootSpendInfo>
264
- . expect ( "Value cached above, option must be some" ) ,
265
- )
215
+ let spend_info = self
216
+ . spend_info
217
+ . read ( )
218
+ . expect ( "Lock poisoned" )
219
+ . as_ref ( )
220
+ . map ( Arc :: clone) ;
221
+
222
+ match spend_info {
223
+ Some ( spend_info) => spend_info,
224
+ None => {
225
+ // Get a new secp context
226
+ // This would be cheap operation after static context support from upstream
227
+ let secp = secp256k1:: Secp256k1 :: verification_only ( ) ;
228
+ // Key spend path with no merkle root
229
+ let data = if self . tree . is_none ( ) {
230
+ TaprootSpendInfo :: new_key_spend (
231
+ & secp,
232
+ self . internal_key . to_x_only_pubkey ( ) ,
233
+ None ,
234
+ )
235
+ } else {
236
+ let mut builder = TaprootBuilder :: new ( ) ;
237
+ for ( depth, ms) in self . iter_scripts ( ) {
238
+ let script = ms. encode ( ) ;
239
+ builder = builder
240
+ . add_leaf ( depth, script)
241
+ . expect ( "Computing spend data on a valid Tree should always succeed" ) ;
242
+ }
243
+ // Assert builder cannot error here because we have a well formed descriptor
244
+ match builder. finalize ( & secp, self . internal_key . to_x_only_pubkey ( ) ) {
245
+ Ok ( data) => data,
246
+ Err ( e) => match e {
247
+ TaprootBuilderError :: InvalidMerkleTreeDepth ( _) => {
248
+ unreachable ! ( "Depth checked in struct construction" )
249
+ }
250
+ TaprootBuilderError :: NodeNotInDfsOrder => {
251
+ unreachable ! ( "Insertion is called in DFS order" )
252
+ }
253
+ TaprootBuilderError :: OverCompleteTree => {
254
+ unreachable ! ( "Taptree is a well formed tree" )
255
+ }
256
+ TaprootBuilderError :: InvalidInternalKey ( _) => {
257
+ unreachable ! ( "Internal key checked for validity" )
258
+ }
259
+ TaprootBuilderError :: IncompleteTree => {
260
+ unreachable ! ( "Taptree is a well formed tree" )
261
+ }
262
+ TaprootBuilderError :: EmptyTree => {
263
+ unreachable ! ( "Taptree is a well formed tree with atleast 1 element" )
264
+ }
265
+ } ,
266
+ }
267
+ } ;
268
+ let spend_info = Arc :: new ( data) ;
269
+ * self . spend_info . write ( ) . expect ( "Lock poisoned" ) = Some ( Arc :: clone ( & spend_info) ) ;
270
+ spend_info
271
+ }
266
272
}
267
273
}
268
274
}
0 commit comments