Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
run: |
git clone https://github.com/rust-bitcoin/rust-lightning
cd rust-lightning
git checkout 0.0.110-bindings
git checkout 0.0.111-bindings

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do you do the checkout as a separate command instead of just git clone --branch?

- name: Rebuild bindings without std, and check the sample app builds + links
run: ./genbindings.sh ./rust-lightning false
- name: Rebuild bindings, and check the sample app builds + links
Expand Down Expand Up @@ -88,7 +88,7 @@ jobs:
run: |
git clone https://github.com/rust-bitcoin/rust-lightning
cd rust-lightning
git checkout 0.0.110-bindings
git checkout 0.0.111-bindings
- name: Rebuild bindings using Apple clang, and check the sample app builds + links
run: ./genbindings.sh ./rust-lightning true
- name: Rebuild bindings using upstream clang, and check the sample app builds + links
Expand Down
26 changes: 14 additions & 12 deletions c-bindings-gen/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ fn maybe_convert_trait_impl<W: std::io::Write>(w: &mut W, trait_path: &syn::Path
},
"lightning::util::ser::Readable"|"lightning::util::ser::ReadableArgs"|"lightning::util::ser::MaybeReadable" => {
// Create the Result<Object, DecodeError> syn::Type
let mut res_ty: syn::Type = parse_quote!(Result<#for_ty, ::ln::msgs::DecodeError>);
let mut res_ty: syn::Type = parse_quote!(Result<#for_ty, lightning::ln::msgs::DecodeError>);

writeln!(w, "#[no_mangle]").unwrap();
writeln!(w, "/// Read a {} from a byte array, created by {}_write", for_obj, for_obj).unwrap();
Expand Down Expand Up @@ -151,7 +151,7 @@ fn maybe_convert_trait_impl<W: std::io::Write>(w: &mut W, trait_path: &syn::Path
} else { unreachable!(); }
} else { unreachable!(); }
} else if t == "lightning::util::ser::MaybeReadable" {
res_ty = parse_quote!(Result<Option<#for_ty>, ::ln::msgs::DecodeError>);
res_ty = parse_quote!(Result<Option<#for_ty>, lightning::ln::msgs::DecodeError>);
}
write!(w, ") -> ").unwrap();
types.write_c_type(w, &res_ty, Some(generics), false);
Expand Down Expand Up @@ -947,7 +947,7 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, i: &syn::ItemImpl, types: &mut Typ
// mappings from a trai defined in a different file, we may mis-resolve or
// fail to resolve the mapped types. Thus, we have to construct a new
// resolver for the module that the trait was defined in here first.
let trait_resolver = get_module_type_resolver!(full_trait_path, types.crate_libs, types.crate_types);
let mut trait_resolver = get_module_type_resolver!(full_trait_path, types.crate_libs, types.crate_types);
gen_types.learn_associated_types(trait_obj, &trait_resolver);
let mut impl_associated_types = HashMap::new();
for item in i.items.iter() {
Expand Down Expand Up @@ -1107,17 +1107,12 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, i: &syn::ItemImpl, types: &mut Typ
_ => {}
}
}
if uncallable_function {
let mut trait_resolver = get_module_type_resolver!(full_trait_path, $types.crate_libs, $types.crate_types);
write_method_params(w, &$trait_meth.sig, "c_void", &mut trait_resolver, Some(&meth_gen_types), true, true);
} else {
write_method_params(w, &$m.sig, "c_void", $types, Some(&meth_gen_types), true, true);
}
write_method_params(w, &$trait_meth.sig, "c_void", &mut trait_resolver, Some(&meth_gen_types), true, true);
write!(w, " {{\n\t").unwrap();
if uncallable_function {
write!(w, "unreachable!();").unwrap();
} else {
write_method_var_decl_body(w, &$m.sig, "", $types, Some(&meth_gen_types), false);
write_method_var_decl_body(w, &$trait_meth.sig, "", &mut trait_resolver, Some(&meth_gen_types), false);
let mut takes_self = false;
for inp in $m.sig.inputs.iter() {
if let syn::FnArg::Receiver(_) = inp {
Expand All @@ -1130,6 +1125,14 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, i: &syn::ItemImpl, types: &mut Typ
if idx != 0 { t_gen_args += ", " };
t_gen_args += "_"
}
// rustc doesn't like <_> if the _ is actually a lifetime, so
// if all the parameters are lifetimes just skip it.
let mut nonlifetime_param = false;
for param in $trait.generics.params.iter() {
if let syn::GenericParam::Lifetime(_) = param {}
else { nonlifetime_param = true; }
}
if !nonlifetime_param { t_gen_args = String::new(); }
if takes_self {
write!(w, "<native{} as {}<{}>>::{}(unsafe {{ &mut *(this_arg as *mut native{}) }}, ", ident, $trait_path, t_gen_args, $m.sig.ident, ident).unwrap();
} else {
Expand All @@ -1147,7 +1150,7 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, i: &syn::ItemImpl, types: &mut Typ
},
_ => {},
}
write_method_call_params(w, &$m.sig, "", $types, Some(&meth_gen_types), &real_type, false);
write_method_call_params(w, &$trait_meth.sig, "", &mut trait_resolver, Some(&meth_gen_types), &real_type, false);
}
write!(w, "\n}}\n").unwrap();
if let syn::ReturnType::Type(_, rtype) = &$m.sig.output {
Expand Down Expand Up @@ -1185,7 +1188,6 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, i: &syn::ItemImpl, types: &mut Typ
assert!(meth.default.is_some());
let old_gen_types = gen_types;
gen_types = GenericTypes::new(Some(resolved_path.clone()));
let mut trait_resolver = get_module_type_resolver!(full_trait_path, types.crate_libs, types.crate_types);
impl_meth!(meth, meth, full_trait_path, trait_obj, "", &mut trait_resolver);
gen_types = old_gen_types;
},
Expand Down
34 changes: 31 additions & 3 deletions c-bindings-gen/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ pub fn export_status(attrs: &[syn::Attribute]) -> ExportStatus {
}

pub fn assert_simple_bound(bound: &syn::TraitBound) {
if bound.paren_token.is_some() || bound.lifetimes.is_some() { unimplemented!(); }
if bound.paren_token.is_some() { unimplemented!(); }
if let syn::TraitBoundModifier::Maybe(_) = bound.modifier { unimplemented!(); }
}

Expand Down Expand Up @@ -936,6 +936,10 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
"bitcoin::secp256k1::ecdsa::RecoverableSignature" => Some("crate::c_types::RecoverableSignature"),
"bitcoin::secp256k1::SecretKey" if is_ref => Some("*const [u8; 32]"),
"bitcoin::secp256k1::SecretKey" if !is_ref => Some("crate::c_types::SecretKey"),
"bitcoin::secp256k1::Scalar" if is_ref => Some("*const crate::c_types::BigEndianScalar"),
"bitcoin::secp256k1::Scalar" if !is_ref => Some("crate::c_types::BigEndianScalar"),
"bitcoin::secp256k1::ecdh::SharedSecret" if !is_ref => Some("crate::c_types::ThirtyTwoBytes"),

"bitcoin::blockdata::script::Script" if is_ref => Some("crate::c_types::u8slice"),
"bitcoin::blockdata::script::Script" if !is_ref => Some("crate::c_types::derived::CVec_u8Z"),
"bitcoin::blockdata::transaction::OutPoint" => Some("crate::lightning::chain::transaction::OutPoint"),
Expand Down Expand Up @@ -1021,6 +1025,9 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
"bitcoin::secp256k1::ecdsa::RecoverableSignature" => Some(""),
"bitcoin::secp256k1::SecretKey" if is_ref => Some("&::bitcoin::secp256k1::SecretKey::from_slice(&unsafe { *"),
"bitcoin::secp256k1::SecretKey" if !is_ref => Some(""),
"bitcoin::secp256k1::Scalar" if !is_ref => Some(""),
"bitcoin::secp256k1::ecdh::SharedSecret" if !is_ref => Some("::bitcoin::secp256k1::ecdh::SharedSecret::from_bytes("),

"bitcoin::blockdata::script::Script" if is_ref => Some("&::bitcoin::blockdata::script::Script::from(Vec::from("),
"bitcoin::blockdata::script::Script" if !is_ref => Some("::bitcoin::blockdata::script::Script::from("),
"bitcoin::blockdata::transaction::Transaction"|"bitcoin::Transaction" if is_ref => Some("&"),
Expand Down Expand Up @@ -1104,6 +1111,9 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
"bitcoin::secp256k1::ecdsa::RecoverableSignature" => Some(".into_rust()"),
"bitcoin::secp256k1::SecretKey" if !is_ref => Some(".into_rust()"),
"bitcoin::secp256k1::SecretKey" if is_ref => Some("}[..]).unwrap()"),
"bitcoin::secp256k1::Scalar" if !is_ref => Some(".into_rust()"),
"bitcoin::secp256k1::ecdh::SharedSecret" if !is_ref => Some(".data)"),

"bitcoin::blockdata::script::Script" if is_ref => Some(".to_slice()))"),
"bitcoin::blockdata::script::Script" if !is_ref => Some(".into_rust())"),
"bitcoin::blockdata::transaction::Transaction"|"bitcoin::Transaction" => Some(".into_bitcoin()"),
Expand Down Expand Up @@ -1196,6 +1206,9 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
"bitcoin::secp256k1::ecdsa::RecoverableSignature" => Some("crate::c_types::RecoverableSignature::from_rust(&"),
"bitcoin::secp256k1::SecretKey" if is_ref => Some(""),
"bitcoin::secp256k1::SecretKey" if !is_ref => Some("crate::c_types::SecretKey::from_rust("),
"bitcoin::secp256k1::Scalar" if !is_ref => Some("crate::c_types::BigEndianScalar::from_rust("),
"bitcoin::secp256k1::ecdh::SharedSecret" if !is_ref => Some("crate::c_types::ThirtyTwoBytes { data: "),

"bitcoin::blockdata::script::Script" if is_ref => Some("crate::c_types::u8slice::from_slice(&"),
"bitcoin::blockdata::script::Script" if !is_ref => Some(""),
"bitcoin::blockdata::transaction::Transaction"|"bitcoin::Transaction" if is_ref => Some("crate::c_types::Transaction::from_bitcoin("),
Expand Down Expand Up @@ -1273,6 +1286,9 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
"bitcoin::secp256k1::ecdsa::RecoverableSignature" => Some(")"),
"bitcoin::secp256k1::SecretKey" if !is_ref => Some(")"),
"bitcoin::secp256k1::SecretKey" if is_ref => Some(".as_ref()"),
"bitcoin::secp256k1::Scalar" if !is_ref => Some(")"),
"bitcoin::secp256k1::ecdh::SharedSecret" if !is_ref => Some(".secret_bytes() }"),

"bitcoin::blockdata::script::Script" if is_ref => Some("[..])"),
"bitcoin::blockdata::script::Script" if !is_ref => Some(".into_bytes().into()"),
"bitcoin::blockdata::transaction::Transaction"|"bitcoin::Transaction" => Some(")"),
Expand Down Expand Up @@ -1381,7 +1397,19 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
if let Some(resolved) = self.maybe_resolve_path(&p.path, generics) {
if self.c_type_has_inner_from_path(&resolved) { return true; }
if self.is_primitive(&resolved) { return false; }
if self.c_type_from_path(&resolved, false, false).is_some() { true } else { false }
// We want to move to using `Option_` mappings where possible rather than
// manual mappings, as it makes downstream bindings simpler and is more
// clear for users. Thus, we default to false but override for a few
// types which had mappings defined when we were avoiding the `Option_`s.
match &resolved as &str {
"lightning::ln::PaymentSecret" => true,
"lightning::ln::PaymentHash" => true,
"lightning::ln::PaymentPreimage" => true,
"lightning::ln::channelmanager::PaymentId" => true,
"bitcoin::hash_types::BlockHash" => true,
"secp256k1::PublicKey"|"bitcoin::secp256k1::PublicKey" => true,
_ => false,
}
} else { unimplemented!(); }
},
syn::Type::Tuple(_) => false,
Expand Down Expand Up @@ -1456,7 +1484,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
(".is_none() { core::ptr::null_mut() } else { ".to_owned(), format!("({}.unwrap())", var_access))
], " }", ContainerPrefixLocation::OutsideConv));
}
} else if self.is_primitive(&inner_path) || self.c_type_from_path(&inner_path, false, false).is_none() {
} else if !self.is_transparent_container("Option", is_ref, [single_contained.unwrap()].iter().map(|a| *a), generics) {
if self.is_primitive(&inner_path) || (!is_contained_ref && !is_ref) || only_contained_has_inner {
let inner_name = self.get_c_mangled_container_type(vec![single_contained.unwrap()], generics, "Option").unwrap();
return Some(("if ", vec![
Expand Down
14 changes: 7 additions & 7 deletions lightning-c-bindings/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ no-std = ["bitcoin/no-std", "lightning/no-std", "lightning-invoice/no-std", "cor
std = ["bitcoin/std", "lightning/std", "lightning-invoice/std"]

[dependencies]
bitcoin = { version = "0.28", default-features = false }
secp256k1 = { version = "0.22", features = ["global-context", "recovery"] }
bitcoin = { version = "0.29", default-features = false }
secp256k1 = { version = "0.24", features = ["global-context", "recovery"] }
# Note that the following line is matched by genbindings to update the path
lightning = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "0.0.110-bindings", default-features = false }
lightning-persister = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "0.0.110-bindings", default-features = false }
lightning-invoice = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "0.0.110-bindings", default-features = false }
lightning-background-processor = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "0.0.110-bindings", default-features = false }
lightning-rapid-gossip-sync = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "0.0.110-bindings", default-features = false }
lightning = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "0.0.111-bindings", default-features = false }
lightning-persister = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "0.0.111-bindings", default-features = false }
lightning-invoice = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "0.0.111-bindings", default-features = false }
lightning-background-processor = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "0.0.111-bindings", default-features = false }
lightning-rapid-gossip-sync = { git = "https://github.com/lightningdevkit/rust-lightning", branch = "0.0.111-bindings", default-features = false }

core2 = { version = "0.3.0", optional = true, default-features = false }

Expand Down
Loading