Skip to content

Commit 673eaf5

Browse files
committed
rebase on v0.0.125 + update rgb-lib
1 parent e80d632 commit 673eaf5

37 files changed

Lines changed: 1718 additions & 245 deletions

Cargo.toml

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -41,25 +41,5 @@ opt-level = 3
4141
lto = true
4242
panic = "abort"
4343

44-
[workspace.lints.rust.unexpected_cfgs]
45-
level = "forbid"
46-
# When adding a new cfg attribute, ensure that it is added to this list.
47-
#
48-
# Note that Cargo automatically declares corresponding cfgs for every feature
49-
# defined in the member-level [features] tables as "expected".
50-
check-cfg = [
51-
"cfg(fuzzing)",
52-
"cfg(secp256k1_fuzz)",
53-
"cfg(hashes_fuzz)",
54-
"cfg(test)",
55-
"cfg(debug_assertions)",
56-
"cfg(c_bindings)",
57-
"cfg(ldk_bench)",
58-
"cfg(ldk_test_vectors)",
59-
"cfg(taproot)",
60-
"cfg(async_signing)",
61-
"cfg(require_route_graph_test)",
62-
"cfg(dual_funding)",
63-
"cfg(splicing)",
64-
"cfg(async_payments)",
65-
]
44+
[workspace.lints.rust]
45+
warnings = "allow"

lightning-invoice/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ lightning-types = { version = "0.1.0", path = "../lightning-types", default-feat
2323
serde = { version = "1.0.118", optional = true }
2424
bitcoin = { version = "0.32.2", default-features = false, features = ["secp-recovery"] }
2525

26+
# RGB and related
27+
rgb-lib = { version = "0.3.0-alpha.11", features = [
28+
"electrum",
29+
"esplora",
30+
], git = "https://github.com/RGB-Tools/rgb-lib.git", rev = "952cd185" }
31+
2632
[dev-dependencies]
2733
serde_json = { version = "1"}
2834
hashbrown = { version = "0.13", default-features = false }

lightning-invoice/src/de.rs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use bech32::{u5, FromBase32};
1313
use bitcoin::{PubkeyHash, ScriptHash, WitnessVersion};
1414
use bitcoin::hashes::Hash;
1515
use bitcoin::hashes::sha256;
16+
use rgb_lib::ContractId;
1617
use crate::prelude::*;
1718
use lightning_types::payment::PaymentSecret;
1819
use lightning_types::routing::{RoutingFees, RouteHint, RouteHintHop};
@@ -22,7 +23,7 @@ use bitcoin::secp256k1::PublicKey;
2223

2324
use super::{Bolt11Invoice, Sha256, TaggedField, ExpiryTime, MinFinalCltvExpiryDelta, Fallback, PayeePubKey, Bolt11InvoiceSignature, PositiveTimestamp,
2425
Bolt11SemanticError, PrivateRoute, Bolt11ParseError, ParseOrSemanticError, Description, RawTaggedField, Currency, RawHrp, SiPrefix, RawBolt11Invoice,
25-
constants, SignedRawBolt11Invoice, RawDataPart, Bolt11InvoiceFeatures};
26+
constants, SignedRawBolt11Invoice, RawDataPart, Bolt11InvoiceFeatures, RgbAmount, RgbContractId};
2627

2728
use self::hrp_sm::parse_hrp;
2829

@@ -466,6 +467,10 @@ impl FromBase32 for TaggedField {
466467
Ok(TaggedField::PaymentMetadata(Vec::<u8>::from_base32(field_data)?)),
467468
constants::TAG_FEATURES =>
468469
Ok(TaggedField::Features(Bolt11InvoiceFeatures::from_base32(field_data)?)),
470+
constants::TAG_RGB_AMOUNT =>
471+
Ok(TaggedField::RgbAmount(RgbAmount::from_base32(field_data)?)),
472+
constants::TAG_RGB_CONTRACT_ID =>
473+
Ok(TaggedField::RgbContractId(RgbContractId::from_base32(field_data)?)),
469474
_ => {
470475
// "A reader MUST skip over unknown fields"
471476
Err(Bolt11ParseError::Skip)
@@ -612,6 +617,7 @@ impl FromBase32 for PrivateRoute {
612617
cltv_expiry_delta: u16::from_be_bytes(hop_bytes[49..51].try_into().expect("slice too big?")),
613618
htlc_minimum_msat: None,
614619
htlc_maximum_msat: None,
620+
htlc_maximum_rgb: None,
615621
};
616622

617623
route_hops.push(hop);
@@ -621,6 +627,32 @@ impl FromBase32 for PrivateRoute {
621627
}
622628
}
623629

630+
impl FromBase32 for RgbAmount {
631+
type Err = Bolt11ParseError;
632+
633+
fn from_base32(field_data: &[u5]) -> Result<RgbAmount, Bolt11ParseError> {
634+
let rgb_amount = parse_u64_be(field_data);
635+
if let Some(rgb_amount) = rgb_amount {
636+
Ok(RgbAmount(rgb_amount))
637+
} else {
638+
Err(Bolt11ParseError::IntegerOverflowError)
639+
}
640+
}
641+
}
642+
643+
impl FromBase32 for RgbContractId {
644+
type Err = Bolt11ParseError;
645+
646+
fn from_base32(field_data: &[u5]) -> Result<RgbContractId, Bolt11ParseError> {
647+
let bytes = Vec::<u8>::from_base32(field_data)?;
648+
let rgb_contract_id_str = String::from(str::from_utf8(&bytes)?);
649+
match ContractId::from_str(&rgb_contract_id_str) {
650+
Ok(cid) => Ok(RgbContractId(cid)),
651+
Err(_) => Err(Bolt11ParseError::InvalidContractId),
652+
}
653+
}
654+
}
655+
624656
impl Display for Bolt11ParseError {
625657
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
626658
match *self {
@@ -669,6 +701,9 @@ impl Display for Bolt11ParseError {
669701
Bolt11ParseError::Skip => {
670702
f.write_str("the tagged field has to be skipped because of an unexpected, but allowed property")
671703
},
704+
Bolt11ParseError::InvalidContractId => {
705+
f.write_str("invalid RGB contract ID")
706+
},
672707
}
673708
}
674709
}

lightning-invoice/src/lib.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ use bitcoin::secp256k1::PublicKey;
4242
use bitcoin::secp256k1::{Message, Secp256k1};
4343
use bitcoin::secp256k1::ecdsa::RecoverableSignature;
4444

45+
use rgb_lib::ContractId;
46+
4547
use core::cmp::Ordering;
4648
use core::fmt::{Display, Formatter, self};
4749
use core::iter::FilterMap;
@@ -98,6 +100,7 @@ pub enum Bolt11ParseError {
98100
InvalidScriptHashLength,
99101
InvalidRecoveryId,
100102
InvalidSliceLength(String),
103+
InvalidContractId,
101104

102105
/// Not an error, but used internally to signal that a part of the invoice should be ignored
103106
/// according to BOLT11
@@ -432,6 +435,8 @@ pub enum TaggedField {
432435
PaymentSecret(PaymentSecret),
433436
PaymentMetadata(Vec<u8>),
434437
Features(Bolt11InvoiceFeatures),
438+
RgbAmount(RgbAmount),
439+
RgbContractId(RgbContractId),
435440
}
436441

437442
/// SHA-256 hash
@@ -468,6 +473,14 @@ pub struct ExpiryTime(Duration);
468473
#[derive(Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
469474
pub struct MinFinalCltvExpiryDelta(pub u64);
470475

476+
/// Requested amount for the RGB asset
477+
#[derive(Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
478+
pub struct RgbAmount(pub u64);
479+
480+
/// Requested RGB contract ID
481+
#[derive(Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
482+
pub struct RgbContractId(pub ContractId);
483+
471484
/// Fallback address in case no LN payment is possible
472485
#[allow(missing_docs)]
473486
#[derive(Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
@@ -518,6 +531,8 @@ pub mod constants {
518531
pub const TAG_PAYMENT_SECRET: u8 = 16;
519532
pub const TAG_PAYMENT_METADATA: u8 = 27;
520533
pub const TAG_FEATURES: u8 = 5;
534+
pub const TAG_RGB_AMOUNT: u8 = 30;
535+
pub const TAG_RGB_CONTRACT_ID: u8 = 31;
521536
}
522537

523538
impl InvoiceBuilder<tb::False, tb::False, tb::False, tb::False, tb::False, tb::False> {
@@ -607,6 +622,18 @@ impl<D: tb::Bool, H: tb::Bool, T: tb::Bool, C: tb::Bool, S: tb::Bool, M: tb::Boo
607622
}
608623
self
609624
}
625+
626+
/// Sets the RGB amount.
627+
pub fn rgb_amount(mut self, rgb_amount: u64) -> Self {
628+
self.tagged_fields.push(TaggedField::RgbAmount(RgbAmount(rgb_amount)));
629+
self
630+
}
631+
632+
/// Sets the RGB contract ID.
633+
pub fn rgb_contract_id(mut self, rgb_contract_id: ContractId) -> Self {
634+
self.tagged_fields.push(TaggedField::RgbContractId(RgbContractId(rgb_contract_id)));
635+
self
636+
}
610637
}
611638

612639
impl<D: tb::Bool, H: tb::Bool, C: tb::Bool, S: tb::Bool, M: tb::Bool> InvoiceBuilder<D, H, tb::True, C, S, M> {
@@ -1065,6 +1092,14 @@ impl RawBolt11Invoice {
10651092
find_extract!(self.known_tagged_fields(), TaggedField::Features(ref x), x)
10661093
}
10671094

1095+
pub fn rgb_amount(&self) -> Option<&RgbAmount> {
1096+
find_extract!(self.known_tagged_fields(), TaggedField::RgbAmount(ref x), x)
1097+
}
1098+
1099+
pub fn rgb_contract_id(&self) -> Option<&RgbContractId> {
1100+
find_extract!(self.known_tagged_fields(), TaggedField::RgbContractId(ref x), x)
1101+
}
1102+
10681103
/// This is not exported to bindings users as we don't support Vec<&NonOpaqueType>
10691104
pub fn fallbacks(&self) -> Vec<&Fallback> {
10701105
find_all_extract!(self.known_tagged_fields(), TaggedField::Fallback(ref x), x).collect()
@@ -1483,6 +1518,18 @@ impl Bolt11Invoice {
14831518
fn amount_pico_btc(&self) -> Option<u64> {
14841519
self.signed_invoice.amount_pico_btc()
14851520
}
1521+
1522+
/// Returns the invoice's `rgb_amount` if present
1523+
pub fn rgb_amount(&self) -> Option<u64> {
1524+
self.signed_invoice.rgb_amount()
1525+
.map(|x| x.0)
1526+
}
1527+
1528+
/// Returns the invoice's `rgb_contract_id` if present
1529+
pub fn rgb_contract_id(&self) -> Option<ContractId> {
1530+
self.signed_invoice.rgb_contract_id()
1531+
.map(|x| x.0)
1532+
}
14861533
}
14871534

14881535
impl From<TaggedField> for RawTaggedField {
@@ -1506,6 +1553,8 @@ impl TaggedField {
15061553
TaggedField::PaymentSecret(_) => constants::TAG_PAYMENT_SECRET,
15071554
TaggedField::PaymentMetadata(_) => constants::TAG_PAYMENT_METADATA,
15081555
TaggedField::Features(_) => constants::TAG_FEATURES,
1556+
TaggedField::RgbAmount(_) => constants::TAG_RGB_AMOUNT,
1557+
TaggedField::RgbContractId(_) => constants::TAG_RGB_CONTRACT_ID,
15091558
};
15101559

15111560
u5::try_from_u8(tag).expect("all tags defined are <32")

lightning-invoice/src/ser.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use bech32::{ToBase32, u5, WriteBase32, Base32Len};
44
use crate::prelude::*;
55

66
use super::{Bolt11Invoice, Sha256, TaggedField, ExpiryTime, MinFinalCltvExpiryDelta, Fallback, PayeePubKey, Bolt11InvoiceSignature, PositiveTimestamp,
7-
PrivateRoute, Description, RawTaggedField, Currency, RawHrp, SiPrefix, constants, SignedRawBolt11Invoice, RawDataPart};
7+
PrivateRoute, Description, RawTaggedField, Currency, RawHrp, SiPrefix, constants, SignedRawBolt11Invoice, RawDataPart, RgbAmount, RgbContractId};
88

99
/// Converts a stream of bytes written to it to base32. On finalization the according padding will
1010
/// be applied. That means the results of writing two data blocks with one or two `BytesToBase32`
@@ -399,6 +399,30 @@ impl Base32Len for PrivateRoute {
399399
}
400400
}
401401

402+
impl ToBase32 for RgbAmount {
403+
fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
404+
writer.write(&encode_int_be_base32(self.0))
405+
}
406+
}
407+
408+
impl Base32Len for RgbAmount {
409+
fn base32_len(&self) -> usize {
410+
encoded_int_be_base32_size(self.0)
411+
}
412+
}
413+
414+
impl ToBase32 for RgbContractId {
415+
fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
416+
self.0.to_string().as_bytes().write_base32(writer)
417+
}
418+
}
419+
420+
impl Base32Len for RgbContractId {
421+
fn base32_len(&self) -> usize {
422+
self.0.to_string().as_bytes().base32_len()
423+
}
424+
}
425+
402426
impl ToBase32 for TaggedField {
403427
fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
404428
/// Writes a tagged field: tag, length and data. `tag` should be in `0..32` otherwise the
@@ -452,6 +476,12 @@ impl ToBase32 for TaggedField {
452476
TaggedField::Features(ref features) => {
453477
write_tagged_field(writer, constants::TAG_FEATURES, features)
454478
},
479+
TaggedField::RgbAmount(ref rgb_amount) => {
480+
write_tagged_field(writer, constants::TAG_RGB_AMOUNT, rgb_amount)
481+
},
482+
TaggedField::RgbContractId(ref rgb_contract_id) => {
483+
write_tagged_field(writer, constants::TAG_RGB_CONTRACT_ID, rgb_contract_id)
484+
},
455485
}
456486
}
457487
}

lightning-rapid-gossip-sync/src/processing.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,7 @@ where
375375
cltv_expiry_delta: default_cltv_expiry_delta,
376376
htlc_minimum_msat: default_htlc_minimum_msat,
377377
htlc_maximum_msat: default_htlc_maximum_msat,
378+
htlc_maximum_rgb: 0, // unused message in RLN, so this value is irrelevant
378379
fee_base_msat: default_fee_base_msat,
379380
fee_proportional_millionths: default_fee_proportional_millionths,
380381
excess_data: Vec::new(),

lightning-types/src/payment.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,13 @@ impl_fmt_traits! {
3737
}
3838
}
3939

40+
impl PaymentHash {
41+
/// Create a payment hash consisting of all-zeros data (e.g. when uninitialized or a placeholder).
42+
pub fn new_zero() -> Self {
43+
Self([0; 32])
44+
}
45+
}
46+
4047
/// The payment preimage is the "secret key" which is used to claim the funds of an HTLC on-chain
4148
/// or in a lightning channel.
4249
///

lightning-types/src/routing.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,6 @@ pub struct RouteHintHop {
4747
pub htlc_minimum_msat: Option<u64>,
4848
/// The maximum value in msat available for routing with a single HTLC.
4949
pub htlc_maximum_msat: Option<u64>,
50+
/// The maximum RGB value available for routing with a single HTLC.
51+
pub htlc_maximum_rgb: Option<u64>,
5052
}

lightning/Cargo.toml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,21 @@ backtrace = { version = "0.3", optional = true }
5151

5252
libm = { version = "0.2", optional = true, default-features = false }
5353

54+
# RGB and related
55+
futures = "0.3"
56+
rgb-lib = { version = "0.3.0-alpha.11", features = [
57+
"electrum",
58+
"esplora",
59+
], git = "https://github.com/RGB-Tools/rgb-lib.git", rev = "952cd185" }
60+
serde = { version = "^1.0", features = [
61+
"derive",
62+
] }
63+
serde_json = "^1.0"
64+
tokio = { version = "1.14.1", features = [
65+
"macros",
66+
"rt-multi-thread",
67+
] }
68+
5469
[dev-dependencies]
5570
regex = "1.5.6"
5671
lightning-types = { version = "0.1.0", path = "../lightning-types", features = ["_test_utils"] }

0 commit comments

Comments
 (0)