1
- use std:: ffi:: { CString } ;
2
- use std:: sync:: Arc ;
1
+ use std:: {
2
+ io:: Error ,
3
+ ffi:: { CString } ,
4
+ hash:: { Hasher , Hash } ,
5
+ sync:: Arc
6
+ } ;
3
7
4
8
use bitcoin_hashes:: sha256d:: Hash as Sha256dHash ;
5
- use bitcoin:: blockdata:: transaction:: Transaction ;
6
- use bitcoin:: blockdata:: script:: Script ;
7
- use bitcoin:: blockdata:: block:: Block ;
8
- use bitcoin:: consensus:: serialize as bitcoin_serialize;
9
+ use bitcoin:: {
10
+ blockdata:: transaction:: Transaction ,
11
+ blockdata:: script:: Script ,
12
+ blockdata:: block:: Block ,
13
+ consensus:: serialize as bitcoin_serialize
14
+ } ;
9
15
10
- use lightning:: util:: logger:: { Logger , Record , Level } ;
11
-
12
- use lightning:: chain:: chaininterface:: { BroadcasterInterface , FeeEstimator , ConfirmationTarget , ChainWatchInterface , ChainError } ;
13
- use lightning:: chain:: keysinterface:: { InMemoryChannelKeys } ;
14
- use lightning:: chain:: transaction:: { OutPoint } ;
15
-
16
- use lightning:: ln:: channelmonitor:: { ManyChannelMonitor , ChannelMonitor , HTLCUpdate , ChannelMonitorUpdateErr , ChannelMonitorUpdate } ;
16
+ use lightning:: {
17
+ chain:: transaction:: { OutPoint } ,
18
+ chain:: keysinterface:: { InMemoryChannelKeys } ,
19
+ chain:: chaininterface:: { BroadcasterInterface , FeeEstimator , ConfirmationTarget , ChainWatchInterface , ChainError } ,
20
+ util:: logger:: { Logger , Record , Level } ,
21
+ ln:: channelmonitor:: { ManyChannelMonitor , ChannelMonitor , HTLCUpdate , ChannelMonitorUpdateErr , ChannelMonitorUpdate } ,
22
+ util:: ser:: { Writeable , Writer } ,
23
+ ln:: peer_handler:: SocketDescriptor ,
24
+ ln:: msgs:: ErrorAction
25
+ } ;
17
26
18
27
pub mod primitives;
19
28
use primitives:: * ;
20
- use lightning:: util:: ser:: { Writeable , Writer } ;
21
- use std:: io:: Error ;
29
+ use std:: convert:: TryFrom ;
30
+ use lightning:: ln:: msgs:: { ErrorMessage , RoutingMessageHandler , HTLCFailChannelUpdate , ChannelAnnouncement , NodeAnnouncement , LightningError , ChannelUpdate } ;
31
+ use std:: ffi:: CStr ;
32
+ use std:: ptr:: NonNull ;
33
+
34
+ type cstr = NonNull < i8 > ;
35
+
36
+ #[ derive( PartialOrd , PartialEq , Eq , Ord , Debug , Copy , Clone ) ]
37
+ #[ repr( u8 ) ]
38
+ pub enum Bool { False = 0 , True = 1 }
39
+ impl Bool {
40
+ pub fn to_bool ( & self ) -> bool { * self == Bool :: True }
41
+ }
22
42
23
43
pub mod broadcaster_fn {
24
44
use crate :: adaptors:: primitives:: FFITransaction ;
@@ -135,11 +155,11 @@ pub struct FFILogRecord {
135
155
/// The verbosity level of the message.
136
156
pub level : FFILogLevel ,
137
157
/// The message body.
138
- pub args : * const i8 ,
158
+ pub args : cstr ,
139
159
/// The module path of the message.
140
- pub module_path : * const i8 ,
160
+ pub module_path : cstr ,
141
161
/// The source file containing the message.
142
- pub file : * const i8 ,
162
+ pub file : cstr ,
143
163
/// The line containing the message.
144
164
pub line : u32 ,
145
165
}
@@ -162,9 +182,9 @@ impl Logger for FFILogger {
162
182
let ffi_record =
163
183
FFILogRecord {
164
184
level : rec. level . into ( ) ,
165
- args : args. as_ptr ( ) ,
166
- module_path : module_path. as_ptr ( ) ,
167
- file : file. as_ptr ( ) ,
185
+ args : NonNull :: new ( args. as_ptr ( ) as * mut _ ) . unwrap ( ) ,
186
+ module_path : NonNull :: new ( module_path. as_ptr ( ) as * mut _ ) . unwrap ( ) ,
187
+ file : NonNull :: new ( file. as_ptr ( ) as * mut _ ) . unwrap ( ) ,
168
188
line : rec. line ,
169
189
} ;
170
190
( self . log_ptr ) ( & ffi_record as * const _ ) ;
@@ -226,3 +246,211 @@ impl ChainWatchInterface for FFIChainWatchInterface {
226
246
}
227
247
}
228
248
249
+ pub mod socket_descriptor_fn {
250
+ use super :: FFIBytes ;
251
+ pub type SendData = extern "cdecl" fn ( data : * const FFIBytes , resume_read : u8 ) -> usize ;
252
+ pub type DisconnectSocket = extern "cdecl" fn ( ) ;
253
+ }
254
+
255
+ #[ repr( C ) ]
256
+ #[ derive( Clone ) ]
257
+ pub struct FFISocketDescriptor {
258
+ pub index : usize ,
259
+ pub send_data_ptr : socket_descriptor_fn:: SendData ,
260
+ pub disconnect_socket_ptr : socket_descriptor_fn:: DisconnectSocket ,
261
+ }
262
+
263
+ impl PartialEq for FFISocketDescriptor {
264
+ fn eq ( & self , other : & Self ) -> bool {
265
+ self . index == other. index
266
+ }
267
+ }
268
+ impl Eq for FFISocketDescriptor { }
269
+ impl Hash for FFISocketDescriptor {
270
+ fn hash < H : Hasher > ( & self , state : & mut H ) {
271
+ self . index . hash ( state)
272
+ }
273
+ }
274
+
275
+ impl SocketDescriptor for FFISocketDescriptor {
276
+ fn send_data ( & mut self , data : & [ u8 ] , resume_read : bool ) -> usize {
277
+ let r: FFIBytes = data. into ( ) ;
278
+ ( self . send_data_ptr ) ( & r as * const _ , resume_read as u8 )
279
+ }
280
+
281
+ fn disconnect_socket ( & mut self ) {
282
+ ( self . disconnect_socket_ptr ) ( )
283
+ }
284
+ }
285
+
286
+ #[ repr( u8 ) ]
287
+ #[ derive( Debug , Clone ) ]
288
+ pub enum FFIErrorActionType {
289
+ DisconnectPeer = 0u8 ,
290
+ /// The peer did something harmless that we weren't able to process, just log and ignore
291
+ IgnoreError ,
292
+ /// The peer did something incorrect. Tell them.
293
+ SendErrorMessage ,
294
+ }
295
+
296
+ #[ repr( C ) ]
297
+ #[ derive( Debug , Clone ) ]
298
+ pub struct FFIErrorMsg {
299
+ pub channel_id : [ u8 ; 32 ] ,
300
+ pub data : cstr ,
301
+ }
302
+
303
+ impl From < FFIErrorMsg > for ErrorMessage {
304
+ fn from ( msg : FFIErrorMsg ) -> Self {
305
+ let data = unsafe_block ! ( "We know pointer is non-null" => CStr :: from_ptr( msg. data. as_ptr( ) ) ) ;
306
+ ErrorMessage {
307
+ data : data. to_str ( ) . unwrap ( ) . to_owned ( ) ,
308
+ channel_id : msg. channel_id
309
+ }
310
+ }
311
+ }
312
+
313
+ #[ repr( C ) ]
314
+ #[ derive( Debug , Clone ) ]
315
+ pub struct FFIErrorAction {
316
+ ty : FFIErrorActionType ,
317
+ payload : Option < * const FFIErrorMsg >
318
+ }
319
+
320
+ impl From < FFIErrorAction > for ErrorAction {
321
+ fn from ( x : FFIErrorAction ) -> Self {
322
+ match x. ty {
323
+ FFIErrorActionType :: DisconnectPeer => {
324
+ ErrorAction :: DisconnectPeer {
325
+ msg : x. payload . map ( |msg| {
326
+ From :: from ( unsafe_block ! ( "`from` conversion consumes x" => ( * msg) . clone( ) ) )
327
+ } )
328
+ }
329
+ } ,
330
+ FFIErrorActionType :: IgnoreError => {
331
+ ErrorAction :: IgnoreError
332
+ } ,
333
+ FFIErrorActionType :: SendErrorMessage => {
334
+ match x. payload {
335
+ None => panic ! ( format!( "Inconsistent enum {:?}" , x) ) ,
336
+ Some ( msg) => {
337
+ let msg = unsafe_block ! ( "`from` conversion consumes x" => ( * msg) . clone( ) ) . into ( ) ;
338
+ ErrorAction :: SendErrorMessage { msg }
339
+ }
340
+ }
341
+ }
342
+ }
343
+ }
344
+ }
345
+
346
+ #[ derive( Clone ) ]
347
+ #[ repr( C ) ]
348
+ pub struct FFILightningError {
349
+ /// A human-readable message describing the error
350
+ pub err : cstr ,
351
+ /// The action which should be taken against the offending peer.
352
+ pub action : FFIErrorAction ,
353
+ }
354
+
355
+ impl From < FFILightningError > for LightningError {
356
+ fn from ( v : FFILightningError ) -> Self {
357
+ let err = unsafe_block ! ( "We know error msg is non-null c string" => CStr :: from_ptr( v. err. as_ptr( ) ) ) ;
358
+ LightningError {
359
+ err : err. to_str ( ) . unwrap ( ) ,
360
+ action : v. action . into ( )
361
+ }
362
+ }
363
+ }
364
+
365
+ pub mod routing_msg_descriptor_fn {
366
+ use super :: * ;
367
+ use crate :: adaptors:: primitives:: PublicKey ;
368
+ use lightning:: ln:: msgs:: { NodeAnnouncement , LightningError , ChannelAnnouncement , ChannelUpdate , HTLCFailChannelUpdate } ;
369
+
370
+ /// Handle an incoming node_announcement message, returning true if it should be forwarded on,
371
+ /// false or returning an Err otherwise.
372
+ pub type HandleNodeAnnouncement = extern "cdecl" fn ( msg : * const FFIBytes , error : * mut FFILightningError ) -> Bool ;
373
+ /// Handle a channel_announcement message, returning true if it should be forwarded on, false
374
+ /// or returning an Err otherwise.
375
+ pub type HandleChannelAnnouncement = extern "cdecl" fn ( msg : * const FFIBytes , error : * mut FFILightningError ) -> Bool ;
376
+ /// Handle an incoming channel_update message, returning true if it should be forwarded on,
377
+ /// false or returning an Err otherwise.
378
+ pub type HandleChannelUpdate = extern "cdecl" fn ( msg : * const FFIBytes , error : * mut FFILightningError ) -> Bool ;
379
+ /// Handle some updates to the route graph that we learned due to an outbound failed payment.
380
+ pub type HandleHTLCFailChannelUpdate = extern "cdecl" fn ( update : * const FFIBytes ) ;
381
+ /// Gets a subset of the channel announcements and updates required to dump our routing table
382
+ /// to a remote node, starting at the short_channel_id indicated by starting_point and
383
+ /// including the batch_amount entries immediately higher in numerical value than starting_point.
384
+ /// Return type is serialized `Vec<(ChannelAnnouncement, ChannelUpdate, ChannelUpdate)>`
385
+ pub type GetNextChannelAnnouncements = extern "cdecl" fn ( starting_point : u64 , batch_amount : u8 ) -> FFIBytes < ' static > ;
386
+ /// Gets a subset of the node announcements required to dump our routing table to a remote node,
387
+ /// starting at the node *after* the provided publickey and including batch_amount entries
388
+ /// immediately higher (as defined by <PublicKey as Ord>::cmp) than starting_point.
389
+ /// If None is provided for starting_point, we start at the first node.
390
+ /// Return type is binary serialized `Vec<NodeAnnouncement>` .
391
+ pub type GetNextNodeAnnouncements = extern "cdecl" fn ( starting_point : Option < * const PublicKey > , batch_amount : u8 ) -> FFIBytes < ' static > ;
392
+ /// Returns whether a full sync should be requested from a peer.
393
+ pub type ShouldRequestFullSync = extern "cdecl" fn ( node_id : NonNull < PublicKey > ) -> Bool ;
394
+ }
395
+
396
+ pub struct FFIRoutingMsgHandler {
397
+ pub handle_node_announcement_ptr : routing_msg_descriptor_fn:: HandleNodeAnnouncement ,
398
+ pub handle_channel_announcement_ptr : routing_msg_descriptor_fn:: HandleChannelAnnouncement ,
399
+ pub handle_channel_update_ptr : routing_msg_descriptor_fn:: HandleChannelUpdate ,
400
+ pub handle_htlc_fail_channel_update_ptr : routing_msg_descriptor_fn:: HandleHTLCFailChannelUpdate ,
401
+ pub get_next_channel_announcements_ptr : routing_msg_descriptor_fn:: GetNextChannelAnnouncements ,
402
+ pub get_next_node_announcements_ptr : routing_msg_descriptor_fn:: GetNextNodeAnnouncements ,
403
+ pub should_request_full_sync_ptr : routing_msg_descriptor_fn:: ShouldRequestFullSync
404
+ }
405
+
406
+ pub struct VecWriter ( pub Vec < u8 > ) ;
407
+ impl Writer for VecWriter {
408
+ fn write_all ( & mut self , buf : & [ u8 ] ) -> Result < ( ) , Error > {
409
+ self . 0 . extend_from_slice ( buf) ;
410
+ Ok ( ( ) )
411
+ }
412
+
413
+ fn size_hint ( & mut self , size : usize ) {
414
+ self . 0 . reserve_exact ( size)
415
+ }
416
+ }
417
+
418
+ impl RoutingMessageHandler for FFIRoutingMsgHandler {
419
+ fn handle_node_announcement ( & self , msg : & NodeAnnouncement ) -> Result < bool , LightningError > {
420
+ let mut w = VecWriter ( Vec :: new ( ) ) ;
421
+ msg. write ( & mut w) ;
422
+ let bytes = FFIBytes :: from ( w. 0 . into_boxed_slice ( ) ) ;
423
+ let e = std:: ptr:: null_mut ( ) ;
424
+ let is_success = ( self . handle_node_announcement_ptr ) ( & bytes as * const _ , e) ;
425
+ if e. is_null ( ) {
426
+ Ok ( is_success. to_bool ( ) )
427
+ } else {
428
+ let e = unsafe_block ! ( "we know the error is not a null pointer" => ( * e) . clone( ) ) ;
429
+ Err ( e. into ( ) )
430
+ }
431
+ }
432
+
433
+ fn handle_channel_announcement ( & self , msg : & ChannelAnnouncement ) -> Result < bool , LightningError > {
434
+ unimplemented ! ( )
435
+ }
436
+
437
+ fn handle_channel_update ( & self , msg : & ChannelUpdate ) -> Result < bool , LightningError > {
438
+ unimplemented ! ( )
439
+ }
440
+
441
+ fn handle_htlc_fail_channel_update ( & self , update : & HTLCFailChannelUpdate ) {
442
+ unimplemented ! ( )
443
+ }
444
+
445
+ fn get_next_channel_announcements ( & self , starting_point : u64 , batch_amount : u8 ) -> Vec < ( ChannelAnnouncement , ChannelUpdate , ChannelUpdate ) > {
446
+ unimplemented ! ( )
447
+ }
448
+
449
+ fn get_next_node_announcements ( & self , starting_point : Option < & secp256k1:: PublicKey > , batch_amount : u8 ) -> Vec < NodeAnnouncement > {
450
+ unimplemented ! ( )
451
+ }
452
+
453
+ fn should_request_full_sync ( & self , node_id : & secp256k1:: PublicKey ) -> bool {
454
+ unimplemented ! ( )
455
+ }
456
+ }
0 commit comments