@@ -83,11 +83,15 @@ where
8383
8484 /// Requests the LSP to register the node.
8585 ///
86+ /// `fee_claim` is an optional lowercase-hex signed grant for a non-standard fee policy; the LSP
87+ /// verifies it against its configured issuer keys. `None` (or an unverifiable claim) leaves the
88+ /// node on the standard policy.
89+ ///
8690 /// The user will receive the LSP's response via an [`InvoiceParametersReady`] event.
8791 ///
8892 /// [`InvoiceParametersReady`]: crate::lsps4::event::LSPS4ClientEvent::InvoiceParametersReady
8993 pub fn register_node (
90- & self , counterparty_node_id : PublicKey
94+ & self , counterparty_node_id : PublicKey , fee_claim : Option < String > ,
9195 ) -> Result < LSPSRequestId , APIError > {
9296 let request_id = crate :: utils:: generate_request_id ( & self . entropy_source ) ;
9397
@@ -109,7 +113,7 @@ where
109113 }
110114 }
111115
112- let request = LSPS4Request :: RegisterNode ( RegisterNodeRequest { fee_claim : None } ) ;
116+ let request = LSPS4Request :: RegisterNode ( RegisterNodeRequest { fee_claim } ) ;
113117 let msg = LSPS4Message :: Request ( request_id. clone ( ) , request) . into ( ) ;
114118 let mut message_queue_notifier = self . pending_messages . notifier ( ) ;
115119 message_queue_notifier. enqueue ( & counterparty_node_id, msg) ;
@@ -199,4 +203,72 @@ where
199203}
200204
201205#[ cfg( test) ]
202- mod tests { }
206+ mod tests {
207+ use super :: * ;
208+ use crate :: lsps0:: ser:: LSPSMessage ;
209+ use bitcoin:: secp256k1:: { Secp256k1 , SecretKey } ;
210+ use core:: sync:: atomic:: { AtomicU64 , Ordering } ;
211+ use lightning:: util:: persist:: KVStoreSyncWrapper ;
212+ use lightning:: util:: test_utils:: TestStore ;
213+ use lightning:: util:: wakers:: Notifier ;
214+ use std:: collections:: VecDeque ;
215+
216+ struct CountingEntropy {
217+ counter : AtomicU64 ,
218+ }
219+
220+ impl EntropySource for CountingEntropy {
221+ fn get_secure_random_bytes ( & self ) -> [ u8 ; 32 ] {
222+ let counter = self . counter . fetch_add ( 1 , Ordering :: SeqCst ) ;
223+ let mut bytes = [ 0u8 ; 32 ] ;
224+ bytes[ 0 ..8 ] . copy_from_slice ( & counter. to_be_bytes ( ) ) ;
225+ bytes
226+ }
227+ }
228+
229+ type TestKVStore = Arc < KVStoreSyncWrapper < Arc < TestStore > > > ;
230+
231+ fn setup ( ) -> ( LSPS4ClientHandler < Arc < CountingEntropy > , TestKVStore > , Arc < MessageQueue > , PublicKey )
232+ {
233+ let entropy = Arc :: new ( CountingEntropy { counter : AtomicU64 :: new ( 1 ) } ) ;
234+ let message_queue = Arc :: new ( MessageQueue :: new ( Arc :: new ( Notifier :: new ( ) ) ) ) ;
235+ let kv_store = Arc :: new ( KVStoreSyncWrapper ( Arc :: new ( TestStore :: new ( false ) ) ) ) ;
236+ let event_queue =
237+ Arc :: new ( EventQueue :: new ( VecDeque :: new ( ) , kv_store, Arc :: new ( Notifier :: new ( ) ) ) ) ;
238+ let client = LSPS4ClientHandler :: new (
239+ entropy,
240+ Arc :: clone ( & message_queue) ,
241+ event_queue,
242+ LSPS4ClientConfig :: default ( ) ,
243+ ) ;
244+ let peer = PublicKey :: from_secret_key ( & Secp256k1 :: new ( ) , & SecretKey :: from_slice ( & [ 42u8 ; 32 ] ) . unwrap ( ) ) ;
245+ ( client, message_queue, peer)
246+ }
247+
248+ /// The single enqueued message must be a `register_node` request; returns its `fee_claim`.
249+ fn sole_request_fee_claim ( message_queue : & MessageQueue ) -> Option < String > {
250+ let mut pending = message_queue. get_and_clear_pending_msgs ( ) ;
251+ assert_eq ! ( pending. len( ) , 1 ) ;
252+ match pending. pop ( ) . unwrap ( ) . 1 {
253+ LSPSMessage :: LSPS4 ( LSPS4Message :: Request ( _, LSPS4Request :: RegisterNode ( req) ) ) => {
254+ req. fee_claim
255+ } ,
256+ other => panic ! ( "expected a register_node request, got {:?}" , other) ,
257+ }
258+ }
259+
260+ #[ test]
261+ fn register_node_carries_the_claim ( ) {
262+ let ( client, message_queue, peer) = setup ( ) ;
263+ let claim = "deadbeef" . to_string ( ) ;
264+ client. register_node ( peer, Some ( claim. clone ( ) ) ) . unwrap ( ) ;
265+ assert_eq ! ( sole_request_fee_claim( & message_queue) , Some ( claim) ) ;
266+ }
267+
268+ #[ test]
269+ fn register_node_without_a_claim_omits_it ( ) {
270+ let ( client, message_queue, peer) = setup ( ) ;
271+ client. register_node ( peer, None ) . unwrap ( ) ;
272+ assert_eq ! ( sole_request_fee_claim( & message_queue) , None ) ;
273+ }
274+ }
0 commit comments