Skip to content

Chore: remove bindgen and replace with hand-rolled FFI bindings#163

Open
alexanderwiederin wants to merge 4 commits into
sedited:masterfrom
alexanderwiederin:ffi
Open

Chore: remove bindgen and replace with hand-rolled FFI bindings#163
alexanderwiederin wants to merge 4 commits into
sedited:masterfrom
alexanderwiederin:ffi

Conversation

@alexanderwiederin
Copy link
Copy Markdown
Collaborator

@alexanderwiederin alexanderwiederin commented Apr 24, 2026

Closes: #157

Summary

Replaces the bindgen-generated FFI bindings with a hand-written lib.rs in libbitcoinkernel-sys. As a follow-up the constants.rs in the wrapper crate is removed and call sites are updated to use the btck_* names from the sys crate.

Motivation

  • Auditability
  • No build-time dependency

Changes

  • libbitcoinkernel-sys/src/lib.rs: Hand-written FFI bindings replacing the bindgen-generated bindings.rs.
  • std::os::raw type aliases replaced with core::ffi equivalents.
  • libbitcoinkernel-sys/build.rs: Bindgen block removed.
  • libbitcoinkernel-sys/Cargo.toml: bindgen removed from build-dependencies.
  • src/ffi/constants.rs: Deleted. Constants now imported from libbitcoinkernel-sys using btck_* names.
  • Cargo-minimal.lock, Cargo-recent.lock: Updated to reflect removed bindgen transitive dependencies.

Question to Reviewers: Is it the right moment to do this?

@alexanderwiederin
Copy link
Copy Markdown
Collaborator Author

alexanderwiederin commented Apr 24, 2026

Will take another look later to ensure the constants have been migrated accurately.

@alexanderwiederin alexanderwiederin marked this pull request as draft April 24, 2026 12:07
@alexanderwiederin alexanderwiederin changed the title Chore: remove Bindgen and replace with hand-rolled FFI bindings Chore: remove bindgen and replace with hand-rolled FFI bindings Apr 24, 2026
@alexanderwiederin alexanderwiederin marked this pull request as ready for review April 24, 2026 14:46
@sedited
Copy link
Copy Markdown
Owner

sedited commented Apr 24, 2026

Question to Reviewers: Is it the right moment to do this?

Yes!

@jaoleal
Copy link
Copy Markdown
Contributor

jaoleal commented Apr 24, 2026

Question to Reviewers: Is it the right moment to do this?

Yeah, this pr will help me a lot and ill be glad to help you guys to ship it.

@alexanderwiederin
Copy link
Copy Markdown
Collaborator Author

alexanderwiederin commented Apr 25, 2026

Good to hear!

I think we are practically good to go here. One thing to note is that opaque types and grouped definitions are ordered alphabetically rather than following the C API order, as I felt it would scale easiest. The extern "C" declarations have the C API ordering as interdependencies require it.

Correction: On second thought, I don't think the extern "C" declarations need to be in the order of the C API either.

@alexanderwiederin alexanderwiederin force-pushed the ffi branch 2 times, most recently from e49a09d to 0917624 Compare April 25, 2026 15:06
_unused: [u8; 0],
}
#[repr(C)]
pub struct btck_ChainstateManagerOptions {
Copy link
Copy Markdown
Owner

@sedited sedited Apr 29, 2026

Choose a reason for hiding this comment

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

I wonder if we should also derive Debug, Copy, and Clone for these types. Do you think there could be a downside?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I removed them to keep the -sys crate minimal. openssl-sys takes the same approach, while secp256k1-sys does derive them - so there's no universal convention. For me it was mostly about keeping the surface area small.

Do you have a preference?

Copy link
Copy Markdown
Owner

@sedited sedited left a comment

Choose a reason for hiding this comment

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

Looks good. The only drawback I see here is that we need to be careful with copying over the correct constant values.

Comment thread libbitcoinkernel-sys/src/lib.rs Outdated
@alexanderwiederin alexanderwiederin force-pushed the ffi branch 3 times, most recently from 5d80502 to 9975909 Compare April 29, 2026 18:50
Copy link
Copy Markdown
Contributor

@jaoleal jaoleal left a comment

Choose a reason for hiding this comment

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

ACK 9975909

Only nits and docs suggestions, perhaps the second commit thats solely to move constants could be included in CHANGELOG.md ?

Also, the README.md under libbitcoinkernel-sys is pretty simple, we could include some sayings about the hand written bindings

// Primitive type aliases - alphabetical order

pub type btck_BlockCheckFlags = u32;
pub type btck_BlockValidationResult = u32;
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.

Reading this and seeing that auditability is one of the purposes for this, perhaps we could work out a little more docs here ? A good example that I saw was secp256k1 bindings.

For this case i suggest some simple docs such as

Suggested change
pub type btck_BlockValidationResult = u32;
/// Represents a granular reason for block validation.
pub type btck_BlockValidationResult = u32;

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Good suggestion, but I'd like to keep the scope focused on the bindings as much as possible. I'll add a top-level doc comment and update the README pointing to the C header for now.

pub type btck_ValidationMode = u8;
pub type btck_Warning = u8;

// btck_BlockValidationResult
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.

The constants looks fine, cant we maintain the constants.rs ? That would leave this lib.rs only for declarations right ?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I would prefer to keep everything in lib.rs and mirror the structure of the C header. This makes auditing easier, especially when updating to newer versions. The file is organised with the section comments to make navigation straightforward. Having said that, if the API grows significantly we can revisit splitting it up.

@jaoleal
Copy link
Copy Markdown
Contributor

jaoleal commented Apr 30, 2026

Question: will this trigger a new release ?

@sedited
Copy link
Copy Markdown
Owner

sedited commented Apr 30, 2026

Yes :)

Comment thread libbitcoinkernel-sys/src/lib.rs Outdated
Comment on lines +327 to +330
assert!(core::mem::size_of::<btck_NotificationInterfaceCallbacks>() == 72);
assert!(core::mem::align_of::<btck_NotificationInterfaceCallbacks>() == 8);
assert!(core::mem::size_of::<btck_ValidationInterfaceCallbacks>() == 48);
assert!(core::mem::align_of::<btck_ValidationInterfaceCallbacks>() == 8);
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.

Suggested change
assert!(core::mem::size_of::<btck_NotificationInterfaceCallbacks>() == 72);
assert!(core::mem::align_of::<btck_NotificationInterfaceCallbacks>() == 8);
assert!(core::mem::size_of::<btck_ValidationInterfaceCallbacks>() == 48);
assert!(core::mem::align_of::<btck_ValidationInterfaceCallbacks>() == 8);
assert!(
core::mem::size_of::<btck_NotificationInterfaceCallbacks>()
== 9 * core::mem::size_of::<*const ()>()
);
assert!(
core::mem::align_of::<btck_NotificationInterfaceCallbacks>()
== core::mem::align_of::<*const ()>()
);
assert!(
core::mem::size_of::<btck_ValidationInterfaceCallbacks>()
== 6 * core::mem::size_of::<*const ()>()
);
assert!(
core::mem::align_of::<btck_ValidationInterfaceCallbacks>()
== core::mem::align_of::<*const ()>()
);

After rebasing #158 on top of this to see if anything breaks, i found a problem regarding pointers size on armv7-linux-androideabi since pointers are 4 bytes on 32-bit targets.

the above suggestion fixed the problem and i was able to successfully build this lib to armv7-linux-androideabi. It multiplies the size of pointers at compile time but im not totally sure if its the best fix for this case.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Good catch! The hardcoded values were assuming 64-but pointer sizes. Your suggestion make the assertions valid on both 32-bit and 64-bit targets.

Applied - thanks!

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Added #175 to formally support 32-bit targets.

@jaoleal jaoleal mentioned this pull request Apr 30, 2026
@alexanderwiederin alexanderwiederin force-pushed the ffi branch 4 times, most recently from ff4de75 to 81bd88d Compare May 1, 2026 10:56
@alexanderwiederin
Copy link
Copy Markdown
Collaborator Author

Only nits and docs suggestions, perhaps the second commit thats solely to move constants could be included in CHANGELOG.md ?

Done.

Also, the README.md under libbitcoinkernel-sys is pretty simple, we could include some sayings about the hand written bindings

Done.

Thanks for the feedback!

Copy link
Copy Markdown
Contributor

@jaoleal jaoleal left a comment

Choose a reason for hiding this comment

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

ACK

… FFI bindings

Replace the bindgen-generated bindings.rs with a hand-written lib.rs.
The bindgen build dependency is removed.

The hand-rolled bindings are verified against bindgen output and match
the types. Layout assertions enforce ABI correctness for three structs
passed by value across the FFI boundary at compile time.

Unnecessary derives (Debug, Copy, Clone) are removed from all types.

Cargo-minimal.lock and Cargo-recent.lock have been updated to remove
bindgen dependency.

libbitcoinkernel-sys/CHANGELOG.md updated to reflect bindgen removal.
…om sys crate

Delete the constants.rs module and update all call sites to import
btck_* constants directly from libbitcoinkernel-sys. The BTCK_* aliases
are no longer needed.
Add #[allow(non_upper_case_globals)] to the From impl blocks that match
on btck_* constants. These names intentionally mirror the C header
naming convention.
@jaoleal
Copy link
Copy Markdown
Contributor

jaoleal commented May 4, 2026

ACK ccb3542

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Consider removing bindgen as a build dependency

3 participants