@@ -78,9 +78,8 @@ use crate::ln::types::ChannelId;
7878use crate::ln::LN_MAX_MSG_LEN;
7979use crate::offers::static_invoice::StaticInvoice;
8080use crate::rgb_utils::{
81- color_closing, color_commitment, color_htlc, get_rgb_channel_info_path,
82- get_rgb_channel_info_pending, parse_rgb_channel_info, rename_rgb_files,
83- update_rgb_channel_amount_pending,
81+ color_closing, color_commitment, color_htlc, get_rgb_channel_info_pending,
82+ read_rgb_channel_info, rename_rgb_files, update_rgb_channel_amount_pending,
8483};
8584use crate::routing::gossip::NodeId;
8685use crate::sign::ecdsa::EcdsaChannelSigner;
@@ -104,6 +103,8 @@ use crate::prelude::*;
104103use crate::sign::type_resolver::ChannelSignerType;
105104#[cfg(any(test, fuzzing, debug_assertions))]
106105use crate::sync::Mutex;
106+ use crate::sync::Arc;
107+ use crate::util::persist::KVStoreSync;
107108use core::ops::Deref;
108109use core::time::Duration;
109110use core::{cmp, fmt, mem};
@@ -3132,6 +3133,9 @@ where
31323133 pub(super) consignment_endpoint: Option<RgbTransport>,
31333134
31343135 pub(crate) ldk_data_dir: PathBuf,
3136+
3137+ /// Optional KVStore for RGB data persistence
3138+ pub(crate) rgb_kv_store: Arc<dyn KVStoreSync + Send + Sync>,
31353139}
31363140
31373141/// A channel struct implementing this trait can receive an initial counterparty commitment
@@ -3232,7 +3236,7 @@ where
32323236 let temporary_channel_id = context.channel_id;
32333237 context.channel_id = channel_id;
32343238 if context.is_colored() {
3235- rename_rgb_files(&context.channel_id, &temporary_channel_id, & context.ldk_data_dir );
3239+ rename_rgb_files(&context.channel_id, &temporary_channel_id, context.rgb_kv_store.as_ref() );
32363240 }
32373241
32383242 assert!(!context.channel_state.is_monitor_update_in_progress()); // We have not had any monitor(s) yet to fail update!
@@ -3401,6 +3405,7 @@ where
34013405 msg_push_msat: u64,
34023406 open_channel_fields: msgs::CommonOpenChannelFields,
34033407 ldk_data_dir: PathBuf,
3408+ rgb_kv_store: Arc<dyn KVStoreSync + Send + Sync>,
34043409 ) -> Result<(FundingScope, ChannelContext<SP>), ChannelError>
34053410 where
34063411 ES::Target: EntropySource,
@@ -3723,6 +3728,7 @@ where
37233728
37243729 consignment_endpoint: open_channel_fields.consignment_endpoint,
37253730 ldk_data_dir,
3731+ rgb_kv_store,
37263732 };
37273733
37283734 Ok((funding, channel_context))
@@ -3748,6 +3754,7 @@ where
37483754 _logger: L,
37493755 consignment_endpoint: Option<RgbTransport>,
37503756 ldk_data_dir: PathBuf,
3757+ rgb_kv_store: Arc<dyn KVStoreSync + Send + Sync>,
37513758 ) -> Result<(FundingScope, ChannelContext<SP>), APIError>
37523759 where
37533760 ES::Target: EntropySource,
@@ -3966,6 +3973,7 @@ where
39663973
39673974 consignment_endpoint,
39683975 ldk_data_dir,
3976+ rgb_kv_store,
39693977 };
39703978
39713979 Ok((funding, channel_context))
@@ -4344,13 +4352,8 @@ where
43444352
43454353 /// Get the channel local RGB amount
43464354 pub fn get_local_rgb_amount(&self) -> u64 {
4347- let info_file_path = get_rgb_channel_info_path(
4348- &self.channel_id.0.as_hex().to_string(),
4349- &self.ldk_data_dir,
4350- false,
4351- );
4352- if info_file_path.exists() {
4353- let rgb_info = parse_rgb_channel_info(&info_file_path);
4355+ let channel_id_str = self.channel_id.0.as_hex().to_string();
4356+ if let Ok(rgb_info) = read_rgb_channel_info(self.rgb_kv_store.as_ref(), &channel_id_str, false) {
43544357 rgb_info.local_rgb_amount
43554358 } else {
43564359 0
@@ -4359,13 +4362,8 @@ where
43594362
43604363 /// Get the channel remote RGB amount
43614364 pub fn get_remote_rgb_amount(&self) -> u64 {
4362- let info_file_path = get_rgb_channel_info_path(
4363- &self.channel_id.0.as_hex().to_string(),
4364- &self.ldk_data_dir,
4365- false,
4366- );
4367- if info_file_path.exists() {
4368- let rgb_info = parse_rgb_channel_info(&info_file_path);
4365+ let channel_id_str = self.channel_id.0.as_hex().to_string();
4366+ if let Ok(rgb_info) = read_rgb_channel_info(self.rgb_kv_store.as_ref(), &channel_id_str, false) {
43694367 rgb_info.remote_rgb_amount
43704368 } else {
43714369 0
@@ -5080,7 +5078,7 @@ where
50805078 &holder_keys.revocation_key,
50815079 );
50825080 if self.is_colored() {
5083- color_htlc(&mut htlc_tx, htlc, &self.ldk_data_dir)
5081+ color_htlc(&mut htlc_tx, htlc, &self.ldk_data_dir, self.rgb_kv_store.as_ref() )
50845082 .expect("successful htlc coloring");
50855083 }
50865084
@@ -7324,6 +7322,7 @@ where
73247322 &self.context.channel_id,
73257323 &mut closing_transaction,
73267324 &self.context.ldk_data_dir,
7325+ self.context.rgb_kv_store.as_ref(),
73277326 )
73287327 .expect("successful closing TX coloring");
73297328 }
@@ -8914,7 +8913,7 @@ where
89148913 &self.context.channel_id,
89158914 rgb_offered_htlc,
89168915 rgb_received_htlc,
8917- & self.context.ldk_data_dir ,
8916+ self.context.rgb_kv_store.as_ref() ,
89188917 );
89198918 }
89208919
@@ -11729,7 +11728,7 @@ where
1172911728 let were_node_one = node_id.as_slice() < counterparty_node_id.as_slice();
1173011729
1173111730 let contract_id = if self.context.is_colored() {
11732- let ( rgb_info, _) = get_rgb_channel_info_pending(&self.context.channel_id, & self.context.ldk_data_dir );
11731+ let rgb_info = get_rgb_channel_info_pending(&self.context.channel_id, self.context.rgb_kv_store.as_ref() );
1173311732 Some(rgb_info.contract_id)
1173411733 } else {
1173511734 None
@@ -12883,7 +12882,7 @@ where
1288312882 }
1288412883 }
1288512884 if self.context.is_colored() && rgb_received_htlc > 0 {
12886- update_rgb_channel_amount_pending(&self.context.channel_id, 0, rgb_received_htlc, & self.context.ldk_data_dir );
12885+ update_rgb_channel_amount_pending(&self.context.channel_id, 0, rgb_received_htlc, self.context.rgb_kv_store.as_ref() );
1288712886 }
1288812887 if let Some((feerate, update_state)) = self.context.pending_update_fee {
1288912888 if update_state == FeeUpdateState::AwaitingRemoteRevokeToAnnounce {
@@ -13550,6 +13549,7 @@ where
1355013549 fee_estimator: &LowerBoundedFeeEstimator<F>, entropy_source: &ES, signer_provider: &SP, counterparty_node_id: PublicKey, their_features: &InitFeatures,
1355113550 channel_value_satoshis: u64, push_msat: u64, user_id: u128, config: &UserConfig, current_chain_height: u32,
1355213551 outbound_scid_alias: u64, temporary_channel_id: Option<ChannelId>, logger: L, consignment_endpoint: Option<RgbTransport>, ldk_data_dir: PathBuf,
13552+ rgb_kv_store: Arc<dyn KVStoreSync + Send + Sync>,
1355313553 ) -> Result<OutboundV1Channel<SP>, APIError>
1355413554 where ES::Target: EntropySource,
1355513555 F::Target: FeeEstimator,
@@ -13589,6 +13589,7 @@ where
1358913589 logger,
1359013590 consignment_endpoint,
1359113591 ldk_data_dir,
13592+ rgb_kv_store,
1359213593 )?;
1359313594 let unfunded_context = UnfundedChannelContext {
1359413595 unfunded_channel_age_ticks: 0,
@@ -13672,7 +13673,7 @@ where
1367213673 let temporary_channel_id = self.context.channel_id;
1367313674 self.context.channel_id = ChannelId::v1_from_funding_outpoint(funding_txo);
1367413675 if self.context.is_colored() {
13675- rename_rgb_files(&self.context.channel_id, &temporary_channel_id, & self.context.ldk_data_dir );
13676+ rename_rgb_files(&self.context.channel_id, &temporary_channel_id, self.context.rgb_kv_store.as_ref() );
1367613677 }
1367713678
1367813679 // If the funding transaction is a coinbase transaction, we need to set the minimum depth to 100.
@@ -13925,7 +13926,8 @@ where
1392513926 fee_estimator: &LowerBoundedFeeEstimator<F>, entropy_source: &ES, signer_provider: &SP,
1392613927 counterparty_node_id: PublicKey, our_supported_features: &ChannelTypeFeatures,
1392713928 their_features: &InitFeatures, msg: &msgs::OpenChannel, user_id: u128, config: &UserConfig,
13928- current_chain_height: u32, logger: &L, is_0conf: bool, ldk_data_dir: PathBuf
13929+ current_chain_height: u32, logger: &L, is_0conf: bool, ldk_data_dir: PathBuf,
13930+ rgb_kv_store: Arc<dyn KVStoreSync + Send + Sync>,
1392913931 ) -> Result<InboundV1Channel<SP>, ChannelError>
1393013932 where ES::Target: EntropySource,
1393113933 F::Target: FeeEstimator,
@@ -13966,6 +13968,7 @@ where
1396613968 msg.push_msat,
1396713969 msg.common_fields.clone(),
1396813970 ldk_data_dir,
13971+ rgb_kv_store,
1396913972 )?;
1397013973 let unfunded_context = UnfundedChannelContext {
1397113974 unfunded_channel_age_ticks: 0,
@@ -14166,7 +14169,7 @@ where
1416614169 counterparty_node_id: PublicKey, their_features: &InitFeatures, funding_satoshis: u64,
1416714170 funding_inputs: Vec<FundingTxInput>, user_id: u128, config: &UserConfig,
1416814171 current_chain_height: u32, outbound_scid_alias: u64, funding_confirmation_target: ConfirmationTarget,
14169- logger: L, ldk_data_dir: PathBuf,
14172+ logger: L, ldk_data_dir: PathBuf, rgb_kv_store: Arc<dyn KVStoreSync + Send + Sync>,
1417014173 ) -> Result<Self, APIError>
1417114174 where ES::Target: EntropySource,
1417214175 F::Target: FeeEstimator,
@@ -14209,6 +14212,7 @@ where
1420914212 // ok to pass consignment_endpoint as None since this method is unused
1421014213 None,
1421114214 ldk_data_dir,
14215+ rgb_kv_store,
1421214216 )?;
1421314217 let unfunded_context = UnfundedChannelContext {
1421414218 unfunded_channel_age_ticks: 0,
@@ -14319,7 +14323,7 @@ where
1431914323 holder_node_id: PublicKey, counterparty_node_id: PublicKey, our_supported_features: &ChannelTypeFeatures,
1432014324 their_features: &InitFeatures, msg: &msgs::OpenChannelV2,
1432114325 user_id: u128, config: &UserConfig, current_chain_height: u32, logger: &L,
14322- ldk_data_dir: PathBuf,
14326+ ldk_data_dir: PathBuf, rgb_kv_store: Arc<dyn KVStoreSync + Send + Sync>,
1432314327 ) -> Result<Self, ChannelError>
1432414328 where ES::Target: EntropySource,
1432514329 F::Target: FeeEstimator,
@@ -14365,6 +14369,7 @@ where
1436514369 0 /* push_msat not used in dual-funding */,
1436614370 msg.common_fields.clone(),
1436714371 ldk_data_dir,
14372+ rgb_kv_store,
1436814373 )?;
1436914374 let channel_id = ChannelId::v2_from_revocation_basepoints(
1437014375 &funding.get_holder_pubkeys().revocation_basepoint,
@@ -15054,16 +15059,16 @@ where
1505415059 }
1505515060}
1505615061
15057- impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c ChannelTypeFeatures, PathBuf)>
15062+ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c ChannelTypeFeatures, PathBuf, Arc<dyn KVStoreSync + Send + Sync> )>
1505815063 for FundedChannel<SP>
1505915064where
1506015065 ES::Target: EntropySource,
1506115066 SP::Target: SignerProvider,
1506215067{
1506315068 fn read<R: io::Read>(
15064- reader: &mut R, args: (&'a ES, &'b SP, &'c ChannelTypeFeatures, PathBuf),
15069+ reader: &mut R, args: (&'a ES, &'b SP, &'c ChannelTypeFeatures, PathBuf, Arc<dyn KVStoreSync + Send + Sync> ),
1506515070 ) -> Result<Self, DecodeError> {
15066- let (entropy_source, signer_provider, our_supported_features, ldk_data_dir) = args;
15071+ let (entropy_source, signer_provider, our_supported_features, ldk_data_dir, rgb_kv_store ) = args;
1506715072 let ver = read_ver_prefix!(reader, SERIALIZATION_VERSION);
1506815073 if ver <= 2 {
1506915074 return Err(DecodeError::UnknownVersion);
@@ -15859,6 +15864,7 @@ where
1585915864
1586015865 consignment_endpoint,
1586115866 ldk_data_dir,
15867+ rgb_kv_store,
1586215868 },
1586315869 holder_commitment_point,
1586415870 pending_splice,
@@ -16770,7 +16776,9 @@ mod tests {
1677016776 // These aren't set in the test vectors:
1677116777 [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],
1677216778 [0; 32],
16779+ std::path::PathBuf::new(),
1677316780 [0; 32],
16781+ None,
1677416782 );
1677516783
1677616784 let holder_pubkeys = signer.pubkeys(&secp_ctx);
0 commit comments