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 genesis_hash = { // We don't care particularly if this is "right"
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 }
96 void print_log(const void *this_arg, const char *record) {
97 printf("%p - %s\n", this_arg, record);
100 uint32_t get_fee(const void *this_arg, LDKConfirmationTarget target) {
101 if (target == LDKConfirmationTarget_Background) {
106 // Note that we don't call _free() on target, but that's OK, its unitary
108 // We use the same fee estimator globally:
109 const LDKFeeEstimator fee_est {
111 .get_est_sat_per_1000_weight = get_fee,
115 static std::atomic_int num_txs_broadcasted(0);
116 void broadcast_tx(const void *this_arg, LDKTransaction tx) {
117 num_txs_broadcasted += 1;
119 Transaction_free(tx);
122 struct NodeMonitors {
124 std::vector<std::pair<LDK::OutPoint, LDK::ChannelMonitor>> mons;
127 void ConnectBlock(const uint8_t (*header)[80], uint32_t height, LDKCVec_C2Tuple_usizeTransactionZZ tx_data, LDKBroadcasterInterface broadcast, LDKFeeEstimator fee_est) {
128 std::unique_lock<std::mutex> l(mut);
129 for (auto& mon : mons) {
130 LDK::CVec_TransactionOutputsZ res = ChannelMonitor_block_connected(&mon.second, header, tx_data, height, broadcast, fee_est, *logger);
135 LDKCResult_NoneChannelMonitorUpdateErrZ add_channel_monitor(const void *this_arg, LDKOutPoint funding_txo_arg, LDKChannelMonitor monitor_arg) {
136 // First bind the args to C++ objects so they auto-free
137 LDK::ChannelMonitor mon(std::move(monitor_arg));
138 LDK::OutPoint funding_txo(std::move(funding_txo_arg));
140 NodeMonitors* arg = (NodeMonitors*) this_arg;
141 std::unique_lock<std::mutex> l(arg->mut);
143 arg->mons.push_back(std::make_pair(std::move(funding_txo), std::move(mon)));
144 return CResult_NoneChannelMonitorUpdateErrZ_ok();
146 static std::atomic_int mons_updated(0);
147 LDKCResult_NoneChannelMonitorUpdateErrZ update_channel_monitor(const void *this_arg, LDKOutPoint funding_txo_arg, LDKChannelMonitorUpdate monitor_arg) {
148 // First bind the args to C++ objects so they auto-free
149 LDK::ChannelMonitorUpdate update(std::move(monitor_arg));
150 LDK::OutPoint funding_txo(std::move(funding_txo_arg));
152 NodeMonitors* arg = (NodeMonitors*) this_arg;
153 std::unique_lock<std::mutex> l(arg->mut);
155 bool updated = false;
156 for (auto& mon : arg->mons) {
157 if (OutPoint_get_index(&mon.first) == OutPoint_get_index(&funding_txo) &&
158 !memcmp(OutPoint_get_txid(&mon.first), OutPoint_get_txid(&funding_txo), 32)) {
160 LDKBroadcasterInterface broadcaster = {
161 .broadcast_transaction = broadcast_tx,
163 LDK::CResult_NoneMonitorUpdateErrorZ res = ChannelMonitor_update_monitor(&mon.second, &update, &broadcaster, &fee_est, arg->logger);
164 assert(res->result_ok);
170 return CResult_NoneChannelMonitorUpdateErrZ_ok();
172 LDKCVec_MonitorEventZ monitors_pending_monitor_events(const void *this_arg) {
173 NodeMonitors* arg = (NodeMonitors*) this_arg;
174 std::unique_lock<std::mutex> l(arg->mut);
176 if (arg->mons.size() == 0) {
177 return LDKCVec_MonitorEventZ {
182 // We only ever actually have one channel per node, plus concatenating two
183 // Rust Vecs to each other from C++ will require a bit of effort.
184 assert(arg->mons.size() == 1);
185 return ChannelMonitor_get_and_clear_pending_monitor_events(&arg->mons[0].second);
189 uintptr_t sock_send_data(void *this_arg, LDKu8slice data, bool resume_read) {
190 return write((int)((long)this_arg), data.data, data.datalen);
192 void sock_disconnect_socket(void *this_arg) {
193 close((int)((long)this_arg));
195 bool sock_eq(const void *this_arg, const LDKSocketDescriptor *other_arg) {
196 return this_arg == other_arg->this_arg;
198 uint64_t sock_hash(const void *this_arg) {
199 return (uint64_t)this_arg;
201 void sock_read_data_thread(int rdfd, LDKSocketDescriptor *peer_descriptor, LDKPeerManager *pm) {
202 unsigned char buf[1024];
206 while ((readlen = read(rdfd, buf, 1024)) > 0) {
207 data.datalen = readlen;
208 LDK::CResult_boolPeerHandleErrorZ res = PeerManager_read_event(&*pm, peer_descriptor, data);
209 if (!res->result_ok) {
210 peer_descriptor->disconnect_socket(peer_descriptor->this_arg);
213 PeerManager_process_events(pm);
215 PeerManager_socket_disconnected(&*pm, peer_descriptor);
218 class PeersConnection {
219 int pipefds_1_to_2[2];
220 int pipefds_2_to_1[2];
222 LDKSocketDescriptor sock1, sock2;
225 PeersConnection(LDK::ChannelManager& cm1, LDK::ChannelManager& cm2, LDK::PeerManager& net1, LDK::PeerManager& net2) {
226 assert(!pipe(pipefds_1_to_2));
227 assert(!pipe(pipefds_2_to_1));
229 sock1 = LDKSocketDescriptor {
230 .this_arg = (void*)(long)pipefds_1_to_2[1],
231 .send_data = sock_send_data,
232 .disconnect_socket = sock_disconnect_socket,
239 sock2 = LDKSocketDescriptor {
240 .this_arg = (void*)(long)pipefds_2_to_1[1],
241 .send_data = sock_send_data,
242 .disconnect_socket = sock_disconnect_socket,
249 t1 = std::thread(&sock_read_data_thread, pipefds_2_to_1[0], &sock1, &net1);
250 t2 = std::thread(&sock_read_data_thread, pipefds_1_to_2[0], &sock2, &net2);
252 // Note that we have to bind the result to a C++ class to make sure it gets free'd
253 LDK::CResult_CVec_u8ZPeerHandleErrorZ con_res = PeerManager_new_outbound_connection(&net1, ChannelManager_get_our_node_id(&cm2), sock1);
254 assert(con_res->result_ok);
255 LDK::CResult_NonePeerHandleErrorZ con_res2 = PeerManager_new_inbound_connection(&net2, sock2);
256 assert(con_res2->result_ok);
258 auto writelen = write(pipefds_1_to_2[1], con_res->contents.result->data, con_res->contents.result->datalen);
259 assert(writelen > 0 && uint64_t(writelen) == con_res->contents.result->datalen);
262 // Wait for the initial handshakes to complete...
263 LDK::CVec_PublicKeyZ peers_1 = PeerManager_get_peer_node_ids(&net1);
264 LDK::CVec_PublicKeyZ peers_2 = PeerManager_get_peer_node_ids(&net2);
265 if (peers_1->datalen == 1 && peers_2->datalen ==1) { break; }
266 std::this_thread::yield();
271 close(pipefds_1_to_2[0]);
272 close(pipefds_2_to_1[0]);
273 close(pipefds_1_to_2[1]);
274 close(pipefds_2_to_1[1]);
281 uint8_t channel_open_header[80];
282 uint8_t header_1[80];
283 uint8_t header_2[80];
284 memcpy(channel_open_header, channel_open_block, 80);
285 memcpy(header_1, block_1, 80);
286 memcpy(header_2, block_2, 80);
288 LDKPublicKey null_pk;
289 memset(&null_pk, 0, sizeof(null_pk));
291 LDKThirtyTwoBytes random_bytes;
292 LDKThirtyTwoBytes chain_tip;
293 memset(&chain_tip, 0, sizeof(chain_tip)); // channel_open_header's prev_blockhash is all-0s
295 LDKNetwork network = LDKNetwork_Testnet;
297 // Trait implementations:
298 LDKBroadcasterInterface broadcast {
300 .broadcast_transaction = broadcast_tx,
304 // Instantiate classes for the nodes that don't get reloaded on a ser-des reload
306 .this_arg = (void*)1,
312 mons1.logger = &logger1;
315 .watch_channel = add_channel_monitor,
316 .update_channel = update_channel_monitor,
317 .release_pending_monitor_events = monitors_pending_monitor_events,
321 LDK::NetGraphMsgHandler net_graph1 = NetGraphMsgHandler_new(genesis_hash, NULL, logger1);
322 LDKSecretKey node_secret1;
325 .this_arg = (void*)2,
331 mons2.logger = &logger2;
334 .watch_channel = add_channel_monitor,
335 .update_channel = update_channel_monitor,
336 .release_pending_monitor_events = monitors_pending_monitor_events,
340 LDK::NetGraphMsgHandler net_graph2 = NetGraphMsgHandler_new(genesis_hash, NULL, logger2);
341 LDKSecretKey node_secret2;
343 LDK::CVec_u8Z cm1_ser = LDKCVec_u8Z {}; // ChannelManager 1 serialization at the end of the ser-des scope
344 LDK::CVec_u8Z cm2_ser = LDKCVec_u8Z {}; // ChannelManager 2 serialization at the end of the ser-des scope
346 { // Scope for the ser-des reload
347 // Instantiate classes for node 1:
348 uint8_t node_seed[32];
349 memset(&node_seed, 0, 32);
350 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 0, 0);
351 LDK::KeysInterface keys_source1 = KeysManager_as_KeysInterface(&keys1);
352 node_secret1 = keys_source1->get_node_secret(keys_source1->this_arg);
354 LDK::ChannelManager cm1 = ChannelManager_new(fee_est, mon1, broadcast, logger1, KeysManager_as_KeysInterface(&keys1), UserConfig_default(), ChainParameters_new(network, BestBlock_new(chain_tip, 0)));
356 LDK::CVec_ChannelDetailsZ channels = ChannelManager_list_channels(&cm1);
357 assert(channels->datalen == 0);
359 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph1));
361 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
362 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, &random_bytes.data, logger1);
364 // Demo getting a channel key and check that its returning real pubkeys:
365 LDK::Sign chan_signer1 = keys_source1->get_channel_signer(keys_source1->this_arg, false, 42);
366 chan_signer1->BaseSign.set_pubkeys(&chan_signer1->BaseSign); // Make sure pubkeys is defined
367 LDKPublicKey payment_point = ChannelPublicKeys_get_payment_point(&chan_signer1->BaseSign.pubkeys);
368 assert(memcmp(&payment_point, &null_pk, sizeof(null_pk)));
370 // Instantiate classes for node 2:
371 memset(&node_seed, 1, 32);
372 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 0, 0);
373 LDK::KeysInterface keys_source2 = KeysManager_as_KeysInterface(&keys2);
374 node_secret2 = keys_source2->get_node_secret(keys_source2->this_arg);
376 LDK::ChannelHandshakeConfig handshake_config2 = ChannelHandshakeConfig_default();
377 ChannelHandshakeConfig_set_minimum_depth(&handshake_config2, 2);
378 LDK::UserConfig config2 = UserConfig_default();
379 UserConfig_set_own_channel_config(&config2, std::move(handshake_config2));
381 LDK::ChannelManager cm2 = ChannelManager_new(fee_est, mon2, broadcast, logger2, KeysManager_as_KeysInterface(&keys2), std::move(config2), ChainParameters_new(network, BestBlock_new(chain_tip, 0)));
383 LDK::CVec_ChannelDetailsZ channels2 = ChannelManager_list_channels(&cm2);
384 assert(channels2->datalen == 0);
386 LDK::RoutingMessageHandler net_msgs2 = NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph2);
387 LDK::CResult_ChannelAnnouncementDecodeErrorZ chan_ann = ChannelAnnouncement_read(LDKu8slice { .data = valid_node_announcement, .datalen = sizeof(valid_node_announcement) });
388 assert(chan_ann->result_ok);
389 LDK::CResult_boolLightningErrorZ ann_res = net_msgs2->handle_channel_announcement(net_msgs2->this_arg, chan_ann->contents.result);
390 assert(ann_res->result_ok);
392 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), std::move(net_msgs2));
394 random_bytes = keys_source2->get_secure_random_bytes(keys_source2->this_arg);
395 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, &random_bytes.data, logger2);
397 // Open a connection!
398 PeersConnection conn(cm1, cm2, net1, net2);
400 // Note that we have to bind the result to a C++ class to make sure it gets free'd
401 LDK::CResult_NoneAPIErrorZ res = ChannelManager_create_channel(&cm1, ChannelManager_get_our_node_id(&cm2), 40000, 1000, 42, UserConfig_default());
402 assert(res->result_ok);
403 PeerManager_process_events(&net1);
405 LDK::CVec_ChannelDetailsZ new_channels = ChannelManager_list_channels(&cm1);
406 assert(new_channels->datalen == 1);
407 LDKPublicKey chan_open_pk = ChannelDetails_get_remote_network_id(&new_channels->data[0]);
408 assert(!memcmp(chan_open_pk.compressed_form, ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
411 LDK::CVec_ChannelDetailsZ new_channels_2 = ChannelManager_list_channels(&cm2);
412 if (new_channels_2->datalen == 1) {
413 // Sample getting our counterparty's init features (which used to be hard to do without a memory leak):
414 const LDK::InitFeatures init_feats = ChannelDetails_get_counterparty_features(&new_channels_2->data[0]);
415 assert(init_feats->inner != NULL);
418 std::this_thread::yield();
421 LDKEventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1);
423 LDK::CVec_EventZ events = ev1.get_and_clear_pending_events(ev1.this_arg);
424 if (events->datalen == 1) {
425 assert(events->data[0].tag == LDKEvent_FundingGenerationReady);
426 assert(events->data[0].funding_generation_ready.user_channel_id == 42);
427 assert(events->data[0].funding_generation_ready.channel_value_satoshis == 40000);
428 assert(events->data[0].funding_generation_ready.output_script.datalen == 34);
429 assert(!memcmp(events->data[0].funding_generation_ready.output_script.data, channel_open_block + 58 + 81, 34));
430 LDKTransaction funding_transaction { .data = const_cast<uint8_t*>(channel_open_block + 81), .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false };
432 LDK::CResult_NoneAPIErrorZ fund_res = ChannelManager_funding_transaction_generated(&cm1, &events->data[0].funding_generation_ready.temporary_channel_id.data, funding_transaction);
433 assert(fund_res->result_ok);
436 std::this_thread::yield();
439 // We observe when the funding signed messages have been exchanged by
440 // waiting for two monitors to be registered.
441 assert(num_txs_broadcasted == 0);
442 PeerManager_process_events(&net1);
443 while (num_txs_broadcasted != 1) {
444 std::this_thread::yield();
447 LDK::Listen listener1 = ChannelManager_as_Listen(&cm1);
448 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
450 LDK::Listen listener2 = ChannelManager_as_Listen(&cm2);
451 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
453 LDKCVec_C2Tuple_usizeTransactionZZ txdata { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
454 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
455 mons1.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
457 txdata = LDKCVec_C2Tuple_usizeTransactionZZ { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
458 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
459 mons2.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
461 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
462 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
463 mons1.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
464 mons2.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
466 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
467 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
468 mons1.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
469 mons2.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
471 PeerManager_process_events(&net1);
472 PeerManager_process_events(&net2);
474 // Now send funds from 1 to 2!
476 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
477 if (outbound_channels->datalen == 1) {
478 const LDKChannelDetails *channel = &outbound_channels->data[0];
479 // Note that the channel ID is the same as the channel txid reversed as the output index is 0
480 uint8_t expected_chan_id[32];
481 for (int i = 0; i < 32; i++) { expected_chan_id[i] = channel_open_txid[31-i]; }
482 assert(!memcmp(ChannelDetails_get_channel_id(channel), expected_chan_id, 32));
483 assert(!memcmp(ChannelDetails_get_remote_network_id(channel).compressed_form,
484 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
485 assert(ChannelDetails_get_channel_value_satoshis(channel) == 40000);
486 // We opened the channel with 1000 push_msat:
487 assert(ChannelDetails_get_outbound_capacity_msat(channel) == 40000*1000 - 1000);
488 assert(ChannelDetails_get_inbound_capacity_msat(channel) == 1000);
489 assert(ChannelDetails_get_is_live(channel));
492 std::this_thread::yield();
495 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
496 LDKCOption_u64Z min_value = {
497 .tag = LDKCOption_u64Z_Some,
500 LDK::C2Tuple_PaymentHashPaymentSecretZ payment_hash_secret = ChannelManager_create_inbound_payment(&cm2, min_value, 3600, 43);
502 LDK::LockedNetworkGraph graph_2_locked = NetGraphMsgHandler_read_locked_graph(&net_graph2);
503 LDK::NetworkGraph graph_2_ref = LockedNetworkGraph_graph(&graph_2_locked);
504 LDK::CResult_RouteLightningErrorZ route = get_route(ChannelManager_get_our_node_id(&cm1), &graph_2_ref, ChannelManager_get_our_node_id(&cm2), LDKInvoiceFeatures {
505 .inner = NULL, .is_owned = false
506 }, &outbound_channels, LDKCVec_RouteHintHopZ {
507 .data = NULL, .datalen = 0
508 }, 5000, 10, logger1);
509 assert(route->result_ok);
510 LDK::CResult_NonePaymentSendFailureZ send_res = ChannelManager_send_payment(&cm1, route->contents.result, payment_hash_secret->a, payment_hash_secret->b);
511 assert(send_res->result_ok);
515 PeerManager_process_events(&net1);
516 while (mons_updated != 4) {
517 std::this_thread::yield();
520 // Check that we received the payment!
521 LDKEventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
523 LDK::CVec_EventZ events = ev2.get_and_clear_pending_events(ev2.this_arg);
524 if (events->datalen == 1) {
525 assert(events->data[0].tag == LDKEvent_PendingHTLCsForwardable);
528 std::this_thread::yield();
530 ChannelManager_process_pending_htlc_forwards(&cm2);
531 PeerManager_process_events(&net2);
534 LDKThirtyTwoBytes payment_preimage;
536 LDK::CVec_EventZ events = ev2.get_and_clear_pending_events(ev2.this_arg);
537 assert(events->datalen == 1);
538 assert(events->data[0].tag == LDKEvent_PaymentReceived);
539 assert(!memcmp(events->data[0].payment_received.payment_hash.data, payment_hash_secret->a.data, 32));
540 assert(!memcmp(events->data[0].payment_received.payment_secret.data, payment_hash_secret->b.data, 32));
541 assert(events->data[0].payment_received.amt == 5000);
542 memcpy(payment_preimage.data, events->data[0].payment_received.payment_preimage.data, 32);
543 assert(ChannelManager_claim_funds(&cm2, payment_preimage));
545 PeerManager_process_events(&net2);
546 // Wait until we've passed through a full set of monitor updates (ie new preimage + CS/RAA messages)
547 while (mons_updated != 5) {
548 std::this_thread::yield();
551 LDK::CVec_EventZ events = ev1.get_and_clear_pending_events(ev1.this_arg);
552 assert(events->datalen == 1);
553 assert(events->data[0].tag == LDKEvent_PaymentSent);
554 assert(!memcmp(events->data[0].payment_sent.payment_preimage.data, payment_preimage.data, 32));
559 cm1_ser = ChannelManager_write(&cm1);
560 cm2_ser = ChannelManager_write(&cm2);
563 LDK::CVec_ChannelMonitorZ mons_list1 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
564 assert(mons1.mons.size() == 1);
565 mons_list1->data[0] = *& std::get<1>(mons1.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
566 mons_list1->data[0].is_owned = false; // XXX: God this sucks
567 uint8_t node_seed[32];
568 memset(&node_seed, 0, 32);
569 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 1, 0);
570 LDK::KeysInterface keys_source1 = KeysManager_as_KeysInterface(&keys1);
572 LDK::ChannelManagerReadArgs cm1_args = ChannelManagerReadArgs_new(KeysManager_as_KeysInterface(&keys1), fee_est, mon1, broadcast, logger1, UserConfig_default(), std::move(mons_list1));
573 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm1_read =
574 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm1_ser->data, .datalen = cm1_ser -> datalen}, std::move(cm1_args));
575 assert(cm1_read->result_ok);
576 LDK::ChannelManager cm1(std::move(cm1_read->contents.result->b));
578 LDK::CVec_ChannelMonitorZ mons_list2 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
579 assert(mons2.mons.size() == 1);
580 mons_list2->data[0] = *& std::get<1>(mons2.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
581 mons_list2->data[0].is_owned = false; // XXX: God this sucks
582 memset(&node_seed, 1, 32);
583 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 1, 0);
585 LDK::ChannelManagerReadArgs cm2_args = ChannelManagerReadArgs_new(KeysManager_as_KeysInterface(&keys2), fee_est, mon2, broadcast, logger2, UserConfig_default(), std::move(mons_list2));
586 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm2_read =
587 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm2_ser->data, .datalen = cm2_ser -> datalen}, std::move(cm2_args));
588 assert(cm2_read->result_ok);
589 LDK::ChannelManager cm2(std::move(cm2_read->contents.result->b));
591 // Attempt to close the channel...
593 for (int i = 0; i < 32; i++) { chan_id[i] = channel_open_txid[31-i]; }
594 LDK::CResult_NoneAPIErrorZ close_res = ChannelManager_close_channel(&cm1, &chan_id);
595 assert(!close_res->result_ok); // Note that we can't close while disconnected!
597 // Open a connection!
598 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph1));
599 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
600 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, &random_bytes.data, logger1);
602 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph2));
603 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
604 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, &random_bytes.data, logger2);
606 PeersConnection conn(cm1, cm2, net1, net2);
609 // Wait for the channels to be considered up once the reestablish messages are processed
610 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
611 if (outbound_channels->datalen == 1) {
616 // Actually close the channel
617 close_res = ChannelManager_close_channel(&cm1, &chan_id);
618 assert(close_res->result_ok);
619 PeerManager_process_events(&net1);
620 num_txs_broadcasted = 0;
621 while (num_txs_broadcasted != 2) {
622 std::this_thread::yield();
624 LDK::CVec_ChannelDetailsZ chans_after_close1 = ChannelManager_list_channels(&cm1);
625 assert(chans_after_close1->datalen == 0);
626 LDK::CVec_ChannelDetailsZ chans_after_close2 = ChannelManager_list_channels(&cm2);
627 assert(chans_after_close2->datalen == 0);
631 // Few extra random tests:
634 LDKThirtyTwoBytes kdiv_params;
635 memset(&kdiv_params, 43, 32);
636 LDK::InMemorySigner signer = InMemorySigner_new(sk, sk, sk, sk, sk, random_bytes, 42, kdiv_params);