From: Matt Corallo Date: Tue, 13 Oct 2020 23:47:13 +0000 (-0400) Subject: explode to constructor args when we cant clone but need to X-Git-Tag: v0.0.1~104 X-Git-Url: http://git.bitcoin.ninja/?a=commitdiff_plain;h=bdfeab0608a87839cb0ac5301652b6497cbbd17a;p=ldk-java explode to constructor args when we cant clone but need to --- diff --git a/genbindings.py b/genbindings.py index 73ef5f92..a0d0ab62 100755 --- a/genbindings.py +++ b/genbindings.py @@ -46,176 +46,185 @@ class ConvInfo: else: out_java.write(" arg") out_c.write(" arg") + +def camel_to_snake(s): + # Convert camel case to snake case, in a way that appears to match cbindgen + con = "_" + ret = "" + lastchar = "" + lastund = False + for char in s: + if lastchar.isupper(): + if not char.isupper() and not lastund: + ret = ret + "_" + lastund = True + else: + lastund = False + ret = ret + lastchar.lower() + else: + ret = ret + lastchar + if char.isupper() and not lastund: + ret = ret + "_" + lastund = True + else: + lastund = False + lastchar = char + if char.isnumeric(): + lastund = True + return (ret + lastchar.lower()).strip("_") + +unitary_enums = set() +var_is_arr_regex = re.compile("\(\*([A-za-z0-9_]*)\)\[([a-z0-9]*)\]") +var_ty_regex = re.compile("([A-za-z_0-9]*)(.*)") +def java_c_types(fn_arg, ret_arr_len): + fn_arg = fn_arg.strip() + if fn_arg.startswith("MUST_USE_RES "): + fn_arg = fn_arg[13:] + is_const = False + if fn_arg.startswith("const "): + fn_arg = fn_arg[6:] + is_const = True + + is_ptr = False + take_by_ptr = False + rust_obj = None + arr_access = None + if fn_arg.startswith("LDKThirtyTwoBytes"): + fn_arg = "uint8_t (*" + fn_arg[18:] + ")[32]" + assert var_is_arr_regex.match(fn_arg[8:]) + rust_obj = "LDKThirtyTwoBytes" + arr_access = "data" + if fn_arg.startswith("LDKPublicKey"): + fn_arg = "uint8_t (*" + fn_arg[13:] + ")[33]" + assert var_is_arr_regex.match(fn_arg[8:]) + rust_obj = "LDKPublicKey" + arr_access = "compressed_form" + if fn_arg.startswith("LDKSecretKey"): + fn_arg = "uint8_t (*" + fn_arg[13:] + ")[32]" + assert var_is_arr_regex.match(fn_arg[8:]) + rust_obj = "LDKSecretKey" + arr_access = "bytes" + if fn_arg.startswith("LDKSignature"): + fn_arg = "uint8_t (*" + fn_arg[13:] + ")[64]" + assert var_is_arr_regex.match(fn_arg[8:]) + rust_obj = "LDKSignature" + arr_access = "compact_form" + if fn_arg.startswith("LDKThreeBytes"): + fn_arg = "uint8_t (*" + fn_arg[14:] + ")[3]" + assert var_is_arr_regex.match(fn_arg[8:]) + rust_obj = "LDKThreeBytes" + arr_access = "data" + if fn_arg.startswith("LDKu8slice"): + fn_arg = "uint8_t (*" + fn_arg[11:] + ")[datalen]" + assert var_is_arr_regex.match(fn_arg[8:]) + rust_obj = "LDKu8slice" + arr_access = "data" + + if fn_arg.startswith("void"): + java_ty = "void" + c_ty = "void" + fn_ty_arg = "V" + fn_arg = fn_arg[4:].strip() + elif fn_arg.startswith("bool"): + java_ty = "boolean" + c_ty = "jboolean" + fn_ty_arg = "Z" + fn_arg = fn_arg[4:].strip() + elif fn_arg.startswith("uint8_t"): + java_ty = "byte" + c_ty = "jbyte" + fn_ty_arg = "B" + fn_arg = fn_arg[7:].strip() + elif fn_arg.startswith("uint16_t"): + java_ty = "short" + c_ty = "jshort" + fn_ty_arg = "S" + fn_arg = fn_arg[8:].strip() + elif fn_arg.startswith("uint32_t"): + java_ty = "int" + c_ty = "jint" + fn_ty_arg = "I" + fn_arg = fn_arg[8:].strip() + elif fn_arg.startswith("uint64_t") or fn_arg.startswith("uintptr_t"): + java_ty = "long" + c_ty = "jlong" + fn_ty_arg = "J" + if fn_arg.startswith("uint64_t"): + fn_arg = fn_arg[8:].strip() + else: + fn_arg = fn_arg[9:].strip() + elif is_const and fn_arg.startswith("char *"): + java_ty = "String" + c_ty = "const char*" + fn_ty_arg = "Ljava/lang/String;" + fn_arg = fn_arg[6:].strip() + else: + ma = var_ty_regex.match(fn_arg) + if ma.group(1).strip() in unitary_enums: + java_ty = ma.group(1).strip() + c_ty = "jclass" + fn_ty_arg = "Lorg/ldk/enums/" + ma.group(1).strip() + ";" + fn_arg = ma.group(2).strip() + rust_obj = ma.group(1).strip() + take_by_ptr = True + else: + java_ty = "long" + c_ty = "jlong" + fn_ty_arg = "J" + fn_arg = ma.group(2).strip() + rust_obj = ma.group(1).strip() + take_by_ptr = True + + if fn_arg.startswith(" *") or fn_arg.startswith("*"): + fn_arg = fn_arg.replace("*", "").strip() + is_ptr = True + c_ty = "jlong" + java_ty = "long" + fn_ty_arg = "J" + + var_is_arr = var_is_arr_regex.match(fn_arg) + if var_is_arr is not None or ret_arr_len is not None: + assert(not take_by_ptr) + assert(not is_ptr) + java_ty = java_ty + "[]" + c_ty = c_ty + "Array" + if var_is_arr is not None: + if var_is_arr.group(1) == "": + return TypeInfo(rust_obj=rust_obj, java_ty=java_ty, java_fn_ty_arg="[" + fn_ty_arg, c_ty=c_ty, + passed_as_ptr=False, is_ptr=False, var_name="arg", arr_len=var_is_arr.group(2), arr_access=arr_access) + return TypeInfo(rust_obj=rust_obj, java_ty=java_ty, java_fn_ty_arg="[" + fn_ty_arg, c_ty=c_ty, + passed_as_ptr=False, is_ptr=False, var_name=var_is_arr.group(1), arr_len=var_is_arr.group(2), arr_access=arr_access) + return TypeInfo(rust_obj=rust_obj, java_ty=java_ty, java_fn_ty_arg=fn_ty_arg, c_ty=c_ty, passed_as_ptr=is_ptr or take_by_ptr, + is_ptr=is_ptr, var_name=fn_arg, arr_len=None, arr_access=None) + + + fn_ptr_regex = re.compile("^extern const ([A-Za-z_0-9\* ]*) \(\*(.*)\)\((.*)\);$") fn_ret_arr_regex = re.compile("(.*) \(\*(.*)\((.*)\)\)\[([0-9]*)\];$") reg_fn_regex = re.compile("([A-Za-z_0-9\* ]* \*?)([a-zA-Z_0-9]*)\((.*)\);$") clone_fns = set() +constructor_fns = {} with open(sys.argv[1]) as in_h: for line in in_h: reg_fn = reg_fn_regex.match(line) if reg_fn is not None: if reg_fn.group(2).endswith("_clone"): clone_fns.add(reg_fn.group(2)) + else: + rty = java_c_types(reg_fn.group(1), None) + if rty.rust_obj is not None and reg_fn.group(2) == rty.rust_obj.replace("LDK", "") + "_new": + constructor_fns[rty.rust_obj] = reg_fn.group(3) continue arr_fn = fn_ret_arr_regex.match(line) if arr_fn is not None: if arr_fn.group(2).endswith("_clone"): clone_fns.add(arr_fn.group(2)) + # No object constructors return arrays, as then they wouldn't be an object constructor continue with open(sys.argv[1]) as in_h, open(sys.argv[2], "w") as out_java, open(sys.argv[4], "w") as out_c: opaque_structs = set() trait_structs = set() - unitary_enums = set() - - def camel_to_snake(s): - # Convert camel case to snake case, in a way that appears to match cbindgen - con = "_" - ret = "" - lastchar = "" - lastund = False - for char in s: - if lastchar.isupper(): - if not char.isupper() and not lastund: - ret = ret + "_" - lastund = True - else: - lastund = False - ret = ret + lastchar.lower() - else: - ret = ret + lastchar - if char.isupper() and not lastund: - ret = ret + "_" - lastund = True - else: - lastund = False - lastchar = char - if char.isnumeric(): - lastund = True - return (ret + lastchar.lower()).strip("_") - - var_is_arr_regex = re.compile("\(\*([A-za-z0-9_]*)\)\[([a-z0-9]*)\]") - var_ty_regex = re.compile("([A-za-z_0-9]*)(.*)") - def java_c_types(fn_arg, ret_arr_len): - fn_arg = fn_arg.strip() - if fn_arg.startswith("MUST_USE_RES "): - fn_arg = fn_arg[13:] - is_const = False - if fn_arg.startswith("const "): - fn_arg = fn_arg[6:] - is_const = True - - is_ptr = False - take_by_ptr = False - rust_obj = None - arr_access = None - if fn_arg.startswith("LDKThirtyTwoBytes"): - fn_arg = "uint8_t (*" + fn_arg[18:] + ")[32]" - assert var_is_arr_regex.match(fn_arg[8:]) - rust_obj = "LDKThirtyTwoBytes" - arr_access = "data" - if fn_arg.startswith("LDKPublicKey"): - fn_arg = "uint8_t (*" + fn_arg[13:] + ")[33]" - assert var_is_arr_regex.match(fn_arg[8:]) - rust_obj = "LDKPublicKey" - arr_access = "compressed_form" - if fn_arg.startswith("LDKSecretKey"): - fn_arg = "uint8_t (*" + fn_arg[13:] + ")[32]" - assert var_is_arr_regex.match(fn_arg[8:]) - rust_obj = "LDKSecretKey" - arr_access = "bytes" - if fn_arg.startswith("LDKSignature"): - fn_arg = "uint8_t (*" + fn_arg[13:] + ")[64]" - assert var_is_arr_regex.match(fn_arg[8:]) - rust_obj = "LDKSignature" - arr_access = "compact_form" - if fn_arg.startswith("LDKThreeBytes"): - fn_arg = "uint8_t (*" + fn_arg[14:] + ")[3]" - assert var_is_arr_regex.match(fn_arg[8:]) - rust_obj = "LDKThreeBytes" - arr_access = "data" - if fn_arg.startswith("LDKu8slice"): - fn_arg = "uint8_t (*" + fn_arg[11:] + ")[datalen]" - assert var_is_arr_regex.match(fn_arg[8:]) - rust_obj = "LDKu8slice" - arr_access = "data" - - if fn_arg.startswith("void"): - java_ty = "void" - c_ty = "void" - fn_ty_arg = "V" - fn_arg = fn_arg[4:].strip() - elif fn_arg.startswith("bool"): - java_ty = "boolean" - c_ty = "jboolean" - fn_ty_arg = "Z" - fn_arg = fn_arg[4:].strip() - elif fn_arg.startswith("uint8_t"): - java_ty = "byte" - c_ty = "jbyte" - fn_ty_arg = "B" - fn_arg = fn_arg[7:].strip() - elif fn_arg.startswith("uint16_t"): - java_ty = "short" - c_ty = "jshort" - fn_ty_arg = "S" - fn_arg = fn_arg[8:].strip() - elif fn_arg.startswith("uint32_t"): - java_ty = "int" - c_ty = "jint" - fn_ty_arg = "I" - fn_arg = fn_arg[8:].strip() - elif fn_arg.startswith("uint64_t") or fn_arg.startswith("uintptr_t"): - java_ty = "long" - c_ty = "jlong" - fn_ty_arg = "J" - if fn_arg.startswith("uint64_t"): - fn_arg = fn_arg[8:].strip() - else: - fn_arg = fn_arg[9:].strip() - elif is_const and fn_arg.startswith("char *"): - java_ty = "String" - c_ty = "const char*" - fn_ty_arg = "Ljava/lang/String;" - fn_arg = fn_arg[6:].strip() - else: - ma = var_ty_regex.match(fn_arg) - if ma.group(1).strip() in unitary_enums: - java_ty = ma.group(1).strip() - c_ty = "jclass" - fn_ty_arg = "Lorg/ldk/enums/" + ma.group(1).strip() + ";" - fn_arg = ma.group(2).strip() - rust_obj = ma.group(1).strip() - take_by_ptr = True - else: - java_ty = "long" - c_ty = "jlong" - fn_ty_arg = "J" - fn_arg = ma.group(2).strip() - rust_obj = ma.group(1).strip() - take_by_ptr = True - - if fn_arg.startswith(" *") or fn_arg.startswith("*"): - fn_arg = fn_arg.replace("*", "").strip() - is_ptr = True - c_ty = "jlong" - java_ty = "long" - fn_ty_arg = "J" - - var_is_arr = var_is_arr_regex.match(fn_arg) - if var_is_arr is not None or ret_arr_len is not None: - assert(not take_by_ptr) - assert(not is_ptr) - java_ty = java_ty + "[]" - c_ty = c_ty + "Array" - if var_is_arr is not None: - if var_is_arr.group(1) == "": - return TypeInfo(rust_obj=rust_obj, java_ty=java_ty, java_fn_ty_arg="[" + fn_ty_arg, c_ty=c_ty, - passed_as_ptr=False, is_ptr=False, var_name="arg", arr_len=var_is_arr.group(2), arr_access=arr_access) - return TypeInfo(rust_obj=rust_obj, java_ty=java_ty, java_fn_ty_arg="[" + fn_ty_arg, c_ty=c_ty, - passed_as_ptr=False, is_ptr=False, var_name=var_is_arr.group(1), arr_len=var_is_arr.group(2), arr_access=arr_access) - return TypeInfo(rust_obj=rust_obj, java_ty=java_ty, java_fn_ty_arg=fn_ty_arg, c_ty=c_ty, passed_as_ptr=is_ptr or take_by_ptr, - is_ptr=is_ptr, var_name=fn_arg, arr_len=None, arr_access=None) def map_type(fn_arg, print_void, ret_arr_len, is_free): ty_info = java_c_types(fn_arg, ret_arr_len) @@ -392,6 +401,7 @@ with open(sys.argv[1]) as in_h, open(sys.argv[2], "w") as out_java, open(sys.arg out_c.write(" JNICALL Java_org_ldk_impl_bindings_" + re_match.group(2).replace('_', '_1') + "(JNIEnv * _env, jclass _b") arg_names = [] + default_constructor_args = {} takes_self = False args_known = not ret_info.passed_as_ptr or ret_info.rust_obj in opaque_structs or ret_info.rust_obj in trait_structs for idx, arg in enumerate(re_match.group(3).split(',')): @@ -407,10 +417,24 @@ with open(sys.argv[1]) as in_h, open(sys.argv[2], "w") as out_java, open(sys.arg takes_self = True if arg_conv_info.passed_as_ptr and not arg_conv_info.rust_obj in opaque_structs: if not arg_conv_info.rust_obj in trait_structs and not arg_conv_info.rust_obj in unitary_enums: - print(re_match.group(2) + " bad - " + arg_conv_info.rust_obj) args_known = False if arg_conv_info.arg_conv is not None and "Warning" in arg_conv_info.arg_conv: - args_known = False + if arg_conv_info.rust_obj in constructor_fns: + assert not is_free + for explode_arg in constructor_fns[arg_conv_info.rust_obj].split(','): + explode_arg_conv = map_type(explode_arg, False, None, False) + if explode_arg_conv.c_ty == "void": + # We actually want to handle this case, but for now its only used in NetGraphMsgHandler::new() + # which ends up resulting in a redundant constructor - both without arguments for the NetworkGraph. + args_known = False + assert explode_arg_conv.arg_name != "this_arg" + if explode_arg_conv.passed_as_ptr and not explode_arg_conv.rust_obj in trait_structs: + args_known = False + if not arg_conv_info.arg_name in default_constructor_args: + default_constructor_args[arg_conv_info.arg_name] = [] + default_constructor_args[arg_conv_info.arg_name].append(explode_arg_conv) + else: + args_known = False arg_names.append(arg_conv_info) out_java_struct = None @@ -434,7 +458,13 @@ with open(sys.argv[1]) as in_h, open(sys.argv[2], "w") as out_java, open(sys.arg if not takes_self or idx > 1: out_java_struct.write(", ") if arg.java_ty != "void" and arg.arg_name != "this_arg": - if arg.passed_as_ptr: + if arg.arg_name in default_constructor_args: + for explode_idx, explode_arg in enumerate(default_constructor_args[arg.arg_name]): + if explode_idx != 0: + out_java_struct.write(", ") + assert explode_arg.rust_obj in opaque_structs or explode_arg.rust_obj in trait_structs + out_java_struct.write(explode_arg.rust_obj.replace("LDK", "") + " " + arg.arg_name + "_" + explode_arg.arg_name) + elif arg.passed_as_ptr: if arg.rust_obj in opaque_structs or arg.rust_obj in trait_structs: out_java_struct.write(arg.rust_obj.replace("LDK", "") + " " + arg.arg_name) else: @@ -499,6 +529,15 @@ with open(sys.argv[1]) as in_h, open(sys.argv[2], "w") as out_java, open(sys.arg out_java_struct.write(", ") if info.arg_name == "this_arg": out_java_struct.write("this.ptr") + elif info.arg_name in default_constructor_args: + out_java_struct.write("bindings." + info.rust_obj.replace("LDK", "") + "_new(") + for explode_idx, explode_arg in enumerate(default_constructor_args[info.arg_name]): + if explode_idx != 0: + out_java_struct.write(", ") + assert explode_arg.passed_as_ptr and explode_arg.rust_obj in trait_structs + expl_arg_name = info.arg_name + "_" + explode_arg.arg_name + out_java_struct.write(expl_arg_name + " == null ? 0 : " + expl_arg_name + ".ptr") + out_java_struct.write(")") elif info.passed_as_ptr and info.rust_obj in opaque_structs: out_java_struct.write(info.arg_name + " == null ? 0 : " + info.arg_name + ".ptr & ~1") elif info.passed_as_ptr and info.rust_obj in trait_structs: @@ -518,6 +557,9 @@ with open(sys.argv[1]) as in_h, open(sys.argv[2], "w") as out_java, open(sys.arg for info in arg_names: if info.arg_name == "this_arg": pass + elif info.arg_name in default_constructor_args: + for explode_arg in default_constructor_args[info.arg_name]: + out_java_struct.write("\t\tthis.ptrs_to.add(" + info.arg_name + "_" + explode_arg.arg_name + ");\n") elif info.passed_as_ptr and (info.rust_obj in opaque_structs or info.rust_obj in trait_structs): out_java_struct.write("\t\tthis.ptrs_to.add(" + info.arg_name + ");\n") diff --git a/src/main/java/org/ldk/structs/PeerManager.java b/src/main/java/org/ldk/structs/PeerManager.java index d2256900..54b4e723 100644 --- a/src/main/java/org/ldk/structs/PeerManager.java +++ b/src/main/java/org/ldk/structs/PeerManager.java @@ -10,7 +10,13 @@ public class PeerManager extends CommonBase { bindings.PeerManager_free(ptr); super.finalize(); } - // Skipped PeerManager_new + public PeerManager(ChannelMessageHandler message_handler_chan_handler_arg, RoutingMessageHandler message_handler_route_handler_arg, byte[] our_node_secret, byte[] ephemeral_random_data, Logger logger) { + super(bindings.PeerManager_new(bindings.MessageHandler_new(message_handler_chan_handler_arg == null ? 0 : message_handler_chan_handler_arg.ptr, message_handler_route_handler_arg == null ? 0 : message_handler_route_handler_arg.ptr), our_node_secret, ephemeral_random_data, logger == null ? 0 : logger.ptr)); + this.ptrs_to.add(message_handler_chan_handler_arg); + this.ptrs_to.add(message_handler_route_handler_arg); + this.ptrs_to.add(logger); + } + // Skipped PeerManager_get_peer_node_ids // Skipped PeerManager_new_outbound_connection // Skipped PeerManager_new_inbound_connection diff --git a/src/test/java/org/ldk/HumanObjectPeerTest.java b/src/test/java/org/ldk/HumanObjectPeerTest.java index cc305da9..935eadb9 100644 --- a/src/test/java/org/ldk/HumanObjectPeerTest.java +++ b/src/test/java/org/ldk/HumanObjectPeerTest.java @@ -22,11 +22,8 @@ public class HumanObjectPeerTest { final KeysInterface keys_interface; final ChannelManager chan_manager; final EventsProvider chan_manager_events; - final long chan_handler; - final long router; - final long route_handler; - final long message_handler; - final long peer_manager; + final NetGraphMsgHandler router; + final PeerManager peer_manager; HashMap monitors; // Wow I forgot just how terrible Java is - we can't put a byte array here. byte[] node_id; @@ -85,17 +82,13 @@ public class HumanObjectPeerTest { }), new Logger(log_trait), keys.as_KeysInterface(), new UserConfig(), 1); this.node_id = chan_manager.get_our_node_id(); this.chan_manager_events = chan_manager.as_EventsProvider(); - - this.chan_handler = bindings.ChannelManager_as_ChannelMessageHandler(chan_manager._test_only_get_ptr()); - this.router = bindings.NetGraphMsgHandler_new(0, logger); - this.route_handler = bindings.NetGraphMsgHandler_as_RoutingMessageHandler(router); - this.message_handler = bindings.MessageHandler_new(chan_handler, route_handler); + this.router = new NetGraphMsgHandler(null, new Logger(log_trait)); byte[] random_data = new byte[32]; for (byte i = 0; i < 32; i++) { random_data[i] = (byte) ((i ^ seed) ^ 0xf0); } - this.peer_manager = bindings.PeerManager_new(message_handler, keys_interface.get_node_secret(), random_data, logger); + this.peer_manager = new PeerManager(chan_manager.as_ChannelMessageHandler(), router.as_RoutingMessageHandler(), keys_interface.get_node_secret(), random_data, new Logger(log_trait)); System.gc(); } @@ -126,25 +119,28 @@ public class HumanObjectPeerTest { bindings.Logger_free(logger); bindings.FeeEstimator_free(fee_estimator); bindings.BroadcasterInterface_free(tx_broadcaster); - bindings.ChannelMessageHandler_free(chan_handler); - bindings.NetGraphMsgHandler_free(router); - bindings.RoutingMessageHandler_free(route_handler); - //MessageHandler was actually moved into the route_handler!: bindings.MessageHandler_free(message_handler); - bindings.PeerManager_free(peer_manager); synchronized (monitors) { for (Long mon : monitors.values()) { bindings.ChannelMonitor_free(mon); } } } + + long get_route(byte[] dest_node, long our_chans) { + LockedNetworkGraph netgraph = this.router.read_locked_graph(); + //r = new WeakReference(netgraph); + NetworkGraph graph = netgraph.graph(); + return bindings.get_route(this.node_id, graph._test_only_get_ptr(), dest_node, our_chans, + bindings.LDKCVecTempl_RouteHint_new(new long[0]), 1000, 42, this.logger); + } } class LongHolder { long val; } java.util.LinkedList must_free_objs = new java.util.LinkedList(); - void do_read_event(ConcurrentLinkedQueue list, long pm, long descriptor, byte[] data) { + void do_read_event(ConcurrentLinkedQueue list, PeerManager pm, long descriptor, byte[] data) { Thread thread = new Thread(() -> { - long res = bindings.PeerManager_read_event(pm, descriptor, data); + long res = bindings.PeerManager_read_event(pm._test_only_get_ptr(), descriptor, data); assert bindings.LDKCResult_boolPeerHandleErrorZ_result_ok(res); //assert bindings.deref_bool(bindings.LDKCResult_boolPeerHandleErrorZ_get_inner(res)); bindings.CResult_boolPeerHandleErrorZ_free(res); @@ -196,10 +192,10 @@ public class HumanObjectPeerTest { }; descriptor1.val = bindings.LDKSocketDescriptor_new(sock2); - long init_vec = bindings.PeerManager_new_outbound_connection(peer1.peer_manager, peer2.node_id, descriptor1.val); + long init_vec = bindings.PeerManager_new_outbound_connection(peer1.peer_manager._test_only_get_ptr(), peer2.node_id, descriptor1.val); assert (bindings.LDKCResult_CVec_u8ZPeerHandleErrorZ_result_ok(init_vec)); - long con_res = bindings.PeerManager_new_inbound_connection(peer2.peer_manager, descriptor2); + long con_res = bindings.PeerManager_new_inbound_connection(peer2.peer_manager._test_only_get_ptr(), descriptor2); assert (bindings.LDKCResult_NonePeerHandleErrorZ_result_ok(con_res)); bindings.CResult_NonePeerHandleErrorZ_free(con_res); do_read_event(list, peer2.peer_manager, descriptor2, bindings.get_u8_slice_bytes(bindings.LDKCResult_CVec_u8ZPeerHandleErrorZ_get_inner(init_vec))); @@ -211,9 +207,9 @@ public class HumanObjectPeerTest { assert bindings.LDKCResult_NoneAPIErrorZ_result_ok(cc_res); bindings.CResult_NoneAPIErrorZ_free(cc_res); - bindings.PeerManager_process_events(peer1.peer_manager); + peer1.peer_manager.process_events(); while (!list.isEmpty()) { list.poll().join(); } - bindings.PeerManager_process_events(peer2.peer_manager); + peer2.peer_manager.process_events(); while (!list.isEmpty()) { list.poll().join(); } long events = bindings.EventsProvider_get_and_clear_pending_events(peer1.chan_manager_events._test_only_get_ptr()); @@ -235,9 +231,9 @@ public class HumanObjectPeerTest { funding.addOutput(Coin.SATOSHI.multiply(10000), new Script(funding_spk)); peer1.chan_manager.funding_transaction_generated(chan_id, new OutPoint(funding.getTxId().getReversedBytes(), (short) 0)); - bindings.PeerManager_process_events(peer1.peer_manager); + peer1.peer_manager.process_events(); while (!list.isEmpty()) { list.poll().join(); } - bindings.PeerManager_process_events(peer2.peer_manager); + peer2.peer_manager.process_events(); while (!list.isEmpty()) { list.poll().join(); } events = bindings.EventsProvider_get_and_clear_pending_events(peer1.chan_manager_events._test_only_get_ptr()); @@ -257,8 +253,8 @@ public class HumanObjectPeerTest { peer2.connect_block(b, null, height); } - bindings.PeerManager_process_events(peer1.peer_manager); - bindings.PeerManager_process_events(peer2.peer_manager); + peer1.peer_manager.process_events(); + peer2.peer_manager.process_events(); while (!list.isEmpty()) { list.poll().join(); } long peer1_chans = bindings.ChannelManager_list_channels(peer1.chan_manager._test_only_get_ptr()); @@ -276,22 +272,21 @@ public class HumanObjectPeerTest { byte[] payment_preimage = new byte[32]; for (int i = 0; i < 32; i++) payment_preimage[i] = (byte) (i ^ 0x0f); byte[] payment_hash = Sha256Hash.hash(payment_preimage); - long netgraph = bindings.NetGraphMsgHandler_read_locked_graph(peer1.router); - long route = bindings.get_route(peer1.node_id, bindings.LockedNetworkGraph_graph(netgraph), peer2.node_id, peer1_chans, - bindings.LDKCVecTempl_RouteHint_new(new long[0]), 1000, 42, peer1.logger); + long route = peer1.get_route(peer2.node_id, peer1_chans); + System.gc(); // Force the lock to release that we took in get_route - we need something better here! + System.runFinalization(); bindings.CVec_ChannelDetailsZ_free(peer1_chans); assert bindings.LDKCResult_RouteLightningErrorZ_result_ok(route); - bindings.LockedNetworkGraph_free(netgraph); long payment_res = bindings.ChannelManager_send_payment(peer1.chan_manager._test_only_get_ptr(), bindings.LDKCResult_RouteLightningErrorZ_get_inner(route), payment_hash, new byte[32]); bindings.CResult_RouteLightningErrorZ_free(route); assert bindings.LDKCResult_NonePaymentSendFailureZ_result_ok(payment_res); bindings.CResult_NonePaymentSendFailureZ_free(payment_res); - bindings.PeerManager_process_events(peer1.peer_manager); + peer1.peer_manager.process_events(); while (!list.isEmpty()) { list.poll().join(); } - bindings.PeerManager_process_events(peer2.peer_manager); + peer2.peer_manager.process_events(); while (!list.isEmpty()) { list.poll().join(); } - bindings.PeerManager_process_events(peer1.peer_manager); + peer1.peer_manager.process_events(); while (!list.isEmpty()) { list.poll().join(); } long peer2_events = bindings.EventsProvider_get_and_clear_pending_events(peer2.chan_manager_events._test_only_get_ptr()); @@ -310,9 +305,9 @@ public class HumanObjectPeerTest { peer2.chan_manager.claim_funds(payment_preimage, new byte[32], ((bindings.LDKEvent.PaymentReceived) payment_recvd).amt); bindings.CVec_EventZ_free(peer2_events); - bindings.PeerManager_process_events(peer2.peer_manager); + peer2.peer_manager.process_events(); while (!list.isEmpty()) { list.poll().join(); } - bindings.PeerManager_process_events(peer1.peer_manager); + peer1.peer_manager.process_events(); while (!list.isEmpty()) { list.poll().join(); } long peer1_events = bindings.EventsProvider_get_and_clear_pending_events(peer1.chan_manager_events._test_only_get_ptr());