Skip to content

Commit ea15124

Browse files
committed
feat: support push_asset_amount on RGB channel open
1 parent 961313c commit ea15124

4 files changed

Lines changed: 58 additions & 19 deletions

File tree

lightning/src/ln/channel.rs

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2357,6 +2357,12 @@ pub(crate) struct FundingScope {
23572357
/// The minimum number of confirmations before the funding is locked. If set, this will override
23582358
/// [`ChannelContext::minimum_depth`].
23592359
minimum_depth_override: Option<u32>,
2360+
2361+
/// The consignment endpoint used to exchange the RGB consignment.
2362+
pub(super) consignment_endpoint: Option<RgbTransport>,
2363+
2364+
/// The RGB asset amount to push to the counterparty on channel open.
2365+
pub(super) push_asset_amount: Option<u64>,
23602366
}
23612367

23622368
impl Writeable for FundingScope {
@@ -2371,6 +2377,8 @@ impl Writeable for FundingScope {
23712377
(13, self.funding_tx_confirmation_height, required),
23722378
(15, self.short_channel_id, option),
23732379
(17, self.minimum_depth_override, option),
2380+
(19, self.consignment_endpoint, option),
2381+
(21, self.push_asset_amount, option),
23742382
});
23752383
Ok(())
23762384
}
@@ -2388,6 +2396,8 @@ impl Readable for FundingScope {
23882396
let mut funding_tx_confirmation_height = RequiredWrapper(None);
23892397
let mut short_channel_id = None;
23902398
let mut minimum_depth_override = None;
2399+
let mut consignment_endpoint = None;
2400+
let mut push_asset_amount = None;
23912401

23922402
read_tlv_fields!(reader, {
23932403
(1, value_to_self_msat, required),
@@ -2399,6 +2409,8 @@ impl Readable for FundingScope {
23992409
(13, funding_tx_confirmation_height, required),
24002410
(15, short_channel_id, option),
24012411
(17, minimum_depth_override, option),
2412+
(19, consignment_endpoint, option),
2413+
(21, push_asset_amount, option),
24022414
});
24032415

24042416
Ok(Self {
@@ -2415,6 +2427,8 @@ impl Readable for FundingScope {
24152427
funding_tx_confirmation_height: funding_tx_confirmation_height.0.unwrap(),
24162428
short_channel_id,
24172429
minimum_depth_override,
2430+
consignment_endpoint,
2431+
push_asset_amount,
24182432
#[cfg(any(test, fuzzing))]
24192433
next_local_fee: Mutex::new(PredictedNextFee::default()),
24202434
#[cfg(any(test, fuzzing))]
@@ -2602,6 +2616,8 @@ impl FundingScope {
26022616
funding_tx_confirmed_in: None,
26032617
minimum_depth_override: None,
26042618
short_channel_id: None,
2619+
consignment_endpoint: None,
2620+
push_asset_amount: None,
26052621
}
26062622
}
26072623

@@ -3128,8 +3144,7 @@ where
31283144
/// promotion.
31293145
pub interactive_tx_signing_session: Option<InteractiveTxSigningSession>,
31303146

3131-
/// The consignment endpoint used to exchange the RGB consignment
3132-
pub(super) consignment_endpoint: Option<RgbTransport>,
3147+
pub(super) is_colored: bool,
31333148

31343149
pub(crate) ldk_data_dir: PathBuf,
31353150
}
@@ -3400,6 +3415,7 @@ where
34003415
msg_channel_reserve_satoshis: u64,
34013416
msg_push_msat: u64,
34023417
open_channel_fields: msgs::CommonOpenChannelFields,
3418+
push_asset_amount: Option<u64>,
34033419
ldk_data_dir: PathBuf,
34043420
) -> Result<(FundingScope, ChannelContext<SP>), ChannelError>
34053421
where
@@ -3608,6 +3624,8 @@ where
36083624
funding_tx_confirmation_height: 0,
36093625
short_channel_id: None,
36103626
minimum_depth_override: None,
3627+
consignment_endpoint: open_channel_fields.consignment_endpoint.clone(),
3628+
push_asset_amount,
36113629
};
36123630
let channel_context = ChannelContext {
36133631
user_id,
@@ -3721,7 +3739,7 @@ where
37213739

37223740
interactive_tx_signing_session: None,
37233741

3724-
consignment_endpoint: open_channel_fields.consignment_endpoint,
3742+
is_colored: funding.consignment_endpoint.is_some(),
37253743
ldk_data_dir,
37263744
};
37273745

@@ -3748,6 +3766,7 @@ where
37483766
_logger: L,
37493767
consignment_endpoint: Option<RgbTransport>,
37503768
ldk_data_dir: PathBuf,
3769+
push_asset_amount: Option<u64>,
37513770
) -> Result<(FundingScope, ChannelContext<SP>), APIError>
37523771
where
37533772
ES::Target: EntropySource,
@@ -3853,6 +3872,8 @@ where
38533872
funding_tx_confirmation_height: 0,
38543873
short_channel_id: None,
38553874
minimum_depth_override: None,
3875+
consignment_endpoint: consignment_endpoint.clone(),
3876+
push_asset_amount,
38563877
};
38573878
let channel_context = Self {
38583879
user_id,
@@ -3964,7 +3985,7 @@ where
39643985

39653986
interactive_tx_signing_session: None,
39663987

3967-
consignment_endpoint,
3988+
is_colored: funding.consignment_endpoint.is_some(),
39683989
ldk_data_dir,
39693990
};
39703991

@@ -3992,7 +4013,7 @@ where
39924013
}
39934014

39944015
pub fn is_colored(&self) -> bool {
3995-
self.consignment_endpoint.is_some()
4016+
self.is_colored
39964017
}
39974018

39984019
/// Gets the fee we'd want to charge for adding an HTLC output to this Channel
@@ -13549,7 +13570,7 @@ where
1354913570
pub fn new<ES: Deref, F: Deref, L: Deref>(
1355013571
fee_estimator: &LowerBoundedFeeEstimator<F>, entropy_source: &ES, signer_provider: &SP, counterparty_node_id: PublicKey, their_features: &InitFeatures,
1355113572
channel_value_satoshis: u64, push_msat: u64, user_id: u128, config: &UserConfig, current_chain_height: u32,
13552-
outbound_scid_alias: u64, temporary_channel_id: Option<ChannelId>, logger: L, consignment_endpoint: Option<RgbTransport>, ldk_data_dir: PathBuf,
13573+
outbound_scid_alias: u64, temporary_channel_id: Option<ChannelId>, logger: L, consignment_endpoint: Option<RgbTransport>, ldk_data_dir: PathBuf, push_asset_amount: Option<u64>,
1355313574
) -> Result<OutboundV1Channel<SP>, APIError>
1355413575
where ES::Target: EntropySource,
1355513576
F::Target: FeeEstimator,
@@ -13589,6 +13610,7 @@ where
1358913610
logger,
1359013611
consignment_endpoint,
1359113612
ldk_data_dir,
13613+
push_asset_amount,
1359213614
)?;
1359313615
let unfunded_context = UnfundedChannelContext {
1359413616
unfunded_channel_age_ticks: 0,
@@ -13766,10 +13788,11 @@ where
1376613788
None => Builder::new().into_script(),
1376713789
}),
1376813790
channel_type: Some(self.funding.get_channel_type().clone()),
13769-
consignment_endpoint: self.context.consignment_endpoint.clone(),
13791+
consignment_endpoint: self.funding.consignment_endpoint.clone(),
1377013792
},
1377113793
push_msat: self.funding.get_value_satoshis() * 1000 - self.funding.value_to_self_msat,
1377213794
channel_reserve_satoshis: self.funding.holder_selected_channel_reserve_satoshis,
13795+
push_asset_amount: self.funding.push_asset_amount,
1377313796
})
1377413797
}
1377513798

@@ -13965,6 +13988,7 @@ where
1396513988
msg.channel_reserve_satoshis,
1396613989
msg.push_msat,
1396713990
msg.common_fields.clone(),
13991+
msg.push_asset_amount,
1396813992
ldk_data_dir,
1396913993
)?;
1397013994
let unfunded_context = UnfundedChannelContext {
@@ -14209,6 +14233,7 @@ where
1420914233
// ok to pass consignment_endpoint as None since this method is unused
1421014234
None,
1421114235
ldk_data_dir,
14236+
None,
1421214237
)?;
1421314238
let unfunded_context = UnfundedChannelContext {
1421414239
unfunded_channel_age_ticks: 0,
@@ -14300,7 +14325,7 @@ where
1430014325
None => Builder::new().into_script(),
1430114326
}),
1430214327
channel_type: Some(self.funding.get_channel_type().clone()),
14303-
consignment_endpoint: self.context.consignment_endpoint.clone(),
14328+
consignment_endpoint: self.funding.consignment_endpoint.clone(),
1430414329
},
1430514330
funding_feerate_sat_per_1000_weight: self.context.feerate_per_kw,
1430614331
second_per_commitment_point,
@@ -14364,6 +14389,7 @@ where
1436414389
counterparty_selected_channel_reserve_satoshis,
1436514390
0 /* push_msat not used in dual-funding */,
1436614391
msg.common_fields.clone(),
14392+
None,
1436714393
ldk_data_dir,
1436814394
)?;
1436914395
let channel_id = ChannelId::v2_from_revocation_basepoints(
@@ -15047,7 +15073,8 @@ where
1504715073
(65, self.quiescent_action, option), // Added in 0.2
1504815074
(67, pending_outbound_held_htlc_flags, optional_vec), // Added in 0.2
1504915075
(69, holding_cell_held_htlc_flags, optional_vec), // Added in 0.2
15050-
(71, self.context.consignment_endpoint, option),
15076+
(71, self.funding.consignment_endpoint, option),
15077+
(73, self.funding.push_asset_amount, option),
1505115078
});
1505215079

1505315080
Ok(())
@@ -15384,6 +15411,7 @@ where
1538415411
let mut temporary_channel_id: Option<ChannelId> = None;
1538515412
let mut holder_max_accepted_htlcs: Option<u16> = None;
1538615413
let mut consignment_endpoint: Option<RgbTransport> = None;
15414+
let mut push_asset_amount: Option<u64> = None;
1538715415

1538815416
let mut blocked_monitor_updates = Some(Vec::new());
1538915417

@@ -15467,6 +15495,7 @@ where
1546715495
(67, pending_outbound_held_htlc_flags_opt, optional_vec), // Added in 0.2
1546815496
(69, holding_cell_held_htlc_flags_opt, optional_vec), // Added in 0.2
1546915497
(71, consignment_endpoint, option),
15498+
(73, push_asset_amount, option),
1547015499
});
1547115500

1547215501
let holder_signer = signer_provider.derive_channel_signer(channel_keys_id);
@@ -15745,6 +15774,8 @@ where
1574515774
funding_tx_confirmation_height,
1574615775
short_channel_id,
1574715776
minimum_depth_override,
15777+
consignment_endpoint: consignment_endpoint.clone(),
15778+
push_asset_amount,
1574815779
},
1574915780
context: ChannelContext {
1575015781
user_id,
@@ -15856,8 +15887,7 @@ where
1585615887
is_manual_broadcast: is_manual_broadcast.unwrap_or(false),
1585715888

1585815889
interactive_tx_signing_session,
15859-
15860-
consignment_endpoint,
15890+
is_colored: consignment_endpoint.is_some(),
1586115891
ldk_data_dir,
1586215892
},
1586315893
holder_commitment_point,
@@ -17848,6 +17878,8 @@ mod tests {
1784817878
funding_tx_confirmation_height: 0,
1784917879
short_channel_id: None,
1785017880
minimum_depth_override: None,
17881+
consignment_endpoint: None,
17882+
push_asset_amount: None,
1785117883
};
1785217884
let post_channel_value =
1785317885
funding.compute_post_splice_value(our_funding_contribution, their_funding_contribution);

lightning/src/ln/channelmanager.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4134,7 +4134,7 @@ where
41344134
/// [`Event::FundingGenerationReady::temporary_channel_id`]: events::Event::FundingGenerationReady::temporary_channel_id
41354135
/// [`Event::ChannelClosed::channel_id`]: events::Event::ChannelClosed::channel_id
41364136
#[rustfmt::skip]
4137-
pub fn create_channel(&self, their_network_key: PublicKey, channel_value_satoshis: u64, push_msat: u64, user_channel_id: u128, temporary_channel_id: Option<ChannelId>, override_config: Option<UserConfig>, consignment_endpoint: Option<RgbTransport>) -> Result<ChannelId, APIError> {
4137+
pub fn create_channel(&self, their_network_key: PublicKey, channel_value_satoshis: u64, push_msat: u64, user_channel_id: u128, temporary_channel_id: Option<ChannelId>, override_config: Option<UserConfig>, consignment_endpoint: Option<RgbTransport>, push_asset_amount: Option<u64>) -> Result<ChannelId, APIError> {
41384138
if channel_value_satoshis < 1000 {
41394139
return Err(APIError::APIMisuseError { err: format!("Channel value must be at least 1000 satoshis. It was {}", channel_value_satoshis) });
41404140
}
@@ -4170,7 +4170,7 @@ where
41704170
};
41714171
match OutboundV1Channel::new(&self.fee_estimator, &self.entropy_source, &self.signer_provider, their_network_key,
41724172
their_features, channel_value_satoshis, push_msat, user_channel_id, config,
4173-
self.best_block.read().unwrap().height, outbound_scid_alias, temporary_channel_id, &*self.logger, consignment_endpoint, self.ldk_data_dir.clone())
4173+
self.best_block.read().unwrap().height, outbound_scid_alias, temporary_channel_id, &*self.logger, consignment_endpoint, self.ldk_data_dir.clone(), push_asset_amount)
41744174
{
41754175
Ok(res) => res,
41764176
Err(e) => {
@@ -10386,8 +10386,8 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
1038610386
{
1038710387
Some(Ok(inbound_chan)) => {
1038810388
let logger = WithChannelContext::from(&self.logger, &inbound_chan.context, None);
10389-
if let Some(consignment_endpoint) = &inbound_chan.context.consignment_endpoint {
10390-
handle_funding(&msg.temporary_channel_id, msg.funding_txid.to_string(), &self.ldk_data_dir, consignment_endpoint.clone())?;
10389+
if let Some(consignment_endpoint) = &inbound_chan.funding.consignment_endpoint {
10390+
handle_funding(&msg.temporary_channel_id, msg.funding_txid.to_string(), &self.ldk_data_dir, consignment_endpoint.clone(), inbound_chan.funding.push_asset_amount)?;
1039110391
}
1039210392
match inbound_chan.funding_created(msg, best_block, &self.signer_provider, &&logger) {
1039310393
Ok(res) => res,

lightning/src/ln/msgs.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,8 @@ pub struct OpenChannel {
299299
pub push_msat: u64,
300300
/// The minimum value unencumbered by HTLCs for the counterparty to keep in the channel
301301
pub channel_reserve_satoshis: u64,
302+
/// The amount of RGB assets to push to the counterparty as part of the open.
303+
pub push_asset_amount: Option<u64>,
302304
}
303305

304306
/// An [`open_channel2`] message to be sent by or received from the channel initiator.
@@ -3135,6 +3137,7 @@ impl Writeable for OpenChannel {
31353137
(0, self.common_fields.shutdown_scriptpubkey.as_ref().map(|s| WithoutLength(s)), option), // Don't encode length twice.
31363138
(1, self.common_fields.channel_type, option),
31373139
(2, self.common_fields.consignment_endpoint, option),
3140+
(3, self.push_asset_amount, option),
31383141
});
31393142
Ok(())
31403143
}
@@ -3164,10 +3167,12 @@ impl LengthReadable for OpenChannel {
31643167
let mut shutdown_scriptpubkey: Option<ScriptBuf> = None;
31653168
let mut channel_type: Option<ChannelTypeFeatures> = None;
31663169
let mut consignment_endpoint: Option<RgbTransport> = None;
3170+
let mut push_asset_amount: Option<u64> = None;
31673171
decode_tlv_stream!(r, {
31683172
(0, shutdown_scriptpubkey, (option, encoding: (ScriptBuf, WithoutLength))),
31693173
(1, channel_type, option),
31703174
(2, consignment_endpoint, option),
3175+
(3, push_asset_amount, option),
31713176
});
31723177
Ok(OpenChannel {
31733178
common_fields: CommonOpenChannelFields {
@@ -3193,6 +3198,7 @@ impl LengthReadable for OpenChannel {
31933198
},
31943199
push_msat,
31953200
channel_reserve_satoshis,
3201+
push_asset_amount,
31963202
})
31973203
}
31983204
}

lightning/src/rgb_utils/mod.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -655,7 +655,7 @@ pub(crate) fn rename_rgb_files(
655655
/// Handle funding on the receiver side
656656
pub(crate) fn handle_funding(
657657
temporary_channel_id: &ChannelId, funding_txid: String, ldk_data_dir: &Path,
658-
consignment_endpoint: RgbTransport,
658+
consignment_endpoint: RgbTransport, push_asset_amount: Option<u64>,
659659
) -> Result<(), MsgHandleErrInternal> {
660660
let handle = Handle::current();
661661
let _ = handle.enter();
@@ -710,16 +710,17 @@ pub(crate) fn handle_funding(
710710
*temporary_channel_id,
711711
));
712712
}
713-
let remote_rgb_amount = match remote_rgb_assignments[0] {
713+
let channel_rgb_amount = match remote_rgb_assignments[0] {
714714
Assignment::Fungible(amt) => amt,
715715
Assignment::NonFungible => 1,
716716
_ => unreachable!("unsupported schema"),
717717
};
718+
let push_amount = push_asset_amount.unwrap_or(0);
718719
let rgb_info = RgbInfo {
719720
contract_id: consignment.contract_id(),
720721
schema: AssetSchema::from_schema_id(consignment.schema_id()).unwrap(),
721-
local_rgb_amount: 0,
722-
remote_rgb_amount,
722+
local_rgb_amount: push_amount,
723+
remote_rgb_amount: channel_rgb_amount - push_amount,
723724
};
724725
let temporary_channel_id_str = temporary_channel_id.0.as_hex().to_string();
725726
write_rgb_channel_info(

0 commit comments

Comments
 (0)