Skip to content

Commit 9494b65

Browse files
fixup: Refactor LSPS5 handlers and LiquidityManager to use generic TimeProvider instead of dyn trait
1 parent 34f4e16 commit 9494b65

File tree

3 files changed

+81
-45
lines changed

3 files changed

+81
-45
lines changed

lightning-liquidity/src/lsps5/client.rs

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -83,18 +83,24 @@ impl Default for LSPS5ClientConfig {
8383
}
8484
}
8585

86-
struct PeerState {
86+
struct PeerState<TP: Deref>
87+
where
88+
TP::Target: TimeProvider,
89+
{
8790
pending_set_webhook_requests:
8891
HashMap<LSPSRequestId, (LSPS5AppName, LSPS5WebhookUrl, LSPSDateTime)>,
8992
pending_list_webhooks_requests: HashMap<LSPSRequestId, LSPSDateTime>,
9093
pending_remove_webhook_requests: HashMap<LSPSRequestId, (LSPS5AppName, LSPSDateTime)>,
9194
last_cleanup: Option<LSPSDateTime>,
9295
max_age_secs: Duration,
93-
time_provider: Arc<dyn TimeProvider>,
96+
time_provider: TP,
9497
}
9598

96-
impl PeerState {
97-
fn new(max_age_secs: Duration, time_provider: Arc<dyn TimeProvider>) -> Self {
99+
impl<TP: Deref> PeerState<TP>
100+
where
101+
TP::Target: TimeProvider,
102+
{
103+
fn new(max_age_secs: Duration, time_provider: TP) -> Self {
98104
Self {
99105
pending_set_webhook_requests: new_hash_map(),
100106
pending_list_webhooks_requests: new_hash_map(),
@@ -148,27 +154,29 @@ impl PeerState {
148154
/// [`lsps5.set_webhook`]: super::msgs::LSPS5Request::SetWebhook
149155
/// [`lsps5.list_webhooks`]: super::msgs::LSPS5Request::ListWebhooks
150156
/// [`lsps5.remove_webhook`]: super::msgs::LSPS5Request::RemoveWebhook
151-
pub struct LSPS5ClientHandler<ES: Deref>
157+
pub struct LSPS5ClientHandler<ES: Deref, TP: Deref + Clone>
152158
where
153159
ES::Target: EntropySource,
160+
TP::Target: TimeProvider,
154161
{
155162
pending_messages: Arc<MessageQueue>,
156163
pending_events: Arc<EventQueue>,
157164
entropy_source: ES,
158-
per_peer_state: RwLock<HashMap<PublicKey, Mutex<PeerState>>>,
165+
per_peer_state: RwLock<HashMap<PublicKey, Mutex<PeerState<TP>>>>,
159166
config: LSPS5ClientConfig,
160-
time_provider: Arc<dyn TimeProvider>,
167+
time_provider: TP,
161168
recent_signatures: Mutex<VecDeque<(String, LSPSDateTime)>>,
162169
}
163170

164-
impl<ES: Deref> LSPS5ClientHandler<ES>
171+
impl<ES: Deref, TP: Deref + Clone> LSPS5ClientHandler<ES, TP>
165172
where
166173
ES::Target: EntropySource,
174+
TP::Target: TimeProvider,
167175
{
168176
/// Constructs an `LSPS5ClientHandler`.
169177
pub(crate) fn new(
170178
entropy_source: ES, pending_messages: Arc<MessageQueue>, pending_events: Arc<EventQueue>,
171-
config: LSPS5ClientConfig, time_provider: Arc<dyn TimeProvider>,
179+
config: LSPS5ClientConfig, time_provider: TP,
172180
) -> Self {
173181
let max_signatures = config.signature_config.max_signatures.clone();
174182
Self {
@@ -184,11 +192,11 @@ where
184192

185193
fn with_peer_state<F, R>(&self, counterparty_node_id: PublicKey, f: F) -> R
186194
where
187-
F: FnOnce(&mut PeerState) -> R,
195+
F: FnOnce(&mut PeerState<TP>) -> R,
188196
{
189197
let mut outer_state_lock = self.per_peer_state.write().unwrap();
190198
let inner_state_lock = outer_state_lock.entry(counterparty_node_id).or_insert(Mutex::new(
191-
PeerState::new(self.config.response_max_age_secs, Arc::clone(&self.time_provider)),
199+
PeerState::new(self.config.response_max_age_secs, self.time_provider.clone()),
192200
));
193201
let mut peer_state_lock = inner_state_lock.lock().unwrap();
194202

@@ -349,7 +357,7 @@ where
349357
action: ErrorAction::IgnoreAndLog(Level::Error),
350358
});
351359
let event_queue_notifier = self.pending_events.notifier();
352-
let handle_response = |peer_state: &mut PeerState| {
360+
let handle_response = |peer_state: &mut PeerState<TP>| {
353361
if let Some((app_name, webhook_url, _)) =
354362
peer_state.pending_set_webhook_requests.remove(&request_id)
355363
{
@@ -548,9 +556,10 @@ where
548556
}
549557
}
550558

551-
impl<ES: Deref> LSPSProtocolMessageHandler for LSPS5ClientHandler<ES>
559+
impl<ES: Deref, TP: Deref + Clone> LSPSProtocolMessageHandler for LSPS5ClientHandler<ES, TP>
552560
where
553561
ES::Target: EntropySource,
562+
TP::Target: TimeProvider,
554563
{
555564
type ProtocolMessage = LSPS5Message;
556565
const PROTOCOL_NUMBER: Option<u16> = Some(5);

lightning-liquidity/src/lsps5/service.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ struct StoredWebhook {
5757
///
5858
/// This trait is used to provide the current time for LSPS5 service operations
5959
/// and to convert between timestamps and durations.
60-
pub trait TimeProvider: Send + Sync {
60+
pub trait TimeProvider {
6161
/// Get the current time as a duration since the Unix epoch.
6262
fn duration_since_epoch(&self) -> Duration;
6363
}
@@ -127,27 +127,29 @@ pub struct LSPS5ServiceConfig {
127127
/// [`LSPS5ServiceEvent::SendWebhookNotification`]: super::event::LSPS5ServiceEvent::SendWebhookNotification
128128
/// [`app_name`]: super::msgs::LSPS5AppName
129129
/// [`lsps5.webhook_registered`]: super::msgs::WebhookNotificationMethod::LSPS5WebhookRegistered
130-
pub struct LSPS5ServiceHandler<CM: Deref>
130+
pub struct LSPS5ServiceHandler<CM: Deref, TP: Deref>
131131
where
132132
CM::Target: AChannelManager,
133+
TP::Target: TimeProvider,
133134
{
134135
config: LSPS5ServiceConfig,
135136
webhooks: Mutex<HashMap<PublicKey, HashMap<LSPS5AppName, StoredWebhook>>>,
136137
event_queue: Arc<EventQueue>,
137138
pending_messages: Arc<MessageQueue>,
138-
time_provider: Arc<dyn TimeProvider>,
139+
time_provider: TP,
139140
channel_manager: CM,
140141
last_pruning: Mutex<Option<LSPSDateTime>>,
141142
}
142143

143-
impl<CM: Deref> LSPS5ServiceHandler<CM>
144+
impl<CM: Deref, TP: Deref> LSPS5ServiceHandler<CM, TP>
144145
where
145146
CM::Target: AChannelManager,
147+
TP::Target: TimeProvider,
146148
{
147149
/// Constructs a `LSPS5ServiceHandler`.
148150
pub(crate) fn new(
149151
event_queue: Arc<EventQueue>, pending_messages: Arc<MessageQueue>, channel_manager: CM,
150-
config: LSPS5ServiceConfig, time_provider: Arc<dyn TimeProvider>,
152+
config: LSPS5ServiceConfig, time_provider: TP,
151153
) -> Self {
152154
assert!(config.max_webhooks_per_client > 0, "`max_webhooks_per_client` must be > 0");
153155
Self {
@@ -494,9 +496,10 @@ where
494496
}
495497
}
496498

497-
impl<CM: Deref> LSPSProtocolMessageHandler for LSPS5ServiceHandler<CM>
499+
impl<CM: Deref, TP: Deref> LSPSProtocolMessageHandler for LSPS5ServiceHandler<CM, TP>
498500
where
499501
CM::Target: AChannelManager,
502+
TP::Target: TimeProvider,
500503
{
501504
type ProtocolMessage = LSPS5Message;
502505
const PROTOCOL_NUMBER: Option<u16> = Some(5);

lightning-liquidity/src/manager.rs

Lines changed: 50 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -94,24 +94,31 @@ pub trait ALiquidityManager {
9494
type Filter: Filter + ?Sized;
9595
/// A type that may be dereferenced to [`Self::Filter`].
9696
type C: Deref<Target = Self::Filter> + Clone;
97+
/// A type implementing [`TimeProvider`].
98+
type TimeProvider: TimeProvider + ?Sized;
99+
/// A type that may be dereferenced to [`Self::TimeProvider`].
100+
type TP: Deref<Target = Self::TimeProvider> + Clone;
97101
/// Returns a reference to the actual [`LiquidityManager`] object.
98-
fn get_lm(&self) -> &LiquidityManager<Self::ES, Self::CM, Self::C>;
102+
fn get_lm(&self) -> &LiquidityManager<Self::ES, Self::CM, Self::C, Self::TP>;
99103
}
100104

101-
impl<ES: Deref + Clone, CM: Deref + Clone, C: Deref + Clone> ALiquidityManager
102-
for LiquidityManager<ES, CM, C>
105+
impl<ES: Deref + Clone, CM: Deref + Clone, C: Deref + Clone, TP: Deref + Clone> ALiquidityManager
106+
for LiquidityManager<ES, CM, C, TP>
103107
where
104108
ES::Target: EntropySource,
105109
CM::Target: AChannelManager,
106110
C::Target: Filter,
111+
TP::Target: TimeProvider,
107112
{
108113
type EntropySource = ES::Target;
109114
type ES = ES;
110115
type AChannelManager = CM::Target;
111116
type CM = CM;
112117
type Filter = C::Target;
113118
type C = C;
114-
fn get_lm(&self) -> &LiquidityManager<ES, CM, C> {
119+
type TimeProvider = TP::Target;
120+
type TP = TP;
121+
fn get_lm(&self) -> &LiquidityManager<ES, CM, C, TP> {
115122
self
116123
}
117124
}
@@ -135,11 +142,16 @@ where
135142
/// [`Event::ChannelReady`]: lightning::events::Event::ChannelReady
136143
/// [`Event::HTLCHandlingFailed`]: lightning::events::Event::HTLCHandlingFailed
137144
/// [`Event::PaymentForwarded`]: lightning::events::Event::PaymentForwarded
138-
pub struct LiquidityManager<ES: Deref + Clone, CM: Deref + Clone, C: Deref + Clone>
139-
where
145+
pub struct LiquidityManager<
146+
ES: Deref + Clone,
147+
CM: Deref + Clone,
148+
C: Deref + Clone,
149+
TP: Deref + Clone,
150+
> where
140151
ES::Target: EntropySource,
141152
CM::Target: AChannelManager,
142153
C::Target: Filter,
154+
TP::Target: TimeProvider,
143155
{
144156
pending_messages: Arc<MessageQueue>,
145157
pending_events: Arc<EventQueue>,
@@ -153,25 +165,23 @@ where
153165
lsps1_client_handler: Option<LSPS1ClientHandler<ES>>,
154166
lsps2_service_handler: Option<LSPS2ServiceHandler<CM>>,
155167
lsps2_client_handler: Option<LSPS2ClientHandler<ES>>,
156-
lsps5_service_handler: Option<LSPS5ServiceHandler<CM>>,
157-
lsps5_client_handler: Option<LSPS5ClientHandler<ES>>,
168+
lsps5_service_handler: Option<LSPS5ServiceHandler<CM, TP>>,
169+
lsps5_client_handler: Option<LSPS5ClientHandler<ES, TP>>,
158170
service_config: Option<LiquidityServiceConfig>,
159171
_client_config: Option<LiquidityClientConfig>,
160172
best_block: RwLock<Option<BestBlock>>,
161173
_chain_source: Option<C>,
162174
}
163175

164-
impl<ES: Deref + Clone, CM: Deref + Clone, C: Deref + Clone> LiquidityManager<ES, CM, C>
176+
#[cfg(feature = "time")]
177+
impl<ES: Deref + Clone, CM: Deref + Clone, C: Deref + Clone>
178+
LiquidityManager<ES, CM, C, Arc<DefaultTimeProvider>>
165179
where
166180
ES::Target: EntropySource,
167181
CM::Target: AChannelManager,
168182
C::Target: Filter,
169183
{
170-
/// Constructor for the [`LiquidityManager`].
171-
///
172-
/// Sets up the required protocol message handlers based on the given
173-
/// [`LiquidityClientConfig`] and [`LiquidityServiceConfig`].
174-
#[cfg(feature = "time")]
184+
/// Constructor for the [`LiquidityManager`] using the default system clock
175185
pub fn new(
176186
entropy_source: ES, channel_manager: CM, chain_source: Option<C>,
177187
chain_params: Option<ChainParameters>, service_config: Option<LiquidityServiceConfig>,
@@ -188,7 +198,16 @@ where
188198
time_provider,
189199
)
190200
}
201+
}
191202

203+
impl<ES: Deref + Clone, CM: Deref + Clone, C: Deref + Clone, TP: Deref + Clone>
204+
LiquidityManager<ES, CM, C, TP>
205+
where
206+
ES::Target: EntropySource,
207+
CM::Target: AChannelManager,
208+
C::Target: Filter,
209+
TP::Target: TimeProvider,
210+
{
192211
/// Constructor for the [`LiquidityManager`] with a custom time provider.
193212
///
194213
/// This should be used on non-std platforms where access to the system time is not
@@ -198,9 +217,8 @@ where
198217
pub fn new_with_custom_time_provider(
199218
entropy_source: ES, channel_manager: CM, chain_source: Option<C>,
200219
chain_params: Option<ChainParameters>, service_config: Option<LiquidityServiceConfig>,
201-
client_config: Option<LiquidityClientConfig>, time_provider: Arc<dyn TimeProvider>,
202-
) -> Self
203-
where {
220+
client_config: Option<LiquidityClientConfig>, time_provider: TP,
221+
) -> Self {
204222
let pending_messages = Arc::new(MessageQueue::new());
205223
let pending_events = Arc::new(EventQueue::new());
206224
let ignored_peers = RwLock::new(new_hash_set());
@@ -248,7 +266,7 @@ where {
248266
let lsps5_service_handler = service_config.as_ref().and_then(|config| {
249267
config.lsps5_service_config.as_ref().map(|config| {
250268
if let Some(number) =
251-
<LSPS5ServiceHandler<CM> as LSPSProtocolMessageHandler>::PROTOCOL_NUMBER
269+
<LSPS5ServiceHandler<CM, TP> as LSPSProtocolMessageHandler>::PROTOCOL_NUMBER
252270
{
253271
supported_protocols.push(number);
254272
}
@@ -369,14 +387,14 @@ where {
369387
/// Returns a reference to the LSPS5 client-side handler.
370388
///
371389
/// The returned hendler allows to initiate the LSPS5 client-side flow. That is, it allows to
372-
pub fn lsps5_client_handler(&self) -> Option<&LSPS5ClientHandler<ES>> {
390+
pub fn lsps5_client_handler(&self) -> Option<&LSPS5ClientHandler<ES, TP>> {
373391
self.lsps5_client_handler.as_ref()
374392
}
375393

376394
/// Returns a reference to the LSPS5 server-side handler.
377395
///
378396
/// The returned hendler allows to initiate the LSPS5 service-side flow.
379-
pub fn lsps5_service_handler(&self) -> Option<&LSPS5ServiceHandler<CM>> {
397+
pub fn lsps5_service_handler(&self) -> Option<&LSPS5ServiceHandler<CM, TP>> {
380398
self.lsps5_service_handler.as_ref()
381399
}
382400

@@ -530,12 +548,13 @@ where {
530548
}
531549
}
532550

533-
impl<ES: Deref + Clone + Clone, CM: Deref + Clone, C: Deref + Clone> CustomMessageReader
534-
for LiquidityManager<ES, CM, C>
551+
impl<ES: Deref + Clone, CM: Deref + Clone, C: Deref + Clone, TP: Deref + Clone> CustomMessageReader
552+
for LiquidityManager<ES, CM, C, TP>
535553
where
536554
ES::Target: EntropySource,
537555
CM::Target: AChannelManager,
538556
C::Target: Filter,
557+
TP::Target: TimeProvider,
539558
{
540559
type CustomMessage = RawLSPSMessage;
541560

@@ -551,12 +570,13 @@ where
551570
}
552571
}
553572

554-
impl<ES: Deref + Clone, CM: Deref + Clone, C: Deref + Clone> CustomMessageHandler
555-
for LiquidityManager<ES, CM, C>
573+
impl<ES: Deref + Clone, CM: Deref + Clone, C: Deref + Clone, TP: Deref + Clone> CustomMessageHandler
574+
for LiquidityManager<ES, CM, C, TP>
556575
where
557576
ES::Target: EntropySource,
558577
CM::Target: AChannelManager,
559578
C::Target: Filter,
579+
TP::Target: TimeProvider,
560580
{
561581
fn handle_custom_message(
562582
&self, msg: Self::CustomMessage, sender_node_id: PublicKey,
@@ -663,11 +683,13 @@ where
663683
}
664684
}
665685

666-
impl<ES: Deref + Clone, CM: Deref + Clone, C: Deref + Clone> Listen for LiquidityManager<ES, CM, C>
686+
impl<ES: Deref + Clone, CM: Deref + Clone, C: Deref + Clone, TP: Deref + Clone> Listen
687+
for LiquidityManager<ES, CM, C, TP>
667688
where
668689
ES::Target: EntropySource,
669690
CM::Target: AChannelManager,
670691
C::Target: Filter,
692+
TP::Target: TimeProvider,
671693
{
672694
fn filtered_block_connected(
673695
&self, header: &bitcoin::block::Header, txdata: &chain::transaction::TransactionData,
@@ -700,11 +722,13 @@ where
700722
}
701723
}
702724

703-
impl<ES: Deref + Clone, CM: Deref + Clone, C: Deref + Clone> Confirm for LiquidityManager<ES, CM, C>
725+
impl<ES: Deref + Clone, CM: Deref + Clone, C: Deref + Clone, TP: Deref + Clone> Confirm
726+
for LiquidityManager<ES, CM, C, TP>
704727
where
705728
ES::Target: EntropySource,
706729
CM::Target: AChannelManager,
707730
C::Target: Filter,
731+
TP::Target: TimeProvider,
708732
{
709733
fn transactions_confirmed(
710734
&self, _header: &bitcoin::block::Header, _txdata: &chain::transaction::TransactionData,

0 commit comments

Comments
 (0)