X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=src%2Fmain%2Fjava%2Forg%2Fldk%2Fstructs%2FCustomMessageHandler.java;h=7425c2ebe65c4c4dfeb30a6c9ffd016fc7dfce3b;hb=5cdb34f643d09f21c147c9d0b2f8888609e43429;hp=5c1a4fab9159258dac2db9db6753faa189d73649;hpb=7aa095f42a570229656ab5fade9d966823b72e06;p=ldk-java diff --git a/src/main/java/org/ldk/structs/CustomMessageHandler.java b/src/main/java/org/ldk/structs/CustomMessageHandler.java index 5c1a4fab..7425c2eb 100644 --- a/src/main/java/org/ldk/structs/CustomMessageHandler.java +++ b/src/main/java/org/ldk/structs/CustomMessageHandler.java @@ -4,10 +4,18 @@ import org.ldk.impl.bindings; import org.ldk.enums.*; import org.ldk.util.*; import java.util.Arrays; +import java.lang.ref.Reference; import javax.annotation.Nullable; /** - * Handler for BOLT1-compliant messages. + * A handler provided to [`PeerManager`] for reading and handling custom messages. + * + * [BOLT 1] specifies a custom message type range for use with experimental or application-specific + * messages. `CustomMessageHandler` allows for user-defined handling of such types. See the + * [`lightning_custom_message`] crate for tools useful in composing more than one custom handler. + * + * [BOLT 1]: https://github.com/lightning/bolts/blob/master/01-messaging.md + * [`lightning_custom_message`]: https://docs.rs/lightning_custom_message/latest/lightning_custom_message */ @SuppressWarnings("unchecked") // We correctly assign various generic arrays public class CustomMessageHandler extends CommonBase { @@ -23,18 +31,30 @@ public class CustomMessageHandler extends CommonBase { protected void finalize() throws Throwable { if (ptr != 0) { bindings.CustomMessageHandler_free(ptr); } super.finalize(); } - + /** + * Destroys the object, freeing associated resources. After this call, any access + * to this object may result in a SEGFAULT or worse. + * + * You should generally NEVER call this method. You should let the garbage collector + * do this for you when it finalizes objects. However, it may be useful for types + * which represent locks and should be closed immediately to avoid holding locks + * until the GC runs. + */ + public void destroy() { + if (ptr != 0) { bindings.CustomMessageHandler_free(ptr); } + ptr = 0; + } public static interface CustomMessageHandlerInterface { /** - * Called with the message type that was received and the buffer to be read. - * Can return a `MessageHandlingError` if the message could not be handled. + * Handles the given message sent from `sender_node_id`, possibly producing messages for + * [`CustomMessageHandler::get_and_clear_pending_msg`] to return and thus for [`PeerManager`] + * to send. */ Result_NoneLightningErrorZ handle_custom_message(Type msg, byte[] sender_node_id); /** - * Gets the list of pending messages which were generated by the custom message - * handler, clearing the list in the process. The first tuple element must - * correspond to the intended recipients node ids. If no connection to one of the - * specified node does not exist, the message is simply not sent to it. + * Returns the list of pending messages that were generated by the handler, clearing the list + * in the process. Each message is paired with the node id of the intended recipient. If no + * connection to the node exists, then the message is simply not sent. */ TwoTuple_PublicKeyTypeZ[] get_and_clear_pending_msg(); } @@ -44,14 +64,16 @@ public class CustomMessageHandler extends CommonBase { impl_holder.held = new CustomMessageHandler(new bindings.LDKCustomMessageHandler() { @Override public long handle_custom_message(long msg, byte[] sender_node_id) { Type ret_hu_conv = new Type(null, msg); - ret_hu_conv.ptrs_to.add(this); + if (ret_hu_conv != null) { ret_hu_conv.ptrs_to.add(this); }; Result_NoneLightningErrorZ ret = arg.handle_custom_message(ret_hu_conv, sender_node_id); - long result = ret != null ? ret.ptr : 0; + Reference.reachabilityFence(arg); + long result = ret == null ? 0 : ret.clone_ptr(); return result; } @Override public long[] get_and_clear_pending_msg() { TwoTuple_PublicKeyTypeZ[] ret = arg.get_and_clear_pending_msg(); - long[] result = ret != null ? Arrays.stream(ret).mapToLong(ret_conv_25 -> ret_conv_25 != null ? ret_conv_25.ptr : 0).toArray() : null; + Reference.reachabilityFence(arg); + long[] result = ret != null ? Arrays.stream(ret).mapToLong(ret_conv_25 -> ret_conv_25 == null ? 0 : ret_conv_25.clone_ptr()).toArray() : null; return result; } }, CustomMessageReader.new_impl(CustomMessageReader_impl).bindings_instance); @@ -63,35 +85,40 @@ public class CustomMessageHandler extends CommonBase { */ public CustomMessageReader get_custom_message_reader() { CustomMessageReader res = new CustomMessageReader(null, bindings.LDKCustomMessageHandler_get_CustomMessageReader(this.ptr)); - this.ptrs_to.add(res); + res.ptrs_to.add(this); return res; } /** - * Called with the message type that was received and the buffer to be read. - * Can return a `MessageHandlingError` if the message could not be handled. + * Handles the given message sent from `sender_node_id`, possibly producing messages for + * [`CustomMessageHandler::get_and_clear_pending_msg`] to return and thus for [`PeerManager`] + * to send. */ - public Result_NoneLightningErrorZ handle_custom_message(Type msg, byte[] sender_node_id) { - long ret = bindings.CustomMessageHandler_handle_custom_message(this.ptr, msg == null ? 0 : msg.ptr, sender_node_id); - if (ret < 1024) { return null; } + public Result_NoneLightningErrorZ handle_custom_message(org.ldk.structs.Type msg, byte[] sender_node_id) { + long ret = bindings.CustomMessageHandler_handle_custom_message(this.ptr, msg == null ? 0 : msg.ptr, InternalUtils.check_arr_len(sender_node_id, 33)); + Reference.reachabilityFence(this); + Reference.reachabilityFence(msg); + Reference.reachabilityFence(sender_node_id); + if (ret >= 0 && ret <= 4096) { return null; } Result_NoneLightningErrorZ ret_hu_conv = Result_NoneLightningErrorZ.constr_from_ptr(ret); - this.ptrs_to.add(msg); + if (this != null) { this.ptrs_to.add(msg); }; return ret_hu_conv; } /** - * Gets the list of pending messages which were generated by the custom message - * handler, clearing the list in the process. The first tuple element must - * correspond to the intended recipients node ids. If no connection to one of the - * specified node does not exist, the message is simply not sent to it. + * Returns the list of pending messages that were generated by the handler, clearing the list + * in the process. Each message is paired with the node id of the intended recipient. If no + * connection to the node exists, then the message is simply not sent. */ public TwoTuple_PublicKeyTypeZ[] get_and_clear_pending_msg() { long[] ret = bindings.CustomMessageHandler_get_and_clear_pending_msg(this.ptr); - TwoTuple_PublicKeyTypeZ[] ret_conv_25_arr = new TwoTuple_PublicKeyTypeZ[ret.length]; - for (int z = 0; z < ret.length; z++) { + Reference.reachabilityFence(this); + int ret_conv_25_len = ret.length; + TwoTuple_PublicKeyTypeZ[] ret_conv_25_arr = new TwoTuple_PublicKeyTypeZ[ret_conv_25_len]; + for (int z = 0; z < ret_conv_25_len; z++) { long ret_conv_25 = ret[z]; TwoTuple_PublicKeyTypeZ ret_conv_25_hu_conv = new TwoTuple_PublicKeyTypeZ(null, ret_conv_25); - ret_conv_25_hu_conv.ptrs_to.add(this); + if (ret_conv_25_hu_conv != null) { ret_conv_25_hu_conv.ptrs_to.add(this); }; ret_conv_25_arr[z] = ret_conv_25_hu_conv; } return ret_conv_25_arr;