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 LDKCResult_ChannelMonitorUpdateStatusNoneZ add_channel_monitor(const void *this_arg, LDKOutPoint funding_txo_arg, LDKChannelMonitor monitor_arg) {
141 // First bind the args to C++ objects so they auto-free
142 LDK::ChannelMonitor mon(std::move(monitor_arg));
143 LDK::OutPoint funding_txo(std::move(funding_txo_arg));
145 NodeMonitors* arg = (NodeMonitors*) this_arg;
146 std::unique_lock<std::mutex> l(arg->mut);
148 arg->mons.push_back(std::make_pair(std::move(funding_txo), std::move(mon)));
149 return CResult_ChannelMonitorUpdateStatusNoneZ_ok(ChannelMonitorUpdateStatus_completed());
151 static std::atomic_int mons_updated(0);
152 LDKChannelMonitorUpdateStatus update_channel_monitor(const void *this_arg, LDKOutPoint funding_txo_arg, const LDKChannelMonitorUpdate *update) {
153 // First bind the args to C++ objects so they auto-free
154 LDK::OutPoint funding_txo(std::move(funding_txo_arg));
156 NodeMonitors* arg = (NodeMonitors*) this_arg;
157 std::unique_lock<std::mutex> l(arg->mut);
159 bool updated = false;
160 for (auto& mon : arg->mons) {
161 if (OutPoint_get_index(&mon.first) == OutPoint_get_index(&funding_txo) &&
162 !memcmp(OutPoint_get_txid(&mon.first), OutPoint_get_txid(&funding_txo), 32)) {
164 LDKBroadcasterInterface broadcaster = {
165 .broadcast_transactions = broadcast_txn,
167 LDK::CResult_NoneNoneZ res = ChannelMonitor_update_monitor(&mon.second, update, &broadcaster, &fee_est, arg->logger);
168 assert(res->result_ok);
174 return ChannelMonitorUpdateStatus_completed();
176 LDKCVec_C3Tuple_OutPointCVec_MonitorEventZPublicKeyZZ monitors_pending_monitor_events(const void *this_arg) {
177 NodeMonitors* arg = (NodeMonitors*) this_arg;
178 std::unique_lock<std::mutex> l(arg->mut);
180 if (arg->mons.size() == 0) {
181 return LDKCVec_C3Tuple_OutPointCVec_MonitorEventZPublicKeyZZ {
186 // We only ever actually have one channel per node, plus concatenating two
187 // Rust Vecs to each other from C++ will require a bit of effort.
188 assert(arg->mons.size() == 1);
189 LDK::CVec_MonitorEventZ events = ChannelMonitor_get_and_clear_pending_monitor_events(&arg->mons[0].second);
190 LDK::C2Tuple_OutPointCVec_u8ZZ funding_info = ChannelMonitor_get_funding_txo(&arg->mons[0].second);
191 LDK::OutPoint outpoint = std::move(funding_info->a);
192 LDKPublicKey counterparty_node_id = ChannelMonitor_get_counterparty_node_id(&arg->mons[0].second);
193 LDK::C3Tuple_OutPointCVec_MonitorEventZPublicKeyZ tuple = C3Tuple_OutPointCVec_MonitorEventZPublicKeyZ_new(std::move(outpoint), std::move(events), std::move(counterparty_node_id));
194 auto vec = LDKCVec_C3Tuple_OutPointCVec_MonitorEventZPublicKeyZZ {
195 .data = (LDKC3Tuple_OutPointCVec_MonitorEventZPublicKeyZ*)malloc(sizeof(LDKC3Tuple_OutPointCVec_MonitorEventZPublicKeyZ)),
198 vec.data[0] = std::move(tuple);
204 std::vector<LDK::Event> events;
206 void handle_event(const void *this_arg, LDKEvent event) {
207 EventQueue* arg = (EventQueue*) this_arg;
208 arg->events.push_back(std::move(event));
212 class PeersConnection {
217 PeersConnection(LDK::ChannelManager& cm1, LDK::ChannelManager& cm2, LDK::PeerManager& net1, LDK::PeerManager& net2) {
218 node1_handler = init_socket_handling(&net1);
219 node2_handler = init_socket_handling(&net2);
221 struct sockaddr_in listen_addr;
222 listen_addr.sin_family = AF_INET;
223 listen_addr.sin_addr.s_addr = htonl((127 << 8*3) | 1);
224 listen_addr.sin_port = htons(10042);
225 assert(!socket_bind(node2_handler, (sockaddr*)&listen_addr, sizeof(listen_addr)));
227 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
229 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting initial handshake completion..." << std::endl;
231 // Wait for the initial handshakes to complete...
232 LDK::CVec_C2Tuple_PublicKeyCOption_SocketAddressZZZ peers_1 = PeerManager_get_peer_node_ids(&net1);
233 LDK::CVec_C2Tuple_PublicKeyCOption_SocketAddressZZZ peers_2 = PeerManager_get_peer_node_ids(&net2);
234 if (peers_1->datalen == 1 && peers_2->datalen == 1) { break; }
235 std::this_thread::yield();
237 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Initial handshake complete!" << std::endl;
239 // Connect twice, which should auto-disconnect, and is a good test of our disconnect pipeline
240 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
241 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
243 // Then disconnect the "main" connection, while another connection is being made.
244 PeerManager_disconnect_by_node_id(&net1, ChannelManager_get_our_node_id(&cm2));
245 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
247 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting new connection handshake..." << std::endl;
249 // Wait for the new connection handshake...
250 LDK::CVec_C2Tuple_PublicKeyCOption_SocketAddressZZZ peers_1 = PeerManager_get_peer_node_ids(&net1);
251 LDK::CVec_C2Tuple_PublicKeyCOption_SocketAddressZZZ peers_2 = PeerManager_get_peer_node_ids(&net2);
252 if (peers_1->datalen == 1 && peers_2->datalen == 1) { break; }
253 std::this_thread::yield();
255 std::cout << __FILE__ << ":" << __LINE__ << " - " << "New connection handshake complete!" << std::endl;
257 // Wait for all our sockets to disconnect (making sure we disconnect any new connections)...
258 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting peer disconnection..." << std::endl;
260 PeerManager_disconnect_by_node_id(&net1, ChannelManager_get_our_node_id(&cm2));
261 // Wait for the peers to disconnect...
262 LDK::CVec_C2Tuple_PublicKeyCOption_SocketAddressZZZ peers_1 = PeerManager_get_peer_node_ids(&net1);
263 LDK::CVec_C2Tuple_PublicKeyCOption_SocketAddressZZZ peers_2 = PeerManager_get_peer_node_ids(&net2);
264 if (peers_1->datalen == 0 && peers_2->datalen == 0) { break; }
265 std::this_thread::yield();
267 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Peers disconnected!" << std::endl;
268 // Note that the above is somewhat race-y, as node 2 may still think its connected.
269 // Thus, make sure any connections are disconnected on its end as well.
270 PeerManager_disconnect_by_node_id(&net2, ChannelManager_get_our_node_id(&cm1));
272 // Finally make an actual connection and keep it this time
273 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
275 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting initial handshake completion..." << std::endl;
277 // Wait for the initial handshakes to complete...
278 LDK::CVec_C2Tuple_PublicKeyCOption_SocketAddressZZZ peers_1 = PeerManager_get_peer_node_ids(&net1);
279 LDK::CVec_C2Tuple_PublicKeyCOption_SocketAddressZZZ peers_2 = PeerManager_get_peer_node_ids(&net2);
280 if (peers_1->datalen == 1 && peers_2->datalen == 1) { break; }
281 std::this_thread::yield();
283 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Initial handshake complete!" << std::endl;
286 interrupt_socket_handling(node1_handler);
287 interrupt_socket_handling(node2_handler);
293 uintptr_t sock_send_data(void *this_arg, LDKu8slice data, bool resume_read) {
294 return write((int)((long)this_arg), data.data, data.datalen);
296 void sock_disconnect_socket(void *this_arg) {
297 close((int)((long)this_arg));
299 bool sock_eq(const void *this_arg, const LDKSocketDescriptor *other_arg) {
300 return this_arg == other_arg->this_arg;
302 uint64_t sock_hash(const void *this_arg) {
303 return (uint64_t)this_arg;
305 void sock_read_data_thread(int rdfd, LDKSocketDescriptor *peer_descriptor, LDKPeerManager *pm) {
306 unsigned char buf[1024];
310 while ((readlen = read(rdfd, buf, 1024)) > 0) {
311 data.datalen = readlen;
312 LDK::CResult_boolPeerHandleErrorZ res = PeerManager_read_event(&*pm, peer_descriptor, data);
313 if (!res->result_ok) {
314 peer_descriptor->disconnect_socket(peer_descriptor->this_arg);
317 PeerManager_process_events(pm);
319 PeerManager_socket_disconnected(&*pm, peer_descriptor);
322 class PeersConnection {
323 int pipefds_1_to_2[2];
324 int pipefds_2_to_1[2];
326 LDKSocketDescriptor sock1, sock2;
329 PeersConnection(LDK::ChannelManager& cm1, LDK::ChannelManager& cm2, LDK::PeerManager& net1, LDK::PeerManager& net2) {
330 assert(!pipe(pipefds_1_to_2));
331 assert(!pipe(pipefds_2_to_1));
333 sock1 = LDKSocketDescriptor {
334 .this_arg = (void*)(long)pipefds_1_to_2[1],
335 .send_data = sock_send_data,
336 .disconnect_socket = sock_disconnect_socket,
343 sock2 = LDKSocketDescriptor {
344 .this_arg = (void*)(long)pipefds_2_to_1[1],
345 .send_data = sock_send_data,
346 .disconnect_socket = sock_disconnect_socket,
353 t1 = std::thread(&sock_read_data_thread, pipefds_2_to_1[0], &sock1, &net1);
354 t2 = std::thread(&sock_read_data_thread, pipefds_1_to_2[0], &sock2, &net2);
356 // Note that we have to bind the result to a C++ class to make sure it gets free'd
357 LDK::CResult_CVec_u8ZPeerHandleErrorZ con_res = PeerManager_new_outbound_connection(&net1, ChannelManager_get_our_node_id(&cm2), sock1, COption_SocketAddressZ_none());
358 assert(con_res->result_ok);
359 LDK::CResult_NonePeerHandleErrorZ con_res2 = PeerManager_new_inbound_connection(&net2, sock2, COption_SocketAddressZ_none());
360 assert(con_res2->result_ok);
362 auto writelen = write(pipefds_1_to_2[1], con_res->contents.result->data, con_res->contents.result->datalen);
363 assert(writelen > 0 && uint64_t(writelen) == con_res->contents.result->datalen);
365 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting initial handshake completion..." << std::endl;
367 // Wait for the initial handshakes to complete...
368 LDK::CVec_C2Tuple_PublicKeyCOption_SocketAddressZZZ peers_1 = PeerManager_get_peer_node_ids(&net1);
369 LDK::CVec_C2Tuple_PublicKeyCOption_SocketAddressZZZ peers_2 = PeerManager_get_peer_node_ids(&net2);
370 if (peers_1->datalen == 1 && peers_2->datalen ==1) { break; }
371 std::this_thread::yield();
373 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Initial handshake complete!" << std::endl;
377 close(pipefds_1_to_2[0]);
378 close(pipefds_2_to_1[0]);
379 close(pipefds_1_to_2[1]);
380 close(pipefds_2_to_1[1]);
387 struct CustomOnionMsgQueue {
389 std::vector<LDK::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_ThirtyTwoBytesAPIErrorZ 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::ScoreLookUp chan_scorer = LDKScoreLookUp {
852 .this_arg = NULL, .channel_penalty_msat = get_chan_score, .free = NULL,
854 LDK::Payee payee = Payee_clear(ChannelManager_get_our_node_id(&cm2), Bolt11Invoice_route_hints(invoice->contents.result),
855 LDKBolt11InvoiceFeatures {
856 .inner = NULL, .is_owned = false
857 }, Bolt11Invoice_min_final_cltv_expiry_delta(invoice->contents.result));
858 LDK::RouteParameters route_params = RouteParameters_from_payment_params_and_value(
859 PaymentParameters_new(std::move(payee), COption_u64Z_none(), 0xffffffff, 1, 2,
860 LDKCVec_u64Z { .data = NULL, .datalen = 0 }),
862 random_bytes = entropy_source1.get_secure_random_bytes();
863 LDK::ProbabilisticScoringFeeParameters params = ProbabilisticScoringFeeParameters_default();
865 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);
867 assert(route->result_ok);
868 LDK::CVec_PathZ paths = Route_get_paths(route->contents.result);
869 assert(paths->datalen == 1);
870 LDK::CVec_RouteHopZ hops = Path_get_hops(&paths->data[0]);
871 assert(hops->datalen == 1);
872 assert(!memcmp(RouteHop_get_pubkey(&hops->data[0]).compressed_form,
873 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
874 assert(RouteHop_get_short_channel_id(&hops->data[0]) == channel_scid);
875 LDKThirtyTwoBytes payment_secret;
876 memcpy(payment_secret.data, Bolt11Invoice_payment_secret(invoice->contents.result), 32);
877 LDK::CResult_NonePaymentSendFailureZ send_res = ChannelManager_send_payment_with_route(&cm1,
878 route->contents.result, payment_hash, RecipientOnionFields_secret_only(payment_secret), payment_hash);
879 assert(send_res->result_ok);
883 PeerManager_process_events(&net1);
884 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting 4 updated monitors..." << std::endl;
885 while (mons_updated != 4) {
886 std::this_thread::yield();
888 std::cout << __FILE__ << ":" << __LINE__ << " - " << "4 monitors updated!" << std::endl;
890 // Check that we received the payment!
891 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting PendingHTLCsForwardable event..." << std::endl;
894 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
895 ev2.process_pending_events(handler);
896 if (queue.events.size() == 1) {
897 assert(queue.events[0]->tag == LDKEvent_PendingHTLCsForwardable);
900 std::this_thread::yield();
902 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received PendingHTLCsForwardable event!" << std::endl;
903 ChannelManager_process_pending_htlc_forwards(&cm2);
904 PeerManager_process_events(&net2);
907 LDKThirtyTwoBytes payment_preimage;
910 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
911 ev2.process_pending_events(handler);
912 assert(queue.events.size() == 1);
913 assert(queue.events[0]->tag == LDKEvent_PaymentClaimable);
914 assert(!memcmp(queue.events[0]->payment_claimable.payment_hash.data, payment_hash.data, 32));
915 assert(queue.events[0]->payment_claimable.purpose.tag == LDKPaymentPurpose_InvoicePayment);
916 assert(!memcmp(queue.events[0]->payment_claimable.purpose.invoice_payment.payment_secret.data,
917 Bolt11Invoice_payment_secret(invoice->contents.result), 32));
918 assert(queue.events[0]->payment_claimable.amount_msat == 5000);
919 assert(queue.events[0]->payment_claimable.purpose.invoice_payment.payment_preimage.tag == LDKCOption_ThirtyTwoBytesZ_Some);
920 memcpy(payment_preimage.data, queue.events[0]->payment_claimable.purpose.invoice_payment.payment_preimage.some.data, 32);
921 ChannelManager_claim_funds(&cm2, payment_preimage);
923 queue.events.clear();
924 ev2.process_pending_events(handler);
925 assert(queue.events.size() == 1);
926 assert(queue.events[0]->tag == LDKEvent_PaymentClaimed);
927 assert(!memcmp(queue.events[0]->payment_claimed.payment_hash.data, payment_hash.data, 32));
928 assert(queue.events[0]->payment_claimed.purpose.tag == LDKPaymentPurpose_InvoicePayment);
930 PeerManager_process_events(&net2);
931 // Wait until we've passed through a full set of monitor updates (ie new preimage + CS/RAA messages)
934 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
935 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting PaymentSent and PaymentPathSuccessful events..." << std::endl;
936 while (queue.events.size() < 2) {
937 ev1.process_pending_events(handler);
938 std::this_thread::yield();
940 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received PaymentSent and PaymentPathSuccessful events (presumably)!" << std::endl;
941 assert(queue.events.size() == 2);
942 assert(queue.events[0]->tag == LDKEvent_PaymentSent);
943 assert(!memcmp(queue.events[0]->payment_sent.payment_preimage.data, payment_preimage.data, 32));
944 assert(queue.events[1]->tag == LDKEvent_PaymentPathSuccessful);
945 assert(queue.events[1]->payment_path_successful.payment_hash.tag == LDKCOption_ThirtyTwoBytesZ_Some);
946 assert(!memcmp(queue.events[1]->payment_path_successful.payment_hash.some.data, payment_hash.data, 32));
948 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting 5 updated monitors..." << std::endl;
949 while (mons_updated != 5) {
950 std::this_thread::yield();
952 std::cout << __FILE__ << ":" << __LINE__ << " - " << "5 monitors updated!" << std::endl;
956 cm1_ser = ChannelManager_write(&cm1);
957 cm2_ser = ChannelManager_write(&cm2);
960 LDK::CVec_ChannelMonitorZ mons_list1 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
961 assert(mons1.mons.size() == 1);
962 mons_list1->data[0] = *& std::get<1>(mons1.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
963 mons_list1->data[0].is_owned = false; // XXX: God this sucks
964 uint8_t node_seed[32];
965 memset(&node_seed, 0, 32);
966 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 1, 0);
967 LDK::NodeSigner node_signer1 = KeysManager_as_NodeSigner(&keys1);
968 LDK::EntropySource entropy_source1 = KeysManager_as_EntropySource(&keys1);
969 LDK::SignerProvider signer_provider1 = KeysManager_as_SignerProvider(&keys1);
971 LDK::ProbabilisticScorer scorer1 = ProbabilisticScorer_new(ProbabilisticScoringDecayParameters_default(), &net_graph1, logger1);
972 LDK::Score scorer_trait1 = ProbabilisticScorer_as_Score(&scorer1);
973 LDK::MultiThreadedLockableScore scorer_mtx1 = MultiThreadedLockableScore_new(std::move(scorer_trait1));
974 LDK::LockableScore scorer_mtx_trait1 = MultiThreadedLockableScore_as_LockableScore(&scorer_mtx1);
975 LDK::ProbabilisticScoringFeeParameters params = ProbabilisticScoringFeeParameters_default();
976 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));
977 LDKRouter router1 = {
978 .this_arg = (void*)&default_router_1,
979 .find_route = NULL, // LDK currently doesn't use this, its just a default-impl
980 .find_route_with_id = custom_find_route,
984 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));
985 LDK::CResult_C2Tuple_ThirtyTwoBytesChannelManagerZDecodeErrorZ cm1_read =
986 C2Tuple_ThirtyTwoBytesChannelManagerZ_read(LDKu8slice { .data = cm1_ser->data, .datalen = cm1_ser -> datalen}, std::move(cm1_args));
987 assert(cm1_read->result_ok);
988 LDK::ChannelManager cm1(std::move(cm1_read->contents.result->b));
990 LDKCustomOnionMessageHandler custom_onion_msg_handler1 = {
992 .handle_custom_message = NULL, // We only create custom messages, not handle them
993 .read_custom_message = NULL, // We only create custom messages, not handle them
996 LDK::DefaultMessageRouter mr1 = DefaultMessageRouter_new();
997 LDK::IgnoringMessageHandler ignorer_1 = IgnoringMessageHandler_new();
998 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));
1000 LDK::CVec_ChannelMonitorZ mons_list2 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
1001 assert(mons2.mons.size() == 1);
1002 mons_list2->data[0] = *& std::get<1>(mons2.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
1003 mons_list2->data[0].is_owned = false; // XXX: God this sucks
1004 memset(&node_seed, 1, 32);
1005 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 1, 0);
1006 LDK::NodeSigner node_signer2 = KeysManager_as_NodeSigner(&keys2);
1007 LDK::EntropySource entropy_source2 = KeysManager_as_EntropySource(&keys2);
1008 LDK::SignerProvider signer_provider2 = KeysManager_as_SignerProvider(&keys2);
1010 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));
1011 LDK::CResult_C2Tuple_ThirtyTwoBytesChannelManagerZDecodeErrorZ cm2_read =
1012 C2Tuple_ThirtyTwoBytesChannelManagerZ_read(LDKu8slice { .data = cm2_ser->data, .datalen = cm2_ser -> datalen}, std::move(cm2_args));
1013 assert(cm2_read->result_ok);
1014 LDK::ChannelManager cm2(std::move(cm2_read->contents.result->b));
1016 CustomOnionMsgQueue peer_2_custom_onion_messages;
1017 LDKCustomOnionMessageHandler custom_onion_msg_handler2 = {
1018 .this_arg = &peer_2_custom_onion_messages,
1019 .handle_custom_message = handle_custom_onion_message,
1020 .read_custom_message = read_custom_onion_message,
1023 LDK::DefaultMessageRouter mr2 = DefaultMessageRouter_new();
1024 LDK::IgnoringMessageHandler ignorer_2 = IgnoringMessageHandler_new();
1025 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);
1027 // Attempt to close the channel...
1028 uint8_t chan_id[32];
1029 for (int i = 0; i < 32; i++) { chan_id[i] = channel_open_txid[31-i]; }
1030 LDK::CResult_NoneAPIErrorZ close_res = ChannelManager_close_channel(&cm1, &chan_id, ChannelManager_get_our_node_id(&cm2));
1031 assert(!close_res->result_ok); // Note that we can't close while disconnected!
1033 // Open a connection!
1034 LDKPublicKey chan_2_node_id = ChannelManager_get_our_node_id(&cm2);
1035 LDKCustomMessageHandler custom_msg_handler1 = {
1036 .this_arg = &chan_2_node_id,
1037 .handle_custom_message = NULL, // We only create custom messages, not handle them
1038 .get_and_clear_pending_msg = create_custom_msg,
1039 .provided_node_features = custom_node_features,
1040 .provided_init_features = custom_init_features,
1041 .CustomMessageReader = LDKCustomMessageReader {
1043 .read = read_custom_message,
1048 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler1), OnionMessenger_as_OnionMessageHandler(&om1), custom_msg_handler1);
1049 random_bytes = entropy_source1.get_secure_random_bytes();
1050 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), 0xdeadbeef, &random_bytes.data, logger1, std::move(node_signer1));
1052 CustomMsgQueue peer_2_custom_messages;
1053 LDKCustomMessageHandler custom_msg_handler2 = {
1054 .this_arg = &peer_2_custom_messages,
1055 .handle_custom_message = handle_custom_message,
1056 .get_and_clear_pending_msg = never_send_custom_msgs,
1057 .provided_node_features = custom_node_features,
1058 .provided_init_features = custom_init_features,
1059 .CustomMessageReader = LDKCustomMessageReader {
1061 .read = read_custom_message,
1066 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler2), OnionMessenger_as_OnionMessageHandler(&om2), custom_msg_handler2);
1067 random_bytes = entropy_source1.get_secure_random_bytes();
1068 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), 0xdeadbeef, &random_bytes.data, logger2, std::move(node_signer2));
1070 PeersConnection conn(cm1, cm2, net1, net2);
1072 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting usable channel..." << std::endl;
1074 // Wait for the channels to be considered up once the reestablish messages are processed
1075 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
1076 if (outbound_channels->datalen == 1) {
1079 std::this_thread::yield();
1081 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Listed usable channel!" << std::endl;
1083 // Send another payment, this time via the retires path
1084 LDK::CResult_Bolt11InvoiceSignOrCreationErrorZ invoice_res2 = create_invoice_from_channelmanager(&cm2,
1085 KeysManager_as_NodeSigner(&keys2), logger1,
1086 LDKCurrency_Bitcoin, COption_u64Z_some(10000),
1088 .chars = (const uint8_t *)"Invoice 2 Description",
1089 .len = strlen("Invoice 2 Description"),
1090 .chars_is_owned = false
1091 }, 3600, COption_u16Z_none());
1092 assert(invoice_res2->result_ok);
1093 const LDKBolt11Invoice *invoice2 = invoice_res2->contents.result;
1094 LDK::CResult_ThirtyTwoBytesPaymentErrorZ invoice_pay_res = pay_invoice(invoice2, Retry_attempts(0), &cm1);
1095 assert(invoice_pay_res->result_ok);
1096 PeerManager_process_events(&net1);
1098 // Check that we received the payment!
1099 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting PendingHTLCsForwardable event..." << std::endl;
1102 LDKEventHandler handler2 = { .this_arg = &queue2, .handle_event = handle_event, .free = NULL };
1103 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
1104 ev2.process_pending_events(handler2);
1105 if (queue2.events.size() == 1) {
1106 assert(queue2.events[0]->tag == LDKEvent_PendingHTLCsForwardable);
1109 std::this_thread::yield();
1111 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received PendingHTLCsForwardable event!" << std::endl;
1112 ChannelManager_process_pending_htlc_forwards(&cm2);
1113 PeerManager_process_events(&net2);
1115 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting PaymentClaimable/PaymentClaimed event..." << std::endl;
1118 LDKEventHandler handler2 = { .this_arg = &queue2, .handle_event = handle_event, .free = NULL };
1119 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
1120 ev2.process_pending_events(handler2);
1121 if (queue2.events.size() == 1) {
1122 assert(queue2.events[0]->tag == LDKEvent_PaymentClaimable);
1123 const struct LDKEvent_LDKPaymentClaimable_Body *event_data = &queue2.events[0]->payment_claimable;
1124 assert(!memcmp(event_data->payment_hash.data, Bolt11Invoice_payment_hash(invoice2), 32));
1125 assert(event_data->purpose.tag == LDKPaymentPurpose_InvoicePayment);
1126 assert(!memcmp(event_data->purpose.invoice_payment.payment_secret.data,
1127 Bolt11Invoice_payment_secret(invoice2), 32));
1128 assert(event_data->amount_msat == 10000);
1129 assert(event_data->purpose.invoice_payment.payment_preimage.tag == LDKCOption_ThirtyTwoBytesZ_Some);
1130 ChannelManager_claim_funds(&cm2, event_data->purpose.invoice_payment.payment_preimage.some);
1132 queue2.events.clear();
1133 ev2.process_pending_events(handler2);
1134 assert(queue2.events.size() == 1);
1135 assert(queue2.events[0]->tag == LDKEvent_PaymentClaimed);
1136 assert(!memcmp(queue2.events[0]->payment_claimed.payment_hash.data, Bolt11Invoice_payment_hash(invoice2), 32));
1137 assert(queue2.events[0]->payment_claimed.purpose.tag == LDKPaymentPurpose_InvoicePayment);
1141 std::this_thread::yield();
1143 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received PaymentClaimable/PaymentClaimed event!" << std::endl;
1146 LDKEventHandler handler1 = { .this_arg = &queue1, .handle_event = handle_event, .free = NULL };
1147 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting PaymentSent and PaymentPathSuccessful events..." << std::endl;
1148 while (queue1.events.size() < 2) {
1149 PeerManager_process_events(&net2);
1150 PeerManager_process_events(&net1);
1152 LDK::EventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1);
1153 ev1.process_pending_events(handler1);
1154 std::this_thread::yield();
1156 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received PaymentSent and PaymentPathSuccessful events (presumably)!" << std::endl;
1157 assert(queue1.events.size() == 2);
1158 assert(queue1.events[0]->tag == LDKEvent_PaymentSent);
1159 assert(queue1.events[1]->tag == LDKEvent_PaymentPathSuccessful);
1161 // Actually close the channel
1162 num_txs_broadcasted = 0;
1163 close_res = ChannelManager_close_channel(&cm1, &chan_id, ChannelManager_get_our_node_id(&cm2));
1164 assert(close_res->result_ok);
1165 PeerManager_process_events(&net1);
1166 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting 2 transaction broadcasts..." << std::endl;
1167 while (num_txs_broadcasted != 2) {
1168 std::this_thread::yield();
1170 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Broadcast 2 transactions!" << std::endl;
1171 LDK::CVec_ChannelDetailsZ chans_after_close1 = ChannelManager_list_channels(&cm1);
1172 assert(chans_after_close1->datalen == 0);
1173 LDK::CVec_ChannelDetailsZ chans_after_close2 = ChannelManager_list_channels(&cm2);
1174 assert(chans_after_close2->datalen == 0);
1176 assert(OnionMessenger_send_onion_message(&om1,
1177 OnionMessagePath_new(
1178 LDKCVec_PublicKeyZ { .data = NULL, .datalen = 0, },
1179 Destination_node(ChannelManager_get_our_node_id(&cm2))
1181 LDKOnionMessageContents {
1182 .tag = LDKOnionMessageContents_Custom,
1183 .custom = build_custom_onion_message()
1184 }, LDKBlindedPath { .inner = NULL, .is_owned = true })
1186 PeerManager_process_events(&net1);
1187 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Awaiting onion message..." << std::endl;
1189 std::this_thread::yield();
1190 std::unique_lock<std::mutex> lck(peer_2_custom_onion_messages.mtx);
1191 if (peer_2_custom_onion_messages.msgs.size() != 0) break;
1193 std::cout << __FILE__ << ":" << __LINE__ << " - " << "Received onion message!" << std::endl;
1197 std::unique_lock<std::mutex> lck(peer_2_custom_onion_messages.mtx);
1198 assert(peer_2_custom_onion_messages.msgs.size() == 1);
1199 assert(peer_2_custom_onion_messages.msgs[0].tlv_type() == 8888);
1200 assert(peer_2_custom_messages.msgs.size() != 0);
1202 // Few extra random tests:
1204 memset(&sk, 42, 32);
1205 LDKThirtyTwoBytes kdiv_params;
1206 memset(&kdiv_params, 43, 32);
1207 LDK::InMemorySigner signer = InMemorySigner_new(sk, sk, sk, sk, sk, random_bytes, 42, kdiv_params, kdiv_params);