2 #include "include/rust_types.h"
3 #include "include/lightning.h"
5 #include "include/lightningpp.hpp"
9 #include <sys/socket.h>
19 const uint8_t valid_node_announcement[] = {
20 0x94, 0xe4, 0xf5, 0x61, 0x41, 0x24, 0x7d, 0x90, 0x23, 0xa0, 0xc8, 0x34, 0x8c, 0xc4, 0xca, 0x51,
21 0xd8, 0x17, 0x59, 0xff, 0x7d, 0xac, 0x8c, 0x9b, 0x63, 0x29, 0x1c, 0xe6, 0x12, 0x12, 0x93, 0xbd,
22 0x66, 0x4d, 0x6b, 0x9c, 0xfb, 0x35, 0xda, 0x16, 0x06, 0x3d, 0xf0, 0x8f, 0x8a, 0x39, 0x99, 0xa2,
23 0xf2, 0x5d, 0x12, 0x0f, 0x2b, 0x42, 0x1b, 0x8b, 0x9a, 0xfe, 0x33, 0x0c, 0xeb, 0x33, 0x5e, 0x52,
24 0xee, 0x99, 0xa1, 0x07, 0x06, 0xed, 0xf8, 0x48, 0x7a, 0xc6, 0xe5, 0xf5, 0x5e, 0x01, 0x3a, 0x41,
25 0x2f, 0x18, 0x94, 0x8a, 0x3b, 0x0a, 0x52, 0x3f, 0xbf, 0x61, 0xa9, 0xc5, 0x4f, 0x70, 0xee, 0xb8,
26 0x79, 0x23, 0xbb, 0x1a, 0x44, 0x7d, 0x91, 0xe6, 0x2a, 0xbc, 0xa1, 0x07, 0xbc, 0x65, 0x3b, 0x02,
27 0xd9, 0x1d, 0xb2, 0xf2, 0x3a, 0xcb, 0x75, 0x79, 0xc6, 0x66, 0xd8, 0xc1, 0x71, 0x29, 0xdf, 0x04,
28 0x60, 0xf4, 0xbf, 0x07, 0x7b, 0xb9, 0xc2, 0x11, 0x94, 0x6a, 0x28, 0xc2, 0xdd, 0xd8, 0x7b, 0x44,
29 0x8f, 0x08, 0xe3, 0xc8, 0xd8, 0xf4, 0x81, 0xb0, 0x9f, 0x94, 0xcb, 0xc8, 0xc1, 0x3c, 0xc2, 0x6e,
30 0x31, 0x26, 0xfc, 0x33, 0x16, 0x3b, 0xe0, 0xde, 0xa1, 0x16, 0x21, 0x9f, 0x89, 0xdd, 0x97, 0xa4,
31 0x41, 0xf2, 0x9f, 0x19, 0xb1, 0xae, 0x82, 0xf7, 0x85, 0x9a, 0xb7, 0x8f, 0xb7, 0x52, 0x7a, 0x72,
32 0xf1, 0x5e, 0x89, 0xe1, 0x8a, 0xcd, 0x40, 0xb5, 0x8e, 0xc3, 0xca, 0x42, 0x76, 0xa3, 0x6e, 0x1b,
33 0xf4, 0x87, 0x35, 0x30, 0x58, 0x43, 0x04, 0xd9, 0x2c, 0x50, 0x54, 0x55, 0x47, 0x6f, 0x70, 0x9b,
34 0x42, 0x1f, 0x91, 0xfc, 0xa1, 0xdb, 0x72, 0x53, 0x96, 0xc8, 0xe5, 0xcd, 0x0e, 0xcb, 0xa0, 0xfe,
35 0x6b, 0x08, 0x77, 0x48, 0xb7, 0xad, 0x4a, 0x69, 0x7c, 0xdc, 0xd8, 0x04, 0x28, 0x35, 0x9b, 0x73,
36 0x00, 0x00, 0x43, 0x49, 0x7f, 0xd7, 0xf8, 0x26, 0x95, 0x71, 0x08, 0xf4, 0xa3, 0x0f, 0xd9, 0xce,
37 0xc3, 0xae, 0xba, 0x79, 0x97, 0x20, 0x84, 0xe9, 0x0e, 0xad, 0x01, 0xea, 0x33, 0x09, 0x00, 0x00,
38 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x5b, 0xe5, 0xe9, 0x47, 0x82,
39 0x09, 0x67, 0x4a, 0x96, 0xe6, 0x0f, 0x1f, 0x03, 0x7f, 0x61, 0x76, 0x54, 0x0f, 0xd0, 0x01, 0xfa,
40 0x1d, 0x64, 0x69, 0x47, 0x70, 0xc5, 0x6a, 0x77, 0x09, 0xc4, 0x2c, 0x03, 0x5c, 0x4e, 0x0d, 0xec,
41 0x72, 0x15, 0xe2, 0x68, 0x33, 0x93, 0x87, 0x30, 0xe5, 0xe5, 0x05, 0xaa, 0x62, 0x50, 0x4d, 0xa8,
42 0x5b, 0xa5, 0x71, 0x06, 0xa4, 0x6b, 0x5a, 0x24, 0x04, 0xfc, 0x9d, 0x8e, 0x02, 0xba, 0x72, 0xa6,
43 0xe8, 0xba, 0x53, 0xe8, 0xb9, 0x71, 0xad, 0x0c, 0x98, 0x23, 0x96, 0x8a, 0xef, 0x4d, 0x78, 0xce,
44 0x8a, 0xf2, 0x55, 0xab, 0x43, 0xdf, 0xf8, 0x30, 0x03, 0xc9, 0x02, 0xfb, 0x8d, 0x02, 0x16, 0x34,
45 0x5b, 0xf8, 0x31, 0x16, 0x4a, 0x03, 0x75, 0x8e, 0xae, 0xa5, 0xe8, 0xb6, 0x6f, 0xee, 0x2b, 0xe7,
46 0x71, 0x0b, 0x8f, 0x19, 0x0e, 0xe8, 0x80, 0x24, 0x90, 0x32, 0xa2, 0x9e, 0xd6, 0x6e
49 // A simple block containing only one transaction (which is the channel-open transaction for the
50 // channel we'll create). This was originally created by printing additional data in a simple
51 // rust-lightning unit test.
52 const uint8_t channel_open_block[] = {
53 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
54 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
55 0x00, 0x00, 0x00, 0x00, 0xa2, 0x47, 0xd2, 0xf8, 0xd4, 0xe0, 0x6a, 0x3f, 0xf9, 0x7a, 0x9a, 0x34,
56 0xbb, 0xa9, 0x96, 0xde, 0x63, 0x84, 0x5a, 0xce, 0xcf, 0x98, 0xb8, 0xbb, 0x75, 0x4c, 0x4f, 0x7d,
57 0xee, 0x4c, 0xa9, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58 0x01, // transaction count
59 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
60 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
61 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62 0x01, 0x40, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0xd1, 0xd9, 0x13, 0xa9,
63 0x76, 0x09, 0x05, 0xa3, 0x4d, 0x13, 0x5b, 0x69, 0xaa, 0xe7, 0x79, 0x71, 0xb9, 0x75, 0xa1, 0xd0,
64 0x77, 0xcb, 0xa2, 0xf6, 0x6a, 0x25, 0x37, 0x3a, 0xaf, 0xdc, 0x11, 0x09, 0x01, 0x00, 0x00, 0x00,
68 // The first transaction in the block is header (80 bytes) + transaction count (1 byte) into the block data.
69 const uint8_t channel_open_txid[] = {
70 0x02, 0xe0, 0x50, 0x05, 0x33, 0xd3, 0x29, 0x66, 0x0c, 0xb2, 0xcb, 0x1e, 0x7a, 0x4a, 0xc7, 0xc7,
71 0x8b, 0x02, 0x46, 0x7e, 0x30, 0x2c, 0xe6, 0x19, 0xce, 0x43, 0x3e, 0xdf, 0x43, 0x65, 0xae, 0xf9,
74 // Two blocks built on top of channel_open_block:
75 const uint8_t block_1[81] = {
76 0x01, 0x00, 0x00, 0x00, 0x0c, 0x7a, 0xc2, 0xdc, 0x08, 0xaf, 0x40, 0x7d, 0x58, 0x81, 0x9b, 0x44,
77 0xc7, 0xe0, 0x0f, 0x78, 0xc0, 0xd1, 0x01, 0xa2, 0x03, 0x16, 0x4a, 0x8d, 0x92, 0x66, 0x4e, 0xaf,
78 0x7f, 0xfc, 0x6e, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
79 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
80 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
81 0x00, // transaction count
83 const uint8_t block_2[81] = {
84 0x01, 0x00, 0x00, 0x00, 0x36, 0x0b, 0xf5, 0x46, 0x4a, 0xc7, 0x26, 0x4c, 0x4b, 0x36, 0xa6, 0x9d,
85 0x0e, 0xf0, 0x14, 0xfb, 0x8a, 0xcb, 0x20, 0x84, 0x18, 0xf3, 0xaa, 0x77, 0x32, 0x2d, 0xf7, 0x48,
86 0x62, 0x92, 0xb1, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
87 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
88 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
89 0x00, // transaction count
92 const LDKThirtyTwoBytes payment_preimage_1 = {
93 .data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1 }
95 const LDKThirtyTwoBytes payment_hash_1 = {
97 0xdc, 0xb1, 0xac, 0x4a, 0x5d, 0xe3, 0x70, 0xca, 0xd0, 0x91, 0xc1, 0x3f, 0x13, 0xae, 0xe2, 0xf9,
98 0x36, 0xc2, 0x78, 0xfa, 0x05, 0xd2, 0x64, 0x65, 0x3c, 0x0c, 0x13, 0x21, 0x85, 0x2a, 0x35, 0xe8
102 const LDKThirtyTwoBytes genesis_hash = { // We don't care particularly if this is "right"
103 .data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1 }
106 void print_log(const void *this_arg, const char *record) {
107 printf("%p - %s\n", this_arg, record);
110 uint32_t get_fee(const void *this_arg, LDKConfirmationTarget target) {
111 if (target == LDKConfirmationTarget_Background) {
116 // Note that we don't call _free() on target, but that's OK, its unitary
118 // We use the same fee estimator globally:
119 const LDKFeeEstimator fee_est {
121 .get_est_sat_per_1000_weight = get_fee,
125 static std::atomic_int num_txs_broadcasted(0);
126 void broadcast_tx(const void *this_arg, LDKTransaction tx) {
127 num_txs_broadcasted += 1;
129 Transaction_free(tx);
132 struct NodeMonitors {
134 std::vector<std::pair<LDK::OutPoint, LDK::ChannelMonitor>> mons;
137 void ConnectBlock(const uint8_t (*header)[80], uint32_t height, LDKCVec_C2Tuple_usizeTransactionZZ tx_data, LDKBroadcasterInterface broadcast, LDKFeeEstimator fee_est) {
138 std::unique_lock<std::mutex> l(mut);
139 for (auto& mon : mons) {
140 LDK::CVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ res = ChannelMonitor_block_connected(&mon.second, header, tx_data, height, broadcast, fee_est, *logger);
145 LDKCResult_NoneChannelMonitorUpdateErrZ add_channel_monitor(const void *this_arg, LDKOutPoint funding_txo_arg, LDKChannelMonitor monitor_arg) {
146 // First bind the args to C++ objects so they auto-free
147 LDK::ChannelMonitor mon(std::move(monitor_arg));
148 LDK::OutPoint funding_txo(std::move(funding_txo_arg));
150 NodeMonitors* arg = (NodeMonitors*) this_arg;
151 std::unique_lock<std::mutex> l(arg->mut);
153 arg->mons.push_back(std::make_pair(std::move(funding_txo), std::move(mon)));
154 return CResult_NoneChannelMonitorUpdateErrZ_ok();
156 static std::atomic_int mons_updated(0);
157 LDKCResult_NoneChannelMonitorUpdateErrZ update_channel_monitor(const void *this_arg, LDKOutPoint funding_txo_arg, LDKChannelMonitorUpdate monitor_arg) {
158 // First bind the args to C++ objects so they auto-free
159 LDK::ChannelMonitorUpdate update(std::move(monitor_arg));
160 LDK::OutPoint funding_txo(std::move(funding_txo_arg));
162 NodeMonitors* arg = (NodeMonitors*) this_arg;
163 std::unique_lock<std::mutex> l(arg->mut);
165 bool updated = false;
166 for (auto& mon : arg->mons) {
167 if (OutPoint_get_index(&mon.first) == OutPoint_get_index(&funding_txo) &&
168 !memcmp(OutPoint_get_txid(&mon.first), OutPoint_get_txid(&funding_txo), 32)) {
170 LDKBroadcasterInterface broadcaster = {
171 .broadcast_transaction = broadcast_tx,
173 LDK::CResult_NoneMonitorUpdateErrorZ res = ChannelMonitor_update_monitor(&mon.second, &update, &broadcaster, &fee_est, arg->logger);
174 assert(res->result_ok);
180 return CResult_NoneChannelMonitorUpdateErrZ_ok();
182 LDKCVec_MonitorEventZ monitors_pending_monitor_events(const void *this_arg) {
183 NodeMonitors* arg = (NodeMonitors*) this_arg;
184 std::unique_lock<std::mutex> l(arg->mut);
186 if (arg->mons.size() == 0) {
187 return LDKCVec_MonitorEventZ {
192 // We only ever actually have one channel per node, plus concatenating two
193 // Rust Vecs to each other from C++ will require a bit of effort.
194 assert(arg->mons.size() == 1);
195 return ChannelMonitor_get_and_clear_pending_monitor_events(&arg->mons[0].second);
199 uintptr_t sock_send_data(void *this_arg, LDKu8slice data, bool resume_read) {
200 return write((int)((long)this_arg), data.data, data.datalen);
202 void sock_disconnect_socket(void *this_arg) {
203 close((int)((long)this_arg));
205 bool sock_eq(const void *this_arg, const LDKSocketDescriptor *other_arg) {
206 return this_arg == other_arg->this_arg;
208 uint64_t sock_hash(const void *this_arg) {
209 return (uint64_t)this_arg;
211 void sock_read_data_thread(int rdfd, LDKSocketDescriptor *peer_descriptor, LDKPeerManager *pm) {
212 unsigned char buf[1024];
216 while ((readlen = read(rdfd, buf, 1024)) > 0) {
217 data.datalen = readlen;
218 LDK::CResult_boolPeerHandleErrorZ res = PeerManager_read_event(&*pm, peer_descriptor, data);
219 if (!res->result_ok) {
220 peer_descriptor->disconnect_socket(peer_descriptor->this_arg);
223 PeerManager_process_events(pm);
225 PeerManager_socket_disconnected(&*pm, peer_descriptor);
228 class PeersConnection {
229 int pipefds_1_to_2[2];
230 int pipefds_2_to_1[2];
232 LDKSocketDescriptor sock1, sock2;
235 PeersConnection(LDK::ChannelManager& cm1, LDK::ChannelManager& cm2, LDK::PeerManager& net1, LDK::PeerManager& net2) {
236 assert(!pipe(pipefds_1_to_2));
237 assert(!pipe(pipefds_2_to_1));
239 sock1 = LDKSocketDescriptor {
240 .this_arg = (void*)(long)pipefds_1_to_2[1],
241 .send_data = sock_send_data,
242 .disconnect_socket = sock_disconnect_socket,
249 sock2 = LDKSocketDescriptor {
250 .this_arg = (void*)(long)pipefds_2_to_1[1],
251 .send_data = sock_send_data,
252 .disconnect_socket = sock_disconnect_socket,
259 t1 = std::thread(&sock_read_data_thread, pipefds_2_to_1[0], &sock1, &net1);
260 t2 = std::thread(&sock_read_data_thread, pipefds_1_to_2[0], &sock2, &net2);
262 // Note that we have to bind the result to a C++ class to make sure it gets free'd
263 LDK::CResult_CVec_u8ZPeerHandleErrorZ con_res = PeerManager_new_outbound_connection(&net1, ChannelManager_get_our_node_id(&cm2), sock1);
264 assert(con_res->result_ok);
265 LDK::CResult_NonePeerHandleErrorZ con_res2 = PeerManager_new_inbound_connection(&net2, sock2);
266 assert(con_res2->result_ok);
268 auto writelen = write(pipefds_1_to_2[1], con_res->contents.result->data, con_res->contents.result->datalen);
269 assert(writelen > 0 && uint64_t(writelen) == con_res->contents.result->datalen);
272 // Wait for the initial handshakes to complete...
273 LDK::CVec_PublicKeyZ peers_1 = PeerManager_get_peer_node_ids(&net1);
274 LDK::CVec_PublicKeyZ peers_2 = PeerManager_get_peer_node_ids(&net2);
275 if (peers_1->datalen == 1 && peers_2->datalen ==1) { break; }
276 std::this_thread::yield();
281 close(pipefds_1_to_2[0]);
282 close(pipefds_2_to_1[0]);
283 close(pipefds_1_to_2[1]);
284 close(pipefds_2_to_1[1]);
291 uint8_t channel_open_header[80];
292 uint8_t header_1[80];
293 uint8_t header_2[80];
294 memcpy(channel_open_header, channel_open_block, 80);
295 memcpy(header_1, block_1, 80);
296 memcpy(header_2, block_2, 80);
298 LDKPublicKey null_pk;
299 memset(&null_pk, 0, sizeof(null_pk));
301 LDKThirtyTwoBytes random_bytes;
302 LDKThirtyTwoBytes chain_tip;
303 memset(&chain_tip, 0, sizeof(chain_tip)); // channel_open_header's prev_blockhash is all-0s
305 LDKNetwork network = LDKNetwork_Testnet;
307 // Trait implementations:
308 LDKBroadcasterInterface broadcast {
310 .broadcast_transaction = broadcast_tx,
314 // Instantiate classes for the nodes that don't get reloaded on a ser-des reload
316 .this_arg = (void*)1,
322 mons1.logger = &logger1;
325 .watch_channel = add_channel_monitor,
326 .update_channel = update_channel_monitor,
327 .release_pending_monitor_events = monitors_pending_monitor_events,
331 LDK::NetGraphMsgHandler net_graph1 = NetGraphMsgHandler_new(genesis_hash, NULL, logger1);
332 LDKSecretKey node_secret1;
335 .this_arg = (void*)2,
341 mons2.logger = &logger2;
344 .watch_channel = add_channel_monitor,
345 .update_channel = update_channel_monitor,
346 .release_pending_monitor_events = monitors_pending_monitor_events,
350 LDK::NetGraphMsgHandler net_graph2 = NetGraphMsgHandler_new(genesis_hash, NULL, logger2);
351 LDKSecretKey node_secret2;
353 LDK::CVec_u8Z cm1_ser = LDKCVec_u8Z {}; // ChannelManager 1 serialization at the end of the ser-des scope
354 LDK::CVec_u8Z cm2_ser = LDKCVec_u8Z {}; // ChannelManager 2 serialization at the end of the ser-des scope
356 { // Scope for the ser-des reload
357 // Instantiate classes for node 1:
358 uint8_t node_seed[32];
359 memset(&node_seed, 0, 32);
360 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 0, 0);
361 LDK::KeysInterface keys_source1 = KeysManager_as_KeysInterface(&keys1);
362 node_secret1 = keys_source1->get_node_secret(keys_source1->this_arg);
364 LDK::ChannelManager cm1 = ChannelManager_new(fee_est, mon1, broadcast, logger1, KeysManager_as_KeysInterface(&keys1), UserConfig_default(), ChainParameters_new(network, chain_tip, 0));
366 LDK::CVec_ChannelDetailsZ channels = ChannelManager_list_channels(&cm1);
367 assert(channels->datalen == 0);
369 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph1));
371 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
372 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, &random_bytes.data, logger1);
374 // Demo getting a channel key and check that its returning real pubkeys:
375 LDK::Sign chan_signer1 = keys_source1->get_channel_signer(keys_source1->this_arg, false, 42);
376 chan_signer1->set_pubkeys(&chan_signer1); // Make sure pubkeys is defined
377 LDKPublicKey payment_point = ChannelPublicKeys_get_payment_point(&chan_signer1->pubkeys);
378 assert(memcmp(&payment_point, &null_pk, sizeof(null_pk)));
380 // Instantiate classes for node 2:
381 memset(&node_seed, 1, 32);
382 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 0, 0);
383 LDK::KeysInterface keys_source2 = KeysManager_as_KeysInterface(&keys2);
384 node_secret2 = keys_source2->get_node_secret(keys_source2->this_arg);
386 LDK::ChannelHandshakeConfig handshake_config2 = ChannelHandshakeConfig_default();
387 ChannelHandshakeConfig_set_minimum_depth(&handshake_config2, 2);
388 LDK::UserConfig config2 = UserConfig_default();
389 UserConfig_set_own_channel_config(&config2, std::move(handshake_config2));
391 LDK::ChannelManager cm2 = ChannelManager_new(fee_est, mon2, broadcast, logger2, KeysManager_as_KeysInterface(&keys2), std::move(config2), ChainParameters_new(network, chain_tip, 0));
393 LDK::CVec_ChannelDetailsZ channels2 = ChannelManager_list_channels(&cm2);
394 assert(channels2->datalen == 0);
396 LDK::RoutingMessageHandler net_msgs2 = NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph2);
397 LDK::CResult_ChannelAnnouncementDecodeErrorZ chan_ann = ChannelAnnouncement_read(LDKu8slice { .data = valid_node_announcement, .datalen = sizeof(valid_node_announcement) });
398 assert(chan_ann->result_ok);
399 LDK::CResult_boolLightningErrorZ ann_res = net_msgs2->handle_channel_announcement(net_msgs2->this_arg, chan_ann->contents.result);
400 assert(ann_res->result_ok);
402 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), std::move(net_msgs2));
404 random_bytes = keys_source2->get_secure_random_bytes(keys_source2->this_arg);
405 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, &random_bytes.data, logger2);
407 // Open a connection!
408 PeersConnection conn(cm1, cm2, net1, net2);
410 // Note that we have to bind the result to a C++ class to make sure it gets free'd
411 LDK::CResult_NoneAPIErrorZ res = ChannelManager_create_channel(&cm1, ChannelManager_get_our_node_id(&cm2), 40000, 1000, 42, UserConfig_default());
412 assert(res->result_ok);
413 PeerManager_process_events(&net1);
415 LDK::CVec_ChannelDetailsZ new_channels = ChannelManager_list_channels(&cm1);
416 assert(new_channels->datalen == 1);
417 LDKPublicKey chan_open_pk = ChannelDetails_get_remote_network_id(&new_channels->data[0]);
418 assert(!memcmp(chan_open_pk.compressed_form, ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
421 LDK::CVec_ChannelDetailsZ new_channels_2 = ChannelManager_list_channels(&cm2);
422 if (new_channels_2->datalen == 1) {
423 // Sample getting our counterparty's init features (which used to be hard to do without a memory leak):
424 const LDK::InitFeatures init_feats = ChannelDetails_get_counterparty_features(&new_channels_2->data[0]);
425 assert(init_feats->inner != NULL);
428 std::this_thread::yield();
431 LDKEventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1);
433 LDK::CVec_EventZ events = ev1.get_and_clear_pending_events(ev1.this_arg);
434 if (events->datalen == 1) {
435 assert(events->data[0].tag == LDKEvent_FundingGenerationReady);
436 assert(events->data[0].funding_generation_ready.user_channel_id == 42);
437 assert(events->data[0].funding_generation_ready.channel_value_satoshis == 40000);
438 assert(events->data[0].funding_generation_ready.output_script.datalen == 34);
439 assert(!memcmp(events->data[0].funding_generation_ready.output_script.data, channel_open_block + 58 + 81, 34));
440 LDKThirtyTwoBytes txid;
441 for (int i = 0; i < 32; i++) { txid.data[i] = channel_open_txid[31-i]; }
442 LDK::OutPoint outp = OutPoint_new(txid, 0);
443 ChannelManager_funding_transaction_generated(&cm1, &events->data[0].funding_generation_ready.temporary_channel_id.data, std::move(outp));
446 std::this_thread::yield();
449 // We observe when the funding signed messages have been exchanged by
450 // waiting for two monitors to be registered.
451 PeerManager_process_events(&net1);
453 LDK::CVec_EventZ events = ev1.get_and_clear_pending_events(ev1.this_arg);
454 if (events->datalen == 1) {
455 assert(events->data[0].tag == LDKEvent_FundingBroadcastSafe);
456 assert(events->data[0].funding_broadcast_safe.user_channel_id == 42);
459 std::this_thread::yield();
462 LDK::Listen listener1 = ChannelManager_as_Listen(&cm1);
463 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
465 LDK::Listen listener2 = ChannelManager_as_Listen(&cm2);
466 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
468 LDKCVec_C2Tuple_usizeTransactionZZ txdata { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
469 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
470 mons1.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
472 txdata = LDKCVec_C2Tuple_usizeTransactionZZ { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
473 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
474 mons2.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
476 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
477 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
478 mons1.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
479 mons2.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
481 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
482 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
483 mons1.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
484 mons2.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
486 PeerManager_process_events(&net1);
487 PeerManager_process_events(&net2);
489 // Now send funds from 1 to 2!
491 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
492 if (outbound_channels->datalen == 1) {
493 const LDKChannelDetails *channel = &outbound_channels->data[0];
494 // Note that the channel ID is the same as the channel txid reversed as the output index is 0
495 uint8_t expected_chan_id[32];
496 for (int i = 0; i < 32; i++) { expected_chan_id[i] = channel_open_txid[31-i]; }
497 assert(!memcmp(ChannelDetails_get_channel_id(channel), expected_chan_id, 32));
498 assert(!memcmp(ChannelDetails_get_remote_network_id(channel).compressed_form,
499 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
500 assert(ChannelDetails_get_channel_value_satoshis(channel) == 40000);
501 // We opened the channel with 1000 push_msat:
502 assert(ChannelDetails_get_outbound_capacity_msat(channel) == 40000*1000 - 1000);
503 assert(ChannelDetails_get_inbound_capacity_msat(channel) == 1000);
504 assert(ChannelDetails_get_is_live(channel));
507 std::this_thread::yield();
510 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
511 LDKThirtyTwoBytes payment_secret;
512 memset(payment_secret.data, 0x42, 32);
514 LDK::LockedNetworkGraph graph_2_locked = NetGraphMsgHandler_read_locked_graph(&net_graph2);
515 LDK::NetworkGraph graph_2_ref = LockedNetworkGraph_graph(&graph_2_locked);
516 LDK::CResult_RouteLightningErrorZ route = get_route(ChannelManager_get_our_node_id(&cm1), &graph_2_ref, ChannelManager_get_our_node_id(&cm2), LDKInvoiceFeatures {
517 .inner = NULL, .is_owned = false
518 }, &outbound_channels, LDKCVec_RouteHintZ {
519 .data = NULL, .datalen = 0
520 }, 5000, 10, logger1);
521 assert(route->result_ok);
522 LDK::CResult_NonePaymentSendFailureZ send_res = ChannelManager_send_payment(&cm1, route->contents.result, payment_hash_1, payment_secret);
523 assert(send_res->result_ok);
527 PeerManager_process_events(&net1);
528 while (mons_updated != 4) {
529 std::this_thread::yield();
532 // Check that we received the payment!
533 LDKEventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
535 LDK::CVec_EventZ events = ev2.get_and_clear_pending_events(ev2.this_arg);
536 if (events->datalen == 1) {
537 assert(events->data[0].tag == LDKEvent_PendingHTLCsForwardable);
540 std::this_thread::yield();
542 ChannelManager_process_pending_htlc_forwards(&cm2);
543 PeerManager_process_events(&net2);
547 LDK::CVec_EventZ events = ev2.get_and_clear_pending_events(ev2.this_arg);
548 assert(events->datalen == 1);
549 assert(events->data[0].tag == LDKEvent_PaymentReceived);
550 assert(!memcmp(events->data[0].payment_received.payment_hash.data, payment_hash_1.data, 32));
551 assert(!memcmp(events->data[0].payment_received.payment_secret.data, payment_secret.data, 32));
552 assert(events->data[0].payment_received.amt == 5000);
553 assert(ChannelManager_claim_funds(&cm2, payment_preimage_1, payment_secret, 5000));
555 PeerManager_process_events(&net2);
556 // Wait until we've passed through a full set of monitor updates (ie new preimage + CS/RAA messages)
557 while (mons_updated != 5) {
558 std::this_thread::yield();
561 LDK::CVec_EventZ events = ev1.get_and_clear_pending_events(ev1.this_arg);
562 assert(events->datalen == 1);
563 assert(events->data[0].tag == LDKEvent_PaymentSent);
564 assert(!memcmp(events->data[0].payment_sent.payment_preimage.data, payment_preimage_1.data, 32));
569 cm1_ser = ChannelManager_write(&cm1);
570 cm2_ser = ChannelManager_write(&cm2);
573 LDK::CVec_ChannelMonitorZ mons_list1 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
574 assert(mons1.mons.size() == 1);
575 mons_list1->data[0] = *& std::get<1>(mons1.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
576 mons_list1->data[0].is_owned = false; // XXX: God this sucks
577 uint8_t node_seed[32];
578 memset(&node_seed, 0, 32);
579 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 1, 0);
580 LDK::KeysInterface keys_source1 = KeysManager_as_KeysInterface(&keys1);
582 LDK::ChannelManagerReadArgs cm1_args = ChannelManagerReadArgs_new(KeysManager_as_KeysInterface(&keys1), fee_est, mon1, broadcast, logger1, UserConfig_default(), std::move(mons_list1));
583 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm1_read =
584 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm1_ser->data, .datalen = cm1_ser -> datalen}, std::move(cm1_args));
585 assert(cm1_read->result_ok);
586 LDK::ChannelManager cm1(std::move(cm1_read->contents.result->b));
588 LDK::CVec_ChannelMonitorZ mons_list2 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
589 assert(mons2.mons.size() == 1);
590 mons_list2->data[0] = *& std::get<1>(mons2.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
591 mons_list2->data[0].is_owned = false; // XXX: God this sucks
592 memset(&node_seed, 1, 32);
593 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 1, 0);
595 LDK::ChannelManagerReadArgs cm2_args = ChannelManagerReadArgs_new(KeysManager_as_KeysInterface(&keys2), fee_est, mon2, broadcast, logger2, UserConfig_default(), std::move(mons_list2));
596 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm2_read =
597 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm2_ser->data, .datalen = cm2_ser -> datalen}, std::move(cm2_args));
598 assert(cm2_read->result_ok);
599 LDK::ChannelManager cm2(std::move(cm2_read->contents.result->b));
601 // Attempt to close the channel...
603 for (int i = 0; i < 32; i++) { chan_id[i] = channel_open_txid[31-i]; }
604 LDK::CResult_NoneAPIErrorZ close_res = ChannelManager_close_channel(&cm1, &chan_id);
605 assert(!close_res->result_ok); // Note that we can't close while disconnected!
607 // Open a connection!
608 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph1));
609 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
610 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, &random_bytes.data, logger1);
612 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph2));
613 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
614 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, &random_bytes.data, logger2);
616 PeersConnection conn(cm1, cm2, net1, net2);
619 // Wait for the channels to be considered up once the reestablish messages are processed
620 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
621 if (outbound_channels->datalen == 1) {
626 // Actually close the channel
627 close_res = ChannelManager_close_channel(&cm1, &chan_id);
628 assert(close_res->result_ok);
629 PeerManager_process_events(&net1);
630 num_txs_broadcasted = 0;
631 while (num_txs_broadcasted != 2) {
632 std::this_thread::yield();
634 LDK::CVec_ChannelDetailsZ chans_after_close1 = ChannelManager_list_channels(&cm1);
635 assert(chans_after_close1->datalen == 0);
636 LDK::CVec_ChannelDetailsZ chans_after_close2 = ChannelManager_list_channels(&cm2);
637 assert(chans_after_close2->datalen == 0);
641 // Few extra random tests:
644 LDKThirtyTwoBytes kdiv_params;
645 memset(&kdiv_params, 43, 32);
646 LDK::InMemorySigner signer = InMemorySigner_new(sk, sk, sk, sk, sk, random_bytes, 42, kdiv_params);