8 #include "include/lightningpp.hpp"
12 #include <sys/socket.h>
13 #include <netinet/in.h>
14 #include <arpa/inet.h>
25 const uint8_t valid_node_announcement[] = {
26 0x94, 0xe4, 0xf5, 0x61, 0x41, 0x24, 0x7d, 0x90, 0x23, 0xa0, 0xc8, 0x34, 0x8c, 0xc4, 0xca, 0x51,
27 0xd8, 0x17, 0x59, 0xff, 0x7d, 0xac, 0x8c, 0x9b, 0x63, 0x29, 0x1c, 0xe6, 0x12, 0x12, 0x93, 0xbd,
28 0x66, 0x4d, 0x6b, 0x9c, 0xfb, 0x35, 0xda, 0x16, 0x06, 0x3d, 0xf0, 0x8f, 0x8a, 0x39, 0x99, 0xa2,
29 0xf2, 0x5d, 0x12, 0x0f, 0x2b, 0x42, 0x1b, 0x8b, 0x9a, 0xfe, 0x33, 0x0c, 0xeb, 0x33, 0x5e, 0x52,
30 0xee, 0x99, 0xa1, 0x07, 0x06, 0xed, 0xf8, 0x48, 0x7a, 0xc6, 0xe5, 0xf5, 0x5e, 0x01, 0x3a, 0x41,
31 0x2f, 0x18, 0x94, 0x8a, 0x3b, 0x0a, 0x52, 0x3f, 0xbf, 0x61, 0xa9, 0xc5, 0x4f, 0x70, 0xee, 0xb8,
32 0x79, 0x23, 0xbb, 0x1a, 0x44, 0x7d, 0x91, 0xe6, 0x2a, 0xbc, 0xa1, 0x07, 0xbc, 0x65, 0x3b, 0x02,
33 0xd9, 0x1d, 0xb2, 0xf2, 0x3a, 0xcb, 0x75, 0x79, 0xc6, 0x66, 0xd8, 0xc1, 0x71, 0x29, 0xdf, 0x04,
34 0x60, 0xf4, 0xbf, 0x07, 0x7b, 0xb9, 0xc2, 0x11, 0x94, 0x6a, 0x28, 0xc2, 0xdd, 0xd8, 0x7b, 0x44,
35 0x8f, 0x08, 0xe3, 0xc8, 0xd8, 0xf4, 0x81, 0xb0, 0x9f, 0x94, 0xcb, 0xc8, 0xc1, 0x3c, 0xc2, 0x6e,
36 0x31, 0x26, 0xfc, 0x33, 0x16, 0x3b, 0xe0, 0xde, 0xa1, 0x16, 0x21, 0x9f, 0x89, 0xdd, 0x97, 0xa4,
37 0x41, 0xf2, 0x9f, 0x19, 0xb1, 0xae, 0x82, 0xf7, 0x85, 0x9a, 0xb7, 0x8f, 0xb7, 0x52, 0x7a, 0x72,
38 0xf1, 0x5e, 0x89, 0xe1, 0x8a, 0xcd, 0x40, 0xb5, 0x8e, 0xc3, 0xca, 0x42, 0x76, 0xa3, 0x6e, 0x1b,
39 0xf4, 0x87, 0x35, 0x30, 0x58, 0x43, 0x04, 0xd9, 0x2c, 0x50, 0x54, 0x55, 0x47, 0x6f, 0x70, 0x9b,
40 0x42, 0x1f, 0x91, 0xfc, 0xa1, 0xdb, 0x72, 0x53, 0x96, 0xc8, 0xe5, 0xcd, 0x0e, 0xcb, 0xa0, 0xfe,
41 0x6b, 0x08, 0x77, 0x48, 0xb7, 0xad, 0x4a, 0x69, 0x7c, 0xdc, 0xd8, 0x04, 0x28, 0x35, 0x9b, 0x73,
42 0x00, 0x00, 0x43, 0x49, 0x7f, 0xd7, 0xf8, 0x26, 0x95, 0x71, 0x08, 0xf4, 0xa3, 0x0f, 0xd9, 0xce,
43 0xc3, 0xae, 0xba, 0x79, 0x97, 0x20, 0x84, 0xe9, 0x0e, 0xad, 0x01, 0xea, 0x33, 0x09, 0x00, 0x00,
44 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x5b, 0xe5, 0xe9, 0x47, 0x82,
45 0x09, 0x67, 0x4a, 0x96, 0xe6, 0x0f, 0x1f, 0x03, 0x7f, 0x61, 0x76, 0x54, 0x0f, 0xd0, 0x01, 0xfa,
46 0x1d, 0x64, 0x69, 0x47, 0x70, 0xc5, 0x6a, 0x77, 0x09, 0xc4, 0x2c, 0x03, 0x5c, 0x4e, 0x0d, 0xec,
47 0x72, 0x15, 0xe2, 0x68, 0x33, 0x93, 0x87, 0x30, 0xe5, 0xe5, 0x05, 0xaa, 0x62, 0x50, 0x4d, 0xa8,
48 0x5b, 0xa5, 0x71, 0x06, 0xa4, 0x6b, 0x5a, 0x24, 0x04, 0xfc, 0x9d, 0x8e, 0x02, 0xba, 0x72, 0xa6,
49 0xe8, 0xba, 0x53, 0xe8, 0xb9, 0x71, 0xad, 0x0c, 0x98, 0x23, 0x96, 0x8a, 0xef, 0x4d, 0x78, 0xce,
50 0x8a, 0xf2, 0x55, 0xab, 0x43, 0xdf, 0xf8, 0x30, 0x03, 0xc9, 0x02, 0xfb, 0x8d, 0x02, 0x16, 0x34,
51 0x5b, 0xf8, 0x31, 0x16, 0x4a, 0x03, 0x75, 0x8e, 0xae, 0xa5, 0xe8, 0xb6, 0x6f, 0xee, 0x2b, 0xe7,
52 0x71, 0x0b, 0x8f, 0x19, 0x0e, 0xe8, 0x80, 0x24, 0x90, 0x32, 0xa2, 0x9e, 0xd6, 0x6e
55 // A simple block containing only one transaction (which is the channel-open transaction for the
56 // channel we'll create). This was originally created by printing additional data in a simple
57 // rust-lightning unit test.
59 // Note that the merkle root is incorrect, but it isn't ever checked by LDK, so should be fine.
60 const uint8_t channel_open_block[] = {
61 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63 0x00, 0x00, 0x00, 0x00, 0xa2, 0x47, 0xd2, 0xf8, 0xd4, 0xe0, 0x6a, 0x3f, 0xf9, 0x7a, 0x9a, 0x34,
64 0xbb, 0xa9, 0x96, 0xde, 0x63, 0x84, 0x5a, 0xce, 0xcf, 0x98, 0xb8, 0xbb, 0x75, 0x4c, 0x4f, 0x7d,
65 0xee, 0x4c, 0xa9, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66 0x01, // transaction count
67 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
69 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
70 0x01, 0x40, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0xc5, 0x1c, 0xad, 0x5e,
71 0x51, 0x11, 0xb0, 0x11, 0xa1, 0x14, 0xf4, 0xda, 0x02, 0x3d, 0xbc, 0xc1, 0x44, 0x3c, 0x67, 0x31,
72 0xec, 0x6f, 0x10, 0x2f, 0x89, 0xc1, 0x05, 0x80, 0xfe, 0xfc, 0xd6, 0xc7, 0x01, 0x00, 0x00, 0x00,
76 // The first transaction in the block is header (80 bytes) + transaction count (1 byte) into the block data.
77 const uint8_t channel_open_txid[] = {
78 0x7a, 0x14, 0x8f, 0xb4, 0x08, 0x49, 0x9b, 0x51, 0x2e, 0xff, 0xf9, 0x46, 0x73, 0xca, 0xc6, 0x48,
79 0xfd, 0x95, 0x0e, 0x72, 0xd4, 0xd3, 0xdb, 0x79, 0xc9, 0x20, 0xed, 0x83, 0xb2, 0xde, 0xed, 0x41,
82 // Two blocks built on top of channel_open_block:
83 const uint8_t block_1[81] = {
84 0x01, 0x00, 0x00, 0x00, 0x0c, 0x7a, 0xc2, 0xdc, 0x08, 0xaf, 0x40, 0x7d, 0x58, 0x81, 0x9b, 0x44,
85 0xc7, 0xe0, 0x0f, 0x78, 0xc0, 0xd1, 0x01, 0xa2, 0x03, 0x16, 0x4a, 0x8d, 0x92, 0x66, 0x4e, 0xaf,
86 0x7f, 0xfc, 0x6e, 0x0c, 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
91 const uint8_t block_2[81] = {
92 0x01, 0x00, 0x00, 0x00, 0x36, 0x0b, 0xf5, 0x46, 0x4a, 0xc7, 0x26, 0x4c, 0x4b, 0x36, 0xa6, 0x9d,
93 0x0e, 0xf0, 0x14, 0xfb, 0x8a, 0xcb, 0x20, 0x84, 0x18, 0xf3, 0xaa, 0x77, 0x32, 0x2d, 0xf7, 0x48,
94 0x62, 0x92, 0xb1, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
95 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
96 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
97 0x00, // transaction count
100 void print_log(const void *this_arg, const LDKRecord *record) {
101 LDK::Str mod = Record_get_module_path(record);
102 LDK::Str str = Record_get_args(record);
103 printf("%p - %.*s:%d - %.*s\n", this_arg, (int)mod->len, mod->chars, Record_get_line(record), (int)str->len, str->chars);
106 uint32_t get_fee(const void *this_arg, LDKConfirmationTarget target) {
107 if (target == LDKConfirmationTarget_AnchorChannelFee || target == LDKConfirmationTarget_MinAllowedAnchorChannelRemoteFee) {
112 // Note that we don't call _free() on target, but that's OK, its unitary
114 // We use the same fee estimator globally:
115 const LDKFeeEstimator fee_est {
117 .get_est_sat_per_1000_weight = get_fee,
121 static std::atomic_int num_txs_broadcasted(0);
122 void broadcast_txn(const void *this_arg, LDKCVec_TransactionZ txn) {
123 num_txs_broadcasted += 1;
124 CVec_TransactionZ_free(txn);
127 struct NodeMonitors {
129 std::vector<std::pair<LDK::OutPoint, LDK::ChannelMonitor>> mons;
132 void ConnectBlock(const uint8_t (*header)[80], uint32_t height, LDKCVec_C2Tuple_usizeTransactionZZ tx_data, LDKBroadcasterInterface broadcast, LDKFeeEstimator fee_est) {
133 std::unique_lock<std::mutex> l(mut);
134 for (auto& mon : mons) {
135 LDK::CVec_TransactionOutputsZ res = ChannelMonitor_block_connected(&mon.second, header, tx_data, height, broadcast, fee_est, *logger);
140 LDKCResult_ChannelMonitorUpdateStatusNoneZ add_channel_monitor(const void *this_arg, LDKOutPoint funding_txo_arg, LDKChannelMonitor monitor_arg) {
141 // First bind the args to C++ objects so they auto-free
142 LDK::ChannelMonitor mon(std::move(monitor_arg));
143 LDK::OutPoint funding_txo(std::move(funding_txo_arg));
145 NodeMonitors* arg = (NodeMonitors*) this_arg;
146 std::unique_lock<std::mutex> l(arg->mut);
148 arg->mons.push_back(std::make_pair(std::move(funding_txo), std::move(mon)));
149 return CResult_ChannelMonitorUpdateStatusNoneZ_ok(ChannelMonitorUpdateStatus_completed());
151 static std::atomic_int mons_updated(0);
152 LDKChannelMonitorUpdateStatus update_channel_monitor(const void *this_arg, LDKOutPoint funding_txo_arg, const LDKChannelMonitorUpdate *update) {
153 // First bind the args to C++ objects so they auto-free
154 LDK::OutPoint funding_txo(std::move(funding_txo_arg));
156 NodeMonitors* arg = (NodeMonitors*) this_arg;
157 std::unique_lock<std::mutex> l(arg->mut);
159 bool updated = false;
160 for (auto& mon : arg->mons) {
161 if (OutPoint_get_index(&mon.first) == OutPoint_get_index(&funding_txo) &&
162 !memcmp(OutPoint_get_txid(&mon.first), OutPoint_get_txid(&funding_txo), 32)) {
164 LDKBroadcasterInterface broadcaster = {
165 .broadcast_transactions = broadcast_txn,
167 LDK::CResult_NoneNoneZ res = ChannelMonitor_update_monitor(&mon.second, update, &broadcaster, &fee_est, arg->logger);
168 assert(res->result_ok);
174 return ChannelMonitorUpdateStatus_completed();
176 LDKCVec_C3Tuple_OutPointCVec_MonitorEventZPublicKeyZZ monitors_pending_monitor_events(const void *this_arg) {
177 NodeMonitors* arg = (NodeMonitors*) this_arg;
178 std::unique_lock<std::mutex> l(arg->mut);
180 if (arg->mons.size() == 0) {
181 return LDKCVec_C3Tuple_OutPointCVec_MonitorEventZPublicKeyZZ {
186 // We only ever actually have one channel per node, plus concatenating two
187 // Rust Vecs to each other from C++ will require a bit of effort.
188 assert(arg->mons.size() == 1);
189 LDK::CVec_MonitorEventZ events = ChannelMonitor_get_and_clear_pending_monitor_events(&arg->mons[0].second);
190 LDK::C2Tuple_OutPointCVec_u8ZZ funding_info = ChannelMonitor_get_funding_txo(&arg->mons[0].second);
191 LDK::OutPoint outpoint = std::move(funding_info->a);
192 LDKPublicKey counterparty_node_id = ChannelMonitor_get_counterparty_node_id(&arg->mons[0].second);
193 LDK::C3Tuple_OutPointCVec_MonitorEventZPublicKeyZ tuple = C3Tuple_OutPointCVec_MonitorEventZPublicKeyZ_new(std::move(outpoint), std::move(events), std::move(counterparty_node_id));
194 auto vec = LDKCVec_C3Tuple_OutPointCVec_MonitorEventZPublicKeyZZ {
195 .data = (LDKC3Tuple_OutPointCVec_MonitorEventZPublicKeyZ*)malloc(sizeof(LDKC3Tuple_OutPointCVec_MonitorEventZPublicKeyZ)),
198 vec.data[0] = std::move(tuple);
204 std::vector<LDK::Event> events;
206 void handle_event(const void *this_arg, LDKEvent event) {
207 EventQueue* arg = (EventQueue*) this_arg;
208 arg->events.push_back(std::move(event));
212 class PeersConnection {
217 PeersConnection(LDK::ChannelManager& cm1, LDK::ChannelManager& cm2, LDK::PeerManager& net1, LDK::PeerManager& net2) {
218 node1_handler = init_socket_handling(&net1);
219 node2_handler = init_socket_handling(&net2);
221 struct sockaddr_in listen_addr;
222 listen_addr.sin_family = AF_INET;
223 listen_addr.sin_addr.s_addr = htonl((127 << 8*3) | 1);
224 listen_addr.sin_port = htons(10042);
225 assert(!socket_bind(node2_handler, (sockaddr*)&listen_addr, sizeof(listen_addr)));
227 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
229 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting initial handshake completion..." << std::endl;
231 // Wait for the initial handshakes to complete...
232 LDK::CVec_C2Tuple_PublicKeyCOption_SocketAddressZZZ peers_1 = PeerManager_get_peer_node_ids(&net1);
233 LDK::CVec_C2Tuple_PublicKeyCOption_SocketAddressZZZ peers_2 = PeerManager_get_peer_node_ids(&net2);
234 if (peers_1->datalen == 1 && peers_2->datalen == 1) { break; }
235 std::this_thread::yield();
237 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Initial handshake complete!" << std::endl;
239 // Connect twice, which should auto-disconnect, and is a good test of our disconnect pipeline
240 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
241 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
243 // Then disconnect the "main" connection, while another connection is being made.
244 PeerManager_disconnect_by_node_id(&net1, ChannelManager_get_our_node_id(&cm2));
245 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
247 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting new connection handshake..." << std::endl;
249 // Wait for the new connection handshake...
250 LDK::CVec_C2Tuple_PublicKeyCOption_SocketAddressZZZ peers_1 = PeerManager_get_peer_node_ids(&net1);
251 LDK::CVec_C2Tuple_PublicKeyCOption_SocketAddressZZZ peers_2 = PeerManager_get_peer_node_ids(&net2);
252 if (peers_1->datalen == 1 && peers_2->datalen == 1) { break; }
253 std::this_thread::yield();
255 std::cout << __FILE__ << ":" << __LINE__ << " - " << "New connection handshake complete!" << std::endl;
257 // Wait for all our sockets to disconnect (making sure we disconnect any new connections)...
258 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting peer disconnection..." << std::endl;
260 PeerManager_disconnect_by_node_id(&net1, ChannelManager_get_our_node_id(&cm2));
261 // Wait for the peers to disconnect...
262 LDK::CVec_C2Tuple_PublicKeyCOption_SocketAddressZZZ peers_1 = PeerManager_get_peer_node_ids(&net1);
263 LDK::CVec_C2Tuple_PublicKeyCOption_SocketAddressZZZ peers_2 = PeerManager_get_peer_node_ids(&net2);
264 if (peers_1->datalen == 0 && peers_2->datalen == 0) { break; }
265 std::this_thread::yield();
267 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Peers disconnected!" << std::endl;
268 // Note that the above is somewhat race-y, as node 2 may still think its connected.
269 // Thus, make sure any connections are disconnected on its end as well.
270 PeerManager_disconnect_by_node_id(&net2, ChannelManager_get_our_node_id(&cm1));
272 // Finally make an actual connection and keep it this time
273 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
275 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting initial handshake completion..." << std::endl;
277 // Wait for the initial handshakes to complete...
278 LDK::CVec_C2Tuple_PublicKeyCOption_SocketAddressZZZ peers_1 = PeerManager_get_peer_node_ids(&net1);
279 LDK::CVec_C2Tuple_PublicKeyCOption_SocketAddressZZZ peers_2 = PeerManager_get_peer_node_ids(&net2);
280 if (peers_1->datalen == 1 && peers_2->datalen == 1) { break; }
281 std::this_thread::yield();
283 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Initial handshake complete!" << std::endl;
286 interrupt_socket_handling(node1_handler);
287 interrupt_socket_handling(node2_handler);
293 uintptr_t sock_send_data(void *this_arg, LDKu8slice data, bool resume_read) {
294 return write((int)((long)this_arg), data.data, data.datalen);
296 void sock_disconnect_socket(void *this_arg) {
297 close((int)((long)this_arg));
299 bool sock_eq(const void *this_arg, const LDKSocketDescriptor *other_arg) {
300 return this_arg == other_arg->this_arg;
302 uint64_t sock_hash(const void *this_arg) {
303 return (uint64_t)this_arg;
305 void sock_read_data_thread(int rdfd, LDKSocketDescriptor *peer_descriptor, LDKPeerManager *pm) {
306 unsigned char buf[1024];
310 while ((readlen = read(rdfd, buf, 1024)) > 0) {
311 data.datalen = readlen;
312 LDK::CResult_boolPeerHandleErrorZ res = PeerManager_read_event(&*pm, peer_descriptor, data);
313 if (!res->result_ok) {
314 peer_descriptor->disconnect_socket(peer_descriptor->this_arg);
317 PeerManager_process_events(pm);
319 PeerManager_socket_disconnected(&*pm, peer_descriptor);
322 class PeersConnection {
323 int pipefds_1_to_2[2];
324 int pipefds_2_to_1[2];
326 LDKSocketDescriptor sock1, sock2;
329 PeersConnection(LDK::ChannelManager& cm1, LDK::ChannelManager& cm2, LDK::PeerManager& net1, LDK::PeerManager& net2) {
330 assert(!pipe(pipefds_1_to_2));
331 assert(!pipe(pipefds_2_to_1));
333 sock1 = LDKSocketDescriptor {
334 .this_arg = (void*)(long)pipefds_1_to_2[1],
335 .send_data = sock_send_data,
336 .disconnect_socket = sock_disconnect_socket,
343 sock2 = LDKSocketDescriptor {
344 .this_arg = (void*)(long)pipefds_2_to_1[1],
345 .send_data = sock_send_data,
346 .disconnect_socket = sock_disconnect_socket,
353 t1 = std::thread(&sock_read_data_thread, pipefds_2_to_1[0], &sock1, &net1);
354 t2 = std::thread(&sock_read_data_thread, pipefds_1_to_2[0], &sock2, &net2);
356 // Note that we have to bind the result to a C++ class to make sure it gets free'd
357 LDK::CResult_CVec_u8ZPeerHandleErrorZ con_res = PeerManager_new_outbound_connection(&net1, ChannelManager_get_our_node_id(&cm2), sock1, COption_SocketAddressZ_none());
358 assert(con_res->result_ok);
359 LDK::CResult_NonePeerHandleErrorZ con_res2 = PeerManager_new_inbound_connection(&net2, sock2, COption_SocketAddressZ_none());
360 assert(con_res2->result_ok);
362 auto writelen = write(pipefds_1_to_2[1], con_res->contents.result->data, con_res->contents.result->datalen);
363 assert(writelen > 0 && uint64_t(writelen) == con_res->contents.result->datalen);
365 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting initial handshake completion..." << std::endl;
367 // Wait for the initial handshakes to complete...
368 LDK::CVec_C2Tuple_PublicKeyCOption_SocketAddressZZZ peers_1 = PeerManager_get_peer_node_ids(&net1);
369 LDK::CVec_C2Tuple_PublicKeyCOption_SocketAddressZZZ peers_2 = PeerManager_get_peer_node_ids(&net2);
370 if (peers_1->datalen == 1 && peers_2->datalen ==1) { break; }
371 std::this_thread::yield();
373 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Initial handshake complete!" << std::endl;
377 close(pipefds_1_to_2[0]);
378 close(pipefds_2_to_1[0]);
379 close(pipefds_1_to_2[1]);
380 close(pipefds_2_to_1[1]);
387 struct CustomOnionMsgQueue {
389 std::vector<LDK::OnionMessageContents> msgs;
392 uint64_t custom_onion_msg_type_id(const void *this_arg) {
395 LDKCVec_u8Z custom_onion_msg_bytes(const void *this_arg) {
396 uint8_t *bytes = (uint8_t *) malloc(1024);
397 memset(bytes, 43, 1024);
399 .data = bytes, .datalen = 1024
403 LDKCOption_OnionMessageContentsZ handle_custom_onion_message(const void* this_arg, struct LDKOnionMessageContents msg) {
404 CustomOnionMsgQueue* arg = (CustomOnionMsgQueue*) this_arg;
405 std::unique_lock<std::mutex> lck(arg->mtx);
406 arg->msgs.push_back(std::move(msg));
407 return COption_OnionMessageContentsZ_none();
410 LDKOnionMessageContents build_custom_onion_message() {
411 return LDKOnionMessageContents {
413 .tlv_type = custom_onion_msg_type_id,
414 .write = custom_onion_msg_bytes,
419 LDKCResult_COption_OnionMessageContentsZDecodeErrorZ read_custom_onion_message(const void* this_arg, uint64_t type, LDKu8slice buf) {
420 assert(type == 8888);
421 assert(buf.datalen == 1024);
423 memset(cmp, 43, 1024);
424 assert(!memcmp(cmp, buf.data, 1024));
425 return CResult_COption_OnionMessageContentsZDecodeErrorZ_ok(COption_OnionMessageContentsZ_some(build_custom_onion_message()));
428 LDKCVec_C3Tuple_OnionMessageContentsDestinationBlindedPathZZ release_no_messages(const void* this_arg) {
429 return LDKCVec_C3Tuple_OnionMessageContentsDestinationBlindedPathZZ {
430 .data = NULL, .datalen = 0 };
433 struct CustomMsgQueue {
434 std::vector<LDK::Type> msgs;
437 uint16_t custom_msg_type_id(const void *this_arg) {
440 LDKCVec_u8Z custom_msg_bytes(const void *this_arg) {
441 uint8_t *bytes = (uint8_t *) malloc(1024);
442 memset(bytes, 42, 1024);
444 .data = bytes, .datalen = 1024
447 LDKStr custom_msg_debug(const void *this_arg) {
449 .chars = (const unsigned char*) "Custom Message", .len = 14, .chars_is_owned = false
453 LDKCResult_COption_TypeZDecodeErrorZ read_custom_message(const void* this_arg, uint16_t type_id, LDKu8slice buf) {
454 assert(type_id == 8888);
455 assert(buf.datalen == 1024);
457 memset(cmp, 42, 1024);
458 assert(!memcmp(cmp, buf.data, 1024));
459 return CResult_COption_TypeZDecodeErrorZ_ok(COption_TypeZ_some(LDKType {
461 .type_id = custom_msg_type_id,
462 .debug_str = custom_msg_debug,
463 .write = NULL, // This message should never be written
468 LDKCResult_NoneLightningErrorZ handle_custom_message(const void* this_arg, struct LDKType msg, struct LDKPublicKey _sender_node_id) {
469 CustomMsgQueue* arg = (CustomMsgQueue*) this_arg;
470 arg->msgs.push_back(std::move(msg));
471 return CResult_NoneLightningErrorZ_ok();
473 LDKCVec_C2Tuple_PublicKeyTypeZZ never_send_custom_msgs(const void* this_arg) {
474 return LDKCVec_C2Tuple_PublicKeyTypeZZ {
475 .data = NULL, .datalen = 0
479 LDKCVec_C2Tuple_PublicKeyTypeZZ create_custom_msg(const void* this_arg) {
480 const LDKPublicKey *counterparty_node_id = (const LDKPublicKey *)this_arg;
481 LDKCVec_C2Tuple_PublicKeyTypeZZ ret = {
482 .data = ((LDKC2Tuple_PublicKeyTypeZ*)malloc(sizeof(LDKC2Tuple_PublicKeyTypeZ))),
485 ret.data[0].a = *counterparty_node_id;
486 ret.data[0].b = LDKType {
488 .type_id = custom_msg_type_id,
489 .debug_str = custom_msg_debug,
490 .write = custom_msg_bytes,
496 LDKNodeFeatures custom_node_features(const void *this_arg) {
497 return NodeFeatures_empty();
500 LDKInitFeatures custom_init_features(const void *this_arg, struct LDKPublicKey their_node_id) {
501 return InitFeatures_empty();
504 uint64_t get_chan_score(const void *this_arg, uint64_t scid, const LDKNodeId *src, const LDKNodeId *dst, LDKChannelUsage usage_in, const LDKProbabilisticScoringFeeParameters *params) {
505 LDK::ChannelUsage usage(std::move(usage_in));
509 struct LDKCResult_RouteLightningErrorZ custom_find_route(const void *this_arg, struct LDKPublicKey payer, const struct LDKRouteParameters *NONNULL_PTR route_params, struct LDKCVec_ChannelDetailsZ *first_hops, const struct LDKInFlightHtlcs in_flights, LDKThirtyTwoBytes payment_id, LDKThirtyTwoBytes payment_hash) {
510 const LDK::DefaultRouter *router = (LDK::DefaultRouter *)this_arg;
511 assert(first_hops->datalen == 1);
512 assert(ChannelDetails_get_is_usable(&first_hops->data[0]));
513 const LDK::Router router_impl = DefaultRouter_as_Router(&*router);
514 return router_impl->find_route(router_impl->this_arg, payer, route_params, first_hops, in_flights);
518 uint8_t channel_open_header[80];
519 uint8_t header_1[80];
520 uint8_t header_2[80];
521 memcpy(channel_open_header, channel_open_block, 80);
522 memcpy(header_1, block_1, 80);
523 memcpy(header_2, block_2, 80);
525 LDKPublicKey null_pk;
526 memset(&null_pk, 0, sizeof(null_pk));
528 LDKThirtyTwoBytes random_bytes;
529 LDKThirtyTwoBytes chain_tip;
530 memset(&chain_tip, 0, sizeof(chain_tip)); // channel_open_header's prev_blockhash is all-0s
532 LDKNetwork network = LDKNetwork_Testnet;
534 // Trait implementations:
535 LDKBroadcasterInterface broadcast {
537 .broadcast_transactions = broadcast_txn,
541 // Instantiate classes for the nodes that don't get reloaded on a ser-des reload
543 .this_arg = (void*)1,
549 mons1.logger = &logger1;
552 .watch_channel = add_channel_monitor,
553 .update_channel = update_channel_monitor,
554 .release_pending_monitor_events = monitors_pending_monitor_events,
558 LDK::NetworkGraph net_graph1 = NetworkGraph_new(network, logger1);
559 LDK::P2PGossipSync graph_msg_handler1 = P2PGossipSync_new(&net_graph1, COption_UtxoLookupZ_none(), logger1);
562 .this_arg = (void*)2,
568 mons2.logger = &logger2;
571 .watch_channel = add_channel_monitor,
572 .update_channel = update_channel_monitor,
573 .release_pending_monitor_events = monitors_pending_monitor_events,
577 LDKRouter panic_router = {
579 .find_route = NULL, // Segfault if we ever try to find a route
580 .find_route_with_id = NULL, // Segfault if we ever try to find a route
584 LDK::NetworkGraph net_graph2 = NetworkGraph_new(network, logger2);
585 LDK::P2PGossipSync graph_msg_handler2 = P2PGossipSync_new(&net_graph2, COption_UtxoLookupZ_none(), logger2);
587 LDK::CVec_u8Z cm1_ser = LDKCVec_u8Z {}; // ChannelManager 1 serialization at the end of the ser-des scope
588 LDK::CVec_u8Z cm2_ser = LDKCVec_u8Z {}; // ChannelManager 2 serialization at the end of the ser-des scope
590 { // Scope for the ser-des reload
591 // Instantiate classes for node 1:
592 uint8_t node_seed[32];
593 memset(&node_seed, 0, 32);
594 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 0, 0);
595 LDK::NodeSigner node_signer1 = KeysManager_as_NodeSigner(&keys1);
596 LDK::EntropySource entropy_source1 = KeysManager_as_EntropySource(&keys1);
597 LDK::SignerProvider signer_provider1 = KeysManager_as_SignerProvider(&keys1);
599 LDK::ChannelManager cm1 = ChannelManager_new(fee_est, mon1, broadcast, panic_router, logger1, KeysManager_as_EntropySource(&keys1), KeysManager_as_NodeSigner(&keys1), KeysManager_as_SignerProvider(&keys1), UserConfig_default(), ChainParameters_new(network, BestBlock_new(chain_tip, 0)), 1689638400);
601 LDK::IgnoringMessageHandler ignoring_handler1 = IgnoringMessageHandler_new();
602 LDK::CustomMessageHandler custom_msg_handler1 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler1);
603 LDK::CustomOnionMessageHandler custom_onion_msg_handler1 = IgnoringMessageHandler_as_CustomOnionMessageHandler(&ignoring_handler1);
604 LDK::DefaultMessageRouter mr1 = DefaultMessageRouter_new();
605 LDK::OnionMessenger om1 = OnionMessenger_new(KeysManager_as_EntropySource(&keys1), KeysManager_as_NodeSigner(&keys1), logger1, DefaultMessageRouter_as_MessageRouter(&mr1), IgnoringMessageHandler_as_OffersMessageHandler(&ignoring_handler1), std::move(custom_onion_msg_handler1));
607 LDK::CVec_ChannelDetailsZ channels = ChannelManager_list_channels(&cm1);
608 assert(channels->datalen == 0);
610 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler1), OnionMessenger_as_OnionMessageHandler(&om1), std::move(custom_msg_handler1));
612 random_bytes = entropy_source1.get_secure_random_bytes();
613 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), 0xdeadbeef, &random_bytes.data, logger1, std::move(node_signer1));
615 // Demo getting a channel key and check that its returning real pubkeys:
616 LDKSixteenBytes user_id_1 { .data = {45, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0} };
617 LDKThirtyTwoBytes chan_signer_id1 = signer_provider1.generate_channel_keys_id(false, 42, U128_new(user_id_1));
618 LDK::WriteableEcdsaChannelSigner chan_signer1 = signer_provider1.derive_channel_signer(42, chan_signer_id1);
619 chan_signer1->EcdsaChannelSigner.ChannelSigner.set_pubkeys(&chan_signer1->EcdsaChannelSigner.ChannelSigner); // Make sure pubkeys is defined
620 LDKPublicKey payment_point = ChannelPublicKeys_get_payment_point(&chan_signer1->EcdsaChannelSigner.ChannelSigner.pubkeys);
621 assert(memcmp(&payment_point, &null_pk, sizeof(null_pk)));
623 // Instantiate classes for node 2:
624 memset(&node_seed, 1, 32);
625 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 0, 0);
626 LDK::NodeSigner node_signer2 = KeysManager_as_NodeSigner(&keys2);
627 LDK::EntropySource entropy_source2 = KeysManager_as_EntropySource(&keys2);
628 LDK::SignerProvider signer_provider2 = KeysManager_as_SignerProvider(&keys2);
630 LDK::ChannelHandshakeConfig handshake_config2 = ChannelHandshakeConfig_default();
631 ChannelHandshakeConfig_set_minimum_depth(&handshake_config2, 2);
632 LDK::UserConfig config2 = UserConfig_default();
633 UserConfig_set_channel_handshake_config(&config2, std::move(handshake_config2));
635 LDK::ChannelManager cm2 = ChannelManager_new(fee_est, mon2, broadcast, panic_router, logger2, KeysManager_as_EntropySource(&keys2), KeysManager_as_NodeSigner(&keys2), KeysManager_as_SignerProvider(&keys2), std::move(config2), ChainParameters_new(network, BestBlock_new(chain_tip, 0)), 1689638400);
637 LDK::IgnoringMessageHandler ignoring_handler2 = IgnoringMessageHandler_new();
638 LDK::CustomMessageHandler custom_msg_handler2 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler2);
639 LDK::CustomOnionMessageHandler custom_onion_msg_handler2 = IgnoringMessageHandler_as_CustomOnionMessageHandler(&ignoring_handler2);
640 LDK::DefaultMessageRouter mr2 = DefaultMessageRouter_new();
641 LDK::OnionMessenger om2 = OnionMessenger_new(KeysManager_as_EntropySource(&keys2), KeysManager_as_NodeSigner(&keys2), logger2, DefaultMessageRouter_as_MessageRouter(&mr2), IgnoringMessageHandler_as_OffersMessageHandler(&ignoring_handler2), std::move(custom_onion_msg_handler2));
643 LDK::CVec_ChannelDetailsZ channels2 = ChannelManager_list_channels(&cm2);
644 assert(channels2->datalen == 0);
646 LDK::RoutingMessageHandler net_msgs2 = P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler2);
647 LDK::CResult_ChannelAnnouncementDecodeErrorZ chan_ann = ChannelAnnouncement_read(LDKu8slice { .data = valid_node_announcement, .datalen = sizeof(valid_node_announcement) });
648 assert(chan_ann->result_ok);
649 LDK::CResult_boolLightningErrorZ ann_res = net_msgs2->handle_channel_announcement(net_msgs2->this_arg, chan_ann->contents.result);
650 assert(ann_res->result_ok);
652 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), std::move(net_msgs2), OnionMessenger_as_OnionMessageHandler(&om1), std::move(custom_msg_handler2));
654 random_bytes = entropy_source2.get_secure_random_bytes();
655 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), 0xdeadbeef, &random_bytes.data, logger2, std::move(node_signer2));
657 // Open a connection!
658 PeersConnection conn(cm1, cm2, net1, net2);
660 // Note that we have to bind the result to a C++ class to make sure it gets free'd
661 LDK::CResult_ThirtyTwoBytesAPIErrorZ res = ChannelManager_create_channel(&cm1, ChannelManager_get_our_node_id(&cm2), 40000, 1000, U128_new(user_id_1), UserConfig_default());
662 assert(res->result_ok);
663 PeerManager_process_events(&net1);
665 LDK::CVec_ChannelDetailsZ new_channels = ChannelManager_list_channels(&cm1);
666 assert(new_channels->datalen == 1);
667 LDK::ChannelCounterparty new_channels_counterparty = ChannelDetails_get_counterparty(&new_channels->data[0]);
668 LDKPublicKey chan_open_pk = ChannelCounterparty_get_node_id(&new_channels_counterparty);
669 assert(!memcmp(chan_open_pk.compressed_form, ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
671 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting first channel..." << std::endl;
673 LDK::CVec_ChannelDetailsZ new_channels_2 = ChannelManager_list_channels(&cm2);
674 if (new_channels_2->datalen == 1) {
675 // Sample getting our counterparty's init features (which used to be hard to do without a memory leak):
676 LDK::ChannelCounterparty new_channels_2_counterparty = ChannelDetails_get_counterparty(&new_channels_2->data[0]);
677 const LDK::InitFeatures init_feats = ChannelCounterparty_get_features(&new_channels_2_counterparty);
678 assert(init_feats->inner != NULL);
681 std::this_thread::yield();
683 std::cout << __FILE__ << ":" << __LINE__ << " - " << "First channel listed!" << std::endl;
685 LDK::EventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1);
686 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting FundingGenerationReady event..." << std::endl;
689 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
690 ev1.process_pending_events(handler);
691 if (queue.events.size() == 1) {
692 assert(queue.events[0]->tag == LDKEvent_FundingGenerationReady);
693 LDKSixteenBytes event_id = U128_le_bytes(queue.events[0]->funding_generation_ready.user_channel_id);
694 assert(!memcmp(&event_id, &user_id_1, 16));
695 assert(queue.events[0]->funding_generation_ready.channel_value_satoshis == 40000);
696 assert(queue.events[0]->funding_generation_ready.output_script.datalen == 34);
698 assert(!memcmp(queue.events[0]->funding_generation_ready.output_script.data, channel_open_block + 58 + 81, 34));
699 LDKTransaction funding_transaction { .data = const_cast<uint8_t*>(channel_open_block + 81), .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false };
701 LDK::CResult_NoneAPIErrorZ fund_res = ChannelManager_funding_transaction_generated(&cm1, &queue.events[0]->funding_generation_ready.temporary_channel_id.data, queue.events[0]->funding_generation_ready.counterparty_node_id, funding_transaction);
702 assert(fund_res->result_ok);
705 std::this_thread::yield();
707 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received FundingGenerationReady event!" << std::endl;
709 // We observe when the funding signed messages have been exchanged by
710 // waiting for two monitors to be registered.
711 assert(num_txs_broadcasted == 0);
712 PeerManager_process_events(&net1);
713 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting transaction broadcast..." << std::endl;
714 while (num_txs_broadcasted != 1) {
715 std::this_thread::yield();
717 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Transaction was broadcast!" << std::endl;
719 // Note that the channel ID is the same as the channel txid reversed as the output index is 0
720 uint8_t expected_chan_id[32];
721 for (int i = 0; i < 32; i++) { expected_chan_id[i] = channel_open_txid[31-i]; }
723 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting ChannelPending event..." << std::endl;
726 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
727 ev1.process_pending_events(handler);
728 if (queue.events.size() == 1) {
729 assert(queue.events[0]->tag == LDKEvent_ChannelPending);
730 assert(!memcmp(queue.events[0]->channel_pending.channel_id.data, expected_chan_id, 32));
733 std::this_thread::yield();
735 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received ChannelPending event!" << std::endl;
737 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
738 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting ChannelPending event..." << std::endl;
741 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
742 ev2.process_pending_events(handler);
743 if (queue.events.size() == 1) {
744 assert(queue.events[0]->tag == LDKEvent_ChannelPending);
745 assert(!memcmp(queue.events[0]->channel_pending.channel_id.data, expected_chan_id, 32));
748 std::this_thread::yield();
750 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received ChannelPending event!" << std::endl;
752 LDK::Listen listener1 = ChannelManager_as_Listen(&cm1);
753 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
755 LDK::Listen listener2 = ChannelManager_as_Listen(&cm2);
756 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
758 LDKCVec_C2Tuple_usizeTransactionZZ txdata { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
759 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
760 mons1.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
762 txdata = LDKCVec_C2Tuple_usizeTransactionZZ { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
763 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
764 mons2.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
766 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
767 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
768 mons1.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
769 mons2.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
771 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
772 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
773 mons1.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
774 mons2.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
776 PeerManager_process_events(&net1);
777 PeerManager_process_events(&net2);
779 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting ChannelReady event..." << std::endl;
782 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
783 ev2.process_pending_events(handler);
784 if (queue.events.size() == 1) {
785 assert(queue.events[0]->tag == LDKEvent_ChannelReady);
786 assert(!memcmp(queue.events[0]->channel_ready.channel_id.data, expected_chan_id, 32));
789 std::this_thread::yield();
791 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received ChannelReady event!" << std::endl;
793 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting ChannelReady event..." << std::endl;
796 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
797 ev1.process_pending_events(handler);
798 if (queue.events.size() == 1) {
799 assert(queue.events[0]->tag == LDKEvent_ChannelReady);
800 assert(!memcmp(queue.events[0]->channel_ready.channel_id.data, expected_chan_id, 32));
803 std::this_thread::yield();
805 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received ChannelReady event!" << std::endl;
807 // Now send funds from 1 to 2!
808 uint64_t channel_scid;
809 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting usable channel..." << std::endl;
811 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
812 if (outbound_channels->datalen == 1) {
813 const LDKChannelDetails *channel = &outbound_channels->data[0];
814 LDK::ChannelCounterparty counterparty = ChannelDetails_get_counterparty(channel);
816 assert(!memcmp(ChannelDetails_get_channel_id(channel), expected_chan_id, 32));
818 ChannelCounterparty_get_node_id(&counterparty).compressed_form,
819 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
820 assert(ChannelDetails_get_channel_value_satoshis(channel) == 40000);
821 // We opened the channel with 1000 push_msat:
822 assert(ChannelDetails_get_outbound_capacity_msat(channel) ==
823 40000*1000 - 1000 - 1000 * ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty));
824 int64_t inbound_capacity = ((int64_t)1000) - ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty);
825 if (inbound_capacity < 0) inbound_capacity = 0;
826 assert(ChannelDetails_get_inbound_capacity_msat(channel) == (uint64_t)inbound_capacity);
827 assert(ChannelDetails_get_is_usable(channel));
828 LDK::COption_u64Z scid_opt = ChannelDetails_get_short_channel_id(channel);
829 assert(scid_opt->some);
830 channel_scid = scid_opt->some;
833 std::this_thread::yield();
835 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Listed usable channel!" << std::endl;
837 LDKCOption_u64Z min_value = {
838 .tag = LDKCOption_u64Z_Some,
841 LDK::CResult_Bolt11InvoiceSignOrCreationErrorZ invoice = create_invoice_from_channelmanager(&cm2,
842 KeysManager_as_NodeSigner(&keys2), logger2,
843 LDKCurrency_Bitcoin, min_value,
845 .chars = (const uint8_t *)"Invoice Description",
846 .len = strlen("Invoice Description"),
847 .chars_is_owned = false
848 }, 3600, COption_u16Z_none());
849 assert(invoice->result_ok);
850 LDKThirtyTwoBytes payment_hash;
851 memcpy(payment_hash.data, Bolt11Invoice_payment_hash(invoice->contents.result), 32);
854 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
855 LDK::ScoreLookUp chan_scorer = LDKScoreLookUp {
856 .this_arg = NULL, .channel_penalty_msat = get_chan_score, .free = NULL,
858 LDK::Payee payee = Payee_clear(ChannelManager_get_our_node_id(&cm2), Bolt11Invoice_route_hints(invoice->contents.result),
859 LDKBolt11InvoiceFeatures {
860 .inner = NULL, .is_owned = false
861 }, Bolt11Invoice_min_final_cltv_expiry_delta(invoice->contents.result));
862 LDK::RouteParameters route_params = RouteParameters_from_payment_params_and_value(
863 PaymentParameters_new(std::move(payee), COption_u64Z_none(), 0xffffffff, 1, 2,
864 LDKCVec_u64Z { .data = NULL, .datalen = 0 }),
866 random_bytes = entropy_source1.get_secure_random_bytes();
867 LDK::ProbabilisticScoringFeeParameters params = ProbabilisticScoringFeeParameters_default();
869 LDK::CResult_RouteLightningErrorZ route = find_route(ChannelManager_get_our_node_id(&cm1), &route_params, &net_graph2, &outbound_channels, logger1, &chan_scorer, ¶ms, &random_bytes.data);
871 assert(route->result_ok);
872 LDK::CVec_PathZ paths = Route_get_paths(route->contents.result);
873 assert(paths->datalen == 1);
874 LDK::CVec_RouteHopZ hops = Path_get_hops(&paths->data[0]);
875 assert(hops->datalen == 1);
876 assert(!memcmp(RouteHop_get_pubkey(&hops->data[0]).compressed_form,
877 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
878 assert(RouteHop_get_short_channel_id(&hops->data[0]) == channel_scid);
879 LDKThirtyTwoBytes payment_secret;
880 memcpy(payment_secret.data, Bolt11Invoice_payment_secret(invoice->contents.result), 32);
881 LDK::CResult_NonePaymentSendFailureZ send_res = ChannelManager_send_payment_with_route(&cm1,
882 route->contents.result, payment_hash, RecipientOnionFields_secret_only(payment_secret), payment_hash);
883 assert(send_res->result_ok);
887 PeerManager_process_events(&net1);
888 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting 4 updated monitors..." << std::endl;
889 while (mons_updated != 4) {
890 std::this_thread::yield();
892 std::cout << __FILE__ << ":" << __LINE__ << " - " << "4 monitors updated!" << std::endl;
894 // Check that we received the payment!
895 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting PendingHTLCsForwardable event..." << std::endl;
898 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
899 ev2.process_pending_events(handler);
900 if (queue.events.size() == 1) {
901 assert(queue.events[0]->tag == LDKEvent_PendingHTLCsForwardable);
904 std::this_thread::yield();
906 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received PendingHTLCsForwardable event!" << std::endl;
907 ChannelManager_process_pending_htlc_forwards(&cm2);
908 PeerManager_process_events(&net2);
911 LDKThirtyTwoBytes payment_preimage;
914 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
915 ev2.process_pending_events(handler);
916 assert(queue.events.size() == 1);
917 assert(queue.events[0]->tag == LDKEvent_PaymentClaimable);
918 assert(!memcmp(queue.events[0]->payment_claimable.payment_hash.data, payment_hash.data, 32));
919 assert(queue.events[0]->payment_claimable.purpose.tag == LDKPaymentPurpose_InvoicePayment);
920 assert(!memcmp(queue.events[0]->payment_claimable.purpose.invoice_payment.payment_secret.data,
921 Bolt11Invoice_payment_secret(invoice->contents.result), 32));
922 assert(queue.events[0]->payment_claimable.amount_msat == 5000);
923 assert(queue.events[0]->payment_claimable.purpose.invoice_payment.payment_preimage.tag == LDKCOption_ThirtyTwoBytesZ_Some);
924 memcpy(payment_preimage.data, queue.events[0]->payment_claimable.purpose.invoice_payment.payment_preimage.some.data, 32);
925 ChannelManager_claim_funds(&cm2, payment_preimage);
927 queue.events.clear();
928 ev2.process_pending_events(handler);
929 assert(queue.events.size() == 1);
930 assert(queue.events[0]->tag == LDKEvent_PaymentClaimed);
931 assert(!memcmp(queue.events[0]->payment_claimed.payment_hash.data, payment_hash.data, 32));
932 assert(queue.events[0]->payment_claimed.purpose.tag == LDKPaymentPurpose_InvoicePayment);
934 PeerManager_process_events(&net2);
935 // Wait until we've passed through a full set of monitor updates (ie new preimage + CS/RAA messages)
938 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
939 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting PaymentSent and PaymentPathSuccessful events..." << std::endl;
940 while (queue.events.size() < 2) {
941 ev1.process_pending_events(handler);
942 std::this_thread::yield();
944 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received PaymentSent and PaymentPathSuccessful events (presumably)!" << std::endl;
945 assert(queue.events.size() == 2);
946 assert(queue.events[0]->tag == LDKEvent_PaymentSent);
947 assert(!memcmp(queue.events[0]->payment_sent.payment_preimage.data, payment_preimage.data, 32));
948 assert(queue.events[1]->tag == LDKEvent_PaymentPathSuccessful);
949 assert(queue.events[1]->payment_path_successful.payment_hash.tag == LDKCOption_ThirtyTwoBytesZ_Some);
950 assert(!memcmp(queue.events[1]->payment_path_successful.payment_hash.some.data, payment_hash.data, 32));
952 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting 5 updated monitors..." << std::endl;
953 while (mons_updated != 5) {
954 std::this_thread::yield();
956 std::cout << __FILE__ << ":" << __LINE__ << " - " << "5 monitors updated!" << std::endl;
960 cm1_ser = ChannelManager_write(&cm1);
961 cm2_ser = ChannelManager_write(&cm2);
964 LDK::CVec_ChannelMonitorZ mons_list1 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
965 assert(mons1.mons.size() == 1);
966 mons_list1->data[0] = *& std::get<1>(mons1.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
967 mons_list1->data[0].is_owned = false; // XXX: God this sucks
968 uint8_t node_seed[32];
969 memset(&node_seed, 0, 32);
970 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 1, 0);
971 LDK::NodeSigner node_signer1 = KeysManager_as_NodeSigner(&keys1);
972 LDK::EntropySource entropy_source1 = KeysManager_as_EntropySource(&keys1);
973 LDK::SignerProvider signer_provider1 = KeysManager_as_SignerProvider(&keys1);
975 LDK::ProbabilisticScorer scorer1 = ProbabilisticScorer_new(ProbabilisticScoringDecayParameters_default(), &net_graph1, logger1);
976 LDK::Score scorer_trait1 = ProbabilisticScorer_as_Score(&scorer1);
977 LDK::MultiThreadedLockableScore scorer_mtx1 = MultiThreadedLockableScore_new(std::move(scorer_trait1));
978 LDK::LockableScore scorer_mtx_trait1 = MultiThreadedLockableScore_as_LockableScore(&scorer_mtx1);
979 LDK::ProbabilisticScoringFeeParameters params = ProbabilisticScoringFeeParameters_default();
980 const LDK::DefaultRouter default_router_1 = DefaultRouter_new(&net_graph1, logger1, entropy_source1.get_secure_random_bytes(), std::move(scorer_mtx_trait1), std::move(params));
981 LDKRouter router1 = {
982 .this_arg = (void*)&default_router_1,
983 .find_route = NULL, // LDK currently doesn't use this, its just a default-impl
984 .find_route_with_id = custom_find_route,
988 LDK::ChannelManagerReadArgs cm1_args = ChannelManagerReadArgs_new(KeysManager_as_EntropySource(&keys1), KeysManager_as_NodeSigner(&keys1), KeysManager_as_SignerProvider(&keys1), fee_est, mon1, broadcast, router1, logger1, UserConfig_default(), std::move(mons_list1));
989 LDK::CResult_C2Tuple_ThirtyTwoBytesChannelManagerZDecodeErrorZ cm1_read =
990 C2Tuple_ThirtyTwoBytesChannelManagerZ_read(LDKu8slice { .data = cm1_ser->data, .datalen = cm1_ser -> datalen}, std::move(cm1_args));
991 assert(cm1_read->result_ok);
992 LDK::ChannelManager cm1(std::move(cm1_read->contents.result->b));
994 LDKCustomOnionMessageHandler custom_onion_msg_handler1 = {
996 .handle_custom_message = NULL, // We only create custom messages, not handle them
997 .read_custom_message = NULL, // We only create custom messages, not handle them
998 .release_pending_custom_messages = release_no_messages,
1001 LDK::DefaultMessageRouter mr1 = DefaultMessageRouter_new();
1002 LDK::IgnoringMessageHandler ignorer_1 = IgnoringMessageHandler_new();
1003 LDK::OnionMessenger om1 = OnionMessenger_new(KeysManager_as_EntropySource(&keys1), KeysManager_as_NodeSigner(&keys1), logger1, DefaultMessageRouter_as_MessageRouter(&mr1), IgnoringMessageHandler_as_OffersMessageHandler(&ignorer_1), std::move(custom_onion_msg_handler1));
1005 LDK::CVec_ChannelMonitorZ mons_list2 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
1006 assert(mons2.mons.size() == 1);
1007 mons_list2->data[0] = *& std::get<1>(mons2.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
1008 mons_list2->data[0].is_owned = false; // XXX: God this sucks
1009 memset(&node_seed, 1, 32);
1010 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 1, 0);
1011 LDK::NodeSigner node_signer2 = KeysManager_as_NodeSigner(&keys2);
1012 LDK::EntropySource entropy_source2 = KeysManager_as_EntropySource(&keys2);
1013 LDK::SignerProvider signer_provider2 = KeysManager_as_SignerProvider(&keys2);
1015 LDK::ChannelManagerReadArgs cm2_args = ChannelManagerReadArgs_new(KeysManager_as_EntropySource(&keys2), KeysManager_as_NodeSigner(&keys2), KeysManager_as_SignerProvider(&keys2), fee_est, mon2, broadcast, panic_router, logger2, UserConfig_default(), std::move(mons_list2));
1016 LDK::CResult_C2Tuple_ThirtyTwoBytesChannelManagerZDecodeErrorZ cm2_read =
1017 C2Tuple_ThirtyTwoBytesChannelManagerZ_read(LDKu8slice { .data = cm2_ser->data, .datalen = cm2_ser -> datalen}, std::move(cm2_args));
1018 assert(cm2_read->result_ok);
1019 LDK::ChannelManager cm2(std::move(cm2_read->contents.result->b));
1021 CustomOnionMsgQueue peer_2_custom_onion_messages;
1022 LDKCustomOnionMessageHandler custom_onion_msg_handler2 = {
1023 .this_arg = &peer_2_custom_onion_messages,
1024 .handle_custom_message = handle_custom_onion_message,
1025 .read_custom_message = read_custom_onion_message,
1026 .release_pending_custom_messages = release_no_messages,
1029 LDK::DefaultMessageRouter mr2 = DefaultMessageRouter_new();
1030 LDK::IgnoringMessageHandler ignorer_2 = IgnoringMessageHandler_new();
1031 LDK::OnionMessenger om2 = OnionMessenger_new(KeysManager_as_EntropySource(&keys2), KeysManager_as_NodeSigner(&keys2), logger2, DefaultMessageRouter_as_MessageRouter(&mr2), IgnoringMessageHandler_as_OffersMessageHandler(&ignorer_2), custom_onion_msg_handler2);
1033 // Attempt to close the channel...
1034 uint8_t chan_id[32];
1035 for (int i = 0; i < 32; i++) { chan_id[i] = channel_open_txid[31-i]; }
1036 LDK::CResult_NoneAPIErrorZ close_res = ChannelManager_close_channel(&cm1, &chan_id, ChannelManager_get_our_node_id(&cm2));
1037 assert(!close_res->result_ok); // Note that we can't close while disconnected!
1039 // Open a connection!
1040 LDKPublicKey chan_2_node_id = ChannelManager_get_our_node_id(&cm2);
1041 LDKCustomMessageHandler custom_msg_handler1 = {
1042 .this_arg = &chan_2_node_id,
1043 .handle_custom_message = NULL, // We only create custom messages, not handle them
1044 .get_and_clear_pending_msg = create_custom_msg,
1045 .provided_node_features = custom_node_features,
1046 .provided_init_features = custom_init_features,
1047 .CustomMessageReader = LDKCustomMessageReader {
1049 .read = read_custom_message,
1054 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler1), OnionMessenger_as_OnionMessageHandler(&om1), custom_msg_handler1);
1055 random_bytes = entropy_source1.get_secure_random_bytes();
1056 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), 0xdeadbeef, &random_bytes.data, logger1, std::move(node_signer1));
1058 CustomMsgQueue peer_2_custom_messages;
1059 LDKCustomMessageHandler custom_msg_handler2 = {
1060 .this_arg = &peer_2_custom_messages,
1061 .handle_custom_message = handle_custom_message,
1062 .get_and_clear_pending_msg = never_send_custom_msgs,
1063 .provided_node_features = custom_node_features,
1064 .provided_init_features = custom_init_features,
1065 .CustomMessageReader = LDKCustomMessageReader {
1067 .read = read_custom_message,
1072 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler2), OnionMessenger_as_OnionMessageHandler(&om2), custom_msg_handler2);
1073 random_bytes = entropy_source1.get_secure_random_bytes();
1074 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), 0xdeadbeef, &random_bytes.data, logger2, std::move(node_signer2));
1076 PeersConnection conn(cm1, cm2, net1, net2);
1078 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting usable channel..." << std::endl;
1080 // Wait for the channels to be considered up once the reestablish messages are processed
1081 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
1082 if (outbound_channels->datalen == 1) {
1085 std::this_thread::yield();
1087 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Listed usable channel!" << std::endl;
1089 // Send another payment, this time via the retires path
1090 LDK::CResult_Bolt11InvoiceSignOrCreationErrorZ invoice_res2 = create_invoice_from_channelmanager(&cm2,
1091 KeysManager_as_NodeSigner(&keys2), logger1,
1092 LDKCurrency_Bitcoin, COption_u64Z_some(10000),
1094 .chars = (const uint8_t *)"Invoice 2 Description",
1095 .len = strlen("Invoice 2 Description"),
1096 .chars_is_owned = false
1097 }, 3600, COption_u16Z_none());
1098 assert(invoice_res2->result_ok);
1099 const LDKBolt11Invoice *invoice2 = invoice_res2->contents.result;
1100 LDK::CResult_ThirtyTwoBytesPaymentErrorZ invoice_pay_res = pay_invoice(invoice2, Retry_attempts(0), &cm1);
1101 assert(invoice_pay_res->result_ok);
1102 PeerManager_process_events(&net1);
1104 // Check that we received the payment!
1105 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting PendingHTLCsForwardable event..." << std::endl;
1108 LDKEventHandler handler2 = { .this_arg = &queue2, .handle_event = handle_event, .free = NULL };
1109 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
1110 ev2.process_pending_events(handler2);
1111 if (queue2.events.size() == 1) {
1112 assert(queue2.events[0]->tag == LDKEvent_PendingHTLCsForwardable);
1115 std::this_thread::yield();
1117 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received PendingHTLCsForwardable event!" << std::endl;
1118 ChannelManager_process_pending_htlc_forwards(&cm2);
1119 PeerManager_process_events(&net2);
1121 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting PaymentClaimable/PaymentClaimed event..." << std::endl;
1124 LDKEventHandler handler2 = { .this_arg = &queue2, .handle_event = handle_event, .free = NULL };
1125 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
1126 ev2.process_pending_events(handler2);
1127 if (queue2.events.size() == 1) {
1128 assert(queue2.events[0]->tag == LDKEvent_PaymentClaimable);
1129 const struct LDKEvent_LDKPaymentClaimable_Body *event_data = &queue2.events[0]->payment_claimable;
1130 assert(!memcmp(event_data->payment_hash.data, Bolt11Invoice_payment_hash(invoice2), 32));
1131 assert(event_data->purpose.tag == LDKPaymentPurpose_InvoicePayment);
1132 assert(!memcmp(event_data->purpose.invoice_payment.payment_secret.data,
1133 Bolt11Invoice_payment_secret(invoice2), 32));
1134 assert(event_data->amount_msat == 10000);
1135 assert(event_data->purpose.invoice_payment.payment_preimage.tag == LDKCOption_ThirtyTwoBytesZ_Some);
1136 ChannelManager_claim_funds(&cm2, event_data->purpose.invoice_payment.payment_preimage.some);
1138 queue2.events.clear();
1139 ev2.process_pending_events(handler2);
1140 assert(queue2.events.size() == 1);
1141 assert(queue2.events[0]->tag == LDKEvent_PaymentClaimed);
1142 assert(!memcmp(queue2.events[0]->payment_claimed.payment_hash.data, Bolt11Invoice_payment_hash(invoice2), 32));
1143 assert(queue2.events[0]->payment_claimed.purpose.tag == LDKPaymentPurpose_InvoicePayment);
1147 std::this_thread::yield();
1149 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received PaymentClaimable/PaymentClaimed event!" << std::endl;
1152 LDKEventHandler handler1 = { .this_arg = &queue1, .handle_event = handle_event, .free = NULL };
1153 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting PaymentSent and PaymentPathSuccessful events..." << std::endl;
1154 while (queue1.events.size() < 2) {
1155 PeerManager_process_events(&net2);
1156 PeerManager_process_events(&net1);
1158 LDK::EventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1);
1159 ev1.process_pending_events(handler1);
1160 std::this_thread::yield();
1162 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received PaymentSent and PaymentPathSuccessful events (presumably)!" << std::endl;
1163 assert(queue1.events.size() == 2);
1164 assert(queue1.events[0]->tag == LDKEvent_PaymentSent);
1165 assert(queue1.events[1]->tag == LDKEvent_PaymentPathSuccessful);
1167 // Actually close the channel
1168 num_txs_broadcasted = 0;
1169 close_res = ChannelManager_close_channel(&cm1, &chan_id, ChannelManager_get_our_node_id(&cm2));
1170 assert(close_res->result_ok);
1171 PeerManager_process_events(&net1);
1172 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting 2 transaction broadcasts..." << std::endl;
1173 while (num_txs_broadcasted != 2) {
1174 std::this_thread::yield();
1176 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Broadcast 2 transactions!" << std::endl;
1177 LDK::CVec_ChannelDetailsZ chans_after_close1 = ChannelManager_list_channels(&cm1);
1178 assert(chans_after_close1->datalen == 0);
1179 LDK::CVec_ChannelDetailsZ chans_after_close2 = ChannelManager_list_channels(&cm2);
1180 assert(chans_after_close2->datalen == 0);
1182 assert(OnionMessenger_send_onion_message(&om1,
1183 OnionMessagePath_new(
1184 LDKCVec_PublicKeyZ { .data = NULL, .datalen = 0, },
1185 Destination_node(ChannelManager_get_our_node_id(&cm2))
1187 build_custom_onion_message(),
1188 LDKBlindedPath { .inner = NULL, .is_owned = true })
1190 PeerManager_process_events(&net1);
1191 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting onion message..." << std::endl;
1193 std::this_thread::yield();
1194 std::unique_lock<std::mutex> lck(peer_2_custom_onion_messages.mtx);
1195 if (peer_2_custom_onion_messages.msgs.size() != 0) break;
1197 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received onion message!" << std::endl;
1201 std::unique_lock<std::mutex> lck(peer_2_custom_onion_messages.mtx);
1202 assert(peer_2_custom_onion_messages.msgs.size() == 1);
1203 assert(peer_2_custom_onion_messages.msgs[0].tlv_type() == 8888);
1204 assert(peer_2_custom_messages.msgs.size() != 0);
1206 // Few extra random tests:
1208 memset(&sk, 42, 32);
1209 LDKThirtyTwoBytes kdiv_params;
1210 memset(&kdiv_params, 43, 32);
1211 LDK::InMemorySigner signer = InMemorySigner_new(sk, sk, sk, sk, sk, random_bytes, 42, kdiv_params, kdiv_params);