@@ -1428,7 +1428,6 @@ fn normalize_funding_psbt_locktime(
14281428// FundingGenerationReady. Returns the value to propagate from the event handler: `Err(ReplayEvent)`
14291429// to retry the event (for transient network errors), or `Ok(())` after force-closing the channel
14301430// (for terminal errors).
1431- #[ allow( dead_code) ]
14321431fn handle_funding_prepare_err (
14331432 e : RgbLibError ,
14341433 channel_manager : & ChannelManager ,
@@ -1556,7 +1555,6 @@ async fn handle_ldk_events(
15561555 false ,
15571556 ) ;
15581557 unlocked_state. virtual_channel_draft_delete ( & temporary_channel_id) ;
1559- * unlocked_state. rgb_send_lock . lock ( ) . unwrap ( ) = false ;
15601558 } ;
15611559
15621560 let mut virtual_funding_txo = virtual_channel_synthetic_outpoint (
@@ -1757,7 +1755,6 @@ async fn handle_ldk_events(
17571755 updated_at : get_current_timestamp ( ) ,
17581756 } ) ;
17591757 unlocked_state. virtual_channel_draft_delete ( & temporary_channel_id) ;
1760- * unlocked_state. rgb_send_lock . lock ( ) . unwrap ( ) = false ;
17611758 tracing:: info!(
17621759 "EVENT: registered trusted no-broadcast funding {} for virtual channel {}" ,
17631760 virtual_funding_txo,
@@ -1777,7 +1774,6 @@ async fn handle_ldk_events(
17771774 false ,
17781775 ) ;
17791776 unlocked_state. virtual_channel_draft_delete ( & temporary_channel_id) ;
1780- * unlocked_state. rgb_send_lock . lock ( ) . unwrap ( ) = false ;
17811777 }
17821778 }
17831779 return Ok ( ( ) ) ;
@@ -1814,39 +1810,40 @@ async fn handle_ldk_events(
18141810
18151811 let unlocked_state_copy = unlocked_state. clone ( ) ;
18161812 let res = tokio:: task:: spawn_blocking (
1817- move || -> Result < ( String , Option < i32 > ) , String > {
1818- let res = unlocked_state_copy
1819- . rgb_send_begin (
1820- recipient_map,
1821- true ,
1822- FEE_RATE ,
1823- MIN_CHANNEL_CONFIRMATIONS ,
1824- None ,
1825- false ,
1826- // Final locktime: this colored tx funds an LN channel.
1827- Some ( 0 ) ,
1828- )
1829- . map_err ( |e| e. to_string ( ) ) ?;
1830- let fascia_str = fs:: read_to_string ( & res. details . fascia_path )
1831- . map_err ( |e| e. to_string ( ) ) ?;
1832- let fascia: Fascia =
1833- serde_json:: from_str ( & fascia_str) . map_err ( |e| e. to_string ( ) ) ?;
1834- unlocked_state_copy
1835- . rgb_consume_fascia ( fascia, None )
1836- . map_err ( |e| e. to_string ( ) ) ?;
1837- unlocked_state_copy
1838- . rgb_create_consignments ( res. psbt . clone ( ) )
1839- . map_err ( |e| e. to_string ( ) ) ?;
1813+ move || -> Result < ( String , Option < i32 > ) , RgbLibError > {
1814+ let res = unlocked_state_copy. rgb_send_begin (
1815+ recipient_map,
1816+ true ,
1817+ FEE_RATE ,
1818+ MIN_CHANNEL_CONFIRMATIONS ,
1819+ None ,
1820+ false ,
1821+ // Final locktime: this colored tx funds an LN channel.
1822+ Some ( 0 ) ,
1823+ ) ?;
1824+ let fascia_str = fs:: read_to_string ( & res. details . fascia_path ) . unwrap ( ) ;
1825+ let fascia: Fascia = serde_json:: from_str ( & fascia_str) . unwrap ( ) ;
1826+ unlocked_state_copy. rgb_consume_fascia ( fascia, None ) ?;
1827+ unlocked_state_copy. rgb_create_consignments ( res. psbt . clone ( ) ) ?;
18401828 Ok ( ( res. psbt , res. batch_transfer_idx ) )
18411829 } ,
18421830 )
18431831 . await
18441832 . unwrap ( ) ;
18451833 let ( unsigned_psbt, batch_transfer_idx) = match res {
18461834 Ok ( result) => result,
1835+ // A failed funding preparation (e.g. the asset allocation is
1836+ // momentarily reserved by a concurrent open) must fail the
1837+ // channel so the caller can retry, not retry the event
1838+ // forever. handle_open_chan_fail (on ChannelClosed) then
1839+ // releases any reserved allocation.
18471840 Err ( e) => {
1848- tracing:: error!( "cannot prepare channel funding transfer: {e}" ) ;
1849- return Err ( ReplayEvent ( ) ) ;
1841+ return handle_funding_prepare_err (
1842+ e,
1843+ & unlocked_state. channel_manager ,
1844+ & temporary_channel_id,
1845+ & counterparty_node_id,
1846+ ) ;
18501847 }
18511848 } ;
18521849 // Record the batch transfer index on the channel's RGB info so a failed
@@ -1866,9 +1863,25 @@ async fn handle_ldk_events(
18661863 }
18671864 ( unsigned_psbt, Some ( asset_id) )
18681865 } else {
1869- let raw_psbt = unlocked_state
1870- . rgb_send_btc_begin ( addr. to_address ( ) , channel_value_satoshis, FEE_RATE )
1871- . unwrap ( ) ;
1866+ // Mirror the colored path: a failed funding preparation must fail
1867+ // the channel (so the caller can retry) rather than panic the event
1868+ // task. handle_funding_prepare_err force-closes on terminal errors
1869+ // and replays the event on transient network errors.
1870+ let raw_psbt = match unlocked_state. rgb_send_btc_begin (
1871+ addr. to_address ( ) ,
1872+ channel_value_satoshis,
1873+ FEE_RATE ,
1874+ ) {
1875+ Ok ( psbt) => psbt,
1876+ Err ( e) => {
1877+ return handle_funding_prepare_err (
1878+ e,
1879+ & unlocked_state. channel_manager ,
1880+ & temporary_channel_id,
1881+ & counterparty_node_id,
1882+ ) ;
1883+ }
1884+ } ;
18721885 let current_best_height =
18731886 unlocked_state. channel_manager . current_best_block ( ) . height ;
18741887 let unsigned_psbt =
@@ -1985,7 +1998,6 @@ async fn handle_ldk_events(
19851998 tracing:: error!(
19861999 "ERROR: Channel went away before we could fund it. The peer disconnected or refused the channel." ,
19872000 ) ;
1988- * unlocked_state. rgb_send_lock . lock ( ) . unwrap ( ) = false ;
19892001 }
19902002 }
19912003 Event :: FundingTxBroadcastSafe { .. } => {
@@ -2577,7 +2589,6 @@ async fn handle_ldk_events(
25772589 . virtual_channel_session_store ( )
25782590 . contains_key ( & channel_id)
25792591 {
2580- * unlocked_state. rgb_send_lock . lock ( ) . unwrap ( ) = false ;
25812592 tracing:: info!(
25822593 "EVENT: virtual channel {} is pending in trusted no-broadcast mode" ,
25832594 channel_id,
@@ -2611,8 +2622,6 @@ async fn handle_ldk_events(
26112622 } )
26122623 . await ;
26132624
2614- * unlocked_state. rgb_send_lock . lock ( ) . unwrap ( ) = false ;
2615-
26162625 let finalize_result = join_result. map_err ( |join_err| {
26172626 tracing:: error!( "Channel opening finalization task failed: {join_err:?}" ) ;
26182627 ReplayEvent ( )
@@ -2696,8 +2705,6 @@ async fn handle_ldk_events(
26962705 reason
26972706 ) ;
26982707
2699- * unlocked_state. rgb_send_lock . lock ( ) . unwrap ( ) = false ;
2700-
27012708 // Release any funds locked for a funding tx that was never broadcast.
27022709 handle_open_chan_fail ( & channel_id, unlocked_state. clone ( ) ) . await ;
27032710
@@ -2729,7 +2736,6 @@ async fn handle_ldk_events(
27292736 & format ! ( "virtual_channel_{}" , channel_id) ,
27302737 false ,
27312738 ) ;
2732- * unlocked_state. rgb_send_lock . lock ( ) . unwrap ( ) = false ;
27332739
27342740 tracing:: warn!(
27352741 "EVENT: cleaned up failed virtual open draft {} after channel close {}" ,
@@ -4706,7 +4712,6 @@ pub(crate) async fn start_ldk(
47064712 taker_swaps,
47074713 router : Arc :: clone ( & router) ,
47084714 output_sweeper : Arc :: clone ( & output_sweeper) ,
4709- rgb_send_lock : Arc :: new ( Mutex :: new ( false ) ) ,
47104715 channel_ids_map,
47114716 proxy_endpoint : proxy_endpoint. to_string ( ) ,
47124717 external_signer_mode,
0 commit comments