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 PeerManager_disconnect_by_node_id(&net2, ChannelManager_get_our_node_id(&cm1));
246 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
248 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting new connection handshake..." << std::endl;
250 // Wait for the new connection handshake...
251 LDK::CVec_C2Tuple_PublicKeyCOption_SocketAddressZZZ peers_1 = PeerManager_get_peer_node_ids(&net1);
252 LDK::CVec_C2Tuple_PublicKeyCOption_SocketAddressZZZ peers_2 = PeerManager_get_peer_node_ids(&net2);
253 if (peers_1->datalen == 1 && peers_2->datalen == 1) { break; }
254 std::this_thread::yield();
256 std::cout << __FILE__ << ":" << __LINE__ << " - " << "New connection handshake complete!" << std::endl;
258 // Wait for all our sockets to disconnect (making sure we disconnect any new connections)...
259 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting peer disconnection..." << std::endl;
261 PeerManager_disconnect_by_node_id(&net1, ChannelManager_get_our_node_id(&cm2));
262 // Wait for the peers to disconnect...
263 LDK::CVec_C2Tuple_PublicKeyCOption_SocketAddressZZZ peers_1 = PeerManager_get_peer_node_ids(&net1);
264 LDK::CVec_C2Tuple_PublicKeyCOption_SocketAddressZZZ peers_2 = PeerManager_get_peer_node_ids(&net2);
265 if (peers_1->datalen == 0 && peers_2->datalen == 0) { break; }
266 std::this_thread::yield();
268 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Peers disconnected!" << std::endl;
269 // Note that the above is somewhat race-y, as node 2 may still think its connected.
270 // Thus, make sure any connections are disconnected on its end as well.
271 PeerManager_disconnect_by_node_id(&net2, ChannelManager_get_our_node_id(&cm1));
273 // Finally make an actual connection and keep it this time
274 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
276 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting initial handshake completion..." << std::endl;
278 // Wait for the initial handshakes to complete...
279 LDK::CVec_C2Tuple_PublicKeyCOption_SocketAddressZZZ peers_1 = PeerManager_get_peer_node_ids(&net1);
280 LDK::CVec_C2Tuple_PublicKeyCOption_SocketAddressZZZ peers_2 = PeerManager_get_peer_node_ids(&net2);
281 if (peers_1->datalen == 1 && peers_2->datalen == 1) { break; }
282 std::this_thread::yield();
284 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Initial handshake complete!" << std::endl;
287 interrupt_socket_handling(node1_handler);
288 interrupt_socket_handling(node2_handler);
294 uintptr_t sock_send_data(void *this_arg, LDKu8slice data, bool resume_read) {
295 return write((int)((long)this_arg), data.data, data.datalen);
297 void sock_disconnect_socket(void *this_arg) {
298 close((int)((long)this_arg));
300 bool sock_eq(const void *this_arg, const LDKSocketDescriptor *other_arg) {
301 return this_arg == other_arg->this_arg;
303 uint64_t sock_hash(const void *this_arg) {
304 return (uint64_t)this_arg;
306 void sock_read_data_thread(int rdfd, LDKSocketDescriptor *peer_descriptor, LDKPeerManager *pm) {
307 unsigned char buf[1024];
311 while ((readlen = read(rdfd, buf, 1024)) > 0) {
312 data.datalen = readlen;
313 LDK::CResult_boolPeerHandleErrorZ res = PeerManager_read_event(&*pm, peer_descriptor, data);
314 if (!res->result_ok) {
315 peer_descriptor->disconnect_socket(peer_descriptor->this_arg);
318 PeerManager_process_events(pm);
320 PeerManager_socket_disconnected(&*pm, peer_descriptor);
323 class PeersConnection {
324 int pipefds_1_to_2[2];
325 int pipefds_2_to_1[2];
327 LDKSocketDescriptor sock1, sock2;
330 PeersConnection(LDK::ChannelManager& cm1, LDK::ChannelManager& cm2, LDK::PeerManager& net1, LDK::PeerManager& net2) {
331 assert(!pipe(pipefds_1_to_2));
332 assert(!pipe(pipefds_2_to_1));
334 sock1 = LDKSocketDescriptor {
335 .this_arg = (void*)(long)pipefds_1_to_2[1],
336 .send_data = sock_send_data,
337 .disconnect_socket = sock_disconnect_socket,
344 sock2 = LDKSocketDescriptor {
345 .this_arg = (void*)(long)pipefds_2_to_1[1],
346 .send_data = sock_send_data,
347 .disconnect_socket = sock_disconnect_socket,
354 t1 = std::thread(&sock_read_data_thread, pipefds_2_to_1[0], &sock1, &net1);
355 t2 = std::thread(&sock_read_data_thread, pipefds_1_to_2[0], &sock2, &net2);
357 // Note that we have to bind the result to a C++ class to make sure it gets free'd
358 LDK::CResult_CVec_u8ZPeerHandleErrorZ con_res = PeerManager_new_outbound_connection(&net1, ChannelManager_get_our_node_id(&cm2), sock1, COption_SocketAddressZ_none());
359 assert(con_res->result_ok);
360 LDK::CResult_NonePeerHandleErrorZ con_res2 = PeerManager_new_inbound_connection(&net2, sock2, COption_SocketAddressZ_none());
361 assert(con_res2->result_ok);
363 auto writelen = write(pipefds_1_to_2[1], con_res->contents.result->data, con_res->contents.result->datalen);
364 assert(writelen > 0 && uint64_t(writelen) == con_res->contents.result->datalen);
366 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting initial handshake completion..." << std::endl;
368 // Wait for the initial handshakes to complete...
369 LDK::CVec_C2Tuple_PublicKeyCOption_SocketAddressZZZ peers_1 = PeerManager_get_peer_node_ids(&net1);
370 LDK::CVec_C2Tuple_PublicKeyCOption_SocketAddressZZZ peers_2 = PeerManager_get_peer_node_ids(&net2);
371 if (peers_1->datalen == 1 && peers_2->datalen ==1) { break; }
372 std::this_thread::yield();
374 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Initial handshake complete!" << std::endl;
378 close(pipefds_1_to_2[0]);
379 close(pipefds_2_to_1[0]);
380 close(pipefds_1_to_2[1]);
381 close(pipefds_2_to_1[1]);
388 struct CustomOnionMsgQueue {
390 std::vector<LDK::OnionMessageContents> msgs;
393 uint64_t custom_onion_msg_type_id(const void *this_arg) {
396 LDKCVec_u8Z custom_onion_msg_bytes(const void *this_arg) {
397 uint8_t *bytes = (uint8_t *) malloc(1024);
398 memset(bytes, 43, 1024);
400 .data = bytes, .datalen = 1024
404 LDKCOption_OnionMessageContentsZ handle_custom_onion_message(const void* this_arg, struct LDKOnionMessageContents msg) {
405 CustomOnionMsgQueue* arg = (CustomOnionMsgQueue*) this_arg;
406 std::unique_lock<std::mutex> lck(arg->mtx);
407 arg->msgs.push_back(std::move(msg));
408 return COption_OnionMessageContentsZ_none();
411 LDKOnionMessageContents build_custom_onion_message() {
412 return LDKOnionMessageContents {
414 .tlv_type = custom_onion_msg_type_id,
415 .write = custom_onion_msg_bytes,
420 LDKCResult_COption_OnionMessageContentsZDecodeErrorZ read_custom_onion_message(const void* this_arg, uint64_t type, LDKu8slice buf) {
421 assert(type == 8888);
422 assert(buf.datalen == 1024);
424 memset(cmp, 43, 1024);
425 assert(!memcmp(cmp, buf.data, 1024));
426 return CResult_COption_OnionMessageContentsZDecodeErrorZ_ok(COption_OnionMessageContentsZ_some(build_custom_onion_message()));
429 LDKCVec_C3Tuple_OnionMessageContentsDestinationBlindedPathZZ release_no_messages(const void* this_arg) {
430 return LDKCVec_C3Tuple_OnionMessageContentsDestinationBlindedPathZZ {
431 .data = NULL, .datalen = 0 };
434 struct CustomMsgQueue {
435 std::vector<LDK::Type> msgs;
438 uint16_t custom_msg_type_id(const void *this_arg) {
441 LDKCVec_u8Z custom_msg_bytes(const void *this_arg) {
442 uint8_t *bytes = (uint8_t *) malloc(1024);
443 memset(bytes, 42, 1024);
445 .data = bytes, .datalen = 1024
448 LDKStr custom_msg_debug(const void *this_arg) {
450 .chars = (const unsigned char*) "Custom Message", .len = 14, .chars_is_owned = false
454 LDKCResult_COption_TypeZDecodeErrorZ read_custom_message(const void* this_arg, uint16_t type_id, LDKu8slice buf) {
455 assert(type_id == 8888);
456 assert(buf.datalen == 1024);
458 memset(cmp, 42, 1024);
459 assert(!memcmp(cmp, buf.data, 1024));
460 return CResult_COption_TypeZDecodeErrorZ_ok(COption_TypeZ_some(LDKType {
462 .type_id = custom_msg_type_id,
463 .debug_str = custom_msg_debug,
464 .write = NULL, // This message should never be written
469 LDKCResult_NoneLightningErrorZ handle_custom_message(const void* this_arg, struct LDKType msg, struct LDKPublicKey _sender_node_id) {
470 CustomMsgQueue* arg = (CustomMsgQueue*) this_arg;
471 arg->msgs.push_back(std::move(msg));
472 return CResult_NoneLightningErrorZ_ok();
474 LDKCVec_C2Tuple_PublicKeyTypeZZ never_send_custom_msgs(const void* this_arg) {
475 return LDKCVec_C2Tuple_PublicKeyTypeZZ {
476 .data = NULL, .datalen = 0
480 LDKCVec_C2Tuple_PublicKeyTypeZZ create_custom_msg(const void* this_arg) {
481 const LDKPublicKey *counterparty_node_id = (const LDKPublicKey *)this_arg;
482 LDKCVec_C2Tuple_PublicKeyTypeZZ ret = {
483 .data = ((LDKC2Tuple_PublicKeyTypeZ*)malloc(sizeof(LDKC2Tuple_PublicKeyTypeZ))),
486 ret.data[0].a = *counterparty_node_id;
487 ret.data[0].b = LDKType {
489 .type_id = custom_msg_type_id,
490 .debug_str = custom_msg_debug,
491 .write = custom_msg_bytes,
497 LDKNodeFeatures custom_node_features(const void *this_arg) {
498 return NodeFeatures_empty();
501 LDKInitFeatures custom_init_features(const void *this_arg, struct LDKPublicKey their_node_id) {
502 return InitFeatures_empty();
505 uint64_t get_chan_score(const void *this_arg, uint64_t scid, const LDKNodeId *src, const LDKNodeId *dst, LDKChannelUsage usage_in, const LDKProbabilisticScoringFeeParameters *params) {
506 LDK::ChannelUsage usage(std::move(usage_in));
510 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) {
511 const LDK::DefaultRouter *router = (LDK::DefaultRouter *)this_arg;
512 assert(first_hops->datalen == 1);
513 assert(ChannelDetails_get_is_usable(&first_hops->data[0]));
514 const LDK::Router router_impl = DefaultRouter_as_Router(&*router);
515 return router_impl->find_route(router_impl->this_arg, payer, route_params, first_hops, in_flights);
519 uint8_t channel_open_header[80];
520 uint8_t header_1[80];
521 uint8_t header_2[80];
522 memcpy(channel_open_header, channel_open_block, 80);
523 memcpy(header_1, block_1, 80);
524 memcpy(header_2, block_2, 80);
526 LDKPublicKey null_pk;
527 memset(&null_pk, 0, sizeof(null_pk));
529 LDKThirtyTwoBytes random_bytes;
530 LDKThirtyTwoBytes chain_tip;
531 memset(&chain_tip, 0, sizeof(chain_tip)); // channel_open_header's prev_blockhash is all-0s
533 LDKNetwork network = LDKNetwork_Testnet;
535 // Trait implementations:
536 LDKBroadcasterInterface broadcast {
538 .broadcast_transactions = broadcast_txn,
542 // Instantiate classes for the nodes that don't get reloaded on a ser-des reload
544 .this_arg = (void*)1,
550 mons1.logger = &logger1;
553 .watch_channel = add_channel_monitor,
554 .update_channel = update_channel_monitor,
555 .release_pending_monitor_events = monitors_pending_monitor_events,
559 LDK::NetworkGraph net_graph1 = NetworkGraph_new(network, logger1);
560 LDK::P2PGossipSync graph_msg_handler1 = P2PGossipSync_new(&net_graph1, COption_UtxoLookupZ_none(), logger1);
563 .this_arg = (void*)2,
569 mons2.logger = &logger2;
572 .watch_channel = add_channel_monitor,
573 .update_channel = update_channel_monitor,
574 .release_pending_monitor_events = monitors_pending_monitor_events,
578 LDKRouter panic_router = {
580 .find_route = NULL, // Segfault if we ever try to find a route
581 .find_route_with_id = NULL, // Segfault if we ever try to find a route
585 LDK::NetworkGraph net_graph2 = NetworkGraph_new(network, logger2);
586 LDK::P2PGossipSync graph_msg_handler2 = P2PGossipSync_new(&net_graph2, COption_UtxoLookupZ_none(), logger2);
588 LDK::CVec_u8Z cm1_ser = LDKCVec_u8Z {}; // ChannelManager 1 serialization at the end of the ser-des scope
589 LDK::CVec_u8Z cm2_ser = LDKCVec_u8Z {}; // ChannelManager 2 serialization at the end of the ser-des scope
591 { // Scope for the ser-des reload
592 // Instantiate classes for node 1:
593 uint8_t node_seed[32];
594 memset(&node_seed, 0, 32);
595 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 0, 0);
596 LDK::NodeSigner node_signer1 = KeysManager_as_NodeSigner(&keys1);
597 LDK::EntropySource entropy_source1 = KeysManager_as_EntropySource(&keys1);
598 LDK::SignerProvider signer_provider1 = KeysManager_as_SignerProvider(&keys1);
600 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);
602 LDK::IgnoringMessageHandler ignoring_handler1 = IgnoringMessageHandler_new();
603 LDK::CustomMessageHandler custom_msg_handler1 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler1);
604 LDK::CustomOnionMessageHandler custom_onion_msg_handler1 = IgnoringMessageHandler_as_CustomOnionMessageHandler(&ignoring_handler1);
605 LDK::DefaultMessageRouter mr1 = DefaultMessageRouter_new();
606 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));
608 LDK::CVec_ChannelDetailsZ channels = ChannelManager_list_channels(&cm1);
609 assert(channels->datalen == 0);
611 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));
613 random_bytes = entropy_source1.get_secure_random_bytes();
614 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), 0xdeadbeef, &random_bytes.data, logger1, std::move(node_signer1));
616 // Demo getting a channel key and check that its returning real pubkeys:
617 LDKSixteenBytes user_id_1 { .data = {45, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0} };
618 LDKThirtyTwoBytes chan_signer_id1 = signer_provider1.generate_channel_keys_id(false, 42, U128_new(user_id_1));
619 LDK::WriteableEcdsaChannelSigner chan_signer1 = signer_provider1.derive_channel_signer(42, chan_signer_id1);
620 chan_signer1->EcdsaChannelSigner.ChannelSigner.set_pubkeys(&chan_signer1->EcdsaChannelSigner.ChannelSigner); // Make sure pubkeys is defined
621 LDKPublicKey payment_point = ChannelPublicKeys_get_payment_point(&chan_signer1->EcdsaChannelSigner.ChannelSigner.pubkeys);
622 assert(memcmp(&payment_point, &null_pk, sizeof(null_pk)));
624 // Instantiate classes for node 2:
625 memset(&node_seed, 1, 32);
626 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 0, 0);
627 LDK::NodeSigner node_signer2 = KeysManager_as_NodeSigner(&keys2);
628 LDK::EntropySource entropy_source2 = KeysManager_as_EntropySource(&keys2);
629 LDK::SignerProvider signer_provider2 = KeysManager_as_SignerProvider(&keys2);
631 LDK::ChannelHandshakeConfig handshake_config2 = ChannelHandshakeConfig_default();
632 ChannelHandshakeConfig_set_minimum_depth(&handshake_config2, 2);
633 LDK::UserConfig config2 = UserConfig_default();
634 UserConfig_set_channel_handshake_config(&config2, std::move(handshake_config2));
636 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);
638 LDK::IgnoringMessageHandler ignoring_handler2 = IgnoringMessageHandler_new();
639 LDK::CustomMessageHandler custom_msg_handler2 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler2);
640 LDK::CustomOnionMessageHandler custom_onion_msg_handler2 = IgnoringMessageHandler_as_CustomOnionMessageHandler(&ignoring_handler2);
641 LDK::DefaultMessageRouter mr2 = DefaultMessageRouter_new();
642 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));
644 LDK::CVec_ChannelDetailsZ channels2 = ChannelManager_list_channels(&cm2);
645 assert(channels2->datalen == 0);
647 LDK::RoutingMessageHandler net_msgs2 = P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler2);
648 LDK::CResult_ChannelAnnouncementDecodeErrorZ chan_ann = ChannelAnnouncement_read(LDKu8slice { .data = valid_node_announcement, .datalen = sizeof(valid_node_announcement) });
649 assert(chan_ann->result_ok);
650 LDK::CResult_boolLightningErrorZ ann_res = net_msgs2->handle_channel_announcement(net_msgs2->this_arg, chan_ann->contents.result);
651 assert(ann_res->result_ok);
653 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), std::move(net_msgs2), OnionMessenger_as_OnionMessageHandler(&om1), std::move(custom_msg_handler2));
655 random_bytes = entropy_source2.get_secure_random_bytes();
656 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), 0xdeadbeef, &random_bytes.data, logger2, std::move(node_signer2));
658 // Open a connection!
659 PeersConnection conn(cm1, cm2, net1, net2);
661 // Note that we have to bind the result to a C++ class to make sure it gets free'd
662 LDK::CResult_ThirtyTwoBytesAPIErrorZ res = ChannelManager_create_channel(&cm1, ChannelManager_get_our_node_id(&cm2), 40000, 1000, U128_new(user_id_1), UserConfig_default());
663 assert(res->result_ok);
664 PeerManager_process_events(&net1);
666 LDK::CVec_ChannelDetailsZ new_channels = ChannelManager_list_channels(&cm1);
667 assert(new_channels->datalen == 1);
668 LDK::ChannelCounterparty new_channels_counterparty = ChannelDetails_get_counterparty(&new_channels->data[0]);
669 LDKPublicKey chan_open_pk = ChannelCounterparty_get_node_id(&new_channels_counterparty);
670 assert(!memcmp(chan_open_pk.compressed_form, ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
672 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting first channel..." << std::endl;
674 LDK::CVec_ChannelDetailsZ new_channels_2 = ChannelManager_list_channels(&cm2);
675 if (new_channels_2->datalen == 1) {
676 // Sample getting our counterparty's init features (which used to be hard to do without a memory leak):
677 LDK::ChannelCounterparty new_channels_2_counterparty = ChannelDetails_get_counterparty(&new_channels_2->data[0]);
678 const LDK::InitFeatures init_feats = ChannelCounterparty_get_features(&new_channels_2_counterparty);
679 assert(init_feats->inner != NULL);
682 std::this_thread::yield();
684 std::cout << __FILE__ << ":" << __LINE__ << " - " << "First channel listed!" << std::endl;
686 LDK::EventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1);
687 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting FundingGenerationReady event..." << std::endl;
690 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
691 ev1.process_pending_events(handler);
692 if (queue.events.size() == 1) {
693 assert(queue.events[0]->tag == LDKEvent_FundingGenerationReady);
694 LDKSixteenBytes event_id = U128_le_bytes(queue.events[0]->funding_generation_ready.user_channel_id);
695 assert(!memcmp(&event_id, &user_id_1, 16));
696 assert(queue.events[0]->funding_generation_ready.channel_value_satoshis == 40000);
697 assert(queue.events[0]->funding_generation_ready.output_script.datalen == 34);
699 assert(!memcmp(queue.events[0]->funding_generation_ready.output_script.data, channel_open_block + 58 + 81, 34));
700 LDKTransaction funding_transaction { .data = const_cast<uint8_t*>(channel_open_block + 81), .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false };
702 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);
703 assert(fund_res->result_ok);
706 std::this_thread::yield();
708 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received FundingGenerationReady event!" << std::endl;
710 // We observe when the funding signed messages have been exchanged by
711 // waiting for two monitors to be registered.
712 assert(num_txs_broadcasted == 0);
713 PeerManager_process_events(&net1);
714 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting transaction broadcast..." << std::endl;
715 while (num_txs_broadcasted != 1) {
716 std::this_thread::yield();
718 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Transaction was broadcast!" << std::endl;
720 // Note that the channel ID is the same as the channel txid reversed as the output index is 0
721 uint8_t expected_chan_id[32];
722 for (int i = 0; i < 32; i++) { expected_chan_id[i] = channel_open_txid[31-i]; }
724 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting ChannelPending event..." << std::endl;
727 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
728 ev1.process_pending_events(handler);
729 if (queue.events.size() == 1) {
730 assert(queue.events[0]->tag == LDKEvent_ChannelPending);
731 assert(!memcmp(queue.events[0]->channel_pending.channel_id.data, expected_chan_id, 32));
734 std::this_thread::yield();
736 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received ChannelPending event!" << std::endl;
738 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
739 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting ChannelPending event..." << std::endl;
742 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
743 ev2.process_pending_events(handler);
744 if (queue.events.size() == 1) {
745 assert(queue.events[0]->tag == LDKEvent_ChannelPending);
746 assert(!memcmp(queue.events[0]->channel_pending.channel_id.data, expected_chan_id, 32));
749 std::this_thread::yield();
751 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received ChannelPending event!" << std::endl;
753 LDK::Listen listener1 = ChannelManager_as_Listen(&cm1);
754 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
756 LDK::Listen listener2 = ChannelManager_as_Listen(&cm2);
757 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
759 LDKCVec_C2Tuple_usizeTransactionZZ txdata { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
760 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
761 mons1.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
763 txdata = LDKCVec_C2Tuple_usizeTransactionZZ { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
764 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
765 mons2.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
767 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
768 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
769 mons1.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
770 mons2.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
772 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
773 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
774 mons1.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
775 mons2.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
777 PeerManager_process_events(&net1);
778 PeerManager_process_events(&net2);
780 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting ChannelReady event..." << std::endl;
783 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
784 ev2.process_pending_events(handler);
785 if (queue.events.size() == 1) {
786 assert(queue.events[0]->tag == LDKEvent_ChannelReady);
787 assert(!memcmp(queue.events[0]->channel_ready.channel_id.data, expected_chan_id, 32));
790 std::this_thread::yield();
792 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received ChannelReady event!" << std::endl;
794 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting ChannelReady event..." << std::endl;
797 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
798 ev1.process_pending_events(handler);
799 if (queue.events.size() == 1) {
800 assert(queue.events[0]->tag == LDKEvent_ChannelReady);
801 assert(!memcmp(queue.events[0]->channel_ready.channel_id.data, expected_chan_id, 32));
804 std::this_thread::yield();
806 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received ChannelReady event!" << std::endl;
808 // Now send funds from 1 to 2!
809 uint64_t channel_scid;
810 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting usable channel..." << std::endl;
812 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
813 if (outbound_channels->datalen == 1) {
814 const LDKChannelDetails *channel = &outbound_channels->data[0];
815 LDK::ChannelCounterparty counterparty = ChannelDetails_get_counterparty(channel);
817 assert(!memcmp(ChannelDetails_get_channel_id(channel), expected_chan_id, 32));
819 ChannelCounterparty_get_node_id(&counterparty).compressed_form,
820 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
821 assert(ChannelDetails_get_channel_value_satoshis(channel) == 40000);
822 // We opened the channel with 1000 push_msat:
823 assert(ChannelDetails_get_outbound_capacity_msat(channel) ==
824 40000*1000 - 1000 - 1000 * ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty));
825 int64_t inbound_capacity = ((int64_t)1000) - ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty);
826 if (inbound_capacity < 0) inbound_capacity = 0;
827 assert(ChannelDetails_get_inbound_capacity_msat(channel) == (uint64_t)inbound_capacity);
828 assert(ChannelDetails_get_is_usable(channel));
829 LDK::COption_u64Z scid_opt = ChannelDetails_get_short_channel_id(channel);
830 assert(scid_opt->some);
831 channel_scid = scid_opt->some;
834 std::this_thread::yield();
836 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Listed usable channel!" << std::endl;
838 LDKCOption_u64Z min_value = {
839 .tag = LDKCOption_u64Z_Some,
842 LDK::CResult_Bolt11InvoiceSignOrCreationErrorZ invoice = create_invoice_from_channelmanager(&cm2,
843 KeysManager_as_NodeSigner(&keys2), logger2,
844 LDKCurrency_Bitcoin, min_value,
846 .chars = (const uint8_t *)"Invoice Description",
847 .len = strlen("Invoice Description"),
848 .chars_is_owned = false
849 }, 3600, COption_u16Z_none());
850 assert(invoice->result_ok);
851 LDKThirtyTwoBytes payment_hash;
852 memcpy(payment_hash.data, Bolt11Invoice_payment_hash(invoice->contents.result), 32);
855 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
856 LDK::ScoreLookUp chan_scorer = LDKScoreLookUp {
857 .this_arg = NULL, .channel_penalty_msat = get_chan_score, .free = NULL,
859 LDK::Payee payee = Payee_clear(ChannelManager_get_our_node_id(&cm2), Bolt11Invoice_route_hints(invoice->contents.result),
860 LDKBolt11InvoiceFeatures {
861 .inner = NULL, .is_owned = false
862 }, Bolt11Invoice_min_final_cltv_expiry_delta(invoice->contents.result));
863 LDK::RouteParameters route_params = RouteParameters_from_payment_params_and_value(
864 PaymentParameters_new(std::move(payee), COption_u64Z_none(), 0xffffffff, 1, 2,
865 LDKCVec_u64Z { .data = NULL, .datalen = 0 }),
867 random_bytes = entropy_source1.get_secure_random_bytes();
868 LDK::ProbabilisticScoringFeeParameters params = ProbabilisticScoringFeeParameters_default();
870 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);
872 assert(route->result_ok);
873 LDK::CVec_PathZ paths = Route_get_paths(route->contents.result);
874 assert(paths->datalen == 1);
875 LDK::CVec_RouteHopZ hops = Path_get_hops(&paths->data[0]);
876 assert(hops->datalen == 1);
877 assert(!memcmp(RouteHop_get_pubkey(&hops->data[0]).compressed_form,
878 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
879 assert(RouteHop_get_short_channel_id(&hops->data[0]) == channel_scid);
880 LDKThirtyTwoBytes payment_secret;
881 memcpy(payment_secret.data, Bolt11Invoice_payment_secret(invoice->contents.result), 32);
882 LDK::CResult_NonePaymentSendFailureZ send_res = ChannelManager_send_payment_with_route(&cm1,
883 route->contents.result, payment_hash, RecipientOnionFields_secret_only(payment_secret), payment_hash);
884 assert(send_res->result_ok);
888 PeerManager_process_events(&net1);
889 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting 4 updated monitors..." << std::endl;
890 while (mons_updated != 4) {
891 std::this_thread::yield();
893 std::cout << __FILE__ << ":" << __LINE__ << " - " << "4 monitors updated!" << std::endl;
895 // Check that we received the payment!
896 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting PendingHTLCsForwardable event..." << std::endl;
899 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
900 ev2.process_pending_events(handler);
901 if (queue.events.size() == 1) {
902 assert(queue.events[0]->tag == LDKEvent_PendingHTLCsForwardable);
905 std::this_thread::yield();
907 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received PendingHTLCsForwardable event!" << std::endl;
908 ChannelManager_process_pending_htlc_forwards(&cm2);
909 PeerManager_process_events(&net2);
912 LDKThirtyTwoBytes payment_preimage;
915 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
916 ev2.process_pending_events(handler);
917 assert(queue.events.size() == 1);
918 assert(queue.events[0]->tag == LDKEvent_PaymentClaimable);
919 assert(!memcmp(queue.events[0]->payment_claimable.payment_hash.data, payment_hash.data, 32));
920 assert(queue.events[0]->payment_claimable.purpose.tag == LDKPaymentPurpose_InvoicePayment);
921 assert(!memcmp(queue.events[0]->payment_claimable.purpose.invoice_payment.payment_secret.data,
922 Bolt11Invoice_payment_secret(invoice->contents.result), 32));
923 assert(queue.events[0]->payment_claimable.amount_msat == 5000);
924 assert(queue.events[0]->payment_claimable.purpose.invoice_payment.payment_preimage.tag == LDKCOption_ThirtyTwoBytesZ_Some);
925 memcpy(payment_preimage.data, queue.events[0]->payment_claimable.purpose.invoice_payment.payment_preimage.some.data, 32);
926 ChannelManager_claim_funds(&cm2, payment_preimage);
928 queue.events.clear();
929 ev2.process_pending_events(handler);
930 assert(queue.events.size() == 1);
931 assert(queue.events[0]->tag == LDKEvent_PaymentClaimed);
932 assert(!memcmp(queue.events[0]->payment_claimed.payment_hash.data, payment_hash.data, 32));
933 assert(queue.events[0]->payment_claimed.purpose.tag == LDKPaymentPurpose_InvoicePayment);
935 PeerManager_process_events(&net2);
936 // Wait until we've passed through a full set of monitor updates (ie new preimage + CS/RAA messages)
939 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
940 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting PaymentSent and PaymentPathSuccessful events..." << std::endl;
941 while (queue.events.size() < 2) {
942 ev1.process_pending_events(handler);
943 std::this_thread::yield();
945 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received PaymentSent and PaymentPathSuccessful events (presumably)!" << std::endl;
946 assert(queue.events.size() == 2);
947 assert(queue.events[0]->tag == LDKEvent_PaymentSent);
948 assert(!memcmp(queue.events[0]->payment_sent.payment_preimage.data, payment_preimage.data, 32));
949 assert(queue.events[1]->tag == LDKEvent_PaymentPathSuccessful);
950 assert(queue.events[1]->payment_path_successful.payment_hash.tag == LDKCOption_ThirtyTwoBytesZ_Some);
951 assert(!memcmp(queue.events[1]->payment_path_successful.payment_hash.some.data, payment_hash.data, 32));
953 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting 5 updated monitors..." << std::endl;
954 while (mons_updated != 5) {
955 std::this_thread::yield();
957 std::cout << __FILE__ << ":" << __LINE__ << " - " << "5 monitors updated!" << std::endl;
961 cm1_ser = ChannelManager_write(&cm1);
962 cm2_ser = ChannelManager_write(&cm2);
965 LDK::CVec_ChannelMonitorZ mons_list1 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
966 assert(mons1.mons.size() == 1);
967 mons_list1->data[0] = *& std::get<1>(mons1.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
968 mons_list1->data[0].is_owned = false; // XXX: God this sucks
969 uint8_t node_seed[32];
970 memset(&node_seed, 0, 32);
971 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 1, 0);
972 LDK::NodeSigner node_signer1 = KeysManager_as_NodeSigner(&keys1);
973 LDK::EntropySource entropy_source1 = KeysManager_as_EntropySource(&keys1);
974 LDK::SignerProvider signer_provider1 = KeysManager_as_SignerProvider(&keys1);
976 LDK::ProbabilisticScorer scorer1 = ProbabilisticScorer_new(ProbabilisticScoringDecayParameters_default(), &net_graph1, logger1);
977 LDK::Score scorer_trait1 = ProbabilisticScorer_as_Score(&scorer1);
978 LDK::MultiThreadedLockableScore scorer_mtx1 = MultiThreadedLockableScore_new(std::move(scorer_trait1));
979 LDK::LockableScore scorer_mtx_trait1 = MultiThreadedLockableScore_as_LockableScore(&scorer_mtx1);
980 LDK::ProbabilisticScoringFeeParameters params = ProbabilisticScoringFeeParameters_default();
981 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));
982 LDKRouter router1 = {
983 .this_arg = (void*)&default_router_1,
984 .find_route = NULL, // LDK currently doesn't use this, its just a default-impl
985 .find_route_with_id = custom_find_route,
989 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));
990 LDK::CResult_C2Tuple_ThirtyTwoBytesChannelManagerZDecodeErrorZ cm1_read =
991 C2Tuple_ThirtyTwoBytesChannelManagerZ_read(LDKu8slice { .data = cm1_ser->data, .datalen = cm1_ser -> datalen}, std::move(cm1_args));
992 assert(cm1_read->result_ok);
993 LDK::ChannelManager cm1(std::move(cm1_read->contents.result->b));
995 LDKCustomOnionMessageHandler custom_onion_msg_handler1 = {
997 .handle_custom_message = NULL, // We only create custom messages, not handle them
998 .read_custom_message = NULL, // We only create custom messages, not handle them
999 .release_pending_custom_messages = release_no_messages,
1002 LDK::DefaultMessageRouter mr1 = DefaultMessageRouter_new();
1003 LDK::IgnoringMessageHandler ignorer_1 = IgnoringMessageHandler_new();
1004 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));
1006 LDK::CVec_ChannelMonitorZ mons_list2 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
1007 assert(mons2.mons.size() == 1);
1008 mons_list2->data[0] = *& std::get<1>(mons2.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
1009 mons_list2->data[0].is_owned = false; // XXX: God this sucks
1010 memset(&node_seed, 1, 32);
1011 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 1, 0);
1012 LDK::NodeSigner node_signer2 = KeysManager_as_NodeSigner(&keys2);
1013 LDK::EntropySource entropy_source2 = KeysManager_as_EntropySource(&keys2);
1014 LDK::SignerProvider signer_provider2 = KeysManager_as_SignerProvider(&keys2);
1016 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));
1017 LDK::CResult_C2Tuple_ThirtyTwoBytesChannelManagerZDecodeErrorZ cm2_read =
1018 C2Tuple_ThirtyTwoBytesChannelManagerZ_read(LDKu8slice { .data = cm2_ser->data, .datalen = cm2_ser -> datalen}, std::move(cm2_args));
1019 assert(cm2_read->result_ok);
1020 LDK::ChannelManager cm2(std::move(cm2_read->contents.result->b));
1022 CustomOnionMsgQueue peer_2_custom_onion_messages;
1023 LDKCustomOnionMessageHandler custom_onion_msg_handler2 = {
1024 .this_arg = &peer_2_custom_onion_messages,
1025 .handle_custom_message = handle_custom_onion_message,
1026 .read_custom_message = read_custom_onion_message,
1027 .release_pending_custom_messages = release_no_messages,
1030 LDK::DefaultMessageRouter mr2 = DefaultMessageRouter_new();
1031 LDK::IgnoringMessageHandler ignorer_2 = IgnoringMessageHandler_new();
1032 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);
1034 // Attempt to close the channel...
1035 uint8_t chan_id[32];
1036 for (int i = 0; i < 32; i++) { chan_id[i] = channel_open_txid[31-i]; }
1037 LDK::CResult_NoneAPIErrorZ close_res = ChannelManager_close_channel(&cm1, &chan_id, ChannelManager_get_our_node_id(&cm2));
1038 assert(!close_res->result_ok); // Note that we can't close while disconnected!
1040 // Open a connection!
1041 LDKPublicKey chan_2_node_id = ChannelManager_get_our_node_id(&cm2);
1042 LDKCustomMessageHandler custom_msg_handler1 = {
1043 .this_arg = &chan_2_node_id,
1044 .handle_custom_message = NULL, // We only create custom messages, not handle them
1045 .get_and_clear_pending_msg = create_custom_msg,
1046 .provided_node_features = custom_node_features,
1047 .provided_init_features = custom_init_features,
1048 .CustomMessageReader = LDKCustomMessageReader {
1050 .read = read_custom_message,
1055 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler1), OnionMessenger_as_OnionMessageHandler(&om1), custom_msg_handler1);
1056 random_bytes = entropy_source1.get_secure_random_bytes();
1057 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), 0xdeadbeef, &random_bytes.data, logger1, std::move(node_signer1));
1059 CustomMsgQueue peer_2_custom_messages;
1060 LDKCustomMessageHandler custom_msg_handler2 = {
1061 .this_arg = &peer_2_custom_messages,
1062 .handle_custom_message = handle_custom_message,
1063 .get_and_clear_pending_msg = never_send_custom_msgs,
1064 .provided_node_features = custom_node_features,
1065 .provided_init_features = custom_init_features,
1066 .CustomMessageReader = LDKCustomMessageReader {
1068 .read = read_custom_message,
1073 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler2), OnionMessenger_as_OnionMessageHandler(&om2), custom_msg_handler2);
1074 random_bytes = entropy_source1.get_secure_random_bytes();
1075 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), 0xdeadbeef, &random_bytes.data, logger2, std::move(node_signer2));
1077 PeersConnection conn(cm1, cm2, net1, net2);
1079 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting usable channel..." << std::endl;
1081 // Wait for the channels to be considered up once the reestablish messages are processed
1082 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
1083 if (outbound_channels->datalen == 1) {
1086 std::this_thread::yield();
1088 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Listed usable channel!" << std::endl;
1090 // Send another payment, this time via the retires path
1091 LDK::CResult_Bolt11InvoiceSignOrCreationErrorZ invoice_res2 = create_invoice_from_channelmanager(&cm2,
1092 KeysManager_as_NodeSigner(&keys2), logger1,
1093 LDKCurrency_Bitcoin, COption_u64Z_some(10000),
1095 .chars = (const uint8_t *)"Invoice 2 Description",
1096 .len = strlen("Invoice 2 Description"),
1097 .chars_is_owned = false
1098 }, 3600, COption_u16Z_none());
1099 assert(invoice_res2->result_ok);
1100 const LDKBolt11Invoice *invoice2 = invoice_res2->contents.result;
1101 LDK::CResult_ThirtyTwoBytesPaymentErrorZ invoice_pay_res = pay_invoice(invoice2, Retry_attempts(0), &cm1);
1102 assert(invoice_pay_res->result_ok);
1103 PeerManager_process_events(&net1);
1105 // Check that we received the payment!
1106 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting PendingHTLCsForwardable event..." << std::endl;
1109 LDKEventHandler handler2 = { .this_arg = &queue2, .handle_event = handle_event, .free = NULL };
1110 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
1111 ev2.process_pending_events(handler2);
1112 if (queue2.events.size() == 1) {
1113 assert(queue2.events[0]->tag == LDKEvent_PendingHTLCsForwardable);
1116 std::this_thread::yield();
1118 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received PendingHTLCsForwardable event!" << std::endl;
1119 ChannelManager_process_pending_htlc_forwards(&cm2);
1120 PeerManager_process_events(&net2);
1122 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting PaymentClaimable/PaymentClaimed event..." << std::endl;
1125 LDKEventHandler handler2 = { .this_arg = &queue2, .handle_event = handle_event, .free = NULL };
1126 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
1127 ev2.process_pending_events(handler2);
1128 if (queue2.events.size() == 1) {
1129 assert(queue2.events[0]->tag == LDKEvent_PaymentClaimable);
1130 const struct LDKEvent_LDKPaymentClaimable_Body *event_data = &queue2.events[0]->payment_claimable;
1131 assert(!memcmp(event_data->payment_hash.data, Bolt11Invoice_payment_hash(invoice2), 32));
1132 assert(event_data->purpose.tag == LDKPaymentPurpose_InvoicePayment);
1133 assert(!memcmp(event_data->purpose.invoice_payment.payment_secret.data,
1134 Bolt11Invoice_payment_secret(invoice2), 32));
1135 assert(event_data->amount_msat == 10000);
1136 assert(event_data->purpose.invoice_payment.payment_preimage.tag == LDKCOption_ThirtyTwoBytesZ_Some);
1137 ChannelManager_claim_funds(&cm2, event_data->purpose.invoice_payment.payment_preimage.some);
1139 queue2.events.clear();
1140 ev2.process_pending_events(handler2);
1141 assert(queue2.events.size() == 1);
1142 assert(queue2.events[0]->tag == LDKEvent_PaymentClaimed);
1143 assert(!memcmp(queue2.events[0]->payment_claimed.payment_hash.data, Bolt11Invoice_payment_hash(invoice2), 32));
1144 assert(queue2.events[0]->payment_claimed.purpose.tag == LDKPaymentPurpose_InvoicePayment);
1148 std::this_thread::yield();
1150 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received PaymentClaimable/PaymentClaimed event!" << std::endl;
1153 LDKEventHandler handler1 = { .this_arg = &queue1, .handle_event = handle_event, .free = NULL };
1154 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting PaymentSent and PaymentPathSuccessful events..." << std::endl;
1155 while (queue1.events.size() < 2) {
1156 PeerManager_process_events(&net2);
1157 PeerManager_process_events(&net1);
1159 LDK::EventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1);
1160 ev1.process_pending_events(handler1);
1161 std::this_thread::yield();
1163 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received PaymentSent and PaymentPathSuccessful events (presumably)!" << std::endl;
1164 assert(queue1.events.size() == 2);
1165 assert(queue1.events[0]->tag == LDKEvent_PaymentSent);
1166 assert(queue1.events[1]->tag == LDKEvent_PaymentPathSuccessful);
1168 // Actually close the channel
1169 num_txs_broadcasted = 0;
1170 close_res = ChannelManager_close_channel(&cm1, &chan_id, ChannelManager_get_our_node_id(&cm2));
1171 assert(close_res->result_ok);
1172 PeerManager_process_events(&net1);
1173 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting 2 transaction broadcasts..." << std::endl;
1174 while (num_txs_broadcasted != 2) {
1175 std::this_thread::yield();
1177 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Broadcast 2 transactions!" << std::endl;
1178 LDK::CVec_ChannelDetailsZ chans_after_close1 = ChannelManager_list_channels(&cm1);
1179 assert(chans_after_close1->datalen == 0);
1180 LDK::CVec_ChannelDetailsZ chans_after_close2 = ChannelManager_list_channels(&cm2);
1181 assert(chans_after_close2->datalen == 0);
1183 assert(OnionMessenger_send_onion_message(&om1,
1184 OnionMessagePath_new(
1185 LDKCVec_PublicKeyZ { .data = NULL, .datalen = 0, },
1186 Destination_node(ChannelManager_get_our_node_id(&cm2))
1188 build_custom_onion_message(),
1189 LDKBlindedPath { .inner = NULL, .is_owned = true })
1191 PeerManager_process_events(&net1);
1192 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting onion message..." << std::endl;
1194 std::this_thread::yield();
1195 std::unique_lock<std::mutex> lck(peer_2_custom_onion_messages.mtx);
1196 if (peer_2_custom_onion_messages.msgs.size() != 0) break;
1198 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received onion message!" << std::endl;
1202 std::unique_lock<std::mutex> lck(peer_2_custom_onion_messages.mtx);
1203 assert(peer_2_custom_onion_messages.msgs.size() == 1);
1204 assert(peer_2_custom_onion_messages.msgs[0].tlv_type() == 8888);
1205 assert(peer_2_custom_messages.msgs.size() != 0);
1207 // Few extra random tests:
1209 memset(&sk, 42, 32);
1210 LDKThirtyTwoBytes kdiv_params;
1211 memset(&kdiv_params, 43, 32);
1212 LDK::InMemorySigner signer = InMemorySigner_new(sk, sk, sk, sk, sk, random_bytes, 42, kdiv_params, kdiv_params);