4 #include "include/lightningpp.hpp"
8 #include <sys/socket.h>
18 const uint8_t valid_node_announcement[] = {
19 0x94, 0xe4, 0xf5, 0x61, 0x41, 0x24, 0x7d, 0x90, 0x23, 0xa0, 0xc8, 0x34, 0x8c, 0xc4, 0xca, 0x51,
20 0xd8, 0x17, 0x59, 0xff, 0x7d, 0xac, 0x8c, 0x9b, 0x63, 0x29, 0x1c, 0xe6, 0x12, 0x12, 0x93, 0xbd,
21 0x66, 0x4d, 0x6b, 0x9c, 0xfb, 0x35, 0xda, 0x16, 0x06, 0x3d, 0xf0, 0x8f, 0x8a, 0x39, 0x99, 0xa2,
22 0xf2, 0x5d, 0x12, 0x0f, 0x2b, 0x42, 0x1b, 0x8b, 0x9a, 0xfe, 0x33, 0x0c, 0xeb, 0x33, 0x5e, 0x52,
23 0xee, 0x99, 0xa1, 0x07, 0x06, 0xed, 0xf8, 0x48, 0x7a, 0xc6, 0xe5, 0xf5, 0x5e, 0x01, 0x3a, 0x41,
24 0x2f, 0x18, 0x94, 0x8a, 0x3b, 0x0a, 0x52, 0x3f, 0xbf, 0x61, 0xa9, 0xc5, 0x4f, 0x70, 0xee, 0xb8,
25 0x79, 0x23, 0xbb, 0x1a, 0x44, 0x7d, 0x91, 0xe6, 0x2a, 0xbc, 0xa1, 0x07, 0xbc, 0x65, 0x3b, 0x02,
26 0xd9, 0x1d, 0xb2, 0xf2, 0x3a, 0xcb, 0x75, 0x79, 0xc6, 0x66, 0xd8, 0xc1, 0x71, 0x29, 0xdf, 0x04,
27 0x60, 0xf4, 0xbf, 0x07, 0x7b, 0xb9, 0xc2, 0x11, 0x94, 0x6a, 0x28, 0xc2, 0xdd, 0xd8, 0x7b, 0x44,
28 0x8f, 0x08, 0xe3, 0xc8, 0xd8, 0xf4, 0x81, 0xb0, 0x9f, 0x94, 0xcb, 0xc8, 0xc1, 0x3c, 0xc2, 0x6e,
29 0x31, 0x26, 0xfc, 0x33, 0x16, 0x3b, 0xe0, 0xde, 0xa1, 0x16, 0x21, 0x9f, 0x89, 0xdd, 0x97, 0xa4,
30 0x41, 0xf2, 0x9f, 0x19, 0xb1, 0xae, 0x82, 0xf7, 0x85, 0x9a, 0xb7, 0x8f, 0xb7, 0x52, 0x7a, 0x72,
31 0xf1, 0x5e, 0x89, 0xe1, 0x8a, 0xcd, 0x40, 0xb5, 0x8e, 0xc3, 0xca, 0x42, 0x76, 0xa3, 0x6e, 0x1b,
32 0xf4, 0x87, 0x35, 0x30, 0x58, 0x43, 0x04, 0xd9, 0x2c, 0x50, 0x54, 0x55, 0x47, 0x6f, 0x70, 0x9b,
33 0x42, 0x1f, 0x91, 0xfc, 0xa1, 0xdb, 0x72, 0x53, 0x96, 0xc8, 0xe5, 0xcd, 0x0e, 0xcb, 0xa0, 0xfe,
34 0x6b, 0x08, 0x77, 0x48, 0xb7, 0xad, 0x4a, 0x69, 0x7c, 0xdc, 0xd8, 0x04, 0x28, 0x35, 0x9b, 0x73,
35 0x00, 0x00, 0x43, 0x49, 0x7f, 0xd7, 0xf8, 0x26, 0x95, 0x71, 0x08, 0xf4, 0xa3, 0x0f, 0xd9, 0xce,
36 0xc3, 0xae, 0xba, 0x79, 0x97, 0x20, 0x84, 0xe9, 0x0e, 0xad, 0x01, 0xea, 0x33, 0x09, 0x00, 0x00,
37 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x5b, 0xe5, 0xe9, 0x47, 0x82,
38 0x09, 0x67, 0x4a, 0x96, 0xe6, 0x0f, 0x1f, 0x03, 0x7f, 0x61, 0x76, 0x54, 0x0f, 0xd0, 0x01, 0xfa,
39 0x1d, 0x64, 0x69, 0x47, 0x70, 0xc5, 0x6a, 0x77, 0x09, 0xc4, 0x2c, 0x03, 0x5c, 0x4e, 0x0d, 0xec,
40 0x72, 0x15, 0xe2, 0x68, 0x33, 0x93, 0x87, 0x30, 0xe5, 0xe5, 0x05, 0xaa, 0x62, 0x50, 0x4d, 0xa8,
41 0x5b, 0xa5, 0x71, 0x06, 0xa4, 0x6b, 0x5a, 0x24, 0x04, 0xfc, 0x9d, 0x8e, 0x02, 0xba, 0x72, 0xa6,
42 0xe8, 0xba, 0x53, 0xe8, 0xb9, 0x71, 0xad, 0x0c, 0x98, 0x23, 0x96, 0x8a, 0xef, 0x4d, 0x78, 0xce,
43 0x8a, 0xf2, 0x55, 0xab, 0x43, 0xdf, 0xf8, 0x30, 0x03, 0xc9, 0x02, 0xfb, 0x8d, 0x02, 0x16, 0x34,
44 0x5b, 0xf8, 0x31, 0x16, 0x4a, 0x03, 0x75, 0x8e, 0xae, 0xa5, 0xe8, 0xb6, 0x6f, 0xee, 0x2b, 0xe7,
45 0x71, 0x0b, 0x8f, 0x19, 0x0e, 0xe8, 0x80, 0x24, 0x90, 0x32, 0xa2, 0x9e, 0xd6, 0x6e
48 // A simple block containing only one transaction (which is the channel-open transaction for the
49 // channel we'll create). This was originally created by printing additional data in a simple
50 // rust-lightning unit test.
51 const uint8_t channel_open_block[] = {
52 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
54 0x00, 0x00, 0x00, 0x00, 0xa2, 0x47, 0xd2, 0xf8, 0xd4, 0xe0, 0x6a, 0x3f, 0xf9, 0x7a, 0x9a, 0x34,
55 0xbb, 0xa9, 0x96, 0xde, 0x63, 0x84, 0x5a, 0xce, 0xcf, 0x98, 0xb8, 0xbb, 0x75, 0x4c, 0x4f, 0x7d,
56 0xee, 0x4c, 0xa9, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57 0x01, // transaction count
58 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
59 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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 0x01, 0x40, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0xd1, 0xd9, 0x13, 0xa9,
62 0x76, 0x09, 0x05, 0xa3, 0x4d, 0x13, 0x5b, 0x69, 0xaa, 0xe7, 0x79, 0x71, 0xb9, 0x75, 0xa1, 0xd0,
63 0x77, 0xcb, 0xa2, 0xf6, 0x6a, 0x25, 0x37, 0x3a, 0xaf, 0xdc, 0x11, 0x09, 0x01, 0x00, 0x00, 0x00,
67 // The first transaction in the block is header (80 bytes) + transaction count (1 byte) into the block data.
68 const uint8_t channel_open_txid[] = {
69 0x02, 0xe0, 0x50, 0x05, 0x33, 0xd3, 0x29, 0x66, 0x0c, 0xb2, 0xcb, 0x1e, 0x7a, 0x4a, 0xc7, 0xc7,
70 0x8b, 0x02, 0x46, 0x7e, 0x30, 0x2c, 0xe6, 0x19, 0xce, 0x43, 0x3e, 0xdf, 0x43, 0x65, 0xae, 0xf9,
73 // Two blocks built on top of channel_open_block:
74 const uint8_t block_1[81] = {
75 0x01, 0x00, 0x00, 0x00, 0x0c, 0x7a, 0xc2, 0xdc, 0x08, 0xaf, 0x40, 0x7d, 0x58, 0x81, 0x9b, 0x44,
76 0xc7, 0xe0, 0x0f, 0x78, 0xc0, 0xd1, 0x01, 0xa2, 0x03, 0x16, 0x4a, 0x8d, 0x92, 0x66, 0x4e, 0xaf,
77 0x7f, 0xfc, 0x6e, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
78 0x00, 0x00, 0x00, 0x00, 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, // transaction count
82 const uint8_t block_2[81] = {
83 0x01, 0x00, 0x00, 0x00, 0x36, 0x0b, 0xf5, 0x46, 0x4a, 0xc7, 0x26, 0x4c, 0x4b, 0x36, 0xa6, 0x9d,
84 0x0e, 0xf0, 0x14, 0xfb, 0x8a, 0xcb, 0x20, 0x84, 0x18, 0xf3, 0xaa, 0x77, 0x32, 0x2d, 0xf7, 0x48,
85 0x62, 0x92, 0xb1, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
86 0x00, 0x00, 0x00, 0x00, 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, // transaction count
91 const LDKThirtyTwoBytes genesis_hash = { // We don't care particularly if this is "right"
92 .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 void print_log(const void *this_arg, const char *record) {
96 printf("%p - %s\n", this_arg, record);
99 uint32_t get_fee(const void *this_arg, LDKConfirmationTarget target) {
100 if (target == LDKConfirmationTarget_Background) {
105 // Note that we don't call _free() on target, but that's OK, its unitary
107 // We use the same fee estimator globally:
108 const LDKFeeEstimator fee_est {
110 .get_est_sat_per_1000_weight = get_fee,
114 static std::atomic_int num_txs_broadcasted(0);
115 void broadcast_tx(const void *this_arg, LDKTransaction tx) {
116 num_txs_broadcasted += 1;
118 Transaction_free(tx);
121 struct NodeMonitors {
123 std::vector<std::pair<LDK::OutPoint, LDK::ChannelMonitor>> mons;
126 void ConnectBlock(const uint8_t (*header)[80], uint32_t height, LDKCVec_C2Tuple_usizeTransactionZZ tx_data, LDKBroadcasterInterface broadcast, LDKFeeEstimator fee_est) {
127 std::unique_lock<std::mutex> l(mut);
128 for (auto& mon : mons) {
129 LDK::CVec_TransactionOutputsZ res = ChannelMonitor_block_connected(&mon.second, header, tx_data, height, broadcast, fee_est, *logger);
134 LDKCResult_NoneChannelMonitorUpdateErrZ add_channel_monitor(const void *this_arg, LDKOutPoint funding_txo_arg, LDKChannelMonitor monitor_arg) {
135 // First bind the args to C++ objects so they auto-free
136 LDK::ChannelMonitor mon(std::move(monitor_arg));
137 LDK::OutPoint funding_txo(std::move(funding_txo_arg));
139 NodeMonitors* arg = (NodeMonitors*) this_arg;
140 std::unique_lock<std::mutex> l(arg->mut);
142 arg->mons.push_back(std::make_pair(std::move(funding_txo), std::move(mon)));
143 return CResult_NoneChannelMonitorUpdateErrZ_ok();
145 static std::atomic_int mons_updated(0);
146 LDKCResult_NoneChannelMonitorUpdateErrZ update_channel_monitor(const void *this_arg, LDKOutPoint funding_txo_arg, LDKChannelMonitorUpdate monitor_arg) {
147 // First bind the args to C++ objects so they auto-free
148 LDK::ChannelMonitorUpdate update(std::move(monitor_arg));
149 LDK::OutPoint funding_txo(std::move(funding_txo_arg));
151 NodeMonitors* arg = (NodeMonitors*) this_arg;
152 std::unique_lock<std::mutex> l(arg->mut);
154 bool updated = false;
155 for (auto& mon : arg->mons) {
156 if (OutPoint_get_index(&mon.first) == OutPoint_get_index(&funding_txo) &&
157 !memcmp(OutPoint_get_txid(&mon.first), OutPoint_get_txid(&funding_txo), 32)) {
159 LDKBroadcasterInterface broadcaster = {
160 .broadcast_transaction = broadcast_tx,
162 LDK::CResult_NoneMonitorUpdateErrorZ res = ChannelMonitor_update_monitor(&mon.second, &update, &broadcaster, &fee_est, arg->logger);
163 assert(res->result_ok);
169 return CResult_NoneChannelMonitorUpdateErrZ_ok();
171 LDKCVec_MonitorEventZ monitors_pending_monitor_events(const void *this_arg) {
172 NodeMonitors* arg = (NodeMonitors*) this_arg;
173 std::unique_lock<std::mutex> l(arg->mut);
175 if (arg->mons.size() == 0) {
176 return LDKCVec_MonitorEventZ {
181 // We only ever actually have one channel per node, plus concatenating two
182 // Rust Vecs to each other from C++ will require a bit of effort.
183 assert(arg->mons.size() == 1);
184 return ChannelMonitor_get_and_clear_pending_monitor_events(&arg->mons[0].second);
189 std::vector<LDK::Event> events;
191 void handle_event(const void *this_arg, LDKEvent event) {
192 EventQueue* arg = (EventQueue*) this_arg;
193 arg->events.push_back(std::move(event));
197 uintptr_t sock_send_data(void *this_arg, LDKu8slice data, bool resume_read) {
198 return write((int)((long)this_arg), data.data, data.datalen);
200 void sock_disconnect_socket(void *this_arg) {
201 close((int)((long)this_arg));
203 bool sock_eq(const void *this_arg, const LDKSocketDescriptor *other_arg) {
204 return this_arg == other_arg->this_arg;
206 uint64_t sock_hash(const void *this_arg) {
207 return (uint64_t)this_arg;
209 void sock_read_data_thread(int rdfd, LDKSocketDescriptor *peer_descriptor, LDKPeerManager *pm) {
210 unsigned char buf[1024];
214 while ((readlen = read(rdfd, buf, 1024)) > 0) {
215 data.datalen = readlen;
216 LDK::CResult_boolPeerHandleErrorZ res = PeerManager_read_event(&*pm, peer_descriptor, data);
217 if (!res->result_ok) {
218 peer_descriptor->disconnect_socket(peer_descriptor->this_arg);
221 PeerManager_process_events(pm);
223 PeerManager_socket_disconnected(&*pm, peer_descriptor);
226 class PeersConnection {
227 int pipefds_1_to_2[2];
228 int pipefds_2_to_1[2];
230 LDKSocketDescriptor sock1, sock2;
233 PeersConnection(LDK::ChannelManager& cm1, LDK::ChannelManager& cm2, LDK::PeerManager& net1, LDK::PeerManager& net2) {
234 assert(!pipe(pipefds_1_to_2));
235 assert(!pipe(pipefds_2_to_1));
237 sock1 = LDKSocketDescriptor {
238 .this_arg = (void*)(long)pipefds_1_to_2[1],
239 .send_data = sock_send_data,
240 .disconnect_socket = sock_disconnect_socket,
247 sock2 = LDKSocketDescriptor {
248 .this_arg = (void*)(long)pipefds_2_to_1[1],
249 .send_data = sock_send_data,
250 .disconnect_socket = sock_disconnect_socket,
257 t1 = std::thread(&sock_read_data_thread, pipefds_2_to_1[0], &sock1, &net1);
258 t2 = std::thread(&sock_read_data_thread, pipefds_1_to_2[0], &sock2, &net2);
260 // Note that we have to bind the result to a C++ class to make sure it gets free'd
261 LDK::CResult_CVec_u8ZPeerHandleErrorZ con_res = PeerManager_new_outbound_connection(&net1, ChannelManager_get_our_node_id(&cm2), sock1);
262 assert(con_res->result_ok);
263 LDK::CResult_NonePeerHandleErrorZ con_res2 = PeerManager_new_inbound_connection(&net2, sock2);
264 assert(con_res2->result_ok);
266 auto writelen = write(pipefds_1_to_2[1], con_res->contents.result->data, con_res->contents.result->datalen);
267 assert(writelen > 0 && uint64_t(writelen) == con_res->contents.result->datalen);
270 // Wait for the initial handshakes to complete...
271 LDK::CVec_PublicKeyZ peers_1 = PeerManager_get_peer_node_ids(&net1);
272 LDK::CVec_PublicKeyZ peers_2 = PeerManager_get_peer_node_ids(&net2);
273 if (peers_1->datalen == 1 && peers_2->datalen ==1) { break; }
274 std::this_thread::yield();
279 close(pipefds_1_to_2[0]);
280 close(pipefds_2_to_1[0]);
281 close(pipefds_1_to_2[1]);
282 close(pipefds_2_to_1[1]);
289 uint8_t channel_open_header[80];
290 uint8_t header_1[80];
291 uint8_t header_2[80];
292 memcpy(channel_open_header, channel_open_block, 80);
293 memcpy(header_1, block_1, 80);
294 memcpy(header_2, block_2, 80);
296 LDKPublicKey null_pk;
297 memset(&null_pk, 0, sizeof(null_pk));
299 LDKThirtyTwoBytes random_bytes;
300 LDKThirtyTwoBytes chain_tip;
301 memset(&chain_tip, 0, sizeof(chain_tip)); // channel_open_header's prev_blockhash is all-0s
303 LDKNetwork network = LDKNetwork_Testnet;
305 // Trait implementations:
306 LDKBroadcasterInterface broadcast {
308 .broadcast_transaction = broadcast_tx,
312 // Instantiate classes for the nodes that don't get reloaded on a ser-des reload
314 .this_arg = (void*)1,
320 mons1.logger = &logger1;
323 .watch_channel = add_channel_monitor,
324 .update_channel = update_channel_monitor,
325 .release_pending_monitor_events = monitors_pending_monitor_events,
329 LDK::NetGraphMsgHandler net_graph1 = NetGraphMsgHandler_new(genesis_hash, NULL, logger1);
330 LDKSecretKey node_secret1;
333 .this_arg = (void*)2,
339 mons2.logger = &logger2;
342 .watch_channel = add_channel_monitor,
343 .update_channel = update_channel_monitor,
344 .release_pending_monitor_events = monitors_pending_monitor_events,
348 LDK::NetGraphMsgHandler net_graph2 = NetGraphMsgHandler_new(genesis_hash, NULL, logger2);
349 LDKSecretKey node_secret2;
351 LDK::CVec_u8Z cm1_ser = LDKCVec_u8Z {}; // ChannelManager 1 serialization at the end of the ser-des scope
352 LDK::CVec_u8Z cm2_ser = LDKCVec_u8Z {}; // ChannelManager 2 serialization at the end of the ser-des scope
354 { // Scope for the ser-des reload
355 // Instantiate classes for node 1:
356 uint8_t node_seed[32];
357 memset(&node_seed, 0, 32);
358 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 0, 0);
359 LDK::KeysInterface keys_source1 = KeysManager_as_KeysInterface(&keys1);
360 node_secret1 = keys_source1->get_node_secret(keys_source1->this_arg);
362 LDK::ChannelManager cm1 = ChannelManager_new(fee_est, mon1, broadcast, logger1, KeysManager_as_KeysInterface(&keys1), UserConfig_default(), ChainParameters_new(network, BestBlock_new(chain_tip, 0)));
364 LDK::CVec_ChannelDetailsZ channels = ChannelManager_list_channels(&cm1);
365 assert(channels->datalen == 0);
367 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph1));
369 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
370 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, &random_bytes.data, logger1);
372 // Demo getting a channel key and check that its returning real pubkeys:
373 LDK::Sign chan_signer1 = keys_source1->get_channel_signer(keys_source1->this_arg, false, 42);
374 chan_signer1->BaseSign.set_pubkeys(&chan_signer1->BaseSign); // Make sure pubkeys is defined
375 LDKPublicKey payment_point = ChannelPublicKeys_get_payment_point(&chan_signer1->BaseSign.pubkeys);
376 assert(memcmp(&payment_point, &null_pk, sizeof(null_pk)));
378 // Instantiate classes for node 2:
379 memset(&node_seed, 1, 32);
380 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 0, 0);
381 LDK::KeysInterface keys_source2 = KeysManager_as_KeysInterface(&keys2);
382 node_secret2 = keys_source2->get_node_secret(keys_source2->this_arg);
384 LDK::ChannelHandshakeConfig handshake_config2 = ChannelHandshakeConfig_default();
385 ChannelHandshakeConfig_set_minimum_depth(&handshake_config2, 2);
386 LDK::UserConfig config2 = UserConfig_default();
387 UserConfig_set_own_channel_config(&config2, std::move(handshake_config2));
389 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)));
391 LDK::CVec_ChannelDetailsZ channels2 = ChannelManager_list_channels(&cm2);
392 assert(channels2->datalen == 0);
394 LDK::RoutingMessageHandler net_msgs2 = NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph2);
395 LDK::CResult_ChannelAnnouncementDecodeErrorZ chan_ann = ChannelAnnouncement_read(LDKu8slice { .data = valid_node_announcement, .datalen = sizeof(valid_node_announcement) });
396 assert(chan_ann->result_ok);
397 LDK::CResult_boolLightningErrorZ ann_res = net_msgs2->handle_channel_announcement(net_msgs2->this_arg, chan_ann->contents.result);
398 assert(ann_res->result_ok);
400 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), std::move(net_msgs2));
402 random_bytes = keys_source2->get_secure_random_bytes(keys_source2->this_arg);
403 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, &random_bytes.data, logger2);
405 // Open a connection!
406 PeersConnection conn(cm1, cm2, net1, net2);
408 // Note that we have to bind the result to a C++ class to make sure it gets free'd
409 LDK::CResult_NoneAPIErrorZ res = ChannelManager_create_channel(&cm1, ChannelManager_get_our_node_id(&cm2), 40000, 1000, 42, UserConfig_default());
410 assert(res->result_ok);
411 PeerManager_process_events(&net1);
413 LDK::CVec_ChannelDetailsZ new_channels = ChannelManager_list_channels(&cm1);
414 assert(new_channels->datalen == 1);
415 LDKPublicKey chan_open_pk = ChannelDetails_get_remote_network_id(&new_channels->data[0]);
416 assert(!memcmp(chan_open_pk.compressed_form, ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
419 LDK::CVec_ChannelDetailsZ new_channels_2 = ChannelManager_list_channels(&cm2);
420 if (new_channels_2->datalen == 1) {
421 // Sample getting our counterparty's init features (which used to be hard to do without a memory leak):
422 const LDK::InitFeatures init_feats = ChannelDetails_get_counterparty_features(&new_channels_2->data[0]);
423 assert(init_feats->inner != NULL);
426 std::this_thread::yield();
429 LDKEventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1);
432 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
433 ev1.process_pending_events(ev1.this_arg, handler);
434 if (queue.events.size() == 1) {
435 assert(queue.events[0]->tag == LDKEvent_FundingGenerationReady);
436 assert(queue.events[0]->funding_generation_ready.user_channel_id == 42);
437 assert(queue.events[0]->funding_generation_ready.channel_value_satoshis == 40000);
438 assert(queue.events[0]->funding_generation_ready.output_script.datalen == 34);
439 assert(!memcmp(queue.events[0]->funding_generation_ready.output_script.data, channel_open_block + 58 + 81, 34));
440 LDKTransaction funding_transaction { .data = const_cast<uint8_t*>(channel_open_block + 81), .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false };
442 LDK::CResult_NoneAPIErrorZ fund_res = ChannelManager_funding_transaction_generated(&cm1, &queue.events[0]->funding_generation_ready.temporary_channel_id.data, funding_transaction);
443 assert(fund_res->result_ok);
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 assert(num_txs_broadcasted == 0);
452 PeerManager_process_events(&net1);
453 while (num_txs_broadcasted != 1) {
454 std::this_thread::yield();
457 LDK::Listen listener1 = ChannelManager_as_Listen(&cm1);
458 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
460 LDK::Listen listener2 = ChannelManager_as_Listen(&cm2);
461 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
463 LDKCVec_C2Tuple_usizeTransactionZZ txdata { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
464 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
465 mons1.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
467 txdata = LDKCVec_C2Tuple_usizeTransactionZZ { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
468 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
469 mons2.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
471 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
472 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
473 mons1.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
474 mons2.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
476 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
477 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
478 mons1.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
479 mons2.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
481 PeerManager_process_events(&net1);
482 PeerManager_process_events(&net2);
484 // Now send funds from 1 to 2!
486 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
487 if (outbound_channels->datalen == 1) {
488 const LDKChannelDetails *channel = &outbound_channels->data[0];
489 // Note that the channel ID is the same as the channel txid reversed as the output index is 0
490 uint8_t expected_chan_id[32];
491 for (int i = 0; i < 32; i++) { expected_chan_id[i] = channel_open_txid[31-i]; }
492 assert(!memcmp(ChannelDetails_get_channel_id(channel), expected_chan_id, 32));
493 assert(!memcmp(ChannelDetails_get_remote_network_id(channel).compressed_form,
494 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
495 assert(ChannelDetails_get_channel_value_satoshis(channel) == 40000);
496 // We opened the channel with 1000 push_msat:
497 assert(ChannelDetails_get_outbound_capacity_msat(channel) == 40000*1000 - 1000);
498 assert(ChannelDetails_get_inbound_capacity_msat(channel) == 1000);
499 assert(ChannelDetails_get_is_usable(channel));
502 std::this_thread::yield();
505 LDKCOption_u64Z min_value = {
506 .tag = LDKCOption_u64Z_Some,
509 LDK::CResult_InvoiceSignOrCreationErrorZ invoice = create_invoice_from_channelmanager(&cm2,
510 KeysManager_as_KeysInterface(&keys2),
511 LDKCurrency_Bitcoin, min_value,
513 .chars = (const uint8_t *)"Invoice Description",
514 .len = strlen("Invoice Description"),
515 .chars_is_owned = false
517 assert(invoice->result_ok);
518 LDKThirtyTwoBytes payment_hash;
519 memcpy(payment_hash.data, Invoice_payment_hash(invoice->contents.result), 32);
522 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
523 LDK::LockedNetworkGraph graph_2_locked = NetGraphMsgHandler_read_locked_graph(&net_graph2);
524 LDK::NetworkGraph graph_2_ref = LockedNetworkGraph_graph(&graph_2_locked);
525 LDK::CResult_RouteLightningErrorZ route = get_route(ChannelManager_get_our_node_id(&cm1), &graph_2_ref, ChannelManager_get_our_node_id(&cm2), LDKInvoiceFeatures {
526 .inner = NULL, .is_owned = false
527 }, &outbound_channels, LDKCVec_RouteHintHopZ {
528 .data = NULL, .datalen = 0
529 }, 5000, Invoice_min_final_cltv_expiry(invoice->contents.result), logger1);
530 assert(route->result_ok);
531 LDK::CResult_NonePaymentSendFailureZ send_res = ChannelManager_send_payment(&cm1, route->contents.result, payment_hash, Invoice_payment_secret(invoice->contents.result));
532 assert(send_res->result_ok);
536 PeerManager_process_events(&net1);
537 while (mons_updated != 4) {
538 std::this_thread::yield();
541 // Check that we received the payment!
542 LDKEventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
545 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
546 ev2.process_pending_events(ev2.this_arg, handler);
547 if (queue.events.size() == 1) {
548 assert(queue.events[0]->tag == LDKEvent_PendingHTLCsForwardable);
551 std::this_thread::yield();
553 ChannelManager_process_pending_htlc_forwards(&cm2);
554 PeerManager_process_events(&net2);
557 LDKThirtyTwoBytes payment_preimage;
560 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
561 ev2.process_pending_events(ev2.this_arg, handler);
562 assert(queue.events.size() == 1);
563 assert(queue.events[0]->tag == LDKEvent_PaymentReceived);
564 assert(!memcmp(queue.events[0]->payment_received.payment_hash.data, payment_hash.data, 32));
565 assert(!memcmp(queue.events[0]->payment_received.payment_secret.data, Invoice_payment_secret(invoice->contents.result).data, 32));
566 assert(queue.events[0]->payment_received.amt == 5000);
567 memcpy(payment_preimage.data, queue.events[0]->payment_received.payment_preimage.data, 32);
568 assert(ChannelManager_claim_funds(&cm2, payment_preimage));
570 PeerManager_process_events(&net2);
571 // Wait until we've passed through a full set of monitor updates (ie new preimage + CS/RAA messages)
572 while (mons_updated != 5) {
573 std::this_thread::yield();
577 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
578 ev1.process_pending_events(ev1.this_arg, handler);
579 assert(queue.events.size() == 1);
580 assert(queue.events[0]->tag == LDKEvent_PaymentSent);
581 assert(!memcmp(queue.events[0]->payment_sent.payment_preimage.data, payment_preimage.data, 32));
586 cm1_ser = ChannelManager_write(&cm1);
587 cm2_ser = ChannelManager_write(&cm2);
590 LDK::CVec_ChannelMonitorZ mons_list1 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
591 assert(mons1.mons.size() == 1);
592 mons_list1->data[0] = *& std::get<1>(mons1.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
593 mons_list1->data[0].is_owned = false; // XXX: God this sucks
594 uint8_t node_seed[32];
595 memset(&node_seed, 0, 32);
596 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 1, 0);
597 LDK::KeysInterface keys_source1 = KeysManager_as_KeysInterface(&keys1);
599 LDK::ChannelManagerReadArgs cm1_args = ChannelManagerReadArgs_new(KeysManager_as_KeysInterface(&keys1), fee_est, mon1, broadcast, logger1, UserConfig_default(), std::move(mons_list1));
600 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm1_read =
601 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm1_ser->data, .datalen = cm1_ser -> datalen}, std::move(cm1_args));
602 assert(cm1_read->result_ok);
603 LDK::ChannelManager cm1(std::move(cm1_read->contents.result->b));
605 LDK::CVec_ChannelMonitorZ mons_list2 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
606 assert(mons2.mons.size() == 1);
607 mons_list2->data[0] = *& std::get<1>(mons2.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
608 mons_list2->data[0].is_owned = false; // XXX: God this sucks
609 memset(&node_seed, 1, 32);
610 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 1, 0);
612 LDK::ChannelManagerReadArgs cm2_args = ChannelManagerReadArgs_new(KeysManager_as_KeysInterface(&keys2), fee_est, mon2, broadcast, logger2, UserConfig_default(), std::move(mons_list2));
613 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm2_read =
614 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm2_ser->data, .datalen = cm2_ser -> datalen}, std::move(cm2_args));
615 assert(cm2_read->result_ok);
616 LDK::ChannelManager cm2(std::move(cm2_read->contents.result->b));
618 // Attempt to close the channel...
620 for (int i = 0; i < 32; i++) { chan_id[i] = channel_open_txid[31-i]; }
621 LDK::CResult_NoneAPIErrorZ close_res = ChannelManager_close_channel(&cm1, &chan_id);
622 assert(!close_res->result_ok); // Note that we can't close while disconnected!
624 // Open a connection!
625 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph1));
626 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
627 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, &random_bytes.data, logger1);
629 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph2));
630 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
631 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, &random_bytes.data, logger2);
633 PeersConnection conn(cm1, cm2, net1, net2);
636 // Wait for the channels to be considered up once the reestablish messages are processed
637 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
638 if (outbound_channels->datalen == 1) {
643 // Actually close the channel
644 close_res = ChannelManager_close_channel(&cm1, &chan_id);
645 assert(close_res->result_ok);
646 PeerManager_process_events(&net1);
647 num_txs_broadcasted = 0;
648 while (num_txs_broadcasted != 2) {
649 std::this_thread::yield();
651 LDK::CVec_ChannelDetailsZ chans_after_close1 = ChannelManager_list_channels(&cm1);
652 assert(chans_after_close1->datalen == 0);
653 LDK::CVec_ChannelDetailsZ chans_after_close2 = ChannelManager_list_channels(&cm2);
654 assert(chans_after_close2->datalen == 0);
658 // Few extra random tests:
661 LDKThirtyTwoBytes kdiv_params;
662 memset(&kdiv_params, 43, 32);
663 LDK::InMemorySigner signer = InMemorySigner_new(sk, sk, sk, sk, sk, random_bytes, 42, kdiv_params);