From 07fe5cf2e1b469125e8fdb97175593399888485b Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sun, 11 Apr 2021 18:33:42 -0400 Subject: [PATCH] Handle std::io::IOError and include lightning-persister in bindings --- c-bindings-gen/src/types.rs | 8 +++- genbindings.sh | 28 +++++++++++--- lightning-c-bindings/Cargo.toml | 1 + lightning-c-bindings/src/c_types/mod.rs | 49 +++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 6 deletions(-) diff --git a/c-bindings-gen/src/types.rs b/c-bindings-gen/src/types.rs index 2cb9369..7e4eee3 100644 --- a/c-bindings-gen/src/types.rs +++ b/c-bindings-gen/src/types.rs @@ -513,7 +513,10 @@ impl<'mod_lifetime, 'crate_lft: 'mod_lifetime> ImportResolver<'mod_lifetime, 'cr let remaining: String = seg_iter.map(|seg| { format!("::{}", seg.ident) }).collect(); - if let Some((imp, _)) = self.imports.get(&first_seg.ident) { + let first_seg_str = format!("{}", first_seg.ident); + if first_seg_str == "std" { + Some(first_seg_str + &remaining) + } else if let Some((imp, _)) = self.imports.get(&first_seg.ident) { if remaining != "" { Some(imp.clone() + &remaining) } else { @@ -775,6 +778,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "String" if is_ref => Some("crate::c_types::Str"), "std::time::Duration" => Some("u64"), + "std::io::Error" => Some("crate::c_types::IOError"), "bitcoin::secp256k1::key::PublicKey" => Some("crate::c_types::PublicKey"), "bitcoin::secp256k1::Signature" => Some("crate::c_types::Signature"), @@ -967,6 +971,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "String" => Some(""), "std::time::Duration" => Some(""), + "std::io::Error" if !is_ref => Some("crate::c_types::IOError::from_rust("), "bitcoin::secp256k1::key::PublicKey" => Some("crate::c_types::PublicKey::from_rust(&"), "bitcoin::secp256k1::Signature" => Some("crate::c_types::Signature::from_rust(&"), @@ -1025,6 +1030,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "String" if is_ref => Some(".as_str().into()"), "std::time::Duration" => Some(".as_secs()"), + "std::io::Error" if !is_ref => Some(")"), "bitcoin::secp256k1::key::PublicKey" => Some(")"), "bitcoin::secp256k1::Signature" => Some(")"), diff --git a/genbindings.sh b/genbindings.sh index ff90b3a..a5c6bc1 100755 --- a/genbindings.sh +++ b/genbindings.sh @@ -16,7 +16,7 @@ fi # On reasonable systems, we can use realpath here, but OSX is a diva with 20-year-old software. ORIG_PWD="$(pwd)" -cd "$1/lightning" +cd "$1" LIGHTNING_PATH="$(pwd)" cd "$ORIG_PWD" @@ -43,8 +43,9 @@ OUT_F="$(pwd)/lightning-c-bindings/include/rust_types.h" OUT_CPP="$(pwd)/lightning-c-bindings/include/lightningpp.hpp" BIN="$(pwd)/c-bindings-gen/target/release/c-bindings-gen" -pushd "$LIGHTNING_PATH" +pushd "$LIGHTNING_PATH/lightning" RUSTC_BOOTSTRAP=1 cargo rustc $FEATURES_ARGS --profile=check -- -Zunstable-options --pretty=expanded > /tmp/lightning-crate-source.txt +popd HOST_PLATFORM="$(rustc --version --verbose | grep "host:")" if [ "$HOST_PLATFORM" = "host: x86_64-apple-darwin" ]; then @@ -55,14 +56,31 @@ else fi echo "}" >> /tmp/lightning-crate-source.txt +if [ "$2" = "true" ]; then + pushd "$LIGHTNING_PATH/lightning-persister" + RUSTC_BOOTSTRAP=1 cargo rustc --profile=check -- -Zunstable-options --pretty=expanded > /tmp/lightning-persist-crate-source.txt + popd + if [ "$HOST_PLATFORM" = "host: x86_64-apple-darwin" ]; then + sed -i".original" '1i\ +pub mod lightning_persister { +' /tmp/lightning-persist-crate-source.txt + else + sed -i '1ipub mod lightning_persister {\n' /tmp/lightning-persist-crate-source.txt + fi + echo "}" >> /tmp/lightning-persist-crate-source.txt + cat /tmp/lightning-persist-crate-source.txt >> /tmp/lightning-crate-source.txt + rm /tmp/lightning-persist-crate-source.txt +fi + cat /tmp/lightning-crate-source.txt | RUST_BACKTRACE=1 "$BIN" "$OUT/" "$OUT_TEMPL" "$OUT_F" "$OUT_CPP" -popd if [ "$HOST_PLATFORM" = "host: x86_64-apple-darwin" ]; then # OSX sed is for some reason not compatible with GNU sed - sed -i '' 's|lightning = { .*|lightning = { path = "'"$LIGHTNING_PATH"'", features = ['"$FEATURES"'] }|' lightning-c-bindings/Cargo.toml + sed -i '' 's|lightning = { .*|lightning = { path = "'"$LIGHTNING_PATH/lightning"'", features = ['"$FEATURES"'] }|' lightning-c-bindings/Cargo.toml + sed -E -i '' 's|lightning-(.*) = \{ .*|lightning-\1 = \{ path = "'"$LIGHTNING_PATH"'/lightning-\1" }|' lightning-c-bindings/Cargo.toml else - sed -i 's|lightning = { .*|lightning = { path = "'"$LIGHTNING_PATH"'", features = ['"$FEATURES"'] }|' lightning-c-bindings/Cargo.toml + sed -i 's|lightning = { .*|lightning = { path = "'"$LIGHTNING_PATH/lightning"'", features = ['"$FEATURES"'] }|' lightning-c-bindings/Cargo.toml + sed -E -i 's|lightning-(.*) = \{ .*|lightning-\1 = \{ path = "'"$LIGHTNING_PATH"'/lightning-\1" }|' lightning-c-bindings/Cargo.toml fi # Set path to include our rustc wrapper as well as cbindgen diff --git a/lightning-c-bindings/Cargo.toml b/lightning-c-bindings/Cargo.toml index eb5ab3c..e764b7e 100644 --- a/lightning-c-bindings/Cargo.toml +++ b/lightning-c-bindings/Cargo.toml @@ -19,6 +19,7 @@ bitcoin = "0.26" secp256k1 = { version = "0.20.1", features = ["global-context-less-secure"] } # Note that the following line is matched by genbindings to update the path lightning = { git = "https://git.bitcoin.ninja/rust-lightning", rev = "52f1d45bb20114bf89880e8128d0f570e426f0a6", features = ["allow_wallclock_use"] } +lightning-persister = { git = "https://git.bitcoin.ninja/rust-lightning", rev = "52f1d45bb20114bf89880e8128d0f570e426f0a6" } [patch.crates-io] # Rust-Secp256k1 PR 279. Should be dropped once merged. diff --git a/lightning-c-bindings/src/c_types/mod.rs b/lightning-c-bindings/src/c_types/mod.rs index 2748734..14e3722 100644 --- a/lightning-c-bindings/src/c_types/mod.rs +++ b/lightning-c-bindings/src/c_types/mod.rs @@ -110,6 +110,55 @@ impl Secp256k1Error { } } +#[repr(C)] +#[allow(missing_docs)] // If there's no docs upstream, that's good enough for us +/// Represents an IO Error. Note that some information is lost in the conversion from Rust. +pub enum IOError { + NotFound, + PermissionDenied, + ConnectionRefused, + ConnectionReset, + ConnectionAborted, + NotConnected, + AddrInUse, + AddrNotAvailable, + BrokenPipe, + AlreadyExists, + WouldBlock, + InvalidInput, + InvalidData, + TimedOut, + WriteZero, + Interrupted, + Other, + UnexpectedEof, +} +impl IOError { + pub(crate) fn from_rust(err: std::io::Error) -> Self { + match err.kind() { + std::io::ErrorKind::NotFound => IOError::NotFound, + std::io::ErrorKind::PermissionDenied => IOError::PermissionDenied, + std::io::ErrorKind::ConnectionRefused => IOError::ConnectionRefused, + std::io::ErrorKind::ConnectionReset => IOError::ConnectionReset, + std::io::ErrorKind::ConnectionAborted => IOError::ConnectionAborted, + std::io::ErrorKind::NotConnected => IOError::NotConnected, + std::io::ErrorKind::AddrInUse => IOError::AddrInUse, + std::io::ErrorKind::AddrNotAvailable => IOError::AddrNotAvailable, + std::io::ErrorKind::BrokenPipe => IOError::BrokenPipe, + std::io::ErrorKind::AlreadyExists => IOError::AlreadyExists, + std::io::ErrorKind::WouldBlock => IOError::WouldBlock, + std::io::ErrorKind::InvalidInput => IOError::InvalidInput, + std::io::ErrorKind::InvalidData => IOError::InvalidData, + std::io::ErrorKind::TimedOut => IOError::TimedOut, + std::io::ErrorKind::WriteZero => IOError::WriteZero, + std::io::ErrorKind::Interrupted => IOError::Interrupted, + std::io::ErrorKind::Other => IOError::Other, + std::io::ErrorKind::UnexpectedEof => IOError::UnexpectedEof, + _ => IOError::Other, + } + } +} + #[repr(C)] /// A serialized transaction, in (pointer, length) form. /// -- 2.30.2