]> git.bitcoin.ninja Git - rust-lightning/blob - lightning-c-bindings/README.md
Add simple README about our C bindings generation stuff
[rust-lightning] / lightning-c-bindings / README.md
1 The wrapper crate and C/C++ Headers in this folder are auto-generated from the Rust-Lightning
2 source by the c-bindings-gen crate contained in the source tree and
3 [cbindgen](https://github.com/eqrion/cbindgen). They are intended to be used as a base for building
4 language-specific bindings, and are thus incredibly low-level and may be difficult to work with
5 directly.
6
7 In other words, if you're reading this, you're either writing bindings for a new language, or
8 you're in the wrong place - individual language bindings should come with their own documentation.
9
10 LDK C Bindings
11 ==============
12
13 The C bindings available at include/lightning.h require inclusion of include/rust_types.h first.
14
15 All of the Rust-Lightning types are mapped into C equivalents which take a few forms, with the C
16 type getting an `LDK` prefix to their native Rust type names.
17
18 #### Structs
19 Structs are mapped into a simple wrapper containing a pointer to the native Rust-Lightning object
20 and a flag to indicate whether the object is owned or only a reference. Such mappings usually
21 generate a `X_free` function which must be called to release the allocated resources. Note that
22 calling `X_free` will do nothing if the underlying pointer is NULL or if the `is_owned` flag is not
23 set.
24
25 You MUST NOT create such wrapper structs manually, relying instead on constructors which have been
26 mapped from equivalent Rust constructors.
27
28 Note that, thanks to the is-owned flag and the pointer being NULLable, such structs effectively
29 represent `RustType`, `&RustType`, and `Option<RustType>`. Check the corresponding Rust
30 documentation for the function or struct you are using to ensure you use the correct call semantics.
31 The passed struct must match the call semantics or an assertion failure or NULL pointer dereference
32 may occur.
33
34 For example, this is the mapping of ChannelManager.
35 ```c
36 typedef struct MUST_USE_STRUCT LDKChannelManager {
37    /** ... */
38    LDKnativeChannelManager *inner;
39    bool is_owned;
40 } LDKChannelManager;
41 ```
42
43 #### Traits
44 Traits are mapped into a concrete struct containing a void pointer (named `this_arg` and a jump
45 table listing the functions which the trait must implement. The void pointer may be set to any value
46 and is never interpreted (or dereferenced) by the bindings logic in any way. It is passed as the
47 first argument to all function calls in the trait. You may wish to use it as a pointer to your own
48 internal data structure, though it may also occasionally make sense to e.g. cast a file descriptor
49 into a void pointer and use it to track a socket.
50
51 This should remind you of a C++ vtable, only written out by hand and with the class only containing
52 a pointer, instead of the regular class data.
53
54 Each trait additionally contains `free` and `clone` function pointers, which may be NULL. The `free`
55 function is passed the void pointer when the object is `Drop`ed in Rust. The `clone` function is
56 passed the void pointer when the object is `Clone`ed in Rust, returning a new void pointer for the
57 new object. If the `free` pointer is NULL, you will not receive any notification when the trait
58 object is no longer needed. If the `clone` pointer is NULL, we assume that the trait object may be
59 `memcpy()`'d to create copies. Note that if you release resources with `free` without implementing
60 `clone`, you will likely end up with use-after-free bugs (as copies of the original this_arg value
61 may still exist, unbeknownst to you).
62
63 For example, `LDKSocketDescriptor` is mapped as follows:
64 ```c
65 typedef struct LDKSocketDescriptor {
66    void *this_arg;
67    /** ... */
68    uintptr_t (*send_data)(void *this_arg, LDKu8slice data, bool resume_read);
69    /** ... */
70    void (*disconnect_socket)(void *this_arg);
71    bool (*eq)(const void *this_arg, const void *other_arg);
72    uint64_t (*hash)(const void *this_arg);
73    void *(*clone)(const void *this_arg);
74    void (*free)(void *this_arg);
75 } LDKSocketDescriptor;
76 ```
77
78 ##### Rust Trait Implementations
79 Rust structs that implement a trait result in the generation of an `X_as_Y` function, which takes a
80 C struct wrapping the Rust native object and returns a generated trait object. Such generated
81 objects are only valid as long as the original Rust native object has not been `free`'d or moved as
82 a part of a Rust function call (ie continues to be owned by the C struct). For example, to use an
83 `LDKInMemoryChannelKeys` as a `ChannelKeys`, `InMemoryChannelKeys_as_ChannelKeys` is exposed:
84
85 ```c
86 LDKChannelKeys InMemoryChannelKeys_as_ChannelKeys(const LDKInMemoryChannelKeys *this_arg);
87 ```
88
89 #### Enums
90 Rust "unitary" enums are mapped simply as an equivalent C enum; however, some Rust enums have
91 variants which contain payloads. Such enums are mapped automatically by cbindgen as a tag which
92 indicates the type and a union which holds the relevant fields for a given tag. An `X_free` function
93 is provided for the enum as a whole which automatically frees the correct fields for a give tag, and
94 a `Sentinel` tag is provided which causes the free function to do nothing (but which must never
95 appear in an enum when accessed by Rust code). The `Sentinel` tag is used by the C++ wrapper classes
96 to allow moving the ownership of an enum while invalidating the old copy.
97
98 For example, the unitary enum `LDKChannelMonitorUpdateErr` is mapped as follows:
99 ```c
100 typedef enum LDKChannelMonitorUpdateErr {
101    /** .. */
102    LDKChannelMonitorUpdateErr_TemporaryFailure,
103    /** .. */
104    LDKChannelMonitorUpdateErr_PermanentFailure,
105    /** .. */
106    LDKChannelMonitorUpdateErr_Sentinel,
107 } LDKChannelMonitorUpdateErr;
108 ```
109
110 and the non-unitary enum LDKErrorAction is mapped as follows:
111 ```c
112 typedef enum LDKErrorAction_Tag {
113    /** .. */
114    LDKErrorAction_DisconnectPeer,
115    /** .. */
116    LDKErrorAction_IgnoreError,
117    /** .. */
118    LDKErrorAction_SendErrorMessage,
119    /** .. */
120    LDKErrorAction_Sentinel,
121 } LDKErrorAction_Tag;
122
123 typedef struct LDKErrorAction_LDKDisconnectPeer_Body {
124    LDKErrorMessage msg;
125 } LDKErrorAction_LDKDisconnectPeer_Body;
126
127 typedef struct LDKErrorAction_LDKSendErrorMessage_Body {
128    LDKErrorMessage msg;
129 } LDKErrorAction_LDKSendErrorMessage_Body;
130
131 typedef struct LDKErrorAction {
132    LDKErrorAction_Tag tag;
133    union {
134       LDKErrorAction_LDKDisconnectPeer_Body disconnect_peer;
135       LDKErrorAction_LDKSendErrorMessage_Body send_error_message;
136    };
137 } LDKErrorAction;
138 ```
139
140 #### Functions
141 Struct member functions are mapped as `Struct_function_name` and take a pointer to the mapped struct
142 as their first argument. Free-standing functions are mapped simply as `function_name` and take the
143 relevant mapped type arguments.
144
145 Functions which return `&OpaqueRustType` and which return `OpaqueRustType` are both mapped to a
146 function returning an owned wrapper struct. The `is_owned` flag (see above) will be set to indicate
147 that the pointed-to Rust object is owned or only a reference. Thus, when implementing a function
148 which Rust will call or calling a Rust function, you should check the Rust documentation for the
149 function to determine whether an owned or referenced object is expected or returned.
150
151 Similarly, when a function takes an `Option<RustType>` as a parameter or a return value, the C type
152 is the same as if it took only `RustType`, with the `inner` field set to NULL to indicate None. For
153 example, `ChannelManager_create_channel` takes an `Option<LDKUserConfig>` not an `LDKUserConfig`,
154 but its definition is:
155 ```c
156 MUST_USE_RES ... ChannelManager_create_channel(const LDKChannelManager *this_arg, ..., LDKUserConfig override_config);
157 ```
158
159 #### Containers
160 Various containers (Tuples, Vecs, Results, etc) are mapped into C structs of the form
161 `LDKCContainerType_ContainerElementsZ`. Inner fields are often pointers, and in the case of
162 primitive types, these may be allocated in C using the system allocator. See [the Rust docs on your
163 platform's default System allocator](https://doc.rust-lang.org/std/alloc/struct.System.html) for
164  which allocator you must use. Recursive containers are possible, and simply replace the
165 `ContainerElements` part with `InnerContainerType_InnerContainerElementsZ`, eg
166 `LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ` represents a
167 `Result<(Signature, Vec<Signature>), ()>`.
168
169 #### Notes
170 As the bindings are auto-generated, the best resource for documentation on them is the native Rust
171 docs available via `cargo doc` or [docs.rs/lightning](https://docs.rs/lightning).
172
173 The memory model is largely the Rust memory model and not a native C-like memory model. Thus,
174 function parameters are largely only ever passed by reference or by move, with pass-by-copy
175 semantics only applying to primitive types. However, because the underlying types are largely
176 pointers, the same function signature may imply two different memory ownership semantics. Thus, you
177 MUST read the Rust documentation while using the C bindings. For functions which take arguments
178 where ownership is moved to the function scope, the corresponding `X_free` function MUST NOT be
179 called on the object, whereas for all other objects, `X_free` MUST be used to free resources.
180
181 LDK C++ Bindings
182 ================
183
184 The C++ bindings available at include/lightningpp.hpp require extern "C" inclusion of lightning.h
185 and rust_types.h first. They represent thin wrappers around the C types which provide a few
186 C++-isms to make memory model correctness easier to achieve. They provide:
187  * automated destructors which call the relevant `X_free` C functions,
188  * move constructors both from C++ classes and the original C struct, with the original object
189    cleared to ensure destruction/`X_free` calls do not cause a double-free.
190  * Move semantics via the () operator, returning the original C struct and clearing the C++ object.
191    This allows calls such as `C_function(cpp_object)` which work as expected with move semantics.
192
193 In general, you should prefer to use the C++ bindings if possible, as they make memory leaks and
194 other violations somewhat easier to avoid. Note that, because the C functions are not redefined in
195 C++, all functions return the C type. Thus, you must bind returned values to the equivalent C++ type
196 (replacing `LDKX` with `LDK::X`) to ensure the destructor is properly run. A demonstration of such
197 usage is available at [demo.cpp](demo.cpp).
198
199 Gotchas
200 =======
201
202 There are a few gotchas around future changes to Rust-Lightning which the bindings may not support.
203 These include:
204  * Any trait method which returns a reference to a struct or inner variable cannot be called in
205    parallel. This is because such functions always return a local variable stored inside the trait,
206    with a call through a function pointer to get the local variable set correctly. Automatically
207    generated setter functions have comments describing the potential race conditions in their
208    definition.
209
210    For example, the `ChannelKeys::pubkeys() -> &ChannelPublicKeys` function is mapped as this:
211
212    ```c
213    typedef struct LDKChannelKeys {
214       ...
215       LDKChannelPublicKeys pubkeys;
216       /** ... */
217       void (*set_pubkeys)(const LDKChannelKeys*);
218           ...
219    } LDKChannelKeys;
220    ```
221  * Private and public keys are asserted valid at the FFI boundary. Thus, before passing any
222    (untrusted) private or public key material across the boundary, ensure that they represent valid
223    (ie in-range) keys.
224    
225 **It is highly recommended that you test any code which relies on the C (or C++) bindings in
226 valgrind, AddressSanitizer, MemorySanitizer, or other similar tools to ensure correctness.**
227
228 Process
229 =======
230
231 `genbindings.sh` is currently a catch-all script for bindings - it generates the latest Rust/C/C++
232 code for bindings from the rust-lightning source code, builds it, and then runs various test apps.
233
234 Note that after running `genbindings.sh`, if possible, the static lib in target/debug (eg
235 target/debug/liblightning.a) will be linked with address sanitizer. In order to build against it,
236 you will need to link with `clang` with `-fsanitize=address` with the same version of LLVM as
237 `rustc`'s LLVM. If `genbindings.sh` failed to find a matching `clang` or you are building on an
238 unsupported platform, a warning noting that address sanitizer is not available will be printed.