+ LDKCVec_C2Tuple_usizeTransactionZZ txdata { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
+ *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_tx, .datalen = sizeof(channel_open_tx), .data_is_owned = false });
+ ChannelManager_block_connected(&cm1, &channel_open_header, txdata, 1);
+
+ txdata = LDKCVec_C2Tuple_usizeTransactionZZ { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
+ *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_tx, .datalen = sizeof(channel_open_tx), .data_is_owned = false });
+ ChannelManager_block_connected(&cm2, &channel_open_header, txdata, 1);
+
+ txdata = LDKCVec_C2Tuple_usizeTransactionZZ { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
+ *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_tx, .datalen = sizeof(channel_open_tx), .data_is_owned = false });
+ mons1.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
+
+ txdata = LDKCVec_C2Tuple_usizeTransactionZZ { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
+ *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_tx, .datalen = sizeof(channel_open_tx), .data_is_owned = false });
+ mons2.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
+
+ ChannelManager_block_connected(&cm1, &header_1, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, 2);
+ ChannelManager_block_connected(&cm2, &header_1, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, 2);
+ mons1.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
+ mons2.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
+
+ ChannelManager_block_connected(&cm1, &header_2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, 3);
+ ChannelManager_block_connected(&cm2, &header_2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, 3);
+ mons1.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
+ mons2.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
+
+ PeerManager_process_events(&net1);
+ PeerManager_process_events(&net2);
+
+ // Now send funds from 1 to 2!
+ while (true) {
+ LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
+ if (outbound_channels->datalen == 1) {
+ const LDKChannelDetails *channel = &outbound_channels->data[0];
+ // Note that the channel ID is the same as the channel txid reversed as the output index is 0
+ uint8_t expected_chan_id[32];
+ for (int i = 0; i < 32; i++) { expected_chan_id[i] = channel_open_txid[31-i]; }
+ assert(!memcmp(ChannelDetails_get_channel_id(channel), expected_chan_id, 32));
+ assert(!memcmp(ChannelDetails_get_remote_network_id(channel).compressed_form,
+ ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
+ assert(ChannelDetails_get_channel_value_satoshis(channel) == 40000);
+ // We opened the channel with 1000 push_msat:
+ assert(ChannelDetails_get_outbound_capacity_msat(channel) == 40000*1000 - 1000);
+ assert(ChannelDetails_get_inbound_capacity_msat(channel) == 1000);
+ assert(ChannelDetails_get_is_live(channel));
+ break;
+ }
+ std::this_thread::yield();
+ }