Skip to content

Commit 4e9c962

Browse files
committed
avoid all compiler error by using ARc
1 parent 481d952 commit 4e9c962

File tree

3 files changed

+74
-86
lines changed

3 files changed

+74
-86
lines changed

bindings/src/channelmanager.rs

Lines changed: 35 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ use lightning::ln::channelmonitor::{ManyChannelMonitor, ChannelMonitor, HTLCUpda
1414
use lightning::ln::channelmanager::{ChannelManager};
1515

1616
use crate::error::FFIResult;
17+
use crate::handle::{Out, Ref, RefMut,HandleShared};
1718

18-
/*
1919
#[repr(C)]
2020
pub struct FFIManyChannelMonitor {
2121
add_monitor_ptr: extern "C" fn(&Self, funding_txo: OutPoint, monitor: ChannelMonitor<InMemoryChannelKeys>) -> i32,
@@ -73,8 +73,6 @@ impl FeeEstimator for FFIFeeEstimator {
7373
}
7474
}
7575

76-
type FFIArcChannelManager = *const ChannelManager<InMemoryChannelKeys, Arc<FFIManyChannelMonitor>, Arc<FFIBroadCaster>, Arc<KeysManager>, Arc<FFIFeeEstimator>>;
77-
7876
#[repr(C)]
7977
pub enum FFINetwork {
8078
MainNet = 0,
@@ -103,73 +101,39 @@ impl Logger for FFILogger {
103101
}
104102
}
105103

106-
#[repr(C)]
107-
pub struct NullFFILogger {
108-
log_ptr: fn(&Self),
109-
}
110-
111-
impl Logger for NullFFILogger {
112-
fn log(&self, record: &Record) {
113-
(self.log_ptr)(self)
114-
}
115-
}
116-
117-
118-
ffi!{
119-
fn create_ffi_channel_manager(seed_ptr: *const u8, seed_len: i32, network_ptr: *const FFINetwork, logger_ptr: *const FFILogger, config_ptr: *mut UserConfig, monitor: *const FFIManyChannelMonitor, broadcaster: *const FFIBroadCaster, fee_est: *const FFIFeeEstimator, cur_block_height: usize) -> FFIArcChannelManager {
120-
unsafe {
121-
let mut emptyArgname = None;
122-
if seed_ptr.is_null() {
123-
emptyArgname = Some(stringify!(seed_ptr));
124-
}
125-
if network_ptr.is_null() {
126-
emptyArgname = Some(stringify!(network_ptr));
127-
}
128-
if config_ptr.is_null() {
129-
emptyArgname = Some(stringify!(config_ptr));
130-
}
131-
if monitor.is_null() {
132-
emptyArgname = Some(stringify!(monitor));
133-
}
134-
if broadcaster.is_null() {
135-
emptyArgname = Some(stringify!(broadcaster)));
136-
}
137-
if fee_est.is_null() {
138-
emptyArgname = Some(stringify!(fee_est));
139-
}
140-
if let Some(v) = emptyArgname {
141-
update_last_error(FFIError::EmptyPointerProvided(v));
142-
return std::ptr::null();
143-
}
144-
if seed_len != 32 {
145-
update_last_error(FFIError::InvalidSeedLength(seed_len))
146-
return std::ptr::null();
147-
}
148-
let network = (&(*network_ptr)).to_network();
149-
let now = SystemTime::now().duration_since(UNIX_EPOCH).expect("Time went backwards");
150-
let logger = Arc::from_raw(logger_ptr);
151-
let seed = std::slice::from_raw_parts(seed_ptr, 32 as usize);
152-
let mut s: [u8; 32] = Default::default();
153-
s.copy_from_slice(&seed[0..32]);
154-
let keyman = Arc::new(KeysManager::new(&s, network, logger.clone(), now.as_secs(), now.subsec_nanos()));
155-
let cfg = Box::from_raw(config_ptr);
156-
let chan_man: FFIArcChannelManager =
157-
Box::into_raw(Box::new(ChannelManager::new(network, Arc::from_raw(fee_est), Arc::from_raw(monitor), Arc::from_raw(broadcaster), logger, keyman, *cfg, cur_block_height).unwrap()));
158-
return chan_man;
159-
};
160-
}
161-
}
162-
163-
164-
#[no_mangle]
165-
pub extern fn release_ffi_channel_manager(ptr: *mut FFIArcChannelManager) {
166-
if ptr.is_null() {
167-
let err = FFIError::EmptyPointerProvided("ptr");
168-
update_last_error(err);
169-
return;
170-
}
171-
unsafe {
172-
Box::from_raw(ptr);
104+
type FFIArcChannelManager = ChannelManager<InMemoryChannelKeys, Arc<FFIManyChannelMonitor>, Arc<FFIBroadCaster>, Arc<KeysManager>, Arc<FFIFeeEstimator>>;
105+
type FFIArcChannelManagerHandle<'a> = HandleShared<'a, FFIArcChannelManager>;
106+
107+
/// We wanted to use `ffi` macro here, but Arc<dyn Logger> does not support unwind safety.
108+
ffi_no_catch!{
109+
fn create_ffi_channel_manager(
110+
seed_ptr: Ref<u8>,
111+
seed_len: usize,
112+
network: Ref<FFINetwork>,
113+
cfg: Ref<UserConfig>,
114+
monitor: Ref<FFIManyChannelMonitor>,
115+
logger: Ref<FFILogger>,
116+
broadcaster: Ref<FFIBroadCaster>,
117+
fee_est: Ref<FFIFeeEstimator>,
118+
cur_block_height: usize,
119+
chan_man: Out<FFIArcChannelManagerHandle>) -> FFIResult {
120+
if seed_len != 32 {
121+
return FFIResult::invalid_seed_length();
122+
}
123+
let seed_slice = unsafe_block!("The seed lives as long as `create_ffi_channel_manager` and the length is within the seed" => seed_ptr.as_bytes(seed_len));
124+
let network = unsafe_block!("We no pointer is not null by function of ffi! macro, and the lifetime will be the same of those with ChannelManager" => network.as_ref().to_network());
125+
let now = SystemTime::now().duration_since(UNIX_EPOCH)?;
126+
let logger = unsafe_block!("" => logger.as_arc());
127+
let mut seed: [u8; 32] = Default::default();
128+
seed.copy_from_slice(seed_slice);
129+
let keyman = Arc::new(KeysManager::new(&seed, network, logger.clone(), now.as_secs(), now.subsec_nanos()));
130+
let cfg = unsafe_block!("" => cfg.as_ref());
131+
let fee_est = unsafe_block!("" => fee_est.as_arc());
132+
let monitor = unsafe_block!("" => monitor.as_arc());
133+
let broadcaster = unsafe_block!("" => broadcaster.as_arc());
134+
let chan_man_raw: FFIArcChannelManager =
135+
ChannelManager::new(network, fee_est, monitor, broadcaster, logger, keyman, (*cfg).clone(), cur_block_height)?;
136+
unsafe_block!("We know chan_man is not null by wrapper macro. And we know `Out` is writable" => chan_man.init(HandleShared::alloc(chan_man_raw)));
137+
FFIResult::ok()
173138
}
174139
}
175-
*/

bindings/src/error.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ impl<E> From<E> for FFIResult
4949
}
5050

5151
/// Allow casting standard `Result` to FFIResult
52+
/// In this way, we assure
5253
impl Try for FFIResult {
5354
type Ok = Self;
5455
type Error = Self;
@@ -148,6 +149,8 @@ impl FFIResult {
148149
self.kind == Kind::InternalError
149150
}
150151

152+
/// Attempt to get a human-readable error message for a result.
153+
/// If the result is successful then this method returns `None`.
151154
pub fn as_err(&self) -> Option<&'static str> {
152155
match self.kind {
153156
Kind::Ok => None,
@@ -158,13 +161,16 @@ impl FFIResult {
158161
}
159162

160163

164+
/// Call a function that returns a `FFIResult`, setting the thread local last result.
165+
/// This method will also catch panics, so the function to call must be unwind safe.
161166
pub(super) fn catch(f: impl FnOnce() -> Self + UnwindSafe) -> Self {
162167
LAST_RESULT.with(|last_result| {
163168
{
164169
*last_result.borrow_mut() = None;
165170
}
166171

167172
match catch_unwind(f) {
173+
// when no panic
168174
Ok(ffi_result) => {
169175
let extract_err = || ffi_result.as_err().map(Into::into);
170176
last_result
@@ -179,7 +185,7 @@ impl FFIResult {
179185
})
180186
.value
181187
},
182-
188+
// when panic
183189
Err(e) => {
184190
let extract_panic = || extract_panic(&e).map(|s| format!("Internal panic with {}", s));
185191
last_result
@@ -197,15 +203,18 @@ impl FFIResult {
197203
})
198204
}
199205

206+
/// Access the last result returned on the calling thread.
207+
/// First argument for the closure is the last FFI result.
208+
/// Second is its error message (if any).
200209
pub(super) fn with_last_result<R>(f: impl FnOnce(Option<(FFIResult, Option<&str>)>) -> R) -> R {
201210
LAST_RESULT.with(|last_result| {
202211
let last_result = last_result.borrow();
203-
let last_result = last_result.as_ref().map(|r| {
212+
let last_result_and_its_err_msg = last_result.as_ref().map(|r| {
204213
let v = r.value;
205214
let msg = v.as_err().and_then(|_| r.err.as_ref().map(|msg| msg.as_ref()));
206215
(v, msg)
207216
});
208-
f(last_result)
217+
f(last_result_and_its_err_msg)
209218
})
210219
}
211220
}

bindings/src/handle/mod.rs

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::marker::PhantomData;
22
use std::panic::{RefUnwindSafe, UnwindSafe};
33
use std::ptr;
44
use std::slice;
5+
use std::sync::Arc;
56

67
pub(crate) mod thread_bound;
78

@@ -115,17 +116,25 @@ unsafe_impl!("The handle is semantically `&mut T`" => impl<'a, T: ?Sized> Send f
115116
unsafe_impl!("The handle uses `ThreadBound` for synchronization" => impl<'a, T: ?Sized> Sync for Ref<'a, T> where &'a T: Sync {});
116117

117118
impl<'a, T: ?Sized> Ref<'a, T> {
118-
unsafe_fn!("The pointer must be nonnull and will remain valid" => pub fn as_ref(&self) -> &T {
119+
unsafe_fn!("The pointer must be nonnull and will remain valid" =>
120+
pub fn as_ref(&self) -> &T {
119121
&*self.0
120-
});
122+
}
123+
);
124+
125+
unsafe_fn!("The pointer must be nonnull" =>
126+
pub fn as_arc(&self) -> Arc<T> {
127+
Arc::from_raw(self.0)
128+
}
129+
);
121130
}
122-
/*
123-
*/
124131

125132
impl<'a> Ref<'a, u8> {
126-
unsafe_fn!("The pointer must be nonnull, the length is correct, and will remain valid" => pub fn as_bytes(&self, len: usize) -> &[u8] {
133+
unsafe_fn!("The pointer must be nonnull, the length is correct, and will remain valid" =>
134+
pub fn as_bytes(&self, len: usize) -> &[u8] {
127135
slice::from_raw_parts(self.0, len)
128-
});
136+
}
137+
);
129138
}
130139

131140
/**
@@ -163,19 +172,25 @@ unsafe_impl!("The handle is semantically `&mut T`" => impl<'a, T: ?Sized> Send f
163172
unsafe_impl!("The handle uses `ThreadBound` for synchronization" => impl<'a, T: ?Sized> Sync for Out<'a, T> where &'a mut T: Sync {});
164173

165174
impl<'a, T> Out<'a, T> {
166-
unsafe_fn!("The pointer must be nonnull and valid for writes" => pub fn init(&mut self, value: T) {
175+
unsafe_fn!("The pointer must be nonnull and valid for writes" =>
176+
pub fn init(&mut self, value: T) {
167177
ptr::write(self.0, value);
168-
});
178+
}
179+
);
169180
}
170181

171182
impl<'a> Out<'a, u8> {
172-
unsafe_fn!("The pointer must be nonnull, not overlap the slice, must be valid for the length of the slice, and valid for writes" => pub fn init_bytes(&mut self, value: &[u8]) {
183+
unsafe_fn!("The pointer must be nonnull, not overlap the slice, must be valid for the length of the slice, and valid for writes" =>
184+
pub fn init_bytes(&mut self, value: &[u8]) {
173185
ptr::copy_nonoverlapping(value.as_ptr(), self.0, value.len());
174-
});
186+
}
187+
);
175188

176-
unsafe_fn!("The slice must never be read from and must be valid for the length of the slice" => pub fn as_uninit_bytes_mut(&mut self, len: usize) -> &mut [u8] {
189+
unsafe_fn!("The slice must never be read from and must be valid for the length of the slice" =>
190+
pub fn as_uninit_bytes_mut(&mut self, len: usize) -> &mut [u8] {
177191
slice::from_raw_parts_mut(self.0, len)
178-
});
192+
}
193+
);
179194
}
180195

181196
impl<'a, T: ?Sized> IsNull for HandleExclusive<'a, T> {

0 commit comments

Comments
 (0)