Bindings updates
[ldk-java] / src / main / jni / bindings.c
index 3a878484cb197611b08d4411eb84da7136c2d050..ad260dc2ef91b5b04de086c42f4586eb7d77229e 100644 (file)
@@ -31,16 +31,18 @@ typedef struct allocation {
        const char* struct_name;
        void* bt[BT_MAX];
        int bt_len;
+       size_t alloc_len;
 } allocation;
 static allocation* allocation_ll = NULL;
 
 void* __real_malloc(size_t len);
 void* __real_calloc(size_t nmemb, size_t len);
-static void new_allocation(void* res, const char* struct_name) {
+static void new_allocation(void* res, const char* struct_name, size_t len) {
        allocation* new_alloc = __real_malloc(sizeof(allocation));
        new_alloc->ptr = res;
        new_alloc->struct_name = struct_name;
        new_alloc->bt_len = backtrace(new_alloc->bt, BT_MAX);
+       new_alloc->alloc_len = len;
        DO_ASSERT(mtx_lock(&allocation_mtx) == thrd_success);
        new_alloc->next = allocation_ll;
        allocation_ll = new_alloc;
@@ -48,7 +50,7 @@ static void new_allocation(void* res, const char* struct_name) {
 }
 static void* MALLOC(size_t len, const char* struct_name) {
        void* res = __real_malloc(len);
-       new_allocation(res, struct_name);
+       new_allocation(res, struct_name, len);
        return res;
 }
 void __real_free(void* ptr);
@@ -81,12 +83,12 @@ static void FREE(void* ptr) {
 
 void* __wrap_malloc(size_t len) {
        void* res = __real_malloc(len);
-       new_allocation(res, "malloc call");
+       new_allocation(res, "malloc call", len);
        return res;
 }
 void* __wrap_calloc(size_t nmemb, size_t len) {
        void* res = __real_calloc(nmemb, len);
-       new_allocation(res, "calloc call");
+       new_allocation(res, "calloc call", len);
        return res;
 }
 void __wrap_free(void* ptr) {
@@ -99,7 +101,7 @@ void* __real_realloc(void* ptr, size_t newlen);
 void* __wrap_realloc(void* ptr, size_t len) {
        if (ptr != NULL) alloc_freed(ptr);
        void* res = __real_realloc(ptr, len);
-       new_allocation(res, "realloc call");
+       new_allocation(res, "realloc call", len);
        return res;
 }
 void __wrap_reallocarray(void* ptr, size_t new_sz) {
@@ -108,11 +110,16 @@ void __wrap_reallocarray(void* ptr, size_t new_sz) {
 }
 
 void __attribute__((destructor)) check_leaks() {
+       size_t alloc_count = 0;
+       size_t alloc_size = 0;
        for (allocation* a = allocation_ll; a != NULL; a = a->next) {
                fprintf(stderr, "%s %p remains:\n", a->struct_name, a->ptr);
                backtrace_symbols_fd(a->bt, a->bt_len, STDERR_FILENO);
                fprintf(stderr, "\n\n");
+               alloc_count++;
+               alloc_size += a->alloc_len;
        }
+       fprintf(stderr, "%lu allocations remained for %lu bytes.\n", alloc_count, alloc_size);
        DO_ASSERT(allocation_ll == NULL);
 }
 
@@ -501,19 +508,12 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKC2Tuple_1u64u64Z_1new(JN
        ret->b = b;
        return (long)ret;
 }
-static inline LDKC2Tuple_u64u64Z C2Tuple_u64u64Z_clone(const LDKC2Tuple_u64u64Z *orig) {
-       LDKC2Tuple_u64u64Z ret = {
-               .a = orig->a,
-               .b = orig->b,
-       };
-       return ret;
-}
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKC2Tuple_1u64u64Z_1get_1a(JNIEnv *env, jclass clz, int64_t ptr) {
-       LDKC2Tuple_u64u64Z *tuple = (LDKC2Tuple_u64u64Z*)ptr;
+       LDKC2Tuple_u64u64Z *tuple = (LDKC2Tuple_u64u64Z*)(ptr & ~1);
        return tuple->a;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKC2Tuple_1u64u64Z_1get_1b(JNIEnv *env, jclass clz, int64_t ptr) {
-       LDKC2Tuple_u64u64Z *tuple = (LDKC2Tuple_u64u64Z*)ptr;
+       LDKC2Tuple_u64u64Z *tuple = (LDKC2Tuple_u64u64Z*)(ptr & ~1);
        return tuple->b;
 }
 static jclass LDKSpendableOutputDescriptor_StaticOutput_class = NULL;
@@ -547,7 +547,7 @@ JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_LDKSpendableOutputDescripto
                        CHECK((((long)outpoint_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
                        CHECK((((long)&outpoint_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
                        long outpoint_ref = (long)outpoint_var.inner & ~1;
-                       long output_ref = (long)&obj->static_output.output;
+                       long output_ref = ((long)&obj->static_output.output) | 1;
                        return (*env)->NewObject(env, LDKSpendableOutputDescriptor_StaticOutput_class, LDKSpendableOutputDescriptor_StaticOutput_meth, outpoint_ref, (long)output_ref);
                }
                case LDKSpendableOutputDescriptor_DynamicOutputP2WSH: {
@@ -557,8 +557,8 @@ JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_LDKSpendableOutputDescripto
                        long outpoint_ref = (long)outpoint_var.inner & ~1;
                        int8_tArray per_commitment_point_arr = (*env)->NewByteArray(env, 33);
                        (*env)->SetByteArrayRegion(env, per_commitment_point_arr, 0, 33, obj->dynamic_output_p2wsh.per_commitment_point.compressed_form);
-                       long output_ref = (long)&obj->dynamic_output_p2wsh.output;
-                       long key_derivation_params_ref = (long)&obj->dynamic_output_p2wsh.key_derivation_params;
+                       long output_ref = ((long)&obj->dynamic_output_p2wsh.output) | 1;
+                       long key_derivation_params_ref = (long)(&obj->dynamic_output_p2wsh.key_derivation_params) | 1;
                        int8_tArray revocation_pubkey_arr = (*env)->NewByteArray(env, 33);
                        (*env)->SetByteArrayRegion(env, revocation_pubkey_arr, 0, 33, obj->dynamic_output_p2wsh.revocation_pubkey.compressed_form);
                        return (*env)->NewObject(env, LDKSpendableOutputDescriptor_DynamicOutputP2WSH_class, LDKSpendableOutputDescriptor_DynamicOutputP2WSH_meth, outpoint_ref, per_commitment_point_arr, obj->dynamic_output_p2wsh.to_self_delay, (long)output_ref, key_derivation_params_ref, revocation_pubkey_arr);
@@ -568,8 +568,8 @@ JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_LDKSpendableOutputDescripto
                        CHECK((((long)outpoint_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
                        CHECK((((long)&outpoint_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
                        long outpoint_ref = (long)outpoint_var.inner & ~1;
-                       long output_ref = (long)&obj->static_output_counterparty_payment.output;
-                       long key_derivation_params_ref = (long)&obj->static_output_counterparty_payment.key_derivation_params;
+                       long output_ref = ((long)&obj->static_output_counterparty_payment.output) | 1;
+                       long key_derivation_params_ref = (long)(&obj->static_output_counterparty_payment.key_derivation_params) | 1;
                        return (*env)->NewObject(env, LDKSpendableOutputDescriptor_StaticOutputCounterpartyPayment_class, LDKSpendableOutputDescriptor_StaticOutputCounterpartyPayment_meth, outpoint_ref, (long)output_ref, key_derivation_params_ref);
                }
                default: abort();
@@ -585,7 +585,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCVec_1SpendableOutputDes
                int64_t *java_elems = (*env)->GetPrimitiveArrayCritical(env, elems, NULL);
                for (size_t i = 0; i < ret->datalen; i++) {
                        int64_t arr_elem = java_elems[i];
-                       LDKSpendableOutputDescriptor arr_elem_conv = *(LDKSpendableOutputDescriptor*)arr_elem;
+                       LDKSpendableOutputDescriptor arr_elem_conv = *(LDKSpendableOutputDescriptor*)(((uint64_t)arr_elem) & ~1);
                        FREE((void*)arr_elem);
                        ret->data[i] = arr_elem_conv;
                }
@@ -948,11 +948,11 @@ JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_LDKMessageSendEvent_1ref_1f
                case LDKMessageSendEvent_HandleError: {
                        int8_tArray node_id_arr = (*env)->NewByteArray(env, 33);
                        (*env)->SetByteArrayRegion(env, node_id_arr, 0, 33, obj->handle_error.node_id.compressed_form);
-                       long action_ref = (long)&obj->handle_error.action;
+                       long action_ref = ((long)&obj->handle_error.action) | 1;
                        return (*env)->NewObject(env, LDKMessageSendEvent_HandleError_class, LDKMessageSendEvent_HandleError_meth, node_id_arr, action_ref);
                }
                case LDKMessageSendEvent_PaymentFailureNetworkUpdate: {
-                       long update_ref = (long)&obj->payment_failure_network_update.update;
+                       long update_ref = ((long)&obj->payment_failure_network_update.update) | 1;
                        return (*env)->NewObject(env, LDKMessageSendEvent_PaymentFailureNetworkUpdate_class, LDKMessageSendEvent_PaymentFailureNetworkUpdate_meth, update_ref);
                }
                case LDKMessageSendEvent_SendChannelRangeQuery: {
@@ -986,7 +986,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCVec_1MessageSendEventZ_
                int64_t *java_elems = (*env)->GetPrimitiveArrayCritical(env, elems, NULL);
                for (size_t i = 0; i < ret->datalen; i++) {
                        int64_t arr_elem = java_elems[i];
-                       LDKMessageSendEvent arr_elem_conv = *(LDKMessageSendEvent*)arr_elem;
+                       LDKMessageSendEvent arr_elem_conv = *(LDKMessageSendEvent*)(((uint64_t)arr_elem) & ~1);
                        FREE((void*)arr_elem);
                        ret->data[i] = arr_elem_conv;
                }
@@ -1095,7 +1095,7 @@ JNIEXPORT jobject JNICALL Java_org_ldk_impl_bindings_LDKEvent_1ref_1from_1ptr(JN
                        int64_tArray outputs_arr = (*env)->NewLongArray(env, outputs_var.datalen);
                        int64_t *outputs_arr_ptr = (*env)->GetPrimitiveArrayCritical(env, outputs_arr, NULL);
                        for (size_t b = 0; b < outputs_var.datalen; b++) {
-                               long arr_conv_27_ref = (long)&outputs_var.data[b];
+                               long arr_conv_27_ref = ((long)&outputs_var.data[b]) | 1;
                                outputs_arr_ptr[b] = arr_conv_27_ref;
                        }
                        (*env)->ReleasePrimitiveArrayCritical(env, outputs_arr, outputs_arr_ptr, 0);
@@ -1114,7 +1114,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCVec_1EventZ_1new(JNIEnv
                int64_t *java_elems = (*env)->GetPrimitiveArrayCritical(env, elems, NULL);
                for (size_t i = 0; i < ret->datalen; i++) {
                        int64_t arr_elem = java_elems[i];
-                       LDKEvent arr_elem_conv = *(LDKEvent*)arr_elem;
+                       LDKEvent arr_elem_conv = *(LDKEvent*)(((uint64_t)arr_elem) & ~1);
                        FREE((void*)arr_elem);
                        ret->data[i] = arr_elem_conv;
                }
@@ -1141,11 +1141,11 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKC2Tuple_1usizeTransactio
        return (long)ret;
 }
 JNIEXPORT intptr_t JNICALL Java_org_ldk_impl_bindings_LDKC2Tuple_1usizeTransactionZ_1get_1a(JNIEnv *env, jclass clz, int64_t ptr) {
-       LDKC2Tuple_usizeTransactionZ *tuple = (LDKC2Tuple_usizeTransactionZ*)ptr;
+       LDKC2Tuple_usizeTransactionZ *tuple = (LDKC2Tuple_usizeTransactionZ*)(ptr & ~1);
        return tuple->a;
 }
 JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_LDKC2Tuple_1usizeTransactionZ_1get_1b(JNIEnv *env, jclass clz, int64_t ptr) {
-       LDKC2Tuple_usizeTransactionZ *tuple = (LDKC2Tuple_usizeTransactionZ*)ptr;
+       LDKC2Tuple_usizeTransactionZ *tuple = (LDKC2Tuple_usizeTransactionZ*)(ptr & ~1);
        LDKTransaction b_var = tuple->b;
        int8_tArray b_arr = (*env)->NewByteArray(env, b_var.datalen);
        (*env)->SetByteArrayRegion(env, b_arr, 0, b_var.datalen, b_var.data);
@@ -1161,7 +1161,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCVec_1C2Tuple_1usizeTran
                int64_t *java_elems = (*env)->GetPrimitiveArrayCritical(env, elems, NULL);
                for (size_t i = 0; i < ret->datalen; i++) {
                        int64_t arr_elem = java_elems[i];
-                       LDKC2Tuple_usizeTransactionZ arr_elem_conv = *(LDKC2Tuple_usizeTransactionZ*)arr_elem;
+                       LDKC2Tuple_usizeTransactionZ arr_elem_conv = *(LDKC2Tuple_usizeTransactionZ*)(((uint64_t)arr_elem) & ~1);
                        FREE((void*)arr_elem);
                        ret->data[i] = arr_elem_conv;
                }
@@ -1173,27 +1173,16 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1NoneChannelMon
        return ((LDKCResult_NoneChannelMonitorUpdateErrZ*)arg)->result_ok;
 }
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_LDKCResult_1NoneChannelMonitorUpdateErrZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_NoneChannelMonitorUpdateErrZ *val = (LDKCResult_NoneChannelMonitorUpdateErrZ*)arg;
+       LDKCResult_NoneChannelMonitorUpdateErrZ *val = (LDKCResult_NoneChannelMonitorUpdateErrZ*)(arg & ~1);
        CHECK(val->result_ok);
        return *val->contents.result;
 }
 JNIEXPORT jclass JNICALL Java_org_ldk_impl_bindings_LDKCResult_1NoneChannelMonitorUpdateErrZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_NoneChannelMonitorUpdateErrZ *val = (LDKCResult_NoneChannelMonitorUpdateErrZ*)arg;
+       LDKCResult_NoneChannelMonitorUpdateErrZ *val = (LDKCResult_NoneChannelMonitorUpdateErrZ*)(arg & ~1);
        CHECK(!val->result_ok);
        jclass err_conv = LDKChannelMonitorUpdateErr_to_java(env, (*val->contents.err));
        return err_conv;
 }
-static inline LDKCResult_NoneChannelMonitorUpdateErrZ CResult_NoneChannelMonitorUpdateErrZ_clone(const LDKCResult_NoneChannelMonitorUpdateErrZ *orig) {
-       LDKCResult_NoneChannelMonitorUpdateErrZ res = { .result_ok = orig->result_ok };
-       if (orig->result_ok) {
-               res.contents.result = NULL;
-       } else {
-               LDKChannelMonitorUpdateErr* contents = MALLOC(sizeof(LDKChannelMonitorUpdateErr), "LDKChannelMonitorUpdateErr result Err clone");
-               *contents = ChannelMonitorUpdateErr_clone(orig->contents.err);
-               res.contents.err = contents;
-       }
-       return res;
-}
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCVec_1MonitorEventZ_1new(JNIEnv *env, jclass clz, int64_tArray elems) {
        LDKCVec_MonitorEventZ *ret = MALLOC(sizeof(LDKCVec_MonitorEventZ), "LDKCVec_MonitorEventZ");
        ret->datalen = (*env)->GetArrayLength(env, elems);
@@ -1207,8 +1196,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCVec_1MonitorEventZ_1new
                        LDKMonitorEvent arr_elem_conv;
                        arr_elem_conv.inner = (void*)(arr_elem & (~1));
                        arr_elem_conv.is_owned = (arr_elem & 1) || (arr_elem == 0);
-                       if (arr_elem_conv.inner != NULL)
-                               arr_elem_conv = MonitorEvent_clone(&arr_elem_conv);
+                       arr_elem_conv = MonitorEvent_clone(&arr_elem_conv);
                        ret->data[i] = arr_elem_conv;
                }
                (*env)->ReleasePrimitiveArrayCritical(env, elems, java_elems, 0);
@@ -1226,7 +1214,7 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1ChannelMonitor
        return ((LDKCResult_ChannelMonitorUpdateDecodeErrorZ*)arg)->result_ok;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1ChannelMonitorUpdateDecodeErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_ChannelMonitorUpdateDecodeErrorZ *val = (LDKCResult_ChannelMonitorUpdateDecodeErrorZ*)arg;
+       LDKCResult_ChannelMonitorUpdateDecodeErrorZ *val = (LDKCResult_ChannelMonitorUpdateDecodeErrorZ*)(arg & ~1);
        CHECK(val->result_ok);
        LDKChannelMonitorUpdate res_var = (*val->contents.result);
        CHECK((((long)res_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -1235,7 +1223,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1ChannelMonitorU
        return res_ref;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1ChannelMonitorUpdateDecodeErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_ChannelMonitorUpdateDecodeErrorZ *val = (LDKCResult_ChannelMonitorUpdateDecodeErrorZ*)arg;
+       LDKCResult_ChannelMonitorUpdateDecodeErrorZ *val = (LDKCResult_ChannelMonitorUpdateDecodeErrorZ*)(arg & ~1);
        CHECK(!val->result_ok);
        LDKDecodeError err_var = (*val->contents.err);
        CHECK((((long)err_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -1247,12 +1235,12 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1NoneMonitorUpd
        return ((LDKCResult_NoneMonitorUpdateErrorZ*)arg)->result_ok;
 }
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_LDKCResult_1NoneMonitorUpdateErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_NoneMonitorUpdateErrorZ *val = (LDKCResult_NoneMonitorUpdateErrorZ*)arg;
+       LDKCResult_NoneMonitorUpdateErrorZ *val = (LDKCResult_NoneMonitorUpdateErrorZ*)(arg & ~1);
        CHECK(val->result_ok);
        return *val->contents.result;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1NoneMonitorUpdateErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_NoneMonitorUpdateErrorZ *val = (LDKCResult_NoneMonitorUpdateErrorZ*)arg;
+       LDKCResult_NoneMonitorUpdateErrorZ *val = (LDKCResult_NoneMonitorUpdateErrorZ*)(arg & ~1);
        CHECK(!val->result_ok);
        LDKMonitorUpdateError err_var = (*val->contents.err);
        CHECK((((long)err_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -1265,8 +1253,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKC2Tuple_1OutPointScriptZ
        LDKOutPoint a_conv;
        a_conv.inner = (void*)(a & (~1));
        a_conv.is_owned = (a & 1) || (a == 0);
-       if (a_conv.inner != NULL)
-               a_conv = OutPoint_clone(&a_conv);
+       a_conv = OutPoint_clone(&a_conv);
        ret->a = a_conv;
        LDKCVec_u8Z b_ref;
        b_ref.datalen = (*env)->GetArrayLength(env, b);
@@ -1275,15 +1262,8 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKC2Tuple_1OutPointScriptZ
        ret->b = b_ref;
        return (long)ret;
 }
-static inline LDKC2Tuple_OutPointScriptZ C2Tuple_OutPointScriptZ_clone(const LDKC2Tuple_OutPointScriptZ *orig) {
-       LDKC2Tuple_OutPointScriptZ ret = {
-               .a = OutPoint_clone(&orig->a),
-               .b = CVec_u8Z_clone(&orig->b),
-       };
-       return ret;
-}
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKC2Tuple_1OutPointScriptZ_1get_1a(JNIEnv *env, jclass clz, int64_t ptr) {
-       LDKC2Tuple_OutPointScriptZ *tuple = (LDKC2Tuple_OutPointScriptZ*)ptr;
+       LDKC2Tuple_OutPointScriptZ *tuple = (LDKC2Tuple_OutPointScriptZ*)(ptr & ~1);
        LDKOutPoint a_var = tuple->a;
        CHECK((((long)a_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&a_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
@@ -1291,7 +1271,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKC2Tuple_1OutPointScriptZ
        return a_ref;
 }
 JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_LDKC2Tuple_1OutPointScriptZ_1get_1b(JNIEnv *env, jclass clz, int64_t ptr) {
-       LDKC2Tuple_OutPointScriptZ *tuple = (LDKC2Tuple_OutPointScriptZ*)ptr;
+       LDKC2Tuple_OutPointScriptZ *tuple = (LDKC2Tuple_OutPointScriptZ*)(ptr & ~1);
        LDKCVec_u8Z b_var = tuple->b;
        int8_tArray b_arr = (*env)->NewByteArray(env, b_var.datalen);
        (*env)->SetByteArrayRegion(env, b_arr, 0, b_var.datalen, b_var.data);
@@ -1300,25 +1280,18 @@ JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_LDKC2Tuple_1OutPointScr
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKC2Tuple_1u32TxOutZ_1new(JNIEnv *env, jclass clz, int32_t a, int64_t b) {
        LDKC2Tuple_u32TxOutZ* ret = MALLOC(sizeof(LDKC2Tuple_u32TxOutZ), "LDKC2Tuple_u32TxOutZ");
        ret->a = a;
-       LDKTxOut b_conv = *(LDKTxOut*)b;
+       LDKTxOut b_conv = *(LDKTxOut*)(((uint64_t)b) & ~1);
        FREE((void*)b);
        ret->b = b_conv;
        return (long)ret;
 }
-static inline LDKC2Tuple_u32TxOutZ C2Tuple_u32TxOutZ_clone(const LDKC2Tuple_u32TxOutZ *orig) {
-       LDKC2Tuple_u32TxOutZ ret = {
-               .a = orig->a,
-               .b = TxOut_clone(&orig->b),
-       };
-       return ret;
-}
 JNIEXPORT int32_t JNICALL Java_org_ldk_impl_bindings_LDKC2Tuple_1u32TxOutZ_1get_1a(JNIEnv *env, jclass clz, int64_t ptr) {
-       LDKC2Tuple_u32TxOutZ *tuple = (LDKC2Tuple_u32TxOutZ*)ptr;
+       LDKC2Tuple_u32TxOutZ *tuple = (LDKC2Tuple_u32TxOutZ*)(ptr & ~1);
        return tuple->a;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKC2Tuple_1u32TxOutZ_1get_1b(JNIEnv *env, jclass clz, int64_t ptr) {
-       LDKC2Tuple_u32TxOutZ *tuple = (LDKC2Tuple_u32TxOutZ*)ptr;
-       long b_ref = (long)&tuple->b;
+       LDKC2Tuple_u32TxOutZ *tuple = (LDKC2Tuple_u32TxOutZ*)(ptr & ~1);
+       long b_ref = ((long)&tuple->b) | 1;
        return (long)b_ref;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCVec_1C2Tuple_1u32TxOutZZ_1new(JNIEnv *env, jclass clz, int64_tArray elems) {
@@ -1331,7 +1304,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCVec_1C2Tuple_1u32TxOutZ
                int64_t *java_elems = (*env)->GetPrimitiveArrayCritical(env, elems, NULL);
                for (size_t i = 0; i < ret->datalen; i++) {
                        int64_t arr_elem = java_elems[i];
-                       LDKC2Tuple_u32TxOutZ arr_elem_conv = *(LDKC2Tuple_u32TxOutZ*)arr_elem;
+                       LDKC2Tuple_u32TxOutZ arr_elem_conv = *(LDKC2Tuple_u32TxOutZ*)(((uint64_t)arr_elem) & ~1);
                        FREE((void*)arr_elem);
                        ret->data[i] = arr_elem_conv;
                }
@@ -1361,7 +1334,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKC2Tuple_1TxidCVec_1C2Tup
        int64_t* b_vals = (*env)->GetLongArrayElements (env, b, NULL);
        for (size_t a = 0; a < b_constr.datalen; a++) {
                int64_t arr_conv_26 = b_vals[a];
-               LDKC2Tuple_u32TxOutZ arr_conv_26_conv = *(LDKC2Tuple_u32TxOutZ*)arr_conv_26;
+               LDKC2Tuple_u32TxOutZ arr_conv_26_conv = *(LDKC2Tuple_u32TxOutZ*)(((uint64_t)arr_conv_26) & ~1);
                FREE((void*)arr_conv_26);
                b_constr.data[a] = arr_conv_26_conv;
        }
@@ -1369,26 +1342,19 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKC2Tuple_1TxidCVec_1C2Tup
        ret->b = b_constr;
        return (long)ret;
 }
-static inline LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ_clone(const LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ *orig) {
-       LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ ret = {
-               .a = ThirtyTwoBytes_clone(&orig->a),
-               .b = CVec_C2Tuple_u32TxOutZZ_clone(&orig->b),
-       };
-       return ret;
-}
 JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_LDKC2Tuple_1TxidCVec_1C2Tuple_1u32TxOutZZZ_1get_1a(JNIEnv *env, jclass clz, int64_t ptr) {
-       LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ *tuple = (LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ*)ptr;
+       LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ *tuple = (LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ*)(ptr & ~1);
        int8_tArray a_arr = (*env)->NewByteArray(env, 32);
        (*env)->SetByteArrayRegion(env, a_arr, 0, 32, tuple->a.data);
        return a_arr;
 }
 JNIEXPORT int64_tArray JNICALL Java_org_ldk_impl_bindings_LDKC2Tuple_1TxidCVec_1C2Tuple_1u32TxOutZZZ_1get_1b(JNIEnv *env, jclass clz, int64_t ptr) {
-       LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ *tuple = (LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ*)ptr;
+       LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ *tuple = (LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ*)(ptr & ~1);
        LDKCVec_C2Tuple_u32TxOutZZ b_var = tuple->b;
        int64_tArray b_arr = (*env)->NewLongArray(env, b_var.datalen);
        int64_t *b_arr_ptr = (*env)->GetPrimitiveArrayCritical(env, b_arr, NULL);
        for (size_t a = 0; a < b_var.datalen; a++) {
-               long arr_conv_26_ref = (long)&b_var.data[a];
+               long arr_conv_26_ref = (long)(&b_var.data[a]) | 1;
                b_arr_ptr[a] = arr_conv_26_ref;
        }
        (*env)->ReleasePrimitiveArrayCritical(env, b_arr, b_arr_ptr, 0);
@@ -1404,7 +1370,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCVec_1C2Tuple_1TxidCVec_
                int64_t *java_elems = (*env)->GetPrimitiveArrayCritical(env, elems, NULL);
                for (size_t i = 0; i < ret->datalen; i++) {
                        int64_t arr_elem = java_elems[i];
-                       LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ arr_elem_conv = *(LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ*)arr_elem;
+                       LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ arr_elem_conv = *(LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ*)(((uint64_t)arr_elem) & ~1);
                        FREE((void*)arr_elem);
                        ret->data[i] = arr_elem_conv;
                }
@@ -1412,13 +1378,6 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCVec_1C2Tuple_1TxidCVec_
        }
        return (long)ret;
 }
-static inline LDKCVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ CVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ_clone(const LDKCVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ *orig) {
-       LDKCVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ ret = { .data = MALLOC(sizeof(LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ) * orig->datalen, "LDKCVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ clone bytes"), .datalen = orig->datalen };
-       for (size_t i = 0; i < ret.datalen; i++) {
-               ret.data[i] = C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ_clone(&orig->data[i]);
-       }
-       return ret;
-}
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKC2Tuple_1SignatureCVec_1SignatureZZ_1new(JNIEnv *env, jclass clz, int8_tArray a, jobjectArray b) {
        LDKC2Tuple_SignatureCVec_SignatureZZ* ret = MALLOC(sizeof(LDKC2Tuple_SignatureCVec_SignatureZZ), "LDKC2Tuple_SignatureCVec_SignatureZZ");
        LDKSignature a_ref;
@@ -1442,13 +1401,13 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKC2Tuple_1SignatureCVec_1
        return (long)ret;
 }
 JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_LDKC2Tuple_1SignatureCVec_1SignatureZZ_1get_1a(JNIEnv *env, jclass clz, int64_t ptr) {
-       LDKC2Tuple_SignatureCVec_SignatureZZ *tuple = (LDKC2Tuple_SignatureCVec_SignatureZZ*)ptr;
+       LDKC2Tuple_SignatureCVec_SignatureZZ *tuple = (LDKC2Tuple_SignatureCVec_SignatureZZ*)(ptr & ~1);
        int8_tArray a_arr = (*env)->NewByteArray(env, 64);
        (*env)->SetByteArrayRegion(env, a_arr, 0, 64, tuple->a.compact_form);
        return a_arr;
 }
 JNIEXPORT jobjectArray JNICALL Java_org_ldk_impl_bindings_LDKC2Tuple_1SignatureCVec_1SignatureZZ_1get_1b(JNIEnv *env, jclass clz, int64_t ptr) {
-       LDKC2Tuple_SignatureCVec_SignatureZZ *tuple = (LDKC2Tuple_SignatureCVec_SignatureZZ*)ptr;
+       LDKC2Tuple_SignatureCVec_SignatureZZ *tuple = (LDKC2Tuple_SignatureCVec_SignatureZZ*)(ptr & ~1);
        LDKCVec_SignatureZ b_var = tuple->b;
        jobjectArray b_arr = (*env)->NewObjectArray(env, b_var.datalen, arr_of_B_clz, NULL);
        ;
@@ -1463,13 +1422,13 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1C2Tuple_1Signa
        return ((LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ*)arg)->result_ok;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1C2Tuple_1SignatureCVec_1SignatureZZNoneZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ *val = (LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ*)arg;
+       LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ *val = (LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ*)(arg & ~1);
        CHECK(val->result_ok);
-       long res_ref = (long)&(*val->contents.result);
+       long res_ref = (long)(&(*val->contents.result)) | 1;
        return res_ref;
 }
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_LDKCResult_1C2Tuple_1SignatureCVec_1SignatureZZNoneZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ *val = (LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ*)arg;
+       LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ *val = (LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ*)(arg & ~1);
        CHECK(!val->result_ok);
        return *val->contents.err;
 }
@@ -1477,35 +1436,14 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1SignatureNoneZ
        return ((LDKCResult_SignatureNoneZ*)arg)->result_ok;
 }
 JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_LDKCResult_1SignatureNoneZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_SignatureNoneZ *val = (LDKCResult_SignatureNoneZ*)arg;
+       LDKCResult_SignatureNoneZ *val = (LDKCResult_SignatureNoneZ*)(arg & ~1);
        CHECK(val->result_ok);
        int8_tArray res_arr = (*env)->NewByteArray(env, 64);
        (*env)->SetByteArrayRegion(env, res_arr, 0, 64, (*val->contents.result).compact_form);
        return res_arr;
 }
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_LDKCResult_1SignatureNoneZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_SignatureNoneZ *val = (LDKCResult_SignatureNoneZ*)arg;
-       CHECK(!val->result_ok);
-       return *val->contents.err;
-}
-JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1CVec_1SignatureZNoneZ_1result_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       return ((LDKCResult_CVec_SignatureZNoneZ*)arg)->result_ok;
-}
-JNIEXPORT jobjectArray JNICALL Java_org_ldk_impl_bindings_LDKCResult_1CVec_1SignatureZNoneZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_CVec_SignatureZNoneZ *val = (LDKCResult_CVec_SignatureZNoneZ*)arg;
-       CHECK(val->result_ok);
-       LDKCVec_SignatureZ res_var = (*val->contents.result);
-       jobjectArray res_arr = (*env)->NewObjectArray(env, res_var.datalen, arr_of_B_clz, NULL);
-       ;
-       for (size_t i = 0; i < res_var.datalen; i++) {
-               int8_tArray arr_conv_8_arr = (*env)->NewByteArray(env, 64);
-               (*env)->SetByteArrayRegion(env, arr_conv_8_arr, 0, 64, res_var.data[i].compact_form);
-               (*env)->SetObjectArrayElement(env, res_arr, i, arr_conv_8_arr);
-       }
-       return res_arr;
-}
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_LDKCResult_1CVec_1SignatureZNoneZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_CVec_SignatureZNoneZ *val = (LDKCResult_CVec_SignatureZNoneZ*)arg;
+       LDKCResult_SignatureNoneZ *val = (LDKCResult_SignatureNoneZ*)(arg & ~1);
        CHECK(!val->result_ok);
        return *val->contents.err;
 }
@@ -1517,8 +1455,7 @@ typedef struct LDKChannelKeys_JCalls {
        jmethodID release_commitment_secret_meth;
        jmethodID key_derivation_params_meth;
        jmethodID sign_counterparty_commitment_meth;
-       jmethodID sign_holder_commitment_meth;
-       jmethodID sign_holder_commitment_htlc_transactions_meth;
+       jmethodID sign_holder_commitment_and_htlcs_meth;
        jmethodID sign_justice_transaction_meth;
        jmethodID sign_counterparty_htlc_transaction_meth;
        jmethodID sign_closing_transaction_meth;
@@ -1566,7 +1503,7 @@ LDKC2Tuple_u64u64Z key_derivation_params_jcall(const void* this_arg) {
        jobject obj = (*env)->NewLocalRef(env, j_calls->o);
        CHECK(obj != NULL);
        LDKC2Tuple_u64u64Z* ret = (LDKC2Tuple_u64u64Z*)(*env)->CallLongMethod(env, obj, j_calls->key_derivation_params_meth);
-       LDKC2Tuple_u64u64Z ret_conv = *(LDKC2Tuple_u64u64Z*)ret;
+       LDKC2Tuple_u64u64Z ret_conv = *(LDKC2Tuple_u64u64Z*)(((uint64_t)ret) & ~1);
        ret_conv = C2Tuple_u64u64Z_clone((LDKC2Tuple_u64u64Z*)ret);
        return ret_conv;
 }
@@ -1575,8 +1512,7 @@ LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ sign_counterparty_commitment_j
        JNIEnv *env;
        DO_ASSERT((*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_8) == JNI_OK);
        LDKCommitmentTransaction commitment_tx_var = *commitment_tx;
-       if (commitment_tx->inner != NULL)
-               commitment_tx_var = CommitmentTransaction_clone(commitment_tx);
+       commitment_tx_var = CommitmentTransaction_clone(commitment_tx);
        CHECK((((long)commitment_tx_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&commitment_tx_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
        long commitment_tx_ref = (long)commitment_tx_var.inner;
@@ -1586,17 +1522,16 @@ LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ sign_counterparty_commitment_j
        jobject obj = (*env)->NewLocalRef(env, j_calls->o);
        CHECK(obj != NULL);
        LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ* ret = (LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ*)(*env)->CallLongMethod(env, obj, j_calls->sign_counterparty_commitment_meth, commitment_tx_ref);
-       LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ ret_conv = *(LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ*)ret;
+       LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ ret_conv = *(LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ*)(((uint64_t)ret) & ~1);
        ret_conv = CResult_C2Tuple_SignatureCVec_SignatureZZNoneZ_clone((LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ*)ret);
        return ret_conv;
 }
-LDKCResult_SignatureNoneZ sign_holder_commitment_jcall(const void* this_arg, const LDKHolderCommitmentTransaction * commitment_tx) {
+LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ sign_holder_commitment_and_htlcs_jcall(const void* this_arg, const LDKHolderCommitmentTransaction * commitment_tx) {
        LDKChannelKeys_JCalls *j_calls = (LDKChannelKeys_JCalls*) this_arg;
        JNIEnv *env;
        DO_ASSERT((*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_8) == JNI_OK);
        LDKHolderCommitmentTransaction commitment_tx_var = *commitment_tx;
-       if (commitment_tx->inner != NULL)
-               commitment_tx_var = HolderCommitmentTransaction_clone(commitment_tx);
+       commitment_tx_var = HolderCommitmentTransaction_clone(commitment_tx);
        CHECK((((long)commitment_tx_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&commitment_tx_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
        long commitment_tx_ref = (long)commitment_tx_var.inner;
@@ -1605,29 +1540,9 @@ LDKCResult_SignatureNoneZ sign_holder_commitment_jcall(const void* this_arg, con
        }
        jobject obj = (*env)->NewLocalRef(env, j_calls->o);
        CHECK(obj != NULL);
-       LDKCResult_SignatureNoneZ* ret = (LDKCResult_SignatureNoneZ*)(*env)->CallLongMethod(env, obj, j_calls->sign_holder_commitment_meth, commitment_tx_ref);
-       LDKCResult_SignatureNoneZ ret_conv = *(LDKCResult_SignatureNoneZ*)ret;
-       ret_conv = CResult_SignatureNoneZ_clone((LDKCResult_SignatureNoneZ*)ret);
-       return ret_conv;
-}
-LDKCResult_CVec_SignatureZNoneZ sign_holder_commitment_htlc_transactions_jcall(const void* this_arg, const LDKHolderCommitmentTransaction * commitment_tx) {
-       LDKChannelKeys_JCalls *j_calls = (LDKChannelKeys_JCalls*) this_arg;
-       JNIEnv *env;
-       DO_ASSERT((*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_8) == JNI_OK);
-       LDKHolderCommitmentTransaction commitment_tx_var = *commitment_tx;
-       if (commitment_tx->inner != NULL)
-               commitment_tx_var = HolderCommitmentTransaction_clone(commitment_tx);
-       CHECK((((long)commitment_tx_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
-       CHECK((((long)&commitment_tx_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
-       long commitment_tx_ref = (long)commitment_tx_var.inner;
-       if (commitment_tx_var.is_owned) {
-               commitment_tx_ref |= 1;
-       }
-       jobject obj = (*env)->NewLocalRef(env, j_calls->o);
-       CHECK(obj != NULL);
-       LDKCResult_CVec_SignatureZNoneZ* ret = (LDKCResult_CVec_SignatureZNoneZ*)(*env)->CallLongMethod(env, obj, j_calls->sign_holder_commitment_htlc_transactions_meth, commitment_tx_ref);
-       LDKCResult_CVec_SignatureZNoneZ ret_conv = *(LDKCResult_CVec_SignatureZNoneZ*)ret;
-       ret_conv = CResult_CVec_SignatureZNoneZ_clone((LDKCResult_CVec_SignatureZNoneZ*)ret);
+       LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ* ret = (LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ*)(*env)->CallLongMethod(env, obj, j_calls->sign_holder_commitment_and_htlcs_meth, commitment_tx_ref);
+       LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ ret_conv = *(LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ*)(((uint64_t)ret) & ~1);
+       ret_conv = CResult_C2Tuple_SignatureCVec_SignatureZZNoneZ_clone((LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ*)ret);
        return ret_conv;
 }
 LDKCResult_SignatureNoneZ sign_justice_transaction_jcall(const void* this_arg, LDKTransaction justice_tx, uintptr_t input, uint64_t amount, const uint8_t (* per_commitment_key)[32], const LDKHTLCOutputInCommitment * htlc) {
@@ -1641,8 +1556,7 @@ LDKCResult_SignatureNoneZ sign_justice_transaction_jcall(const void* this_arg, L
        int8_tArray per_commitment_key_arr = (*env)->NewByteArray(env, 32);
        (*env)->SetByteArrayRegion(env, per_commitment_key_arr, 0, 32, *per_commitment_key);
        LDKHTLCOutputInCommitment htlc_var = *htlc;
-       if (htlc->inner != NULL)
-               htlc_var = HTLCOutputInCommitment_clone(htlc);
+       htlc_var = HTLCOutputInCommitment_clone(htlc);
        CHECK((((long)htlc_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&htlc_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
        long htlc_ref = (long)htlc_var.inner;
@@ -1652,7 +1566,7 @@ LDKCResult_SignatureNoneZ sign_justice_transaction_jcall(const void* this_arg, L
        jobject obj = (*env)->NewLocalRef(env, j_calls->o);
        CHECK(obj != NULL);
        LDKCResult_SignatureNoneZ* ret = (LDKCResult_SignatureNoneZ*)(*env)->CallLongMethod(env, obj, j_calls->sign_justice_transaction_meth, justice_tx_arr, input, amount, per_commitment_key_arr, htlc_ref);
-       LDKCResult_SignatureNoneZ ret_conv = *(LDKCResult_SignatureNoneZ*)ret;
+       LDKCResult_SignatureNoneZ ret_conv = *(LDKCResult_SignatureNoneZ*)(((uint64_t)ret) & ~1);
        ret_conv = CResult_SignatureNoneZ_clone((LDKCResult_SignatureNoneZ*)ret);
        return ret_conv;
 }
@@ -1667,8 +1581,7 @@ LDKCResult_SignatureNoneZ sign_counterparty_htlc_transaction_jcall(const void* t
        int8_tArray per_commitment_point_arr = (*env)->NewByteArray(env, 33);
        (*env)->SetByteArrayRegion(env, per_commitment_point_arr, 0, 33, per_commitment_point.compressed_form);
        LDKHTLCOutputInCommitment htlc_var = *htlc;
-       if (htlc->inner != NULL)
-               htlc_var = HTLCOutputInCommitment_clone(htlc);
+       htlc_var = HTLCOutputInCommitment_clone(htlc);
        CHECK((((long)htlc_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&htlc_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
        long htlc_ref = (long)htlc_var.inner;
@@ -1678,7 +1591,7 @@ LDKCResult_SignatureNoneZ sign_counterparty_htlc_transaction_jcall(const void* t
        jobject obj = (*env)->NewLocalRef(env, j_calls->o);
        CHECK(obj != NULL);
        LDKCResult_SignatureNoneZ* ret = (LDKCResult_SignatureNoneZ*)(*env)->CallLongMethod(env, obj, j_calls->sign_counterparty_htlc_transaction_meth, htlc_tx_arr, input, amount, per_commitment_point_arr, htlc_ref);
-       LDKCResult_SignatureNoneZ ret_conv = *(LDKCResult_SignatureNoneZ*)ret;
+       LDKCResult_SignatureNoneZ ret_conv = *(LDKCResult_SignatureNoneZ*)(((uint64_t)ret) & ~1);
        ret_conv = CResult_SignatureNoneZ_clone((LDKCResult_SignatureNoneZ*)ret);
        return ret_conv;
 }
@@ -1693,7 +1606,7 @@ LDKCResult_SignatureNoneZ sign_closing_transaction_jcall(const void* this_arg, L
        jobject obj = (*env)->NewLocalRef(env, j_calls->o);
        CHECK(obj != NULL);
        LDKCResult_SignatureNoneZ* ret = (LDKCResult_SignatureNoneZ*)(*env)->CallLongMethod(env, obj, j_calls->sign_closing_transaction_meth, closing_tx_arr);
-       LDKCResult_SignatureNoneZ ret_conv = *(LDKCResult_SignatureNoneZ*)ret;
+       LDKCResult_SignatureNoneZ ret_conv = *(LDKCResult_SignatureNoneZ*)(((uint64_t)ret) & ~1);
        ret_conv = CResult_SignatureNoneZ_clone((LDKCResult_SignatureNoneZ*)ret);
        return ret_conv;
 }
@@ -1702,8 +1615,7 @@ LDKCResult_SignatureNoneZ sign_channel_announcement_jcall(const void* this_arg,
        JNIEnv *env;
        DO_ASSERT((*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_8) == JNI_OK);
        LDKUnsignedChannelAnnouncement msg_var = *msg;
-       if (msg->inner != NULL)
-               msg_var = UnsignedChannelAnnouncement_clone(msg);
+       msg_var = UnsignedChannelAnnouncement_clone(msg);
        CHECK((((long)msg_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&msg_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
        long msg_ref = (long)msg_var.inner;
@@ -1713,7 +1625,7 @@ LDKCResult_SignatureNoneZ sign_channel_announcement_jcall(const void* this_arg,
        jobject obj = (*env)->NewLocalRef(env, j_calls->o);
        CHECK(obj != NULL);
        LDKCResult_SignatureNoneZ* ret = (LDKCResult_SignatureNoneZ*)(*env)->CallLongMethod(env, obj, j_calls->sign_channel_announcement_meth, msg_ref);
-       LDKCResult_SignatureNoneZ ret_conv = *(LDKCResult_SignatureNoneZ*)ret;
+       LDKCResult_SignatureNoneZ ret_conv = *(LDKCResult_SignatureNoneZ*)(((uint64_t)ret) & ~1);
        ret_conv = CResult_SignatureNoneZ_clone((LDKCResult_SignatureNoneZ*)ret);
        return ret_conv;
 }
@@ -1722,8 +1634,7 @@ void ready_channel_jcall(void* this_arg, const LDKChannelTransactionParameters *
        JNIEnv *env;
        DO_ASSERT((*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_8) == JNI_OK);
        LDKChannelTransactionParameters channel_parameters_var = *channel_parameters;
-       if (channel_parameters->inner != NULL)
-               channel_parameters_var = ChannelTransactionParameters_clone(channel_parameters);
+       channel_parameters_var = ChannelTransactionParameters_clone(channel_parameters);
        CHECK((((long)channel_parameters_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&channel_parameters_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
        long channel_parameters_ref = (long)channel_parameters_var.inner;
@@ -1767,10 +1678,8 @@ static inline LDKChannelKeys LDKChannelKeys_init (JNIEnv *env, jclass clz, jobje
        CHECK(calls->key_derivation_params_meth != NULL);
        calls->sign_counterparty_commitment_meth = (*env)->GetMethodID(env, c, "sign_counterparty_commitment", "(J)J");
        CHECK(calls->sign_counterparty_commitment_meth != NULL);
-       calls->sign_holder_commitment_meth = (*env)->GetMethodID(env, c, "sign_holder_commitment", "(J)J");
-       CHECK(calls->sign_holder_commitment_meth != NULL);
-       calls->sign_holder_commitment_htlc_transactions_meth = (*env)->GetMethodID(env, c, "sign_holder_commitment_htlc_transactions", "(J)J");
-       CHECK(calls->sign_holder_commitment_htlc_transactions_meth != NULL);
+       calls->sign_holder_commitment_and_htlcs_meth = (*env)->GetMethodID(env, c, "sign_holder_commitment_and_htlcs", "(J)J");
+       CHECK(calls->sign_holder_commitment_and_htlcs_meth != NULL);
        calls->sign_justice_transaction_meth = (*env)->GetMethodID(env, c, "sign_justice_transaction", "([BJJ[BJ)J");
        CHECK(calls->sign_justice_transaction_meth != NULL);
        calls->sign_counterparty_htlc_transaction_meth = (*env)->GetMethodID(env, c, "sign_counterparty_htlc_transaction", "([BJJ[BJ)J");
@@ -1787,8 +1696,7 @@ static inline LDKChannelKeys LDKChannelKeys_init (JNIEnv *env, jclass clz, jobje
        LDKChannelPublicKeys pubkeys_conv;
        pubkeys_conv.inner = (void*)(pubkeys & (~1));
        pubkeys_conv.is_owned = (pubkeys & 1) || (pubkeys == 0);
-       if (pubkeys_conv.inner != NULL)
-               pubkeys_conv = ChannelPublicKeys_clone(&pubkeys_conv);
+       pubkeys_conv = ChannelPublicKeys_clone(&pubkeys_conv);
 
        LDKChannelKeys ret = {
                .this_arg = (void*) calls,
@@ -1796,8 +1704,7 @@ static inline LDKChannelKeys LDKChannelKeys_init (JNIEnv *env, jclass clz, jobje
                .release_commitment_secret = release_commitment_secret_jcall,
                .key_derivation_params = key_derivation_params_jcall,
                .sign_counterparty_commitment = sign_counterparty_commitment_jcall,
-               .sign_holder_commitment = sign_holder_commitment_jcall,
-               .sign_holder_commitment_htlc_transactions = sign_holder_commitment_htlc_transactions_jcall,
+               .sign_holder_commitment_and_htlcs = sign_holder_commitment_and_htlcs_jcall,
                .sign_justice_transaction = sign_justice_transaction_jcall,
                .sign_counterparty_htlc_transaction = sign_counterparty_htlc_transaction_jcall,
                .sign_closing_transaction = sign_closing_transaction_jcall,
@@ -1847,23 +1754,13 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ChannelKeys_1sign_1counterp
        return (long)ret_conv;
 }
 
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ChannelKeys_1sign_1holder_1commitment(JNIEnv *env, jclass clz, int64_t this_arg, int64_t commitment_tx) {
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ChannelKeys_1sign_1holder_1commitment_1and_1htlcs(JNIEnv *env, jclass clz, int64_t this_arg, int64_t commitment_tx) {
        LDKChannelKeys* this_arg_conv = (LDKChannelKeys*)this_arg;
        LDKHolderCommitmentTransaction commitment_tx_conv;
        commitment_tx_conv.inner = (void*)(commitment_tx & (~1));
        commitment_tx_conv.is_owned = false;
-       LDKCResult_SignatureNoneZ* ret_conv = MALLOC(sizeof(LDKCResult_SignatureNoneZ), "LDKCResult_SignatureNoneZ");
-       *ret_conv = (this_arg_conv->sign_holder_commitment)(this_arg_conv->this_arg, &commitment_tx_conv);
-       return (long)ret_conv;
-}
-
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ChannelKeys_1sign_1holder_1commitment_1htlc_1transactions(JNIEnv *env, jclass clz, int64_t this_arg, int64_t commitment_tx) {
-       LDKChannelKeys* this_arg_conv = (LDKChannelKeys*)this_arg;
-       LDKHolderCommitmentTransaction commitment_tx_conv;
-       commitment_tx_conv.inner = (void*)(commitment_tx & (~1));
-       commitment_tx_conv.is_owned = false;
-       LDKCResult_CVec_SignatureZNoneZ* ret_conv = MALLOC(sizeof(LDKCResult_CVec_SignatureZNoneZ), "LDKCResult_CVec_SignatureZNoneZ");
-       *ret_conv = (this_arg_conv->sign_holder_commitment_htlc_transactions)(this_arg_conv->this_arg, &commitment_tx_conv);
+       LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ* ret_conv = MALLOC(sizeof(LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ), "LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ");
+       *ret_conv = (this_arg_conv->sign_holder_commitment_and_htlcs)(this_arg_conv->this_arg, &commitment_tx_conv);
        return (long)ret_conv;
 }
 
@@ -1969,18 +1866,18 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKC2Tuple_1BlockHashChanne
        LDKChannelMonitor b_conv;
        b_conv.inner = (void*)(b & (~1));
        b_conv.is_owned = (b & 1) || (b == 0);
-       // Warning: we may need a move here but can't clone!
+       b_conv = ChannelMonitor_clone(&b_conv);
        ret->b = b_conv;
        return (long)ret;
 }
 JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_LDKC2Tuple_1BlockHashChannelMonitorZ_1get_1a(JNIEnv *env, jclass clz, int64_t ptr) {
-       LDKC2Tuple_BlockHashChannelMonitorZ *tuple = (LDKC2Tuple_BlockHashChannelMonitorZ*)ptr;
+       LDKC2Tuple_BlockHashChannelMonitorZ *tuple = (LDKC2Tuple_BlockHashChannelMonitorZ*)(ptr & ~1);
        int8_tArray a_arr = (*env)->NewByteArray(env, 32);
        (*env)->SetByteArrayRegion(env, a_arr, 0, 32, tuple->a.data);
        return a_arr;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKC2Tuple_1BlockHashChannelMonitorZ_1get_1b(JNIEnv *env, jclass clz, int64_t ptr) {
-       LDKC2Tuple_BlockHashChannelMonitorZ *tuple = (LDKC2Tuple_BlockHashChannelMonitorZ*)ptr;
+       LDKC2Tuple_BlockHashChannelMonitorZ *tuple = (LDKC2Tuple_BlockHashChannelMonitorZ*)(ptr & ~1);
        LDKChannelMonitor b_var = tuple->b;
        CHECK((((long)b_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&b_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
@@ -1991,13 +1888,13 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1C2Tuple_1Block
        return ((LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ*)arg)->result_ok;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1C2Tuple_1BlockHashChannelMonitorZDecodeErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ *val = (LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ*)arg;
+       LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ *val = (LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ*)(arg & ~1);
        CHECK(val->result_ok);
-       long res_ref = (long)&(*val->contents.result);
+       long res_ref = (long)(&(*val->contents.result)) | 1;
        return res_ref;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1C2Tuple_1BlockHashChannelMonitorZDecodeErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ *val = (LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ*)arg;
+       LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ *val = (LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ*)(arg & ~1);
        CHECK(!val->result_ok);
        LDKDecodeError err_var = (*val->contents.err);
        CHECK((((long)err_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -2009,13 +1906,13 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1SpendableOutpu
        return ((LDKCResult_SpendableOutputDescriptorDecodeErrorZ*)arg)->result_ok;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1SpendableOutputDescriptorDecodeErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_SpendableOutputDescriptorDecodeErrorZ *val = (LDKCResult_SpendableOutputDescriptorDecodeErrorZ*)arg;
+       LDKCResult_SpendableOutputDescriptorDecodeErrorZ *val = (LDKCResult_SpendableOutputDescriptorDecodeErrorZ*)(arg & ~1);
        CHECK(val->result_ok);
-       long res_ref = (long)&(*val->contents.result);
+       long res_ref = ((long)&(*val->contents.result)) | 1;
        return res_ref;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1SpendableOutputDescriptorDecodeErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_SpendableOutputDescriptorDecodeErrorZ *val = (LDKCResult_SpendableOutputDescriptorDecodeErrorZ*)arg;
+       LDKCResult_SpendableOutputDescriptorDecodeErrorZ *val = (LDKCResult_SpendableOutputDescriptorDecodeErrorZ*)(arg & ~1);
        CHECK(!val->result_ok);
        LDKDecodeError err_var = (*val->contents.err);
        CHECK((((long)err_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -2027,14 +1924,14 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1ChanKeySignerD
        return ((LDKCResult_ChanKeySignerDecodeErrorZ*)arg)->result_ok;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1ChanKeySignerDecodeErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_ChanKeySignerDecodeErrorZ *val = (LDKCResult_ChanKeySignerDecodeErrorZ*)arg;
+       LDKCResult_ChanKeySignerDecodeErrorZ *val = (LDKCResult_ChanKeySignerDecodeErrorZ*)(arg & ~1);
        CHECK(val->result_ok);
        LDKChannelKeys* ret = MALLOC(sizeof(LDKChannelKeys), "LDKChannelKeys");
-       *ret = (*val->contents.result);
+       *ret = ChannelKeys_clone(&(*val->contents.result));
        return (long)ret;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1ChanKeySignerDecodeErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_ChanKeySignerDecodeErrorZ *val = (LDKCResult_ChanKeySignerDecodeErrorZ*)arg;
+       LDKCResult_ChanKeySignerDecodeErrorZ *val = (LDKCResult_ChanKeySignerDecodeErrorZ*)(arg & ~1);
        CHECK(!val->result_ok);
        LDKDecodeError err_var = (*val->contents.err);
        CHECK((((long)err_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -2046,7 +1943,7 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1InMemoryChanne
        return ((LDKCResult_InMemoryChannelKeysDecodeErrorZ*)arg)->result_ok;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1InMemoryChannelKeysDecodeErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_InMemoryChannelKeysDecodeErrorZ *val = (LDKCResult_InMemoryChannelKeysDecodeErrorZ*)arg;
+       LDKCResult_InMemoryChannelKeysDecodeErrorZ *val = (LDKCResult_InMemoryChannelKeysDecodeErrorZ*)(arg & ~1);
        CHECK(val->result_ok);
        LDKInMemoryChannelKeys res_var = (*val->contents.result);
        CHECK((((long)res_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -2055,7 +1952,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1InMemoryChannel
        return res_ref;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1InMemoryChannelKeysDecodeErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_InMemoryChannelKeysDecodeErrorZ *val = (LDKCResult_InMemoryChannelKeysDecodeErrorZ*)arg;
+       LDKCResult_InMemoryChannelKeysDecodeErrorZ *val = (LDKCResult_InMemoryChannelKeysDecodeErrorZ*)(arg & ~1);
        CHECK(!val->result_ok);
        LDKDecodeError err_var = (*val->contents.err);
        CHECK((((long)err_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -2067,30 +1964,17 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1TxOutAccessErr
        return ((LDKCResult_TxOutAccessErrorZ*)arg)->result_ok;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1TxOutAccessErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_TxOutAccessErrorZ *val = (LDKCResult_TxOutAccessErrorZ*)arg;
+       LDKCResult_TxOutAccessErrorZ *val = (LDKCResult_TxOutAccessErrorZ*)(arg & ~1);
        CHECK(val->result_ok);
-       long res_ref = (long)&(*val->contents.result);
+       long res_ref = ((long)&(*val->contents.result)) | 1;
        return (long)res_ref;
 }
 JNIEXPORT jclass JNICALL Java_org_ldk_impl_bindings_LDKCResult_1TxOutAccessErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_TxOutAccessErrorZ *val = (LDKCResult_TxOutAccessErrorZ*)arg;
+       LDKCResult_TxOutAccessErrorZ *val = (LDKCResult_TxOutAccessErrorZ*)(arg & ~1);
        CHECK(!val->result_ok);
        jclass err_conv = LDKAccessError_to_java(env, (*val->contents.err));
        return err_conv;
 }
-static inline LDKCResult_TxOutAccessErrorZ CResult_TxOutAccessErrorZ_clone(const LDKCResult_TxOutAccessErrorZ *orig) {
-       LDKCResult_TxOutAccessErrorZ res = { .result_ok = orig->result_ok };
-       if (orig->result_ok) {
-               LDKTxOut* contents = MALLOC(sizeof(LDKTxOut), "LDKTxOut result OK clone");
-               *contents = TxOut_clone(orig->contents.result);
-               res.contents.result = contents;
-       } else {
-               LDKAccessError* contents = MALLOC(sizeof(LDKAccessError), "LDKAccessError result Err clone");
-               *contents = AccessError_clone(orig->contents.err);
-               res.contents.err = contents;
-       }
-       return res;
-}
 static jclass LDKAPIError_APIMisuseError_class = NULL;
 static jmethodID LDKAPIError_APIMisuseError_meth = NULL;
 static jclass LDKAPIError_FeeRateTooHigh_class = NULL;
@@ -2164,27 +2048,16 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1NoneAPIErrorZ_
        return ((LDKCResult_NoneAPIErrorZ*)arg)->result_ok;
 }
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_LDKCResult_1NoneAPIErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_NoneAPIErrorZ *val = (LDKCResult_NoneAPIErrorZ*)arg;
+       LDKCResult_NoneAPIErrorZ *val = (LDKCResult_NoneAPIErrorZ*)(arg & ~1);
        CHECK(val->result_ok);
        return *val->contents.result;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1NoneAPIErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_NoneAPIErrorZ *val = (LDKCResult_NoneAPIErrorZ*)arg;
+       LDKCResult_NoneAPIErrorZ *val = (LDKCResult_NoneAPIErrorZ*)(arg & ~1);
        CHECK(!val->result_ok);
-       long err_ref = (long)&(*val->contents.err);
+       long err_ref = ((long)&(*val->contents.err)) | 1;
        return err_ref;
 }
-static inline LDKCResult_NoneAPIErrorZ CResult_NoneAPIErrorZ_clone(const LDKCResult_NoneAPIErrorZ *orig) {
-       LDKCResult_NoneAPIErrorZ res = { .result_ok = orig->result_ok };
-       if (orig->result_ok) {
-               res.contents.result = NULL;
-       } else {
-               LDKAPIError* contents = MALLOC(sizeof(LDKAPIError), "LDKAPIError result Err clone");
-               *contents = APIError_clone(orig->contents.err);
-               res.contents.err = contents;
-       }
-       return res;
-}
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCVec_1ChannelDetailsZ_1new(JNIEnv *env, jclass clz, int64_tArray elems) {
        LDKCVec_ChannelDetailsZ *ret = MALLOC(sizeof(LDKCVec_ChannelDetailsZ), "LDKCVec_ChannelDetailsZ");
        ret->datalen = (*env)->GetArrayLength(env, elems);
@@ -2198,8 +2071,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCVec_1ChannelDetailsZ_1n
                        LDKChannelDetails arr_elem_conv;
                        arr_elem_conv.inner = (void*)(arr_elem & (~1));
                        arr_elem_conv.is_owned = (arr_elem & 1) || (arr_elem == 0);
-                       if (arr_elem_conv.inner != NULL)
-                               arr_elem_conv = ChannelDetails_clone(&arr_elem_conv);
+                       arr_elem_conv = ChannelDetails_clone(&arr_elem_conv);
                        ret->data[i] = arr_elem_conv;
                }
                (*env)->ReleasePrimitiveArrayCritical(env, elems, java_elems, 0);
@@ -2217,12 +2089,12 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1NonePaymentSen
        return ((LDKCResult_NonePaymentSendFailureZ*)arg)->result_ok;
 }
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_LDKCResult_1NonePaymentSendFailureZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_NonePaymentSendFailureZ *val = (LDKCResult_NonePaymentSendFailureZ*)arg;
+       LDKCResult_NonePaymentSendFailureZ *val = (LDKCResult_NonePaymentSendFailureZ*)(arg & ~1);
        CHECK(val->result_ok);
        return *val->contents.result;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1NonePaymentSendFailureZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_NonePaymentSendFailureZ *val = (LDKCResult_NonePaymentSendFailureZ*)arg;
+       LDKCResult_NonePaymentSendFailureZ *val = (LDKCResult_NonePaymentSendFailureZ*)(arg & ~1);
        CHECK(!val->result_ok);
        LDKPaymentSendFailure err_var = (*val->contents.err);
        CHECK((((long)err_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -2296,7 +2168,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCVec_1NetAddressZ_1new(J
                int64_t *java_elems = (*env)->GetPrimitiveArrayCritical(env, elems, NULL);
                for (size_t i = 0; i < ret->datalen; i++) {
                        int64_t arr_elem = java_elems[i];
-                       LDKNetAddress arr_elem_conv = *(LDKNetAddress*)arr_elem;
+                       LDKNetAddress arr_elem_conv = *(LDKNetAddress*)(((uint64_t)arr_elem) & ~1);
                        FREE((void*)arr_elem);
                        ret->data[i] = arr_elem_conv;
                }
@@ -2324,13 +2196,20 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCVec_1ChannelMonitorZ_1n
                        LDKChannelMonitor arr_elem_conv;
                        arr_elem_conv.inner = (void*)(arr_elem & (~1));
                        arr_elem_conv.is_owned = (arr_elem & 1) || (arr_elem == 0);
-                       // Warning: we may need a move here but can't clone!
+                       arr_elem_conv = ChannelMonitor_clone(&arr_elem_conv);
                        ret->data[i] = arr_elem_conv;
                }
                (*env)->ReleasePrimitiveArrayCritical(env, elems, java_elems, 0);
        }
        return (long)ret;
 }
+static inline LDKCVec_ChannelMonitorZ CVec_ChannelMonitorZ_clone(const LDKCVec_ChannelMonitorZ *orig) {
+       LDKCVec_ChannelMonitorZ ret = { .data = MALLOC(sizeof(LDKChannelMonitor) * orig->datalen, "LDKCVec_ChannelMonitorZ clone bytes"), .datalen = orig->datalen };
+       for (size_t i = 0; i < ret.datalen; i++) {
+               ret.data[i] = ChannelMonitor_clone(&orig->data[i]);
+       }
+       return ret;
+}
 typedef struct LDKWatch_JCalls {
        atomic_size_t refcnt;
        JavaVM *vm;
@@ -2369,7 +2248,7 @@ LDKCResult_NoneChannelMonitorUpdateErrZ watch_channel_jcall(const void* this_arg
        jobject obj = (*env)->NewLocalRef(env, j_calls->o);
        CHECK(obj != NULL);
        LDKCResult_NoneChannelMonitorUpdateErrZ* ret = (LDKCResult_NoneChannelMonitorUpdateErrZ*)(*env)->CallLongMethod(env, obj, j_calls->watch_channel_meth, funding_txo_ref, monitor_ref);
-       LDKCResult_NoneChannelMonitorUpdateErrZ ret_conv = *(LDKCResult_NoneChannelMonitorUpdateErrZ*)ret;
+       LDKCResult_NoneChannelMonitorUpdateErrZ ret_conv = *(LDKCResult_NoneChannelMonitorUpdateErrZ*)(((uint64_t)ret) & ~1);
        ret_conv = CResult_NoneChannelMonitorUpdateErrZ_clone((LDKCResult_NoneChannelMonitorUpdateErrZ*)ret);
        return ret_conv;
 }
@@ -2394,7 +2273,7 @@ LDKCResult_NoneChannelMonitorUpdateErrZ update_channel_jcall(const void* this_ar
        jobject obj = (*env)->NewLocalRef(env, j_calls->o);
        CHECK(obj != NULL);
        LDKCResult_NoneChannelMonitorUpdateErrZ* ret = (LDKCResult_NoneChannelMonitorUpdateErrZ*)(*env)->CallLongMethod(env, obj, j_calls->update_channel_meth, funding_txo_ref, update_ref);
-       LDKCResult_NoneChannelMonitorUpdateErrZ ret_conv = *(LDKCResult_NoneChannelMonitorUpdateErrZ*)ret;
+       LDKCResult_NoneChannelMonitorUpdateErrZ ret_conv = *(LDKCResult_NoneChannelMonitorUpdateErrZ*)(((uint64_t)ret) & ~1);
        ret_conv = CResult_NoneChannelMonitorUpdateErrZ_clone((LDKCResult_NoneChannelMonitorUpdateErrZ*)ret);
        return ret_conv;
 }
@@ -2417,8 +2296,7 @@ LDKCVec_MonitorEventZ release_pending_monitor_events_jcall(const void* this_arg)
                LDKMonitorEvent arr_conv_14_conv;
                arr_conv_14_conv.inner = (void*)(arr_conv_14 & (~1));
                arr_conv_14_conv.is_owned = (arr_conv_14 & 1) || (arr_conv_14 == 0);
-               if (arr_conv_14_conv.inner != NULL)
-                       arr_conv_14_conv = MonitorEvent_clone(&arr_conv_14_conv);
+               arr_conv_14_conv = MonitorEvent_clone(&arr_conv_14_conv);
                arg_constr.data[o] = arr_conv_14_conv;
        }
        (*env)->ReleaseLongArrayElements(env, arg, arg_vals, 0);
@@ -2462,12 +2340,11 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Watch_1watch_1channel(JNIEn
        LDKOutPoint funding_txo_conv;
        funding_txo_conv.inner = (void*)(funding_txo & (~1));
        funding_txo_conv.is_owned = (funding_txo & 1) || (funding_txo == 0);
-       if (funding_txo_conv.inner != NULL)
-               funding_txo_conv = OutPoint_clone(&funding_txo_conv);
+       funding_txo_conv = OutPoint_clone(&funding_txo_conv);
        LDKChannelMonitor monitor_conv;
        monitor_conv.inner = (void*)(monitor & (~1));
        monitor_conv.is_owned = (monitor & 1) || (monitor == 0);
-       // Warning: we may need a move here but can't clone!
+       monitor_conv = ChannelMonitor_clone(&monitor_conv);
        LDKCResult_NoneChannelMonitorUpdateErrZ* ret_conv = MALLOC(sizeof(LDKCResult_NoneChannelMonitorUpdateErrZ), "LDKCResult_NoneChannelMonitorUpdateErrZ");
        *ret_conv = (this_arg_conv->watch_channel)(this_arg_conv->this_arg, funding_txo_conv, monitor_conv);
        return (long)ret_conv;
@@ -2478,13 +2355,11 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Watch_1update_1channel(JNIE
        LDKOutPoint funding_txo_conv;
        funding_txo_conv.inner = (void*)(funding_txo & (~1));
        funding_txo_conv.is_owned = (funding_txo & 1) || (funding_txo == 0);
-       if (funding_txo_conv.inner != NULL)
-               funding_txo_conv = OutPoint_clone(&funding_txo_conv);
+       funding_txo_conv = OutPoint_clone(&funding_txo_conv);
        LDKChannelMonitorUpdate update_conv;
        update_conv.inner = (void*)(update & (~1));
        update_conv.is_owned = (update & 1) || (update == 0);
-       if (update_conv.inner != NULL)
-               update_conv = ChannelMonitorUpdate_clone(&update_conv);
+       update_conv = ChannelMonitorUpdate_clone(&update_conv);
        LDKCResult_NoneChannelMonitorUpdateErrZ* ret_conv = MALLOC(sizeof(LDKCResult_NoneChannelMonitorUpdateErrZ), "LDKCResult_NoneChannelMonitorUpdateErrZ");
        *ret_conv = (this_arg_conv->update_channel)(this_arg_conv->this_arg, funding_txo_conv, update_conv);
        return (long)ret_conv;
@@ -2638,7 +2513,7 @@ LDKChannelKeys get_channel_keys_jcall(const void* this_arg, bool inbound, uint64
        jobject obj = (*env)->NewLocalRef(env, j_calls->o);
        CHECK(obj != NULL);
        LDKChannelKeys* ret = (LDKChannelKeys*)(*env)->CallLongMethod(env, obj, j_calls->get_channel_keys_meth, inbound, channel_value_satoshis);
-       LDKChannelKeys ret_conv = *(LDKChannelKeys*)ret;
+       LDKChannelKeys ret_conv = *(LDKChannelKeys*)(((uint64_t)ret) & ~1);
        ret_conv = ChannelKeys_clone(ret);
        return ret_conv;
 }
@@ -2664,8 +2539,8 @@ LDKCResult_ChanKeySignerDecodeErrorZ read_chan_signer_jcall(const void* this_arg
        jobject obj = (*env)->NewLocalRef(env, j_calls->o);
        CHECK(obj != NULL);
        LDKCResult_ChanKeySignerDecodeErrorZ* ret = (LDKCResult_ChanKeySignerDecodeErrorZ*)(*env)->CallLongMethod(env, obj, j_calls->read_chan_signer_meth, reader_arr);
-       LDKCResult_ChanKeySignerDecodeErrorZ ret_conv = *(LDKCResult_ChanKeySignerDecodeErrorZ*)ret;
-       // Warning: we may need a move here but can't do a full clone!
+       LDKCResult_ChanKeySignerDecodeErrorZ ret_conv = *(LDKCResult_ChanKeySignerDecodeErrorZ*)(((uint64_t)ret) & ~1);
+       ret_conv = CResult_ChanKeySignerDecodeErrorZ_clone((LDKCResult_ChanKeySignerDecodeErrorZ*)ret);
        return ret_conv;
 }
 static void* LDKKeysInterface_JCalls_clone(const void* this_arg) {
@@ -2877,18 +2752,18 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKC2Tuple_1BlockHashChanne
        LDKChannelManager b_conv;
        b_conv.inner = (void*)(b & (~1));
        b_conv.is_owned = (b & 1) || (b == 0);
-       // Warning: we may need a move here but can't clone!
+       // Warning: we need a move here but no clone is available for LDKChannelManager
        ret->b = b_conv;
        return (long)ret;
 }
 JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_LDKC2Tuple_1BlockHashChannelManagerZ_1get_1a(JNIEnv *env, jclass clz, int64_t ptr) {
-       LDKC2Tuple_BlockHashChannelManagerZ *tuple = (LDKC2Tuple_BlockHashChannelManagerZ*)ptr;
+       LDKC2Tuple_BlockHashChannelManagerZ *tuple = (LDKC2Tuple_BlockHashChannelManagerZ*)(ptr & ~1);
        int8_tArray a_arr = (*env)->NewByteArray(env, 32);
        (*env)->SetByteArrayRegion(env, a_arr, 0, 32, tuple->a.data);
        return a_arr;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKC2Tuple_1BlockHashChannelManagerZ_1get_1b(JNIEnv *env, jclass clz, int64_t ptr) {
-       LDKC2Tuple_BlockHashChannelManagerZ *tuple = (LDKC2Tuple_BlockHashChannelManagerZ*)ptr;
+       LDKC2Tuple_BlockHashChannelManagerZ *tuple = (LDKC2Tuple_BlockHashChannelManagerZ*)(ptr & ~1);
        LDKChannelManager b_var = tuple->b;
        CHECK((((long)b_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&b_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
@@ -2899,13 +2774,13 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1C2Tuple_1Block
        return ((LDKCResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ*)arg)->result_ok;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1C2Tuple_1BlockHashChannelManagerZDecodeErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ *val = (LDKCResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ*)arg;
+       LDKCResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ *val = (LDKCResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ*)(arg & ~1);
        CHECK(val->result_ok);
-       long res_ref = (long)&(*val->contents.result);
+       long res_ref = (long)(&(*val->contents.result)) | 1;
        return res_ref;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1C2Tuple_1BlockHashChannelManagerZDecodeErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ *val = (LDKCResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ*)arg;
+       LDKCResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ *val = (LDKCResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ*)(arg & ~1);
        CHECK(!val->result_ok);
        LDKDecodeError err_var = (*val->contents.err);
        CHECK((((long)err_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -2917,34 +2792,21 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1NetAddressu8Z_
        return ((LDKCResult_NetAddressu8Z*)arg)->result_ok;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1NetAddressu8Z_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_NetAddressu8Z *val = (LDKCResult_NetAddressu8Z*)arg;
+       LDKCResult_NetAddressu8Z *val = (LDKCResult_NetAddressu8Z*)(arg & ~1);
        CHECK(val->result_ok);
-       long res_ref = (long)&(*val->contents.result);
+       long res_ref = ((long)&(*val->contents.result)) | 1;
        return res_ref;
 }
 JNIEXPORT int8_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1NetAddressu8Z_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_NetAddressu8Z *val = (LDKCResult_NetAddressu8Z*)arg;
+       LDKCResult_NetAddressu8Z *val = (LDKCResult_NetAddressu8Z*)(arg & ~1);
        CHECK(!val->result_ok);
        return *val->contents.err;
 }
-static inline LDKCResult_NetAddressu8Z CResult_NetAddressu8Z_clone(const LDKCResult_NetAddressu8Z *orig) {
-       LDKCResult_NetAddressu8Z res = { .result_ok = orig->result_ok };
-       if (orig->result_ok) {
-               LDKNetAddress* contents = MALLOC(sizeof(LDKNetAddress), "LDKNetAddress result OK clone");
-               *contents = NetAddress_clone(orig->contents.result);
-               res.contents.result = contents;
-       } else {
-               int8_t* contents = MALLOC(sizeof(int8_t), "int8_t result Err clone");
-               *contents = *orig->contents.err;
-               res.contents.err = contents;
-       }
-       return res;
-}
 JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1CResult_1NetAddressu8ZDecodeErrorZ_1result_1ok(JNIEnv *env, jclass clz, int64_t arg) {
        return ((LDKCResult_CResult_NetAddressu8ZDecodeErrorZ*)arg)->result_ok;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1CResult_1NetAddressu8ZDecodeErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_CResult_NetAddressu8ZDecodeErrorZ *val = (LDKCResult_CResult_NetAddressu8ZDecodeErrorZ*)arg;
+       LDKCResult_CResult_NetAddressu8ZDecodeErrorZ *val = (LDKCResult_CResult_NetAddressu8ZDecodeErrorZ*)(arg & ~1);
        CHECK(val->result_ok);
        LDKCResult_NetAddressu8Z* res_conv = MALLOC(sizeof(LDKCResult_NetAddressu8Z), "LDKCResult_NetAddressu8Z");
        *res_conv = (*val->contents.result);
@@ -2952,7 +2814,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1CResult_1NetAdd
        return (long)res_conv;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1CResult_1NetAddressu8ZDecodeErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_CResult_NetAddressu8ZDecodeErrorZ *val = (LDKCResult_CResult_NetAddressu8ZDecodeErrorZ*)arg;
+       LDKCResult_CResult_NetAddressu8ZDecodeErrorZ *val = (LDKCResult_CResult_NetAddressu8ZDecodeErrorZ*)(arg & ~1);
        CHECK(!val->result_ok);
        LDKDecodeError err_var = (*val->contents.err);
        CHECK((((long)err_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -2993,8 +2855,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCVec_1UpdateAddHTLCZ_1ne
                        LDKUpdateAddHTLC arr_elem_conv;
                        arr_elem_conv.inner = (void*)(arr_elem & (~1));
                        arr_elem_conv.is_owned = (arr_elem & 1) || (arr_elem == 0);
-                       if (arr_elem_conv.inner != NULL)
-                               arr_elem_conv = UpdateAddHTLC_clone(&arr_elem_conv);
+                       arr_elem_conv = UpdateAddHTLC_clone(&arr_elem_conv);
                        ret->data[i] = arr_elem_conv;
                }
                (*env)->ReleasePrimitiveArrayCritical(env, elems, java_elems, 0);
@@ -3021,8 +2882,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCVec_1UpdateFulfillHTLCZ
                        LDKUpdateFulfillHTLC arr_elem_conv;
                        arr_elem_conv.inner = (void*)(arr_elem & (~1));
                        arr_elem_conv.is_owned = (arr_elem & 1) || (arr_elem == 0);
-                       if (arr_elem_conv.inner != NULL)
-                               arr_elem_conv = UpdateFulfillHTLC_clone(&arr_elem_conv);
+                       arr_elem_conv = UpdateFulfillHTLC_clone(&arr_elem_conv);
                        ret->data[i] = arr_elem_conv;
                }
                (*env)->ReleasePrimitiveArrayCritical(env, elems, java_elems, 0);
@@ -3049,8 +2909,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCVec_1UpdateFailHTLCZ_1n
                        LDKUpdateFailHTLC arr_elem_conv;
                        arr_elem_conv.inner = (void*)(arr_elem & (~1));
                        arr_elem_conv.is_owned = (arr_elem & 1) || (arr_elem == 0);
-                       if (arr_elem_conv.inner != NULL)
-                               arr_elem_conv = UpdateFailHTLC_clone(&arr_elem_conv);
+                       arr_elem_conv = UpdateFailHTLC_clone(&arr_elem_conv);
                        ret->data[i] = arr_elem_conv;
                }
                (*env)->ReleasePrimitiveArrayCritical(env, elems, java_elems, 0);
@@ -3077,8 +2936,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCVec_1UpdateFailMalforme
                        LDKUpdateFailMalformedHTLC arr_elem_conv;
                        arr_elem_conv.inner = (void*)(arr_elem & (~1));
                        arr_elem_conv.is_owned = (arr_elem & 1) || (arr_elem == 0);
-                       if (arr_elem_conv.inner != NULL)
-                               arr_elem_conv = UpdateFailMalformedHTLC_clone(&arr_elem_conv);
+                       arr_elem_conv = UpdateFailMalformedHTLC_clone(&arr_elem_conv);
                        ret->data[i] = arr_elem_conv;
                }
                (*env)->ReleasePrimitiveArrayCritical(env, elems, java_elems, 0);
@@ -3096,12 +2954,12 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1boolLightningE
        return ((LDKCResult_boolLightningErrorZ*)arg)->result_ok;
 }
 JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1boolLightningErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_boolLightningErrorZ *val = (LDKCResult_boolLightningErrorZ*)arg;
+       LDKCResult_boolLightningErrorZ *val = (LDKCResult_boolLightningErrorZ*)(arg & ~1);
        CHECK(val->result_ok);
        return *val->contents.result;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1boolLightningErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_boolLightningErrorZ *val = (LDKCResult_boolLightningErrorZ*)arg;
+       LDKCResult_boolLightningErrorZ *val = (LDKCResult_boolLightningErrorZ*)(arg & ~1);
        CHECK(!val->result_ok);
        LDKLightningError err_var = (*val->contents.err);
        CHECK((((long)err_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3114,33 +2972,22 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKC3Tuple_1ChannelAnnounce
        LDKChannelAnnouncement a_conv;
        a_conv.inner = (void*)(a & (~1));
        a_conv.is_owned = (a & 1) || (a == 0);
-       if (a_conv.inner != NULL)
-               a_conv = ChannelAnnouncement_clone(&a_conv);
+       a_conv = ChannelAnnouncement_clone(&a_conv);
        ret->a = a_conv;
        LDKChannelUpdate b_conv;
        b_conv.inner = (void*)(b & (~1));
        b_conv.is_owned = (b & 1) || (b == 0);
-       if (b_conv.inner != NULL)
-               b_conv = ChannelUpdate_clone(&b_conv);
+       b_conv = ChannelUpdate_clone(&b_conv);
        ret->b = b_conv;
        LDKChannelUpdate c_conv;
        c_conv.inner = (void*)(c & (~1));
        c_conv.is_owned = (c & 1) || (c == 0);
-       if (c_conv.inner != NULL)
-               c_conv = ChannelUpdate_clone(&c_conv);
+       c_conv = ChannelUpdate_clone(&c_conv);
        ret->c = c_conv;
        return (long)ret;
 }
-static inline LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ_clone(const LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ *orig) {
-       LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ ret = {
-               .a = ChannelAnnouncement_clone(&orig->a),
-               .b = ChannelUpdate_clone(&orig->b),
-               .c = ChannelUpdate_clone(&orig->c),
-       };
-       return ret;
-}
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKC3Tuple_1ChannelAnnouncementChannelUpdateChannelUpdateZ_1get_1a(JNIEnv *env, jclass clz, int64_t ptr) {
-       LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ *tuple = (LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ*)ptr;
+       LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ *tuple = (LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ*)(ptr & ~1);
        LDKChannelAnnouncement a_var = tuple->a;
        CHECK((((long)a_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&a_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
@@ -3148,7 +2995,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKC3Tuple_1ChannelAnnounce
        return a_ref;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKC3Tuple_1ChannelAnnouncementChannelUpdateChannelUpdateZ_1get_1b(JNIEnv *env, jclass clz, int64_t ptr) {
-       LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ *tuple = (LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ*)ptr;
+       LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ *tuple = (LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ*)(ptr & ~1);
        LDKChannelUpdate b_var = tuple->b;
        CHECK((((long)b_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&b_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
@@ -3156,7 +3003,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKC3Tuple_1ChannelAnnounce
        return b_ref;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKC3Tuple_1ChannelAnnouncementChannelUpdateChannelUpdateZ_1get_1c(JNIEnv *env, jclass clz, int64_t ptr) {
-       LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ *tuple = (LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ*)ptr;
+       LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ *tuple = (LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ*)(ptr & ~1);
        LDKChannelUpdate c_var = tuple->c;
        CHECK((((long)c_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&c_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
@@ -3173,7 +3020,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCVec_1C3Tuple_1ChannelAn
                int64_t *java_elems = (*env)->GetPrimitiveArrayCritical(env, elems, NULL);
                for (size_t i = 0; i < ret->datalen; i++) {
                        int64_t arr_elem = java_elems[i];
-                       LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ arr_elem_conv = *(LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ*)arr_elem;
+                       LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ arr_elem_conv = *(LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ*)(((uint64_t)arr_elem) & ~1);
                        FREE((void*)arr_elem);
                        ret->data[i] = arr_elem_conv;
                }
@@ -3181,13 +3028,6 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCVec_1C3Tuple_1ChannelAn
        }
        return (long)ret;
 }
-static inline LDKCVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ CVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ_clone(const LDKCVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ *orig) {
-       LDKCVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ ret = { .data = MALLOC(sizeof(LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ) * orig->datalen, "LDKCVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ clone bytes"), .datalen = orig->datalen };
-       for (size_t i = 0; i < ret.datalen; i++) {
-               ret.data[i] = C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ_clone(&orig->data[i]);
-       }
-       return ret;
-}
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCVec_1NodeAnnouncementZ_1new(JNIEnv *env, jclass clz, int64_tArray elems) {
        LDKCVec_NodeAnnouncementZ *ret = MALLOC(sizeof(LDKCVec_NodeAnnouncementZ), "LDKCVec_NodeAnnouncementZ");
        ret->datalen = (*env)->GetArrayLength(env, elems);
@@ -3201,8 +3041,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCVec_1NodeAnnouncementZ_
                        LDKNodeAnnouncement arr_elem_conv;
                        arr_elem_conv.inner = (void*)(arr_elem & (~1));
                        arr_elem_conv.is_owned = (arr_elem & 1) || (arr_elem == 0);
-                       if (arr_elem_conv.inner != NULL)
-                               arr_elem_conv = NodeAnnouncement_clone(&arr_elem_conv);
+                       arr_elem_conv = NodeAnnouncement_clone(&arr_elem_conv);
                        ret->data[i] = arr_elem_conv;
                }
                (*env)->ReleasePrimitiveArrayCritical(env, elems, java_elems, 0);
@@ -3220,12 +3059,12 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1NoneLightningE
        return ((LDKCResult_NoneLightningErrorZ*)arg)->result_ok;
 }
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_LDKCResult_1NoneLightningErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_NoneLightningErrorZ *val = (LDKCResult_NoneLightningErrorZ*)arg;
+       LDKCResult_NoneLightningErrorZ *val = (LDKCResult_NoneLightningErrorZ*)(arg & ~1);
        CHECK(val->result_ok);
        return *val->contents.result;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1NoneLightningErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_NoneLightningErrorZ *val = (LDKCResult_NoneLightningErrorZ*)arg;
+       LDKCResult_NoneLightningErrorZ *val = (LDKCResult_NoneLightningErrorZ*)(arg & ~1);
        CHECK(!val->result_ok);
        LDKLightningError err_var = (*val->contents.err);
        CHECK((((long)err_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3237,7 +3076,7 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1ChannelReestab
        return ((LDKCResult_ChannelReestablishDecodeErrorZ*)arg)->result_ok;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1ChannelReestablishDecodeErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_ChannelReestablishDecodeErrorZ *val = (LDKCResult_ChannelReestablishDecodeErrorZ*)arg;
+       LDKCResult_ChannelReestablishDecodeErrorZ *val = (LDKCResult_ChannelReestablishDecodeErrorZ*)(arg & ~1);
        CHECK(val->result_ok);
        LDKChannelReestablish res_var = (*val->contents.result);
        CHECK((((long)res_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3246,7 +3085,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1ChannelReestabl
        return res_ref;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1ChannelReestablishDecodeErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_ChannelReestablishDecodeErrorZ *val = (LDKCResult_ChannelReestablishDecodeErrorZ*)arg;
+       LDKCResult_ChannelReestablishDecodeErrorZ *val = (LDKCResult_ChannelReestablishDecodeErrorZ*)(arg & ~1);
        CHECK(!val->result_ok);
        LDKDecodeError err_var = (*val->contents.err);
        CHECK((((long)err_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3258,7 +3097,7 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1InitDecodeErro
        return ((LDKCResult_InitDecodeErrorZ*)arg)->result_ok;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1InitDecodeErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_InitDecodeErrorZ *val = (LDKCResult_InitDecodeErrorZ*)arg;
+       LDKCResult_InitDecodeErrorZ *val = (LDKCResult_InitDecodeErrorZ*)(arg & ~1);
        CHECK(val->result_ok);
        LDKInit res_var = (*val->contents.result);
        CHECK((((long)res_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3267,7 +3106,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1InitDecodeError
        return res_ref;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1InitDecodeErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_InitDecodeErrorZ *val = (LDKCResult_InitDecodeErrorZ*)arg;
+       LDKCResult_InitDecodeErrorZ *val = (LDKCResult_InitDecodeErrorZ*)(arg & ~1);
        CHECK(!val->result_ok);
        LDKDecodeError err_var = (*val->contents.err);
        CHECK((((long)err_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3279,7 +3118,7 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1PingDecodeErro
        return ((LDKCResult_PingDecodeErrorZ*)arg)->result_ok;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1PingDecodeErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_PingDecodeErrorZ *val = (LDKCResult_PingDecodeErrorZ*)arg;
+       LDKCResult_PingDecodeErrorZ *val = (LDKCResult_PingDecodeErrorZ*)(arg & ~1);
        CHECK(val->result_ok);
        LDKPing res_var = (*val->contents.result);
        CHECK((((long)res_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3288,7 +3127,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1PingDecodeError
        return res_ref;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1PingDecodeErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_PingDecodeErrorZ *val = (LDKCResult_PingDecodeErrorZ*)arg;
+       LDKCResult_PingDecodeErrorZ *val = (LDKCResult_PingDecodeErrorZ*)(arg & ~1);
        CHECK(!val->result_ok);
        LDKDecodeError err_var = (*val->contents.err);
        CHECK((((long)err_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3300,7 +3139,7 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1PongDecodeErro
        return ((LDKCResult_PongDecodeErrorZ*)arg)->result_ok;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1PongDecodeErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_PongDecodeErrorZ *val = (LDKCResult_PongDecodeErrorZ*)arg;
+       LDKCResult_PongDecodeErrorZ *val = (LDKCResult_PongDecodeErrorZ*)(arg & ~1);
        CHECK(val->result_ok);
        LDKPong res_var = (*val->contents.result);
        CHECK((((long)res_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3309,7 +3148,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1PongDecodeError
        return res_ref;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1PongDecodeErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_PongDecodeErrorZ *val = (LDKCResult_PongDecodeErrorZ*)arg;
+       LDKCResult_PongDecodeErrorZ *val = (LDKCResult_PongDecodeErrorZ*)(arg & ~1);
        CHECK(!val->result_ok);
        LDKDecodeError err_var = (*val->contents.err);
        CHECK((((long)err_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3321,7 +3160,7 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1UnsignedChanne
        return ((LDKCResult_UnsignedChannelAnnouncementDecodeErrorZ*)arg)->result_ok;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1UnsignedChannelAnnouncementDecodeErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_UnsignedChannelAnnouncementDecodeErrorZ *val = (LDKCResult_UnsignedChannelAnnouncementDecodeErrorZ*)arg;
+       LDKCResult_UnsignedChannelAnnouncementDecodeErrorZ *val = (LDKCResult_UnsignedChannelAnnouncementDecodeErrorZ*)(arg & ~1);
        CHECK(val->result_ok);
        LDKUnsignedChannelAnnouncement res_var = (*val->contents.result);
        CHECK((((long)res_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3330,7 +3169,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1UnsignedChannel
        return res_ref;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1UnsignedChannelAnnouncementDecodeErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_UnsignedChannelAnnouncementDecodeErrorZ *val = (LDKCResult_UnsignedChannelAnnouncementDecodeErrorZ*)arg;
+       LDKCResult_UnsignedChannelAnnouncementDecodeErrorZ *val = (LDKCResult_UnsignedChannelAnnouncementDecodeErrorZ*)(arg & ~1);
        CHECK(!val->result_ok);
        LDKDecodeError err_var = (*val->contents.err);
        CHECK((((long)err_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3342,7 +3181,7 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1UnsignedChanne
        return ((LDKCResult_UnsignedChannelUpdateDecodeErrorZ*)arg)->result_ok;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1UnsignedChannelUpdateDecodeErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_UnsignedChannelUpdateDecodeErrorZ *val = (LDKCResult_UnsignedChannelUpdateDecodeErrorZ*)arg;
+       LDKCResult_UnsignedChannelUpdateDecodeErrorZ *val = (LDKCResult_UnsignedChannelUpdateDecodeErrorZ*)(arg & ~1);
        CHECK(val->result_ok);
        LDKUnsignedChannelUpdate res_var = (*val->contents.result);
        CHECK((((long)res_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3351,7 +3190,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1UnsignedChannel
        return res_ref;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1UnsignedChannelUpdateDecodeErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_UnsignedChannelUpdateDecodeErrorZ *val = (LDKCResult_UnsignedChannelUpdateDecodeErrorZ*)arg;
+       LDKCResult_UnsignedChannelUpdateDecodeErrorZ *val = (LDKCResult_UnsignedChannelUpdateDecodeErrorZ*)(arg & ~1);
        CHECK(!val->result_ok);
        LDKDecodeError err_var = (*val->contents.err);
        CHECK((((long)err_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3363,7 +3202,7 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1ErrorMessageDe
        return ((LDKCResult_ErrorMessageDecodeErrorZ*)arg)->result_ok;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1ErrorMessageDecodeErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_ErrorMessageDecodeErrorZ *val = (LDKCResult_ErrorMessageDecodeErrorZ*)arg;
+       LDKCResult_ErrorMessageDecodeErrorZ *val = (LDKCResult_ErrorMessageDecodeErrorZ*)(arg & ~1);
        CHECK(val->result_ok);
        LDKErrorMessage res_var = (*val->contents.result);
        CHECK((((long)res_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3372,7 +3211,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1ErrorMessageDec
        return res_ref;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1ErrorMessageDecodeErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_ErrorMessageDecodeErrorZ *val = (LDKCResult_ErrorMessageDecodeErrorZ*)arg;
+       LDKCResult_ErrorMessageDecodeErrorZ *val = (LDKCResult_ErrorMessageDecodeErrorZ*)(arg & ~1);
        CHECK(!val->result_ok);
        LDKDecodeError err_var = (*val->contents.err);
        CHECK((((long)err_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3384,7 +3223,7 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1UnsignedNodeAn
        return ((LDKCResult_UnsignedNodeAnnouncementDecodeErrorZ*)arg)->result_ok;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1UnsignedNodeAnnouncementDecodeErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_UnsignedNodeAnnouncementDecodeErrorZ *val = (LDKCResult_UnsignedNodeAnnouncementDecodeErrorZ*)arg;
+       LDKCResult_UnsignedNodeAnnouncementDecodeErrorZ *val = (LDKCResult_UnsignedNodeAnnouncementDecodeErrorZ*)(arg & ~1);
        CHECK(val->result_ok);
        LDKUnsignedNodeAnnouncement res_var = (*val->contents.result);
        CHECK((((long)res_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3393,7 +3232,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1UnsignedNodeAnn
        return res_ref;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1UnsignedNodeAnnouncementDecodeErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_UnsignedNodeAnnouncementDecodeErrorZ *val = (LDKCResult_UnsignedNodeAnnouncementDecodeErrorZ*)arg;
+       LDKCResult_UnsignedNodeAnnouncementDecodeErrorZ *val = (LDKCResult_UnsignedNodeAnnouncementDecodeErrorZ*)(arg & ~1);
        CHECK(!val->result_ok);
        LDKDecodeError err_var = (*val->contents.err);
        CHECK((((long)err_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3405,7 +3244,7 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1QueryShortChan
        return ((LDKCResult_QueryShortChannelIdsDecodeErrorZ*)arg)->result_ok;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1QueryShortChannelIdsDecodeErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_QueryShortChannelIdsDecodeErrorZ *val = (LDKCResult_QueryShortChannelIdsDecodeErrorZ*)arg;
+       LDKCResult_QueryShortChannelIdsDecodeErrorZ *val = (LDKCResult_QueryShortChannelIdsDecodeErrorZ*)(arg & ~1);
        CHECK(val->result_ok);
        LDKQueryShortChannelIds res_var = (*val->contents.result);
        CHECK((((long)res_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3414,7 +3253,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1QueryShortChann
        return res_ref;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1QueryShortChannelIdsDecodeErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_QueryShortChannelIdsDecodeErrorZ *val = (LDKCResult_QueryShortChannelIdsDecodeErrorZ*)arg;
+       LDKCResult_QueryShortChannelIdsDecodeErrorZ *val = (LDKCResult_QueryShortChannelIdsDecodeErrorZ*)(arg & ~1);
        CHECK(!val->result_ok);
        LDKDecodeError err_var = (*val->contents.err);
        CHECK((((long)err_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3426,7 +3265,7 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1ReplyShortChan
        return ((LDKCResult_ReplyShortChannelIdsEndDecodeErrorZ*)arg)->result_ok;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1ReplyShortChannelIdsEndDecodeErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_ReplyShortChannelIdsEndDecodeErrorZ *val = (LDKCResult_ReplyShortChannelIdsEndDecodeErrorZ*)arg;
+       LDKCResult_ReplyShortChannelIdsEndDecodeErrorZ *val = (LDKCResult_ReplyShortChannelIdsEndDecodeErrorZ*)(arg & ~1);
        CHECK(val->result_ok);
        LDKReplyShortChannelIdsEnd res_var = (*val->contents.result);
        CHECK((((long)res_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3435,7 +3274,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1ReplyShortChann
        return res_ref;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1ReplyShortChannelIdsEndDecodeErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_ReplyShortChannelIdsEndDecodeErrorZ *val = (LDKCResult_ReplyShortChannelIdsEndDecodeErrorZ*)arg;
+       LDKCResult_ReplyShortChannelIdsEndDecodeErrorZ *val = (LDKCResult_ReplyShortChannelIdsEndDecodeErrorZ*)(arg & ~1);
        CHECK(!val->result_ok);
        LDKDecodeError err_var = (*val->contents.err);
        CHECK((((long)err_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3447,7 +3286,7 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1QueryChannelRa
        return ((LDKCResult_QueryChannelRangeDecodeErrorZ*)arg)->result_ok;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1QueryChannelRangeDecodeErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_QueryChannelRangeDecodeErrorZ *val = (LDKCResult_QueryChannelRangeDecodeErrorZ*)arg;
+       LDKCResult_QueryChannelRangeDecodeErrorZ *val = (LDKCResult_QueryChannelRangeDecodeErrorZ*)(arg & ~1);
        CHECK(val->result_ok);
        LDKQueryChannelRange res_var = (*val->contents.result);
        CHECK((((long)res_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3456,7 +3295,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1QueryChannelRan
        return res_ref;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1QueryChannelRangeDecodeErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_QueryChannelRangeDecodeErrorZ *val = (LDKCResult_QueryChannelRangeDecodeErrorZ*)arg;
+       LDKCResult_QueryChannelRangeDecodeErrorZ *val = (LDKCResult_QueryChannelRangeDecodeErrorZ*)(arg & ~1);
        CHECK(!val->result_ok);
        LDKDecodeError err_var = (*val->contents.err);
        CHECK((((long)err_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3468,7 +3307,7 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1ReplyChannelRa
        return ((LDKCResult_ReplyChannelRangeDecodeErrorZ*)arg)->result_ok;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1ReplyChannelRangeDecodeErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_ReplyChannelRangeDecodeErrorZ *val = (LDKCResult_ReplyChannelRangeDecodeErrorZ*)arg;
+       LDKCResult_ReplyChannelRangeDecodeErrorZ *val = (LDKCResult_ReplyChannelRangeDecodeErrorZ*)(arg & ~1);
        CHECK(val->result_ok);
        LDKReplyChannelRange res_var = (*val->contents.result);
        CHECK((((long)res_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3477,7 +3316,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1ReplyChannelRan
        return res_ref;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1ReplyChannelRangeDecodeErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_ReplyChannelRangeDecodeErrorZ *val = (LDKCResult_ReplyChannelRangeDecodeErrorZ*)arg;
+       LDKCResult_ReplyChannelRangeDecodeErrorZ *val = (LDKCResult_ReplyChannelRangeDecodeErrorZ*)(arg & ~1);
        CHECK(!val->result_ok);
        LDKDecodeError err_var = (*val->contents.err);
        CHECK((((long)err_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3489,7 +3328,7 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1GossipTimestam
        return ((LDKCResult_GossipTimestampFilterDecodeErrorZ*)arg)->result_ok;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1GossipTimestampFilterDecodeErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_GossipTimestampFilterDecodeErrorZ *val = (LDKCResult_GossipTimestampFilterDecodeErrorZ*)arg;
+       LDKCResult_GossipTimestampFilterDecodeErrorZ *val = (LDKCResult_GossipTimestampFilterDecodeErrorZ*)(arg & ~1);
        CHECK(val->result_ok);
        LDKGossipTimestampFilter res_var = (*val->contents.result);
        CHECK((((long)res_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3498,7 +3337,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1GossipTimestamp
        return res_ref;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1GossipTimestampFilterDecodeErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_GossipTimestampFilterDecodeErrorZ *val = (LDKCResult_GossipTimestampFilterDecodeErrorZ*)arg;
+       LDKCResult_GossipTimestampFilterDecodeErrorZ *val = (LDKCResult_GossipTimestampFilterDecodeErrorZ*)(arg & ~1);
        CHECK(!val->result_ok);
        LDKDecodeError err_var = (*val->contents.err);
        CHECK((((long)err_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3510,7 +3349,7 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1CVec_1u8ZPeerH
        return ((LDKCResult_CVec_u8ZPeerHandleErrorZ*)arg)->result_ok;
 }
 JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_LDKCResult_1CVec_1u8ZPeerHandleErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_CVec_u8ZPeerHandleErrorZ *val = (LDKCResult_CVec_u8ZPeerHandleErrorZ*)arg;
+       LDKCResult_CVec_u8ZPeerHandleErrorZ *val = (LDKCResult_CVec_u8ZPeerHandleErrorZ*)(arg & ~1);
        CHECK(val->result_ok);
        LDKCVec_u8Z res_var = (*val->contents.result);
        int8_tArray res_arr = (*env)->NewByteArray(env, res_var.datalen);
@@ -3518,7 +3357,7 @@ JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_LDKCResult_1CVec_1u8ZPe
        return res_arr;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1CVec_1u8ZPeerHandleErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_CVec_u8ZPeerHandleErrorZ *val = (LDKCResult_CVec_u8ZPeerHandleErrorZ*)arg;
+       LDKCResult_CVec_u8ZPeerHandleErrorZ *val = (LDKCResult_CVec_u8ZPeerHandleErrorZ*)(arg & ~1);
        CHECK(!val->result_ok);
        LDKPeerHandleError err_var = (*val->contents.err);
        CHECK((((long)err_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3530,12 +3369,12 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1NonePeerHandle
        return ((LDKCResult_NonePeerHandleErrorZ*)arg)->result_ok;
 }
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_LDKCResult_1NonePeerHandleErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_NonePeerHandleErrorZ *val = (LDKCResult_NonePeerHandleErrorZ*)arg;
+       LDKCResult_NonePeerHandleErrorZ *val = (LDKCResult_NonePeerHandleErrorZ*)(arg & ~1);
        CHECK(val->result_ok);
        return *val->contents.result;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1NonePeerHandleErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_NonePeerHandleErrorZ *val = (LDKCResult_NonePeerHandleErrorZ*)arg;
+       LDKCResult_NonePeerHandleErrorZ *val = (LDKCResult_NonePeerHandleErrorZ*)(arg & ~1);
        CHECK(!val->result_ok);
        LDKPeerHandleError err_var = (*val->contents.err);
        CHECK((((long)err_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3547,12 +3386,12 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1boolPeerHandle
        return ((LDKCResult_boolPeerHandleErrorZ*)arg)->result_ok;
 }
 JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1boolPeerHandleErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_boolPeerHandleErrorZ *val = (LDKCResult_boolPeerHandleErrorZ*)arg;
+       LDKCResult_boolPeerHandleErrorZ *val = (LDKCResult_boolPeerHandleErrorZ*)(arg & ~1);
        CHECK(val->result_ok);
        return *val->contents.result;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1boolPeerHandleErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_boolPeerHandleErrorZ *val = (LDKCResult_boolPeerHandleErrorZ*)arg;
+       LDKCResult_boolPeerHandleErrorZ *val = (LDKCResult_boolPeerHandleErrorZ*)(arg & ~1);
        CHECK(!val->result_ok);
        LDKPeerHandleError err_var = (*val->contents.err);
        CHECK((((long)err_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3564,14 +3403,14 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1SecretKeySecpE
        return ((LDKCResult_SecretKeySecpErrorZ*)arg)->result_ok;
 }
 JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_LDKCResult_1SecretKeySecpErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_SecretKeySecpErrorZ *val = (LDKCResult_SecretKeySecpErrorZ*)arg;
+       LDKCResult_SecretKeySecpErrorZ *val = (LDKCResult_SecretKeySecpErrorZ*)(arg & ~1);
        CHECK(val->result_ok);
        int8_tArray res_arr = (*env)->NewByteArray(env, 32);
        (*env)->SetByteArrayRegion(env, res_arr, 0, 32, (*val->contents.result).bytes);
        return res_arr;
 }
 JNIEXPORT jclass JNICALL Java_org_ldk_impl_bindings_LDKCResult_1SecretKeySecpErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_SecretKeySecpErrorZ *val = (LDKCResult_SecretKeySecpErrorZ*)arg;
+       LDKCResult_SecretKeySecpErrorZ *val = (LDKCResult_SecretKeySecpErrorZ*)(arg & ~1);
        CHECK(!val->result_ok);
        jclass err_conv = LDKSecp256k1Error_to_java(env, (*val->contents.err));
        return err_conv;
@@ -3580,14 +3419,14 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1PublicKeySecpE
        return ((LDKCResult_PublicKeySecpErrorZ*)arg)->result_ok;
 }
 JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_LDKCResult_1PublicKeySecpErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_PublicKeySecpErrorZ *val = (LDKCResult_PublicKeySecpErrorZ*)arg;
+       LDKCResult_PublicKeySecpErrorZ *val = (LDKCResult_PublicKeySecpErrorZ*)(arg & ~1);
        CHECK(val->result_ok);
        int8_tArray res_arr = (*env)->NewByteArray(env, 33);
        (*env)->SetByteArrayRegion(env, res_arr, 0, 33, (*val->contents.result).compressed_form);
        return res_arr;
 }
 JNIEXPORT jclass JNICALL Java_org_ldk_impl_bindings_LDKCResult_1PublicKeySecpErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_PublicKeySecpErrorZ *val = (LDKCResult_PublicKeySecpErrorZ*)arg;
+       LDKCResult_PublicKeySecpErrorZ *val = (LDKCResult_PublicKeySecpErrorZ*)(arg & ~1);
        CHECK(!val->result_ok);
        jclass err_conv = LDKSecp256k1Error_to_java(env, (*val->contents.err));
        return err_conv;
@@ -3596,7 +3435,7 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1TxCreationKeys
        return ((LDKCResult_TxCreationKeysSecpErrorZ*)arg)->result_ok;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1TxCreationKeysSecpErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_TxCreationKeysSecpErrorZ *val = (LDKCResult_TxCreationKeysSecpErrorZ*)arg;
+       LDKCResult_TxCreationKeysSecpErrorZ *val = (LDKCResult_TxCreationKeysSecpErrorZ*)(arg & ~1);
        CHECK(val->result_ok);
        LDKTxCreationKeys res_var = (*val->contents.result);
        CHECK((((long)res_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3605,7 +3444,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1TxCreationKeysS
        return res_ref;
 }
 JNIEXPORT jclass JNICALL Java_org_ldk_impl_bindings_LDKCResult_1TxCreationKeysSecpErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_TxCreationKeysSecpErrorZ *val = (LDKCResult_TxCreationKeysSecpErrorZ*)arg;
+       LDKCResult_TxCreationKeysSecpErrorZ *val = (LDKCResult_TxCreationKeysSecpErrorZ*)(arg & ~1);
        CHECK(!val->result_ok);
        jclass err_conv = LDKSecp256k1Error_to_java(env, (*val->contents.err));
        return err_conv;
@@ -3614,7 +3453,7 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1TrustedCommitm
        return ((LDKCResult_TrustedCommitmentTransactionNoneZ*)arg)->result_ok;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1TrustedCommitmentTransactionNoneZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_TrustedCommitmentTransactionNoneZ *val = (LDKCResult_TrustedCommitmentTransactionNoneZ*)arg;
+       LDKCResult_TrustedCommitmentTransactionNoneZ *val = (LDKCResult_TrustedCommitmentTransactionNoneZ*)(arg & ~1);
        CHECK(val->result_ok);
        LDKTrustedCommitmentTransaction res_var = (*val->contents.result);
        CHECK((((long)res_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3623,7 +3462,28 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1TrustedCommitme
        return res_ref;
 }
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_LDKCResult_1TrustedCommitmentTransactionNoneZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_TrustedCommitmentTransactionNoneZ *val = (LDKCResult_TrustedCommitmentTransactionNoneZ*)arg;
+       LDKCResult_TrustedCommitmentTransactionNoneZ *val = (LDKCResult_TrustedCommitmentTransactionNoneZ*)(arg & ~1);
+       CHECK(!val->result_ok);
+       return *val->contents.err;
+}
+JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1CVec_1SignatureZNoneZ_1result_1ok(JNIEnv *env, jclass clz, int64_t arg) {
+       return ((LDKCResult_CVec_SignatureZNoneZ*)arg)->result_ok;
+}
+JNIEXPORT jobjectArray JNICALL Java_org_ldk_impl_bindings_LDKCResult_1CVec_1SignatureZNoneZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
+       LDKCResult_CVec_SignatureZNoneZ *val = (LDKCResult_CVec_SignatureZNoneZ*)(arg & ~1);
+       CHECK(val->result_ok);
+       LDKCVec_SignatureZ res_var = (*val->contents.result);
+       jobjectArray res_arr = (*env)->NewObjectArray(env, res_var.datalen, arr_of_B_clz, NULL);
+       ;
+       for (size_t i = 0; i < res_var.datalen; i++) {
+               int8_tArray arr_conv_8_arr = (*env)->NewByteArray(env, 64);
+               (*env)->SetByteArrayRegion(env, arr_conv_8_arr, 0, 64, res_var.data[i].compact_form);
+               (*env)->SetObjectArrayElement(env, res_arr, i, arr_conv_8_arr);
+       }
+       return res_arr;
+}
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_LDKCResult_1CVec_1SignatureZNoneZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
+       LDKCResult_CVec_SignatureZNoneZ *val = (LDKCResult_CVec_SignatureZNoneZ*)(arg & ~1);
        CHECK(!val->result_ok);
        return *val->contents.err;
 }
@@ -3640,8 +3500,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCVec_1RouteHopZ_1new(JNI
                        LDKRouteHop arr_elem_conv;
                        arr_elem_conv.inner = (void*)(arr_elem & (~1));
                        arr_elem_conv.is_owned = (arr_elem & 1) || (arr_elem == 0);
-                       if (arr_elem_conv.inner != NULL)
-                               arr_elem_conv = RouteHop_clone(&arr_elem_conv);
+                       arr_elem_conv = RouteHop_clone(&arr_elem_conv);
                        ret->data[i] = arr_elem_conv;
                }
                (*env)->ReleasePrimitiveArrayCritical(env, elems, java_elems, 0);
@@ -3666,7 +3525,7 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1RouteDecodeErr
        return ((LDKCResult_RouteDecodeErrorZ*)arg)->result_ok;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1RouteDecodeErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_RouteDecodeErrorZ *val = (LDKCResult_RouteDecodeErrorZ*)arg;
+       LDKCResult_RouteDecodeErrorZ *val = (LDKCResult_RouteDecodeErrorZ*)(arg & ~1);
        CHECK(val->result_ok);
        LDKRoute res_var = (*val->contents.result);
        CHECK((((long)res_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3675,7 +3534,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1RouteDecodeErro
        return res_ref;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1RouteDecodeErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_RouteDecodeErrorZ *val = (LDKCResult_RouteDecodeErrorZ*)arg;
+       LDKCResult_RouteDecodeErrorZ *val = (LDKCResult_RouteDecodeErrorZ*)(arg & ~1);
        CHECK(!val->result_ok);
        LDKDecodeError err_var = (*val->contents.err);
        CHECK((((long)err_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3696,8 +3555,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCVec_1RouteHintZ_1new(JN
                        LDKRouteHint arr_elem_conv;
                        arr_elem_conv.inner = (void*)(arr_elem & (~1));
                        arr_elem_conv.is_owned = (arr_elem & 1) || (arr_elem == 0);
-                       if (arr_elem_conv.inner != NULL)
-                               arr_elem_conv = RouteHint_clone(&arr_elem_conv);
+                       arr_elem_conv = RouteHint_clone(&arr_elem_conv);
                        ret->data[i] = arr_elem_conv;
                }
                (*env)->ReleasePrimitiveArrayCritical(env, elems, java_elems, 0);
@@ -3715,7 +3573,7 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1RouteLightning
        return ((LDKCResult_RouteLightningErrorZ*)arg)->result_ok;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1RouteLightningErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_RouteLightningErrorZ *val = (LDKCResult_RouteLightningErrorZ*)arg;
+       LDKCResult_RouteLightningErrorZ *val = (LDKCResult_RouteLightningErrorZ*)(arg & ~1);
        CHECK(val->result_ok);
        LDKRoute res_var = (*val->contents.result);
        CHECK((((long)res_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3724,7 +3582,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1RouteLightningE
        return res_ref;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1RouteLightningErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_RouteLightningErrorZ *val = (LDKCResult_RouteLightningErrorZ*)arg;
+       LDKCResult_RouteLightningErrorZ *val = (LDKCResult_RouteLightningErrorZ*)(arg & ~1);
        CHECK(!val->result_ok);
        LDKLightningError err_var = (*val->contents.err);
        CHECK((((long)err_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3736,7 +3594,7 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1RoutingFeesDec
        return ((LDKCResult_RoutingFeesDecodeErrorZ*)arg)->result_ok;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1RoutingFeesDecodeErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_RoutingFeesDecodeErrorZ *val = (LDKCResult_RoutingFeesDecodeErrorZ*)arg;
+       LDKCResult_RoutingFeesDecodeErrorZ *val = (LDKCResult_RoutingFeesDecodeErrorZ*)(arg & ~1);
        CHECK(val->result_ok);
        LDKRoutingFees res_var = (*val->contents.result);
        CHECK((((long)res_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3745,7 +3603,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1RoutingFeesDeco
        return res_ref;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1RoutingFeesDecodeErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_RoutingFeesDecodeErrorZ *val = (LDKCResult_RoutingFeesDecodeErrorZ*)arg;
+       LDKCResult_RoutingFeesDecodeErrorZ *val = (LDKCResult_RoutingFeesDecodeErrorZ*)(arg & ~1);
        CHECK(!val->result_ok);
        LDKDecodeError err_var = (*val->contents.err);
        CHECK((((long)err_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3757,7 +3615,7 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1NodeAnnounceme
        return ((LDKCResult_NodeAnnouncementInfoDecodeErrorZ*)arg)->result_ok;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1NodeAnnouncementInfoDecodeErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_NodeAnnouncementInfoDecodeErrorZ *val = (LDKCResult_NodeAnnouncementInfoDecodeErrorZ*)arg;
+       LDKCResult_NodeAnnouncementInfoDecodeErrorZ *val = (LDKCResult_NodeAnnouncementInfoDecodeErrorZ*)(arg & ~1);
        CHECK(val->result_ok);
        LDKNodeAnnouncementInfo res_var = (*val->contents.result);
        CHECK((((long)res_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3766,7 +3624,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1NodeAnnouncemen
        return res_ref;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1NodeAnnouncementInfoDecodeErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_NodeAnnouncementInfoDecodeErrorZ *val = (LDKCResult_NodeAnnouncementInfoDecodeErrorZ*)arg;
+       LDKCResult_NodeAnnouncementInfoDecodeErrorZ *val = (LDKCResult_NodeAnnouncementInfoDecodeErrorZ*)(arg & ~1);
        CHECK(!val->result_ok);
        LDKDecodeError err_var = (*val->contents.err);
        CHECK((((long)err_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3778,7 +3636,7 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1NodeInfoDecode
        return ((LDKCResult_NodeInfoDecodeErrorZ*)arg)->result_ok;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1NodeInfoDecodeErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_NodeInfoDecodeErrorZ *val = (LDKCResult_NodeInfoDecodeErrorZ*)arg;
+       LDKCResult_NodeInfoDecodeErrorZ *val = (LDKCResult_NodeInfoDecodeErrorZ*)(arg & ~1);
        CHECK(val->result_ok);
        LDKNodeInfo res_var = (*val->contents.result);
        CHECK((((long)res_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3787,7 +3645,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1NodeInfoDecodeE
        return res_ref;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1NodeInfoDecodeErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_NodeInfoDecodeErrorZ *val = (LDKCResult_NodeInfoDecodeErrorZ*)arg;
+       LDKCResult_NodeInfoDecodeErrorZ *val = (LDKCResult_NodeInfoDecodeErrorZ*)(arg & ~1);
        CHECK(!val->result_ok);
        LDKDecodeError err_var = (*val->contents.err);
        CHECK((((long)err_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3799,7 +3657,7 @@ JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_LDKCResult_1NetworkGraphDe
        return ((LDKCResult_NetworkGraphDecodeErrorZ*)arg)->result_ok;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1NetworkGraphDecodeErrorZ_1get_1ok(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_NetworkGraphDecodeErrorZ *val = (LDKCResult_NetworkGraphDecodeErrorZ*)arg;
+       LDKCResult_NetworkGraphDecodeErrorZ *val = (LDKCResult_NetworkGraphDecodeErrorZ*)(arg & ~1);
        CHECK(val->result_ok);
        LDKNetworkGraph res_var = (*val->contents.result);
        CHECK((((long)res_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3808,7 +3666,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1NetworkGraphDec
        return res_ref;
 }
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LDKCResult_1NetworkGraphDecodeErrorZ_1get_1err(JNIEnv *env, jclass clz, int64_t arg) {
-       LDKCResult_NetworkGraphDecodeErrorZ *val = (LDKCResult_NetworkGraphDecodeErrorZ*)arg;
+       LDKCResult_NetworkGraphDecodeErrorZ *val = (LDKCResult_NetworkGraphDecodeErrorZ*)(arg & ~1);
        CHECK(!val->result_ok);
        LDKDecodeError err_var = (*val->contents.err);
        CHECK((((long)err_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -3847,7 +3705,7 @@ LDKCVec_MessageSendEventZ get_and_clear_pending_msg_events_jcall(const void* thi
        int64_t* arg_vals = (*env)->GetLongArrayElements (env, arg, NULL);
        for (size_t s = 0; s < arg_constr.datalen; s++) {
                int64_t arr_conv_18 = arg_vals[s];
-               LDKMessageSendEvent arr_conv_18_conv = *(LDKMessageSendEvent*)arr_conv_18;
+               LDKMessageSendEvent arr_conv_18_conv = *(LDKMessageSendEvent*)(((uint64_t)arr_conv_18) & ~1);
                FREE((void*)arr_conv_18);
                arg_constr.data[s] = arr_conv_18_conv;
        }
@@ -3928,7 +3786,7 @@ LDKCVec_EventZ get_and_clear_pending_events_jcall(const void* this_arg) {
        int64_t* arg_vals = (*env)->GetLongArrayElements (env, arg, NULL);
        for (size_t h = 0; h < arg_constr.datalen; h++) {
                int64_t arr_conv_7 = arg_vals[h];
-               LDKEvent arr_conv_7_conv = *(LDKEvent*)arr_conv_7;
+               LDKEvent arr_conv_7_conv = *(LDKEvent*)(((uint64_t)arr_conv_7) & ~1);
                FREE((void*)arr_conv_7);
                arg_constr.data[h] = arr_conv_7_conv;
        }
@@ -4002,7 +3860,7 @@ LDKCResult_TxOutAccessErrorZ get_utxo_jcall(const void* this_arg, const uint8_t
        jobject obj = (*env)->NewLocalRef(env, j_calls->o);
        CHECK(obj != NULL);
        LDKCResult_TxOutAccessErrorZ* ret = (LDKCResult_TxOutAccessErrorZ*)(*env)->CallLongMethod(env, obj, j_calls->get_utxo_meth, genesis_hash_arr, short_channel_id);
-       LDKCResult_TxOutAccessErrorZ ret_conv = *(LDKCResult_TxOutAccessErrorZ*)ret;
+       LDKCResult_TxOutAccessErrorZ ret_conv = *(LDKCResult_TxOutAccessErrorZ*)(((uint64_t)ret) & ~1);
        ret_conv = CResult_TxOutAccessErrorZ_clone((LDKCResult_TxOutAccessErrorZ*)ret);
        return ret_conv;
 }
@@ -4078,8 +3936,7 @@ void register_output_jcall(const void* this_arg, const LDKOutPoint * outpoint, L
        JNIEnv *env;
        DO_ASSERT((*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_8) == JNI_OK);
        LDKOutPoint outpoint_var = *outpoint;
-       if (outpoint->inner != NULL)
-               outpoint_var = OutPoint_clone(outpoint);
+       outpoint_var = OutPoint_clone(outpoint);
        CHECK((((long)outpoint_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&outpoint_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
        long outpoint_ref = (long)outpoint_var.inner;
@@ -4176,7 +4033,7 @@ LDKCResult_NoneChannelMonitorUpdateErrZ persist_new_channel_jcall(const void* th
                id_ref |= 1;
        }
        LDKChannelMonitor data_var = *data;
-       // Warning: we may need a move here but can't clone!
+       data_var = ChannelMonitor_clone(data);
        CHECK((((long)data_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&data_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
        long data_ref = (long)data_var.inner;
@@ -4186,7 +4043,7 @@ LDKCResult_NoneChannelMonitorUpdateErrZ persist_new_channel_jcall(const void* th
        jobject obj = (*env)->NewLocalRef(env, j_calls->o);
        CHECK(obj != NULL);
        LDKCResult_NoneChannelMonitorUpdateErrZ* ret = (LDKCResult_NoneChannelMonitorUpdateErrZ*)(*env)->CallLongMethod(env, obj, j_calls->persist_new_channel_meth, id_ref, data_ref);
-       LDKCResult_NoneChannelMonitorUpdateErrZ ret_conv = *(LDKCResult_NoneChannelMonitorUpdateErrZ*)ret;
+       LDKCResult_NoneChannelMonitorUpdateErrZ ret_conv = *(LDKCResult_NoneChannelMonitorUpdateErrZ*)(((uint64_t)ret) & ~1);
        ret_conv = CResult_NoneChannelMonitorUpdateErrZ_clone((LDKCResult_NoneChannelMonitorUpdateErrZ*)ret);
        return ret_conv;
 }
@@ -4202,8 +4059,7 @@ LDKCResult_NoneChannelMonitorUpdateErrZ update_persisted_channel_jcall(const voi
                id_ref |= 1;
        }
        LDKChannelMonitorUpdate update_var = *update;
-       if (update->inner != NULL)
-               update_var = ChannelMonitorUpdate_clone(update);
+       update_var = ChannelMonitorUpdate_clone(update);
        CHECK((((long)update_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&update_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
        long update_ref = (long)update_var.inner;
@@ -4211,7 +4067,7 @@ LDKCResult_NoneChannelMonitorUpdateErrZ update_persisted_channel_jcall(const voi
                update_ref |= 1;
        }
        LDKChannelMonitor data_var = *data;
-       // Warning: we may need a move here but can't clone!
+       data_var = ChannelMonitor_clone(data);
        CHECK((((long)data_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&data_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
        long data_ref = (long)data_var.inner;
@@ -4221,7 +4077,7 @@ LDKCResult_NoneChannelMonitorUpdateErrZ update_persisted_channel_jcall(const voi
        jobject obj = (*env)->NewLocalRef(env, j_calls->o);
        CHECK(obj != NULL);
        LDKCResult_NoneChannelMonitorUpdateErrZ* ret = (LDKCResult_NoneChannelMonitorUpdateErrZ*)(*env)->CallLongMethod(env, obj, j_calls->update_persisted_channel_meth, id_ref, update_ref, data_ref);
-       LDKCResult_NoneChannelMonitorUpdateErrZ ret_conv = *(LDKCResult_NoneChannelMonitorUpdateErrZ*)ret;
+       LDKCResult_NoneChannelMonitorUpdateErrZ ret_conv = *(LDKCResult_NoneChannelMonitorUpdateErrZ*)(((uint64_t)ret) & ~1);
        ret_conv = CResult_NoneChannelMonitorUpdateErrZ_clone((LDKCResult_NoneChannelMonitorUpdateErrZ*)ret);
        return ret_conv;
 }
@@ -4260,8 +4116,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Persist_1persist_1new_1chan
        LDKOutPoint id_conv;
        id_conv.inner = (void*)(id & (~1));
        id_conv.is_owned = (id & 1) || (id == 0);
-       if (id_conv.inner != NULL)
-               id_conv = OutPoint_clone(&id_conv);
+       id_conv = OutPoint_clone(&id_conv);
        LDKChannelMonitor data_conv;
        data_conv.inner = (void*)(data & (~1));
        data_conv.is_owned = false;
@@ -4275,8 +4130,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Persist_1update_1persisted_
        LDKOutPoint id_conv;
        id_conv.inner = (void*)(id & (~1));
        id_conv.is_owned = (id & 1) || (id == 0);
-       if (id_conv.inner != NULL)
-               id_conv = OutPoint_clone(&id_conv);
+       id_conv = OutPoint_clone(&id_conv);
        LDKChannelMonitorUpdate update_conv;
        update_conv.inner = (void*)(update & (~1));
        update_conv.is_owned = false;
@@ -4336,8 +4190,7 @@ void handle_open_channel_jcall(const void* this_arg, LDKPublicKey their_node_id,
                their_features_ref |= 1;
        }
        LDKOpenChannel msg_var = *msg;
-       if (msg->inner != NULL)
-               msg_var = OpenChannel_clone(msg);
+       msg_var = OpenChannel_clone(msg);
        CHECK((((long)msg_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&msg_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
        long msg_ref = (long)msg_var.inner;
@@ -4362,8 +4215,7 @@ void handle_accept_channel_jcall(const void* this_arg, LDKPublicKey their_node_i
                their_features_ref |= 1;
        }
        LDKAcceptChannel msg_var = *msg;
-       if (msg->inner != NULL)
-               msg_var = AcceptChannel_clone(msg);
+       msg_var = AcceptChannel_clone(msg);
        CHECK((((long)msg_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&msg_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
        long msg_ref = (long)msg_var.inner;
@@ -4381,8 +4233,7 @@ void handle_funding_created_jcall(const void* this_arg, LDKPublicKey their_node_
        int8_tArray their_node_id_arr = (*env)->NewByteArray(env, 33);
        (*env)->SetByteArrayRegion(env, their_node_id_arr, 0, 33, their_node_id.compressed_form);
        LDKFundingCreated msg_var = *msg;
-       if (msg->inner != NULL)
-               msg_var = FundingCreated_clone(msg);
+       msg_var = FundingCreated_clone(msg);
        CHECK((((long)msg_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&msg_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
        long msg_ref = (long)msg_var.inner;
@@ -4400,8 +4251,7 @@ void handle_funding_signed_jcall(const void* this_arg, LDKPublicKey their_node_i
        int8_tArray their_node_id_arr = (*env)->NewByteArray(env, 33);
        (*env)->SetByteArrayRegion(env, their_node_id_arr, 0, 33, their_node_id.compressed_form);
        LDKFundingSigned msg_var = *msg;
-       if (msg->inner != NULL)
-               msg_var = FundingSigned_clone(msg);
+       msg_var = FundingSigned_clone(msg);
        CHECK((((long)msg_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&msg_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
        long msg_ref = (long)msg_var.inner;
@@ -4419,8 +4269,7 @@ void handle_funding_locked_jcall(const void* this_arg, LDKPublicKey their_node_i
        int8_tArray their_node_id_arr = (*env)->NewByteArray(env, 33);
        (*env)->SetByteArrayRegion(env, their_node_id_arr, 0, 33, their_node_id.compressed_form);
        LDKFundingLocked msg_var = *msg;
-       if (msg->inner != NULL)
-               msg_var = FundingLocked_clone(msg);
+       msg_var = FundingLocked_clone(msg);
        CHECK((((long)msg_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&msg_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
        long msg_ref = (long)msg_var.inner;
@@ -4438,8 +4287,7 @@ void handle_shutdown_jcall(const void* this_arg, LDKPublicKey their_node_id, con
        int8_tArray their_node_id_arr = (*env)->NewByteArray(env, 33);
        (*env)->SetByteArrayRegion(env, their_node_id_arr, 0, 33, their_node_id.compressed_form);
        LDKShutdown msg_var = *msg;
-       if (msg->inner != NULL)
-               msg_var = Shutdown_clone(msg);
+       msg_var = Shutdown_clone(msg);
        CHECK((((long)msg_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&msg_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
        long msg_ref = (long)msg_var.inner;
@@ -4457,8 +4305,7 @@ void handle_closing_signed_jcall(const void* this_arg, LDKPublicKey their_node_i
        int8_tArray their_node_id_arr = (*env)->NewByteArray(env, 33);
        (*env)->SetByteArrayRegion(env, their_node_id_arr, 0, 33, their_node_id.compressed_form);
        LDKClosingSigned msg_var = *msg;
-       if (msg->inner != NULL)
-               msg_var = ClosingSigned_clone(msg);
+       msg_var = ClosingSigned_clone(msg);
        CHECK((((long)msg_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&msg_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
        long msg_ref = (long)msg_var.inner;
@@ -4476,8 +4323,7 @@ void handle_update_add_htlc_jcall(const void* this_arg, LDKPublicKey their_node_
        int8_tArray their_node_id_arr = (*env)->NewByteArray(env, 33);
        (*env)->SetByteArrayRegion(env, their_node_id_arr, 0, 33, their_node_id.compressed_form);
        LDKUpdateAddHTLC msg_var = *msg;
-       if (msg->inner != NULL)
-               msg_var = UpdateAddHTLC_clone(msg);
+       msg_var = UpdateAddHTLC_clone(msg);
        CHECK((((long)msg_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&msg_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
        long msg_ref = (long)msg_var.inner;
@@ -4495,8 +4341,7 @@ void handle_update_fulfill_htlc_jcall(const void* this_arg, LDKPublicKey their_n
        int8_tArray their_node_id_arr = (*env)->NewByteArray(env, 33);
        (*env)->SetByteArrayRegion(env, their_node_id_arr, 0, 33, their_node_id.compressed_form);
        LDKUpdateFulfillHTLC msg_var = *msg;
-       if (msg->inner != NULL)
-               msg_var = UpdateFulfillHTLC_clone(msg);
+       msg_var = UpdateFulfillHTLC_clone(msg);
        CHECK((((long)msg_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&msg_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
        long msg_ref = (long)msg_var.inner;
@@ -4514,8 +4359,7 @@ void handle_update_fail_htlc_jcall(const void* this_arg, LDKPublicKey their_node
        int8_tArray their_node_id_arr = (*env)->NewByteArray(env, 33);
        (*env)->SetByteArrayRegion(env, their_node_id_arr, 0, 33, their_node_id.compressed_form);
        LDKUpdateFailHTLC msg_var = *msg;
-       if (msg->inner != NULL)
-               msg_var = UpdateFailHTLC_clone(msg);
+       msg_var = UpdateFailHTLC_clone(msg);
        CHECK((((long)msg_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&msg_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
        long msg_ref = (long)msg_var.inner;
@@ -4533,8 +4377,7 @@ void handle_update_fail_malformed_htlc_jcall(const void* this_arg, LDKPublicKey
        int8_tArray their_node_id_arr = (*env)->NewByteArray(env, 33);
        (*env)->SetByteArrayRegion(env, their_node_id_arr, 0, 33, their_node_id.compressed_form);
        LDKUpdateFailMalformedHTLC msg_var = *msg;
-       if (msg->inner != NULL)
-               msg_var = UpdateFailMalformedHTLC_clone(msg);
+       msg_var = UpdateFailMalformedHTLC_clone(msg);
        CHECK((((long)msg_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&msg_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
        long msg_ref = (long)msg_var.inner;
@@ -4552,8 +4395,7 @@ void handle_commitment_signed_jcall(const void* this_arg, LDKPublicKey their_nod
        int8_tArray their_node_id_arr = (*env)->NewByteArray(env, 33);
        (*env)->SetByteArrayRegion(env, their_node_id_arr, 0, 33, their_node_id.compressed_form);
        LDKCommitmentSigned msg_var = *msg;
-       if (msg->inner != NULL)
-               msg_var = CommitmentSigned_clone(msg);
+       msg_var = CommitmentSigned_clone(msg);
        CHECK((((long)msg_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&msg_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
        long msg_ref = (long)msg_var.inner;
@@ -4571,8 +4413,7 @@ void handle_revoke_and_ack_jcall(const void* this_arg, LDKPublicKey their_node_i
        int8_tArray their_node_id_arr = (*env)->NewByteArray(env, 33);
        (*env)->SetByteArrayRegion(env, their_node_id_arr, 0, 33, their_node_id.compressed_form);
        LDKRevokeAndACK msg_var = *msg;
-       if (msg->inner != NULL)
-               msg_var = RevokeAndACK_clone(msg);
+       msg_var = RevokeAndACK_clone(msg);
        CHECK((((long)msg_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&msg_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
        long msg_ref = (long)msg_var.inner;
@@ -4590,8 +4431,7 @@ void handle_update_fee_jcall(const void* this_arg, LDKPublicKey their_node_id, c
        int8_tArray their_node_id_arr = (*env)->NewByteArray(env, 33);
        (*env)->SetByteArrayRegion(env, their_node_id_arr, 0, 33, their_node_id.compressed_form);
        LDKUpdateFee msg_var = *msg;
-       if (msg->inner != NULL)
-               msg_var = UpdateFee_clone(msg);
+       msg_var = UpdateFee_clone(msg);
        CHECK((((long)msg_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&msg_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
        long msg_ref = (long)msg_var.inner;
@@ -4609,8 +4449,7 @@ void handle_announcement_signatures_jcall(const void* this_arg, LDKPublicKey the
        int8_tArray their_node_id_arr = (*env)->NewByteArray(env, 33);
        (*env)->SetByteArrayRegion(env, their_node_id_arr, 0, 33, their_node_id.compressed_form);
        LDKAnnouncementSignatures msg_var = *msg;
-       if (msg->inner != NULL)
-               msg_var = AnnouncementSignatures_clone(msg);
+       msg_var = AnnouncementSignatures_clone(msg);
        CHECK((((long)msg_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&msg_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
        long msg_ref = (long)msg_var.inner;
@@ -4638,8 +4477,7 @@ void peer_connected_jcall(const void* this_arg, LDKPublicKey their_node_id, cons
        int8_tArray their_node_id_arr = (*env)->NewByteArray(env, 33);
        (*env)->SetByteArrayRegion(env, their_node_id_arr, 0, 33, their_node_id.compressed_form);
        LDKInit msg_var = *msg;
-       if (msg->inner != NULL)
-               msg_var = Init_clone(msg);
+       msg_var = Init_clone(msg);
        CHECK((((long)msg_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&msg_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
        long msg_ref = (long)msg_var.inner;
@@ -4657,8 +4495,7 @@ void handle_channel_reestablish_jcall(const void* this_arg, LDKPublicKey their_n
        int8_tArray their_node_id_arr = (*env)->NewByteArray(env, 33);
        (*env)->SetByteArrayRegion(env, their_node_id_arr, 0, 33, their_node_id.compressed_form);
        LDKChannelReestablish msg_var = *msg;
-       if (msg->inner != NULL)
-               msg_var = ChannelReestablish_clone(msg);
+       msg_var = ChannelReestablish_clone(msg);
        CHECK((((long)msg_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&msg_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
        long msg_ref = (long)msg_var.inner;
@@ -4676,8 +4513,7 @@ void handle_error_jcall(const void* this_arg, LDKPublicKey their_node_id, const
        int8_tArray their_node_id_arr = (*env)->NewByteArray(env, 33);
        (*env)->SetByteArrayRegion(env, their_node_id_arr, 0, 33, their_node_id.compressed_form);
        LDKErrorMessage msg_var = *msg;
-       if (msg->inner != NULL)
-               msg_var = ErrorMessage_clone(msg);
+       msg_var = ErrorMessage_clone(msg);
        CHECK((((long)msg_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&msg_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
        long msg_ref = (long)msg_var.inner;
@@ -4780,7 +4616,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelMessageHandler_1handle_
        LDKInitFeatures their_features_conv;
        their_features_conv.inner = (void*)(their_features & (~1));
        their_features_conv.is_owned = (their_features & 1) || (their_features == 0);
-       // Warning: we may need a move here but can't clone!
+       // Warning: we need a move here but no clone is available for LDKInitFeatures
        LDKOpenChannel msg_conv;
        msg_conv.inner = (void*)(msg & (~1));
        msg_conv.is_owned = false;
@@ -4795,7 +4631,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelMessageHandler_1handle_
        LDKInitFeatures their_features_conv;
        their_features_conv.inner = (void*)(their_features & (~1));
        their_features_conv.is_owned = (their_features & 1) || (their_features == 0);
-       // Warning: we may need a move here but can't clone!
+       // Warning: we need a move here but no clone is available for LDKInitFeatures
        LDKAcceptChannel msg_conv;
        msg_conv.inner = (void*)(msg & (~1));
        msg_conv.is_owned = false;
@@ -5017,8 +4853,7 @@ LDKCResult_boolLightningErrorZ handle_node_announcement_jcall(const void* this_a
        JNIEnv *env;
        DO_ASSERT((*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_8) == JNI_OK);
        LDKNodeAnnouncement msg_var = *msg;
-       if (msg->inner != NULL)
-               msg_var = NodeAnnouncement_clone(msg);
+       msg_var = NodeAnnouncement_clone(msg);
        CHECK((((long)msg_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&msg_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
        long msg_ref = (long)msg_var.inner;
@@ -5028,8 +4863,8 @@ LDKCResult_boolLightningErrorZ handle_node_announcement_jcall(const void* this_a
        jobject obj = (*env)->NewLocalRef(env, j_calls->o);
        CHECK(obj != NULL);
        LDKCResult_boolLightningErrorZ* ret = (LDKCResult_boolLightningErrorZ*)(*env)->CallLongMethod(env, obj, j_calls->handle_node_announcement_meth, msg_ref);
-       LDKCResult_boolLightningErrorZ ret_conv = *(LDKCResult_boolLightningErrorZ*)ret;
-       // Warning: we may need a move here but can't do a full clone!
+       LDKCResult_boolLightningErrorZ ret_conv = *(LDKCResult_boolLightningErrorZ*)(((uint64_t)ret) & ~1);
+       ret_conv = CResult_boolLightningErrorZ_clone((LDKCResult_boolLightningErrorZ*)ret);
        return ret_conv;
 }
 LDKCResult_boolLightningErrorZ handle_channel_announcement_jcall(const void* this_arg, const LDKChannelAnnouncement * msg) {
@@ -5037,8 +4872,7 @@ LDKCResult_boolLightningErrorZ handle_channel_announcement_jcall(const void* thi
        JNIEnv *env;
        DO_ASSERT((*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_8) == JNI_OK);
        LDKChannelAnnouncement msg_var = *msg;
-       if (msg->inner != NULL)
-               msg_var = ChannelAnnouncement_clone(msg);
+       msg_var = ChannelAnnouncement_clone(msg);
        CHECK((((long)msg_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&msg_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
        long msg_ref = (long)msg_var.inner;
@@ -5048,8 +4882,8 @@ LDKCResult_boolLightningErrorZ handle_channel_announcement_jcall(const void* thi
        jobject obj = (*env)->NewLocalRef(env, j_calls->o);
        CHECK(obj != NULL);
        LDKCResult_boolLightningErrorZ* ret = (LDKCResult_boolLightningErrorZ*)(*env)->CallLongMethod(env, obj, j_calls->handle_channel_announcement_meth, msg_ref);
-       LDKCResult_boolLightningErrorZ ret_conv = *(LDKCResult_boolLightningErrorZ*)ret;
-       // Warning: we may need a move here but can't do a full clone!
+       LDKCResult_boolLightningErrorZ ret_conv = *(LDKCResult_boolLightningErrorZ*)(((uint64_t)ret) & ~1);
+       ret_conv = CResult_boolLightningErrorZ_clone((LDKCResult_boolLightningErrorZ*)ret);
        return ret_conv;
 }
 LDKCResult_boolLightningErrorZ handle_channel_update_jcall(const void* this_arg, const LDKChannelUpdate * msg) {
@@ -5057,8 +4891,7 @@ LDKCResult_boolLightningErrorZ handle_channel_update_jcall(const void* this_arg,
        JNIEnv *env;
        DO_ASSERT((*j_calls->vm)->GetEnv(j_calls->vm, (void**)&env, JNI_VERSION_1_8) == JNI_OK);
        LDKChannelUpdate msg_var = *msg;
-       if (msg->inner != NULL)
-               msg_var = ChannelUpdate_clone(msg);
+       msg_var = ChannelUpdate_clone(msg);
        CHECK((((long)msg_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&msg_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
        long msg_ref = (long)msg_var.inner;
@@ -5068,8 +4901,8 @@ LDKCResult_boolLightningErrorZ handle_channel_update_jcall(const void* this_arg,
        jobject obj = (*env)->NewLocalRef(env, j_calls->o);
        CHECK(obj != NULL);
        LDKCResult_boolLightningErrorZ* ret = (LDKCResult_boolLightningErrorZ*)(*env)->CallLongMethod(env, obj, j_calls->handle_channel_update_meth, msg_ref);
-       LDKCResult_boolLightningErrorZ ret_conv = *(LDKCResult_boolLightningErrorZ*)ret;
-       // Warning: we may need a move here but can't do a full clone!
+       LDKCResult_boolLightningErrorZ ret_conv = *(LDKCResult_boolLightningErrorZ*)(((uint64_t)ret) & ~1);
+       ret_conv = CResult_boolLightningErrorZ_clone((LDKCResult_boolLightningErrorZ*)ret);
        return ret_conv;
 }
 void handle_htlc_fail_channel_update_jcall(const void* this_arg, const LDKHTLCFailChannelUpdate * update) {
@@ -5097,7 +4930,7 @@ LDKCVec_C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZZ get_next_channel
        int64_t* arg_vals = (*env)->GetLongArrayElements (env, arg, NULL);
        for (size_t l = 0; l < arg_constr.datalen; l++) {
                int64_t arr_conv_63 = arg_vals[l];
-               LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ arr_conv_63_conv = *(LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ*)arr_conv_63;
+               LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ arr_conv_63_conv = *(LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ*)(((uint64_t)arr_conv_63) & ~1);
                FREE((void*)arr_conv_63);
                arg_constr.data[l] = arr_conv_63_conv;
        }
@@ -5125,8 +4958,7 @@ LDKCVec_NodeAnnouncementZ get_next_node_announcements_jcall(const void* this_arg
                LDKNodeAnnouncement arr_conv_18_conv;
                arr_conv_18_conv.inner = (void*)(arr_conv_18 & (~1));
                arr_conv_18_conv.is_owned = (arr_conv_18 & 1) || (arr_conv_18 == 0);
-               if (arr_conv_18_conv.inner != NULL)
-                       arr_conv_18_conv = NodeAnnouncement_clone(&arr_conv_18_conv);
+               arr_conv_18_conv = NodeAnnouncement_clone(&arr_conv_18_conv);
                arg_constr.data[s] = arr_conv_18_conv;
        }
        (*env)->ReleaseLongArrayElements(env, arg, arg_vals, 0);
@@ -5139,8 +4971,7 @@ void sync_routing_table_jcall(const void* this_arg, LDKPublicKey their_node_id,
        int8_tArray their_node_id_arr = (*env)->NewByteArray(env, 33);
        (*env)->SetByteArrayRegion(env, their_node_id_arr, 0, 33, their_node_id.compressed_form);
        LDKInit init_var = *init;
-       if (init->inner != NULL)
-               init_var = Init_clone(init);
+       init_var = Init_clone(init);
        CHECK((((long)init_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&init_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
        long init_ref = (long)init_var.inner;
@@ -5167,8 +4998,8 @@ LDKCResult_NoneLightningErrorZ handle_reply_channel_range_jcall(const void* this
        jobject obj = (*env)->NewLocalRef(env, j_calls->o);
        CHECK(obj != NULL);
        LDKCResult_NoneLightningErrorZ* ret = (LDKCResult_NoneLightningErrorZ*)(*env)->CallLongMethod(env, obj, j_calls->handle_reply_channel_range_meth, their_node_id_arr, msg_ref);
-       LDKCResult_NoneLightningErrorZ ret_conv = *(LDKCResult_NoneLightningErrorZ*)ret;
-       // Warning: we may need a move here but can't do a full clone!
+       LDKCResult_NoneLightningErrorZ ret_conv = *(LDKCResult_NoneLightningErrorZ*)(((uint64_t)ret) & ~1);
+       ret_conv = CResult_NoneLightningErrorZ_clone((LDKCResult_NoneLightningErrorZ*)ret);
        return ret_conv;
 }
 LDKCResult_NoneLightningErrorZ handle_reply_short_channel_ids_end_jcall(const void* this_arg, LDKPublicKey their_node_id, LDKReplyShortChannelIdsEnd msg) {
@@ -5187,8 +5018,8 @@ LDKCResult_NoneLightningErrorZ handle_reply_short_channel_ids_end_jcall(const vo
        jobject obj = (*env)->NewLocalRef(env, j_calls->o);
        CHECK(obj != NULL);
        LDKCResult_NoneLightningErrorZ* ret = (LDKCResult_NoneLightningErrorZ*)(*env)->CallLongMethod(env, obj, j_calls->handle_reply_short_channel_ids_end_meth, their_node_id_arr, msg_ref);
-       LDKCResult_NoneLightningErrorZ ret_conv = *(LDKCResult_NoneLightningErrorZ*)ret;
-       // Warning: we may need a move here but can't do a full clone!
+       LDKCResult_NoneLightningErrorZ ret_conv = *(LDKCResult_NoneLightningErrorZ*)(((uint64_t)ret) & ~1);
+       ret_conv = CResult_NoneLightningErrorZ_clone((LDKCResult_NoneLightningErrorZ*)ret);
        return ret_conv;
 }
 LDKCResult_NoneLightningErrorZ handle_query_channel_range_jcall(const void* this_arg, LDKPublicKey their_node_id, LDKQueryChannelRange msg) {
@@ -5207,8 +5038,8 @@ LDKCResult_NoneLightningErrorZ handle_query_channel_range_jcall(const void* this
        jobject obj = (*env)->NewLocalRef(env, j_calls->o);
        CHECK(obj != NULL);
        LDKCResult_NoneLightningErrorZ* ret = (LDKCResult_NoneLightningErrorZ*)(*env)->CallLongMethod(env, obj, j_calls->handle_query_channel_range_meth, their_node_id_arr, msg_ref);
-       LDKCResult_NoneLightningErrorZ ret_conv = *(LDKCResult_NoneLightningErrorZ*)ret;
-       // Warning: we may need a move here but can't do a full clone!
+       LDKCResult_NoneLightningErrorZ ret_conv = *(LDKCResult_NoneLightningErrorZ*)(((uint64_t)ret) & ~1);
+       ret_conv = CResult_NoneLightningErrorZ_clone((LDKCResult_NoneLightningErrorZ*)ret);
        return ret_conv;
 }
 LDKCResult_NoneLightningErrorZ handle_query_short_channel_ids_jcall(const void* this_arg, LDKPublicKey their_node_id, LDKQueryShortChannelIds msg) {
@@ -5227,8 +5058,8 @@ LDKCResult_NoneLightningErrorZ handle_query_short_channel_ids_jcall(const void*
        jobject obj = (*env)->NewLocalRef(env, j_calls->o);
        CHECK(obj != NULL);
        LDKCResult_NoneLightningErrorZ* ret = (LDKCResult_NoneLightningErrorZ*)(*env)->CallLongMethod(env, obj, j_calls->handle_query_short_channel_ids_meth, their_node_id_arr, msg_ref);
-       LDKCResult_NoneLightningErrorZ ret_conv = *(LDKCResult_NoneLightningErrorZ*)ret;
-       // Warning: we may need a move here but can't do a full clone!
+       LDKCResult_NoneLightningErrorZ ret_conv = *(LDKCResult_NoneLightningErrorZ*)(((uint64_t)ret) & ~1);
+       ret_conv = CResult_NoneLightningErrorZ_clone((LDKCResult_NoneLightningErrorZ*)ret);
        return ret_conv;
 }
 static void* LDKRoutingMessageHandler_JCalls_clone(const void* this_arg) {
@@ -5335,9 +5166,6 @@ JNIEXPORT int64_tArray JNICALL Java_org_ldk_impl_bindings_RoutingMessageHandler_
        for (size_t l = 0; l < ret_var.datalen; l++) {
                LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ* arr_conv_63_ref = MALLOC(sizeof(LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ), "LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ");
                *arr_conv_63_ref = ret_var.data[l];
-               arr_conv_63_ref->a = ChannelAnnouncement_clone(&arr_conv_63_ref->a);
-               arr_conv_63_ref->b = ChannelUpdate_clone(&arr_conv_63_ref->b);
-               arr_conv_63_ref->c = ChannelUpdate_clone(&arr_conv_63_ref->c);
                ret_arr_ptr[l] = (long)arr_conv_63_ref;
        }
        (*env)->ReleasePrimitiveArrayCritical(env, ret_arr, ret_arr_ptr, 0);
@@ -5387,8 +5215,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_RoutingMessageHandler_1hand
        LDKReplyChannelRange msg_conv;
        msg_conv.inner = (void*)(msg & (~1));
        msg_conv.is_owned = (msg & 1) || (msg == 0);
-       if (msg_conv.inner != NULL)
-               msg_conv = ReplyChannelRange_clone(&msg_conv);
+       msg_conv = ReplyChannelRange_clone(&msg_conv);
        LDKCResult_NoneLightningErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_NoneLightningErrorZ), "LDKCResult_NoneLightningErrorZ");
        *ret_conv = (this_arg_conv->handle_reply_channel_range)(this_arg_conv->this_arg, their_node_id_ref, msg_conv);
        return (long)ret_conv;
@@ -5402,8 +5229,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_RoutingMessageHandler_1hand
        LDKReplyShortChannelIdsEnd msg_conv;
        msg_conv.inner = (void*)(msg & (~1));
        msg_conv.is_owned = (msg & 1) || (msg == 0);
-       if (msg_conv.inner != NULL)
-               msg_conv = ReplyShortChannelIdsEnd_clone(&msg_conv);
+       msg_conv = ReplyShortChannelIdsEnd_clone(&msg_conv);
        LDKCResult_NoneLightningErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_NoneLightningErrorZ), "LDKCResult_NoneLightningErrorZ");
        *ret_conv = (this_arg_conv->handle_reply_short_channel_ids_end)(this_arg_conv->this_arg, their_node_id_ref, msg_conv);
        return (long)ret_conv;
@@ -5417,8 +5243,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_RoutingMessageHandler_1hand
        LDKQueryChannelRange msg_conv;
        msg_conv.inner = (void*)(msg & (~1));
        msg_conv.is_owned = (msg & 1) || (msg == 0);
-       if (msg_conv.inner != NULL)
-               msg_conv = QueryChannelRange_clone(&msg_conv);
+       msg_conv = QueryChannelRange_clone(&msg_conv);
        LDKCResult_NoneLightningErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_NoneLightningErrorZ), "LDKCResult_NoneLightningErrorZ");
        *ret_conv = (this_arg_conv->handle_query_channel_range)(this_arg_conv->this_arg, their_node_id_ref, msg_conv);
        return (long)ret_conv;
@@ -5432,8 +5257,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_RoutingMessageHandler_1hand
        LDKQueryShortChannelIds msg_conv;
        msg_conv.inner = (void*)(msg & (~1));
        msg_conv.is_owned = (msg & 1) || (msg == 0);
-       if (msg_conv.inner != NULL)
-               msg_conv = QueryShortChannelIds_clone(&msg_conv);
+       msg_conv = QueryShortChannelIds_clone(&msg_conv);
        LDKCResult_NoneLightningErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_NoneLightningErrorZ), "LDKCResult_NoneLightningErrorZ");
        *ret_conv = (this_arg_conv->handle_query_short_channel_ids)(this_arg_conv->this_arg, their_node_id_ref, msg_conv);
        return (long)ret_conv;
@@ -5562,13 +5386,14 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Transaction_1free(JNIEnv *env,
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_TxOut_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKTxOut _res_conv = *(LDKTxOut*)_res;
+       if ((_res & 1) != 0) return;
+       LDKTxOut _res_conv = *(LDKTxOut*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        TxOut_free(_res_conv);
 }
 
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_TxOut_1clone(JNIEnv *env, jclass clz, int64_t orig) {
-       LDKTxOut* orig_conv = (LDKTxOut*)orig;
+       LDKTxOut* orig_conv = (LDKTxOut*)(orig & ~1);
        LDKTxOut* ret_ref = MALLOC(sizeof(LDKTxOut), "LDKTxOut");
        *ret_ref = TxOut_clone(orig_conv);
        return (long)ret_ref;
@@ -5584,7 +5409,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CVec_1SpendableOutputDescripto
        int64_t* _res_vals = (*env)->GetLongArrayElements (env, _res, NULL);
        for (size_t b = 0; b < _res_constr.datalen; b++) {
                int64_t arr_conv_27 = _res_vals[b];
-               LDKSpendableOutputDescriptor arr_conv_27_conv = *(LDKSpendableOutputDescriptor*)arr_conv_27;
+               LDKSpendableOutputDescriptor arr_conv_27_conv = *(LDKSpendableOutputDescriptor*)(((uint64_t)arr_conv_27) & ~1);
                FREE((void*)arr_conv_27);
                _res_constr.data[b] = arr_conv_27_conv;
        }
@@ -5602,7 +5427,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CVec_1MessageSendEventZ_1free(
        int64_t* _res_vals = (*env)->GetLongArrayElements (env, _res, NULL);
        for (size_t s = 0; s < _res_constr.datalen; s++) {
                int64_t arr_conv_18 = _res_vals[s];
-               LDKMessageSendEvent arr_conv_18_conv = *(LDKMessageSendEvent*)arr_conv_18;
+               LDKMessageSendEvent arr_conv_18_conv = *(LDKMessageSendEvent*)(((uint64_t)arr_conv_18) & ~1);
                FREE((void*)arr_conv_18);
                _res_constr.data[s] = arr_conv_18_conv;
        }
@@ -5620,7 +5445,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CVec_1EventZ_1free(JNIEnv *env
        int64_t* _res_vals = (*env)->GetLongArrayElements (env, _res, NULL);
        for (size_t h = 0; h < _res_constr.datalen; h++) {
                int64_t arr_conv_7 = _res_vals[h];
-               LDKEvent arr_conv_7_conv = *(LDKEvent*)arr_conv_7;
+               LDKEvent arr_conv_7_conv = *(LDKEvent*)(((uint64_t)arr_conv_7) & ~1);
                FREE((void*)arr_conv_7);
                _res_constr.data[h] = arr_conv_7_conv;
        }
@@ -5629,7 +5454,8 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CVec_1EventZ_1free(JNIEnv *env
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_C2Tuple_1usizeTransactionZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKC2Tuple_usizeTransactionZ _res_conv = *(LDKC2Tuple_usizeTransactionZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKC2Tuple_usizeTransactionZ _res_conv = *(LDKC2Tuple_usizeTransactionZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        C2Tuple_usizeTransactionZ_free(_res_conv);
 }
@@ -5642,7 +5468,6 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_C2Tuple_1usizeTransactionZ_
        b_ref.data_is_owned = true;
        LDKC2Tuple_usizeTransactionZ* ret_ref = MALLOC(sizeof(LDKC2Tuple_usizeTransactionZ), "LDKC2Tuple_usizeTransactionZ");
        *ret_ref = C2Tuple_usizeTransactionZ_new(a, b_ref);
-       // XXX: We likely need to clone here, but no _clone fn is available for byte[]
        return (long)ret_ref;
 }
 
@@ -5656,7 +5481,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CVec_1C2Tuple_1usizeTransactio
        int64_t* _res_vals = (*env)->GetLongArrayElements (env, _res, NULL);
        for (size_t y = 0; y < _res_constr.datalen; y++) {
                int64_t arr_conv_24 = _res_vals[y];
-               LDKC2Tuple_usizeTransactionZ arr_conv_24_conv = *(LDKC2Tuple_usizeTransactionZ*)arr_conv_24;
+               LDKC2Tuple_usizeTransactionZ arr_conv_24_conv = *(LDKC2Tuple_usizeTransactionZ*)(((uint64_t)arr_conv_24) & ~1);
                FREE((void*)arr_conv_24);
                _res_constr.data[y] = arr_conv_24_conv;
        }
@@ -5678,11 +5503,19 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NoneChannelMonitor
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1NoneChannelMonitorUpdateErrZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_NoneChannelMonitorUpdateErrZ _res_conv = *(LDKCResult_NoneChannelMonitorUpdateErrZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_NoneChannelMonitorUpdateErrZ _res_conv = *(LDKCResult_NoneChannelMonitorUpdateErrZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_NoneChannelMonitorUpdateErrZ_free(_res_conv);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NoneChannelMonitorUpdateErrZ_1clone(JNIEnv *env, jclass clz, int64_t orig) {
+       LDKCResult_NoneChannelMonitorUpdateErrZ* orig_conv = (LDKCResult_NoneChannelMonitorUpdateErrZ*)(orig & ~1);
+       LDKCResult_NoneChannelMonitorUpdateErrZ* ret_conv = MALLOC(sizeof(LDKCResult_NoneChannelMonitorUpdateErrZ), "LDKCResult_NoneChannelMonitorUpdateErrZ");
+       *ret_conv = CResult_NoneChannelMonitorUpdateErrZ_clone(orig_conv);
+       return (long)ret_conv;
+}
+
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CVec_1MonitorEventZ_1free(JNIEnv *env, jclass clz, int64_tArray _res) {
        LDKCVec_MonitorEventZ _res_constr;
        _res_constr.datalen = (*env)->GetArrayLength(env, _res);
@@ -5706,8 +5539,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1ChannelMonitorUpda
        LDKChannelMonitorUpdate o_conv;
        o_conv.inner = (void*)(o & (~1));
        o_conv.is_owned = (o & 1) || (o == 0);
-       if (o_conv.inner != NULL)
-               o_conv = ChannelMonitorUpdate_clone(&o_conv);
+       o_conv = ChannelMonitorUpdate_clone(&o_conv);
        LDKCResult_ChannelMonitorUpdateDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_ChannelMonitorUpdateDecodeErrorZ), "LDKCResult_ChannelMonitorUpdateDecodeErrorZ");
        *ret_conv = CResult_ChannelMonitorUpdateDecodeErrorZ_ok(o_conv);
        return (long)ret_conv;
@@ -5717,14 +5549,15 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1ChannelMonitorUpda
        LDKDecodeError e_conv;
        e_conv.inner = (void*)(e & (~1));
        e_conv.is_owned = (e & 1) || (e == 0);
-       // Warning: we may need a move here but can't clone!
+       e_conv = DecodeError_clone(&e_conv);
        LDKCResult_ChannelMonitorUpdateDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_ChannelMonitorUpdateDecodeErrorZ), "LDKCResult_ChannelMonitorUpdateDecodeErrorZ");
        *ret_conv = CResult_ChannelMonitorUpdateDecodeErrorZ_err(e_conv);
        return (long)ret_conv;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1ChannelMonitorUpdateDecodeErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_ChannelMonitorUpdateDecodeErrorZ _res_conv = *(LDKCResult_ChannelMonitorUpdateDecodeErrorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_ChannelMonitorUpdateDecodeErrorZ _res_conv = *(LDKCResult_ChannelMonitorUpdateDecodeErrorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_ChannelMonitorUpdateDecodeErrorZ_free(_res_conv);
 }
@@ -5739,20 +5572,29 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NoneMonitorUpdateE
        LDKMonitorUpdateError e_conv;
        e_conv.inner = (void*)(e & (~1));
        e_conv.is_owned = (e & 1) || (e == 0);
-       // Warning: we may need a move here but can't clone!
+       e_conv = MonitorUpdateError_clone(&e_conv);
        LDKCResult_NoneMonitorUpdateErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_NoneMonitorUpdateErrorZ), "LDKCResult_NoneMonitorUpdateErrorZ");
        *ret_conv = CResult_NoneMonitorUpdateErrorZ_err(e_conv);
        return (long)ret_conv;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1NoneMonitorUpdateErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_NoneMonitorUpdateErrorZ _res_conv = *(LDKCResult_NoneMonitorUpdateErrorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_NoneMonitorUpdateErrorZ _res_conv = *(LDKCResult_NoneMonitorUpdateErrorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_NoneMonitorUpdateErrorZ_free(_res_conv);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NoneMonitorUpdateErrorZ_1clone(JNIEnv *env, jclass clz, int64_t orig) {
+       LDKCResult_NoneMonitorUpdateErrorZ* orig_conv = (LDKCResult_NoneMonitorUpdateErrorZ*)(orig & ~1);
+       LDKCResult_NoneMonitorUpdateErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_NoneMonitorUpdateErrorZ), "LDKCResult_NoneMonitorUpdateErrorZ");
+       *ret_conv = CResult_NoneMonitorUpdateErrorZ_clone(orig_conv);
+       return (long)ret_conv;
+}
+
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_C2Tuple_1OutPointScriptZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKC2Tuple_OutPointScriptZ _res_conv = *(LDKC2Tuple_OutPointScriptZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKC2Tuple_OutPointScriptZ _res_conv = *(LDKC2Tuple_OutPointScriptZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        C2Tuple_OutPointScriptZ_free(_res_conv);
 }
@@ -5761,16 +5603,13 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_C2Tuple_1OutPointScriptZ_1n
        LDKOutPoint a_conv;
        a_conv.inner = (void*)(a & (~1));
        a_conv.is_owned = (a & 1) || (a == 0);
-       if (a_conv.inner != NULL)
-               a_conv = OutPoint_clone(&a_conv);
+       a_conv = OutPoint_clone(&a_conv);
        LDKCVec_u8Z b_ref;
        b_ref.datalen = (*env)->GetArrayLength(env, b);
        b_ref.data = MALLOC(b_ref.datalen, "LDKCVec_u8Z Bytes");
        (*env)->GetByteArrayRegion(env, b, 0, b_ref.datalen, b_ref.data);
        LDKC2Tuple_OutPointScriptZ* ret_ref = MALLOC(sizeof(LDKC2Tuple_OutPointScriptZ), "LDKC2Tuple_OutPointScriptZ");
        *ret_ref = C2Tuple_OutPointScriptZ_new(a_conv, b_ref);
-       ret_ref->a = OutPoint_clone(&ret_ref->a);
-       ret_ref->b = CVec_u8Z_clone(&ret_ref->b);
        return (long)ret_ref;
 }
 
@@ -5793,18 +5632,25 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CVec_1TransactionZ_1free(JNIEn
        CVec_TransactionZ_free(_res_constr);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_C2Tuple_1u32TxOutZ_1clone(JNIEnv *env, jclass clz, int64_t orig) {
+       LDKC2Tuple_u32TxOutZ* orig_conv = (LDKC2Tuple_u32TxOutZ*)(orig & ~1);
+       LDKC2Tuple_u32TxOutZ* ret_ref = MALLOC(sizeof(LDKC2Tuple_u32TxOutZ), "LDKC2Tuple_u32TxOutZ");
+       *ret_ref = C2Tuple_u32TxOutZ_clone(orig_conv);
+       return (long)ret_ref;
+}
+
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_C2Tuple_1u32TxOutZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKC2Tuple_u32TxOutZ _res_conv = *(LDKC2Tuple_u32TxOutZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKC2Tuple_u32TxOutZ _res_conv = *(LDKC2Tuple_u32TxOutZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        C2Tuple_u32TxOutZ_free(_res_conv);
 }
 
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_C2Tuple_1u32TxOutZ_1new(JNIEnv *env, jclass clz, int32_t a, int64_t b) {
-       LDKTxOut b_conv = *(LDKTxOut*)b;
+       LDKTxOut b_conv = *(LDKTxOut*)(((uint64_t)b) & ~1);
        FREE((void*)b);
        LDKC2Tuple_u32TxOutZ* ret_ref = MALLOC(sizeof(LDKC2Tuple_u32TxOutZ), "LDKC2Tuple_u32TxOutZ");
        *ret_ref = C2Tuple_u32TxOutZ_new(a, b_conv);
-       ret_ref->b = TxOut_clone(&ret_ref->b);
        return (long)ret_ref;
 }
 
@@ -5818,7 +5664,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CVec_1C2Tuple_1u32TxOutZZ_1fre
        int64_t* _res_vals = (*env)->GetLongArrayElements (env, _res, NULL);
        for (size_t a = 0; a < _res_constr.datalen; a++) {
                int64_t arr_conv_26 = _res_vals[a];
-               LDKC2Tuple_u32TxOutZ arr_conv_26_conv = *(LDKC2Tuple_u32TxOutZ*)arr_conv_26;
+               LDKC2Tuple_u32TxOutZ arr_conv_26_conv = *(LDKC2Tuple_u32TxOutZ*)(((uint64_t)arr_conv_26) & ~1);
                FREE((void*)arr_conv_26);
                _res_constr.data[a] = arr_conv_26_conv;
        }
@@ -5827,7 +5673,8 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CVec_1C2Tuple_1u32TxOutZZ_1fre
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_C2Tuple_1TxidCVec_1C2Tuple_1u32TxOutZZZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ _res_conv = *(LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ _res_conv = *(LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ_free(_res_conv);
 }
@@ -5845,15 +5692,13 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_C2Tuple_1TxidCVec_1C2Tuple_
        int64_t* b_vals = (*env)->GetLongArrayElements (env, b, NULL);
        for (size_t a = 0; a < b_constr.datalen; a++) {
                int64_t arr_conv_26 = b_vals[a];
-               LDKC2Tuple_u32TxOutZ arr_conv_26_conv = *(LDKC2Tuple_u32TxOutZ*)arr_conv_26;
+               LDKC2Tuple_u32TxOutZ arr_conv_26_conv = *(LDKC2Tuple_u32TxOutZ*)(((uint64_t)arr_conv_26) & ~1);
                FREE((void*)arr_conv_26);
                b_constr.data[a] = arr_conv_26_conv;
        }
        (*env)->ReleaseLongArrayElements(env, b, b_vals, 0);
        LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ* ret_ref = MALLOC(sizeof(LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ), "LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ");
        *ret_ref = C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ_new(a_ref, b_constr);
-       ret_ref->a = ThirtyTwoBytes_clone(&ret_ref->a);
-       ret_ref->b = CVec_C2Tuple_u32TxOutZZ_clone(&ret_ref->b);
        return (long)ret_ref;
 }
 
@@ -5867,7 +5712,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CVec_1C2Tuple_1TxidCVec_1C2Tup
        int64_t* _res_vals = (*env)->GetLongArrayElements (env, _res, NULL);
        for (size_t u = 0; u < _res_constr.datalen; u++) {
                int64_t arr_conv_46 = _res_vals[u];
-               LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ arr_conv_46_conv = *(LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ*)arr_conv_46;
+               LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ arr_conv_46_conv = *(LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ*)(((uint64_t)arr_conv_46) & ~1);
                FREE((void*)arr_conv_46);
                _res_constr.data[u] = arr_conv_46_conv;
        }
@@ -5876,7 +5721,8 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CVec_1C2Tuple_1TxidCVec_1C2Tup
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_C2Tuple_1BlockHashChannelMonitorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKC2Tuple_BlockHashChannelMonitorZ _res_conv = *(LDKC2Tuple_BlockHashChannelMonitorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKC2Tuple_BlockHashChannelMonitorZ _res_conv = *(LDKC2Tuple_BlockHashChannelMonitorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        C2Tuple_BlockHashChannelMonitorZ_free(_res_conv);
 }
@@ -5888,16 +5734,14 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_C2Tuple_1BlockHashChannelMo
        LDKChannelMonitor b_conv;
        b_conv.inner = (void*)(b & (~1));
        b_conv.is_owned = (b & 1) || (b == 0);
-       // Warning: we may need a move here but can't clone!
+       b_conv = ChannelMonitor_clone(&b_conv);
        LDKC2Tuple_BlockHashChannelMonitorZ* ret_ref = MALLOC(sizeof(LDKC2Tuple_BlockHashChannelMonitorZ), "LDKC2Tuple_BlockHashChannelMonitorZ");
        *ret_ref = C2Tuple_BlockHashChannelMonitorZ_new(a_ref, b_conv);
-       ret_ref->a = ThirtyTwoBytes_clone(&ret_ref->a);
-       // XXX: We likely need to clone here, but no _clone fn is available for ChannelMonitor
        return (long)ret_ref;
 }
 
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1C2Tuple_1BlockHashChannelMonitorZDecodeErrorZ_1ok(JNIEnv *env, jclass clz, int64_t o) {
-       LDKC2Tuple_BlockHashChannelMonitorZ o_conv = *(LDKC2Tuple_BlockHashChannelMonitorZ*)o;
+       LDKC2Tuple_BlockHashChannelMonitorZ o_conv = *(LDKC2Tuple_BlockHashChannelMonitorZ*)(((uint64_t)o) & ~1);
        FREE((void*)o);
        LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ), "LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ");
        *ret_conv = CResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ_ok(o_conv);
@@ -5908,20 +5752,29 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1C2Tuple_1BlockHash
        LDKDecodeError e_conv;
        e_conv.inner = (void*)(e & (~1));
        e_conv.is_owned = (e & 1) || (e == 0);
-       // Warning: we may need a move here but can't clone!
+       e_conv = DecodeError_clone(&e_conv);
        LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ), "LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ");
        *ret_conv = CResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ_err(e_conv);
        return (long)ret_conv;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1C2Tuple_1BlockHashChannelMonitorZDecodeErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ _res_conv = *(LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ _res_conv = *(LDKCResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ_free(_res_conv);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_C2Tuple_1u64u64Z_1clone(JNIEnv *env, jclass clz, int64_t orig) {
+       LDKC2Tuple_u64u64Z* orig_conv = (LDKC2Tuple_u64u64Z*)(orig & ~1);
+       LDKC2Tuple_u64u64Z* ret_ref = MALLOC(sizeof(LDKC2Tuple_u64u64Z), "LDKC2Tuple_u64u64Z");
+       *ret_ref = C2Tuple_u64u64Z_clone(orig_conv);
+       return (long)ret_ref;
+}
+
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_C2Tuple_1u64u64Z_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKC2Tuple_u64u64Z _res_conv = *(LDKC2Tuple_u64u64Z*)_res;
+       if ((_res & 1) != 0) return;
+       LDKC2Tuple_u64u64Z _res_conv = *(LDKC2Tuple_u64u64Z*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        C2Tuple_u64u64Z_free(_res_conv);
 }
@@ -5933,7 +5786,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_C2Tuple_1u64u64Z_1new(JNIEn
 }
 
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1SpendableOutputDescriptorDecodeErrorZ_1ok(JNIEnv *env, jclass clz, int64_t o) {
-       LDKSpendableOutputDescriptor o_conv = *(LDKSpendableOutputDescriptor*)o;
+       LDKSpendableOutputDescriptor o_conv = *(LDKSpendableOutputDescriptor*)(((uint64_t)o) & ~1);
        FREE((void*)o);
        LDKCResult_SpendableOutputDescriptorDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_SpendableOutputDescriptorDecodeErrorZ), "LDKCResult_SpendableOutputDescriptorDecodeErrorZ");
        *ret_conv = CResult_SpendableOutputDescriptorDecodeErrorZ_ok(o_conv);
@@ -5944,18 +5797,26 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1SpendableOutputDes
        LDKDecodeError e_conv;
        e_conv.inner = (void*)(e & (~1));
        e_conv.is_owned = (e & 1) || (e == 0);
-       // Warning: we may need a move here but can't clone!
+       e_conv = DecodeError_clone(&e_conv);
        LDKCResult_SpendableOutputDescriptorDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_SpendableOutputDescriptorDecodeErrorZ), "LDKCResult_SpendableOutputDescriptorDecodeErrorZ");
        *ret_conv = CResult_SpendableOutputDescriptorDecodeErrorZ_err(e_conv);
        return (long)ret_conv;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1SpendableOutputDescriptorDecodeErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_SpendableOutputDescriptorDecodeErrorZ _res_conv = *(LDKCResult_SpendableOutputDescriptorDecodeErrorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_SpendableOutputDescriptorDecodeErrorZ _res_conv = *(LDKCResult_SpendableOutputDescriptorDecodeErrorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_SpendableOutputDescriptorDecodeErrorZ_free(_res_conv);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1SpendableOutputDescriptorDecodeErrorZ_1clone(JNIEnv *env, jclass clz, int64_t orig) {
+       LDKCResult_SpendableOutputDescriptorDecodeErrorZ* orig_conv = (LDKCResult_SpendableOutputDescriptorDecodeErrorZ*)(orig & ~1);
+       LDKCResult_SpendableOutputDescriptorDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_SpendableOutputDescriptorDecodeErrorZ), "LDKCResult_SpendableOutputDescriptorDecodeErrorZ");
+       *ret_conv = CResult_SpendableOutputDescriptorDecodeErrorZ_clone(orig_conv);
+       return (long)ret_conv;
+}
+
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CVec_1SignatureZ_1free(JNIEnv *env, jclass clz, jobjectArray _res) {
        LDKCVec_SignatureZ _res_constr;
        _res_constr.datalen = (*env)->GetArrayLength(env, _res);
@@ -5973,8 +5834,16 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CVec_1SignatureZ_1free(JNIEnv
        CVec_SignatureZ_free(_res_constr);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_C2Tuple_1SignatureCVec_1SignatureZZ_1clone(JNIEnv *env, jclass clz, int64_t orig) {
+       LDKC2Tuple_SignatureCVec_SignatureZZ* orig_conv = (LDKC2Tuple_SignatureCVec_SignatureZZ*)(orig & ~1);
+       LDKC2Tuple_SignatureCVec_SignatureZZ* ret_ref = MALLOC(sizeof(LDKC2Tuple_SignatureCVec_SignatureZZ), "LDKC2Tuple_SignatureCVec_SignatureZZ");
+       *ret_ref = C2Tuple_SignatureCVec_SignatureZZ_clone(orig_conv);
+       return (long)ret_ref;
+}
+
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_C2Tuple_1SignatureCVec_1SignatureZZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKC2Tuple_SignatureCVec_SignatureZZ _res_conv = *(LDKC2Tuple_SignatureCVec_SignatureZZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKC2Tuple_SignatureCVec_SignatureZZ _res_conv = *(LDKC2Tuple_SignatureCVec_SignatureZZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        C2Tuple_SignatureCVec_SignatureZZ_free(_res_conv);
 }
@@ -5998,13 +5867,11 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_C2Tuple_1SignatureCVec_1Sig
        }
        LDKC2Tuple_SignatureCVec_SignatureZZ* ret_ref = MALLOC(sizeof(LDKC2Tuple_SignatureCVec_SignatureZZ), "LDKC2Tuple_SignatureCVec_SignatureZZ");
        *ret_ref = C2Tuple_SignatureCVec_SignatureZZ_new(a_ref, b_constr);
-       // XXX: We likely need to clone here, but no _clone fn is available for byte[]
-       // XXX: We likely need to clone here, but no _clone fn is available for byte[][]
        return (long)ret_ref;
 }
 
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1C2Tuple_1SignatureCVec_1SignatureZZNoneZ_1ok(JNIEnv *env, jclass clz, int64_t o) {
-       LDKC2Tuple_SignatureCVec_SignatureZZ o_conv = *(LDKC2Tuple_SignatureCVec_SignatureZZ*)o;
+       LDKC2Tuple_SignatureCVec_SignatureZZ o_conv = *(LDKC2Tuple_SignatureCVec_SignatureZZ*)(((uint64_t)o) & ~1);
        FREE((void*)o);
        LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ* ret_conv = MALLOC(sizeof(LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ), "LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ");
        *ret_conv = CResult_C2Tuple_SignatureCVec_SignatureZZNoneZ_ok(o_conv);
@@ -6018,13 +5885,14 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1C2Tuple_1Signature
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1C2Tuple_1SignatureCVec_1SignatureZZNoneZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ _res_conv = *(LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ _res_conv = *(LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_C2Tuple_SignatureCVec_SignatureZZNoneZ_free(_res_conv);
 }
 
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1C2Tuple_1SignatureCVec_1SignatureZZNoneZ_1clone(JNIEnv *env, jclass clz, int64_t orig) {
-       LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ* orig_conv = (LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ*)orig;
+       LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ* orig_conv = (LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ*)(orig & ~1);
        LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ* ret_conv = MALLOC(sizeof(LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ), "LDKCResult_C2Tuple_SignatureCVec_SignatureZZNoneZ");
        *ret_conv = CResult_C2Tuple_SignatureCVec_SignatureZZNoneZ_clone(orig_conv);
        return (long)ret_conv;
@@ -6046,58 +5914,21 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1SignatureNoneZ_1er
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1SignatureNoneZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_SignatureNoneZ _res_conv = *(LDKCResult_SignatureNoneZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_SignatureNoneZ _res_conv = *(LDKCResult_SignatureNoneZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_SignatureNoneZ_free(_res_conv);
 }
 
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1SignatureNoneZ_1clone(JNIEnv *env, jclass clz, int64_t orig) {
-       LDKCResult_SignatureNoneZ* orig_conv = (LDKCResult_SignatureNoneZ*)orig;
+       LDKCResult_SignatureNoneZ* orig_conv = (LDKCResult_SignatureNoneZ*)(orig & ~1);
        LDKCResult_SignatureNoneZ* ret_conv = MALLOC(sizeof(LDKCResult_SignatureNoneZ), "LDKCResult_SignatureNoneZ");
        *ret_conv = CResult_SignatureNoneZ_clone(orig_conv);
        return (long)ret_conv;
 }
 
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1CVec_1SignatureZNoneZ_1ok(JNIEnv *env, jclass clz, jobjectArray o) {
-       LDKCVec_SignatureZ o_constr;
-       o_constr.datalen = (*env)->GetArrayLength(env, o);
-       if (o_constr.datalen > 0)
-               o_constr.data = MALLOC(o_constr.datalen * sizeof(LDKSignature), "LDKCVec_SignatureZ Elements");
-       else
-               o_constr.data = NULL;
-       for (size_t i = 0; i < o_constr.datalen; i++) {
-               int8_tArray arr_conv_8 = (*env)->GetObjectArrayElement(env, o, i);
-               LDKSignature arr_conv_8_ref;
-               CHECK((*env)->GetArrayLength(env, arr_conv_8) == 64);
-               (*env)->GetByteArrayRegion(env, arr_conv_8, 0, 64, arr_conv_8_ref.compact_form);
-               o_constr.data[i] = arr_conv_8_ref;
-       }
-       LDKCResult_CVec_SignatureZNoneZ* ret_conv = MALLOC(sizeof(LDKCResult_CVec_SignatureZNoneZ), "LDKCResult_CVec_SignatureZNoneZ");
-       *ret_conv = CResult_CVec_SignatureZNoneZ_ok(o_constr);
-       return (long)ret_conv;
-}
-
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1CVec_1SignatureZNoneZ_1err(JNIEnv *env, jclass clz) {
-       LDKCResult_CVec_SignatureZNoneZ* ret_conv = MALLOC(sizeof(LDKCResult_CVec_SignatureZNoneZ), "LDKCResult_CVec_SignatureZNoneZ");
-       *ret_conv = CResult_CVec_SignatureZNoneZ_err();
-       return (long)ret_conv;
-}
-
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1CVec_1SignatureZNoneZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_CVec_SignatureZNoneZ _res_conv = *(LDKCResult_CVec_SignatureZNoneZ*)_res;
-       FREE((void*)_res);
-       CResult_CVec_SignatureZNoneZ_free(_res_conv);
-}
-
-JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1CVec_1SignatureZNoneZ_1clone(JNIEnv *env, jclass clz, int64_t orig) {
-       LDKCResult_CVec_SignatureZNoneZ* orig_conv = (LDKCResult_CVec_SignatureZNoneZ*)orig;
-       LDKCResult_CVec_SignatureZNoneZ* ret_conv = MALLOC(sizeof(LDKCResult_CVec_SignatureZNoneZ), "LDKCResult_CVec_SignatureZNoneZ");
-       *ret_conv = CResult_CVec_SignatureZNoneZ_clone(orig_conv);
-       return (long)ret_conv;
-}
-
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1ChanKeySignerDecodeErrorZ_1ok(JNIEnv *env, jclass clz, int64_t o) {
-       LDKChannelKeys o_conv = *(LDKChannelKeys*)o;
+       LDKChannelKeys o_conv = *(LDKChannelKeys*)(((uint64_t)o) & ~1);
        if (o_conv.free == LDKChannelKeys_JCalls_free) {
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKChannelKeys_JCalls_clone(o_conv.this_arg);
@@ -6111,24 +5942,31 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1ChanKeySignerDecod
        LDKDecodeError e_conv;
        e_conv.inner = (void*)(e & (~1));
        e_conv.is_owned = (e & 1) || (e == 0);
-       // Warning: we may need a move here but can't clone!
+       e_conv = DecodeError_clone(&e_conv);
        LDKCResult_ChanKeySignerDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_ChanKeySignerDecodeErrorZ), "LDKCResult_ChanKeySignerDecodeErrorZ");
        *ret_conv = CResult_ChanKeySignerDecodeErrorZ_err(e_conv);
        return (long)ret_conv;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1ChanKeySignerDecodeErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_ChanKeySignerDecodeErrorZ _res_conv = *(LDKCResult_ChanKeySignerDecodeErrorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_ChanKeySignerDecodeErrorZ _res_conv = *(LDKCResult_ChanKeySignerDecodeErrorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_ChanKeySignerDecodeErrorZ_free(_res_conv);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1ChanKeySignerDecodeErrorZ_1clone(JNIEnv *env, jclass clz, int64_t orig) {
+       LDKCResult_ChanKeySignerDecodeErrorZ* orig_conv = (LDKCResult_ChanKeySignerDecodeErrorZ*)(orig & ~1);
+       LDKCResult_ChanKeySignerDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_ChanKeySignerDecodeErrorZ), "LDKCResult_ChanKeySignerDecodeErrorZ");
+       *ret_conv = CResult_ChanKeySignerDecodeErrorZ_clone(orig_conv);
+       return (long)ret_conv;
+}
+
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1InMemoryChannelKeysDecodeErrorZ_1ok(JNIEnv *env, jclass clz, int64_t o) {
        LDKInMemoryChannelKeys o_conv;
        o_conv.inner = (void*)(o & (~1));
        o_conv.is_owned = (o & 1) || (o == 0);
-       if (o_conv.inner != NULL)
-               o_conv = InMemoryChannelKeys_clone(&o_conv);
+       o_conv = InMemoryChannelKeys_clone(&o_conv);
        LDKCResult_InMemoryChannelKeysDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_InMemoryChannelKeysDecodeErrorZ), "LDKCResult_InMemoryChannelKeysDecodeErrorZ");
        *ret_conv = CResult_InMemoryChannelKeysDecodeErrorZ_ok(o_conv);
        return (long)ret_conv;
@@ -6138,20 +5976,21 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1InMemoryChannelKey
        LDKDecodeError e_conv;
        e_conv.inner = (void*)(e & (~1));
        e_conv.is_owned = (e & 1) || (e == 0);
-       // Warning: we may need a move here but can't clone!
+       e_conv = DecodeError_clone(&e_conv);
        LDKCResult_InMemoryChannelKeysDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_InMemoryChannelKeysDecodeErrorZ), "LDKCResult_InMemoryChannelKeysDecodeErrorZ");
        *ret_conv = CResult_InMemoryChannelKeysDecodeErrorZ_err(e_conv);
        return (long)ret_conv;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1InMemoryChannelKeysDecodeErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_InMemoryChannelKeysDecodeErrorZ _res_conv = *(LDKCResult_InMemoryChannelKeysDecodeErrorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_InMemoryChannelKeysDecodeErrorZ _res_conv = *(LDKCResult_InMemoryChannelKeysDecodeErrorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_InMemoryChannelKeysDecodeErrorZ_free(_res_conv);
 }
 
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1TxOutAccessErrorZ_1ok(JNIEnv *env, jclass clz, int64_t o) {
-       LDKTxOut o_conv = *(LDKTxOut*)o;
+       LDKTxOut o_conv = *(LDKTxOut*)(((uint64_t)o) & ~1);
        FREE((void*)o);
        LDKCResult_TxOutAccessErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_TxOutAccessErrorZ), "LDKCResult_TxOutAccessErrorZ");
        *ret_conv = CResult_TxOutAccessErrorZ_ok(o_conv);
@@ -6166,11 +6005,19 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1TxOutAccessErrorZ_
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1TxOutAccessErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_TxOutAccessErrorZ _res_conv = *(LDKCResult_TxOutAccessErrorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_TxOutAccessErrorZ _res_conv = *(LDKCResult_TxOutAccessErrorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_TxOutAccessErrorZ_free(_res_conv);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1TxOutAccessErrorZ_1clone(JNIEnv *env, jclass clz, int64_t orig) {
+       LDKCResult_TxOutAccessErrorZ* orig_conv = (LDKCResult_TxOutAccessErrorZ*)(orig & ~1);
+       LDKCResult_TxOutAccessErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_TxOutAccessErrorZ), "LDKCResult_TxOutAccessErrorZ");
+       *ret_conv = CResult_TxOutAccessErrorZ_clone(orig_conv);
+       return (long)ret_conv;
+}
+
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NoneAPIErrorZ_1ok(JNIEnv *env, jclass clz) {
        LDKCResult_NoneAPIErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_NoneAPIErrorZ), "LDKCResult_NoneAPIErrorZ");
        *ret_conv = CResult_NoneAPIErrorZ_ok();
@@ -6178,7 +6025,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NoneAPIErrorZ_1ok(
 }
 
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NoneAPIErrorZ_1err(JNIEnv *env, jclass clz, int64_t e) {
-       LDKAPIError e_conv = *(LDKAPIError*)e;
+       LDKAPIError e_conv = *(LDKAPIError*)(((uint64_t)e) & ~1);
        FREE((void*)e);
        LDKCResult_NoneAPIErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_NoneAPIErrorZ), "LDKCResult_NoneAPIErrorZ");
        *ret_conv = CResult_NoneAPIErrorZ_err(e_conv);
@@ -6186,7 +6033,8 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NoneAPIErrorZ_1err
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1NoneAPIErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_NoneAPIErrorZ _res_conv = *(LDKCResult_NoneAPIErrorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_NoneAPIErrorZ _res_conv = *(LDKCResult_NoneAPIErrorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_NoneAPIErrorZ_free(_res_conv);
 }
@@ -6220,18 +6068,26 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NonePaymentSendFai
        LDKPaymentSendFailure e_conv;
        e_conv.inner = (void*)(e & (~1));
        e_conv.is_owned = (e & 1) || (e == 0);
-       // Warning: we may need a move here but can't clone!
+       e_conv = PaymentSendFailure_clone(&e_conv);
        LDKCResult_NonePaymentSendFailureZ* ret_conv = MALLOC(sizeof(LDKCResult_NonePaymentSendFailureZ), "LDKCResult_NonePaymentSendFailureZ");
        *ret_conv = CResult_NonePaymentSendFailureZ_err(e_conv);
        return (long)ret_conv;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1NonePaymentSendFailureZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_NonePaymentSendFailureZ _res_conv = *(LDKCResult_NonePaymentSendFailureZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_NonePaymentSendFailureZ _res_conv = *(LDKCResult_NonePaymentSendFailureZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_NonePaymentSendFailureZ_free(_res_conv);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NonePaymentSendFailureZ_1clone(JNIEnv *env, jclass clz, int64_t orig) {
+       LDKCResult_NonePaymentSendFailureZ* orig_conv = (LDKCResult_NonePaymentSendFailureZ*)(orig & ~1);
+       LDKCResult_NonePaymentSendFailureZ* ret_conv = MALLOC(sizeof(LDKCResult_NonePaymentSendFailureZ), "LDKCResult_NonePaymentSendFailureZ");
+       *ret_conv = CResult_NonePaymentSendFailureZ_clone(orig_conv);
+       return (long)ret_conv;
+}
+
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CVec_1NetAddressZ_1free(JNIEnv *env, jclass clz, int64_tArray _res) {
        LDKCVec_NetAddressZ _res_constr;
        _res_constr.datalen = (*env)->GetArrayLength(env, _res);
@@ -6242,7 +6098,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CVec_1NetAddressZ_1free(JNIEnv
        int64_t* _res_vals = (*env)->GetLongArrayElements (env, _res, NULL);
        for (size_t m = 0; m < _res_constr.datalen; m++) {
                int64_t arr_conv_12 = _res_vals[m];
-               LDKNetAddress arr_conv_12_conv = *(LDKNetAddress*)arr_conv_12;
+               LDKNetAddress arr_conv_12_conv = *(LDKNetAddress*)(((uint64_t)arr_conv_12) & ~1);
                FREE((void*)arr_conv_12);
                _res_constr.data[m] = arr_conv_12_conv;
        }
@@ -6270,7 +6126,8 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CVec_1ChannelMonitorZ_1free(JN
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_C2Tuple_1BlockHashChannelManagerZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKC2Tuple_BlockHashChannelManagerZ _res_conv = *(LDKC2Tuple_BlockHashChannelManagerZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKC2Tuple_BlockHashChannelManagerZ _res_conv = *(LDKC2Tuple_BlockHashChannelManagerZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        C2Tuple_BlockHashChannelManagerZ_free(_res_conv);
 }
@@ -6282,16 +6139,14 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_C2Tuple_1BlockHashChannelMa
        LDKChannelManager b_conv;
        b_conv.inner = (void*)(b & (~1));
        b_conv.is_owned = (b & 1) || (b == 0);
-       // Warning: we may need a move here but can't clone!
+       // Warning: we need a move here but no clone is available for LDKChannelManager
        LDKC2Tuple_BlockHashChannelManagerZ* ret_ref = MALLOC(sizeof(LDKC2Tuple_BlockHashChannelManagerZ), "LDKC2Tuple_BlockHashChannelManagerZ");
        *ret_ref = C2Tuple_BlockHashChannelManagerZ_new(a_ref, b_conv);
-       ret_ref->a = ThirtyTwoBytes_clone(&ret_ref->a);
-       // XXX: We likely need to clone here, but no _clone fn is available for ChannelManager
        return (long)ret_ref;
 }
 
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1C2Tuple_1BlockHashChannelManagerZDecodeErrorZ_1ok(JNIEnv *env, jclass clz, int64_t o) {
-       LDKC2Tuple_BlockHashChannelManagerZ o_conv = *(LDKC2Tuple_BlockHashChannelManagerZ*)o;
+       LDKC2Tuple_BlockHashChannelManagerZ o_conv = *(LDKC2Tuple_BlockHashChannelManagerZ*)(((uint64_t)o) & ~1);
        FREE((void*)o);
        LDKCResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ), "LDKCResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ");
        *ret_conv = CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ_ok(o_conv);
@@ -6302,20 +6157,21 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1C2Tuple_1BlockHash
        LDKDecodeError e_conv;
        e_conv.inner = (void*)(e & (~1));
        e_conv.is_owned = (e & 1) || (e == 0);
-       // Warning: we may need a move here but can't clone!
+       e_conv = DecodeError_clone(&e_conv);
        LDKCResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ), "LDKCResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ");
        *ret_conv = CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ_err(e_conv);
        return (long)ret_conv;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1C2Tuple_1BlockHashChannelManagerZDecodeErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ _res_conv = *(LDKCResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ _res_conv = *(LDKCResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ_free(_res_conv);
 }
 
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NetAddressu8Z_1ok(JNIEnv *env, jclass clz, int64_t o) {
-       LDKNetAddress o_conv = *(LDKNetAddress*)o;
+       LDKNetAddress o_conv = *(LDKNetAddress*)(((uint64_t)o) & ~1);
        FREE((void*)o);
        LDKCResult_NetAddressu8Z* ret_conv = MALLOC(sizeof(LDKCResult_NetAddressu8Z), "LDKCResult_NetAddressu8Z");
        *ret_conv = CResult_NetAddressu8Z_ok(o_conv);
@@ -6329,13 +6185,21 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NetAddressu8Z_1err
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1NetAddressu8Z_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_NetAddressu8Z _res_conv = *(LDKCResult_NetAddressu8Z*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_NetAddressu8Z _res_conv = *(LDKCResult_NetAddressu8Z*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_NetAddressu8Z_free(_res_conv);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NetAddressu8Z_1clone(JNIEnv *env, jclass clz, int64_t orig) {
+       LDKCResult_NetAddressu8Z* orig_conv = (LDKCResult_NetAddressu8Z*)(orig & ~1);
+       LDKCResult_NetAddressu8Z* ret_conv = MALLOC(sizeof(LDKCResult_NetAddressu8Z), "LDKCResult_NetAddressu8Z");
+       *ret_conv = CResult_NetAddressu8Z_clone(orig_conv);
+       return (long)ret_conv;
+}
+
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1CResult_1NetAddressu8ZDecodeErrorZ_1ok(JNIEnv *env, jclass clz, int64_t o) {
-       LDKCResult_NetAddressu8Z o_conv = *(LDKCResult_NetAddressu8Z*)o;
+       LDKCResult_NetAddressu8Z o_conv = *(LDKCResult_NetAddressu8Z*)(((uint64_t)o) & ~1);
        FREE((void*)o);
        LDKCResult_CResult_NetAddressu8ZDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_CResult_NetAddressu8ZDecodeErrorZ), "LDKCResult_CResult_NetAddressu8ZDecodeErrorZ");
        *ret_conv = CResult_CResult_NetAddressu8ZDecodeErrorZ_ok(o_conv);
@@ -6346,14 +6210,15 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1CResult_1NetAddres
        LDKDecodeError e_conv;
        e_conv.inner = (void*)(e & (~1));
        e_conv.is_owned = (e & 1) || (e == 0);
-       // Warning: we may need a move here but can't clone!
+       e_conv = DecodeError_clone(&e_conv);
        LDKCResult_CResult_NetAddressu8ZDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_CResult_NetAddressu8ZDecodeErrorZ), "LDKCResult_CResult_NetAddressu8ZDecodeErrorZ");
        *ret_conv = CResult_CResult_NetAddressu8ZDecodeErrorZ_err(e_conv);
        return (long)ret_conv;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1CResult_1NetAddressu8ZDecodeErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_CResult_NetAddressu8ZDecodeErrorZ _res_conv = *(LDKCResult_CResult_NetAddressu8ZDecodeErrorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_CResult_NetAddressu8ZDecodeErrorZ _res_conv = *(LDKCResult_CResult_NetAddressu8ZDecodeErrorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_CResult_NetAddressu8ZDecodeErrorZ_free(_res_conv);
 }
@@ -6460,20 +6325,29 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1boolLightningError
        LDKLightningError e_conv;
        e_conv.inner = (void*)(e & (~1));
        e_conv.is_owned = (e & 1) || (e == 0);
-       // Warning: we may need a move here but can't clone!
+       e_conv = LightningError_clone(&e_conv);
        LDKCResult_boolLightningErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_boolLightningErrorZ), "LDKCResult_boolLightningErrorZ");
        *ret_conv = CResult_boolLightningErrorZ_err(e_conv);
        return (long)ret_conv;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1boolLightningErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_boolLightningErrorZ _res_conv = *(LDKCResult_boolLightningErrorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_boolLightningErrorZ _res_conv = *(LDKCResult_boolLightningErrorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_boolLightningErrorZ_free(_res_conv);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1boolLightningErrorZ_1clone(JNIEnv *env, jclass clz, int64_t orig) {
+       LDKCResult_boolLightningErrorZ* orig_conv = (LDKCResult_boolLightningErrorZ*)(orig & ~1);
+       LDKCResult_boolLightningErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_boolLightningErrorZ), "LDKCResult_boolLightningErrorZ");
+       *ret_conv = CResult_boolLightningErrorZ_clone(orig_conv);
+       return (long)ret_conv;
+}
+
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_C3Tuple_1ChannelAnnouncementChannelUpdateChannelUpdateZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ _res_conv = *(LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ _res_conv = *(LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ_free(_res_conv);
 }
@@ -6482,23 +6356,17 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_C3Tuple_1ChannelAnnouncemen
        LDKChannelAnnouncement a_conv;
        a_conv.inner = (void*)(a & (~1));
        a_conv.is_owned = (a & 1) || (a == 0);
-       if (a_conv.inner != NULL)
-               a_conv = ChannelAnnouncement_clone(&a_conv);
+       a_conv = ChannelAnnouncement_clone(&a_conv);
        LDKChannelUpdate b_conv;
        b_conv.inner = (void*)(b & (~1));
        b_conv.is_owned = (b & 1) || (b == 0);
-       if (b_conv.inner != NULL)
-               b_conv = ChannelUpdate_clone(&b_conv);
+       b_conv = ChannelUpdate_clone(&b_conv);
        LDKChannelUpdate c_conv;
        c_conv.inner = (void*)(c & (~1));
        c_conv.is_owned = (c & 1) || (c == 0);
-       if (c_conv.inner != NULL)
-               c_conv = ChannelUpdate_clone(&c_conv);
+       c_conv = ChannelUpdate_clone(&c_conv);
        LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ* ret_ref = MALLOC(sizeof(LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ), "LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ");
        *ret_ref = C3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ_new(a_conv, b_conv, c_conv);
-       ret_ref->a = ChannelAnnouncement_clone(&ret_ref->a);
-       ret_ref->b = ChannelUpdate_clone(&ret_ref->b);
-       ret_ref->c = ChannelUpdate_clone(&ret_ref->c);
        return (long)ret_ref;
 }
 
@@ -6512,7 +6380,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CVec_1C3Tuple_1ChannelAnnounce
        int64_t* _res_vals = (*env)->GetLongArrayElements (env, _res, NULL);
        for (size_t l = 0; l < _res_constr.datalen; l++) {
                int64_t arr_conv_63 = _res_vals[l];
-               LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ arr_conv_63_conv = *(LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ*)arr_conv_63;
+               LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ arr_conv_63_conv = *(LDKC3Tuple_ChannelAnnouncementChannelUpdateChannelUpdateZ*)(((uint64_t)arr_conv_63) & ~1);
                FREE((void*)arr_conv_63);
                _res_constr.data[l] = arr_conv_63_conv;
        }
@@ -6549,24 +6417,31 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NoneLightningError
        LDKLightningError e_conv;
        e_conv.inner = (void*)(e & (~1));
        e_conv.is_owned = (e & 1) || (e == 0);
-       // Warning: we may need a move here but can't clone!
+       e_conv = LightningError_clone(&e_conv);
        LDKCResult_NoneLightningErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_NoneLightningErrorZ), "LDKCResult_NoneLightningErrorZ");
        *ret_conv = CResult_NoneLightningErrorZ_err(e_conv);
        return (long)ret_conv;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1NoneLightningErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_NoneLightningErrorZ _res_conv = *(LDKCResult_NoneLightningErrorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_NoneLightningErrorZ _res_conv = *(LDKCResult_NoneLightningErrorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_NoneLightningErrorZ_free(_res_conv);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NoneLightningErrorZ_1clone(JNIEnv *env, jclass clz, int64_t orig) {
+       LDKCResult_NoneLightningErrorZ* orig_conv = (LDKCResult_NoneLightningErrorZ*)(orig & ~1);
+       LDKCResult_NoneLightningErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_NoneLightningErrorZ), "LDKCResult_NoneLightningErrorZ");
+       *ret_conv = CResult_NoneLightningErrorZ_clone(orig_conv);
+       return (long)ret_conv;
+}
+
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1ChannelReestablishDecodeErrorZ_1ok(JNIEnv *env, jclass clz, int64_t o) {
        LDKChannelReestablish o_conv;
        o_conv.inner = (void*)(o & (~1));
        o_conv.is_owned = (o & 1) || (o == 0);
-       if (o_conv.inner != NULL)
-               o_conv = ChannelReestablish_clone(&o_conv);
+       o_conv = ChannelReestablish_clone(&o_conv);
        LDKCResult_ChannelReestablishDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_ChannelReestablishDecodeErrorZ), "LDKCResult_ChannelReestablishDecodeErrorZ");
        *ret_conv = CResult_ChannelReestablishDecodeErrorZ_ok(o_conv);
        return (long)ret_conv;
@@ -6576,14 +6451,15 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1ChannelReestablish
        LDKDecodeError e_conv;
        e_conv.inner = (void*)(e & (~1));
        e_conv.is_owned = (e & 1) || (e == 0);
-       // Warning: we may need a move here but can't clone!
+       e_conv = DecodeError_clone(&e_conv);
        LDKCResult_ChannelReestablishDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_ChannelReestablishDecodeErrorZ), "LDKCResult_ChannelReestablishDecodeErrorZ");
        *ret_conv = CResult_ChannelReestablishDecodeErrorZ_err(e_conv);
        return (long)ret_conv;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1ChannelReestablishDecodeErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_ChannelReestablishDecodeErrorZ _res_conv = *(LDKCResult_ChannelReestablishDecodeErrorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_ChannelReestablishDecodeErrorZ _res_conv = *(LDKCResult_ChannelReestablishDecodeErrorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_ChannelReestablishDecodeErrorZ_free(_res_conv);
 }
@@ -6592,8 +6468,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1InitDecodeErrorZ_1
        LDKInit o_conv;
        o_conv.inner = (void*)(o & (~1));
        o_conv.is_owned = (o & 1) || (o == 0);
-       if (o_conv.inner != NULL)
-               o_conv = Init_clone(&o_conv);
+       o_conv = Init_clone(&o_conv);
        LDKCResult_InitDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_InitDecodeErrorZ), "LDKCResult_InitDecodeErrorZ");
        *ret_conv = CResult_InitDecodeErrorZ_ok(o_conv);
        return (long)ret_conv;
@@ -6603,14 +6478,15 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1InitDecodeErrorZ_1
        LDKDecodeError e_conv;
        e_conv.inner = (void*)(e & (~1));
        e_conv.is_owned = (e & 1) || (e == 0);
-       // Warning: we may need a move here but can't clone!
+       e_conv = DecodeError_clone(&e_conv);
        LDKCResult_InitDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_InitDecodeErrorZ), "LDKCResult_InitDecodeErrorZ");
        *ret_conv = CResult_InitDecodeErrorZ_err(e_conv);
        return (long)ret_conv;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1InitDecodeErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_InitDecodeErrorZ _res_conv = *(LDKCResult_InitDecodeErrorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_InitDecodeErrorZ _res_conv = *(LDKCResult_InitDecodeErrorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_InitDecodeErrorZ_free(_res_conv);
 }
@@ -6619,8 +6495,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1PingDecodeErrorZ_1
        LDKPing o_conv;
        o_conv.inner = (void*)(o & (~1));
        o_conv.is_owned = (o & 1) || (o == 0);
-       if (o_conv.inner != NULL)
-               o_conv = Ping_clone(&o_conv);
+       o_conv = Ping_clone(&o_conv);
        LDKCResult_PingDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_PingDecodeErrorZ), "LDKCResult_PingDecodeErrorZ");
        *ret_conv = CResult_PingDecodeErrorZ_ok(o_conv);
        return (long)ret_conv;
@@ -6630,14 +6505,15 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1PingDecodeErrorZ_1
        LDKDecodeError e_conv;
        e_conv.inner = (void*)(e & (~1));
        e_conv.is_owned = (e & 1) || (e == 0);
-       // Warning: we may need a move here but can't clone!
+       e_conv = DecodeError_clone(&e_conv);
        LDKCResult_PingDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_PingDecodeErrorZ), "LDKCResult_PingDecodeErrorZ");
        *ret_conv = CResult_PingDecodeErrorZ_err(e_conv);
        return (long)ret_conv;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1PingDecodeErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_PingDecodeErrorZ _res_conv = *(LDKCResult_PingDecodeErrorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_PingDecodeErrorZ _res_conv = *(LDKCResult_PingDecodeErrorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_PingDecodeErrorZ_free(_res_conv);
 }
@@ -6646,8 +6522,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1PongDecodeErrorZ_1
        LDKPong o_conv;
        o_conv.inner = (void*)(o & (~1));
        o_conv.is_owned = (o & 1) || (o == 0);
-       if (o_conv.inner != NULL)
-               o_conv = Pong_clone(&o_conv);
+       o_conv = Pong_clone(&o_conv);
        LDKCResult_PongDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_PongDecodeErrorZ), "LDKCResult_PongDecodeErrorZ");
        *ret_conv = CResult_PongDecodeErrorZ_ok(o_conv);
        return (long)ret_conv;
@@ -6657,14 +6532,15 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1PongDecodeErrorZ_1
        LDKDecodeError e_conv;
        e_conv.inner = (void*)(e & (~1));
        e_conv.is_owned = (e & 1) || (e == 0);
-       // Warning: we may need a move here but can't clone!
+       e_conv = DecodeError_clone(&e_conv);
        LDKCResult_PongDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_PongDecodeErrorZ), "LDKCResult_PongDecodeErrorZ");
        *ret_conv = CResult_PongDecodeErrorZ_err(e_conv);
        return (long)ret_conv;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1PongDecodeErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_PongDecodeErrorZ _res_conv = *(LDKCResult_PongDecodeErrorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_PongDecodeErrorZ _res_conv = *(LDKCResult_PongDecodeErrorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_PongDecodeErrorZ_free(_res_conv);
 }
@@ -6673,8 +6549,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1UnsignedChannelAnn
        LDKUnsignedChannelAnnouncement o_conv;
        o_conv.inner = (void*)(o & (~1));
        o_conv.is_owned = (o & 1) || (o == 0);
-       if (o_conv.inner != NULL)
-               o_conv = UnsignedChannelAnnouncement_clone(&o_conv);
+       o_conv = UnsignedChannelAnnouncement_clone(&o_conv);
        LDKCResult_UnsignedChannelAnnouncementDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_UnsignedChannelAnnouncementDecodeErrorZ), "LDKCResult_UnsignedChannelAnnouncementDecodeErrorZ");
        *ret_conv = CResult_UnsignedChannelAnnouncementDecodeErrorZ_ok(o_conv);
        return (long)ret_conv;
@@ -6684,14 +6559,15 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1UnsignedChannelAnn
        LDKDecodeError e_conv;
        e_conv.inner = (void*)(e & (~1));
        e_conv.is_owned = (e & 1) || (e == 0);
-       // Warning: we may need a move here but can't clone!
+       e_conv = DecodeError_clone(&e_conv);
        LDKCResult_UnsignedChannelAnnouncementDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_UnsignedChannelAnnouncementDecodeErrorZ), "LDKCResult_UnsignedChannelAnnouncementDecodeErrorZ");
        *ret_conv = CResult_UnsignedChannelAnnouncementDecodeErrorZ_err(e_conv);
        return (long)ret_conv;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1UnsignedChannelAnnouncementDecodeErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_UnsignedChannelAnnouncementDecodeErrorZ _res_conv = *(LDKCResult_UnsignedChannelAnnouncementDecodeErrorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_UnsignedChannelAnnouncementDecodeErrorZ _res_conv = *(LDKCResult_UnsignedChannelAnnouncementDecodeErrorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_UnsignedChannelAnnouncementDecodeErrorZ_free(_res_conv);
 }
@@ -6700,8 +6576,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1UnsignedChannelUpd
        LDKUnsignedChannelUpdate o_conv;
        o_conv.inner = (void*)(o & (~1));
        o_conv.is_owned = (o & 1) || (o == 0);
-       if (o_conv.inner != NULL)
-               o_conv = UnsignedChannelUpdate_clone(&o_conv);
+       o_conv = UnsignedChannelUpdate_clone(&o_conv);
        LDKCResult_UnsignedChannelUpdateDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_UnsignedChannelUpdateDecodeErrorZ), "LDKCResult_UnsignedChannelUpdateDecodeErrorZ");
        *ret_conv = CResult_UnsignedChannelUpdateDecodeErrorZ_ok(o_conv);
        return (long)ret_conv;
@@ -6711,14 +6586,15 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1UnsignedChannelUpd
        LDKDecodeError e_conv;
        e_conv.inner = (void*)(e & (~1));
        e_conv.is_owned = (e & 1) || (e == 0);
-       // Warning: we may need a move here but can't clone!
+       e_conv = DecodeError_clone(&e_conv);
        LDKCResult_UnsignedChannelUpdateDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_UnsignedChannelUpdateDecodeErrorZ), "LDKCResult_UnsignedChannelUpdateDecodeErrorZ");
        *ret_conv = CResult_UnsignedChannelUpdateDecodeErrorZ_err(e_conv);
        return (long)ret_conv;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1UnsignedChannelUpdateDecodeErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_UnsignedChannelUpdateDecodeErrorZ _res_conv = *(LDKCResult_UnsignedChannelUpdateDecodeErrorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_UnsignedChannelUpdateDecodeErrorZ _res_conv = *(LDKCResult_UnsignedChannelUpdateDecodeErrorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_UnsignedChannelUpdateDecodeErrorZ_free(_res_conv);
 }
@@ -6727,8 +6603,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1ErrorMessageDecode
        LDKErrorMessage o_conv;
        o_conv.inner = (void*)(o & (~1));
        o_conv.is_owned = (o & 1) || (o == 0);
-       if (o_conv.inner != NULL)
-               o_conv = ErrorMessage_clone(&o_conv);
+       o_conv = ErrorMessage_clone(&o_conv);
        LDKCResult_ErrorMessageDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_ErrorMessageDecodeErrorZ), "LDKCResult_ErrorMessageDecodeErrorZ");
        *ret_conv = CResult_ErrorMessageDecodeErrorZ_ok(o_conv);
        return (long)ret_conv;
@@ -6738,14 +6613,15 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1ErrorMessageDecode
        LDKDecodeError e_conv;
        e_conv.inner = (void*)(e & (~1));
        e_conv.is_owned = (e & 1) || (e == 0);
-       // Warning: we may need a move here but can't clone!
+       e_conv = DecodeError_clone(&e_conv);
        LDKCResult_ErrorMessageDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_ErrorMessageDecodeErrorZ), "LDKCResult_ErrorMessageDecodeErrorZ");
        *ret_conv = CResult_ErrorMessageDecodeErrorZ_err(e_conv);
        return (long)ret_conv;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1ErrorMessageDecodeErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_ErrorMessageDecodeErrorZ _res_conv = *(LDKCResult_ErrorMessageDecodeErrorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_ErrorMessageDecodeErrorZ _res_conv = *(LDKCResult_ErrorMessageDecodeErrorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_ErrorMessageDecodeErrorZ_free(_res_conv);
 }
@@ -6754,8 +6630,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1UnsignedNodeAnnoun
        LDKUnsignedNodeAnnouncement o_conv;
        o_conv.inner = (void*)(o & (~1));
        o_conv.is_owned = (o & 1) || (o == 0);
-       if (o_conv.inner != NULL)
-               o_conv = UnsignedNodeAnnouncement_clone(&o_conv);
+       o_conv = UnsignedNodeAnnouncement_clone(&o_conv);
        LDKCResult_UnsignedNodeAnnouncementDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_UnsignedNodeAnnouncementDecodeErrorZ), "LDKCResult_UnsignedNodeAnnouncementDecodeErrorZ");
        *ret_conv = CResult_UnsignedNodeAnnouncementDecodeErrorZ_ok(o_conv);
        return (long)ret_conv;
@@ -6765,14 +6640,15 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1UnsignedNodeAnnoun
        LDKDecodeError e_conv;
        e_conv.inner = (void*)(e & (~1));
        e_conv.is_owned = (e & 1) || (e == 0);
-       // Warning: we may need a move here but can't clone!
+       e_conv = DecodeError_clone(&e_conv);
        LDKCResult_UnsignedNodeAnnouncementDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_UnsignedNodeAnnouncementDecodeErrorZ), "LDKCResult_UnsignedNodeAnnouncementDecodeErrorZ");
        *ret_conv = CResult_UnsignedNodeAnnouncementDecodeErrorZ_err(e_conv);
        return (long)ret_conv;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1UnsignedNodeAnnouncementDecodeErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_UnsignedNodeAnnouncementDecodeErrorZ _res_conv = *(LDKCResult_UnsignedNodeAnnouncementDecodeErrorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_UnsignedNodeAnnouncementDecodeErrorZ _res_conv = *(LDKCResult_UnsignedNodeAnnouncementDecodeErrorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_UnsignedNodeAnnouncementDecodeErrorZ_free(_res_conv);
 }
@@ -6781,8 +6657,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1QueryShortChannelI
        LDKQueryShortChannelIds o_conv;
        o_conv.inner = (void*)(o & (~1));
        o_conv.is_owned = (o & 1) || (o == 0);
-       if (o_conv.inner != NULL)
-               o_conv = QueryShortChannelIds_clone(&o_conv);
+       o_conv = QueryShortChannelIds_clone(&o_conv);
        LDKCResult_QueryShortChannelIdsDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_QueryShortChannelIdsDecodeErrorZ), "LDKCResult_QueryShortChannelIdsDecodeErrorZ");
        *ret_conv = CResult_QueryShortChannelIdsDecodeErrorZ_ok(o_conv);
        return (long)ret_conv;
@@ -6792,14 +6667,15 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1QueryShortChannelI
        LDKDecodeError e_conv;
        e_conv.inner = (void*)(e & (~1));
        e_conv.is_owned = (e & 1) || (e == 0);
-       // Warning: we may need a move here but can't clone!
+       e_conv = DecodeError_clone(&e_conv);
        LDKCResult_QueryShortChannelIdsDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_QueryShortChannelIdsDecodeErrorZ), "LDKCResult_QueryShortChannelIdsDecodeErrorZ");
        *ret_conv = CResult_QueryShortChannelIdsDecodeErrorZ_err(e_conv);
        return (long)ret_conv;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1QueryShortChannelIdsDecodeErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_QueryShortChannelIdsDecodeErrorZ _res_conv = *(LDKCResult_QueryShortChannelIdsDecodeErrorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_QueryShortChannelIdsDecodeErrorZ _res_conv = *(LDKCResult_QueryShortChannelIdsDecodeErrorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_QueryShortChannelIdsDecodeErrorZ_free(_res_conv);
 }
@@ -6808,8 +6684,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1ReplyShortChannelI
        LDKReplyShortChannelIdsEnd o_conv;
        o_conv.inner = (void*)(o & (~1));
        o_conv.is_owned = (o & 1) || (o == 0);
-       if (o_conv.inner != NULL)
-               o_conv = ReplyShortChannelIdsEnd_clone(&o_conv);
+       o_conv = ReplyShortChannelIdsEnd_clone(&o_conv);
        LDKCResult_ReplyShortChannelIdsEndDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_ReplyShortChannelIdsEndDecodeErrorZ), "LDKCResult_ReplyShortChannelIdsEndDecodeErrorZ");
        *ret_conv = CResult_ReplyShortChannelIdsEndDecodeErrorZ_ok(o_conv);
        return (long)ret_conv;
@@ -6819,14 +6694,15 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1ReplyShortChannelI
        LDKDecodeError e_conv;
        e_conv.inner = (void*)(e & (~1));
        e_conv.is_owned = (e & 1) || (e == 0);
-       // Warning: we may need a move here but can't clone!
+       e_conv = DecodeError_clone(&e_conv);
        LDKCResult_ReplyShortChannelIdsEndDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_ReplyShortChannelIdsEndDecodeErrorZ), "LDKCResult_ReplyShortChannelIdsEndDecodeErrorZ");
        *ret_conv = CResult_ReplyShortChannelIdsEndDecodeErrorZ_err(e_conv);
        return (long)ret_conv;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1ReplyShortChannelIdsEndDecodeErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_ReplyShortChannelIdsEndDecodeErrorZ _res_conv = *(LDKCResult_ReplyShortChannelIdsEndDecodeErrorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_ReplyShortChannelIdsEndDecodeErrorZ _res_conv = *(LDKCResult_ReplyShortChannelIdsEndDecodeErrorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_ReplyShortChannelIdsEndDecodeErrorZ_free(_res_conv);
 }
@@ -6835,8 +6711,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1QueryChannelRangeD
        LDKQueryChannelRange o_conv;
        o_conv.inner = (void*)(o & (~1));
        o_conv.is_owned = (o & 1) || (o == 0);
-       if (o_conv.inner != NULL)
-               o_conv = QueryChannelRange_clone(&o_conv);
+       o_conv = QueryChannelRange_clone(&o_conv);
        LDKCResult_QueryChannelRangeDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_QueryChannelRangeDecodeErrorZ), "LDKCResult_QueryChannelRangeDecodeErrorZ");
        *ret_conv = CResult_QueryChannelRangeDecodeErrorZ_ok(o_conv);
        return (long)ret_conv;
@@ -6846,14 +6721,15 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1QueryChannelRangeD
        LDKDecodeError e_conv;
        e_conv.inner = (void*)(e & (~1));
        e_conv.is_owned = (e & 1) || (e == 0);
-       // Warning: we may need a move here but can't clone!
+       e_conv = DecodeError_clone(&e_conv);
        LDKCResult_QueryChannelRangeDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_QueryChannelRangeDecodeErrorZ), "LDKCResult_QueryChannelRangeDecodeErrorZ");
        *ret_conv = CResult_QueryChannelRangeDecodeErrorZ_err(e_conv);
        return (long)ret_conv;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1QueryChannelRangeDecodeErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_QueryChannelRangeDecodeErrorZ _res_conv = *(LDKCResult_QueryChannelRangeDecodeErrorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_QueryChannelRangeDecodeErrorZ _res_conv = *(LDKCResult_QueryChannelRangeDecodeErrorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_QueryChannelRangeDecodeErrorZ_free(_res_conv);
 }
@@ -6862,8 +6738,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1ReplyChannelRangeD
        LDKReplyChannelRange o_conv;
        o_conv.inner = (void*)(o & (~1));
        o_conv.is_owned = (o & 1) || (o == 0);
-       if (o_conv.inner != NULL)
-               o_conv = ReplyChannelRange_clone(&o_conv);
+       o_conv = ReplyChannelRange_clone(&o_conv);
        LDKCResult_ReplyChannelRangeDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_ReplyChannelRangeDecodeErrorZ), "LDKCResult_ReplyChannelRangeDecodeErrorZ");
        *ret_conv = CResult_ReplyChannelRangeDecodeErrorZ_ok(o_conv);
        return (long)ret_conv;
@@ -6873,14 +6748,15 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1ReplyChannelRangeD
        LDKDecodeError e_conv;
        e_conv.inner = (void*)(e & (~1));
        e_conv.is_owned = (e & 1) || (e == 0);
-       // Warning: we may need a move here but can't clone!
+       e_conv = DecodeError_clone(&e_conv);
        LDKCResult_ReplyChannelRangeDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_ReplyChannelRangeDecodeErrorZ), "LDKCResult_ReplyChannelRangeDecodeErrorZ");
        *ret_conv = CResult_ReplyChannelRangeDecodeErrorZ_err(e_conv);
        return (long)ret_conv;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1ReplyChannelRangeDecodeErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_ReplyChannelRangeDecodeErrorZ _res_conv = *(LDKCResult_ReplyChannelRangeDecodeErrorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_ReplyChannelRangeDecodeErrorZ _res_conv = *(LDKCResult_ReplyChannelRangeDecodeErrorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_ReplyChannelRangeDecodeErrorZ_free(_res_conv);
 }
@@ -6889,8 +6765,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1GossipTimestampFil
        LDKGossipTimestampFilter o_conv;
        o_conv.inner = (void*)(o & (~1));
        o_conv.is_owned = (o & 1) || (o == 0);
-       if (o_conv.inner != NULL)
-               o_conv = GossipTimestampFilter_clone(&o_conv);
+       o_conv = GossipTimestampFilter_clone(&o_conv);
        LDKCResult_GossipTimestampFilterDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_GossipTimestampFilterDecodeErrorZ), "LDKCResult_GossipTimestampFilterDecodeErrorZ");
        *ret_conv = CResult_GossipTimestampFilterDecodeErrorZ_ok(o_conv);
        return (long)ret_conv;
@@ -6900,14 +6775,15 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1GossipTimestampFil
        LDKDecodeError e_conv;
        e_conv.inner = (void*)(e & (~1));
        e_conv.is_owned = (e & 1) || (e == 0);
-       // Warning: we may need a move here but can't clone!
+       e_conv = DecodeError_clone(&e_conv);
        LDKCResult_GossipTimestampFilterDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_GossipTimestampFilterDecodeErrorZ), "LDKCResult_GossipTimestampFilterDecodeErrorZ");
        *ret_conv = CResult_GossipTimestampFilterDecodeErrorZ_err(e_conv);
        return (long)ret_conv;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1GossipTimestampFilterDecodeErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_GossipTimestampFilterDecodeErrorZ _res_conv = *(LDKCResult_GossipTimestampFilterDecodeErrorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_GossipTimestampFilterDecodeErrorZ _res_conv = *(LDKCResult_GossipTimestampFilterDecodeErrorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_GossipTimestampFilterDecodeErrorZ_free(_res_conv);
 }
@@ -6951,18 +6827,26 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1CVec_1u8ZPeerHandl
        LDKPeerHandleError e_conv;
        e_conv.inner = (void*)(e & (~1));
        e_conv.is_owned = (e & 1) || (e == 0);
-       // Warning: we may need a move here but can't clone!
+       e_conv = PeerHandleError_clone(&e_conv);
        LDKCResult_CVec_u8ZPeerHandleErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_CVec_u8ZPeerHandleErrorZ), "LDKCResult_CVec_u8ZPeerHandleErrorZ");
        *ret_conv = CResult_CVec_u8ZPeerHandleErrorZ_err(e_conv);
        return (long)ret_conv;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1CVec_1u8ZPeerHandleErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_CVec_u8ZPeerHandleErrorZ _res_conv = *(LDKCResult_CVec_u8ZPeerHandleErrorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_CVec_u8ZPeerHandleErrorZ _res_conv = *(LDKCResult_CVec_u8ZPeerHandleErrorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_CVec_u8ZPeerHandleErrorZ_free(_res_conv);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1CVec_1u8ZPeerHandleErrorZ_1clone(JNIEnv *env, jclass clz, int64_t orig) {
+       LDKCResult_CVec_u8ZPeerHandleErrorZ* orig_conv = (LDKCResult_CVec_u8ZPeerHandleErrorZ*)(orig & ~1);
+       LDKCResult_CVec_u8ZPeerHandleErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_CVec_u8ZPeerHandleErrorZ), "LDKCResult_CVec_u8ZPeerHandleErrorZ");
+       *ret_conv = CResult_CVec_u8ZPeerHandleErrorZ_clone(orig_conv);
+       return (long)ret_conv;
+}
+
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NonePeerHandleErrorZ_1ok(JNIEnv *env, jclass clz) {
        LDKCResult_NonePeerHandleErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_NonePeerHandleErrorZ), "LDKCResult_NonePeerHandleErrorZ");
        *ret_conv = CResult_NonePeerHandleErrorZ_ok();
@@ -6973,18 +6857,26 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NonePeerHandleErro
        LDKPeerHandleError e_conv;
        e_conv.inner = (void*)(e & (~1));
        e_conv.is_owned = (e & 1) || (e == 0);
-       // Warning: we may need a move here but can't clone!
+       e_conv = PeerHandleError_clone(&e_conv);
        LDKCResult_NonePeerHandleErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_NonePeerHandleErrorZ), "LDKCResult_NonePeerHandleErrorZ");
        *ret_conv = CResult_NonePeerHandleErrorZ_err(e_conv);
        return (long)ret_conv;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1NonePeerHandleErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_NonePeerHandleErrorZ _res_conv = *(LDKCResult_NonePeerHandleErrorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_NonePeerHandleErrorZ _res_conv = *(LDKCResult_NonePeerHandleErrorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_NonePeerHandleErrorZ_free(_res_conv);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NonePeerHandleErrorZ_1clone(JNIEnv *env, jclass clz, int64_t orig) {
+       LDKCResult_NonePeerHandleErrorZ* orig_conv = (LDKCResult_NonePeerHandleErrorZ*)(orig & ~1);
+       LDKCResult_NonePeerHandleErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_NonePeerHandleErrorZ), "LDKCResult_NonePeerHandleErrorZ");
+       *ret_conv = CResult_NonePeerHandleErrorZ_clone(orig_conv);
+       return (long)ret_conv;
+}
+
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1boolPeerHandleErrorZ_1ok(JNIEnv *env, jclass clz, jboolean o) {
        LDKCResult_boolPeerHandleErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_boolPeerHandleErrorZ), "LDKCResult_boolPeerHandleErrorZ");
        *ret_conv = CResult_boolPeerHandleErrorZ_ok(o);
@@ -6995,18 +6887,26 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1boolPeerHandleErro
        LDKPeerHandleError e_conv;
        e_conv.inner = (void*)(e & (~1));
        e_conv.is_owned = (e & 1) || (e == 0);
-       // Warning: we may need a move here but can't clone!
+       e_conv = PeerHandleError_clone(&e_conv);
        LDKCResult_boolPeerHandleErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_boolPeerHandleErrorZ), "LDKCResult_boolPeerHandleErrorZ");
        *ret_conv = CResult_boolPeerHandleErrorZ_err(e_conv);
        return (long)ret_conv;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1boolPeerHandleErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_boolPeerHandleErrorZ _res_conv = *(LDKCResult_boolPeerHandleErrorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_boolPeerHandleErrorZ _res_conv = *(LDKCResult_boolPeerHandleErrorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_boolPeerHandleErrorZ_free(_res_conv);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1boolPeerHandleErrorZ_1clone(JNIEnv *env, jclass clz, int64_t orig) {
+       LDKCResult_boolPeerHandleErrorZ* orig_conv = (LDKCResult_boolPeerHandleErrorZ*)(orig & ~1);
+       LDKCResult_boolPeerHandleErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_boolPeerHandleErrorZ), "LDKCResult_boolPeerHandleErrorZ");
+       *ret_conv = CResult_boolPeerHandleErrorZ_clone(orig_conv);
+       return (long)ret_conv;
+}
+
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1SecretKeySecpErrorZ_1ok(JNIEnv *env, jclass clz, int8_tArray o) {
        LDKSecretKey o_ref;
        CHECK((*env)->GetArrayLength(env, o) == 32);
@@ -7024,7 +6924,8 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1SecretKeySecpError
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1SecretKeySecpErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_SecretKeySecpErrorZ _res_conv = *(LDKCResult_SecretKeySecpErrorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_SecretKeySecpErrorZ _res_conv = *(LDKCResult_SecretKeySecpErrorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_SecretKeySecpErrorZ_free(_res_conv);
 }
@@ -7046,7 +6947,8 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1PublicKeySecpError
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1PublicKeySecpErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_PublicKeySecpErrorZ _res_conv = *(LDKCResult_PublicKeySecpErrorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_PublicKeySecpErrorZ _res_conv = *(LDKCResult_PublicKeySecpErrorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_PublicKeySecpErrorZ_free(_res_conv);
 }
@@ -7055,8 +6957,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1TxCreationKeysSecp
        LDKTxCreationKeys o_conv;
        o_conv.inner = (void*)(o & (~1));
        o_conv.is_owned = (o & 1) || (o == 0);
-       if (o_conv.inner != NULL)
-               o_conv = TxCreationKeys_clone(&o_conv);
+       o_conv = TxCreationKeys_clone(&o_conv);
        LDKCResult_TxCreationKeysSecpErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_TxCreationKeysSecpErrorZ), "LDKCResult_TxCreationKeysSecpErrorZ");
        *ret_conv = CResult_TxCreationKeysSecpErrorZ_ok(o_conv);
        return (long)ret_conv;
@@ -7070,7 +6971,8 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1TxCreationKeysSecp
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1TxCreationKeysSecpErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_TxCreationKeysSecpErrorZ _res_conv = *(LDKCResult_TxCreationKeysSecpErrorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_TxCreationKeysSecpErrorZ _res_conv = *(LDKCResult_TxCreationKeysSecpErrorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_TxCreationKeysSecpErrorZ_free(_res_conv);
 }
@@ -7079,7 +6981,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1TrustedCommitmentT
        LDKTrustedCommitmentTransaction o_conv;
        o_conv.inner = (void*)(o & (~1));
        o_conv.is_owned = (o & 1) || (o == 0);
-       // Warning: we may need a move here but can't clone!
+       // Warning: we need a move here but no clone is available for LDKTrustedCommitmentTransaction
        LDKCResult_TrustedCommitmentTransactionNoneZ* ret_conv = MALLOC(sizeof(LDKCResult_TrustedCommitmentTransactionNoneZ), "LDKCResult_TrustedCommitmentTransactionNoneZ");
        *ret_conv = CResult_TrustedCommitmentTransactionNoneZ_ok(o_conv);
        return (long)ret_conv;
@@ -7092,11 +6994,51 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1TrustedCommitmentT
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1TrustedCommitmentTransactionNoneZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_TrustedCommitmentTransactionNoneZ _res_conv = *(LDKCResult_TrustedCommitmentTransactionNoneZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_TrustedCommitmentTransactionNoneZ _res_conv = *(LDKCResult_TrustedCommitmentTransactionNoneZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_TrustedCommitmentTransactionNoneZ_free(_res_conv);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1CVec_1SignatureZNoneZ_1ok(JNIEnv *env, jclass clz, jobjectArray o) {
+       LDKCVec_SignatureZ o_constr;
+       o_constr.datalen = (*env)->GetArrayLength(env, o);
+       if (o_constr.datalen > 0)
+               o_constr.data = MALLOC(o_constr.datalen * sizeof(LDKSignature), "LDKCVec_SignatureZ Elements");
+       else
+               o_constr.data = NULL;
+       for (size_t i = 0; i < o_constr.datalen; i++) {
+               int8_tArray arr_conv_8 = (*env)->GetObjectArrayElement(env, o, i);
+               LDKSignature arr_conv_8_ref;
+               CHECK((*env)->GetArrayLength(env, arr_conv_8) == 64);
+               (*env)->GetByteArrayRegion(env, arr_conv_8, 0, 64, arr_conv_8_ref.compact_form);
+               o_constr.data[i] = arr_conv_8_ref;
+       }
+       LDKCResult_CVec_SignatureZNoneZ* ret_conv = MALLOC(sizeof(LDKCResult_CVec_SignatureZNoneZ), "LDKCResult_CVec_SignatureZNoneZ");
+       *ret_conv = CResult_CVec_SignatureZNoneZ_ok(o_constr);
+       return (long)ret_conv;
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1CVec_1SignatureZNoneZ_1err(JNIEnv *env, jclass clz) {
+       LDKCResult_CVec_SignatureZNoneZ* ret_conv = MALLOC(sizeof(LDKCResult_CVec_SignatureZNoneZ), "LDKCResult_CVec_SignatureZNoneZ");
+       *ret_conv = CResult_CVec_SignatureZNoneZ_err();
+       return (long)ret_conv;
+}
+
+JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1CVec_1SignatureZNoneZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
+       if ((_res & 1) != 0) return;
+       LDKCResult_CVec_SignatureZNoneZ _res_conv = *(LDKCResult_CVec_SignatureZNoneZ*)(((uint64_t)_res) & ~1);
+       FREE((void*)_res);
+       CResult_CVec_SignatureZNoneZ_free(_res_conv);
+}
+
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1CVec_1SignatureZNoneZ_1clone(JNIEnv *env, jclass clz, int64_t orig) {
+       LDKCResult_CVec_SignatureZNoneZ* orig_conv = (LDKCResult_CVec_SignatureZNoneZ*)(orig & ~1);
+       LDKCResult_CVec_SignatureZNoneZ* ret_conv = MALLOC(sizeof(LDKCResult_CVec_SignatureZNoneZ), "LDKCResult_CVec_SignatureZNoneZ");
+       *ret_conv = CResult_CVec_SignatureZNoneZ_clone(orig_conv);
+       return (long)ret_conv;
+}
+
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CVec_1RouteHopZ_1free(JNIEnv *env, jclass clz, int64_tArray _res) {
        LDKCVec_RouteHopZ _res_constr;
        _res_constr.datalen = (*env)->GetArrayLength(env, _res);
@@ -7149,8 +7091,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1RouteDecodeErrorZ_
        LDKRoute o_conv;
        o_conv.inner = (void*)(o & (~1));
        o_conv.is_owned = (o & 1) || (o == 0);
-       if (o_conv.inner != NULL)
-               o_conv = Route_clone(&o_conv);
+       o_conv = Route_clone(&o_conv);
        LDKCResult_RouteDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_RouteDecodeErrorZ), "LDKCResult_RouteDecodeErrorZ");
        *ret_conv = CResult_RouteDecodeErrorZ_ok(o_conv);
        return (long)ret_conv;
@@ -7160,14 +7101,15 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1RouteDecodeErrorZ_
        LDKDecodeError e_conv;
        e_conv.inner = (void*)(e & (~1));
        e_conv.is_owned = (e & 1) || (e == 0);
-       // Warning: we may need a move here but can't clone!
+       e_conv = DecodeError_clone(&e_conv);
        LDKCResult_RouteDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_RouteDecodeErrorZ), "LDKCResult_RouteDecodeErrorZ");
        *ret_conv = CResult_RouteDecodeErrorZ_err(e_conv);
        return (long)ret_conv;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1RouteDecodeErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_RouteDecodeErrorZ _res_conv = *(LDKCResult_RouteDecodeErrorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_RouteDecodeErrorZ _res_conv = *(LDKCResult_RouteDecodeErrorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_RouteDecodeErrorZ_free(_res_conv);
 }
@@ -7195,8 +7137,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1RouteLightningErro
        LDKRoute o_conv;
        o_conv.inner = (void*)(o & (~1));
        o_conv.is_owned = (o & 1) || (o == 0);
-       if (o_conv.inner != NULL)
-               o_conv = Route_clone(&o_conv);
+       o_conv = Route_clone(&o_conv);
        LDKCResult_RouteLightningErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_RouteLightningErrorZ), "LDKCResult_RouteLightningErrorZ");
        *ret_conv = CResult_RouteLightningErrorZ_ok(o_conv);
        return (long)ret_conv;
@@ -7206,14 +7147,15 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1RouteLightningErro
        LDKLightningError e_conv;
        e_conv.inner = (void*)(e & (~1));
        e_conv.is_owned = (e & 1) || (e == 0);
-       // Warning: we may need a move here but can't clone!
+       e_conv = LightningError_clone(&e_conv);
        LDKCResult_RouteLightningErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_RouteLightningErrorZ), "LDKCResult_RouteLightningErrorZ");
        *ret_conv = CResult_RouteLightningErrorZ_err(e_conv);
        return (long)ret_conv;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1RouteLightningErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_RouteLightningErrorZ _res_conv = *(LDKCResult_RouteLightningErrorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_RouteLightningErrorZ _res_conv = *(LDKCResult_RouteLightningErrorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_RouteLightningErrorZ_free(_res_conv);
 }
@@ -7222,8 +7164,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1RoutingFeesDecodeE
        LDKRoutingFees o_conv;
        o_conv.inner = (void*)(o & (~1));
        o_conv.is_owned = (o & 1) || (o == 0);
-       if (o_conv.inner != NULL)
-               o_conv = RoutingFees_clone(&o_conv);
+       o_conv = RoutingFees_clone(&o_conv);
        LDKCResult_RoutingFeesDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_RoutingFeesDecodeErrorZ), "LDKCResult_RoutingFeesDecodeErrorZ");
        *ret_conv = CResult_RoutingFeesDecodeErrorZ_ok(o_conv);
        return (long)ret_conv;
@@ -7233,14 +7174,15 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1RoutingFeesDecodeE
        LDKDecodeError e_conv;
        e_conv.inner = (void*)(e & (~1));
        e_conv.is_owned = (e & 1) || (e == 0);
-       // Warning: we may need a move here but can't clone!
+       e_conv = DecodeError_clone(&e_conv);
        LDKCResult_RoutingFeesDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_RoutingFeesDecodeErrorZ), "LDKCResult_RoutingFeesDecodeErrorZ");
        *ret_conv = CResult_RoutingFeesDecodeErrorZ_err(e_conv);
        return (long)ret_conv;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1RoutingFeesDecodeErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_RoutingFeesDecodeErrorZ _res_conv = *(LDKCResult_RoutingFeesDecodeErrorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_RoutingFeesDecodeErrorZ _res_conv = *(LDKCResult_RoutingFeesDecodeErrorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_RoutingFeesDecodeErrorZ_free(_res_conv);
 }
@@ -7249,7 +7191,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NodeAnnouncementIn
        LDKNodeAnnouncementInfo o_conv;
        o_conv.inner = (void*)(o & (~1));
        o_conv.is_owned = (o & 1) || (o == 0);
-       // Warning: we may need a move here but can't clone!
+       o_conv = NodeAnnouncementInfo_clone(&o_conv);
        LDKCResult_NodeAnnouncementInfoDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_NodeAnnouncementInfoDecodeErrorZ), "LDKCResult_NodeAnnouncementInfoDecodeErrorZ");
        *ret_conv = CResult_NodeAnnouncementInfoDecodeErrorZ_ok(o_conv);
        return (long)ret_conv;
@@ -7259,23 +7201,31 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NodeAnnouncementIn
        LDKDecodeError e_conv;
        e_conv.inner = (void*)(e & (~1));
        e_conv.is_owned = (e & 1) || (e == 0);
-       // Warning: we may need a move here but can't clone!
+       e_conv = DecodeError_clone(&e_conv);
        LDKCResult_NodeAnnouncementInfoDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_NodeAnnouncementInfoDecodeErrorZ), "LDKCResult_NodeAnnouncementInfoDecodeErrorZ");
        *ret_conv = CResult_NodeAnnouncementInfoDecodeErrorZ_err(e_conv);
        return (long)ret_conv;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1NodeAnnouncementInfoDecodeErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_NodeAnnouncementInfoDecodeErrorZ _res_conv = *(LDKCResult_NodeAnnouncementInfoDecodeErrorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_NodeAnnouncementInfoDecodeErrorZ _res_conv = *(LDKCResult_NodeAnnouncementInfoDecodeErrorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_NodeAnnouncementInfoDecodeErrorZ_free(_res_conv);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NodeAnnouncementInfoDecodeErrorZ_1clone(JNIEnv *env, jclass clz, int64_t orig) {
+       LDKCResult_NodeAnnouncementInfoDecodeErrorZ* orig_conv = (LDKCResult_NodeAnnouncementInfoDecodeErrorZ*)(orig & ~1);
+       LDKCResult_NodeAnnouncementInfoDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_NodeAnnouncementInfoDecodeErrorZ), "LDKCResult_NodeAnnouncementInfoDecodeErrorZ");
+       *ret_conv = CResult_NodeAnnouncementInfoDecodeErrorZ_clone(orig_conv);
+       return (long)ret_conv;
+}
+
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NodeInfoDecodeErrorZ_1ok(JNIEnv *env, jclass clz, int64_t o) {
        LDKNodeInfo o_conv;
        o_conv.inner = (void*)(o & (~1));
        o_conv.is_owned = (o & 1) || (o == 0);
-       // Warning: we may need a move here but can't clone!
+       o_conv = NodeInfo_clone(&o_conv);
        LDKCResult_NodeInfoDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_NodeInfoDecodeErrorZ), "LDKCResult_NodeInfoDecodeErrorZ");
        *ret_conv = CResult_NodeInfoDecodeErrorZ_ok(o_conv);
        return (long)ret_conv;
@@ -7285,23 +7235,31 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NodeInfoDecodeErro
        LDKDecodeError e_conv;
        e_conv.inner = (void*)(e & (~1));
        e_conv.is_owned = (e & 1) || (e == 0);
-       // Warning: we may need a move here but can't clone!
+       e_conv = DecodeError_clone(&e_conv);
        LDKCResult_NodeInfoDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_NodeInfoDecodeErrorZ), "LDKCResult_NodeInfoDecodeErrorZ");
        *ret_conv = CResult_NodeInfoDecodeErrorZ_err(e_conv);
        return (long)ret_conv;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1NodeInfoDecodeErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_NodeInfoDecodeErrorZ _res_conv = *(LDKCResult_NodeInfoDecodeErrorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_NodeInfoDecodeErrorZ _res_conv = *(LDKCResult_NodeInfoDecodeErrorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_NodeInfoDecodeErrorZ_free(_res_conv);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NodeInfoDecodeErrorZ_1clone(JNIEnv *env, jclass clz, int64_t orig) {
+       LDKCResult_NodeInfoDecodeErrorZ* orig_conv = (LDKCResult_NodeInfoDecodeErrorZ*)(orig & ~1);
+       LDKCResult_NodeInfoDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_NodeInfoDecodeErrorZ), "LDKCResult_NodeInfoDecodeErrorZ");
+       *ret_conv = CResult_NodeInfoDecodeErrorZ_clone(orig_conv);
+       return (long)ret_conv;
+}
+
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NetworkGraphDecodeErrorZ_1ok(JNIEnv *env, jclass clz, int64_t o) {
        LDKNetworkGraph o_conv;
        o_conv.inner = (void*)(o & (~1));
        o_conv.is_owned = (o & 1) || (o == 0);
-       // Warning: we may need a move here but can't clone!
+       // Warning: we need a move here but no clone is available for LDKNetworkGraph
        LDKCResult_NetworkGraphDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_NetworkGraphDecodeErrorZ), "LDKCResult_NetworkGraphDecodeErrorZ");
        *ret_conv = CResult_NetworkGraphDecodeErrorZ_ok(o_conv);
        return (long)ret_conv;
@@ -7311,20 +7269,22 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CResult_1NetworkGraphDecode
        LDKDecodeError e_conv;
        e_conv.inner = (void*)(e & (~1));
        e_conv.is_owned = (e & 1) || (e == 0);
-       // Warning: we may need a move here but can't clone!
+       e_conv = DecodeError_clone(&e_conv);
        LDKCResult_NetworkGraphDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_NetworkGraphDecodeErrorZ), "LDKCResult_NetworkGraphDecodeErrorZ");
        *ret_conv = CResult_NetworkGraphDecodeErrorZ_err(e_conv);
        return (long)ret_conv;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CResult_1NetworkGraphDecodeErrorZ_1free(JNIEnv *env, jclass clz, int64_t _res) {
-       LDKCResult_NetworkGraphDecodeErrorZ _res_conv = *(LDKCResult_NetworkGraphDecodeErrorZ*)_res;
+       if ((_res & 1) != 0) return;
+       LDKCResult_NetworkGraphDecodeErrorZ _res_conv = *(LDKCResult_NetworkGraphDecodeErrorZ*)(((uint64_t)_res) & ~1);
        FREE((void*)_res);
        CResult_NetworkGraphDecodeErrorZ_free(_res_conv);
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Event_1free(JNIEnv *env, jclass clz, int64_t this_ptr) {
-       LDKEvent this_ptr_conv = *(LDKEvent*)this_ptr;
+       if ((this_ptr & 1) != 0) return;
+       LDKEvent this_ptr_conv = *(LDKEvent*)(((uint64_t)this_ptr) & ~1);
        FREE((void*)this_ptr);
        Event_free(this_ptr_conv);
 }
@@ -7347,7 +7307,8 @@ JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_Event_1write(JNIEnv *en
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_MessageSendEvent_1free(JNIEnv *env, jclass clz, int64_t this_ptr) {
-       LDKMessageSendEvent this_ptr_conv = *(LDKMessageSendEvent*)this_ptr;
+       if ((this_ptr & 1) != 0) return;
+       LDKMessageSendEvent this_ptr_conv = *(LDKMessageSendEvent*)(((uint64_t)this_ptr) & ~1);
        FREE((void*)this_ptr);
        MessageSendEvent_free(this_ptr_conv);
 }
@@ -7361,19 +7322,22 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_MessageSendEvent_1clone(JNI
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_MessageSendEventsProvider_1free(JNIEnv *env, jclass clz, int64_t this_ptr) {
-       LDKMessageSendEventsProvider this_ptr_conv = *(LDKMessageSendEventsProvider*)this_ptr;
+       if ((this_ptr & 1) != 0) return;
+       LDKMessageSendEventsProvider this_ptr_conv = *(LDKMessageSendEventsProvider*)(((uint64_t)this_ptr) & ~1);
        FREE((void*)this_ptr);
        MessageSendEventsProvider_free(this_ptr_conv);
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_EventsProvider_1free(JNIEnv *env, jclass clz, int64_t this_ptr) {
-       LDKEventsProvider this_ptr_conv = *(LDKEventsProvider*)this_ptr;
+       if ((this_ptr & 1) != 0) return;
+       LDKEventsProvider this_ptr_conv = *(LDKEventsProvider*)(((uint64_t)this_ptr) & ~1);
        FREE((void*)this_ptr);
        EventsProvider_free(this_ptr_conv);
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_APIError_1free(JNIEnv *env, jclass clz, int64_t this_ptr) {
-       LDKAPIError this_ptr_conv = *(LDKAPIError*)this_ptr;
+       if ((this_ptr & 1) != 0) return;
+       LDKAPIError this_ptr_conv = *(LDKAPIError*)(((uint64_t)this_ptr) & ~1);
        FREE((void*)this_ptr);
        APIError_free(this_ptr_conv);
 }
@@ -7387,7 +7351,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_APIError_1clone(JNIEnv *env
 }
 
 JNIEXPORT jclass JNICALL Java_org_ldk_impl_bindings_Level_1clone(JNIEnv *env, jclass clz, int64_t orig) {
-       LDKLevel* orig_conv = (LDKLevel*)orig;
+       LDKLevel* orig_conv = (LDKLevel*)(orig & ~1);
        jclass ret_conv = LDKLevel_to_java(env, Level_clone(orig_conv));
        return ret_conv;
 }
@@ -7398,7 +7362,8 @@ JNIEXPORT jclass JNICALL Java_org_ldk_impl_bindings_Level_1max(JNIEnv *env, jcla
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Logger_1free(JNIEnv *env, jclass clz, int64_t this_ptr) {
-       LDKLogger this_ptr_conv = *(LDKLogger*)this_ptr;
+       if ((this_ptr & 1) != 0) return;
+       LDKLogger this_ptr_conv = *(LDKLogger*)(((uint64_t)this_ptr) & ~1);
        FREE((void*)this_ptr);
        Logger_free(this_ptr_conv);
 }
@@ -7840,8 +7805,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_UserConfig_1set_1own_1channel_
        LDKChannelHandshakeConfig val_conv;
        val_conv.inner = (void*)(val & (~1));
        val_conv.is_owned = (val & 1) || (val == 0);
-       if (val_conv.inner != NULL)
-               val_conv = ChannelHandshakeConfig_clone(&val_conv);
+       val_conv = ChannelHandshakeConfig_clone(&val_conv);
        UserConfig_set_own_channel_config(&this_ptr_conv, val_conv);
 }
 
@@ -7866,8 +7830,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_UserConfig_1set_1peer_1channel
        LDKChannelHandshakeLimits val_conv;
        val_conv.inner = (void*)(val & (~1));
        val_conv.is_owned = (val & 1) || (val == 0);
-       if (val_conv.inner != NULL)
-               val_conv = ChannelHandshakeLimits_clone(&val_conv);
+       val_conv = ChannelHandshakeLimits_clone(&val_conv);
        UserConfig_set_peer_channel_config_limits(&this_ptr_conv, val_conv);
 }
 
@@ -7892,8 +7855,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_UserConfig_1set_1channel_1opti
        LDKChannelConfig val_conv;
        val_conv.inner = (void*)(val & (~1));
        val_conv.is_owned = (val & 1) || (val == 0);
-       if (val_conv.inner != NULL)
-               val_conv = ChannelConfig_clone(&val_conv);
+       val_conv = ChannelConfig_clone(&val_conv);
        UserConfig_set_channel_options(&this_ptr_conv, val_conv);
 }
 
@@ -7901,18 +7863,15 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_UserConfig_1new(JNIEnv *env
        LDKChannelHandshakeConfig own_channel_config_arg_conv;
        own_channel_config_arg_conv.inner = (void*)(own_channel_config_arg & (~1));
        own_channel_config_arg_conv.is_owned = (own_channel_config_arg & 1) || (own_channel_config_arg == 0);
-       if (own_channel_config_arg_conv.inner != NULL)
-               own_channel_config_arg_conv = ChannelHandshakeConfig_clone(&own_channel_config_arg_conv);
+       own_channel_config_arg_conv = ChannelHandshakeConfig_clone(&own_channel_config_arg_conv);
        LDKChannelHandshakeLimits peer_channel_config_limits_arg_conv;
        peer_channel_config_limits_arg_conv.inner = (void*)(peer_channel_config_limits_arg & (~1));
        peer_channel_config_limits_arg_conv.is_owned = (peer_channel_config_limits_arg & 1) || (peer_channel_config_limits_arg == 0);
-       if (peer_channel_config_limits_arg_conv.inner != NULL)
-               peer_channel_config_limits_arg_conv = ChannelHandshakeLimits_clone(&peer_channel_config_limits_arg_conv);
+       peer_channel_config_limits_arg_conv = ChannelHandshakeLimits_clone(&peer_channel_config_limits_arg_conv);
        LDKChannelConfig channel_options_arg_conv;
        channel_options_arg_conv.inner = (void*)(channel_options_arg & (~1));
        channel_options_arg_conv.is_owned = (channel_options_arg & 1) || (channel_options_arg == 0);
-       if (channel_options_arg_conv.inner != NULL)
-               channel_options_arg_conv = ChannelConfig_clone(&channel_options_arg_conv);
+       channel_options_arg_conv = ChannelConfig_clone(&channel_options_arg_conv);
        LDKUserConfig ret_var = UserConfig_new(own_channel_config_arg_conv, peer_channel_config_limits_arg_conv, channel_options_arg_conv);
        CHECK((((long)ret_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&ret_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
@@ -7935,43 +7894,48 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_UserConfig_1default(JNIEnv
 }
 
 JNIEXPORT jclass JNICALL Java_org_ldk_impl_bindings_AccessError_1clone(JNIEnv *env, jclass clz, int64_t orig) {
-       LDKAccessError* orig_conv = (LDKAccessError*)orig;
+       LDKAccessError* orig_conv = (LDKAccessError*)(orig & ~1);
        jclass ret_conv = LDKAccessError_to_java(env, AccessError_clone(orig_conv));
        return ret_conv;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Access_1free(JNIEnv *env, jclass clz, int64_t this_ptr) {
-       LDKAccess this_ptr_conv = *(LDKAccess*)this_ptr;
+       if ((this_ptr & 1) != 0) return;
+       LDKAccess this_ptr_conv = *(LDKAccess*)(((uint64_t)this_ptr) & ~1);
        FREE((void*)this_ptr);
        Access_free(this_ptr_conv);
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Watch_1free(JNIEnv *env, jclass clz, int64_t this_ptr) {
-       LDKWatch this_ptr_conv = *(LDKWatch*)this_ptr;
+       if ((this_ptr & 1) != 0) return;
+       LDKWatch this_ptr_conv = *(LDKWatch*)(((uint64_t)this_ptr) & ~1);
        FREE((void*)this_ptr);
        Watch_free(this_ptr_conv);
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Filter_1free(JNIEnv *env, jclass clz, int64_t this_ptr) {
-       LDKFilter this_ptr_conv = *(LDKFilter*)this_ptr;
+       if ((this_ptr & 1) != 0) return;
+       LDKFilter this_ptr_conv = *(LDKFilter*)(((uint64_t)this_ptr) & ~1);
        FREE((void*)this_ptr);
        Filter_free(this_ptr_conv);
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_BroadcasterInterface_1free(JNIEnv *env, jclass clz, int64_t this_ptr) {
-       LDKBroadcasterInterface this_ptr_conv = *(LDKBroadcasterInterface*)this_ptr;
+       if ((this_ptr & 1) != 0) return;
+       LDKBroadcasterInterface this_ptr_conv = *(LDKBroadcasterInterface*)(((uint64_t)this_ptr) & ~1);
        FREE((void*)this_ptr);
        BroadcasterInterface_free(this_ptr_conv);
 }
 
 JNIEXPORT jclass JNICALL Java_org_ldk_impl_bindings_ConfirmationTarget_1clone(JNIEnv *env, jclass clz, int64_t orig) {
-       LDKConfirmationTarget* orig_conv = (LDKConfirmationTarget*)orig;
+       LDKConfirmationTarget* orig_conv = (LDKConfirmationTarget*)(orig & ~1);
        jclass ret_conv = LDKConfirmationTarget_to_java(env, ConfirmationTarget_clone(orig_conv));
        return ret_conv;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_FeeEstimator_1free(JNIEnv *env, jclass clz, int64_t this_ptr) {
-       LDKFeeEstimator this_ptr_conv = *(LDKFeeEstimator*)this_ptr;
+       if ((this_ptr & 1) != 0) return;
+       LDKFeeEstimator this_ptr_conv = *(LDKFeeEstimator*)(((uint64_t)this_ptr) & ~1);
        FREE((void*)this_ptr);
        FeeEstimator_free(this_ptr_conv);
 }
@@ -8000,7 +7964,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChainMonitor_1block_1connected
        int64_t* txdata_vals = (*env)->GetLongArrayElements (env, txdata, NULL);
        for (size_t y = 0; y < txdata_constr.datalen; y++) {
                int64_t arr_conv_24 = txdata_vals[y];
-               LDKC2Tuple_usizeTransactionZ arr_conv_24_conv = *(LDKC2Tuple_usizeTransactionZ*)arr_conv_24;
+               LDKC2Tuple_usizeTransactionZ arr_conv_24_conv = *(LDKC2Tuple_usizeTransactionZ*)(((uint64_t)arr_conv_24) & ~1);
                FREE((void*)arr_conv_24);
                txdata_constr.data[y] = arr_conv_24_conv;
        }
@@ -8021,22 +7985,22 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChainMonitor_1block_1disconnec
 
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ChainMonitor_1new(JNIEnv *env, jclass clz, int64_t chain_source, int64_t broadcaster, int64_t logger, int64_t feeest, int64_t persister) {
        LDKFilter* chain_source_conv = (LDKFilter*)chain_source;
-       LDKBroadcasterInterface broadcaster_conv = *(LDKBroadcasterInterface*)broadcaster;
+       LDKBroadcasterInterface broadcaster_conv = *(LDKBroadcasterInterface*)(((uint64_t)broadcaster) & ~1);
        if (broadcaster_conv.free == LDKBroadcasterInterface_JCalls_free) {
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKBroadcasterInterface_JCalls_clone(broadcaster_conv.this_arg);
        }
-       LDKLogger logger_conv = *(LDKLogger*)logger;
+       LDKLogger logger_conv = *(LDKLogger*)(((uint64_t)logger) & ~1);
        if (logger_conv.free == LDKLogger_JCalls_free) {
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKLogger_JCalls_clone(logger_conv.this_arg);
        }
-       LDKFeeEstimator feeest_conv = *(LDKFeeEstimator*)feeest;
+       LDKFeeEstimator feeest_conv = *(LDKFeeEstimator*)(((uint64_t)feeest) & ~1);
        if (feeest_conv.free == LDKFeeEstimator_JCalls_free) {
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKFeeEstimator_JCalls_clone(feeest_conv.this_arg);
        }
-       LDKPersist persister_conv = *(LDKPersist*)persister;
+       LDKPersist persister_conv = *(LDKPersist*)(((uint64_t)persister) & ~1);
        if (persister_conv.free == LDKPersist_JCalls_free) {
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKPersist_JCalls_clone(persister_conv.this_arg);
@@ -8127,7 +8091,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ChannelMonitorUpdate_1read(
 }
 
 JNIEXPORT jclass JNICALL Java_org_ldk_impl_bindings_ChannelMonitorUpdateErr_1clone(JNIEnv *env, jclass clz, int64_t orig) {
-       LDKChannelMonitorUpdateErr* orig_conv = (LDKChannelMonitorUpdateErr*)orig;
+       LDKChannelMonitorUpdateErr* orig_conv = (LDKChannelMonitorUpdateErr*)(orig & ~1);
        jclass ret_conv = LDKChannelMonitorUpdateErr_to_java(env, ChannelMonitorUpdateErr_clone(orig_conv));
        return ret_conv;
 }
@@ -8139,6 +8103,20 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_MonitorUpdateError_1free(JNIEn
        MonitorUpdateError_free(this_ptr_conv);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_MonitorUpdateError_1clone(JNIEnv *env, jclass clz, int64_t orig) {
+       LDKMonitorUpdateError orig_conv;
+       orig_conv.inner = (void*)(orig & (~1));
+       orig_conv.is_owned = false;
+       LDKMonitorUpdateError ret_var = MonitorUpdateError_clone(&orig_conv);
+       CHECK((((long)ret_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
+       CHECK((((long)&ret_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
+       long ret_ref = (long)ret_var.inner;
+       if (ret_var.is_owned) {
+               ret_ref |= 1;
+       }
+       return ret_ref;
+}
+
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_MonitorEvent_1free(JNIEnv *env, jclass clz, int64_t this_ptr) {
        LDKMonitorEvent this_ptr_conv;
        this_ptr_conv.inner = (void*)(this_ptr & (~1));
@@ -8214,6 +8192,20 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelMonitor_1free(JNIEnv *e
        ChannelMonitor_free(this_ptr_conv);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ChannelMonitor_1clone(JNIEnv *env, jclass clz, int64_t orig) {
+       LDKChannelMonitor orig_conv;
+       orig_conv.inner = (void*)(orig & (~1));
+       orig_conv.is_owned = false;
+       LDKChannelMonitor ret_var = ChannelMonitor_clone(&orig_conv);
+       CHECK((((long)ret_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
+       CHECK((((long)&ret_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
+       long ret_ref = (long)ret_var.inner;
+       if (ret_var.is_owned) {
+               ret_ref |= 1;
+       }
+       return ret_ref;
+}
+
 JNIEXPORT int8_tArray JNICALL Java_org_ldk_impl_bindings_ChannelMonitor_1write(JNIEnv *env, jclass clz, int64_t obj) {
        LDKChannelMonitor obj_conv;
        obj_conv.inner = (void*)(obj & (~1));
@@ -8254,8 +8246,6 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ChannelMonitor_1get_1fundin
        this_arg_conv.is_owned = false;
        LDKC2Tuple_OutPointScriptZ* ret_ref = MALLOC(sizeof(LDKC2Tuple_OutPointScriptZ), "LDKC2Tuple_OutPointScriptZ");
        *ret_ref = ChannelMonitor_get_funding_txo(&this_arg_conv);
-       ret_ref->a = OutPoint_clone(&ret_ref->a);
-       ret_ref->b = CVec_u8Z_clone(&ret_ref->b);
        return (long)ret_ref;
 }
 
@@ -8335,22 +8325,22 @@ JNIEXPORT int64_tArray JNICALL Java_org_ldk_impl_bindings_ChannelMonitor_1block_
        int64_t* txdata_vals = (*env)->GetLongArrayElements (env, txdata, NULL);
        for (size_t y = 0; y < txdata_constr.datalen; y++) {
                int64_t arr_conv_24 = txdata_vals[y];
-               LDKC2Tuple_usizeTransactionZ arr_conv_24_conv = *(LDKC2Tuple_usizeTransactionZ*)arr_conv_24;
+               LDKC2Tuple_usizeTransactionZ arr_conv_24_conv = *(LDKC2Tuple_usizeTransactionZ*)(((uint64_t)arr_conv_24) & ~1);
                FREE((void*)arr_conv_24);
                txdata_constr.data[y] = arr_conv_24_conv;
        }
        (*env)->ReleaseLongArrayElements(env, txdata, txdata_vals, 0);
-       LDKBroadcasterInterface broadcaster_conv = *(LDKBroadcasterInterface*)broadcaster;
+       LDKBroadcasterInterface broadcaster_conv = *(LDKBroadcasterInterface*)(((uint64_t)broadcaster) & ~1);
        if (broadcaster_conv.free == LDKBroadcasterInterface_JCalls_free) {
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKBroadcasterInterface_JCalls_clone(broadcaster_conv.this_arg);
        }
-       LDKFeeEstimator fee_estimator_conv = *(LDKFeeEstimator*)fee_estimator;
+       LDKFeeEstimator fee_estimator_conv = *(LDKFeeEstimator*)(((uint64_t)fee_estimator) & ~1);
        if (fee_estimator_conv.free == LDKFeeEstimator_JCalls_free) {
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKFeeEstimator_JCalls_clone(fee_estimator_conv.this_arg);
        }
-       LDKLogger logger_conv = *(LDKLogger*)logger;
+       LDKLogger logger_conv = *(LDKLogger*)(((uint64_t)logger) & ~1);
        if (logger_conv.free == LDKLogger_JCalls_free) {
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKLogger_JCalls_clone(logger_conv.this_arg);
@@ -8361,8 +8351,6 @@ JNIEXPORT int64_tArray JNICALL Java_org_ldk_impl_bindings_ChannelMonitor_1block_
        for (size_t u = 0; u < ret_var.datalen; u++) {
                LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ* arr_conv_46_ref = MALLOC(sizeof(LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ), "LDKC2Tuple_TxidCVec_C2Tuple_u32TxOutZZZ");
                *arr_conv_46_ref = ret_var.data[u];
-               arr_conv_46_ref->a = ThirtyTwoBytes_clone(&arr_conv_46_ref->a);
-               arr_conv_46_ref->b = CVec_C2Tuple_u32TxOutZZ_clone(&arr_conv_46_ref->b);
                ret_arr_ptr[u] = (long)arr_conv_46_ref;
        }
        (*env)->ReleasePrimitiveArrayCritical(env, ret_arr, ret_arr_ptr, 0);
@@ -8378,17 +8366,17 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelMonitor_1block_1disconn
        CHECK((*env)->GetArrayLength(env, header) == 80);
        (*env)->GetByteArrayRegion(env, header, 0, 80, header_arr);
        unsigned char (*header_ref)[80] = &header_arr;
-       LDKBroadcasterInterface broadcaster_conv = *(LDKBroadcasterInterface*)broadcaster;
+       LDKBroadcasterInterface broadcaster_conv = *(LDKBroadcasterInterface*)(((uint64_t)broadcaster) & ~1);
        if (broadcaster_conv.free == LDKBroadcasterInterface_JCalls_free) {
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKBroadcasterInterface_JCalls_clone(broadcaster_conv.this_arg);
        }
-       LDKFeeEstimator fee_estimator_conv = *(LDKFeeEstimator*)fee_estimator;
+       LDKFeeEstimator fee_estimator_conv = *(LDKFeeEstimator*)(((uint64_t)fee_estimator) & ~1);
        if (fee_estimator_conv.free == LDKFeeEstimator_JCalls_free) {
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKFeeEstimator_JCalls_clone(fee_estimator_conv.this_arg);
        }
-       LDKLogger logger_conv = *(LDKLogger*)logger;
+       LDKLogger logger_conv = *(LDKLogger*)(((uint64_t)logger) & ~1);
        if (logger_conv.free == LDKLogger_JCalls_free) {
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKLogger_JCalls_clone(logger_conv.this_arg);
@@ -8397,7 +8385,8 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelMonitor_1block_1disconn
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Persist_1free(JNIEnv *env, jclass clz, int64_t this_ptr) {
-       LDKPersist this_ptr_conv = *(LDKPersist*)this_ptr;
+       if ((this_ptr & 1) != 0) return;
+       LDKPersist this_ptr_conv = *(LDKPersist*)(((uint64_t)this_ptr) & ~1);
        FREE((void*)this_ptr);
        Persist_free(this_ptr_conv);
 }
@@ -8518,7 +8507,8 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_OutPoint_1read(JNIEnv *env,
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_SpendableOutputDescriptor_1free(JNIEnv *env, jclass clz, int64_t this_ptr) {
-       LDKSpendableOutputDescriptor this_ptr_conv = *(LDKSpendableOutputDescriptor*)this_ptr;
+       if ((this_ptr & 1) != 0) return;
+       LDKSpendableOutputDescriptor this_ptr_conv = *(LDKSpendableOutputDescriptor*)(((uint64_t)this_ptr) & ~1);
        FREE((void*)this_ptr);
        SpendableOutputDescriptor_free(this_ptr_conv);
 }
@@ -8558,13 +8548,15 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ChannelKeys_1clone(JNIEnv *
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelKeys_1free(JNIEnv *env, jclass clz, int64_t this_ptr) {
-       LDKChannelKeys this_ptr_conv = *(LDKChannelKeys*)this_ptr;
+       if ((this_ptr & 1) != 0) return;
+       LDKChannelKeys this_ptr_conv = *(LDKChannelKeys*)(((uint64_t)this_ptr) & ~1);
        FREE((void*)this_ptr);
        ChannelKeys_free(this_ptr_conv);
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_KeysInterface_1free(JNIEnv *env, jclass clz, int64_t this_ptr) {
-       LDKKeysInterface this_ptr_conv = *(LDKKeysInterface*)this_ptr;
+       if ((this_ptr & 1) != 0) return;
+       LDKKeysInterface this_ptr_conv = *(LDKKeysInterface*)(((uint64_t)this_ptr) & ~1);
        FREE((void*)this_ptr);
        KeysInterface_free(this_ptr_conv);
 }
@@ -8723,7 +8715,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_InMemoryChannelKeys_1new(JN
        LDKThirtyTwoBytes commitment_seed_ref;
        CHECK((*env)->GetArrayLength(env, commitment_seed) == 32);
        (*env)->GetByteArrayRegion(env, commitment_seed, 0, 32, commitment_seed_ref.data);
-       LDKC2Tuple_u64u64Z key_derivation_params_conv = *(LDKC2Tuple_u64u64Z*)key_derivation_params;
+       LDKC2Tuple_u64u64Z key_derivation_params_conv = *(LDKC2Tuple_u64u64Z*)(((uint64_t)key_derivation_params) & ~1);
        FREE((void*)key_derivation_params);
        LDKInMemoryChannelKeys ret_var = InMemoryChannelKeys_new(funding_key_ref, revocation_base_key_ref, payment_key_ref, delayed_payment_base_key_ref, htlc_base_key_ref, commitment_seed_ref, channel_value_satoshis, key_derivation_params_conv);
        CHECK((((long)ret_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -8964,7 +8956,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelDetails_1set_1counterpa
        LDKInitFeatures val_conv;
        val_conv.inner = (void*)(val & (~1));
        val_conv.is_owned = (val & 1) || (val == 0);
-       // Warning: we may need a move here but can't clone!
+       // Warning: we need a move here but no clone is available for LDKInitFeatures
        ChannelDetails_set_counterparty_features(&this_ptr_conv, val_conv);
 }
 
@@ -9050,29 +9042,43 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_PaymentSendFailure_1free(JNIEn
        PaymentSendFailure_free(this_ptr_conv);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_PaymentSendFailure_1clone(JNIEnv *env, jclass clz, int64_t orig) {
+       LDKPaymentSendFailure orig_conv;
+       orig_conv.inner = (void*)(orig & (~1));
+       orig_conv.is_owned = false;
+       LDKPaymentSendFailure ret_var = PaymentSendFailure_clone(&orig_conv);
+       CHECK((((long)ret_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
+       CHECK((((long)&ret_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
+       long ret_ref = (long)ret_var.inner;
+       if (ret_var.is_owned) {
+               ret_ref |= 1;
+       }
+       return ret_ref;
+}
+
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ChannelManager_1new(JNIEnv *env, jclass clz, jclass network, int64_t fee_est, int64_t chain_monitor, int64_t tx_broadcaster, int64_t logger, int64_t keys_manager, int64_t config, intptr_t current_blockchain_height) {
        LDKNetwork network_conv = LDKNetwork_from_java(env, network);
-       LDKFeeEstimator fee_est_conv = *(LDKFeeEstimator*)fee_est;
+       LDKFeeEstimator fee_est_conv = *(LDKFeeEstimator*)(((uint64_t)fee_est) & ~1);
        if (fee_est_conv.free == LDKFeeEstimator_JCalls_free) {
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKFeeEstimator_JCalls_clone(fee_est_conv.this_arg);
        }
-       LDKWatch chain_monitor_conv = *(LDKWatch*)chain_monitor;
+       LDKWatch chain_monitor_conv = *(LDKWatch*)(((uint64_t)chain_monitor) & ~1);
        if (chain_monitor_conv.free == LDKWatch_JCalls_free) {
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKWatch_JCalls_clone(chain_monitor_conv.this_arg);
        }
-       LDKBroadcasterInterface tx_broadcaster_conv = *(LDKBroadcasterInterface*)tx_broadcaster;
+       LDKBroadcasterInterface tx_broadcaster_conv = *(LDKBroadcasterInterface*)(((uint64_t)tx_broadcaster) & ~1);
        if (tx_broadcaster_conv.free == LDKBroadcasterInterface_JCalls_free) {
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKBroadcasterInterface_JCalls_clone(tx_broadcaster_conv.this_arg);
        }
-       LDKLogger logger_conv = *(LDKLogger*)logger;
+       LDKLogger logger_conv = *(LDKLogger*)(((uint64_t)logger) & ~1);
        if (logger_conv.free == LDKLogger_JCalls_free) {
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKLogger_JCalls_clone(logger_conv.this_arg);
        }
-       LDKKeysInterface keys_manager_conv = *(LDKKeysInterface*)keys_manager;
+       LDKKeysInterface keys_manager_conv = *(LDKKeysInterface*)(((uint64_t)keys_manager) & ~1);
        if (keys_manager_conv.free == LDKKeysInterface_JCalls_free) {
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKKeysInterface_JCalls_clone(keys_manager_conv.this_arg);
@@ -9080,8 +9086,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ChannelManager_1new(JNIEnv
        LDKUserConfig config_conv;
        config_conv.inner = (void*)(config & (~1));
        config_conv.is_owned = (config & 1) || (config == 0);
-       if (config_conv.inner != NULL)
-               config_conv = UserConfig_clone(&config_conv);
+       config_conv = UserConfig_clone(&config_conv);
        LDKChannelManager ret_var = ChannelManager_new(network_conv, fee_est_conv, chain_monitor_conv, tx_broadcaster_conv, logger_conv, keys_manager_conv, config_conv, current_blockchain_height);
        CHECK((((long)ret_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&ret_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
@@ -9102,8 +9107,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ChannelManager_1create_1cha
        LDKUserConfig override_config_conv;
        override_config_conv.inner = (void*)(override_config & (~1));
        override_config_conv.is_owned = (override_config & 1) || (override_config == 0);
-       if (override_config_conv.inner != NULL)
-               override_config_conv = UserConfig_clone(&override_config_conv);
+       override_config_conv = UserConfig_clone(&override_config_conv);
        LDKCResult_NoneAPIErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_NoneAPIErrorZ), "LDKCResult_NoneAPIErrorZ");
        *ret_conv = ChannelManager_create_channel(&this_arg_conv, their_network_key_ref, channel_value_satoshis, push_msat, user_id, override_config_conv);
        return (long)ret_conv;
@@ -9166,7 +9170,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ChannelManager_1close_1chan
        return (long)ret_conv;
 }
 
-JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelManager_1force_1close_1channel(JNIEnv *env, jclass clz, int64_t this_arg, int8_tArray channel_id) {
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ChannelManager_1force_1close_1channel(JNIEnv *env, jclass clz, int64_t this_arg, int8_tArray channel_id) {
        LDKChannelManager this_arg_conv;
        this_arg_conv.inner = (void*)(this_arg & (~1));
        this_arg_conv.is_owned = false;
@@ -9174,7 +9178,9 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelManager_1force_1close_1
        CHECK((*env)->GetArrayLength(env, channel_id) == 32);
        (*env)->GetByteArrayRegion(env, channel_id, 0, 32, channel_id_arr);
        unsigned char (*channel_id_ref)[32] = &channel_id_arr;
-       ChannelManager_force_close_channel(&this_arg_conv, channel_id_ref);
+       LDKCResult_NoneAPIErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_NoneAPIErrorZ), "LDKCResult_NoneAPIErrorZ");
+       *ret_conv = ChannelManager_force_close_channel(&this_arg_conv, channel_id_ref);
+       return (long)ret_conv;
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelManager_1force_1close_1all_1channels(JNIEnv *env, jclass clz, int64_t this_arg) {
@@ -9213,8 +9219,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelManager_1funding_1trans
        LDKOutPoint funding_txo_conv;
        funding_txo_conv.inner = (void*)(funding_txo & (~1));
        funding_txo_conv.is_owned = (funding_txo & 1) || (funding_txo == 0);
-       if (funding_txo_conv.inner != NULL)
-               funding_txo_conv = OutPoint_clone(&funding_txo_conv);
+       funding_txo_conv = OutPoint_clone(&funding_txo_conv);
        ChannelManager_funding_transaction_generated(&this_arg_conv, temporary_channel_id_ref, funding_txo_conv);
 }
 
@@ -9237,7 +9242,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelManager_1broadcast_1nod
        int64_t* addresses_vals = (*env)->GetLongArrayElements (env, addresses, NULL);
        for (size_t m = 0; m < addresses_constr.datalen; m++) {
                int64_t arr_conv_12 = addresses_vals[m];
-               LDKNetAddress arr_conv_12_conv = *(LDKNetAddress*)arr_conv_12;
+               LDKNetAddress arr_conv_12_conv = *(LDKNetAddress*)(((uint64_t)arr_conv_12) & ~1);
                FREE((void*)arr_conv_12);
                addresses_constr.data[m] = arr_conv_12_conv;
        }
@@ -9342,7 +9347,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelManager_1block_1connect
        int64_t* txdata_vals = (*env)->GetLongArrayElements (env, txdata, NULL);
        for (size_t y = 0; y < txdata_constr.datalen; y++) {
                int64_t arr_conv_24 = txdata_vals[y];
-               LDKC2Tuple_usizeTransactionZ arr_conv_24_conv = *(LDKC2Tuple_usizeTransactionZ*)arr_conv_24;
+               LDKC2Tuple_usizeTransactionZ arr_conv_24_conv = *(LDKC2Tuple_usizeTransactionZ*)(((uint64_t)arr_conv_24) & ~1);
                FREE((void*)arr_conv_24);
                txdata_constr.data[y] = arr_conv_24_conv;
        }
@@ -9400,7 +9405,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelManagerReadArgs_1set_1k
        LDKChannelManagerReadArgs this_ptr_conv;
        this_ptr_conv.inner = (void*)(this_ptr & (~1));
        this_ptr_conv.is_owned = false;
-       LDKKeysInterface val_conv = *(LDKKeysInterface*)val;
+       LDKKeysInterface val_conv = *(LDKKeysInterface*)(((uint64_t)val) & ~1);
        if (val_conv.free == LDKKeysInterface_JCalls_free) {
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKKeysInterface_JCalls_clone(val_conv.this_arg);
@@ -9420,7 +9425,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelManagerReadArgs_1set_1f
        LDKChannelManagerReadArgs this_ptr_conv;
        this_ptr_conv.inner = (void*)(this_ptr & (~1));
        this_ptr_conv.is_owned = false;
-       LDKFeeEstimator val_conv = *(LDKFeeEstimator*)val;
+       LDKFeeEstimator val_conv = *(LDKFeeEstimator*)(((uint64_t)val) & ~1);
        if (val_conv.free == LDKFeeEstimator_JCalls_free) {
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKFeeEstimator_JCalls_clone(val_conv.this_arg);
@@ -9440,7 +9445,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelManagerReadArgs_1set_1c
        LDKChannelManagerReadArgs this_ptr_conv;
        this_ptr_conv.inner = (void*)(this_ptr & (~1));
        this_ptr_conv.is_owned = false;
-       LDKWatch val_conv = *(LDKWatch*)val;
+       LDKWatch val_conv = *(LDKWatch*)(((uint64_t)val) & ~1);
        if (val_conv.free == LDKWatch_JCalls_free) {
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKWatch_JCalls_clone(val_conv.this_arg);
@@ -9460,7 +9465,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelManagerReadArgs_1set_1t
        LDKChannelManagerReadArgs this_ptr_conv;
        this_ptr_conv.inner = (void*)(this_ptr & (~1));
        this_ptr_conv.is_owned = false;
-       LDKBroadcasterInterface val_conv = *(LDKBroadcasterInterface*)val;
+       LDKBroadcasterInterface val_conv = *(LDKBroadcasterInterface*)(((uint64_t)val) & ~1);
        if (val_conv.free == LDKBroadcasterInterface_JCalls_free) {
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKBroadcasterInterface_JCalls_clone(val_conv.this_arg);
@@ -9480,7 +9485,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelManagerReadArgs_1set_1l
        LDKChannelManagerReadArgs this_ptr_conv;
        this_ptr_conv.inner = (void*)(this_ptr & (~1));
        this_ptr_conv.is_owned = false;
-       LDKLogger val_conv = *(LDKLogger*)val;
+       LDKLogger val_conv = *(LDKLogger*)(((uint64_t)val) & ~1);
        if (val_conv.free == LDKLogger_JCalls_free) {
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKLogger_JCalls_clone(val_conv.this_arg);
@@ -9509,33 +9514,32 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelManagerReadArgs_1set_1d
        LDKUserConfig val_conv;
        val_conv.inner = (void*)(val & (~1));
        val_conv.is_owned = (val & 1) || (val == 0);
-       if (val_conv.inner != NULL)
-               val_conv = UserConfig_clone(&val_conv);
+       val_conv = UserConfig_clone(&val_conv);
        ChannelManagerReadArgs_set_default_config(&this_ptr_conv, val_conv);
 }
 
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ChannelManagerReadArgs_1new(JNIEnv *env, jclass clz, int64_t keys_manager, int64_t fee_estimator, int64_t chain_monitor, int64_t tx_broadcaster, int64_t logger, int64_t default_config, int64_tArray channel_monitors) {
-       LDKKeysInterface keys_manager_conv = *(LDKKeysInterface*)keys_manager;
+       LDKKeysInterface keys_manager_conv = *(LDKKeysInterface*)(((uint64_t)keys_manager) & ~1);
        if (keys_manager_conv.free == LDKKeysInterface_JCalls_free) {
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKKeysInterface_JCalls_clone(keys_manager_conv.this_arg);
        }
-       LDKFeeEstimator fee_estimator_conv = *(LDKFeeEstimator*)fee_estimator;
+       LDKFeeEstimator fee_estimator_conv = *(LDKFeeEstimator*)(((uint64_t)fee_estimator) & ~1);
        if (fee_estimator_conv.free == LDKFeeEstimator_JCalls_free) {
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKFeeEstimator_JCalls_clone(fee_estimator_conv.this_arg);
        }
-       LDKWatch chain_monitor_conv = *(LDKWatch*)chain_monitor;
+       LDKWatch chain_monitor_conv = *(LDKWatch*)(((uint64_t)chain_monitor) & ~1);
        if (chain_monitor_conv.free == LDKWatch_JCalls_free) {
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKWatch_JCalls_clone(chain_monitor_conv.this_arg);
        }
-       LDKBroadcasterInterface tx_broadcaster_conv = *(LDKBroadcasterInterface*)tx_broadcaster;
+       LDKBroadcasterInterface tx_broadcaster_conv = *(LDKBroadcasterInterface*)(((uint64_t)tx_broadcaster) & ~1);
        if (tx_broadcaster_conv.free == LDKBroadcasterInterface_JCalls_free) {
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKBroadcasterInterface_JCalls_clone(tx_broadcaster_conv.this_arg);
        }
-       LDKLogger logger_conv = *(LDKLogger*)logger;
+       LDKLogger logger_conv = *(LDKLogger*)(((uint64_t)logger) & ~1);
        if (logger_conv.free == LDKLogger_JCalls_free) {
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKLogger_JCalls_clone(logger_conv.this_arg);
@@ -9543,8 +9547,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ChannelManagerReadArgs_1new
        LDKUserConfig default_config_conv;
        default_config_conv.inner = (void*)(default_config & (~1));
        default_config_conv.is_owned = (default_config & 1) || (default_config == 0);
-       if (default_config_conv.inner != NULL)
-               default_config_conv = UserConfig_clone(&default_config_conv);
+       default_config_conv = UserConfig_clone(&default_config_conv);
        LDKCVec_ChannelMonitorZ channel_monitors_constr;
        channel_monitors_constr.datalen = (*env)->GetArrayLength(env, channel_monitors);
        if (channel_monitors_constr.datalen > 0)
@@ -9557,7 +9560,6 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ChannelManagerReadArgs_1new
                LDKChannelMonitor arr_conv_16_conv;
                arr_conv_16_conv.inner = (void*)(arr_conv_16 & (~1));
                arr_conv_16_conv.is_owned = (arr_conv_16 & 1) || (arr_conv_16 == 0);
-               // Warning: we may need a move here but can't clone!
                channel_monitors_constr.data[q] = arr_conv_16_conv;
        }
        (*env)->ReleaseLongArrayElements(env, channel_monitors, channel_monitors_vals, 0);
@@ -9578,7 +9580,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_C2Tuple_1BlockHashChannelMa
        LDKChannelManagerReadArgs arg_conv;
        arg_conv.inner = (void*)(arg & (~1));
        arg_conv.is_owned = (arg & 1) || (arg == 0);
-       // Warning: we may need a move here but can't clone!
+       // Warning: we need a move here but no clone is available for LDKChannelManagerReadArgs
        LDKCResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ* ret_conv = MALLOC(sizeof(LDKCResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ), "LDKCResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ");
        *ret_conv = C2Tuple_BlockHashChannelManagerZ_read(ser_ref, arg_conv);
        (*env)->ReleaseByteArrayElements(env, ser, (int8_t*)ser_ref.data, 0);
@@ -9592,6 +9594,20 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_DecodeError_1free(JNIEnv *env,
        DecodeError_free(this_ptr_conv);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_DecodeError_1clone(JNIEnv *env, jclass clz, int64_t orig) {
+       LDKDecodeError orig_conv;
+       orig_conv.inner = (void*)(orig & (~1));
+       orig_conv.is_owned = false;
+       LDKDecodeError ret_var = DecodeError_clone(&orig_conv);
+       CHECK((((long)ret_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
+       CHECK((((long)&ret_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
+       long ret_ref = (long)ret_var.inner;
+       if (ret_var.is_owned) {
+               ret_ref |= 1;
+       }
+       return ret_ref;
+}
+
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Init_1free(JNIEnv *env, jclass clz, int64_t this_ptr) {
        LDKInit this_ptr_conv;
        this_ptr_conv.inner = (void*)(this_ptr & (~1));
@@ -11673,7 +11689,8 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_AnnouncementSignatures_1new
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_NetAddress_1free(JNIEnv *env, jclass clz, int64_t this_ptr) {
-       LDKNetAddress this_ptr_conv = *(LDKNetAddress*)this_ptr;
+       if ((this_ptr & 1) != 0) return;
+       LDKNetAddress this_ptr_conv = *(LDKNetAddress*)(((uint64_t)this_ptr) & ~1);
        FREE((void*)this_ptr);
        NetAddress_free(this_ptr_conv);
 }
@@ -11747,7 +11764,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_UnsignedNodeAnnouncement_1set_
        LDKNodeFeatures val_conv;
        val_conv.inner = (void*)(val & (~1));
        val_conv.is_owned = (val & 1) || (val == 0);
-       // Warning: we may need a move here but can't clone!
+       // Warning: we need a move here but no clone is available for LDKNodeFeatures
        UnsignedNodeAnnouncement_set_features(&this_ptr_conv, val_conv);
 }
 
@@ -11836,7 +11853,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_UnsignedNodeAnnouncement_1set_
        int64_t* val_vals = (*env)->GetLongArrayElements (env, val, NULL);
        for (size_t m = 0; m < val_constr.datalen; m++) {
                int64_t arr_conv_12 = val_vals[m];
-               LDKNetAddress arr_conv_12_conv = *(LDKNetAddress*)arr_conv_12;
+               LDKNetAddress arr_conv_12_conv = *(LDKNetAddress*)(((uint64_t)arr_conv_12) & ~1);
                FREE((void*)arr_conv_12);
                val_constr.data[m] = arr_conv_12_conv;
        }
@@ -11905,8 +11922,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_NodeAnnouncement_1set_1content
        LDKUnsignedNodeAnnouncement val_conv;
        val_conv.inner = (void*)(val & (~1));
        val_conv.is_owned = (val & 1) || (val == 0);
-       if (val_conv.inner != NULL)
-               val_conv = UnsignedNodeAnnouncement_clone(&val_conv);
+       val_conv = UnsignedNodeAnnouncement_clone(&val_conv);
        NodeAnnouncement_set_contents(&this_ptr_conv, val_conv);
 }
 
@@ -11917,8 +11933,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_NodeAnnouncement_1new(JNIEn
        LDKUnsignedNodeAnnouncement contents_arg_conv;
        contents_arg_conv.inner = (void*)(contents_arg & (~1));
        contents_arg_conv.is_owned = (contents_arg & 1) || (contents_arg == 0);
-       if (contents_arg_conv.inner != NULL)
-               contents_arg_conv = UnsignedNodeAnnouncement_clone(&contents_arg_conv);
+       contents_arg_conv = UnsignedNodeAnnouncement_clone(&contents_arg_conv);
        LDKNodeAnnouncement ret_var = NodeAnnouncement_new(signature_arg_ref, contents_arg_conv);
        CHECK((((long)ret_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&ret_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
@@ -11971,7 +11986,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_UnsignedChannelAnnouncement_1s
        LDKChannelFeatures val_conv;
        val_conv.inner = (void*)(val & (~1));
        val_conv.is_owned = (val & 1) || (val == 0);
-       // Warning: we may need a move here but can't clone!
+       // Warning: we need a move here but no clone is available for LDKChannelFeatures
        UnsignedChannelAnnouncement_set_features(&this_ptr_conv, val_conv);
 }
 
@@ -12203,8 +12218,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelAnnouncement_1set_1cont
        LDKUnsignedChannelAnnouncement val_conv;
        val_conv.inner = (void*)(val & (~1));
        val_conv.is_owned = (val & 1) || (val == 0);
-       if (val_conv.inner != NULL)
-               val_conv = UnsignedChannelAnnouncement_clone(&val_conv);
+       val_conv = UnsignedChannelAnnouncement_clone(&val_conv);
        ChannelAnnouncement_set_contents(&this_ptr_conv, val_conv);
 }
 
@@ -12224,8 +12238,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ChannelAnnouncement_1new(JN
        LDKUnsignedChannelAnnouncement contents_arg_conv;
        contents_arg_conv.inner = (void*)(contents_arg & (~1));
        contents_arg_conv.is_owned = (contents_arg & 1) || (contents_arg == 0);
-       if (contents_arg_conv.inner != NULL)
-               contents_arg_conv = UnsignedChannelAnnouncement_clone(&contents_arg_conv);
+       contents_arg_conv = UnsignedChannelAnnouncement_clone(&contents_arg_conv);
        LDKChannelAnnouncement ret_var = ChannelAnnouncement_new(node_signature_1_arg_ref, node_signature_2_arg_ref, bitcoin_signature_1_arg_ref, bitcoin_signature_2_arg_ref, contents_arg_conv);
        CHECK((((long)ret_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&ret_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
@@ -12442,8 +12455,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelUpdate_1set_1contents(J
        LDKUnsignedChannelUpdate val_conv;
        val_conv.inner = (void*)(val & (~1));
        val_conv.is_owned = (val & 1) || (val == 0);
-       if (val_conv.inner != NULL)
-               val_conv = UnsignedChannelUpdate_clone(&val_conv);
+       val_conv = UnsignedChannelUpdate_clone(&val_conv);
        ChannelUpdate_set_contents(&this_ptr_conv, val_conv);
 }
 
@@ -12454,8 +12466,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ChannelUpdate_1new(JNIEnv *
        LDKUnsignedChannelUpdate contents_arg_conv;
        contents_arg_conv.inner = (void*)(contents_arg & (~1));
        contents_arg_conv.is_owned = (contents_arg & 1) || (contents_arg == 0);
-       if (contents_arg_conv.inner != NULL)
-               contents_arg_conv = UnsignedChannelUpdate_clone(&contents_arg_conv);
+       contents_arg_conv = UnsignedChannelUpdate_clone(&contents_arg_conv);
        LDKChannelUpdate ret_var = ChannelUpdate_new(signature_arg_ref, contents_arg_conv);
        CHECK((((long)ret_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&ret_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
@@ -12919,7 +12930,8 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_GossipTimestampFilter_1new(
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ErrorAction_1free(JNIEnv *env, jclass clz, int64_t this_ptr) {
-       LDKErrorAction this_ptr_conv = *(LDKErrorAction*)this_ptr;
+       if ((this_ptr & 1) != 0) return;
+       LDKErrorAction this_ptr_conv = *(LDKErrorAction*)(((uint64_t)this_ptr) & ~1);
        FREE((void*)this_ptr);
        ErrorAction_free(this_ptr_conv);
 }
@@ -12939,6 +12951,20 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_LightningError_1free(JNIEnv *e
        LightningError_free(this_ptr_conv);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LightningError_1clone(JNIEnv *env, jclass clz, int64_t orig) {
+       LDKLightningError orig_conv;
+       orig_conv.inner = (void*)(orig & (~1));
+       orig_conv.is_owned = false;
+       LDKLightningError ret_var = LightningError_clone(&orig_conv);
+       CHECK((((long)ret_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
+       CHECK((((long)&ret_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
+       long ret_ref = (long)ret_var.inner;
+       if (ret_var.is_owned) {
+               ret_ref |= 1;
+       }
+       return ret_ref;
+}
+
 JNIEXPORT jstring JNICALL Java_org_ldk_impl_bindings_LightningError_1get_1err(JNIEnv *env, jclass clz, int64_t this_ptr) {
        LDKLightningError this_ptr_conv;
        this_ptr_conv.inner = (void*)(this_ptr & (~1));
@@ -12973,7 +12999,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_LightningError_1set_1action(JN
        LDKLightningError this_ptr_conv;
        this_ptr_conv.inner = (void*)(this_ptr & (~1));
        this_ptr_conv.is_owned = false;
-       LDKErrorAction val_conv = *(LDKErrorAction*)val;
+       LDKErrorAction val_conv = *(LDKErrorAction*)(((uint64_t)val) & ~1);
        FREE((void*)val);
        LightningError_set_action(&this_ptr_conv, val_conv);
 }
@@ -12983,7 +13009,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_LightningError_1new(JNIEnv
        err_arg_ref.datalen = (*env)->GetArrayLength(env, err_arg);
        err_arg_ref.data = MALLOC(err_arg_ref.datalen, "LDKCVec_u8Z Bytes");
        (*env)->GetByteArrayRegion(env, err_arg, 0, err_arg_ref.datalen, err_arg_ref.data);
-       LDKErrorAction action_arg_conv = *(LDKErrorAction*)action_arg;
+       LDKErrorAction action_arg_conv = *(LDKErrorAction*)(((uint64_t)action_arg) & ~1);
        FREE((void*)action_arg);
        LDKLightningError ret_var = LightningError_new(err_arg_ref, action_arg_conv);
        CHECK((((long)ret_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
@@ -13032,8 +13058,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CommitmentUpdate_1set_1update_
                LDKUpdateAddHTLC arr_conv_15_conv;
                arr_conv_15_conv.inner = (void*)(arr_conv_15 & (~1));
                arr_conv_15_conv.is_owned = (arr_conv_15 & 1) || (arr_conv_15 == 0);
-               if (arr_conv_15_conv.inner != NULL)
-                       arr_conv_15_conv = UpdateAddHTLC_clone(&arr_conv_15_conv);
+               arr_conv_15_conv = UpdateAddHTLC_clone(&arr_conv_15_conv);
                val_constr.data[p] = arr_conv_15_conv;
        }
        (*env)->ReleaseLongArrayElements(env, val, val_vals, 0);
@@ -13056,8 +13081,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CommitmentUpdate_1set_1update_
                LDKUpdateFulfillHTLC arr_conv_19_conv;
                arr_conv_19_conv.inner = (void*)(arr_conv_19 & (~1));
                arr_conv_19_conv.is_owned = (arr_conv_19 & 1) || (arr_conv_19 == 0);
-               if (arr_conv_19_conv.inner != NULL)
-                       arr_conv_19_conv = UpdateFulfillHTLC_clone(&arr_conv_19_conv);
+               arr_conv_19_conv = UpdateFulfillHTLC_clone(&arr_conv_19_conv);
                val_constr.data[t] = arr_conv_19_conv;
        }
        (*env)->ReleaseLongArrayElements(env, val, val_vals, 0);
@@ -13080,8 +13104,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CommitmentUpdate_1set_1update_
                LDKUpdateFailHTLC arr_conv_16_conv;
                arr_conv_16_conv.inner = (void*)(arr_conv_16 & (~1));
                arr_conv_16_conv.is_owned = (arr_conv_16 & 1) || (arr_conv_16 == 0);
-               if (arr_conv_16_conv.inner != NULL)
-                       arr_conv_16_conv = UpdateFailHTLC_clone(&arr_conv_16_conv);
+               arr_conv_16_conv = UpdateFailHTLC_clone(&arr_conv_16_conv);
                val_constr.data[q] = arr_conv_16_conv;
        }
        (*env)->ReleaseLongArrayElements(env, val, val_vals, 0);
@@ -13104,8 +13127,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CommitmentUpdate_1set_1update_
                LDKUpdateFailMalformedHTLC arr_conv_25_conv;
                arr_conv_25_conv.inner = (void*)(arr_conv_25 & (~1));
                arr_conv_25_conv.is_owned = (arr_conv_25 & 1) || (arr_conv_25 == 0);
-               if (arr_conv_25_conv.inner != NULL)
-                       arr_conv_25_conv = UpdateFailMalformedHTLC_clone(&arr_conv_25_conv);
+               arr_conv_25_conv = UpdateFailMalformedHTLC_clone(&arr_conv_25_conv);
                val_constr.data[z] = arr_conv_25_conv;
        }
        (*env)->ReleaseLongArrayElements(env, val, val_vals, 0);
@@ -13133,8 +13155,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CommitmentUpdate_1set_1update_
        LDKUpdateFee val_conv;
        val_conv.inner = (void*)(val & (~1));
        val_conv.is_owned = (val & 1) || (val == 0);
-       if (val_conv.inner != NULL)
-               val_conv = UpdateFee_clone(&val_conv);
+       val_conv = UpdateFee_clone(&val_conv);
        CommitmentUpdate_set_update_fee(&this_ptr_conv, val_conv);
 }
 
@@ -13159,8 +13180,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CommitmentUpdate_1set_1commitm
        LDKCommitmentSigned val_conv;
        val_conv.inner = (void*)(val & (~1));
        val_conv.is_owned = (val & 1) || (val == 0);
-       if (val_conv.inner != NULL)
-               val_conv = CommitmentSigned_clone(&val_conv);
+       val_conv = CommitmentSigned_clone(&val_conv);
        CommitmentUpdate_set_commitment_signed(&this_ptr_conv, val_conv);
 }
 
@@ -13177,8 +13197,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CommitmentUpdate_1new(JNIEn
                LDKUpdateAddHTLC arr_conv_15_conv;
                arr_conv_15_conv.inner = (void*)(arr_conv_15 & (~1));
                arr_conv_15_conv.is_owned = (arr_conv_15 & 1) || (arr_conv_15 == 0);
-               if (arr_conv_15_conv.inner != NULL)
-                       arr_conv_15_conv = UpdateAddHTLC_clone(&arr_conv_15_conv);
+               arr_conv_15_conv = UpdateAddHTLC_clone(&arr_conv_15_conv);
                update_add_htlcs_arg_constr.data[p] = arr_conv_15_conv;
        }
        (*env)->ReleaseLongArrayElements(env, update_add_htlcs_arg, update_add_htlcs_arg_vals, 0);
@@ -13194,8 +13213,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CommitmentUpdate_1new(JNIEn
                LDKUpdateFulfillHTLC arr_conv_19_conv;
                arr_conv_19_conv.inner = (void*)(arr_conv_19 & (~1));
                arr_conv_19_conv.is_owned = (arr_conv_19 & 1) || (arr_conv_19 == 0);
-               if (arr_conv_19_conv.inner != NULL)
-                       arr_conv_19_conv = UpdateFulfillHTLC_clone(&arr_conv_19_conv);
+               arr_conv_19_conv = UpdateFulfillHTLC_clone(&arr_conv_19_conv);
                update_fulfill_htlcs_arg_constr.data[t] = arr_conv_19_conv;
        }
        (*env)->ReleaseLongArrayElements(env, update_fulfill_htlcs_arg, update_fulfill_htlcs_arg_vals, 0);
@@ -13211,8 +13229,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CommitmentUpdate_1new(JNIEn
                LDKUpdateFailHTLC arr_conv_16_conv;
                arr_conv_16_conv.inner = (void*)(arr_conv_16 & (~1));
                arr_conv_16_conv.is_owned = (arr_conv_16 & 1) || (arr_conv_16 == 0);
-               if (arr_conv_16_conv.inner != NULL)
-                       arr_conv_16_conv = UpdateFailHTLC_clone(&arr_conv_16_conv);
+               arr_conv_16_conv = UpdateFailHTLC_clone(&arr_conv_16_conv);
                update_fail_htlcs_arg_constr.data[q] = arr_conv_16_conv;
        }
        (*env)->ReleaseLongArrayElements(env, update_fail_htlcs_arg, update_fail_htlcs_arg_vals, 0);
@@ -13228,21 +13245,18 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CommitmentUpdate_1new(JNIEn
                LDKUpdateFailMalformedHTLC arr_conv_25_conv;
                arr_conv_25_conv.inner = (void*)(arr_conv_25 & (~1));
                arr_conv_25_conv.is_owned = (arr_conv_25 & 1) || (arr_conv_25 == 0);
-               if (arr_conv_25_conv.inner != NULL)
-                       arr_conv_25_conv = UpdateFailMalformedHTLC_clone(&arr_conv_25_conv);
+               arr_conv_25_conv = UpdateFailMalformedHTLC_clone(&arr_conv_25_conv);
                update_fail_malformed_htlcs_arg_constr.data[z] = arr_conv_25_conv;
        }
        (*env)->ReleaseLongArrayElements(env, update_fail_malformed_htlcs_arg, update_fail_malformed_htlcs_arg_vals, 0);
        LDKUpdateFee update_fee_arg_conv;
        update_fee_arg_conv.inner = (void*)(update_fee_arg & (~1));
        update_fee_arg_conv.is_owned = (update_fee_arg & 1) || (update_fee_arg == 0);
-       if (update_fee_arg_conv.inner != NULL)
-               update_fee_arg_conv = UpdateFee_clone(&update_fee_arg_conv);
+       update_fee_arg_conv = UpdateFee_clone(&update_fee_arg_conv);
        LDKCommitmentSigned commitment_signed_arg_conv;
        commitment_signed_arg_conv.inner = (void*)(commitment_signed_arg & (~1));
        commitment_signed_arg_conv.is_owned = (commitment_signed_arg & 1) || (commitment_signed_arg == 0);
-       if (commitment_signed_arg_conv.inner != NULL)
-               commitment_signed_arg_conv = CommitmentSigned_clone(&commitment_signed_arg_conv);
+       commitment_signed_arg_conv = CommitmentSigned_clone(&commitment_signed_arg_conv);
        LDKCommitmentUpdate ret_var = CommitmentUpdate_new(update_add_htlcs_arg_constr, update_fulfill_htlcs_arg_constr, update_fail_htlcs_arg_constr, update_fail_malformed_htlcs_arg_constr, update_fee_arg_conv, commitment_signed_arg_conv);
        CHECK((((long)ret_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&ret_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
@@ -13254,7 +13268,8 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CommitmentUpdate_1new(JNIEn
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_HTLCFailChannelUpdate_1free(JNIEnv *env, jclass clz, int64_t this_ptr) {
-       LDKHTLCFailChannelUpdate this_ptr_conv = *(LDKHTLCFailChannelUpdate*)this_ptr;
+       if ((this_ptr & 1) != 0) return;
+       LDKHTLCFailChannelUpdate this_ptr_conv = *(LDKHTLCFailChannelUpdate*)(((uint64_t)this_ptr) & ~1);
        FREE((void*)this_ptr);
        HTLCFailChannelUpdate_free(this_ptr_conv);
 }
@@ -13268,13 +13283,15 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_HTLCFailChannelUpdate_1clon
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelMessageHandler_1free(JNIEnv *env, jclass clz, int64_t this_ptr) {
-       LDKChannelMessageHandler this_ptr_conv = *(LDKChannelMessageHandler*)this_ptr;
+       if ((this_ptr & 1) != 0) return;
+       LDKChannelMessageHandler this_ptr_conv = *(LDKChannelMessageHandler*)(((uint64_t)this_ptr) & ~1);
        FREE((void*)this_ptr);
        ChannelMessageHandler_free(this_ptr_conv);
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_RoutingMessageHandler_1free(JNIEnv *env, jclass clz, int64_t this_ptr) {
-       LDKRoutingMessageHandler this_ptr_conv = *(LDKRoutingMessageHandler*)this_ptr;
+       if ((this_ptr & 1) != 0) return;
+       LDKRoutingMessageHandler this_ptr_conv = *(LDKRoutingMessageHandler*)(((uint64_t)this_ptr) & ~1);
        FREE((void*)this_ptr);
        RoutingMessageHandler_free(this_ptr_conv);
 }
@@ -14039,7 +14056,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_MessageHandler_1set_1chan_1han
        LDKMessageHandler this_ptr_conv;
        this_ptr_conv.inner = (void*)(this_ptr & (~1));
        this_ptr_conv.is_owned = false;
-       LDKChannelMessageHandler val_conv = *(LDKChannelMessageHandler*)val;
+       LDKChannelMessageHandler val_conv = *(LDKChannelMessageHandler*)(((uint64_t)val) & ~1);
        if (val_conv.free == LDKChannelMessageHandler_JCalls_free) {
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKChannelMessageHandler_JCalls_clone(val_conv.this_arg);
@@ -14059,7 +14076,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_MessageHandler_1set_1route_1ha
        LDKMessageHandler this_ptr_conv;
        this_ptr_conv.inner = (void*)(this_ptr & (~1));
        this_ptr_conv.is_owned = false;
-       LDKRoutingMessageHandler val_conv = *(LDKRoutingMessageHandler*)val;
+       LDKRoutingMessageHandler val_conv = *(LDKRoutingMessageHandler*)(((uint64_t)val) & ~1);
        if (val_conv.free == LDKRoutingMessageHandler_JCalls_free) {
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKRoutingMessageHandler_JCalls_clone(val_conv.this_arg);
@@ -14068,12 +14085,12 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_MessageHandler_1set_1route_1ha
 }
 
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_MessageHandler_1new(JNIEnv *env, jclass clz, int64_t chan_handler_arg, int64_t route_handler_arg) {
-       LDKChannelMessageHandler chan_handler_arg_conv = *(LDKChannelMessageHandler*)chan_handler_arg;
+       LDKChannelMessageHandler chan_handler_arg_conv = *(LDKChannelMessageHandler*)(((uint64_t)chan_handler_arg) & ~1);
        if (chan_handler_arg_conv.free == LDKChannelMessageHandler_JCalls_free) {
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKChannelMessageHandler_JCalls_clone(chan_handler_arg_conv.this_arg);
        }
-       LDKRoutingMessageHandler route_handler_arg_conv = *(LDKRoutingMessageHandler*)route_handler_arg;
+       LDKRoutingMessageHandler route_handler_arg_conv = *(LDKRoutingMessageHandler*)(((uint64_t)route_handler_arg) & ~1);
        if (route_handler_arg_conv.free == LDKRoutingMessageHandler_JCalls_free) {
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKRoutingMessageHandler_JCalls_clone(route_handler_arg_conv.this_arg);
@@ -14096,7 +14113,8 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_SocketDescriptor_1clone(JNI
 }
 
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_SocketDescriptor_1free(JNIEnv *env, jclass clz, int64_t this_ptr) {
-       LDKSocketDescriptor this_ptr_conv = *(LDKSocketDescriptor*)this_ptr;
+       if ((this_ptr & 1) != 0) return;
+       LDKSocketDescriptor this_ptr_conv = *(LDKSocketDescriptor*)(((uint64_t)this_ptr) & ~1);
        FREE((void*)this_ptr);
        SocketDescriptor_free(this_ptr_conv);
 }
@@ -14108,6 +14126,20 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_PeerHandleError_1free(JNIEnv *
        PeerHandleError_free(this_ptr_conv);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_PeerHandleError_1clone(JNIEnv *env, jclass clz, int64_t orig) {
+       LDKPeerHandleError orig_conv;
+       orig_conv.inner = (void*)(orig & (~1));
+       orig_conv.is_owned = false;
+       LDKPeerHandleError ret_var = PeerHandleError_clone(&orig_conv);
+       CHECK((((long)ret_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
+       CHECK((((long)&ret_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
+       long ret_ref = (long)ret_var.inner;
+       if (ret_var.is_owned) {
+               ret_ref |= 1;
+       }
+       return ret_ref;
+}
+
 JNIEXPORT jboolean JNICALL Java_org_ldk_impl_bindings_PeerHandleError_1get_1no_1connection_1possible(JNIEnv *env, jclass clz, int64_t this_ptr) {
        LDKPeerHandleError this_ptr_conv;
        this_ptr_conv.inner = (void*)(this_ptr & (~1));
@@ -14145,7 +14177,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_PeerManager_1new(JNIEnv *en
        LDKMessageHandler message_handler_conv;
        message_handler_conv.inner = (void*)(message_handler & (~1));
        message_handler_conv.is_owned = (message_handler & 1) || (message_handler == 0);
-       // Warning: we may need a move here but can't clone!
+       // Warning: we need a move here but no clone is available for LDKMessageHandler
        LDKSecretKey our_node_secret_ref;
        CHECK((*env)->GetArrayLength(env, our_node_secret) == 32);
        (*env)->GetByteArrayRegion(env, our_node_secret, 0, 32, our_node_secret_ref.bytes);
@@ -14153,7 +14185,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_PeerManager_1new(JNIEnv *en
        CHECK((*env)->GetArrayLength(env, ephemeral_random_data) == 32);
        (*env)->GetByteArrayRegion(env, ephemeral_random_data, 0, 32, ephemeral_random_data_arr);
        unsigned char (*ephemeral_random_data_ref)[32] = &ephemeral_random_data_arr;
-       LDKLogger logger_conv = *(LDKLogger*)logger;
+       LDKLogger logger_conv = *(LDKLogger*)(((uint64_t)logger) & ~1);
        if (logger_conv.free == LDKLogger_JCalls_free) {
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKLogger_JCalls_clone(logger_conv.this_arg);
@@ -14191,7 +14223,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_PeerManager_1new_1outbound_
        LDKPublicKey their_node_id_ref;
        CHECK((*env)->GetArrayLength(env, their_node_id) == 33);
        (*env)->GetByteArrayRegion(env, their_node_id, 0, 33, their_node_id_ref.compressed_form);
-       LDKSocketDescriptor descriptor_conv = *(LDKSocketDescriptor*)descriptor;
+       LDKSocketDescriptor descriptor_conv = *(LDKSocketDescriptor*)(((uint64_t)descriptor) & ~1);
        if (descriptor_conv.free == LDKSocketDescriptor_JCalls_free) {
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKSocketDescriptor_JCalls_clone(descriptor_conv.this_arg);
@@ -14205,7 +14237,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_PeerManager_1new_1inbound_1
        LDKPeerManager this_arg_conv;
        this_arg_conv.inner = (void*)(this_arg & (~1));
        this_arg_conv.is_owned = false;
-       LDKSocketDescriptor descriptor_conv = *(LDKSocketDescriptor*)descriptor;
+       LDKSocketDescriptor descriptor_conv = *(LDKSocketDescriptor*)(((uint64_t)descriptor) & ~1);
        if (descriptor_conv.free == LDKSocketDescriptor_JCalls_free) {
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKSocketDescriptor_JCalls_clone(descriptor_conv.this_arg);
@@ -14910,8 +14942,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelTransactionParameters_1
        LDKChannelPublicKeys val_conv;
        val_conv.inner = (void*)(val & (~1));
        val_conv.is_owned = (val & 1) || (val == 0);
-       if (val_conv.inner != NULL)
-               val_conv = ChannelPublicKeys_clone(&val_conv);
+       val_conv = ChannelPublicKeys_clone(&val_conv);
        ChannelTransactionParameters_set_holder_pubkeys(&this_ptr_conv, val_conv);
 }
 
@@ -14966,8 +14997,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelTransactionParameters_1
        LDKCounterpartyChannelTransactionParameters val_conv;
        val_conv.inner = (void*)(val & (~1));
        val_conv.is_owned = (val & 1) || (val == 0);
-       if (val_conv.inner != NULL)
-               val_conv = CounterpartyChannelTransactionParameters_clone(&val_conv);
+       val_conv = CounterpartyChannelTransactionParameters_clone(&val_conv);
        ChannelTransactionParameters_set_counterparty_parameters(&this_ptr_conv, val_conv);
 }
 
@@ -14992,8 +15022,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelTransactionParameters_1
        LDKOutPoint val_conv;
        val_conv.inner = (void*)(val & (~1));
        val_conv.is_owned = (val & 1) || (val == 0);
-       if (val_conv.inner != NULL)
-               val_conv = OutPoint_clone(&val_conv);
+       val_conv = OutPoint_clone(&val_conv);
        ChannelTransactionParameters_set_funding_outpoint(&this_ptr_conv, val_conv);
 }
 
@@ -15001,18 +15030,15 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_ChannelTransactionParameter
        LDKChannelPublicKeys holder_pubkeys_arg_conv;
        holder_pubkeys_arg_conv.inner = (void*)(holder_pubkeys_arg & (~1));
        holder_pubkeys_arg_conv.is_owned = (holder_pubkeys_arg & 1) || (holder_pubkeys_arg == 0);
-       if (holder_pubkeys_arg_conv.inner != NULL)
-               holder_pubkeys_arg_conv = ChannelPublicKeys_clone(&holder_pubkeys_arg_conv);
+       holder_pubkeys_arg_conv = ChannelPublicKeys_clone(&holder_pubkeys_arg_conv);
        LDKCounterpartyChannelTransactionParameters counterparty_parameters_arg_conv;
        counterparty_parameters_arg_conv.inner = (void*)(counterparty_parameters_arg & (~1));
        counterparty_parameters_arg_conv.is_owned = (counterparty_parameters_arg & 1) || (counterparty_parameters_arg == 0);
-       if (counterparty_parameters_arg_conv.inner != NULL)
-               counterparty_parameters_arg_conv = CounterpartyChannelTransactionParameters_clone(&counterparty_parameters_arg_conv);
+       counterparty_parameters_arg_conv = CounterpartyChannelTransactionParameters_clone(&counterparty_parameters_arg_conv);
        LDKOutPoint funding_outpoint_arg_conv;
        funding_outpoint_arg_conv.inner = (void*)(funding_outpoint_arg & (~1));
        funding_outpoint_arg_conv.is_owned = (funding_outpoint_arg & 1) || (funding_outpoint_arg == 0);
-       if (funding_outpoint_arg_conv.inner != NULL)
-               funding_outpoint_arg_conv = OutPoint_clone(&funding_outpoint_arg_conv);
+       funding_outpoint_arg_conv = OutPoint_clone(&funding_outpoint_arg_conv);
        LDKChannelTransactionParameters ret_var = ChannelTransactionParameters_new(holder_pubkeys_arg_conv, holder_selected_contest_delay_arg, is_outbound_from_holder_arg, counterparty_parameters_arg_conv, funding_outpoint_arg_conv);
        CHECK((((long)ret_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&ret_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
@@ -15065,8 +15091,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_CounterpartyChannelTransaction
        LDKChannelPublicKeys val_conv;
        val_conv.inner = (void*)(val & (~1));
        val_conv.is_owned = (val & 1) || (val == 0);
-       if (val_conv.inner != NULL)
-               val_conv = ChannelPublicKeys_clone(&val_conv);
+       val_conv = ChannelPublicKeys_clone(&val_conv);
        CounterpartyChannelTransactionParameters_set_pubkeys(&this_ptr_conv, val_conv);
 }
 
@@ -15089,8 +15114,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_CounterpartyChannelTransact
        LDKChannelPublicKeys pubkeys_arg_conv;
        pubkeys_arg_conv.inner = (void*)(pubkeys_arg & (~1));
        pubkeys_arg_conv.is_owned = (pubkeys_arg & 1) || (pubkeys_arg == 0);
-       if (pubkeys_arg_conv.inner != NULL)
-               pubkeys_arg_conv = ChannelPublicKeys_clone(&pubkeys_arg_conv);
+       pubkeys_arg_conv = ChannelPublicKeys_clone(&pubkeys_arg_conv);
        LDKCounterpartyChannelTransactionParameters ret_var = CounterpartyChannelTransactionParameters_new(pubkeys_arg_conv, selected_contest_delay_arg);
        CHECK((((long)ret_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&ret_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
@@ -15344,8 +15368,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_HolderCommitmentTransaction
        LDKCommitmentTransaction commitment_tx_conv;
        commitment_tx_conv.inner = (void*)(commitment_tx & (~1));
        commitment_tx_conv.is_owned = (commitment_tx & 1) || (commitment_tx == 0);
-       if (commitment_tx_conv.inner != NULL)
-               commitment_tx_conv = CommitmentTransaction_clone(&commitment_tx_conv);
+       commitment_tx_conv = CommitmentTransaction_clone(&commitment_tx_conv);
        LDKSignature counterparty_sig_ref;
        CHECK((*env)->GetArrayLength(env, counterparty_sig) == 64);
        (*env)->GetByteArrayRegion(env, counterparty_sig, 0, 64, counterparty_sig_ref.compact_form);
@@ -15780,7 +15803,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_RouteHop_1set_1node_1features(
        LDKNodeFeatures val_conv;
        val_conv.inner = (void*)(val & (~1));
        val_conv.is_owned = (val & 1) || (val == 0);
-       // Warning: we may need a move here but can't clone!
+       // Warning: we need a move here but no clone is available for LDKNodeFeatures
        RouteHop_set_node_features(&this_ptr_conv, val_conv);
 }
 
@@ -15820,7 +15843,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_RouteHop_1set_1channel_1featur
        LDKChannelFeatures val_conv;
        val_conv.inner = (void*)(val & (~1));
        val_conv.is_owned = (val & 1) || (val == 0);
-       // Warning: we may need a move here but can't clone!
+       // Warning: we need a move here but no clone is available for LDKChannelFeatures
        RouteHop_set_channel_features(&this_ptr_conv, val_conv);
 }
 
@@ -15861,11 +15884,11 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_RouteHop_1new(JNIEnv *env,
        LDKNodeFeatures node_features_arg_conv;
        node_features_arg_conv.inner = (void*)(node_features_arg & (~1));
        node_features_arg_conv.is_owned = (node_features_arg & 1) || (node_features_arg == 0);
-       // Warning: we may need a move here but can't clone!
+       // Warning: we need a move here but no clone is available for LDKNodeFeatures
        LDKChannelFeatures channel_features_arg_conv;
        channel_features_arg_conv.inner = (void*)(channel_features_arg & (~1));
        channel_features_arg_conv.is_owned = (channel_features_arg & 1) || (channel_features_arg == 0);
-       // Warning: we may need a move here but can't clone!
+       // Warning: we need a move here but no clone is available for LDKChannelFeatures
        LDKRouteHop ret_var = RouteHop_new(pubkey_arg_ref, node_features_arg_conv, short_channel_id_arg, channel_features_arg_conv, fee_msat_arg, cltv_expiry_delta_arg);
        CHECK((((long)ret_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&ret_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
@@ -15921,8 +15944,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_Route_1set_1paths(JNIEnv *env,
                        LDKRouteHop arr_conv_10_conv;
                        arr_conv_10_conv.inner = (void*)(arr_conv_10 & (~1));
                        arr_conv_10_conv.is_owned = (arr_conv_10 & 1) || (arr_conv_10 == 0);
-                       if (arr_conv_10_conv.inner != NULL)
-                               arr_conv_10_conv = RouteHop_clone(&arr_conv_10_conv);
+                       arr_conv_10_conv = RouteHop_clone(&arr_conv_10_conv);
                        arr_conv_12_constr.data[k] = arr_conv_10_conv;
                }
                (*env)->ReleaseLongArrayElements(env, arr_conv_12, arr_conv_12_vals, 0);
@@ -15952,8 +15974,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_Route_1new(JNIEnv *env, jcl
                        LDKRouteHop arr_conv_10_conv;
                        arr_conv_10_conv.inner = (void*)(arr_conv_10 & (~1));
                        arr_conv_10_conv.is_owned = (arr_conv_10 & 1) || (arr_conv_10 == 0);
-                       if (arr_conv_10_conv.inner != NULL)
-                               arr_conv_10_conv = RouteHop_clone(&arr_conv_10_conv);
+                       arr_conv_10_conv = RouteHop_clone(&arr_conv_10_conv);
                        arr_conv_12_constr.data[k] = arr_conv_10_conv;
                }
                (*env)->ReleaseLongArrayElements(env, arr_conv_12, arr_conv_12_vals, 0);
@@ -16066,8 +16087,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_RouteHint_1set_1fees(JNIEnv *e
        LDKRoutingFees val_conv;
        val_conv.inner = (void*)(val & (~1));
        val_conv.is_owned = (val & 1) || (val == 0);
-       if (val_conv.inner != NULL)
-               val_conv = RoutingFees_clone(&val_conv);
+       val_conv = RoutingFees_clone(&val_conv);
        RouteHint_set_fees(&this_ptr_conv, val_conv);
 }
 
@@ -16108,8 +16128,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_RouteHint_1new(JNIEnv *env,
        LDKRoutingFees fees_arg_conv;
        fees_arg_conv.inner = (void*)(fees_arg & (~1));
        fees_arg_conv.is_owned = (fees_arg & 1) || (fees_arg == 0);
-       if (fees_arg_conv.inner != NULL)
-               fees_arg_conv = RoutingFees_clone(&fees_arg_conv);
+       fees_arg_conv = RoutingFees_clone(&fees_arg_conv);
        LDKRouteHint ret_var = RouteHint_new(src_node_id_arg_ref, short_channel_id_arg, fees_arg_conv, cltv_expiry_delta_arg, htlc_minimum_msat_arg);
        CHECK((((long)ret_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&ret_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
@@ -16157,12 +16176,11 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_get_1route(JNIEnv *env, jcl
                LDKRouteHint arr_conv_11_conv;
                arr_conv_11_conv.inner = (void*)(arr_conv_11 & (~1));
                arr_conv_11_conv.is_owned = (arr_conv_11 & 1) || (arr_conv_11 == 0);
-               if (arr_conv_11_conv.inner != NULL)
-                       arr_conv_11_conv = RouteHint_clone(&arr_conv_11_conv);
+               arr_conv_11_conv = RouteHint_clone(&arr_conv_11_conv);
                last_hops_constr.data[l] = arr_conv_11_conv;
        }
        (*env)->ReleaseLongArrayElements(env, last_hops, last_hops_vals, 0);
-       LDKLogger logger_conv = *(LDKLogger*)logger;
+       LDKLogger logger_conv = *(LDKLogger*)(((uint64_t)logger) & ~1);
        if (logger_conv.free == LDKLogger_JCalls_free) {
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKLogger_JCalls_clone(logger_conv.this_arg);
@@ -16199,7 +16217,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_NetGraphMsgHandler_1new(JNI
        CHECK((*env)->GetArrayLength(env, genesis_hash) == 32);
        (*env)->GetByteArrayRegion(env, genesis_hash, 0, 32, genesis_hash_ref.data);
        LDKAccess* chain_access_conv = (LDKAccess*)chain_access;
-       LDKLogger logger_conv = *(LDKLogger*)logger;
+       LDKLogger logger_conv = *(LDKLogger*)(((uint64_t)logger) & ~1);
        if (logger_conv.free == LDKLogger_JCalls_free) {
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKLogger_JCalls_clone(logger_conv.this_arg);
@@ -16216,7 +16234,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_NetGraphMsgHandler_1new(JNI
 
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_NetGraphMsgHandler_1from_1net_1graph(JNIEnv *env, jclass clz, int64_t chain_access, int64_t logger, int64_t network_graph) {
        LDKAccess* chain_access_conv = (LDKAccess*)chain_access;
-       LDKLogger logger_conv = *(LDKLogger*)logger;
+       LDKLogger logger_conv = *(LDKLogger*)(((uint64_t)logger) & ~1);
        if (logger_conv.free == LDKLogger_JCalls_free) {
                // If this_arg is a JCalls struct, then we need to increment the refcnt in it.
                LDKLogger_JCalls_clone(logger_conv.this_arg);
@@ -16224,7 +16242,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_NetGraphMsgHandler_1from_1n
        LDKNetworkGraph network_graph_conv;
        network_graph_conv.inner = (void*)(network_graph & (~1));
        network_graph_conv.is_owned = (network_graph & 1) || (network_graph == 0);
-       // Warning: we may need a move here but can't clone!
+       // Warning: we need a move here but no clone is available for LDKNetworkGraph
        LDKNetGraphMsgHandler ret_var = NetGraphMsgHandler_from_net_graph(chain_access_conv, logger_conv, network_graph_conv);
        CHECK((((long)ret_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&ret_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
@@ -16288,6 +16306,20 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_DirectionalChannelInfo_1free(J
        DirectionalChannelInfo_free(this_ptr_conv);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_DirectionalChannelInfo_1clone(JNIEnv *env, jclass clz, int64_t orig) {
+       LDKDirectionalChannelInfo orig_conv;
+       orig_conv.inner = (void*)(orig & (~1));
+       orig_conv.is_owned = false;
+       LDKDirectionalChannelInfo ret_var = DirectionalChannelInfo_clone(&orig_conv);
+       CHECK((((long)ret_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
+       CHECK((((long)&ret_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
+       long ret_ref = (long)ret_var.inner;
+       if (ret_var.is_owned) {
+               ret_ref |= 1;
+       }
+       return ret_ref;
+}
+
 JNIEXPORT int32_t JNICALL Java_org_ldk_impl_bindings_DirectionalChannelInfo_1get_1last_1update(JNIEnv *env, jclass clz, int64_t this_ptr) {
        LDKDirectionalChannelInfo this_ptr_conv;
        this_ptr_conv.inner = (void*)(this_ptr & (~1));
@@ -16369,8 +16401,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_DirectionalChannelInfo_1set_1f
        LDKRoutingFees val_conv;
        val_conv.inner = (void*)(val & (~1));
        val_conv.is_owned = (val & 1) || (val == 0);
-       if (val_conv.inner != NULL)
-               val_conv = RoutingFees_clone(&val_conv);
+       val_conv = RoutingFees_clone(&val_conv);
        DirectionalChannelInfo_set_fees(&this_ptr_conv, val_conv);
 }
 
@@ -16395,8 +16426,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_DirectionalChannelInfo_1set_1l
        LDKChannelUpdate val_conv;
        val_conv.inner = (void*)(val & (~1));
        val_conv.is_owned = (val & 1) || (val == 0);
-       if (val_conv.inner != NULL)
-               val_conv = ChannelUpdate_clone(&val_conv);
+       val_conv = ChannelUpdate_clone(&val_conv);
        DirectionalChannelInfo_set_last_update_message(&this_ptr_conv, val_conv);
 }
 
@@ -16454,7 +16484,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelInfo_1set_1features(JNI
        LDKChannelFeatures val_conv;
        val_conv.inner = (void*)(val & (~1));
        val_conv.is_owned = (val & 1) || (val == 0);
-       // Warning: we may need a move here but can't clone!
+       // Warning: we need a move here but no clone is available for LDKChannelFeatures
        ChannelInfo_set_features(&this_ptr_conv, val_conv);
 }
 
@@ -16498,7 +16528,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelInfo_1set_1one_1to_1two
        LDKDirectionalChannelInfo val_conv;
        val_conv.inner = (void*)(val & (~1));
        val_conv.is_owned = (val & 1) || (val == 0);
-       // Warning: we may need a move here but can't clone!
+       val_conv = DirectionalChannelInfo_clone(&val_conv);
        ChannelInfo_set_one_to_two(&this_ptr_conv, val_conv);
 }
 
@@ -16542,7 +16572,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelInfo_1set_1two_1to_1one
        LDKDirectionalChannelInfo val_conv;
        val_conv.inner = (void*)(val & (~1));
        val_conv.is_owned = (val & 1) || (val == 0);
-       // Warning: we may need a move here but can't clone!
+       val_conv = DirectionalChannelInfo_clone(&val_conv);
        ChannelInfo_set_two_to_one(&this_ptr_conv, val_conv);
 }
 
@@ -16567,8 +16597,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_ChannelInfo_1set_1announcement
        LDKChannelAnnouncement val_conv;
        val_conv.inner = (void*)(val & (~1));
        val_conv.is_owned = (val & 1) || (val == 0);
-       if (val_conv.inner != NULL)
-               val_conv = ChannelAnnouncement_clone(&val_conv);
+       val_conv = ChannelAnnouncement_clone(&val_conv);
        ChannelInfo_set_announcement_message(&this_ptr_conv, val_conv);
 }
 
@@ -16688,6 +16717,20 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_NodeAnnouncementInfo_1free(JNI
        NodeAnnouncementInfo_free(this_ptr_conv);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_NodeAnnouncementInfo_1clone(JNIEnv *env, jclass clz, int64_t orig) {
+       LDKNodeAnnouncementInfo orig_conv;
+       orig_conv.inner = (void*)(orig & (~1));
+       orig_conv.is_owned = false;
+       LDKNodeAnnouncementInfo ret_var = NodeAnnouncementInfo_clone(&orig_conv);
+       CHECK((((long)ret_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
+       CHECK((((long)&ret_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
+       long ret_ref = (long)ret_var.inner;
+       if (ret_var.is_owned) {
+               ret_ref |= 1;
+       }
+       return ret_ref;
+}
+
 JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_NodeAnnouncementInfo_1get_1features(JNIEnv *env, jclass clz, int64_t this_ptr) {
        LDKNodeAnnouncementInfo this_ptr_conv;
        this_ptr_conv.inner = (void*)(this_ptr & (~1));
@@ -16709,7 +16752,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_NodeAnnouncementInfo_1set_1fea
        LDKNodeFeatures val_conv;
        val_conv.inner = (void*)(val & (~1));
        val_conv.is_owned = (val & 1) || (val == 0);
-       // Warning: we may need a move here but can't clone!
+       // Warning: we need a move here but no clone is available for LDKNodeFeatures
        NodeAnnouncementInfo_set_features(&this_ptr_conv, val_conv);
 }
 
@@ -16779,7 +16822,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_NodeAnnouncementInfo_1set_1add
        int64_t* val_vals = (*env)->GetLongArrayElements (env, val, NULL);
        for (size_t m = 0; m < val_constr.datalen; m++) {
                int64_t arr_conv_12 = val_vals[m];
-               LDKNetAddress arr_conv_12_conv = *(LDKNetAddress*)arr_conv_12;
+               LDKNetAddress arr_conv_12_conv = *(LDKNetAddress*)(((uint64_t)arr_conv_12) & ~1);
                FREE((void*)arr_conv_12);
                val_constr.data[m] = arr_conv_12_conv;
        }
@@ -16808,8 +16851,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_NodeAnnouncementInfo_1set_1ann
        LDKNodeAnnouncement val_conv;
        val_conv.inner = (void*)(val & (~1));
        val_conv.is_owned = (val & 1) || (val == 0);
-       if (val_conv.inner != NULL)
-               val_conv = NodeAnnouncement_clone(&val_conv);
+       val_conv = NodeAnnouncement_clone(&val_conv);
        NodeAnnouncementInfo_set_announcement_message(&this_ptr_conv, val_conv);
 }
 
@@ -16817,7 +16859,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_NodeAnnouncementInfo_1new(J
        LDKNodeFeatures features_arg_conv;
        features_arg_conv.inner = (void*)(features_arg & (~1));
        features_arg_conv.is_owned = (features_arg & 1) || (features_arg == 0);
-       // Warning: we may need a move here but can't clone!
+       // Warning: we need a move here but no clone is available for LDKNodeFeatures
        LDKThreeBytes rgb_arg_ref;
        CHECK((*env)->GetArrayLength(env, rgb_arg) == 3);
        (*env)->GetByteArrayRegion(env, rgb_arg, 0, 3, rgb_arg_ref.data);
@@ -16833,7 +16875,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_NodeAnnouncementInfo_1new(J
        int64_t* addresses_arg_vals = (*env)->GetLongArrayElements (env, addresses_arg, NULL);
        for (size_t m = 0; m < addresses_arg_constr.datalen; m++) {
                int64_t arr_conv_12 = addresses_arg_vals[m];
-               LDKNetAddress arr_conv_12_conv = *(LDKNetAddress*)arr_conv_12;
+               LDKNetAddress arr_conv_12_conv = *(LDKNetAddress*)(((uint64_t)arr_conv_12) & ~1);
                FREE((void*)arr_conv_12);
                addresses_arg_constr.data[m] = arr_conv_12_conv;
        }
@@ -16841,8 +16883,7 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_NodeAnnouncementInfo_1new(J
        LDKNodeAnnouncement announcement_message_arg_conv;
        announcement_message_arg_conv.inner = (void*)(announcement_message_arg & (~1));
        announcement_message_arg_conv.is_owned = (announcement_message_arg & 1) || (announcement_message_arg == 0);
-       if (announcement_message_arg_conv.inner != NULL)
-               announcement_message_arg_conv = NodeAnnouncement_clone(&announcement_message_arg_conv);
+       announcement_message_arg_conv = NodeAnnouncement_clone(&announcement_message_arg_conv);
        LDKNodeAnnouncementInfo ret_var = NodeAnnouncementInfo_new(features_arg_conv, last_update_arg, rgb_arg_ref, alias_arg_ref, addresses_arg_constr, announcement_message_arg_conv);
        CHECK((((long)ret_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&ret_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
@@ -16881,6 +16922,20 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_NodeInfo_1free(JNIEnv *env, jc
        NodeInfo_free(this_ptr_conv);
 }
 
+JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_NodeInfo_1clone(JNIEnv *env, jclass clz, int64_t orig) {
+       LDKNodeInfo orig_conv;
+       orig_conv.inner = (void*)(orig & (~1));
+       orig_conv.is_owned = false;
+       LDKNodeInfo ret_var = NodeInfo_clone(&orig_conv);
+       CHECK((((long)ret_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
+       CHECK((((long)&ret_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.
+       long ret_ref = (long)ret_var.inner;
+       if (ret_var.is_owned) {
+               ret_ref |= 1;
+       }
+       return ret_ref;
+}
+
 JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_NodeInfo_1set_1channels(JNIEnv *env, jclass clz, int64_t this_ptr, int64_tArray val) {
        LDKNodeInfo this_ptr_conv;
        this_ptr_conv.inner = (void*)(this_ptr & (~1));
@@ -16921,8 +16976,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_NodeInfo_1set_1lowest_1inbound
        LDKRoutingFees val_conv;
        val_conv.inner = (void*)(val & (~1));
        val_conv.is_owned = (val & 1) || (val == 0);
-       if (val_conv.inner != NULL)
-               val_conv = RoutingFees_clone(&val_conv);
+       val_conv = RoutingFees_clone(&val_conv);
        NodeInfo_set_lowest_inbound_channel_fees(&this_ptr_conv, val_conv);
 }
 
@@ -16947,7 +17001,7 @@ JNIEXPORT void JNICALL Java_org_ldk_impl_bindings_NodeInfo_1set_1announcement_1i
        LDKNodeAnnouncementInfo val_conv;
        val_conv.inner = (void*)(val & (~1));
        val_conv.is_owned = (val & 1) || (val == 0);
-       // Warning: we may need a move here but can't clone!
+       val_conv = NodeAnnouncementInfo_clone(&val_conv);
        NodeInfo_set_announcement_info(&this_ptr_conv, val_conv);
 }
 
@@ -16967,12 +17021,11 @@ JNIEXPORT int64_t JNICALL Java_org_ldk_impl_bindings_NodeInfo_1new(JNIEnv *env,
        LDKRoutingFees lowest_inbound_channel_fees_arg_conv;
        lowest_inbound_channel_fees_arg_conv.inner = (void*)(lowest_inbound_channel_fees_arg & (~1));
        lowest_inbound_channel_fees_arg_conv.is_owned = (lowest_inbound_channel_fees_arg & 1) || (lowest_inbound_channel_fees_arg == 0);
-       if (lowest_inbound_channel_fees_arg_conv.inner != NULL)
-               lowest_inbound_channel_fees_arg_conv = RoutingFees_clone(&lowest_inbound_channel_fees_arg_conv);
+       lowest_inbound_channel_fees_arg_conv = RoutingFees_clone(&lowest_inbound_channel_fees_arg_conv);
        LDKNodeAnnouncementInfo announcement_info_arg_conv;
        announcement_info_arg_conv.inner = (void*)(announcement_info_arg & (~1));
        announcement_info_arg_conv.is_owned = (announcement_info_arg & 1) || (announcement_info_arg == 0);
-       // Warning: we may need a move here but can't clone!
+       announcement_info_arg_conv = NodeAnnouncementInfo_clone(&announcement_info_arg_conv);
        LDKNodeInfo ret_var = NodeInfo_new(channels_arg_constr, lowest_inbound_channel_fees_arg_conv, announcement_info_arg_conv);
        CHECK((((long)ret_var.inner) & 1) == 0); // We rely on a free low bit, malloc guarantees this.
        CHECK((((long)&ret_var) & 1) == 0); // We rely on a free low bit, pointer alignment guarantees this.