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);
188 uintptr_t sock_send_data(void *this_arg, LDKu8slice data, bool resume_read) {
189 return write((int)((long)this_arg), data.data, data.datalen);
191 void sock_disconnect_socket(void *this_arg) {
192 close((int)((long)this_arg));
194 bool sock_eq(const void *this_arg, const LDKSocketDescriptor *other_arg) {
195 return this_arg == other_arg->this_arg;
197 uint64_t sock_hash(const void *this_arg) {
198 return (uint64_t)this_arg;
200 void sock_read_data_thread(int rdfd, LDKSocketDescriptor *peer_descriptor, LDKPeerManager *pm) {
201 unsigned char buf[1024];
205 while ((readlen = read(rdfd, buf, 1024)) > 0) {
206 data.datalen = readlen;
207 LDK::CResult_boolPeerHandleErrorZ res = PeerManager_read_event(&*pm, peer_descriptor, data);
208 if (!res->result_ok) {
209 peer_descriptor->disconnect_socket(peer_descriptor->this_arg);
212 PeerManager_process_events(pm);
214 PeerManager_socket_disconnected(&*pm, peer_descriptor);
217 class PeersConnection {
218 int pipefds_1_to_2[2];
219 int pipefds_2_to_1[2];
221 LDKSocketDescriptor sock1, sock2;
224 PeersConnection(LDK::ChannelManager& cm1, LDK::ChannelManager& cm2, LDK::PeerManager& net1, LDK::PeerManager& net2) {
225 assert(!pipe(pipefds_1_to_2));
226 assert(!pipe(pipefds_2_to_1));
228 sock1 = LDKSocketDescriptor {
229 .this_arg = (void*)(long)pipefds_1_to_2[1],
230 .send_data = sock_send_data,
231 .disconnect_socket = sock_disconnect_socket,
238 sock2 = LDKSocketDescriptor {
239 .this_arg = (void*)(long)pipefds_2_to_1[1],
240 .send_data = sock_send_data,
241 .disconnect_socket = sock_disconnect_socket,
248 t1 = std::thread(&sock_read_data_thread, pipefds_2_to_1[0], &sock1, &net1);
249 t2 = std::thread(&sock_read_data_thread, pipefds_1_to_2[0], &sock2, &net2);
251 // Note that we have to bind the result to a C++ class to make sure it gets free'd
252 LDK::CResult_CVec_u8ZPeerHandleErrorZ con_res = PeerManager_new_outbound_connection(&net1, ChannelManager_get_our_node_id(&cm2), sock1);
253 assert(con_res->result_ok);
254 LDK::CResult_NonePeerHandleErrorZ con_res2 = PeerManager_new_inbound_connection(&net2, sock2);
255 assert(con_res2->result_ok);
257 auto writelen = write(pipefds_1_to_2[1], con_res->contents.result->data, con_res->contents.result->datalen);
258 assert(writelen > 0 && uint64_t(writelen) == con_res->contents.result->datalen);
261 // Wait for the initial handshakes to complete...
262 LDK::CVec_PublicKeyZ peers_1 = PeerManager_get_peer_node_ids(&net1);
263 LDK::CVec_PublicKeyZ peers_2 = PeerManager_get_peer_node_ids(&net2);
264 if (peers_1->datalen == 1 && peers_2->datalen ==1) { break; }
265 std::this_thread::yield();
270 close(pipefds_1_to_2[0]);
271 close(pipefds_2_to_1[0]);
272 close(pipefds_1_to_2[1]);
273 close(pipefds_2_to_1[1]);
280 uint8_t channel_open_header[80];
281 uint8_t header_1[80];
282 uint8_t header_2[80];
283 memcpy(channel_open_header, channel_open_block, 80);
284 memcpy(header_1, block_1, 80);
285 memcpy(header_2, block_2, 80);
287 LDKPublicKey null_pk;
288 memset(&null_pk, 0, sizeof(null_pk));
290 LDKThirtyTwoBytes random_bytes;
291 LDKThirtyTwoBytes chain_tip;
292 memset(&chain_tip, 0, sizeof(chain_tip)); // channel_open_header's prev_blockhash is all-0s
294 LDKNetwork network = LDKNetwork_Testnet;
296 // Trait implementations:
297 LDKBroadcasterInterface broadcast {
299 .broadcast_transaction = broadcast_tx,
303 // Instantiate classes for the nodes that don't get reloaded on a ser-des reload
305 .this_arg = (void*)1,
311 mons1.logger = &logger1;
314 .watch_channel = add_channel_monitor,
315 .update_channel = update_channel_monitor,
316 .release_pending_monitor_events = monitors_pending_monitor_events,
320 LDK::NetGraphMsgHandler net_graph1 = NetGraphMsgHandler_new(genesis_hash, NULL, logger1);
321 LDKSecretKey node_secret1;
324 .this_arg = (void*)2,
330 mons2.logger = &logger2;
333 .watch_channel = add_channel_monitor,
334 .update_channel = update_channel_monitor,
335 .release_pending_monitor_events = monitors_pending_monitor_events,
339 LDK::NetGraphMsgHandler net_graph2 = NetGraphMsgHandler_new(genesis_hash, NULL, logger2);
340 LDKSecretKey node_secret2;
342 LDK::CVec_u8Z cm1_ser = LDKCVec_u8Z {}; // ChannelManager 1 serialization at the end of the ser-des scope
343 LDK::CVec_u8Z cm2_ser = LDKCVec_u8Z {}; // ChannelManager 2 serialization at the end of the ser-des scope
345 { // Scope for the ser-des reload
346 // Instantiate classes for node 1:
347 uint8_t node_seed[32];
348 memset(&node_seed, 0, 32);
349 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 0, 0);
350 LDK::KeysInterface keys_source1 = KeysManager_as_KeysInterface(&keys1);
351 node_secret1 = keys_source1->get_node_secret(keys_source1->this_arg);
353 LDK::ChannelManager cm1 = ChannelManager_new(fee_est, mon1, broadcast, logger1, KeysManager_as_KeysInterface(&keys1), UserConfig_default(), ChainParameters_new(network, BestBlock_new(chain_tip, 0)));
355 LDK::CVec_ChannelDetailsZ channels = ChannelManager_list_channels(&cm1);
356 assert(channels->datalen == 0);
358 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph1));
360 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
361 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, &random_bytes.data, logger1);
363 // Demo getting a channel key and check that its returning real pubkeys:
364 LDK::Sign chan_signer1 = keys_source1->get_channel_signer(keys_source1->this_arg, false, 42);
365 chan_signer1->BaseSign.set_pubkeys(&chan_signer1->BaseSign); // Make sure pubkeys is defined
366 LDKPublicKey payment_point = ChannelPublicKeys_get_payment_point(&chan_signer1->BaseSign.pubkeys);
367 assert(memcmp(&payment_point, &null_pk, sizeof(null_pk)));
369 // Instantiate classes for node 2:
370 memset(&node_seed, 1, 32);
371 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 0, 0);
372 LDK::KeysInterface keys_source2 = KeysManager_as_KeysInterface(&keys2);
373 node_secret2 = keys_source2->get_node_secret(keys_source2->this_arg);
375 LDK::ChannelHandshakeConfig handshake_config2 = ChannelHandshakeConfig_default();
376 ChannelHandshakeConfig_set_minimum_depth(&handshake_config2, 2);
377 LDK::UserConfig config2 = UserConfig_default();
378 UserConfig_set_own_channel_config(&config2, std::move(handshake_config2));
380 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)));
382 LDK::CVec_ChannelDetailsZ channels2 = ChannelManager_list_channels(&cm2);
383 assert(channels2->datalen == 0);
385 LDK::RoutingMessageHandler net_msgs2 = NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph2);
386 LDK::CResult_ChannelAnnouncementDecodeErrorZ chan_ann = ChannelAnnouncement_read(LDKu8slice { .data = valid_node_announcement, .datalen = sizeof(valid_node_announcement) });
387 assert(chan_ann->result_ok);
388 LDK::CResult_boolLightningErrorZ ann_res = net_msgs2->handle_channel_announcement(net_msgs2->this_arg, chan_ann->contents.result);
389 assert(ann_res->result_ok);
391 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), std::move(net_msgs2));
393 random_bytes = keys_source2->get_secure_random_bytes(keys_source2->this_arg);
394 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, &random_bytes.data, logger2);
396 // Open a connection!
397 PeersConnection conn(cm1, cm2, net1, net2);
399 // Note that we have to bind the result to a C++ class to make sure it gets free'd
400 LDK::CResult_NoneAPIErrorZ res = ChannelManager_create_channel(&cm1, ChannelManager_get_our_node_id(&cm2), 40000, 1000, 42, UserConfig_default());
401 assert(res->result_ok);
402 PeerManager_process_events(&net1);
404 LDK::CVec_ChannelDetailsZ new_channels = ChannelManager_list_channels(&cm1);
405 assert(new_channels->datalen == 1);
406 LDKPublicKey chan_open_pk = ChannelDetails_get_remote_network_id(&new_channels->data[0]);
407 assert(!memcmp(chan_open_pk.compressed_form, ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
410 LDK::CVec_ChannelDetailsZ new_channels_2 = ChannelManager_list_channels(&cm2);
411 if (new_channels_2->datalen == 1) {
412 // Sample getting our counterparty's init features (which used to be hard to do without a memory leak):
413 const LDK::InitFeatures init_feats = ChannelDetails_get_counterparty_features(&new_channels_2->data[0]);
414 assert(init_feats->inner != NULL);
417 std::this_thread::yield();
420 LDKEventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1);
422 LDK::CVec_EventZ events = ev1.get_and_clear_pending_events(ev1.this_arg);
423 if (events->datalen == 1) {
424 assert(events->data[0].tag == LDKEvent_FundingGenerationReady);
425 assert(events->data[0].funding_generation_ready.user_channel_id == 42);
426 assert(events->data[0].funding_generation_ready.channel_value_satoshis == 40000);
427 assert(events->data[0].funding_generation_ready.output_script.datalen == 34);
428 assert(!memcmp(events->data[0].funding_generation_ready.output_script.data, channel_open_block + 58 + 81, 34));
429 LDKTransaction funding_transaction { .data = const_cast<uint8_t*>(channel_open_block + 81), .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false };
431 LDK::CResult_NoneAPIErrorZ fund_res = ChannelManager_funding_transaction_generated(&cm1, &events->data[0].funding_generation_ready.temporary_channel_id.data, funding_transaction);
432 assert(fund_res->result_ok);
435 std::this_thread::yield();
438 // We observe when the funding signed messages have been exchanged by
439 // waiting for two monitors to be registered.
440 assert(num_txs_broadcasted == 0);
441 PeerManager_process_events(&net1);
442 while (num_txs_broadcasted != 1) {
443 std::this_thread::yield();
446 LDK::Listen listener1 = ChannelManager_as_Listen(&cm1);
447 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
449 LDK::Listen listener2 = ChannelManager_as_Listen(&cm2);
450 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
452 LDKCVec_C2Tuple_usizeTransactionZZ txdata { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
453 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
454 mons1.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
456 txdata = LDKCVec_C2Tuple_usizeTransactionZZ { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
457 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
458 mons2.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
460 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
461 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
462 mons1.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
463 mons2.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
465 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
466 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
467 mons1.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
468 mons2.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
470 PeerManager_process_events(&net1);
471 PeerManager_process_events(&net2);
473 // Now send funds from 1 to 2!
475 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
476 if (outbound_channels->datalen == 1) {
477 const LDKChannelDetails *channel = &outbound_channels->data[0];
478 // Note that the channel ID is the same as the channel txid reversed as the output index is 0
479 uint8_t expected_chan_id[32];
480 for (int i = 0; i < 32; i++) { expected_chan_id[i] = channel_open_txid[31-i]; }
481 assert(!memcmp(ChannelDetails_get_channel_id(channel), expected_chan_id, 32));
482 assert(!memcmp(ChannelDetails_get_remote_network_id(channel).compressed_form,
483 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
484 assert(ChannelDetails_get_channel_value_satoshis(channel) == 40000);
485 // We opened the channel with 1000 push_msat:
486 assert(ChannelDetails_get_outbound_capacity_msat(channel) == 40000*1000 - 1000);
487 assert(ChannelDetails_get_inbound_capacity_msat(channel) == 1000);
488 assert(ChannelDetails_get_is_live(channel));
491 std::this_thread::yield();
494 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
495 LDKCOption_u64Z min_value = {
496 .tag = LDKCOption_u64Z_Some,
499 LDK::C2Tuple_PaymentHashPaymentSecretZ payment_hash_secret = ChannelManager_create_inbound_payment(&cm2, min_value, 3600, 43);
501 LDK::LockedNetworkGraph graph_2_locked = NetGraphMsgHandler_read_locked_graph(&net_graph2);
502 LDK::NetworkGraph graph_2_ref = LockedNetworkGraph_graph(&graph_2_locked);
503 LDK::CResult_RouteLightningErrorZ route = get_route(ChannelManager_get_our_node_id(&cm1), &graph_2_ref, ChannelManager_get_our_node_id(&cm2), LDKInvoiceFeatures {
504 .inner = NULL, .is_owned = false
505 }, &outbound_channels, LDKCVec_RouteHintHopZ {
506 .data = NULL, .datalen = 0
507 }, 5000, 10, logger1);
508 assert(route->result_ok);
509 LDK::CResult_NonePaymentSendFailureZ send_res = ChannelManager_send_payment(&cm1, route->contents.result, payment_hash_secret->a, payment_hash_secret->b);
510 assert(send_res->result_ok);
514 PeerManager_process_events(&net1);
515 while (mons_updated != 4) {
516 std::this_thread::yield();
519 // Check that we received the payment!
520 LDKEventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
522 LDK::CVec_EventZ events = ev2.get_and_clear_pending_events(ev2.this_arg);
523 if (events->datalen == 1) {
524 assert(events->data[0].tag == LDKEvent_PendingHTLCsForwardable);
527 std::this_thread::yield();
529 ChannelManager_process_pending_htlc_forwards(&cm2);
530 PeerManager_process_events(&net2);
533 LDKThirtyTwoBytes payment_preimage;
535 LDK::CVec_EventZ events = ev2.get_and_clear_pending_events(ev2.this_arg);
536 assert(events->datalen == 1);
537 assert(events->data[0].tag == LDKEvent_PaymentReceived);
538 assert(!memcmp(events->data[0].payment_received.payment_hash.data, payment_hash_secret->a.data, 32));
539 assert(!memcmp(events->data[0].payment_received.payment_secret.data, payment_hash_secret->b.data, 32));
540 assert(events->data[0].payment_received.amt == 5000);
541 memcpy(payment_preimage.data, events->data[0].payment_received.payment_preimage.data, 32);
542 assert(ChannelManager_claim_funds(&cm2, payment_preimage));
544 PeerManager_process_events(&net2);
545 // Wait until we've passed through a full set of monitor updates (ie new preimage + CS/RAA messages)
546 while (mons_updated != 5) {
547 std::this_thread::yield();
550 LDK::CVec_EventZ events = ev1.get_and_clear_pending_events(ev1.this_arg);
551 assert(events->datalen == 1);
552 assert(events->data[0].tag == LDKEvent_PaymentSent);
553 assert(!memcmp(events->data[0].payment_sent.payment_preimage.data, payment_preimage.data, 32));
558 cm1_ser = ChannelManager_write(&cm1);
559 cm2_ser = ChannelManager_write(&cm2);
562 LDK::CVec_ChannelMonitorZ mons_list1 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
563 assert(mons1.mons.size() == 1);
564 mons_list1->data[0] = *& std::get<1>(mons1.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
565 mons_list1->data[0].is_owned = false; // XXX: God this sucks
566 uint8_t node_seed[32];
567 memset(&node_seed, 0, 32);
568 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 1, 0);
569 LDK::KeysInterface keys_source1 = KeysManager_as_KeysInterface(&keys1);
571 LDK::ChannelManagerReadArgs cm1_args = ChannelManagerReadArgs_new(KeysManager_as_KeysInterface(&keys1), fee_est, mon1, broadcast, logger1, UserConfig_default(), std::move(mons_list1));
572 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm1_read =
573 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm1_ser->data, .datalen = cm1_ser -> datalen}, std::move(cm1_args));
574 assert(cm1_read->result_ok);
575 LDK::ChannelManager cm1(std::move(cm1_read->contents.result->b));
577 LDK::CVec_ChannelMonitorZ mons_list2 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
578 assert(mons2.mons.size() == 1);
579 mons_list2->data[0] = *& std::get<1>(mons2.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
580 mons_list2->data[0].is_owned = false; // XXX: God this sucks
581 memset(&node_seed, 1, 32);
582 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 1, 0);
584 LDK::ChannelManagerReadArgs cm2_args = ChannelManagerReadArgs_new(KeysManager_as_KeysInterface(&keys2), fee_est, mon2, broadcast, logger2, UserConfig_default(), std::move(mons_list2));
585 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm2_read =
586 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm2_ser->data, .datalen = cm2_ser -> datalen}, std::move(cm2_args));
587 assert(cm2_read->result_ok);
588 LDK::ChannelManager cm2(std::move(cm2_read->contents.result->b));
590 // Attempt to close the channel...
592 for (int i = 0; i < 32; i++) { chan_id[i] = channel_open_txid[31-i]; }
593 LDK::CResult_NoneAPIErrorZ close_res = ChannelManager_close_channel(&cm1, &chan_id);
594 assert(!close_res->result_ok); // Note that we can't close while disconnected!
596 // Open a connection!
597 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph1));
598 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
599 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, &random_bytes.data, logger1);
601 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph2));
602 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
603 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, &random_bytes.data, logger2);
605 PeersConnection conn(cm1, cm2, net1, net2);
608 // Wait for the channels to be considered up once the reestablish messages are processed
609 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
610 if (outbound_channels->datalen == 1) {
615 // Actually close the channel
616 close_res = ChannelManager_close_channel(&cm1, &chan_id);
617 assert(close_res->result_ok);
618 PeerManager_process_events(&net1);
619 num_txs_broadcasted = 0;
620 while (num_txs_broadcasted != 2) {
621 std::this_thread::yield();
623 LDK::CVec_ChannelDetailsZ chans_after_close1 = ChannelManager_list_channels(&cm1);
624 assert(chans_after_close1->datalen == 0);
625 LDK::CVec_ChannelDetailsZ chans_after_close2 = ChannelManager_list_channels(&cm2);
626 assert(chans_after_close2->datalen == 0);
630 // Few extra random tests:
633 LDKThirtyTwoBytes kdiv_params;
634 memset(&kdiv_params, 43, 32);
635 LDK::InMemorySigner signer = InMemorySigner_new(sk, sk, sk, sk, sk, random_bytes, 42, kdiv_params);