Skip to content

Commit c9f3685

Browse files
committed
Refactor bindings
* use fixed length array when possible
1 parent 53a2889 commit c9f3685

File tree

12 files changed

+225
-240
lines changed

12 files changed

+225
-240
lines changed

bindings/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,4 @@ bitcoin_hashes = "0.7"
1919
# see https://github.com/rust-lang/cargo/issues/7634
2020
# as a workaround, we just included it as an usual dependency
2121
hex = "0.3"
22-
rand = "0.7.3"
2322

bindings/src/adaptors/mod.rs

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,8 @@ use lightning::{
2323
pub mod primitives;
2424
use primitives::*;
2525
use std::sync::Arc;
26-
use lightning::util::ser::Readable;
27-
use std::io::Read;
28-
use lightning::ln::msgs::DecodeError;
2926

30-
type cstr = NonNull<i8>;
27+
type Cstr = NonNull<i8>;
3128

3229
#[derive(PartialOrd, PartialEq, Eq, Ord, Debug, Copy, Clone)]
3330
#[repr(u8)]
@@ -158,11 +155,11 @@ pub struct FFILogRecord {
158155
/// The verbosity level of the message.
159156
pub level: FFILogLevel,
160157
/// The message body.
161-
pub args: cstr,
158+
pub args: Cstr,
162159
/// The module path of the message.
163-
pub module_path: cstr,
160+
pub module_path: Cstr,
164161
/// The source file containing the message.
165-
pub file: cstr,
162+
pub file: Cstr,
166163
/// The line containing the message.
167164
pub line: u32,
168165
}
@@ -196,10 +193,10 @@ impl Logger for FFILogger {
196193

197194
pub mod chain_watch_interface_fn {
198195
use super::*;
199-
pub type InstallWatchTxPtr = extern "cdecl" fn(*const FFISha256dHash, script_pub_key: *const FFIScript);
196+
pub type InstallWatchTxPtr = extern "cdecl" fn(*const Bytes32, script_pub_key: *const FFIScript);
200197
pub type InstallWatchOutpointPtr = extern "cdecl" fn(outpoint: *const FFIOutPoint, out_script: *const FFIScript);
201198
pub type WatchAllTxnPtr = extern "cdecl" fn();
202-
pub type GetChainUtxoPtr = extern "cdecl" fn(genesis_hash: *const FFISha256dHash, unspent_tx_output_identifier: u64, err: *mut FFIChainError, script: *mut FFITxOut);
199+
pub type GetChainUtxoPtr = extern "cdecl" fn(genesis_hash: *const Bytes32, unspent_tx_output_identifier: u64, err: *mut FFIChainError, script: *mut FFITxOut);
203200
}
204201

205202
#[repr(C)]
@@ -217,7 +214,7 @@ impl FFIChainWatchInterface {
217214
watch_all_txn: chain_watch_interface_fn::WatchAllTxnPtr,
218215
get_chain_utxo: chain_watch_interface_fn::GetChainUtxoPtr,
219216
network: Network,
220-
logger: Arc<Logger>
217+
logger: Arc<dyn Logger>
221218
) -> FFIChainWatchInterface {
222219
FFIChainWatchInterface{
223220
install_watch_tx_ptr: install_watch_tx,
@@ -234,11 +231,12 @@ impl ChainWatchInterface for FFIChainWatchInterface {
234231
self.util.install_watch_tx(txid, script_pub_key);
235232
let spk_vec = bitcoin_serialize(script_pub_key);
236233
let ffi_spk = FFIScript::from(spk_vec.as_slice());
237-
(self.install_watch_tx_ptr)(&txid.into() as *const _, &ffi_spk as *const _)
234+
let txid: Bytes32 = txid.clone().into();
235+
(self.install_watch_tx_ptr)(&txid as *const _, &ffi_spk as *const _)
238236
}
239237
fn install_watch_outpoint(&self, outpoint: (Txid, u32), out_script: &Script) {
240238
self.util.install_watch_outpoint(outpoint, out_script);
241-
let txid: FFISha256dHash = outpoint.0.into();
239+
let txid: Bytes32 = outpoint.0.into();
242240
let ffi_outpoint = FFIOutPoint { txid: txid, index: outpoint.1 as u16 };
243241
let out_script_vec = bitcoin_serialize(out_script);
244242
let ffi_outscript = FFIScript::from(out_script_vec.as_slice());
@@ -320,7 +318,7 @@ pub enum FFIErrorActionType {
320318
#[derive(Debug, Clone)]
321319
pub struct FFIErrorMsg {
322320
pub channel_id: [u8; 32],
323-
pub data: cstr,
321+
pub data: Cstr,
324322
}
325323

326324
impl From<FFIErrorMsg> for ErrorMessage {
@@ -370,7 +368,7 @@ impl From<FFIErrorAction> for ErrorAction {
370368
#[repr(C)]
371369
pub struct FFILightningError {
372370
/// A human-readable message describing the error
373-
pub err: cstr,
371+
pub err: Cstr,
374372
/// The action which should be taken against the offending peer.
375373
pub action: FFIErrorAction,
376374
}
@@ -387,7 +385,7 @@ impl From<FFILightningError> for LightningError {
387385

388386
pub mod routing_msg_descriptor_fn {
389387
use super::*;
390-
use crate::adaptors::primitives::PublicKey;
388+
use crate::adaptors::primitives::Bytes33;
391389

392390
/// Handle an incoming node_announcement message, returning true if it should be forwarded on,
393391
/// false or returning an Err otherwise.
@@ -410,9 +408,9 @@ pub mod routing_msg_descriptor_fn {
410408
/// immediately higher (as defined by <PublicKey as Ord>::cmp) than starting_point.
411409
/// If None is provided for starting_point, we start at the first node.
412410
/// Return type is binary serialized `Vec<NodeAnnouncement>` .
413-
pub type GetNextNodeAnnouncements = extern "cdecl" fn (starting_point: Option<*const PublicKey>, batch_amount: u8) -> FFIBytes;
411+
pub type GetNextNodeAnnouncements = extern "cdecl" fn (starting_point: Option<*const Bytes33>, batch_amount: u8) -> FFIBytes;
414412
/// Returns whether a full sync should be requested from a peer.
415-
pub type ShouldRequestFullSync = extern "cdecl" fn (node_id: NonNull<PublicKey>) -> Bool;
413+
pub type ShouldRequestFullSync = extern "cdecl" fn (node_id: NonNull<Bytes33>) -> Bool;
416414
}
417415

418416
pub struct FFIRoutingMsgHandler {

bindings/src/adaptors/primitives.rs

Lines changed: 136 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::{
2-
convert::{TryFrom, TryInto},
3-
fmt::{Formatter, Error}
2+
convert::{TryFrom},
3+
fmt::{Formatter}
44
};
55

66
use bitcoin::{
@@ -22,6 +22,139 @@ use crate::{
2222
FFIResult,
2323
is_null::IsNull
2424
};
25+
use lightning::ln::channelmanager::PaymentPreimage;
26+
27+
#[derive(Debug, Clone)]
28+
#[repr(C)]
29+
pub struct Bytes32 {
30+
pub bytes: [u8; 32],
31+
}
32+
33+
impl IsNull for Bytes32 {
34+
fn is_null(&self) -> bool {
35+
false
36+
}
37+
}
38+
39+
impl From<Bytes32> for secp256k1::SecretKey {
40+
fn from(value: Bytes32) -> Self {
41+
secp256k1::SecretKey::from_slice(&value.bytes).unwrap()
42+
}
43+
}
44+
45+
impl From<secp256k1::SecretKey> for Bytes32 {
46+
fn from(value: secp256k1::SecretKey) -> Self {
47+
let mut bytes = [0;32];
48+
bytes.copy_from_slice(&value[..]);
49+
Self {
50+
bytes
51+
}
52+
}
53+
}
54+
55+
impl From<Bytes32> for PaymentHash {
56+
fn from(ffi_hash: Bytes32) -> PaymentHash {
57+
PaymentHash(ffi_hash.bytes)
58+
}
59+
}
60+
61+
impl From<Txid> for Bytes32 {
62+
fn from(hash: Txid) -> Self {
63+
let bytes = hash.as_hash().into_inner();
64+
Bytes32{ bytes }
65+
}
66+
}
67+
68+
impl From<Bytes32> for Txid {
69+
fn from(hash: Bytes32) -> Self {
70+
Txid::from_slice(&hash.bytes).unwrap()
71+
}
72+
}
73+
74+
impl From<BlockHash> for Bytes32 {
75+
fn from(hash: BlockHash) -> Self {
76+
let bytes = hash.as_hash().into_inner();
77+
Bytes32{ bytes }
78+
}
79+
}
80+
81+
impl From<Bytes32> for PaymentSecret {
82+
fn from(ffi_secret: Bytes32) -> PaymentSecret {
83+
PaymentSecret(ffi_secret.bytes)
84+
}
85+
}
86+
87+
impl From<PaymentSecret> for Bytes32 {
88+
fn from(x: PaymentSecret) -> Self {
89+
Self {bytes: x.0}
90+
}
91+
}
92+
93+
impl From<PaymentPreimage> for Bytes32 {
94+
fn from(x: PaymentPreimage) -> Self {
95+
Self { bytes: x.0 }
96+
}
97+
}
98+
99+
impl From<Bytes32> for PaymentPreimage {
100+
fn from(x: Bytes32) -> Self {
101+
PaymentPreimage(x.bytes)
102+
}
103+
}
104+
105+
#[derive(Clone)]
106+
#[repr(C)]
107+
pub struct Bytes33 {
108+
pub bytes: [u8; 33]
109+
}
110+
111+
impl IsNull for Bytes33 {
112+
fn is_null(&self) -> bool {
113+
false
114+
}
115+
}
116+
117+
impl From<Bytes33> for secp256k1::PublicKey {
118+
fn from(value: Bytes33) -> Self {
119+
secp256k1::PublicKey::from_slice(&value.bytes).unwrap()
120+
}
121+
}
122+
123+
impl From<secp256k1::PublicKey> for Bytes33 {
124+
fn from(value: secp256k1::PublicKey) -> Self {
125+
Self {
126+
bytes: value.serialize()
127+
}
128+
}
129+
}
130+
131+
132+
#[derive(Clone)]
133+
#[repr(C)]
134+
pub struct FFIOutPoint {
135+
pub txid: Bytes32,
136+
pub index: u16,
137+
}
138+
139+
impl From<FFIOutPoint> for OutPoint {
140+
fn from(value: FFIOutPoint) -> Self {
141+
let txid = value.txid.into();
142+
OutPoint{ txid, index: value.index }
143+
}
144+
}
145+
146+
impl From<OutPoint> for FFIOutPoint {
147+
fn from(value: OutPoint) -> Self {
148+
let txid: Bytes32 = value.txid.into();
149+
FFIOutPoint { txid, index: value.index }
150+
}
151+
}
152+
153+
impl IsNull for FFIOutPoint {
154+
fn is_null(&self) -> bool {
155+
false
156+
}
157+
}
25158

26159
macro_rules! array_struct{
27160
(
@@ -78,129 +211,13 @@ macro_rules! array_struct{
78211
}
79212
}
80213

81-
#[doc="The length must be [the same as a byte number of secp256k1 secret key](secp256k1::constants::SECRET_KEY_SIZE)"]
82-
array_struct!(SecretKey);
83-
84-
impl TryFrom<SecretKey> for secp256k1::SecretKey {
85-
type Error = FFIResult;
86-
87-
fn try_from(value: SecretKey) -> Result<Self, Self::Error> {
88-
let s = value.as_ref();
89-
secp256k1::SecretKey::from_slice(s).map_err(|e| FFIResult::internal_error().context(e))
90-
}
91-
}
92-
93-
94-
#[doc="The length must be [the same as a byte number of secp256k1 public key] `secp256k1::constants::PUBLIC_KEY_SIZE`"]
95-
array_struct!(PublicKey);
96-
97-
impl TryFrom<PublicKey> for secp256k1::PublicKey {
98-
type Error = FFIResult;
99-
100-
fn try_from(value: PublicKey) -> Result<Self, Self::Error> {
101-
let s = value.as_ref();
102-
secp256k1::PublicKey::from_slice(s).map_err(|e| FFIResult::internal_error().context(e))
103-
}
104-
}
105-
106-
#[doc="256 bit seed to initialize [ChannelManager](lightning::ln::channelmanager::ChannelManager)"]
107-
array_struct!(Seed);
108-
109-
array_struct!(FFISha256dHash);
110-
111-
impl TryFrom<FFISha256dHash> for PaymentHash {
112-
type Error = FFIResult;
113-
114-
fn try_from(ffi_hash: FFISha256dHash) -> Result<PaymentHash, Self::Error> {
115-
let s = unsafe_block!("" => std::slice::from_raw_parts(ffi_hash.ptr, ffi_hash.len));
116-
let s:[u8; 32] = s.try_into().map_err(|_| FFIResult::invalid_data_length())?;
117-
Ok(PaymentHash(s))
118-
}
119-
}
120-
121-
impl From<&Txid> for FFISha256dHash {
122-
fn from(hash: &Txid) -> Self {
123-
let v = hash.encode();
124-
FFISha256dHash::from(v.into_boxed_slice())
125-
}
126-
}
127-
128-
impl From<Txid> for FFISha256dHash {
129-
fn from(hash: Txid) -> Self {
130-
let v = hash.encode();
131-
FFISha256dHash::from(v.into_boxed_slice())
132-
}
133-
}
134-
135-
impl TryFrom<FFISha256dHash> for Txid {
136-
type Error = bitcoin::hashes::Error;
137-
fn try_from(hash: FFISha256dHash) -> Result<Self, Self::Error> {
138-
let slice = unsafe_block!("We know it points to valid buffer" => std::slice::from_raw_parts(hash.ptr, hash.len));
139-
let v = bitcoin::hashes::sha256d::Hash::from_slice(slice)?;
140-
Ok(v.into())
141-
}
142-
}
143-
144-
impl From<&BlockHash> for FFISha256dHash {
145-
fn from(hash: &BlockHash) -> Self {
146-
let v = hash.encode();
147-
FFISha256dHash::from(v.into_boxed_slice())
148-
}
149-
}
150-
151-
impl From<BlockHash> for FFISha256dHash {
152-
fn from(hash: BlockHash) -> Self {
153-
let v = hash.encode();
154-
FFISha256dHash::from(v.into_boxed_slice())
155-
}
156-
}
157-
158-
array_struct!(FFISecret);
159-
160-
impl TryFrom<FFISecret> for PaymentSecret {
161-
type Error = FFIResult;
162-
163-
fn try_from(ffi_secret: FFISecret) -> Result<PaymentSecret, Self::Error> {
164-
let s = unsafe_block!("" => std::slice::from_raw_parts(ffi_secret.ptr, ffi_secret.len));
165-
let s:[u8; 32] = s.try_into().map_err(|_| FFIResult::invalid_data_length())?;
166-
Ok(PaymentSecret(s))
167-
}
168-
}
169-
170214
array_struct!(FFIScript);
171215
impl FFIScript {
172216
pub fn to_script(&self) -> Script {
173217
unimplemented!()
174218
}
175219
}
176220

177-
#[derive(Clone)]
178-
#[repr(C)]
179-
pub struct FFIOutPoint {
180-
pub txid: FFISha256dHash,
181-
pub index: u16,
182-
}
183-
184-
impl TryFrom<FFIOutPoint> for OutPoint {
185-
type Error = bitcoin::hashes::Error;
186-
fn try_from(value: FFIOutPoint) -> Result<Self, Self::Error> {
187-
let txid = value.txid.try_into()?;
188-
Ok(OutPoint{ txid, index: value.index })
189-
}
190-
}
191-
192-
impl From<OutPoint> for FFIOutPoint {
193-
fn from(value: OutPoint) -> Self {
194-
FFIOutPoint { txid: value.txid.into(), index: value.index }
195-
}
196-
}
197-
198-
impl IsNull for FFIOutPoint {
199-
fn is_null(&self) -> bool {
200-
false
201-
}
202-
}
203-
204221
#[derive(Clone)]
205222
#[repr(C)]
206223
pub struct FFITxOut {
@@ -244,7 +261,7 @@ array_struct!(FFITransaction);
244261
array_struct!(FFIBlock);
245262
array_struct!(FFIEvents);
246263

247-
/// General purpose byte array which has to cross ffi-boundary
264+
// General purpose byte array which has to cross ffi-boundary
248265
array_struct!(FFIBytes);
249266

250267
/// For `ChainWatchInterface::filter_block`

0 commit comments

Comments
 (0)