Skip to content

Commit 6d094e7

Browse files
authored
Merge pull request #56 from TheBlueMatt/main
v0.0.103.1
2 parents 99d1a3b + a766f4f commit 6d094e7

File tree

618 files changed

+45276
-7684
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

618 files changed

+45276
-7684
lines changed

.github/workflows/build.yml

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -290,23 +290,26 @@ jobs:
290290
./genbindings.sh ./ldk-c-bindings/ "-I$JAVA_HOME/include/ -I$JAVA_HOME/include/darwin -isysroot$(xcrun --show-sdk-path)" false false || echo
291291
cat src/main/resources/liblightningjni_MacOSX-aarch64.nativelib > /dev/null
292292
fi
293-
- name: Fetch Maven 3.8.3
293+
- name: Fetch Maven 3.8.4
294294
run: |
295-
wget -O apache-maven-3.8.3-bin.tar.gz https://apache.osuosl.org/maven/maven-3/3.8.3/binaries/apache-maven-3.8.3-bin.tar.gz
296-
if [ "$(shasum -a 256 apache-maven-3.8.3-bin.tar.gz | awk '{ print $1 }')" != "0f1597d11085b8fe93d84652a18c6deea71ece9fabba45a02cf6600c7758fd5b" ]; then
295+
# We don't bother using the upstream mirrors as they remove prior
296+
# releases aggressively, causing spurious CI failures when we don't
297+
# care about the version used.
298+
wget -O apache-maven-3.8.4-bin.tar.gz https://bitcoin.ninja/apache-maven-3.8.4-bin.tar.gz
299+
if [ "$(shasum -a 256 apache-maven-3.8.4-bin.tar.gz | awk '{ print $1 }')" != "2cdc9c519427bb20fdc25bef5a9063b790e4abd930e7b14b4e9f4863d6f9f13c" ]; then
297300
echo "Bad hash"
298301
exit 1
299302
fi
300-
tar xvvf apache-maven-3.8.3-bin.tar.gz
301-
export PATH=apache-maven-3.8.3/bin:$PATH
303+
tar xvvf apache-maven-3.8.4-bin.tar.gz
304+
export PATH=apache-maven-3.8.4/bin:$PATH
302305
- name: Run Java Tests against built jar
303306
run: |
304-
mvn -DskipTests=true package
307+
mvn -q -B -DskipTests=true package
305308
export LDK_GARBAGECOLLECTED_GIT_OVERRIDE="$(git describe --tag HEAD)"
306309
JAR_VERSION=${LDK_GARBAGECOLLECTED_GIT_OVERRIDE:1:100}
307310
mvn install:install-file -Dfile=target/ldk-java-${JAR_VERSION}.jar -DgroupId=org.lightningdevkit -DartifactId=ldk-java -Dversion=1.0-SNAPSHOT -Dpackaging=jar
308311
cd javatester
309-
mvn package
312+
mvn -q -B package
310313
java -ea -jar target/ldk-java-tests-1.0-SNAPSHOT-jar-with-dependencies.jar
311314
cd ..
312315
- name: Check latest release libs are in git
@@ -323,11 +326,11 @@ jobs:
323326
export LDK_GARBAGECOLLECTED_GIT_OVERRIDE="$(git describe --tag HEAD)"
324327
cp "ldk-java-bins/${LDK_GARBAGECOLLECTED_GIT_OVERRIDE}/"liblightningjni_MacOSX-{x86_64,aarch64}.nativelib src/main/resources/
325328
mvn clean
326-
mvn -DskipTests=true package
329+
mvn -q -B -DskipTests=true package
327330
JAR_VERSION=${LDK_GARBAGECOLLECTED_GIT_OVERRIDE:1:100}
328331
mvn install:install-file -Dfile=target/ldk-java-${JAR_VERSION}.jar -DgroupId=org.lightningdevkit -DartifactId=ldk-java -Dversion=1.0-SNAPSHOT -Dpackaging=jar
329332
cd javatester
330-
mvn package
333+
mvn -q -B package
331334
java -ea -jar target/ldk-java-tests-1.0-SNAPSHOT-jar-with-dependencies.jar
332335
cd ..
333336
fi

bindingstypes.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
class TypeInfo:
2-
def __init__(self, is_native_primitive, rust_obj, java_ty, java_fn_ty_arg, java_hu_ty, c_ty, is_const, passed_as_ptr, is_ptr, nonnull_ptr, var_name, arr_len, arr_access, subty=None):
2+
def __init__(self, is_native_primitive, rust_obj, java_ty, java_fn_ty_arg, java_hu_ty, c_ty, is_const, passed_as_ptr, is_ptr, nonnull_ptr, var_name, arr_len, arr_access, subty=None, contains_trait=False):
33
self.is_native_primitive = is_native_primitive
44
self.rust_obj = rust_obj
55
self.java_ty = java_ty
@@ -16,6 +16,7 @@ def __init__(self, is_native_primitive, rust_obj, java_ty, java_fn_ty_arg, java_
1616
self.subty = subty
1717
self.pass_by_ref = is_ptr
1818
self.requires_clone = None
19+
self.contains_trait = contains_trait
1920

2021
def get_full_rust_ty(self):
2122
ret = ""
@@ -77,7 +78,8 @@ def __init__(self, fn_name, self_is_const, ret_ty_info, args_ty, docs):
7778
self.docs = docs
7879

7980
class ComplexEnumVariantInfo:
80-
def __init__(self, var_name, fields, tuple_variant):
81+
def __init__(self, var_name, var_docs, fields, tuple_variant):
8182
self.var_name = var_name
83+
self.var_docs = var_docs
8284
self.fields = fields
8385
self.tuple_variant = tuple_variant

gen_type_mapping.py

Lines changed: 63 additions & 20 deletions
Large diffs are not rendered by default.

genbindings.py

Lines changed: 43 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,8 @@ def doc_to_params_ret_nullable(doc):
9494
return (params, ret_null)
9595

9696
unitary_enums = set()
97-
complex_enums = set()
97+
# Map from enum name to "contains trait object"
98+
complex_enums = {}
9899
opaque_structs = set()
99100
trait_structs = {}
100101
result_types = set()
@@ -225,6 +226,7 @@ def java_c_types(fn_arg, ret_arr_len):
225226
var_name=res.var_name, arr_len="datalen", arr_access="data", subty=res, is_native_primitive=False)
226227

227228
is_primitive = False
229+
contains_trait = False
228230
arr_len = None
229231
mapped_type = []
230232
java_type_plural = None
@@ -316,6 +318,10 @@ def java_c_types(fn_arg, ret_arr_len):
316318
fn_ty_arg = "J"
317319
fn_arg = ma.group(2).strip()
318320
rust_obj = ma.group(1).strip()
321+
if rust_obj in trait_structs:
322+
contains_trait = True
323+
elif rust_obj in complex_enums:
324+
contains_trait = complex_enums[rust_obj]
319325
take_by_ptr = True
320326

321327
if fn_arg.startswith(" *") or fn_arg.startswith("*"):
@@ -339,15 +345,16 @@ def java_c_types(fn_arg, ret_arr_len):
339345
if var_is_arr.group(1) == "":
340346
return TypeInfo(rust_obj=rust_obj, java_ty=java_ty, java_hu_ty=java_ty, java_fn_ty_arg="[" + fn_ty_arg, c_ty=c_ty, is_const=is_const,
341347
passed_as_ptr=False, is_ptr=False, nonnull_ptr=nonnull_ptr, var_name="arg",
342-
arr_len=var_is_arr.group(2), arr_access=arr_access, is_native_primitive=False)
348+
arr_len=var_is_arr.group(2), arr_access=arr_access, is_native_primitive=False, contains_trait=contains_trait)
343349
return TypeInfo(rust_obj=rust_obj, java_ty=java_ty, java_hu_ty=java_ty, java_fn_ty_arg="[" + fn_ty_arg, c_ty=c_ty, is_const=is_const,
344350
passed_as_ptr=False, is_ptr=False, nonnull_ptr=nonnull_ptr, var_name=var_is_arr.group(1),
345-
arr_len=var_is_arr.group(2), arr_access=arr_access, is_native_primitive=False)
351+
arr_len=var_is_arr.group(2), arr_access=arr_access, is_native_primitive=False, contains_trait=contains_trait)
346352

347353
if java_hu_ty is None:
348354
java_hu_ty = java_ty
349355
return TypeInfo(rust_obj=rust_obj, java_ty=java_ty, java_hu_ty=java_hu_ty, java_fn_ty_arg=fn_ty_arg, c_ty=c_ty, passed_as_ptr=is_ptr or take_by_ptr,
350-
is_const=is_const, is_ptr=is_ptr, nonnull_ptr=nonnull_ptr, var_name=fn_arg, arr_len=arr_len, arr_access=arr_access, is_native_primitive=is_primitive)
356+
is_const=is_const, is_ptr=is_ptr, nonnull_ptr=nonnull_ptr, var_name=fn_arg, arr_len=arr_len, arr_access=arr_access, is_native_primitive=is_primitive,
357+
contains_trait=contains_trait)
351358

352359
fn_ptr_regex = re.compile("^extern const ([A-Za-z_0-9\* ]*) \(\*(.*)\)\((.*)\);$")
353360
fn_ret_arr_regex = re.compile("(.*) \(\*(.*)\((.*)\)\)\[([0-9]*)\];$")
@@ -395,15 +402,22 @@ def map_fn_with_ref_option(line, re_match, ret_arr_len, c_call_string, doc_comme
395402
method_comma_separated_arguments = re_match.group(3)
396403
method_arguments = method_comma_separated_arguments.split(',')
397404

405+
if method_name.startswith("__"):
406+
return
407+
398408
is_free = method_name.endswith("_free")
399409
if method_name.startswith("COption") or method_name.startswith("CResult"):
400410
struct_meth = method_name.rsplit("Z", 1)[0][1:] + "Z"
401411
expected_struct = "LDKC" + struct_meth
402412
struct_meth_name = method_name[len(struct_meth) + 1:].strip("_")
403-
elif method_name.startswith("C2Tuple"):
413+
elif method_name.startswith("C2Tuple") or method_name.startswith("C3Tuple"):
404414
tuple_name = method_name.rsplit("Z", 1)[0][2:] + "Z"
405-
struct_meth = "Two" + tuple_name
406-
expected_struct = "LDKC2" + tuple_name
415+
if method_name.startswith("C2Tuple"):
416+
struct_meth = "Two" + tuple_name
417+
expected_struct = "LDKC2" + tuple_name
418+
else:
419+
struct_meth = "Three" + tuple_name
420+
expected_struct = "LDKC3" + tuple_name
407421
struct_meth_name = method_name[len(tuple_name) + 2:].strip("_")
408422
else:
409423
struct_meth = method_name.split("_")[0]
@@ -416,6 +430,15 @@ def map_fn_with_ref_option(line, re_match, ret_arr_len, c_call_string, doc_comme
416430
else:
417431
return_type_info = type_mapping_generator.map_type(method_return_type.strip() + " ret", True, ret_arr_len, False, force_holds_ref)
418432

433+
if method_name.endswith("_clone") and expected_struct not in unitary_enums:
434+
meth_line = "uint64_t " + expected_struct.replace("LDK", "") + "_clone_ptr(" + expected_struct + " *NONNULL_PTR arg)"
435+
write_c("static inline " + meth_line + " {\n")
436+
write_c("\t" + return_type_info.ret_conv[0].replace("\n", "\n\t"))
437+
write_c(method_name + "(arg)")
438+
write_c(return_type_info.ret_conv[1])
439+
write_c("\n\treturn " + return_type_info.ret_conv_name + ";\n}\n")
440+
map_fn(meth_line + ";\n", re.compile("(uint64_t) ([A-Za-z_0-9]*)\((.*)\)").match(meth_line), None, None, None)
441+
419442
argument_types = []
420443
default_constructor_args = {}
421444
takes_self = False
@@ -532,18 +555,18 @@ def map_unitary_enum(struct_name, field_lines, enum_doc_comment):
532555
elif idx == len(field_lines) - 1:
533556
assert(struct_line == "")
534557
assert struct_name.startswith("LDK")
535-
(c_out, native_file_out, native_out) = consts.native_c_unitary_enum_map(struct_name[3:], [x.strip().strip(",") for x, _ in field_lines[1:-3]], enum_doc_comment)
558+
(c_out, native_file_out, native_out) = consts.native_c_unitary_enum_map(struct_name[3:], [(x.strip().strip(","), y) for x, y in field_lines[1:-3]], enum_doc_comment)
536559
write_c(c_out)
537560
out_java_enum.write(native_file_out)
538561
out_java.write(native_out)
539562

540563
def map_complex_enum(struct_name, union_enum_items, inline_enum_variants, enum_doc_comment):
541564
java_hu_type = struct_name.replace("LDK", "").replace("COption", "Option")
542-
complex_enums.add(struct_name)
543565

544566
enum_variants = []
545567
tag_field_lines = union_enum_items["field_lines"]
546-
for idx, (struct_line, _) in enumerate(tag_field_lines):
568+
contains_trait = False
569+
for idx, (struct_line, variant_docs) in enumerate(tag_field_lines):
547570
if idx == 0:
548571
assert(struct_line == "typedef enum %s_Tag {" % struct_name)
549572
elif idx == len(tag_field_lines) - 3:
@@ -560,19 +583,23 @@ def map_complex_enum(struct_name, union_enum_items, inline_enum_variants, enum_d
560583
for idx, (field, field_docs) in enumerate(enum_var_lines):
561584
if idx != 0 and idx < len(enum_var_lines) - 2 and field.strip() != "":
562585
field_ty = type_mapping_generator.java_c_types(field.strip(' ;'), None)
586+
contains_trait |= field_ty.contains_trait
563587
if field_docs is not None and doc_to_field_nullable(field_docs):
564588
field_conv = type_mapping_generator.map_type_with_info(field_ty, False, None, False, True, True)
565589
else:
566590
field_conv = type_mapping_generator.map_type_with_info(field_ty, False, None, False, True, False)
567591
fields.append((field_conv, field_docs))
568-
enum_variants.append(ComplexEnumVariantInfo(variant_name, fields, False))
592+
enum_variants.append(ComplexEnumVariantInfo(variant_name, variant_docs, fields, False))
569593
elif camel_to_snake(variant_name) in inline_enum_variants:
570594
# TODO: If we ever have a rust enum Variant(Option<Struct>) we need to pipe
571595
# docs through to there, and then potentially mark the field nullable.
572-
fields.append((type_mapping_generator.map_type(inline_enum_variants[camel_to_snake(variant_name)] + " " + camel_to_snake(variant_name), False, None, False, True), None))
573-
enum_variants.append(ComplexEnumVariantInfo(variant_name, fields, True))
596+
mapped = type_mapping_generator.map_type(inline_enum_variants[camel_to_snake(variant_name)] + " " + camel_to_snake(variant_name), False, None, False, True)
597+
contains_trait |= mapped.ty_info.contains_trait
598+
fields.append((mapped, None))
599+
enum_variants.append(ComplexEnumVariantInfo(variant_name, variant_docs, fields, True))
574600
else:
575-
enum_variants.append(ComplexEnumVariantInfo(variant_name, fields, True))
601+
enum_variants.append(ComplexEnumVariantInfo(variant_name, variant_docs, fields, True))
602+
complex_enums[struct_name] = contains_trait
576603

577604
with open(f"{sys.argv[3]}/structs/{java_hu_type}{consts.file_ext}", "w") as out_java_enum:
578605
(out_java_addendum, out_java_enum_addendum, out_c_addendum) = consts.map_complex_enum(struct_name, enum_variants, camel_to_snake, enum_doc_comment)
@@ -658,7 +685,7 @@ def map_result(struct_name, res_ty, err_ty):
658685
out_java_struct.write("\t\tif (ptr != 0) { bindings." + struct_name.replace("LDK","") + "_free(ptr); } super.finalize();\n")
659686
out_java_struct.write("\t}\n\n")
660687
out_java_struct.write("\tstatic " + human_ty + " constr_from_ptr(long ptr) {\n")
661-
out_java_struct.write("\t\tif (bindings." + struct_name + "_result_ok(ptr)) {\n")
688+
out_java_struct.write("\t\tif (bindings." + struct_name.replace("LDK", "") + "_is_ok(ptr)) {\n")
662689
out_java_struct.write("\t\t\treturn new " + human_ty + "_OK(null, ptr);\n")
663690
out_java_struct.write("\t\t} else {\n")
664691
out_java_struct.write("\t\t\treturn new " + human_ty + "_Err(null, ptr);\n")
@@ -673,11 +700,6 @@ def map_result(struct_name, res_ty, err_ty):
673700
if not err_map.is_native_primitive and (err_map.rust_obj.replace("LDK", "") + "_clone" not in clone_fns):
674701
can_clone = False
675702

676-
out_java.write("\tpublic static native boolean " + struct_name + "_result_ok(long arg);\n")
677-
write_c(consts.c_fn_ty_pfx + "jboolean " + consts.c_fn_name_define_pfx(struct_name + "_result_ok", True) + consts.ptr_c_ty + " arg) {\n")
678-
write_c("\treturn ((" + struct_name + "*)arg)->result_ok;\n")
679-
write_c("}\n")
680-
681703
out_java.write("\tpublic static native " + res_map.java_ty + " " + struct_name + "_get_ok(long arg);\n")
682704
write_c(consts.c_fn_ty_pfx + res_map.c_ty + " " + consts.c_fn_name_define_pfx(struct_name + "_get_ok", True) + consts.ptr_c_ty + " arg) {\n")
683705
write_c("\t" + struct_name + " *val = (" + struct_name + "*)(arg & ~1);\n")
@@ -833,7 +855,7 @@ def map_tuple(struct_name, field_lines):
833855
last_struct_block_comment = block_comment.strip("\n")
834856
block_comment = None
835857
else:
836-
block_comment = block_comment + "\n" + struct_line.strip(" /*")
858+
block_comment = block_comment + "\n" + struct_line.strip(" /*").replace("…", "...")
837859
else:
838860
struct_name_match = struct_name_regex.match(struct_line)
839861
if struct_name_match is not None:
@@ -898,33 +920,6 @@ def map_tuple(struct_name, field_lines):
898920
map_tuple(struct_name, field_lines)
899921
elif vec_ty is not None:
900922
ty_info = type_mapping_generator.map_type(vec_ty + " arr_elem", False, None, False, False)
901-
if len(ty_info.java_fn_ty_arg) == 1: # ie we're a primitive of some form
902-
out_java.write("\tpublic static native long " + struct_name + "_new(" + ty_info.java_ty + "[] elems);\n")
903-
write_c(consts.c_fn_ty_pfx + consts.ptr_c_ty + " " + consts.c_fn_name_define_pfx(struct_name + "_new", True) + ty_info.c_ty + "Array elems) {\n")
904-
write_c("\t" + struct_name + " *ret = MALLOC(sizeof(" + struct_name + "), \"" + struct_name + "\");\n")
905-
write_c("\tret->datalen = " + consts.get_native_arr_len_call[0] + "elems" + consts.get_native_arr_len_call[1] + ";\n")
906-
write_c("\tif (ret->datalen == 0) {\n")
907-
write_c("\t\tret->data = NULL;\n")
908-
write_c("\t} else {\n")
909-
write_c("\t\tret->data = MALLOC(sizeof(" + vec_ty + ") * ret->datalen, \"" + struct_name + " Data\");\n")
910-
native_arr_ptr_call = consts.get_native_arr_ptr_call(ty_info.ty_info)
911-
write_c("\t\t" + ty_info.c_ty + " *java_elems = " + native_arr_ptr_call[0] + "elems" + native_arr_ptr_call[1] + ";\n")
912-
write_c("\t\tfor (size_t i = 0; i < ret->datalen; i++) {\n")
913-
if ty_info.arg_conv is not None:
914-
write_c("\t\t\t" + ty_info.c_ty + " arr_elem = java_elems[i];\n")
915-
write_c("\t\t\t" + ty_info.arg_conv.replace("\n", "\n\t\t\t") + "\n")
916-
write_c("\t\t\tret->data[i] = " + ty_info.arg_conv_name + ";\n")
917-
assert ty_info.arg_conv_cleanup is None
918-
else:
919-
write_c("\t\t\tret->data[i] = java_elems[i];\n")
920-
write_c("\t\t}\n")
921-
cleanup = consts.release_native_arr_ptr_call(ty_info.ty_info, "elems", "java_elems")
922-
if cleanup is not None:
923-
write_c("\t\t" + cleanup + ";\n")
924-
write_c("\t}\n")
925-
write_c("\treturn (uint64_t)ret;\n")
926-
write_c("}\n")
927-
928923
if ty_info.is_native_primitive:
929924
clone_fns.add(struct_name.replace("LDK", "") + "_clone")
930925
write_c("static inline " + struct_name + " " + struct_name.replace("LDK", "") + "_clone(const " + struct_name + " *orig) {\n")

genbindings.sh

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,15 @@ if [ "$4" = "true" ]; then
7878
else
7979
./genbindings.py "./lightning.h" src/main/java/org/ldk/impl src/main/java/org/ldk src/main/jni/ $DEBUG_ARG java $4
8080
fi
81-
echo "#define LDKCVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ LDKCVec_TransactionOutputsZ" > src/main/jni/bindings.c
81+
rm -f src/main/jni/bindings.c
82+
if [ "$3" = "true" ]; then
83+
echo "#define LDK_DEBUG_BUILD" > src/main/jni/bindings.c
84+
elif [ "$3" = "leaks" ]; then
85+
# For leak checking we use release libldk which doesn't expose
86+
# __unmangle_inner_ptr, but the C code expects to be able to call it.
87+
echo "#define __unmangle_inner_ptr(a) (a)" > src/main/jni/bindings.c
88+
fi
89+
echo "#define LDKCVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ LDKCVec_TransactionOutputsZ" >> src/main/jni/bindings.c
8290
echo "#define CVec_C2Tuple_TxidCVec_C2Tuple_u32TxOutZZZZ_free CVec_TransactionOutputsZ_free" >> src/main/jni/bindings.c
8391
cat src/main/jni/bindings.c.body >> src/main/jni/bindings.c
8492
javac -h src/main/jni src/main/java/org/ldk/enums/*.java src/main/java/org/ldk/impl/*.java

0 commit comments

Comments
 (0)