Skip to content

Commit 0da33ff

Browse files
committed
externalize KeysInterface
1 parent 1846766 commit 0da33ff

File tree

2 files changed

+176
-9
lines changed

2 files changed

+176
-9
lines changed

bindings/src/adaptors/mod.rs

Lines changed: 147 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@ use std::{
77
};
88

99
use bitcoin::hash_types::{BlockHash, Txid};
10-
use bitcoin::{blockdata::transaction::Transaction, blockdata::script::Script, blockdata::block::Block, consensus::serialize as bitcoin_serialize, Network};
10+
use bitcoin::{blockdata::transaction::Transaction, blockdata::script::Script, blockdata::block::Block, consensus::serialize as bitcoin_serialize, consensus::deserialize as bitcoin_deserialize, Network};
1111
use bitcoin::secp256k1;
12+
use bitcoin::secp256k1::{Secp256k1, Signing};
1213

1314
use lightning::{
1415
chain::chaininterface::{BroadcasterInterface, FeeEstimator, ConfirmationTarget, ChainWatchInterface, ChainError},
@@ -22,6 +23,12 @@ use lightning::{
2223
pub mod primitives;
2324
use primitives::*;
2425
use std::sync::Arc;
26+
use lightning::chain::keysinterface::{ChannelKeys, InMemoryChannelKeys, KeysInterface};
27+
use bitcoin::secp256k1::{SecretKey, PublicKey};
28+
use bitcoin::secp256k1::Error::InvalidMessage;
29+
use bitcoin::util::key::Error::Secp256k1 as Secp256k1Error;
30+
use lightning::util::ser::Readable;
31+
use lightning::ln::msgs::DecodeError;
2532

2633
type Cstr = NonNull<i8>;
2734

@@ -285,6 +292,145 @@ impl ChainWatchInterface for FFIChainWatchInterface {
285292
}
286293
}
287294

295+
#[repr(C)]
296+
pub struct FFIChannelKeys {
297+
funding_key: [u8; 32],
298+
revocation_base_key: [u8; 32],
299+
payment_key: [u8; 32],
300+
delayed_payment_base_key: [u8; 32],
301+
htlc_base_key: [u8; 32],
302+
commitment_seed: [u8; 32],
303+
channel_value_satoshis: u64,
304+
key_derivation_params_1: u64,
305+
key_derivation_params_2: u64,
306+
}
307+
308+
impl FFIChannelKeys {
309+
fn to_in_memory_channel_keys<C: Signing>(&self, ctx: &Secp256k1<C>) -> InMemoryChannelKeys {
310+
InMemoryChannelKeys::new(
311+
ctx,
312+
secp256k1::key::SecretKey::from_slice(&self.funding_key).unwrap(),
313+
secp256k1::key::SecretKey::from_slice(&self.revocation_base_key).unwrap(),
314+
secp256k1::key::SecretKey::from_slice(&self.payment_key).unwrap(),
315+
secp256k1::key::SecretKey::from_slice(&self.delayed_payment_base_key).unwrap(),
316+
secp256k1::key::SecretKey::from_slice(&self.htlc_base_key).unwrap(),
317+
self.commitment_seed,
318+
self.channel_value_satoshis,
319+
(self.key_derivation_params_1, self.key_derivation_params_2)
320+
)
321+
}
322+
}
323+
324+
impl Readable for FFIChannelKeys {
325+
fn read<R: ::std::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
326+
let funding_key = Readable::read(reader)?;
327+
let revocation_base_key = Readable::read(reader)?;
328+
let payment_key = Readable::read(reader)?;
329+
let delayed_payment_base_key = Readable::read(reader)?;
330+
let htlc_base_key = Readable::read(reader)?;
331+
let commitment_seed = Readable::read(reader)?;
332+
let channel_value_satoshis = Readable::read(reader)?;
333+
let key_derivation_params_1 = Readable::read(reader)?;
334+
let key_derivation_params_2 = Readable::read(reader)?;
335+
Ok (FFIChannelKeys{
336+
funding_key,
337+
revocation_base_key,
338+
payment_key,
339+
delayed_payment_base_key,
340+
htlc_base_key,
341+
commitment_seed,
342+
channel_value_satoshis,
343+
key_derivation_params_1,
344+
key_derivation_params_2,
345+
})
346+
}
347+
}
348+
349+
pub mod keys_interface_fn {
350+
use super::{Bytes32, FFIChannelKeys, Bool};
351+
pub type GetNodeSecret = extern "cdecl" fn (*mut [u8; 32]);
352+
pub type GetDestinationScript = extern "cdecl" fn (script_ptr: *mut u8, script_len: *mut usize);
353+
pub type GetShutdownPubKey = extern "cdecl" fn (pk_ptr: *mut [u8; 33]);
354+
pub type GetChannelKeys = extern "cdecl" fn (inbound: Bool, satoshis: u64, ffi_channel_keys_ptr: *mut [u8; 216]);
355+
pub type GetOnionRand = extern "cdecl" fn (secret: *mut [u8; 32], prng_seed: *mut [u8; 32]);
356+
pub type GetChannelId = extern "cdecl" fn(channel_id: *mut [u8; 32]);
357+
}
358+
359+
pub struct FFIKeysInterface {
360+
pub get_node_secret_ptr: keys_interface_fn::GetNodeSecret,
361+
pub get_destination_script_ptr: keys_interface_fn::GetDestinationScript,
362+
pub get_shutdown_pubkey_ptr: keys_interface_fn::GetShutdownPubKey,
363+
pub get_channel_keys_ptr: keys_interface_fn::GetChannelKeys,
364+
pub get_onion_rand_ptr: keys_interface_fn::GetOnionRand,
365+
pub get_channel_id_ptr: keys_interface_fn::GetChannelId,
366+
secp_ctx: Secp256k1<secp256k1::SignOnly>,
367+
}
368+
369+
impl FFIKeysInterface {
370+
pub fn new(
371+
get_node_secret_ptr: keys_interface_fn::GetNodeSecret,
372+
get_destination_script_ptr: keys_interface_fn::GetDestinationScript,
373+
get_shutdown_pubkey_ptr: keys_interface_fn::GetShutdownPubKey,
374+
get_channel_keys_ptr: keys_interface_fn::GetChannelKeys,
375+
get_onion_rand_ptr: keys_interface_fn::GetOnionRand,
376+
get_channel_id_ptr: keys_interface_fn::GetChannelId
377+
) -> Self {
378+
FFIKeysInterface {
379+
get_node_secret_ptr,
380+
get_destination_script_ptr,
381+
get_shutdown_pubkey_ptr,
382+
get_channel_keys_ptr,
383+
get_onion_rand_ptr,
384+
get_channel_id_ptr,
385+
secp_ctx: Secp256k1::signing_only()
386+
}
387+
}
388+
}
389+
390+
impl KeysInterface for FFIKeysInterface {
391+
type ChanKeySigner = InMemoryChannelKeys;
392+
393+
fn get_node_secret(&self) -> SecretKey {
394+
let mut secret = [0u8; 32];
395+
(self.get_node_secret_ptr)(&mut secret as *mut _);
396+
SecretKey::from_slice(&secret).unwrap()
397+
}
398+
399+
fn get_destination_script(&self) -> Script {
400+
let mut script_ptr = [0u8; 512];
401+
let mut script_len: &mut usize = &mut usize::MAX;
402+
(self.get_destination_script_ptr)(script_ptr.as_mut_ptr(), script_len as *mut _);
403+
let s = bitcoin::consensus::Decodable::consensus_decode(&script_ptr[..(*script_len)]).expect("Failed to deserialize script");
404+
s
405+
}
406+
407+
fn get_shutdown_pubkey(&self) -> PublicKey {
408+
let mut pk = [0u8; 33];
409+
(self.get_shutdown_pubkey_ptr)(&mut pk as *mut _);
410+
PublicKey::from_slice(&pk).unwrap()
411+
}
412+
413+
fn get_channel_keys(&self, inbound: bool, channel_value_satoshis: u64) -> Self::ChanKeySigner {
414+
let mut channel_keys_b = [0u8; 216];
415+
(self.get_channel_keys_ptr)(if inbound { Bool::True } else { Bool::False }, channel_value_satoshis, &mut channel_keys_b as *mut _);
416+
let ffi_channel_keys: FFIChannelKeys = Readable::read(&mut channel_keys_b.as_ref()).expect("Failed to deserialize channel keys");
417+
ffi_channel_keys.to_in_memory_channel_keys(&self.secp_ctx)
418+
}
419+
420+
fn get_onion_rand(&self) -> (SecretKey, [u8; 32]) {
421+
let mut secret = [0; 32];
422+
let mut prng_seed = [0; 32];
423+
(self.get_onion_rand_ptr)(&mut secret as *mut _, &mut prng_seed as *mut _);
424+
(SecretKey::from_slice(&secret).unwrap(), prng_seed)
425+
}
426+
427+
fn get_channel_id(&self) -> [u8; 32] {
428+
let mut channel_id = [0; 32];
429+
(self.get_channel_id_ptr)(&mut channel_id as *mut _);
430+
channel_id
431+
}
432+
}
433+
288434
pub mod socket_descriptor_fn {
289435
use super::FFIBytes;
290436
pub type SendData = extern "cdecl" fn (data: FFIBytes, resume_read: u8) -> usize;

bindings/src/channelmanager.rs

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use lightning::{
1414
channelmonitor::SimpleManyChannelMonitor
1515
},
1616
chain::{
17-
keysinterface::{KeysManager, InMemoryChannelKeys},
17+
keysinterface::{InMemoryChannelKeys},
1818
transaction::OutPoint
1919
},
2020
routing::router::Route,
@@ -38,7 +38,7 @@ use crate::{
3838
};
3939

4040
pub type FFIManyChannelMonitor = SimpleManyChannelMonitor<OutPoint, InMemoryChannelKeys, Arc<FFIBroadCaster>, Arc<FFIFeeEstimator>, Arc<FFILogger>, Arc<FFIChainWatchInterface>>;
41-
pub type FFIArcChannelManager = ChannelManager<InMemoryChannelKeys, Arc<FFIManyChannelMonitor>, Arc<FFIBroadCaster>, Arc<KeysManager>, Arc<FFIFeeEstimator>, Arc<FFILogger>>;
41+
pub type FFIArcChannelManager = ChannelManager<InMemoryChannelKeys, Arc<FFIManyChannelMonitor>, Arc<FFIBroadCaster>, Arc<FFIKeysInterface>, Arc<FFIFeeEstimator>, Arc<FFILogger>>;
4242
pub type FFIArcChannelManagerHandle<'a> = HandleShared<'a, FFIArcChannelManager>;
4343

4444
fn fail_htlc_backwards_inner(payment_hash: Ref<Bytes32>, payment_secret: &Option<PaymentSecret>, handle: FFIArcChannelManagerHandle) -> Result<bool, FFIResult> {
@@ -73,7 +73,6 @@ fn send_payment_inner(handle: FFIArcChannelManagerHandle, route_ref: Ref<FFIRout
7373
}
7474

7575
pub(crate) fn construct_channel_manager(
76-
seed: Ref<Bytes32>,
7776
ffi_network: FFINetwork,
7877
cfg: Ref<UserConfig>,
7978

@@ -84,6 +83,8 @@ pub(crate) fn construct_channel_manager(
8483
filter_block: &chain_watch_interface_fn::FilterBlock,
8584
reentered: &chain_watch_interface_fn::ReEntered,
8685

86+
keys_interface: Arc<FFIKeysInterface>,
87+
8788
broadcast_transaction_ptr: Ref<broadcaster_fn::BroadcastTransactionPtr>,
8889
log_ref: &ffilogger_fn::LogExtern,
8990
get_est_sat_per_1000_weight_ptr: Ref<fee_estimator_fn::GetEstSatPer1000WeightPtr>,
@@ -92,7 +93,6 @@ pub(crate) fn construct_channel_manager(
9293
) -> FFIArcChannelManager {
9394
let network = ffi_network.to_network();
9495
let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
95-
let mut seed: [u8; 32] = unsafe_block!("it points to valid length buffer" => seed.as_ref()).clone().bytes;
9696

9797
let logger_arc = Arc::new( FFILogger{ log_ptr: *log_ref } );
9898

@@ -114,7 +114,6 @@ pub(crate) fn construct_channel_manager(
114114
let fee_est_fn_ref = unsafe_block!("" => get_est_sat_per_1000_weight_ptr.as_ref());
115115
let fee_est = FFIFeeEstimator{ get_est_sat_per_1000_weight_ptr: *fee_est_fn_ref };
116116

117-
let keyman = Arc::new(KeysManager::new(&seed, network, now.as_secs(), now.subsec_nanos()));
118117
let cfg = unsafe_block!("" => cfg.as_ref());
119118

120119
let monitor =
@@ -126,7 +125,7 @@ pub(crate) fn construct_channel_manager(
126125
monitor,
127126
broadcaster,
128127
logger_arc,
129-
keyman,
128+
keys_interface,
130129
cfg.clone(),
131130
cur_block_height
132131
)
@@ -135,7 +134,6 @@ pub(crate) fn construct_channel_manager(
135134
ffi! {
136135

137136
fn create_channel_manager(
138-
seed: Ref<Bytes32>,
139137
network_ref: Ref<FFINetwork>,
140138
cfg: Ref<UserConfig>,
141139

@@ -146,6 +144,13 @@ ffi! {
146144
filter_block_ptr: Ref<chain_watch_interface_fn::FilterBlock>,
147145
reentered_ptr: Ref<chain_watch_interface_fn::ReEntered>,
148146

147+
get_node_secret_ptr: Ref<keys_interface_fn::GetNodeSecret>,
148+
get_destination_script_ptr: Ref<keys_interface_fn::GetDestinationScript>,
149+
get_shutdown_key_ptr: Ref<keys_interface_fn::GetShutdownPubKey>,
150+
get_channel_keys_ptr: Ref<keys_interface_fn::GetChannelKeys>,
151+
get_onion_rand_ptr: Ref<keys_interface_fn::GetOnionRand>,
152+
get_channel_id_ptr: Ref<keys_interface_fn::GetChannelId>,
153+
149154
broadcast_transaction_ptr: Ref<broadcaster_fn::BroadcastTransactionPtr>,
150155
log_ptr: Ref<ffilogger_fn::LogExtern>,
151156
get_est_sat_per_1000_weight_ptr: Ref<fee_estimator_fn::GetEstSatPer1000WeightPtr>,
@@ -161,9 +166,23 @@ ffi! {
161166
let filter_block_ref = unsafe_block!("function pointer lives as long as ChainWatchInterface and it points to valid data" => filter_block_ptr.as_ref());
162167
let reentered_ref = unsafe_block!("function pointer lives as long as ChainWatchInterface and it points to valid data" => reentered_ptr.as_ref());
163168

169+
let get_node_secret_ref = unsafe_block!("function pointer lives as long as KeysInterface and it points to valid data" => get_node_secret_ptr.as_ref());
170+
let get_destination_script_ref = unsafe_block!("function pointer lives as long as KeysInterface and it points to valid data" => get_destination_script_ptr.as_ref());
171+
let get_shutdown_key_ref = unsafe_block!("function pointer lives as long as KeysInterface and it points to valid data" => get_shutdown_key_ptr.as_ref());
172+
let get_channel_keys_ref = unsafe_block!("function pointer lives as long as KeysInterface and it points to valid data" => get_channel_keys_ptr.as_ref());
173+
let get_onion_rand_ref = unsafe_block!("function pointer lives as long as KeysInterface and it points to valid data" => get_onion_rand_ptr.as_ref());
174+
let get_channel_id_ref = unsafe_block!("function pointer lives as long as KeysInterface and it points to valid data" => get_channel_id_ptr.as_ref());
175+
let keys_interface = FFIKeysInterface::new(
176+
*get_node_secret_ref,
177+
*get_destination_script_ref,
178+
*get_shutdown_key_ref,
179+
*get_channel_keys_ref,
180+
*get_onion_rand_ref,
181+
*get_channel_id_ref,
182+
);
183+
164184
let chan_man_raw =
165185
construct_channel_manager(
166-
seed,
167186
network,
168187
cfg,
169188

@@ -174,6 +193,8 @@ ffi! {
174193
filter_block_ref,
175194
reentered_ref,
176195

196+
Arc::new(keys_interface),
197+
177198
broadcast_transaction_ptr,
178199
log_ref,
179200
get_est_sat_per_1000_weight_ptr,

0 commit comments

Comments
 (0)