@@ -12,13 +12,13 @@ use crate::{
1212 plugins:: { NewBlockInfo , VaultInfo } ,
1313} ;
1414use revault_tx:: {
15- bitcoin:: { consensus:: encode, secp256k1, Amount , OutPoint } ,
15+ bitcoin:: { consensus:: encode, secp256k1, Amount , OutPoint , Transaction } ,
1616 scripts:: { DerivedCpfpDescriptor , DerivedDepositDescriptor , DerivedUnvaultDescriptor } ,
1717 transactions:: {
1818 CancelTransaction , RevaultPresignedTransaction , RevaultTransaction , UnvaultTransaction ,
1919 } ,
2020 txins:: { DepositTxIn , RevaultTxIn , UnvaultTxIn } ,
21- txouts:: { DepositTxOut , RevaultTxOut } ,
21+ txouts:: { DepositTxOut , RevaultTxOut , UnvaultTxOut } ,
2222} ;
2323
2424use revault_net:: noise:: SecretKey as NoisePrivkey ;
@@ -365,6 +365,8 @@ fn check_for_unvault(
365365) -> Result < Vec < VaultInfo > , PollerError > {
366366 let deleg_vaults = db_blank_vaults ( db_path) ?;
367367 let mut new_attempts = vec ! [ ] ;
368+ // Map of the spend transactions with their input previous_output outpoints as keys.
369+ let mut spend_cache = HashMap :: < OutPoint , Transaction > :: new ( ) ;
368370
369371 for mut db_vault in deleg_vaults {
370372 let ( deposit_desc, unvault_desc, cpfp_desc) = descriptors ( secp, config, & db_vault) ;
@@ -398,52 +400,65 @@ fn check_for_unvault(
398400 // If needed to be canceled it will be marked as such when plugins tell us so.
399401 db_updates. new_unvaulted . insert ( db_vault. id , db_vault) ;
400402
403+ let unvault_txin_outpoint = unvault_txin. outpoint ( ) ;
401404 let candidate_tx = if let Some ( client) = coordinator_client {
402- match client. get_spend_transaction ( db_vault. deposit_outpoint . clone ( ) ) {
403- Ok ( Some ( tx) ) => {
404- let spent_unvault_outpoint = unvault_txin. outpoint ( ) ;
405- if let Some ( i) = tx
406- . input
407- . iter ( )
408- . position ( |input| input. previous_output == spent_unvault_outpoint)
409- {
410- let txout = unvault_txin. txout ( ) . txout ( ) ;
411- if let Err ( e) = bitcoinconsensus:: verify (
412- & txout. script_pubkey . as_bytes ( ) ,
413- txout. value ,
414- & encode:: serialize ( & tx) ,
415- i,
416- ) {
417- log:: error!(
405+ if let Some ( tx) = spend_cache. get ( & unvault_txin_outpoint) {
406+ Some ( tx. clone ( ) )
407+ } else {
408+ match client. get_spend_transaction ( db_vault. deposit_outpoint . clone ( ) ) {
409+ Ok ( Some ( tx) ) => {
410+ if let Some ( i) = tx
411+ . input
412+ . iter ( )
413+ . position ( |input| input. previous_output == unvault_txin_outpoint)
414+ {
415+ let txout = unvault_txin. txout ( ) . txout ( ) ;
416+ if let Err ( e) = bitcoinconsensus:: verify (
417+ & txout. script_pubkey . as_bytes ( ) ,
418+ txout. value ,
419+ & encode:: serialize ( & tx) ,
420+ i,
421+ ) {
422+ log:: error!(
418423 "Coordinator sent a suspicious tx {}, libbitcoinconsensus error: {:?}" ,
419424 tx. txid( ) ,
420425 e
421426 ) ;
422- None
427+ None
428+ } else {
429+ Some ( tx)
430+ }
423431 } else {
424- Some ( tx)
425- }
426- } else {
427- log:: error!(
432+ log:: error!(
428433 "Coordinator sent a suspicious tx {}, the transaction does not spend the vault" ,
429434 tx. txid( ) ,
430435 ) ;
436+ None
437+ }
438+ }
439+ Ok ( None ) => None ,
440+ Err ( _e) => {
441+ // Because we do not trust the coordinator, we consider it refuses to deliver the
442+ // spend tx if a communication error happened.
431443 None
432444 }
433445 }
434- Ok ( None ) => None ,
435- Err ( _e) => {
436- // Because we do not trust the coordinator, we consider it refuses to deliver the
437- // spend tx if a communication error happened.
438- None
439- }
440446 }
441447 } else {
442448 // No coordinator configuration was found in the config
443449 // therefore no spend transaction can be shared to plugins
444450 None
445451 } ;
446452
453+ // Populate the spend cache
454+ if spend_cache. get ( & unvault_txin_outpoint) . is_none ( ) {
455+ if let Some ( tx) = candidate_tx. as_ref ( ) {
456+ for input in & tx. input {
457+ spend_cache. insert ( input. previous_output , tx. clone ( ) ) ;
458+ }
459+ }
460+ }
461+
447462 let vault_info = VaultInfo {
448463 value : db_vault. amount ,
449464 deposit_outpoint : db_vault. deposit_outpoint ,
0 commit comments