Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ log = { version = "0.4.22", default-features = false, features = ["std"]}

vss-client = "0.3"
prost = { version = "0.11.6", default-features = false}
bitcoin-payment-instructions = { version = "0.5" }
lightning-dns-resolver = "0.2.0"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add this above to the group(s) of lightning-* imports (also the commented-out ones) and follow the scheme there.


[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = ["winbase"] }
Expand Down
13 changes: 8 additions & 5 deletions bindings/ldk_node.udl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ dictionary Config {
u64 probing_liquidity_limit_multiplier;
AnchorChannelsConfig? anchor_channels_config;
SendingParameters? sending_parameters;
boolean is_hrn_resolver;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I think over at the first PR we discussed to introduce a dedicated config for HRN-related things, also to specify default resolvers, for example? Probably this should be part of such a config?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes we did - I'll re-introduce the dedicated config for HRN-related things.

};

dictionary AnchorChannelsConfig {
Expand Down Expand Up @@ -127,7 +128,7 @@ interface Node {
Bolt12Payment bolt12_payment();
SpontaneousPayment spontaneous_payment();
OnchainPayment onchain_payment();
UnifiedQrPayment unified_qr_payment();
UnifiedPayment unified_payment();
LSPS1Liquidity lsps1_liquidity();
[Throws=NodeError]
void connect(PublicKey node_id, SocketAddress address, boolean persist);
Expand Down Expand Up @@ -243,11 +244,11 @@ interface FeeRate {
u64 to_sat_per_vb_ceil();
};

interface UnifiedQrPayment {
interface UnifiedPayment {
[Throws=NodeError]
string receive(u64 amount_sats, [ByRef]string message, u32 expiry_sec);
[Throws=NodeError]
QrPaymentResult send([ByRef]string uri_str);
[Throws=NodeError, Async]
UnifiedPaymentResult send([ByRef]string uri_str, u64? amount_msat);
};

interface LSPS1Liquidity {
Expand Down Expand Up @@ -311,6 +312,7 @@ enum NodeError {
"InsufficientFunds",
"LiquiditySourceUnavailable",
"LiquidityFeeTooHigh",
"HrnResolverNotConfigured",
};

dictionary NodeStatus {
Expand Down Expand Up @@ -347,6 +349,7 @@ enum BuildError {
"WalletSetupFailed",
"LoggerSetupFailed",
"NetworkMismatch",
"DNSResolverSetupFailed",
};

[Trait]
Expand Down Expand Up @@ -418,7 +421,7 @@ interface PaymentKind {
};

[Enum]
interface QrPaymentResult {
interface UnifiedPaymentResult {
Onchain(Txid txid);
Bolt11(PaymentId payment_id);
Bolt12(PaymentId payment_id);
Expand Down
51 changes: 48 additions & 3 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ use crate::peer_store::PeerStore;
use crate::runtime::Runtime;
use crate::tx_broadcaster::TransactionBroadcaster;
use crate::types::{
ChainMonitor, ChannelManager, DynStore, GossipSync, Graph, KeysManager, MessageRouter,
OnionMessenger, PaymentStore, PeerManager,
ChainMonitor, ChannelManager, DomainResolver, DynStore, GossipSync, Graph, HRNResolver,
KeysManager, MessageRouter, OnionMessenger, PaymentStore, PeerManager,
};
use crate::wallet::persist::KVStoreWalletPersister;
use crate::wallet::Wallet;
Expand All @@ -43,6 +43,7 @@ use lightning::io::Cursor;
use lightning::ln::channelmanager::{self, ChainParameters, ChannelManagerReadArgs};
use lightning::ln::msgs::{RoutingMessageHandler, SocketAddress};
use lightning::ln::peer_handler::{IgnoringMessageHandler, MessageHandler};
use lightning::onion_message::dns_resolution::DNSResolverMessageHandler;
use lightning::routing::gossip::NodeAlias;
use lightning::routing::router::DefaultRouter;
use lightning::routing::scoring::{
Expand All @@ -59,6 +60,8 @@ use lightning::util::sweep::OutputSweeper;

use lightning_persister::fs_store::FilesystemStore;

use lightning_dns_resolver::OMDomainResolver;

use bdk_wallet::template::Bip84;
use bdk_wallet::KeychainKind;
use bdk_wallet::Wallet as BdkWallet;
Expand All @@ -80,6 +83,8 @@ use std::sync::{Arc, Mutex, Once, RwLock};
use std::time::SystemTime;
use vss_client::headers::{FixedHeaders, LnurlAuthToJwtProvider, VssHeaderProvider};

use bitcoin_payment_instructions::onion_message_resolver::LDKOnionMessageDNSSECHrnResolver;

const VSS_HARDENED_CHILD_INDEX: u32 = 877;
const VSS_LNURL_AUTH_HARDENED_CHILD_INDEX: u32 = 138;
const LSPS_HARDENED_CHILD_INDEX: u32 = 577;
Expand Down Expand Up @@ -191,6 +196,8 @@ pub enum BuildError {
LoggerSetupFailed,
/// The given network does not match the node's previously configured network.
NetworkMismatch,
/// An attempt to setup a DNS Resolver failed.
DNSResolverSetupFailed,
}

impl fmt::Display for BuildError {
Expand Down Expand Up @@ -219,12 +226,20 @@ impl fmt::Display for BuildError {
Self::NetworkMismatch => {
write!(f, "Given network does not match the node's previously configured network.")
},
Self::DNSResolverSetupFailed => {
write!(f, "An attempt to setup a DNS resolver has failed.")
},
}
}
}

impl std::error::Error for BuildError {}

enum Resolver {
HRN(Arc<HRNResolver>),
DNS(Arc<DomainResolver>),
}

/// A builder for an [`Node`] instance, allowing to set some configuration and module choices from
/// the getgo.
///
Expand Down Expand Up @@ -1454,6 +1469,23 @@ fn build_with_store_internal(
})?;
}

let resolver = if config.is_hrn_resolver {
Resolver::DNS(Arc::new(OMDomainResolver::ignoring_incoming_proofs(
"8.8.8.8:53".parse().map_err(|_| BuildError::DNSResolverSetupFailed)?,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably want to make the DNS server used configurable via the config?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes that makes sense - will do.

)))
} else {
Resolver::HRN(Arc::new(LDKOnionMessageDNSSECHrnResolver::new(Arc::clone(&network_graph))))
};

let om_resolver = match resolver {
Resolver::DNS(ref dns_resolver) => {
Arc::clone(dns_resolver) as Arc<dyn DNSResolverMessageHandler + Send + Sync>
},
Resolver::HRN(ref hrn_resolver) => {
Arc::clone(hrn_resolver) as Arc<dyn DNSResolverMessageHandler + Send + Sync>
},
};

// Initialize the PeerManager
let onion_messenger: Arc<OnionMessenger> = Arc::new(OnionMessenger::new(
Arc::clone(&keys_manager),
Expand All @@ -1463,7 +1495,7 @@ fn build_with_store_internal(
message_router,
Arc::clone(&channel_manager),
IgnoringMessageHandler {},
IgnoringMessageHandler {},
Arc::clone(&om_resolver),
IgnoringMessageHandler {},
));
let ephemeral_bytes: [u8; 32] = keys_manager.get_secure_random_bytes();
Expand Down Expand Up @@ -1589,6 +1621,18 @@ fn build_with_store_internal(
Arc::clone(&keys_manager),
));

let peer_manager_clone = Arc::clone(&peer_manager);

let hrn_resolver = match resolver {
Resolver::DNS(_) => None,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh, so if we're resolving for others, we won't be able to send to HRNs ourselves?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From my understanding, it seems this is the case. The onion messenger can take only one type of dns_resolver at a time - either the one sending out the query or the one handling the query and responding with the proof. If our node is configured to resolve for others, we'd have to pass the appropriate resolver to the onion messenger, preventing us from sending to HRNs ourselves.

Resolver::HRN(ref hrn_resolver) => {
hrn_resolver.register_post_queue_action(Box::new(move || {
peer_manager_clone.process_events();
}));
Some(hrn_resolver)
},
};

liquidity_source.as_ref().map(|l| l.set_peer_manager(Arc::clone(&peer_manager)));

gossip_source.set_gossip_verifier(
Expand Down Expand Up @@ -1696,6 +1740,7 @@ fn build_with_store_internal(
is_running,
is_listening,
node_metrics,
hrn_resolver: hrn_resolver.cloned(),
})
}

Expand Down
4 changes: 4 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ pub const WALLET_KEYS_SEED_LEN: usize = 64;
/// | `log_level` | Debug |
/// | `anchor_channels_config` | Some(..) |
/// | `sending_parameters` | None |
/// | `is_hrn_resolver` | false |
///
/// See [`AnchorChannelsConfig`] and [`SendingParameters`] for more information regarding their
/// respective default values.
Expand Down Expand Up @@ -179,6 +180,8 @@ pub struct Config {
/// **Note:** If unset, default parameters will be used, and you will be able to override the
/// parameters on a per-payment basis in the corresponding method calls.
pub sending_parameters: Option<SendingParameters>,
/// This allows us to use our node as a DNS resolver for 3rd party HRN resolutions.
pub is_hrn_resolver: bool,
}

impl Default for Config {
Expand All @@ -193,6 +196,7 @@ impl Default for Config {
anchor_channels_config: Some(AnchorChannelsConfig::default()),
sending_parameters: None,
node_alias: None,
is_hrn_resolver: false,
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ pub enum Error {
LiquiditySourceUnavailable,
/// The given operation failed due to the LSP's required opening fee being too high.
LiquidityFeeTooHigh,
/// A HRN resolver was not configured
HrnResolverNotConfigured,
}

impl fmt::Display for Error {
Expand Down Expand Up @@ -193,6 +195,9 @@ impl fmt::Display for Error {
Self::LiquidityFeeTooHigh => {
write!(f, "The given operation failed due to the LSP's required opening fee being too high.")
},
Self::HrnResolverNotConfigured => {
write!(f, "A HRN resolver was not configured.")
},
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/ffi/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub use crate::logger::{LogLevel, LogRecord, LogWriter};
pub use crate::payment::store::{
ConfirmationStatus, LSPFeeLimits, PaymentDirection, PaymentKind, PaymentStatus,
};
pub use crate::payment::{MaxTotalRoutingFeeLimit, QrPaymentResult, SendingParameters};
pub use crate::payment::{MaxTotalRoutingFeeLimit, SendingParameters, UnifiedPaymentResult};

pub use lightning::chain::channelmonitor::BalanceSource;
pub use lightning::events::{ClosureReason, PaymentFailureReason};
Expand Down
24 changes: 18 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,13 +139,14 @@ use io::utils::write_node_metrics;
use liquidity::{LSPS1Liquidity, LiquiditySource};
use payment::{
Bolt11Payment, Bolt12Payment, OnchainPayment, PaymentDetails, SpontaneousPayment,
UnifiedQrPayment,
UnifiedPayment,
};
use peer_store::{PeerInfo, PeerStore};
use runtime::Runtime;
use types::{
Broadcaster, BumpTransactionEventHandler, ChainMonitor, ChannelManager, DynStore, Graph,
KeysManager, OnionMessenger, PaymentStore, PeerManager, Router, Scorer, Sweeper, Wallet,
HRNResolver, KeysManager, OnionMessenger, PaymentStore, PeerManager, Router, Scorer, Sweeper,
Wallet,
};
pub use types::{ChannelDetails, CustomTlvRecord, PeerDetails, UserChannelId};

Expand Down Expand Up @@ -205,6 +206,7 @@ pub struct Node {
is_running: Arc<RwLock<bool>>,
is_listening: Arc<AtomicBool>,
node_metrics: Arc<RwLock<NodeMetrics>>,
hrn_resolver: Option<Arc<HRNResolver>>,
}

impl Node {
Expand Down Expand Up @@ -466,6 +468,8 @@ impl Node {
if let Some(node_alias) = node_alias.as_ref() {
bcast_pm.broadcast_node_announcement([0; 3], node_alias.0, addresses);

println!("broadcasted announncement");

let unix_time_secs_opt =
SystemTime::now().duration_since(UNIX_EPOCH).ok().map(|d| d.as_secs());
{
Expand Down Expand Up @@ -885,34 +889,42 @@ impl Node {
/// Returns a payment handler allowing to create [BIP 21] URIs with an on-chain, [BOLT 11],
/// and [BOLT 12] payment options.
///
/// This handler allows you to send payments to these URIs as well as [BIP 353] HRNs.
///
/// [BOLT 11]: https://github.com/lightning/bolts/blob/master/11-payment-encoding.md
/// [BOLT 12]: https://github.com/lightning/bolts/blob/master/12-offer-encoding.md
/// [BIP 21]: https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki
/// [BIP 353]: https://github.com/bitcoin/bips/blob/master/bip-0353.mediawiki
#[cfg(not(feature = "uniffi"))]
pub fn unified_qr_payment(&self) -> UnifiedQrPayment {
UnifiedQrPayment::new(
pub fn unified_payment(&self) -> UnifiedPayment {
UnifiedPayment::new(
self.onchain_payment().into(),
self.bolt11_payment().into(),
self.bolt12_payment().into(),
Arc::clone(&self.config),
Arc::clone(&self.logger),
Arc::new(self.hrn_resolver.clone()),
)
}

/// Returns a payment handler allowing to create [BIP 21] URIs with an on-chain, [BOLT 11],
/// and [BOLT 12] payment options.
///
/// This handler allows you to send payments to these URIs as well as [BIP 353] HRNs.
///
/// [BOLT 11]: https://github.com/lightning/bolts/blob/master/11-payment-encoding.md
/// [BOLT 12]: https://github.com/lightning/bolts/blob/master/12-offer-encoding.md
/// [BIP 21]: https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki
/// [BIP 353]: https://github.com/bitcoin/bips/blob/master/bip-0353.mediawiki
#[cfg(feature = "uniffi")]
pub fn unified_qr_payment(&self) -> Arc<UnifiedQrPayment> {
Arc::new(UnifiedQrPayment::new(
pub fn unified_payment(&self) -> Arc<UnifiedPayment> {
Arc::new(UnifiedPayment::new(
self.onchain_payment(),
self.bolt11_payment(),
self.bolt12_payment(),
Arc::clone(&self.config),
Arc::clone(&self.logger),
Arc::new(self.hrn_resolver.clone()),
))
}

Expand Down
4 changes: 2 additions & 2 deletions src/payment/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ mod bolt12;
mod onchain;
mod spontaneous;
pub(crate) mod store;
mod unified_qr;
mod unified;

pub use bolt11::Bolt11Payment;
pub use bolt12::Bolt12Payment;
Expand All @@ -21,7 +21,7 @@ pub use spontaneous::SpontaneousPayment;
pub use store::{
ConfirmationStatus, LSPFeeLimits, PaymentDetails, PaymentDirection, PaymentKind, PaymentStatus,
};
pub use unified_qr::{QrPaymentResult, UnifiedQrPayment};
pub use unified::{UnifiedPayment, UnifiedPaymentResult};

/// Represents information used to send a payment.
#[derive(Clone, Debug, PartialEq)]
Expand Down
Loading
Loading