X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning-c-bindings%2Fdemo.cpp;h=fd716b6d46a5ba413bc11d5a79a269322e5d2642;hb=6a576b303a7b0de3fa2e009a23c1ffbf54dc679e;hp=1d29ed60293b96ca7789edc3e20b5f1e96320c9f;hpb=d15b7a463b2402bf6193599755fd7418da5d90d4;p=ldk-c-bindings diff --git a/lightning-c-bindings/demo.cpp b/lightning-c-bindings/demo.cpp index 1d29ed6..fd716b6 100644 --- a/lightning-c-bindings/demo.cpp +++ b/lightning-c-bindings/demo.cpp @@ -139,7 +139,7 @@ struct NodeMonitors { } }; -LDKCResult_NoneChannelMonitorUpdateErrZ add_channel_monitor(const void *this_arg, LDKOutPoint funding_txo_arg, LDKChannelMonitor monitor_arg) { +LDKChannelMonitorUpdateStatus add_channel_monitor(const void *this_arg, LDKOutPoint funding_txo_arg, LDKChannelMonitor monitor_arg) { // First bind the args to C++ objects so they auto-free LDK::ChannelMonitor mon(std::move(monitor_arg)); LDK::OutPoint funding_txo(std::move(funding_txo_arg)); @@ -148,10 +148,10 @@ LDKCResult_NoneChannelMonitorUpdateErrZ add_channel_monitor(const void *this_arg std::unique_lock l(arg->mut); arg->mons.push_back(std::make_pair(std::move(funding_txo), std::move(mon))); - return CResult_NoneChannelMonitorUpdateErrZ_ok(); + return ChannelMonitorUpdateStatus_completed(); } static std::atomic_int mons_updated(0); -LDKCResult_NoneChannelMonitorUpdateErrZ update_channel_monitor(const void *this_arg, LDKOutPoint funding_txo_arg, LDKChannelMonitorUpdate monitor_arg) { +LDKChannelMonitorUpdateStatus update_channel_monitor(const void *this_arg, LDKOutPoint funding_txo_arg, LDKChannelMonitorUpdate monitor_arg) { // First bind the args to C++ objects so they auto-free LDK::ChannelMonitorUpdate update(std::move(monitor_arg)); LDK::OutPoint funding_txo(std::move(funding_txo_arg)); @@ -167,21 +167,21 @@ LDKCResult_NoneChannelMonitorUpdateErrZ update_channel_monitor(const void *this_ LDKBroadcasterInterface broadcaster = { .broadcast_transaction = broadcast_tx, }; - LDK::CResult_NoneNoneZ res = ChannelMonitor_update_monitor(&mon.second, &update, &broadcaster, &fee_est, arg->logger); + LDK::CResult_NoneNoneZ res = ChannelMonitor_update_monitor(&mon.second, &update, &broadcaster, fee_est, arg->logger); assert(res->result_ok); } } assert(updated); mons_updated += 1; - return CResult_NoneChannelMonitorUpdateErrZ_ok(); + return ChannelMonitorUpdateStatus_completed(); } -LDKCVec_C2Tuple_OutPointCVec_MonitorEventZZZ monitors_pending_monitor_events(const void *this_arg) { +LDKCVec_C3Tuple_OutPointCVec_MonitorEventZPublicKeyZZ monitors_pending_monitor_events(const void *this_arg) { NodeMonitors* arg = (NodeMonitors*) this_arg; std::unique_lock l(arg->mut); if (arg->mons.size() == 0) { - return LDKCVec_C2Tuple_OutPointCVec_MonitorEventZZZ { + return LDKCVec_C3Tuple_OutPointCVec_MonitorEventZPublicKeyZZ { .data = NULL, .datalen = 0, }; @@ -192,12 +192,13 @@ LDKCVec_C2Tuple_OutPointCVec_MonitorEventZZZ monitors_pending_monitor_events(con LDK::CVec_MonitorEventZ events = ChannelMonitor_get_and_clear_pending_monitor_events(&arg->mons[0].second); LDK::C2Tuple_OutPointScriptZ funding_info = ChannelMonitor_get_funding_txo(&arg->mons[0].second); LDK::OutPoint outpoint = std::move(funding_info->a); - LDK::C2Tuple_OutPointCVec_MonitorEventZZ pair = C2Tuple_OutPointCVec_MonitorEventZZ_new(std::move(outpoint), std::move(events)); - auto vec = LDKCVec_C2Tuple_OutPointCVec_MonitorEventZZZ { - .data = (LDKC2Tuple_OutPointCVec_MonitorEventZZ*)malloc(sizeof(LDKC2Tuple_OutPointCVec_MonitorEventZZ)), + LDKPublicKey counterparty_node_id = ChannelMonitor_get_counterparty_node_id(&arg->mons[0].second); + LDK::C3Tuple_OutPointCVec_MonitorEventZPublicKeyZ tuple = C3Tuple_OutPointCVec_MonitorEventZPublicKeyZ_new(std::move(outpoint), std::move(events), std::move(counterparty_node_id)); + auto vec = LDKCVec_C3Tuple_OutPointCVec_MonitorEventZPublicKeyZZ { + .data = (LDKC3Tuple_OutPointCVec_MonitorEventZPublicKeyZ*)malloc(sizeof(LDKC3Tuple_OutPointCVec_MonitorEventZPublicKeyZ)), .datalen = 1, }; - vec.data[0] = std::move(pair); + vec.data[0] = std::move(tuple); return vec; } } @@ -368,6 +369,47 @@ public: }; #endif // !REAL_NET +struct CustomOnionMsgQueue { + std::mutex mtx; + std::vector msgs; +}; + +uint64_t custom_onion_msg_type_id(const void *this_arg) { + return 8888; +} +LDKCVec_u8Z custom_onion_msg_bytes(const void *this_arg) { + uint8_t *bytes = (uint8_t *) malloc(1024); + memset(bytes, 43, 1024); + return LDKCVec_u8Z { + .data = bytes, .datalen = 1024 + }; +} + +void handle_custom_onion_message(const void* this_arg, struct LDKCustomOnionMessageContents msg) { + CustomOnionMsgQueue* arg = (CustomOnionMsgQueue*) this_arg; + std::unique_lock lck(arg->mtx); + arg->msgs.push_back(std::move(msg)); +} + +LDKCustomOnionMessageContents build_custom_onion_message() { + return LDKCustomOnionMessageContents { + .this_arg = NULL, + .tlv_type = custom_onion_msg_type_id, + .write = custom_onion_msg_bytes, + .free = NULL, + }; +} + +LDKCResult_COption_CustomOnionMessageContentsZDecodeErrorZ read_custom_onion_message(const void* this_arg, uint64_t type, LDKu8slice buf) { + assert(type == 8888); + assert(buf.datalen == 1024); + uint8_t cmp[1024]; + memset(cmp, 43, 1024); + assert(!memcmp(cmp, buf.data, 1024)); + return CResult_COption_CustomOnionMessageContentsZDecodeErrorZ_ok(COption_CustomOnionMessageContentsZ_some(build_custom_onion_message())); +} + + struct CustomMsgQueue { std::vector msgs; }; @@ -435,17 +477,23 @@ uint64_t get_chan_score(const void *this_arg, uint64_t scid, const LDKNodeId *sr return 42; } -struct CustomRouteFinderParams { - LDKLogger *logger; - LDKNetworkGraph *graph_ref; - LDKThirtyTwoBytes random_seed_bytes; -}; -struct LDKCResult_RouteLightningErrorZ custom_find_route(const void *this_arg, struct LDKPublicKey payer, const struct LDKRouteParameters *NONNULL_PTR route_params, const uint8_t (*payment_hash)[32], struct LDKCVec_ChannelDetailsZ *first_hops, const struct LDKScore *NONNULL_PTR scorer) { - const struct CustomRouteFinderParams *params = (struct CustomRouteFinderParams *)this_arg; +struct LDKCResult_RouteLightningErrorZ custom_find_route(const void *this_arg, struct LDKPublicKey payer, const struct LDKRouteParameters *NONNULL_PTR route_params, const uint8_t (*payment_hash)[32], struct LDKCVec_ChannelDetailsZ *first_hops, const struct LDKInFlightHtlcs in_flights) { + const LDK::DefaultRouter *router = (LDK::DefaultRouter *)this_arg; assert(first_hops->datalen == 1); assert(ChannelDetails_get_is_usable(&first_hops->data[0])); - LDK::ReadOnlyNetworkGraph graph_lock = NetworkGraph_read_only(params->graph_ref); - return find_route(payer, route_params, &graph_lock, first_hops, *params->logger, scorer, ¶ms->random_seed_bytes.data); + const LDK::Router router_impl = DefaultRouter_as_Router(&*router); + return router_impl->find_route(router_impl->this_arg, payer, route_params, payment_hash, first_hops, in_flights); +} + +void custom_notify_payment_path_failed(const void *this_arg, struct LDKCVec_RouteHopZ path, uint64_t short_channel_id) { + const LDK::DefaultRouter *router = (LDK::DefaultRouter *)this_arg; + const LDK::Router router_impl = DefaultRouter_as_Router(&*router); + return router_impl->notify_payment_path_failed(router_impl->this_arg, path, short_channel_id); +} +void custom_notify_payment_path_successful(const void *this_arg, struct LDKCVec_RouteHopZ path) { + const LDK::DefaultRouter *router = (LDK::DefaultRouter *)this_arg; + const LDK::Router router_impl = DefaultRouter_as_Router(&*router); + return router_impl->notify_payment_path_successful(router_impl->this_arg, path); } int main() { @@ -528,16 +576,19 @@ int main() { LDK::ChannelManager cm1 = ChannelManager_new(fee_est, mon1, broadcast, logger1, KeysManager_as_KeysInterface(&keys1), UserConfig_default(), ChainParameters_new(network, BestBlock_new(chain_tip, 0))); + LDK::IgnoringMessageHandler ignoring_handler1 = IgnoringMessageHandler_new(); + LDK::CustomMessageHandler custom_msg_handler1 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler1); + LDK::CustomOnionMessageHandler custom_onion_msg_handler1 = IgnoringMessageHandler_as_CustomOnionMessageHandler(&ignoring_handler1); + + LDK::OnionMessenger om1 = OnionMessenger_new(KeysManager_as_KeysInterface(&keys1), logger1, std::move(custom_onion_msg_handler1)); + LDK::CVec_ChannelDetailsZ channels = ChannelManager_list_channels(&cm1); assert(channels->datalen == 0); - LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler1)); - - LDK::IgnoringMessageHandler ignoring_handler1 = IgnoringMessageHandler_new(); - LDK::CustomMessageHandler custom_msg_handler1 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler1); + LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler1), OnionMessenger_as_OnionMessageHandler(&om1)); random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg); - LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, &random_bytes.data, logger1, std::move(custom_msg_handler1)); + LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, 0xdeadbeef, &random_bytes.data, logger1, std::move(custom_msg_handler1)); // Demo getting a channel key and check that its returning real pubkeys: LDK::Sign chan_signer1 = keys_source1->get_channel_signer(keys_source1->this_arg, false, 42); @@ -556,10 +607,16 @@ int main() { LDK::ChannelHandshakeConfig handshake_config2 = ChannelHandshakeConfig_default(); ChannelHandshakeConfig_set_minimum_depth(&handshake_config2, 2); LDK::UserConfig config2 = UserConfig_default(); - UserConfig_set_own_channel_config(&config2, std::move(handshake_config2)); + UserConfig_set_channel_handshake_config(&config2, std::move(handshake_config2)); LDK::ChannelManager cm2 = ChannelManager_new(fee_est, mon2, broadcast, logger2, KeysManager_as_KeysInterface(&keys2), std::move(config2), ChainParameters_new(network, BestBlock_new(chain_tip, 0))); + LDK::IgnoringMessageHandler ignoring_handler2 = IgnoringMessageHandler_new(); + LDK::CustomMessageHandler custom_msg_handler2 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler2); + LDK::CustomOnionMessageHandler custom_onion_msg_handler2 = IgnoringMessageHandler_as_CustomOnionMessageHandler(&ignoring_handler2); + + LDK::OnionMessenger om2 = OnionMessenger_new(KeysManager_as_KeysInterface(&keys2), logger2, std::move(custom_onion_msg_handler2)); + LDK::CVec_ChannelDetailsZ channels2 = ChannelManager_list_channels(&cm2); assert(channels2->datalen == 0); @@ -569,13 +626,10 @@ int main() { LDK::CResult_boolLightningErrorZ ann_res = net_msgs2->handle_channel_announcement(net_msgs2->this_arg, chan_ann->contents.result); assert(ann_res->result_ok); - LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), std::move(net_msgs2)); - - LDK::IgnoringMessageHandler ignoring_handler2 = IgnoringMessageHandler_new(); - LDK::CustomMessageHandler custom_msg_handler2 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler2); + LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), std::move(net_msgs2), OnionMessenger_as_OnionMessageHandler(&om1)); random_bytes = keys_source2->get_secure_random_bytes(keys_source2->this_arg); - LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, &random_bytes.data, logger2, std::move(custom_msg_handler2)); + LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, 0xdeadbeef, &random_bytes.data, logger2, std::move(custom_msg_handler2)); // Open a connection! PeersConnection conn(cm1, cm2, net1, net2); @@ -693,7 +747,7 @@ int main() { .some = 5000, }; LDK::CResult_InvoiceSignOrCreationErrorZ invoice = create_invoice_from_channelmanager(&cm2, - KeysManager_as_KeysInterface(&keys2), + KeysManager_as_KeysInterface(&keys2), logger2, LDKCurrency_Bitcoin, min_value, LDKStr { .chars = (const uint8_t *)"Invoice Description", @@ -712,12 +766,12 @@ int main() { LDK::RouteParameters route_params = RouteParameters_new(PaymentParameters_new( ChannelManager_get_our_node_id(&cm2), LDKInvoiceFeatures { .inner = NULL, .is_owned = false - }, Invoice_route_hints(invoice->contents.result), COption_u64Z_none(), 0xffffffff), + }, Invoice_route_hints(invoice->contents.result), COption_u64Z_none(), 0xffffffff, + 1, 2, LDKCVec_u64Z { .data = NULL, .datalen = 0 }), 5000, Invoice_min_final_cltv_expiry(invoice->contents.result)); random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg); - LDK::ReadOnlyNetworkGraph graph_lock = NetworkGraph_read_only(&net_graph2); - LDK::CResult_RouteLightningErrorZ route = find_route(ChannelManager_get_our_node_id(&cm1), &route_params, &graph_lock, &outbound_channels, logger1, &chan_scorer, &random_bytes.data); + LDK::CResult_RouteLightningErrorZ route = find_route(ChannelManager_get_our_node_id(&cm1), &route_params, &net_graph2, &outbound_channels, logger1, &chan_scorer, &random_bytes.data); assert(route->result_ok); LDK::CVec_CVec_RouteHopZZ paths = Route_get_paths(route->contents.result); @@ -814,6 +868,14 @@ int main() { assert(cm1_read->result_ok); LDK::ChannelManager cm1(std::move(cm1_read->contents.result->b)); + LDKCustomOnionMessageHandler custom_onion_msg_handler1 = { + .this_arg = NULL, + .handle_custom_message = NULL, // We only create custom messages, not handle them + .read_custom_message = NULL, // We only create custom messages, not handle them + .free = NULL, + }; + LDK::OnionMessenger om1 = OnionMessenger_new(KeysManager_as_KeysInterface(&keys1), logger1, custom_onion_msg_handler1); + LDK::CVec_ChannelMonitorZ mons_list2 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 }; assert(mons2.mons.size() == 1); mons_list2->data[0] = *& std::get<1>(mons2.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does. @@ -827,6 +889,15 @@ int main() { assert(cm2_read->result_ok); LDK::ChannelManager cm2(std::move(cm2_read->contents.result->b)); + CustomOnionMsgQueue peer_2_custom_onion_messages; + LDKCustomOnionMessageHandler custom_onion_msg_handler2 = { + .this_arg = &peer_2_custom_onion_messages, + .handle_custom_message = handle_custom_onion_message, + .read_custom_message = read_custom_onion_message, + .free = NULL, + }; + LDK::OnionMessenger om2 = OnionMessenger_new(KeysManager_as_KeysInterface(&keys2), logger2, custom_onion_msg_handler2); + // Attempt to close the channel... uint8_t chan_id[32]; for (int i = 0; i < 32; i++) { chan_id[i] = channel_open_txid[31-i]; } @@ -834,7 +905,7 @@ int main() { assert(!close_res->result_ok); // Note that we can't close while disconnected! // Open a connection! - LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler1)); + LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler1), OnionMessenger_as_OnionMessageHandler(&om1)); random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg); LDKPublicKey chan_2_node_id = ChannelManager_get_our_node_id(&cm2); @@ -849,9 +920,9 @@ int main() { }, .free = NULL, }; - LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, &random_bytes.data, logger1, std::move(custom_msg_handler1)); + LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, 0xdeadbeef, &random_bytes.data, logger1, std::move(custom_msg_handler1)); - LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler2)); + LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler2), OnionMessenger_as_OnionMessageHandler(&om2)); CustomMsgQueue peer_2_custom_messages; LDKCustomMessageHandler custom_msg_handler2 = { .this_arg = &peer_2_custom_messages, @@ -865,7 +936,7 @@ int main() { .free = NULL, }; random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg); - LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, &random_bytes.data, logger2, std::move(custom_msg_handler2)); + LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, 0xdeadbeef, &random_bytes.data, logger2, std::move(custom_msg_handler2)); PeersConnection conn(cm1, cm2, net1, net2); @@ -878,24 +949,27 @@ int main() { } // Send another payment, this time via the InvoicePayer - struct CustomRouteFinderParams router_params = { - .logger = &logger1, - .graph_ref = &net_graph1, - .random_seed_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg), - }; + LDK::ProbabilisticScorer scorer = ProbabilisticScorer_new(ProbabilisticScoringParameters_default(), &net_graph1, logger1); + LDK::Score scorer_trait = ProbabilisticScorer_as_Score(&scorer); + LDK::MultiThreadedLockableScore scorer_mtx = MultiThreadedLockableScore_new(std::move(scorer_trait)); + LDK::LockableScore scorer_mtx_trait = MultiThreadedLockableScore_as_LockableScore(&scorer_mtx); + const LDK::DefaultRouter router = DefaultRouter_new(&net_graph1, logger1, keys_source1->get_secure_random_bytes(keys_source1->this_arg), std::move(scorer_mtx_trait)); LDKRouter sending_router = { - .this_arg = &router_params, + .this_arg = (void*)&router, .find_route = custom_find_route, + .notify_payment_path_failed = custom_notify_payment_path_failed, + .notify_payment_path_successful = custom_notify_payment_path_successful, + // We don't probe, so we opt to crash if the probe functions are called. + .notify_payment_probe_successful = NULL, + .notify_payment_probe_failed = NULL, .free = NULL, }; - LDK::ProbabilisticScorer scorer = ProbabilisticScorer_new(ProbabilisticScoringParameters_default(), &net_graph1, logger1); - LDK::MultiThreadedLockableScore scorer_mtx = MultiThreadedLockableScore_new(ProbabilisticScorer_as_Score(&scorer)); EventQueue queue1; LDKEventHandler handler1 = { .this_arg = &queue1, .handle_event = handle_event, .free = NULL }; - LDK::InvoicePayer payer = InvoicePayer_new(ChannelManager_as_Payer(&cm1), sending_router, &scorer_mtx, logger1, handler1, Retry_attempts(0)); + LDK::InvoicePayer payer = InvoicePayer_new(ChannelManager_as_Payer(&cm1), sending_router, logger1, handler1, Retry_attempts(0)); LDK::CResult_InvoiceSignOrCreationErrorZ invoice_res2 = create_invoice_from_channelmanager(&cm2, - KeysManager_as_KeysInterface(&keys2), + KeysManager_as_KeysInterface(&keys2), logger1, LDKCurrency_Bitcoin, COption_u64Z_some(10000), LDKStr { .chars = (const uint8_t *)"Invoice 2 Description", @@ -975,8 +1049,23 @@ int main() { LDK::CVec_ChannelDetailsZ chans_after_close2 = ChannelManager_list_channels(&cm2); assert(chans_after_close2->datalen == 0); + assert(OnionMessenger_send_custom_onion_message(&om1, + LDKCVec_PublicKeyZ { .data = NULL, .datalen = 0, }, + Destination_node(ChannelManager_get_our_node_id(&cm2)), + build_custom_onion_message(), LDKBlindedRoute { .inner = NULL, .is_owned = true }) + .result_ok); + PeerManager_process_events(&net1); + while (true) { + std::this_thread::yield(); + std::unique_lock lck(peer_2_custom_onion_messages.mtx); + if (peer_2_custom_onion_messages.msgs.size() != 0) break; + } + conn.stop(); + std::unique_lock lck(peer_2_custom_onion_messages.mtx); + assert(peer_2_custom_onion_messages.msgs.size() == 1); + assert(peer_2_custom_onion_messages.msgs[0].tlv_type() == 8888); assert(peer_2_custom_messages.msgs.size() != 0); // Few extra random tests: