rust-lightning/lightning-c-bindings/demo.c
Matt Corallo d9a38d1846 [bindings] Give Transaction objects a buffer-is-owned flag.
A lot of our container mapping depends on the `is_owned` flag
which we have for in-crate mapped objects to map references and
non-references into the same container type. Transaction was
mapped to two completely different types (a slice and a Vec type),
which led to a number of edge cases in the bindings generation.
Specifically, I spent a few days trying to map
`[(A, &Transaction)]` properly and came up empty - we map slices
into the same types as Vecs (and rely on the `is_owned` flag to
avoid double-free) and the lack of one for `Transaction` would have
required a special-case in numerous functions.

Instead, we just add a flag in `Transaction` to mirror what we do
for in-crate types and check it before free-ing any underlying
memory.

Note that, sadly, because the c_types objects aren't mapped as a
part of our C++ bindings generation, you have to manually call
`Transaction_free()` even in C++.
2020-10-21 14:50:22 -04:00

97 lines
2.7 KiB
C

#include "include/rust_types.h"
#include "include/lightning.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
void print_log(const void *this_arg, const char *record) {
printf("%s", record);
}
uint32_t get_fee(const void *this_arg, LDKConfirmationTarget target) {
if (target == LDKConfirmationTarget_Background) {
return 253;
} else {
return 507;
}
}
void broadcast_tx(const void *this_arg, LDKTransaction tx) {
//TODO
Transaction_free(tx);
}
LDKCResult_NoneChannelMonitorUpdateErrZ add_channel_monitor(const void *this_arg, LDKOutPoint funding_txo, LDKChannelMonitor monitor) {
return CResult_NoneChannelMonitorUpdateErrZ_ok();
}
LDKCResult_NoneChannelMonitorUpdateErrZ update_channel_monitor(const void *this_arg, LDKOutPoint funding_txo, LDKChannelMonitorUpdate monitor) {
return CResult_NoneChannelMonitorUpdateErrZ_ok();
}
LDKCVec_MonitorEventZ monitors_pending_monitor_events(const void *this_arg) {
LDKCVec_MonitorEventZ empty_htlc_vec = {
.data = NULL,
.datalen = 0,
};
return empty_htlc_vec;
}
int main() {
uint8_t node_seed[32];
memset(node_seed, 0, 32);
LDKNetwork net = LDKNetwork_Bitcoin;
LDKLogger logger = {
.this_arg = NULL,
.log = print_log,
.free = NULL,
};
LDKFeeEstimator fee_est = {
.this_arg = NULL,
.get_est_sat_per_1000_weight = get_fee,
.free = NULL
};
LDKManyChannelMonitor mon = {
.this_arg = NULL,
.add_monitor = add_channel_monitor,
.update_monitor = update_channel_monitor,
.get_and_clear_pending_monitor_events = monitors_pending_monitor_events,
.free = NULL,
};
LDKBroadcasterInterface broadcast = {
broadcast.this_arg = NULL,
broadcast.broadcast_transaction = broadcast_tx,
.free = NULL,
};
LDKKeysManager keys = KeysManager_new(&node_seed, net, 0, 0);
LDKKeysInterface keys_source = KeysManager_as_KeysInterface(&keys);
LDKUserConfig config = UserConfig_default();
LDKChannelManager cm = ChannelManager_new(net, fee_est, mon, broadcast, logger, keys_source, config, 0);
LDKCVec_ChannelDetailsZ channels = ChannelManager_list_channels(&cm);
assert((unsigned long)channels.data < 4096); // There's an offset, but it should still be an offset against null in the 0 page
assert(channels.datalen == 0);
CVec_ChannelDetailsZ_free(channels);
LDKEventsProvider prov = ChannelManager_as_EventsProvider(&cm);
LDKCVec_EventZ events = (prov.get_and_clear_pending_events)(prov.this_arg);
assert((unsigned long)events.data < 4096); // There's an offset, but it should still be an offset against null in the 0 page
assert(events.datalen == 0);
ChannelManager_free(cm);
KeysManager_free(keys);
// Check that passing empty vecs to rust doesn't blow it up:
LDKCVec_MonitorEventZ empty_htlc_vec = {
.data = NULL,
.datalen = 0,
};
CVec_MonitorEventZ_free(empty_htlc_vec);
}