@@ -79,7 +79,7 @@ use crate::ln::LN_MAX_MSG_LEN;
7979use crate::offers::static_invoice::StaticInvoice;
8080use crate::rgb_utils::{
8181 color_closing, color_commitment, color_htlc, get_rgb_channel_info_path,
82- get_rgb_channel_info_pending, get_rgb_kv_store, parse_rgb_channel_info,
82+ get_rgb_channel_info_pending, parse_rgb_channel_info,
8383 read_rgb_channel_info_kv, rename_rgb_files, update_rgb_channel_amount_pending,
8484};
8585use crate::routing::gossip::NodeId;
@@ -104,6 +104,8 @@ use crate::prelude::*;
104104use crate::sign::type_resolver::ChannelSignerType;
105105#[cfg(any(test, fuzzing, debug_assertions))]
106106use crate::sync::Mutex;
107+ use crate::sync::Arc;
108+ use crate::util::persist::KVStoreSync;
107109use core::ops::Deref;
108110use core::time::Duration;
109111use core::{cmp, fmt, mem};
@@ -3132,6 +3134,9 @@ where
31323134 pub(super) consignment_endpoint: Option<RgbTransport>,
31333135
31343136 pub(crate) ldk_data_dir: PathBuf,
3137+
3138+ /// Optional KVStore for RGB data persistence
3139+ pub(crate) rgb_kv_store: Option<Arc<dyn KVStoreSync + Send + Sync>>,
31353140}
31363141
31373142/// A channel struct implementing this trait can receive an initial counterparty commitment
@@ -3232,7 +3237,7 @@ where
32323237 let temporary_channel_id = context.channel_id;
32333238 context.channel_id = channel_id;
32343239 if context.is_colored() {
3235- rename_rgb_files(&context.channel_id, &temporary_channel_id, &context.ldk_data_dir);
3240+ rename_rgb_files(&context.channel_id, &temporary_channel_id, &context.ldk_data_dir, context.rgb_kv_store.as_ref() );
32363241 }
32373242
32383243 assert!(!context.channel_state.is_monitor_update_in_progress()); // We have not had any monitor(s) yet to fail update!
@@ -3401,6 +3406,7 @@ where
34013406 msg_push_msat: u64,
34023407 open_channel_fields: msgs::CommonOpenChannelFields,
34033408 ldk_data_dir: PathBuf,
3409+ rgb_kv_store: Option<Arc<dyn KVStoreSync + Send + Sync>>,
34043410 ) -> Result<(FundingScope, ChannelContext<SP>), ChannelError>
34053411 where
34063412 ES::Target: EntropySource,
@@ -3723,6 +3729,7 @@ where
37233729
37243730 consignment_endpoint: open_channel_fields.consignment_endpoint,
37253731 ldk_data_dir,
3732+ rgb_kv_store,
37263733 };
37273734
37283735 Ok((funding, channel_context))
@@ -3748,6 +3755,7 @@ where
37483755 _logger: L,
37493756 consignment_endpoint: Option<RgbTransport>,
37503757 ldk_data_dir: PathBuf,
3758+ rgb_kv_store: Option<Arc<dyn KVStoreSync + Send + Sync>>,
37513759 ) -> Result<(FundingScope, ChannelContext<SP>), APIError>
37523760 where
37533761 ES::Target: EntropySource,
@@ -3966,6 +3974,7 @@ where
39663974
39673975 consignment_endpoint,
39683976 ldk_data_dir,
3977+ rgb_kv_store,
39693978 };
39703979
39713980 Ok((funding, channel_context))
@@ -4345,8 +4354,8 @@ where
43454354 /// Get the channel local RGB amount
43464355 pub fn get_local_rgb_amount(&self) -> u64 {
43474356 let channel_id_str = self.channel_id.0.as_hex().to_string();
4348- // Try KVStore first
4349- if let Some(kv_store) = get_rgb_kv_store(& self.ldk_data_dir) {
4357+ // Try KVStore first (using injected store)
4358+ if let Some(ref kv_store) = self.rgb_kv_store {
43504359 if let Ok(rgb_info) = read_rgb_channel_info_kv(kv_store.as_ref(), &channel_id_str, false) {
43514360 return rgb_info.local_rgb_amount;
43524361 }
@@ -4364,8 +4373,8 @@ where
43644373 /// Get the channel remote RGB amount
43654374 pub fn get_remote_rgb_amount(&self) -> u64 {
43664375 let channel_id_str = self.channel_id.0.as_hex().to_string();
4367- // Try KVStore first
4368- if let Some(kv_store) = get_rgb_kv_store(& self.ldk_data_dir) {
4376+ // Try KVStore first (using injected store)
4377+ if let Some(ref kv_store) = self.rgb_kv_store {
43694378 if let Ok(rgb_info) = read_rgb_channel_info_kv(kv_store.as_ref(), &channel_id_str, false) {
43704379 return rgb_info.remote_rgb_amount;
43714380 }
@@ -5088,7 +5097,7 @@ where
50885097 &holder_keys.revocation_key,
50895098 );
50905099 if self.is_colored() {
5091- color_htlc(&mut htlc_tx, htlc, &self.ldk_data_dir)
5100+ color_htlc(&mut htlc_tx, htlc, &self.ldk_data_dir, self.rgb_kv_store.as_ref() )
50925101 .expect("successful htlc coloring");
50935102 }
50945103
@@ -7332,6 +7341,7 @@ where
73327341 &self.context.channel_id,
73337342 &mut closing_transaction,
73347343 &self.context.ldk_data_dir,
7344+ self.context.rgb_kv_store.as_ref(),
73357345 )
73367346 .expect("successful closing TX coloring");
73377347 }
@@ -8923,6 +8933,7 @@ where
89238933 rgb_offered_htlc,
89248934 rgb_received_htlc,
89258935 &self.context.ldk_data_dir,
8936+ self.context.rgb_kv_store.as_ref(),
89268937 );
89278938 }
89288939
@@ -11737,7 +11748,7 @@ where
1173711748 let were_node_one = node_id.as_slice() < counterparty_node_id.as_slice();
1173811749
1173911750 let contract_id = if self.context.is_colored() {
11740- let (rgb_info, _) = get_rgb_channel_info_pending(&self.context.channel_id, &self.context.ldk_data_dir);
11751+ let (rgb_info, _) = get_rgb_channel_info_pending(&self.context.channel_id, &self.context.ldk_data_dir, self.context.rgb_kv_store.as_ref() );
1174111752 Some(rgb_info.contract_id)
1174211753 } else {
1174311754 None
@@ -12891,7 +12902,7 @@ where
1289112902 }
1289212903 }
1289312904 if self.context.is_colored() && rgb_received_htlc > 0 {
12894- update_rgb_channel_amount_pending(&self.context.channel_id, 0, rgb_received_htlc, &self.context.ldk_data_dir);
12905+ update_rgb_channel_amount_pending(&self.context.channel_id, 0, rgb_received_htlc, &self.context.ldk_data_dir, self.context.rgb_kv_store.as_ref() );
1289512906 }
1289612907 if let Some((feerate, update_state)) = self.context.pending_update_fee {
1289712908 if update_state == FeeUpdateState::AwaitingRemoteRevokeToAnnounce {
@@ -13558,6 +13569,7 @@ where
1355813569 fee_estimator: &LowerBoundedFeeEstimator<F>, entropy_source: &ES, signer_provider: &SP, counterparty_node_id: PublicKey, their_features: &InitFeatures,
1355913570 channel_value_satoshis: u64, push_msat: u64, user_id: u128, config: &UserConfig, current_chain_height: u32,
1356013571 outbound_scid_alias: u64, temporary_channel_id: Option<ChannelId>, logger: L, consignment_endpoint: Option<RgbTransport>, ldk_data_dir: PathBuf,
13572+ rgb_kv_store: Option<Arc<dyn KVStoreSync + Send + Sync>>,
1356113573 ) -> Result<OutboundV1Channel<SP>, APIError>
1356213574 where ES::Target: EntropySource,
1356313575 F::Target: FeeEstimator,
@@ -13597,6 +13609,7 @@ where
1359713609 logger,
1359813610 consignment_endpoint,
1359913611 ldk_data_dir,
13612+ rgb_kv_store,
1360013613 )?;
1360113614 let unfunded_context = UnfundedChannelContext {
1360213615 unfunded_channel_age_ticks: 0,
@@ -13680,7 +13693,7 @@ where
1368013693 let temporary_channel_id = self.context.channel_id;
1368113694 self.context.channel_id = ChannelId::v1_from_funding_outpoint(funding_txo);
1368213695 if self.context.is_colored() {
13683- rename_rgb_files(&self.context.channel_id, &temporary_channel_id, &self.context.ldk_data_dir);
13696+ rename_rgb_files(&self.context.channel_id, &temporary_channel_id, &self.context.ldk_data_dir, self.context.rgb_kv_store.as_ref() );
1368413697 }
1368513698
1368613699 // If the funding transaction is a coinbase transaction, we need to set the minimum depth to 100.
@@ -13933,7 +13946,8 @@ where
1393313946 fee_estimator: &LowerBoundedFeeEstimator<F>, entropy_source: &ES, signer_provider: &SP,
1393413947 counterparty_node_id: PublicKey, our_supported_features: &ChannelTypeFeatures,
1393513948 their_features: &InitFeatures, msg: &msgs::OpenChannel, user_id: u128, config: &UserConfig,
13936- current_chain_height: u32, logger: &L, is_0conf: bool, ldk_data_dir: PathBuf
13949+ current_chain_height: u32, logger: &L, is_0conf: bool, ldk_data_dir: PathBuf,
13950+ rgb_kv_store: Option<Arc<dyn KVStoreSync + Send + Sync>>,
1393713951 ) -> Result<InboundV1Channel<SP>, ChannelError>
1393813952 where ES::Target: EntropySource,
1393913953 F::Target: FeeEstimator,
@@ -13974,6 +13988,7 @@ where
1397413988 msg.push_msat,
1397513989 msg.common_fields.clone(),
1397613990 ldk_data_dir,
13991+ rgb_kv_store,
1397713992 )?;
1397813993 let unfunded_context = UnfundedChannelContext {
1397913994 unfunded_channel_age_ticks: 0,
@@ -14174,7 +14189,7 @@ where
1417414189 counterparty_node_id: PublicKey, their_features: &InitFeatures, funding_satoshis: u64,
1417514190 funding_inputs: Vec<FundingTxInput>, user_id: u128, config: &UserConfig,
1417614191 current_chain_height: u32, outbound_scid_alias: u64, funding_confirmation_target: ConfirmationTarget,
14177- logger: L, ldk_data_dir: PathBuf,
14192+ logger: L, ldk_data_dir: PathBuf, rgb_kv_store: Option<Arc<dyn KVStoreSync + Send + Sync>>,
1417814193 ) -> Result<Self, APIError>
1417914194 where ES::Target: EntropySource,
1418014195 F::Target: FeeEstimator,
@@ -14217,6 +14232,7 @@ where
1421714232 // ok to pass consignment_endpoint as None since this method is unused
1421814233 None,
1421914234 ldk_data_dir,
14235+ rgb_kv_store,
1422014236 )?;
1422114237 let unfunded_context = UnfundedChannelContext {
1422214238 unfunded_channel_age_ticks: 0,
@@ -14327,7 +14343,7 @@ where
1432714343 holder_node_id: PublicKey, counterparty_node_id: PublicKey, our_supported_features: &ChannelTypeFeatures,
1432814344 their_features: &InitFeatures, msg: &msgs::OpenChannelV2,
1432914345 user_id: u128, config: &UserConfig, current_chain_height: u32, logger: &L,
14330- ldk_data_dir: PathBuf,
14346+ ldk_data_dir: PathBuf, rgb_kv_store: Option<Arc<dyn KVStoreSync + Send + Sync>>,
1433114347 ) -> Result<Self, ChannelError>
1433214348 where ES::Target: EntropySource,
1433314349 F::Target: FeeEstimator,
@@ -14373,6 +14389,7 @@ where
1437314389 0 /* push_msat not used in dual-funding */,
1437414390 msg.common_fields.clone(),
1437514391 ldk_data_dir,
14392+ rgb_kv_store,
1437614393 )?;
1437714394 let channel_id = ChannelId::v2_from_revocation_basepoints(
1437814395 &funding.get_holder_pubkeys().revocation_basepoint,
@@ -15062,16 +15079,16 @@ where
1506215079 }
1506315080}
1506415081
15065- impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c ChannelTypeFeatures, PathBuf)>
15082+ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c ChannelTypeFeatures, PathBuf, Option<Arc<dyn KVStoreSync + Send + Sync>> )>
1506615083 for FundedChannel<SP>
1506715084where
1506815085 ES::Target: EntropySource,
1506915086 SP::Target: SignerProvider,
1507015087{
1507115088 fn read<R: io::Read>(
15072- reader: &mut R, args: (&'a ES, &'b SP, &'c ChannelTypeFeatures, PathBuf),
15089+ reader: &mut R, args: (&'a ES, &'b SP, &'c ChannelTypeFeatures, PathBuf, Option<Arc<dyn KVStoreSync + Send + Sync>> ),
1507315090 ) -> Result<Self, DecodeError> {
15074- let (entropy_source, signer_provider, our_supported_features, ldk_data_dir) = args;
15091+ let (entropy_source, signer_provider, our_supported_features, ldk_data_dir, rgb_kv_store ) = args;
1507515092 let ver = read_ver_prefix!(reader, SERIALIZATION_VERSION);
1507615093 if ver <= 2 {
1507715094 return Err(DecodeError::UnknownVersion);
@@ -15867,6 +15884,7 @@ where
1586715884
1586815885 consignment_endpoint,
1586915886 ldk_data_dir,
15887+ rgb_kv_store,
1587015888 },
1587115889 holder_commitment_point,
1587215890 pending_splice,
@@ -16778,7 +16796,9 @@ mod tests {
1677816796 // These aren't set in the test vectors:
1677916797 [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff],
1678016798 [0; 32],
16799+ std::path::PathBuf::new(),
1678116800 [0; 32],
16801+ None,
1678216802 );
1678316803
1678416804 let holder_pubkeys = signer.pubkeys(&secp_ctx);
0 commit comments