Skip to content

Commit 167a2c4

Browse files
committed
Implement RGB KVStore Integration
1 parent 245e4f5 commit 167a2c4

7 files changed

Lines changed: 336 additions & 268 deletions

File tree

lightning/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ libm = { version = "0.2", default-features = false }
5252
inventory = { version = "0.3", optional = true }
5353

5454
# RGB and related
55+
bincode = "1.3"
5556
futures = "0.3"
5657
rgb-lib = { version = "0.3.0-beta.5", features = [
5758
"electrum",
@@ -60,7 +61,6 @@ rgb-lib = { version = "0.3.0-beta.5", features = [
6061
serde = { version = "^1.0", features = [
6162
"derive",
6263
] }
63-
serde_json = "^1.0"
6464
tokio = { version = "1.14.1", features = [
6565
"macros",
6666
"rt-multi-thread",

lightning/src/ln/chan_utils.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ use crate::ln::msgs::DecodeError;
3636
use crate::rgb_utils::{color_htlc, is_tx_colored};
3737
use crate::sign::EntropySource;
3838
use crate::types::payment::{PaymentHash, PaymentPreimage};
39+
use crate::util::persist::KVStoreSync;
3940
use crate::util::ser::{Readable, ReadableArgs, RequiredWrapper, Writeable, Writer};
4041
use crate::util::transaction_utils;
4142

@@ -2156,6 +2157,7 @@ impl<'a> TrustedCommitmentTransaction<'a> {
21562157
pub fn get_htlc_sigs<T: secp256k1::Signing, ES: Deref>(
21572158
&self, htlc_base_key: &SecretKey, channel_parameters: &DirectedChannelTransactionParameters,
21582159
entropy_source: &ES, secp_ctx: &Secp256k1<T>, ldk_data_dir: &PathBuf,
2160+
rgb_kv_store: &dyn KVStoreSync,
21592161
) -> Result<Vec<Signature>, ()> where ES::Target: EntropySource {
21602162
let inner = self.inner;
21612163
let keys = &inner.keys;
@@ -2167,7 +2169,7 @@ impl<'a> TrustedCommitmentTransaction<'a> {
21672169
assert!(this_htlc.transaction_output_index.is_some());
21682170
let mut htlc_tx = build_htlc_transaction(&txid, inner.feerate_per_kw, channel_parameters.contest_delay(), &this_htlc, &self.channel_type_features, &keys.broadcaster_delayed_payment_key, &keys.revocation_key);
21692171
if inner.is_colored() {
2170-
if let Err(_e) = color_htlc(&mut htlc_tx, this_htlc, ldk_data_dir) {
2172+
if let Err(_e) = color_htlc(&mut htlc_tx, this_htlc, ldk_data_dir, rgb_kv_store) {
21712173
return Err(());
21722174
}
21732175
}

lightning/src/ln/channel.rs

Lines changed: 37 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,8 @@ use crate::ln::types::ChannelId;
7878
use crate::ln::LN_MAX_MSG_LEN;
7979
use crate::offers::static_invoice::StaticInvoice;
8080
use 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, rename_rgb_files,
82+
update_rgb_channel_amount_pending, RgbKvStoreExt,
8483
};
8584
use crate::routing::gossip::NodeId;
8685
use crate::sign::ecdsa::EcdsaChannelSigner;
@@ -104,6 +103,8 @@ use crate::prelude::*;
104103
use crate::sign::type_resolver::ChannelSignerType;
105104
#[cfg(any(test, fuzzing, debug_assertions))]
106105
use crate::sync::Mutex;
106+
use crate::sync::Arc;
107+
use crate::util::persist::KVStoreSync;
107108
use core::ops::Deref;
108109
use core::time::Duration;
109110
use core::{cmp, fmt, mem};
@@ -3147,6 +3148,9 @@ where
31473148
pub(super) is_colored: bool,
31483149

31493150
pub(crate) ldk_data_dir: PathBuf,
3151+
3152+
/// KVStore for RGB data persistence
3153+
pub(crate) rgb_kv_store: Arc<dyn KVStoreSync + Send + Sync>,
31503154
}
31513155

31523156
/// A channel struct implementing this trait can receive an initial counterparty commitment
@@ -3246,8 +3250,8 @@ where
32463250
let context = self.context_mut();
32473251
let temporary_channel_id = context.channel_id;
32483252
context.channel_id = channel_id;
3249-
if context.is_colored() {
3250-
rename_rgb_files(&context.channel_id, &temporary_channel_id, &context.ldk_data_dir);
3253+
if context.is_colored() && temporary_channel_id != channel_id {
3254+
rename_rgb_files(&context.channel_id, &temporary_channel_id, context.rgb_kv_store.as_ref());
32513255
}
32523256

32533257
assert!(!context.channel_state.is_monitor_update_in_progress()); // We have not had any monitor(s) yet to fail update!
@@ -3417,6 +3421,7 @@ where
34173421
open_channel_fields: msgs::CommonOpenChannelFields,
34183422
push_asset_amount: Option<u64>,
34193423
ldk_data_dir: PathBuf,
3424+
rgb_kv_store: Arc<dyn KVStoreSync + Send + Sync>,
34203425
) -> Result<(FundingScope, ChannelContext<SP>), ChannelError>
34213426
where
34223427
ES::Target: EntropySource,
@@ -3741,6 +3746,7 @@ where
37413746

37423747
is_colored: funding.consignment_endpoint.is_some(),
37433748
ldk_data_dir,
3749+
rgb_kv_store,
37443750
};
37453751

37463752
Ok((funding, channel_context))
@@ -3767,6 +3773,7 @@ where
37673773
consignment_endpoint: Option<RgbTransport>,
37683774
ldk_data_dir: PathBuf,
37693775
push_asset_amount: Option<u64>,
3776+
rgb_kv_store: Arc<dyn KVStoreSync + Send + Sync>,
37703777
) -> Result<(FundingScope, ChannelContext<SP>), APIError>
37713778
where
37723779
ES::Target: EntropySource,
@@ -3987,6 +3994,7 @@ where
39873994

39883995
is_colored: funding.consignment_endpoint.is_some(),
39893996
ldk_data_dir,
3997+
rgb_kv_store,
39903998
};
39913999

39924000
Ok((funding, channel_context))
@@ -4365,13 +4373,8 @@ where
43654373

43664374
/// Get the channel local RGB amount
43674375
pub fn get_local_rgb_amount(&self) -> u64 {
4368-
let info_file_path = get_rgb_channel_info_path(
4369-
&self.channel_id.0.as_hex().to_string(),
4370-
&self.ldk_data_dir,
4371-
false,
4372-
);
4373-
if info_file_path.exists() {
4374-
let rgb_info = parse_rgb_channel_info(&info_file_path);
4376+
let channel_id_str = self.channel_id.0.as_hex().to_string();
4377+
if let Ok(rgb_info) = self.rgb_kv_store.read_rgb_channel_info(&channel_id_str, false) {
43754378
rgb_info.local_rgb_amount
43764379
} else {
43774380
0
@@ -4380,13 +4383,8 @@ where
43804383

43814384
/// Get the channel remote RGB amount
43824385
pub fn get_remote_rgb_amount(&self) -> u64 {
4383-
let info_file_path = get_rgb_channel_info_path(
4384-
&self.channel_id.0.as_hex().to_string(),
4385-
&self.ldk_data_dir,
4386-
false,
4387-
);
4388-
if info_file_path.exists() {
4389-
let rgb_info = parse_rgb_channel_info(&info_file_path);
4386+
let channel_id_str = self.channel_id.0.as_hex().to_string();
4387+
if let Ok(rgb_info) = self.rgb_kv_store.read_rgb_channel_info(&channel_id_str, false) {
43904388
rgb_info.remote_rgb_amount
43914389
} else {
43924390
0
@@ -5101,7 +5099,7 @@ where
51015099
&holder_keys.revocation_key,
51025100
);
51035101
if self.is_colored() {
5104-
color_htlc(&mut htlc_tx, htlc, &self.ldk_data_dir)
5102+
color_htlc(&mut htlc_tx, htlc, &self.ldk_data_dir, self.rgb_kv_store.as_ref())
51055103
.expect("successful htlc coloring");
51065104
}
51075105

@@ -7345,6 +7343,7 @@ where
73457343
&self.context.channel_id,
73467344
&mut closing_transaction,
73477345
&self.context.ldk_data_dir,
7346+
self.context.rgb_kv_store.as_ref(),
73487347
)
73497348
.expect("successful closing TX coloring");
73507349
}
@@ -8944,7 +8943,7 @@ where
89448943
&self.context.channel_id,
89458944
rgb_offered_htlc,
89468945
rgb_received_htlc,
8947-
&self.context.ldk_data_dir,
8946+
self.context.rgb_kv_store.as_ref(),
89488947
);
89498948
}
89508949

@@ -11758,7 +11757,7 @@ where
1175811757
let were_node_one = node_id.as_slice() < counterparty_node_id.as_slice();
1175911758

1176011759
let contract_id = if self.context.is_colored() {
11761-
let (rgb_info, _) = get_rgb_channel_info_pending(&self.context.channel_id, &self.context.ldk_data_dir);
11760+
let rgb_info = get_rgb_channel_info_pending(&self.context.channel_id, self.context.rgb_kv_store.as_ref());
1176211761
Some(rgb_info.contract_id)
1176311762
} else {
1176411763
None
@@ -12912,7 +12911,7 @@ where
1291212911
}
1291312912
}
1291412913
if self.context.is_colored() && rgb_received_htlc > 0 {
12915-
update_rgb_channel_amount_pending(&self.context.channel_id, 0, rgb_received_htlc, &self.context.ldk_data_dir);
12914+
update_rgb_channel_amount_pending(&self.context.channel_id, 0, rgb_received_htlc, self.context.rgb_kv_store.as_ref());
1291612915
}
1291712916
if let Some((feerate, update_state)) = self.context.pending_update_fee {
1291812917
if update_state == FeeUpdateState::AwaitingRemoteRevokeToAnnounce {
@@ -13579,6 +13578,7 @@ where
1357913578
fee_estimator: &LowerBoundedFeeEstimator<F>, entropy_source: &ES, signer_provider: &SP, counterparty_node_id: PublicKey, their_features: &InitFeatures,
1358013579
channel_value_satoshis: u64, push_msat: u64, user_id: u128, config: &UserConfig, current_chain_height: u32,
1358113580
outbound_scid_alias: u64, temporary_channel_id: Option<ChannelId>, logger: L, consignment_endpoint: Option<RgbTransport>, ldk_data_dir: PathBuf, push_asset_amount: Option<u64>,
13581+
rgb_kv_store: Arc<dyn KVStoreSync + Send + Sync>,
1358213582
) -> Result<OutboundV1Channel<SP>, APIError>
1358313583
where ES::Target: EntropySource,
1358413584
F::Target: FeeEstimator,
@@ -13619,6 +13619,7 @@ where
1361913619
consignment_endpoint,
1362013620
ldk_data_dir,
1362113621
push_asset_amount,
13622+
rgb_kv_store,
1362213623
)?;
1362313624
let unfunded_context = UnfundedChannelContext {
1362413625
unfunded_channel_age_ticks: 0,
@@ -13702,7 +13703,7 @@ where
1370213703
let temporary_channel_id = self.context.channel_id;
1370313704
self.context.channel_id = ChannelId::v1_from_funding_outpoint(funding_txo);
1370413705
if self.context.is_colored() {
13705-
rename_rgb_files(&self.context.channel_id, &temporary_channel_id, &self.context.ldk_data_dir);
13706+
rename_rgb_files(&self.context.channel_id, &temporary_channel_id, self.context.rgb_kv_store.as_ref());
1370613707
}
1370713708

1370813709
// If the funding transaction is a coinbase transaction, we need to set the minimum depth to 100.
@@ -13956,7 +13957,8 @@ where
1395613957
fee_estimator: &LowerBoundedFeeEstimator<F>, entropy_source: &ES, signer_provider: &SP,
1395713958
counterparty_node_id: PublicKey, our_supported_features: &ChannelTypeFeatures,
1395813959
their_features: &InitFeatures, msg: &msgs::OpenChannel, user_id: u128, config: &UserConfig,
13959-
current_chain_height: u32, logger: &L, is_0conf: bool, ldk_data_dir: PathBuf
13960+
current_chain_height: u32, logger: &L, is_0conf: bool, ldk_data_dir: PathBuf,
13961+
rgb_kv_store: Arc<dyn KVStoreSync + Send + Sync>,
1396013962
) -> Result<InboundV1Channel<SP>, ChannelError>
1396113963
where ES::Target: EntropySource,
1396213964
F::Target: FeeEstimator,
@@ -13998,6 +14000,7 @@ where
1399814000
msg.common_fields.clone(),
1399914001
msg.push_asset_amount,
1400014002
ldk_data_dir,
14003+
rgb_kv_store,
1400114004
)?;
1400214005
let unfunded_context = UnfundedChannelContext {
1400314006
unfunded_channel_age_ticks: 0,
@@ -14198,7 +14201,7 @@ where
1419814201
counterparty_node_id: PublicKey, their_features: &InitFeatures, funding_satoshis: u64,
1419914202
funding_inputs: Vec<FundingTxInput>, user_id: u128, config: &UserConfig,
1420014203
current_chain_height: u32, outbound_scid_alias: u64, funding_confirmation_target: ConfirmationTarget,
14201-
logger: L, ldk_data_dir: PathBuf,
14204+
logger: L, ldk_data_dir: PathBuf, rgb_kv_store: Arc<dyn KVStoreSync + Send + Sync>,
1420214205
) -> Result<Self, APIError>
1420314206
where ES::Target: EntropySource,
1420414207
F::Target: FeeEstimator,
@@ -14242,6 +14245,7 @@ where
1424214245
None,
1424314246
ldk_data_dir,
1424414247
None,
14248+
rgb_kv_store,
1424514249
)?;
1424614250
let unfunded_context = UnfundedChannelContext {
1424714251
unfunded_channel_age_ticks: 0,
@@ -14352,7 +14356,7 @@ where
1435214356
holder_node_id: PublicKey, counterparty_node_id: PublicKey, our_supported_features: &ChannelTypeFeatures,
1435314357
their_features: &InitFeatures, msg: &msgs::OpenChannelV2,
1435414358
user_id: u128, config: &UserConfig, current_chain_height: u32, logger: &L,
14355-
ldk_data_dir: PathBuf,
14359+
ldk_data_dir: PathBuf, rgb_kv_store: Arc<dyn KVStoreSync + Send + Sync>,
1435614360
) -> Result<Self, ChannelError>
1435714361
where ES::Target: EntropySource,
1435814362
F::Target: FeeEstimator,
@@ -14399,6 +14403,7 @@ where
1439914403
msg.common_fields.clone(),
1440014404
None,
1440114405
ldk_data_dir,
14406+
rgb_kv_store,
1440214407
)?;
1440314408
let channel_id = ChannelId::v2_from_revocation_basepoints(
1440414409
&funding.get_holder_pubkeys().revocation_basepoint,
@@ -15089,16 +15094,16 @@ where
1508915094
}
1509015095
}
1509115096

15092-
impl<'a, 'b, 'c, ES: Deref, SP: Deref>
15093-
ReadableArgs<(&'a ES, &'b SP, &'c ChannelTypeFeatures, PathBuf)> for FundedChannel<SP>
15097+
impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, &'c ChannelTypeFeatures, PathBuf, Arc<dyn KVStoreSync + Send + Sync>)>
15098+
for FundedChannel<SP>
1509415099
where
1509515100
ES::Target: EntropySource,
1509615101
SP::Target: SignerProvider,
1509715102
{
1509815103
fn read<R: io::Read>(
15099-
reader: &mut R, args: (&'a ES, &'b SP, &'c ChannelTypeFeatures, PathBuf),
15104+
reader: &mut R, args: (&'a ES, &'b SP, &'c ChannelTypeFeatures, PathBuf, Arc<dyn KVStoreSync + Send + Sync>),
1510015105
) -> Result<Self, DecodeError> {
15101-
let (entropy_source, signer_provider, our_supported_features, ldk_data_dir) = args;
15106+
let (entropy_source, signer_provider, our_supported_features, ldk_data_dir, rgb_kv_store) = args;
1510215107
let ver = read_ver_prefix!(reader, SERIALIZATION_VERSION);
1510315108
if ver <= 2 {
1510415109
return Err(DecodeError::UnknownVersion);
@@ -15897,6 +15902,7 @@ where
1589715902
interactive_tx_signing_session,
1589815903
is_colored: consignment_endpoint.is_some(),
1589915904
ldk_data_dir,
15905+
rgb_kv_store,
1590015906
},
1590115907
holder_commitment_point,
1590215908
pending_splice,

0 commit comments

Comments
 (0)