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_Background) {
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 LDKChannelMonitorUpdateStatus 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 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_OutPointScriptZ 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_NetAddressZZZ peers_1 = PeerManager_get_peer_node_ids(&net1);
233 LDK::CVec_C2Tuple_PublicKeyCOption_NetAddressZZZ 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_NetAddressZZZ peers_1 = PeerManager_get_peer_node_ids(&net1);
251 LDK::CVec_C2Tuple_PublicKeyCOption_NetAddressZZZ 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_NetAddressZZZ peers_1 = PeerManager_get_peer_node_ids(&net1);
263 LDK::CVec_C2Tuple_PublicKeyCOption_NetAddressZZZ 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_NetAddressZZZ peers_1 = PeerManager_get_peer_node_ids(&net1);
279 LDK::CVec_C2Tuple_PublicKeyCOption_NetAddressZZZ 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_NetAddressZ_none());
358 assert(con_res->result_ok);
359 LDK::CResult_NonePeerHandleErrorZ con_res2 = PeerManager_new_inbound_connection(&net2, sock2, COption_NetAddressZ_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_NetAddressZZZ peers_1 = PeerManager_get_peer_node_ids(&net1);
369 LDK::CVec_C2Tuple_PublicKeyCOption_NetAddressZZZ 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::CustomOnionMessageContents> 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_CustomOnionMessageContentsZ handle_custom_onion_message(const void* this_arg, struct LDKCustomOnionMessageContents 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_CustomOnionMessageContentsZ_none();
410 LDKCustomOnionMessageContents build_custom_onion_message() {
411 return LDKCustomOnionMessageContents {
413 .tlv_type = custom_onion_msg_type_id,
414 .write = custom_onion_msg_bytes,
419 LDKCResult_COption_CustomOnionMessageContentsZDecodeErrorZ 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_CustomOnionMessageContentsZDecodeErrorZ_ok(COption_CustomOnionMessageContentsZ_some(build_custom_onion_message()));
429 struct CustomMsgQueue {
430 std::vector<LDK::Type> msgs;
433 uint16_t custom_msg_type_id(const void *this_arg) {
436 LDKCVec_u8Z custom_msg_bytes(const void *this_arg) {
437 uint8_t *bytes = (uint8_t *) malloc(1024);
438 memset(bytes, 42, 1024);
440 .data = bytes, .datalen = 1024
443 LDKStr custom_msg_debug(const void *this_arg) {
445 .chars = (const unsigned char*) "Custom Message", .len = 14, .chars_is_owned = false
449 LDKCResult_COption_TypeZDecodeErrorZ read_custom_message(const void* this_arg, uint16_t type_id, LDKu8slice buf) {
450 assert(type_id == 8888);
451 assert(buf.datalen == 1024);
453 memset(cmp, 42, 1024);
454 assert(!memcmp(cmp, buf.data, 1024));
455 return CResult_COption_TypeZDecodeErrorZ_ok(COption_TypeZ_some(LDKType {
457 .type_id = custom_msg_type_id,
458 .debug_str = custom_msg_debug,
459 .write = NULL, // This message should never be written
464 LDKCResult_NoneLightningErrorZ handle_custom_message(const void* this_arg, struct LDKType msg, struct LDKPublicKey _sender_node_id) {
465 CustomMsgQueue* arg = (CustomMsgQueue*) this_arg;
466 arg->msgs.push_back(std::move(msg));
467 return CResult_NoneLightningErrorZ_ok();
469 LDKCVec_C2Tuple_PublicKeyTypeZZ never_send_custom_msgs(const void* this_arg) {
470 return LDKCVec_C2Tuple_PublicKeyTypeZZ {
471 .data = NULL, .datalen = 0
475 LDKCVec_C2Tuple_PublicKeyTypeZZ create_custom_msg(const void* this_arg) {
476 const LDKPublicKey *counterparty_node_id = (const LDKPublicKey *)this_arg;
477 LDKCVec_C2Tuple_PublicKeyTypeZZ ret = {
478 .data = ((LDKC2Tuple_PublicKeyTypeZ*)malloc(sizeof(LDKC2Tuple_PublicKeyTypeZ))),
481 ret.data[0].a = *counterparty_node_id;
482 ret.data[0].b = LDKType {
484 .type_id = custom_msg_type_id,
485 .debug_str = custom_msg_debug,
486 .write = custom_msg_bytes,
492 LDKNodeFeatures custom_node_features(const void *this_arg) {
493 return NodeFeatures_empty();
496 LDKInitFeatures custom_init_features(const void *this_arg, struct LDKPublicKey their_node_id) {
497 return InitFeatures_empty();
500 uint64_t get_chan_score(const void *this_arg, uint64_t scid, const LDKNodeId *src, const LDKNodeId *dst, LDKChannelUsage usage_in, const LDKProbabilisticScoringFeeParameters *params) {
501 LDK::ChannelUsage usage(std::move(usage_in));
505 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) {
506 const LDK::DefaultRouter *router = (LDK::DefaultRouter *)this_arg;
507 assert(first_hops->datalen == 1);
508 assert(ChannelDetails_get_is_usable(&first_hops->data[0]));
509 const LDK::Router router_impl = DefaultRouter_as_Router(&*router);
510 return router_impl->find_route(router_impl->this_arg, payer, route_params, first_hops, in_flights);
514 uint8_t channel_open_header[80];
515 uint8_t header_1[80];
516 uint8_t header_2[80];
517 memcpy(channel_open_header, channel_open_block, 80);
518 memcpy(header_1, block_1, 80);
519 memcpy(header_2, block_2, 80);
521 LDKPublicKey null_pk;
522 memset(&null_pk, 0, sizeof(null_pk));
524 LDKThirtyTwoBytes random_bytes;
525 LDKThirtyTwoBytes chain_tip;
526 memset(&chain_tip, 0, sizeof(chain_tip)); // channel_open_header's prev_blockhash is all-0s
528 LDKNetwork network = LDKNetwork_Testnet;
530 // Trait implementations:
531 LDKBroadcasterInterface broadcast {
533 .broadcast_transactions = broadcast_txn,
537 // Instantiate classes for the nodes that don't get reloaded on a ser-des reload
539 .this_arg = (void*)1,
545 mons1.logger = &logger1;
548 .watch_channel = add_channel_monitor,
549 .update_channel = update_channel_monitor,
550 .release_pending_monitor_events = monitors_pending_monitor_events,
554 LDK::NetworkGraph net_graph1 = NetworkGraph_new(network, logger1);
555 LDK::P2PGossipSync graph_msg_handler1 = P2PGossipSync_new(&net_graph1, COption_UtxoLookupZ_none(), logger1);
558 .this_arg = (void*)2,
564 mons2.logger = &logger2;
567 .watch_channel = add_channel_monitor,
568 .update_channel = update_channel_monitor,
569 .release_pending_monitor_events = monitors_pending_monitor_events,
573 LDKRouter panic_router = {
575 .find_route = NULL, // Segfault if we ever try to find a route
576 .find_route_with_id = NULL, // Segfault if we ever try to find a route
580 LDK::NetworkGraph net_graph2 = NetworkGraph_new(network, logger2);
581 LDK::P2PGossipSync graph_msg_handler2 = P2PGossipSync_new(&net_graph2, COption_UtxoLookupZ_none(), logger2);
583 LDK::CVec_u8Z cm1_ser = LDKCVec_u8Z {}; // ChannelManager 1 serialization at the end of the ser-des scope
584 LDK::CVec_u8Z cm2_ser = LDKCVec_u8Z {}; // ChannelManager 2 serialization at the end of the ser-des scope
586 { // Scope for the ser-des reload
587 // Instantiate classes for node 1:
588 uint8_t node_seed[32];
589 memset(&node_seed, 0, 32);
590 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 0, 0);
591 LDK::NodeSigner node_signer1 = KeysManager_as_NodeSigner(&keys1);
592 LDK::EntropySource entropy_source1 = KeysManager_as_EntropySource(&keys1);
593 LDK::SignerProvider signer_provider1 = KeysManager_as_SignerProvider(&keys1);
595 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);
597 LDK::IgnoringMessageHandler ignoring_handler1 = IgnoringMessageHandler_new();
598 LDK::CustomMessageHandler custom_msg_handler1 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler1);
599 LDK::CustomOnionMessageHandler custom_onion_msg_handler1 = IgnoringMessageHandler_as_CustomOnionMessageHandler(&ignoring_handler1);
600 LDK::DefaultMessageRouter mr1 = DefaultMessageRouter_new();
601 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));
603 LDK::CVec_ChannelDetailsZ channels = ChannelManager_list_channels(&cm1);
604 assert(channels->datalen == 0);
606 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));
608 random_bytes = entropy_source1.get_secure_random_bytes();
609 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), 0xdeadbeef, &random_bytes.data, logger1, std::move(node_signer1));
611 // Demo getting a channel key and check that its returning real pubkeys:
612 LDKSixteenBytes user_id_1 { .data = {45, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0} };
613 LDKThirtyTwoBytes chan_signer_id1 = signer_provider1.generate_channel_keys_id(false, 42, U128_new(user_id_1));
614 LDK::WriteableEcdsaChannelSigner chan_signer1 = signer_provider1.derive_channel_signer(42, chan_signer_id1);
615 chan_signer1->EcdsaChannelSigner.ChannelSigner.set_pubkeys(&chan_signer1->EcdsaChannelSigner.ChannelSigner); // Make sure pubkeys is defined
616 LDKPublicKey payment_point = ChannelPublicKeys_get_payment_point(&chan_signer1->EcdsaChannelSigner.ChannelSigner.pubkeys);
617 assert(memcmp(&payment_point, &null_pk, sizeof(null_pk)));
619 // Instantiate classes for node 2:
620 memset(&node_seed, 1, 32);
621 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 0, 0);
622 LDK::NodeSigner node_signer2 = KeysManager_as_NodeSigner(&keys2);
623 LDK::EntropySource entropy_source2 = KeysManager_as_EntropySource(&keys2);
624 LDK::SignerProvider signer_provider2 = KeysManager_as_SignerProvider(&keys2);
626 LDK::ChannelHandshakeConfig handshake_config2 = ChannelHandshakeConfig_default();
627 ChannelHandshakeConfig_set_minimum_depth(&handshake_config2, 2);
628 LDK::UserConfig config2 = UserConfig_default();
629 UserConfig_set_channel_handshake_config(&config2, std::move(handshake_config2));
631 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);
633 LDK::IgnoringMessageHandler ignoring_handler2 = IgnoringMessageHandler_new();
634 LDK::CustomMessageHandler custom_msg_handler2 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler2);
635 LDK::CustomOnionMessageHandler custom_onion_msg_handler2 = IgnoringMessageHandler_as_CustomOnionMessageHandler(&ignoring_handler2);
636 LDK::DefaultMessageRouter mr2 = DefaultMessageRouter_new();
637 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));
639 LDK::CVec_ChannelDetailsZ channels2 = ChannelManager_list_channels(&cm2);
640 assert(channels2->datalen == 0);
642 LDK::RoutingMessageHandler net_msgs2 = P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler2);
643 LDK::CResult_ChannelAnnouncementDecodeErrorZ chan_ann = ChannelAnnouncement_read(LDKu8slice { .data = valid_node_announcement, .datalen = sizeof(valid_node_announcement) });
644 assert(chan_ann->result_ok);
645 LDK::CResult_boolLightningErrorZ ann_res = net_msgs2->handle_channel_announcement(net_msgs2->this_arg, chan_ann->contents.result);
646 assert(ann_res->result_ok);
648 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), std::move(net_msgs2), OnionMessenger_as_OnionMessageHandler(&om1), std::move(custom_msg_handler2));
650 random_bytes = entropy_source2.get_secure_random_bytes();
651 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), 0xdeadbeef, &random_bytes.data, logger2, std::move(node_signer2));
653 // Open a connection!
654 PeersConnection conn(cm1, cm2, net1, net2);
656 // Note that we have to bind the result to a C++ class to make sure it gets free'd
657 LDK::CResult__u832APIErrorZ res = ChannelManager_create_channel(&cm1, ChannelManager_get_our_node_id(&cm2), 40000, 1000, U128_new(user_id_1), UserConfig_default());
658 assert(res->result_ok);
659 PeerManager_process_events(&net1);
661 LDK::CVec_ChannelDetailsZ new_channels = ChannelManager_list_channels(&cm1);
662 assert(new_channels->datalen == 1);
663 LDK::ChannelCounterparty new_channels_counterparty = ChannelDetails_get_counterparty(&new_channels->data[0]);
664 LDKPublicKey chan_open_pk = ChannelCounterparty_get_node_id(&new_channels_counterparty);
665 assert(!memcmp(chan_open_pk.compressed_form, ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
667 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting first channel..." << std::endl;
669 LDK::CVec_ChannelDetailsZ new_channels_2 = ChannelManager_list_channels(&cm2);
670 if (new_channels_2->datalen == 1) {
671 // Sample getting our counterparty's init features (which used to be hard to do without a memory leak):
672 LDK::ChannelCounterparty new_channels_2_counterparty = ChannelDetails_get_counterparty(&new_channels_2->data[0]);
673 const LDK::InitFeatures init_feats = ChannelCounterparty_get_features(&new_channels_2_counterparty);
674 assert(init_feats->inner != NULL);
677 std::this_thread::yield();
679 std::cout << __FILE__ << ":" << __LINE__ << " - " << "First channel listed!" << std::endl;
681 LDK::EventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1);
682 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting FundingGenerationReady event..." << std::endl;
685 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
686 ev1.process_pending_events(handler);
687 if (queue.events.size() == 1) {
688 assert(queue.events[0]->tag == LDKEvent_FundingGenerationReady);
689 LDKSixteenBytes event_id = U128_le_bytes(queue.events[0]->funding_generation_ready.user_channel_id);
690 assert(!memcmp(&event_id, &user_id_1, 16));
691 assert(queue.events[0]->funding_generation_ready.channel_value_satoshis == 40000);
692 assert(queue.events[0]->funding_generation_ready.output_script.datalen == 34);
694 assert(!memcmp(queue.events[0]->funding_generation_ready.output_script.data, channel_open_block + 58 + 81, 34));
695 LDKTransaction funding_transaction { .data = const_cast<uint8_t*>(channel_open_block + 81), .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false };
697 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);
698 assert(fund_res->result_ok);
701 std::this_thread::yield();
703 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received FundingGenerationReady event!" << std::endl;
705 // We observe when the funding signed messages have been exchanged by
706 // waiting for two monitors to be registered.
707 assert(num_txs_broadcasted == 0);
708 PeerManager_process_events(&net1);
709 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting transaction broadcast..." << std::endl;
710 while (num_txs_broadcasted != 1) {
711 std::this_thread::yield();
713 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Transaction was broadcast!" << std::endl;
715 // Note that the channel ID is the same as the channel txid reversed as the output index is 0
716 uint8_t expected_chan_id[32];
717 for (int i = 0; i < 32; i++) { expected_chan_id[i] = channel_open_txid[31-i]; }
719 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting ChannelPending event..." << std::endl;
722 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
723 ev1.process_pending_events(handler);
724 if (queue.events.size() == 1) {
725 assert(queue.events[0]->tag == LDKEvent_ChannelPending);
726 assert(!memcmp(queue.events[0]->channel_pending.channel_id.data, expected_chan_id, 32));
729 std::this_thread::yield();
731 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received ChannelPending event!" << std::endl;
733 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
734 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting ChannelPending event..." << std::endl;
737 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
738 ev2.process_pending_events(handler);
739 if (queue.events.size() == 1) {
740 assert(queue.events[0]->tag == LDKEvent_ChannelPending);
741 assert(!memcmp(queue.events[0]->channel_pending.channel_id.data, expected_chan_id, 32));
744 std::this_thread::yield();
746 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received ChannelPending event!" << std::endl;
748 LDK::Listen listener1 = ChannelManager_as_Listen(&cm1);
749 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
751 LDK::Listen listener2 = ChannelManager_as_Listen(&cm2);
752 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
754 LDKCVec_C2Tuple_usizeTransactionZZ txdata { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
755 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
756 mons1.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
758 txdata = LDKCVec_C2Tuple_usizeTransactionZZ { .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 mons2.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
762 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
763 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
764 mons1.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
765 mons2.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
767 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
768 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
769 mons1.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
770 mons2.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
772 PeerManager_process_events(&net1);
773 PeerManager_process_events(&net2);
775 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting ChannelReady event..." << std::endl;
778 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
779 ev2.process_pending_events(handler);
780 if (queue.events.size() == 1) {
781 assert(queue.events[0]->tag == LDKEvent_ChannelReady);
782 assert(!memcmp(queue.events[0]->channel_ready.channel_id.data, expected_chan_id, 32));
785 std::this_thread::yield();
787 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received ChannelReady event!" << std::endl;
789 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting ChannelReady event..." << std::endl;
792 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
793 ev1.process_pending_events(handler);
794 if (queue.events.size() == 1) {
795 assert(queue.events[0]->tag == LDKEvent_ChannelReady);
796 assert(!memcmp(queue.events[0]->channel_ready.channel_id.data, expected_chan_id, 32));
799 std::this_thread::yield();
801 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received ChannelReady event!" << std::endl;
803 // Now send funds from 1 to 2!
804 uint64_t channel_scid;
805 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting usable channel..." << std::endl;
807 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
808 if (outbound_channels->datalen == 1) {
809 const LDKChannelDetails *channel = &outbound_channels->data[0];
810 LDK::ChannelCounterparty counterparty = ChannelDetails_get_counterparty(channel);
812 assert(!memcmp(ChannelDetails_get_channel_id(channel), expected_chan_id, 32));
814 ChannelCounterparty_get_node_id(&counterparty).compressed_form,
815 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
816 assert(ChannelDetails_get_channel_value_satoshis(channel) == 40000);
817 // We opened the channel with 1000 push_msat:
818 assert(ChannelDetails_get_outbound_capacity_msat(channel) ==
819 40000*1000 - 1000 - 1000 * ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty));
820 int64_t inbound_capacity = ((int64_t)1000) - ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty);
821 if (inbound_capacity < 0) inbound_capacity = 0;
822 assert(ChannelDetails_get_inbound_capacity_msat(channel) == (uint64_t)inbound_capacity);
823 assert(ChannelDetails_get_is_usable(channel));
824 LDK::COption_u64Z scid_opt = ChannelDetails_get_short_channel_id(channel);
825 assert(scid_opt->some);
826 channel_scid = scid_opt->some;
829 std::this_thread::yield();
831 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Listed usable channel!" << std::endl;
833 LDKCOption_u64Z min_value = {
834 .tag = LDKCOption_u64Z_Some,
837 LDK::CResult_Bolt11InvoiceSignOrCreationErrorZ invoice = create_invoice_from_channelmanager(&cm2,
838 KeysManager_as_NodeSigner(&keys2), logger2,
839 LDKCurrency_Bitcoin, min_value,
841 .chars = (const uint8_t *)"Invoice Description",
842 .len = strlen("Invoice Description"),
843 .chars_is_owned = false
844 }, 3600, COption_u16Z_none());
845 assert(invoice->result_ok);
846 LDKThirtyTwoBytes payment_hash;
847 memcpy(payment_hash.data, Bolt11Invoice_payment_hash(invoice->contents.result), 32);
850 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
851 LDK::Score chan_scorer = LDKScore {
852 .this_arg = NULL, .channel_penalty_msat = get_chan_score,
853 .payment_path_failed = NULL, .payment_path_successful = NULL, .probe_failed = NULL,
854 .probe_successful = NULL, .write = NULL, .free = NULL,
856 LDK::Payee payee = Payee_clear(ChannelManager_get_our_node_id(&cm2), Bolt11Invoice_route_hints(invoice->contents.result),
857 LDKBolt11InvoiceFeatures {
858 .inner = NULL, .is_owned = false
859 }, Bolt11Invoice_min_final_cltv_expiry_delta(invoice->contents.result));
860 LDK::RouteParameters route_params = RouteParameters_new(PaymentParameters_new(
861 std::move(payee), COption_u64Z_none(), 0xffffffff, 1, 2,
862 LDKCVec_u64Z { .data = NULL, .datalen = 0 }),
864 random_bytes = entropy_source1.get_secure_random_bytes();
865 LDK::ProbabilisticScoringFeeParameters params = ProbabilisticScoringFeeParameters_default();
867 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);
869 assert(route->result_ok);
870 LDK::CVec_PathZ paths = Route_get_paths(route->contents.result);
871 assert(paths->datalen == 1);
872 LDK::CVec_RouteHopZ hops = Path_get_hops(&paths->data[0]);
873 assert(hops->datalen == 1);
874 assert(!memcmp(RouteHop_get_pubkey(&hops->data[0]).compressed_form,
875 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
876 assert(RouteHop_get_short_channel_id(&hops->data[0]) == channel_scid);
877 LDKThirtyTwoBytes payment_secret;
878 memcpy(payment_secret.data, Bolt11Invoice_payment_secret(invoice->contents.result), 32);
879 LDK::CResult_NonePaymentSendFailureZ send_res = ChannelManager_send_payment_with_route(&cm1,
880 route->contents.result, payment_hash, RecipientOnionFields_secret_only(payment_secret), payment_hash);
881 assert(send_res->result_ok);
885 PeerManager_process_events(&net1);
886 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting 4 updated monitors..." << std::endl;
887 while (mons_updated != 4) {
888 std::this_thread::yield();
890 std::cout << __FILE__ << ":" << __LINE__ << " - " << "4 monitors updated!" << std::endl;
892 // Check that we received the payment!
893 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting PendingHTLCsForwardable event..." << std::endl;
896 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
897 ev2.process_pending_events(handler);
898 if (queue.events.size() == 1) {
899 assert(queue.events[0]->tag == LDKEvent_PendingHTLCsForwardable);
902 std::this_thread::yield();
904 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received PendingHTLCsForwardable event!" << std::endl;
905 ChannelManager_process_pending_htlc_forwards(&cm2);
906 PeerManager_process_events(&net2);
909 LDKThirtyTwoBytes payment_preimage;
912 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
913 ev2.process_pending_events(handler);
914 assert(queue.events.size() == 1);
915 assert(queue.events[0]->tag == LDKEvent_PaymentClaimable);
916 assert(!memcmp(queue.events[0]->payment_claimable.payment_hash.data, payment_hash.data, 32));
917 assert(queue.events[0]->payment_claimable.purpose.tag == LDKPaymentPurpose_InvoicePayment);
918 assert(!memcmp(queue.events[0]->payment_claimable.purpose.invoice_payment.payment_secret.data,
919 Bolt11Invoice_payment_secret(invoice->contents.result), 32));
920 assert(queue.events[0]->payment_claimable.amount_msat == 5000);
921 assert(queue.events[0]->payment_claimable.purpose.invoice_payment.payment_preimage.tag == LDKCOption_PaymentPreimageZ_Some);
922 memcpy(payment_preimage.data, queue.events[0]->payment_claimable.purpose.invoice_payment.payment_preimage.some.data, 32);
923 ChannelManager_claim_funds(&cm2, payment_preimage);
925 queue.events.clear();
926 ev2.process_pending_events(handler);
927 assert(queue.events.size() == 1);
928 assert(queue.events[0]->tag == LDKEvent_PaymentClaimed);
929 assert(!memcmp(queue.events[0]->payment_claimed.payment_hash.data, payment_hash.data, 32));
930 assert(queue.events[0]->payment_claimed.purpose.tag == LDKPaymentPurpose_InvoicePayment);
932 PeerManager_process_events(&net2);
933 // Wait until we've passed through a full set of monitor updates (ie new preimage + CS/RAA messages)
934 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting 5 updated monitors..." << std::endl;
935 while (mons_updated != 5) {
936 std::this_thread::yield();
938 std::cout << __FILE__ << ":" << __LINE__ << " - " << "5 monitors updated!" << std::endl;
941 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
942 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting PaymentSent and PaymentPathSuccessful events..." << std::endl;
943 while (queue.events.size() < 2) {
944 ev1.process_pending_events(handler);
945 std::this_thread::yield();
947 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received PaymentSent and PaymentPathSuccessful events (presumably)!" << std::endl;
948 assert(queue.events.size() == 2);
949 assert(queue.events[0]->tag == LDKEvent_PaymentSent);
950 assert(!memcmp(queue.events[0]->payment_sent.payment_preimage.data, payment_preimage.data, 32));
951 assert(queue.events[1]->tag == LDKEvent_PaymentPathSuccessful);
952 assert(queue.events[1]->payment_path_successful.payment_hash.tag == LDKCOption_PaymentHashZ_Some);
953 assert(!memcmp(queue.events[1]->payment_path_successful.payment_hash.some.data, payment_hash.data, 32));
958 cm1_ser = ChannelManager_write(&cm1);
959 cm2_ser = ChannelManager_write(&cm2);
962 LDK::CVec_ChannelMonitorZ mons_list1 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
963 assert(mons1.mons.size() == 1);
964 mons_list1->data[0] = *& std::get<1>(mons1.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
965 mons_list1->data[0].is_owned = false; // XXX: God this sucks
966 uint8_t node_seed[32];
967 memset(&node_seed, 0, 32);
968 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 1, 0);
969 LDK::NodeSigner node_signer1 = KeysManager_as_NodeSigner(&keys1);
970 LDK::EntropySource entropy_source1 = KeysManager_as_EntropySource(&keys1);
971 LDK::SignerProvider signer_provider1 = KeysManager_as_SignerProvider(&keys1);
973 LDK::ProbabilisticScorer scorer1 = ProbabilisticScorer_new(ProbabilisticScoringDecayParameters_default(), &net_graph1, logger1);
974 LDK::Score scorer_trait1 = ProbabilisticScorer_as_Score(&scorer1);
975 LDK::MultiThreadedLockableScore scorer_mtx1 = MultiThreadedLockableScore_new(std::move(scorer_trait1));
976 LDK::LockableScore scorer_mtx_trait1 = MultiThreadedLockableScore_as_LockableScore(&scorer_mtx1);
977 LDK::ProbabilisticScoringFeeParameters params = ProbabilisticScoringFeeParameters_default();
978 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));
979 LDKRouter router1 = {
980 .this_arg = (void*)&default_router_1,
981 .find_route = NULL, // LDK currently doesn't use this, its just a default-impl
982 .find_route_with_id = custom_find_route,
986 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));
987 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm1_read =
988 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm1_ser->data, .datalen = cm1_ser -> datalen}, std::move(cm1_args));
989 assert(cm1_read->result_ok);
990 LDK::ChannelManager cm1(std::move(cm1_read->contents.result->b));
992 LDKCustomOnionMessageHandler custom_onion_msg_handler1 = {
994 .handle_custom_message = NULL, // We only create custom messages, not handle them
995 .read_custom_message = NULL, // We only create custom messages, not handle them
998 LDK::DefaultMessageRouter mr1 = DefaultMessageRouter_new();
999 LDK::IgnoringMessageHandler ignorer_1 = IgnoringMessageHandler_new();
1000 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));
1002 LDK::CVec_ChannelMonitorZ mons_list2 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
1003 assert(mons2.mons.size() == 1);
1004 mons_list2->data[0] = *& std::get<1>(mons2.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
1005 mons_list2->data[0].is_owned = false; // XXX: God this sucks
1006 memset(&node_seed, 1, 32);
1007 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 1, 0);
1008 LDK::NodeSigner node_signer2 = KeysManager_as_NodeSigner(&keys2);
1009 LDK::EntropySource entropy_source2 = KeysManager_as_EntropySource(&keys2);
1010 LDK::SignerProvider signer_provider2 = KeysManager_as_SignerProvider(&keys2);
1012 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));
1013 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm2_read =
1014 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm2_ser->data, .datalen = cm2_ser -> datalen}, std::move(cm2_args));
1015 assert(cm2_read->result_ok);
1016 LDK::ChannelManager cm2(std::move(cm2_read->contents.result->b));
1018 CustomOnionMsgQueue peer_2_custom_onion_messages;
1019 LDKCustomOnionMessageHandler custom_onion_msg_handler2 = {
1020 .this_arg = &peer_2_custom_onion_messages,
1021 .handle_custom_message = handle_custom_onion_message,
1022 .read_custom_message = read_custom_onion_message,
1025 LDK::DefaultMessageRouter mr2 = DefaultMessageRouter_new();
1026 LDK::IgnoringMessageHandler ignorer_2 = IgnoringMessageHandler_new();
1027 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);
1029 // Attempt to close the channel...
1030 uint8_t chan_id[32];
1031 for (int i = 0; i < 32; i++) { chan_id[i] = channel_open_txid[31-i]; }
1032 LDK::CResult_NoneAPIErrorZ close_res = ChannelManager_close_channel(&cm1, &chan_id, ChannelManager_get_our_node_id(&cm2));
1033 assert(!close_res->result_ok); // Note that we can't close while disconnected!
1035 // Open a connection!
1036 LDKPublicKey chan_2_node_id = ChannelManager_get_our_node_id(&cm2);
1037 LDKCustomMessageHandler custom_msg_handler1 = {
1038 .this_arg = &chan_2_node_id,
1039 .handle_custom_message = NULL, // We only create custom messages, not handle them
1040 .get_and_clear_pending_msg = create_custom_msg,
1041 .provided_node_features = custom_node_features,
1042 .provided_init_features = custom_init_features,
1043 .CustomMessageReader = LDKCustomMessageReader {
1045 .read = read_custom_message,
1050 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler1), OnionMessenger_as_OnionMessageHandler(&om1), custom_msg_handler1);
1051 random_bytes = entropy_source1.get_secure_random_bytes();
1052 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), 0xdeadbeef, &random_bytes.data, logger1, std::move(node_signer1));
1054 CustomMsgQueue peer_2_custom_messages;
1055 LDKCustomMessageHandler custom_msg_handler2 = {
1056 .this_arg = &peer_2_custom_messages,
1057 .handle_custom_message = handle_custom_message,
1058 .get_and_clear_pending_msg = never_send_custom_msgs,
1059 .provided_node_features = custom_node_features,
1060 .provided_init_features = custom_init_features,
1061 .CustomMessageReader = LDKCustomMessageReader {
1063 .read = read_custom_message,
1068 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler2), OnionMessenger_as_OnionMessageHandler(&om2), custom_msg_handler2);
1069 random_bytes = entropy_source1.get_secure_random_bytes();
1070 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), 0xdeadbeef, &random_bytes.data, logger2, std::move(node_signer2));
1072 PeersConnection conn(cm1, cm2, net1, net2);
1074 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting usable channel..." << std::endl;
1076 // Wait for the channels to be considered up once the reestablish messages are processed
1077 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
1078 if (outbound_channels->datalen == 1) {
1081 std::this_thread::yield();
1083 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Listed usable channel!" << std::endl;
1085 // Send another payment, this time via the retires path
1086 LDK::CResult_Bolt11InvoiceSignOrCreationErrorZ invoice_res2 = create_invoice_from_channelmanager(&cm2,
1087 KeysManager_as_NodeSigner(&keys2), logger1,
1088 LDKCurrency_Bitcoin, COption_u64Z_some(10000),
1090 .chars = (const uint8_t *)"Invoice 2 Description",
1091 .len = strlen("Invoice 2 Description"),
1092 .chars_is_owned = false
1093 }, 3600, COption_u16Z_none());
1094 assert(invoice_res2->result_ok);
1095 const LDKBolt11Invoice *invoice2 = invoice_res2->contents.result;
1096 LDK::CResult_PaymentIdPaymentErrorZ invoice_pay_res = pay_invoice(invoice2, Retry_attempts(0), &cm1);
1097 assert(invoice_pay_res->result_ok);
1098 PeerManager_process_events(&net1);
1100 // Check that we received the payment!
1101 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting PendingHTLCsForwardable event..." << std::endl;
1104 LDKEventHandler handler2 = { .this_arg = &queue2, .handle_event = handle_event, .free = NULL };
1105 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
1106 ev2.process_pending_events(handler2);
1107 if (queue2.events.size() == 1) {
1108 assert(queue2.events[0]->tag == LDKEvent_PendingHTLCsForwardable);
1111 std::this_thread::yield();
1113 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received PendingHTLCsForwardable event!" << std::endl;
1114 ChannelManager_process_pending_htlc_forwards(&cm2);
1115 PeerManager_process_events(&net2);
1117 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting PaymentClaimable/PaymentClaimed event..." << std::endl;
1120 LDKEventHandler handler2 = { .this_arg = &queue2, .handle_event = handle_event, .free = NULL };
1121 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
1122 ev2.process_pending_events(handler2);
1123 if (queue2.events.size() == 1) {
1124 assert(queue2.events[0]->tag == LDKEvent_PaymentClaimable);
1125 const struct LDKEvent_LDKPaymentClaimable_Body *event_data = &queue2.events[0]->payment_claimable;
1126 assert(!memcmp(event_data->payment_hash.data, Bolt11Invoice_payment_hash(invoice2), 32));
1127 assert(event_data->purpose.tag == LDKPaymentPurpose_InvoicePayment);
1128 assert(!memcmp(event_data->purpose.invoice_payment.payment_secret.data,
1129 Bolt11Invoice_payment_secret(invoice2), 32));
1130 assert(event_data->amount_msat == 10000);
1131 assert(event_data->purpose.invoice_payment.payment_preimage.tag == LDKCOption_PaymentPreimageZ_Some);
1132 ChannelManager_claim_funds(&cm2, event_data->purpose.invoice_payment.payment_preimage.some);
1134 queue2.events.clear();
1135 ev2.process_pending_events(handler2);
1136 assert(queue2.events.size() == 1);
1137 assert(queue2.events[0]->tag == LDKEvent_PaymentClaimed);
1138 assert(!memcmp(queue2.events[0]->payment_claimed.payment_hash.data, Bolt11Invoice_payment_hash(invoice2), 32));
1139 assert(queue2.events[0]->payment_claimed.purpose.tag == LDKPaymentPurpose_InvoicePayment);
1143 std::this_thread::yield();
1145 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received PaymentClaimable/PaymentClaimed event!" << std::endl;
1148 LDKEventHandler handler1 = { .this_arg = &queue1, .handle_event = handle_event, .free = NULL };
1149 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting PaymentSent and PaymentPathSuccessful events..." << std::endl;
1150 while (queue1.events.size() < 2) {
1151 PeerManager_process_events(&net2);
1152 PeerManager_process_events(&net1);
1154 LDK::EventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1);
1155 ev1.process_pending_events(handler1);
1156 std::this_thread::yield();
1158 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received PaymentSent and PaymentPathSuccessful events (presumably)!" << std::endl;
1159 assert(queue1.events.size() == 2);
1160 assert(queue1.events[0]->tag == LDKEvent_PaymentSent);
1161 assert(queue1.events[1]->tag == LDKEvent_PaymentPathSuccessful);
1163 // Actually close the channel
1164 num_txs_broadcasted = 0;
1165 close_res = ChannelManager_close_channel(&cm1, &chan_id, ChannelManager_get_our_node_id(&cm2));
1166 assert(close_res->result_ok);
1167 PeerManager_process_events(&net1);
1168 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting 2 transaction broadcasts..." << std::endl;
1169 while (num_txs_broadcasted != 2) {
1170 std::this_thread::yield();
1172 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Broadcast 2 transactions!" << std::endl;
1173 LDK::CVec_ChannelDetailsZ chans_after_close1 = ChannelManager_list_channels(&cm1);
1174 assert(chans_after_close1->datalen == 0);
1175 LDK::CVec_ChannelDetailsZ chans_after_close2 = ChannelManager_list_channels(&cm2);
1176 assert(chans_after_close2->datalen == 0);
1178 assert(OnionMessenger_send_onion_message(&om1,
1179 OnionMessagePath_new(
1180 LDKCVec_PublicKeyZ { .data = NULL, .datalen = 0, },
1181 Destination_node(ChannelManager_get_our_node_id(&cm2))
1183 LDKOnionMessageContents {
1184 .tag = LDKOnionMessageContents_Custom,
1185 .custom = build_custom_onion_message()
1186 }, LDKBlindedPath { .inner = NULL, .is_owned = true })
1188 PeerManager_process_events(&net1);
1189 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting onion message..." << std::endl;
1191 std::this_thread::yield();
1192 std::unique_lock<std::mutex> lck(peer_2_custom_onion_messages.mtx);
1193 if (peer_2_custom_onion_messages.msgs.size() != 0) break;
1195 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received onion message!" << std::endl;
1199 std::unique_lock<std::mutex> lck(peer_2_custom_onion_messages.mtx);
1200 assert(peer_2_custom_onion_messages.msgs.size() == 1);
1201 assert(peer_2_custom_onion_messages.msgs[0].tlv_type() == 8888);
1202 assert(peer_2_custom_messages.msgs.size() != 0);
1204 // Few extra random tests:
1206 memset(&sk, 42, 32);
1207 LDKThirtyTwoBytes kdiv_params;
1208 memset(&kdiv_params, 43, 32);
1209 LDK::InMemorySigner signer = InMemorySigner_new(sk, sk, sk, sk, sk, random_bytes, 42, kdiv_params, kdiv_params);