Skip to content

Commit db1a110

Browse files
authored
Merge pull request #33 from TheBlueMatt/main
Expose supertrait implemetations to the Java API
2 parents 002b08e + ba1af51 commit db1a110

File tree

285 files changed

+8453
-685
lines changed

Some content is hidden

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

285 files changed

+8453
-685
lines changed

.github/workflows/build.yml

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ jobs:
1010
container: debian:bullseye
1111
env:
1212
TOOLCHAIN: stable
13+
strategy:
14+
fail-fast: false
1315
steps:
1416
- name: Install native Rust toolchain, Valgrind, and build utilitis
1517
run: |
@@ -32,6 +34,8 @@ jobs:
3234
git checkout origin/2021-03-java-bindings-base
3335
cd ..
3436
git clone https://github.com/lightningdevkit/ldk-c-bindings
37+
cd ldk-c-bindings
38+
git checkout 0.0.99
3539
- name: Rebuild C bindings without STD for WASM
3640
run: |
3741
cd ldk-c-bindings
@@ -80,13 +84,6 @@ jobs:
8084
./genbindings.sh ./ldk-c-bindings/ "-I/usr/lib/jvm/java-11-openjdk-amd64/include/ -I/usr/lib/jvm/java-11-openjdk-amd64/include/linux/" false false
8185
- name: Build deterministic release jar
8286
run: ./build-release-jar.sh
83-
- name: Run Java Tests against built release jar
84-
run: |
85-
mvn install:install-file -Dfile=ldk-java.jar -DgroupId=org.ldk -DartifactId=ldk-java -Dversion=1.0-SNAPSHOT -Dpackaging=jar
86-
cd javatester
87-
mvn package
88-
java -ea -jar target/ldk-java-tests-1.0-SNAPSHOT-jar-with-dependencies.jar
89-
cd ..
9087
- name: Check latest headers are in git
9188
run: |
9289
git diff --exit-code
@@ -100,14 +97,31 @@ jobs:
10097
cp ldk-java.jar "ldk-java-bins/${LDK_GARBAGECOLLECTED_GIT_OVERRIDE}/"
10198
cp ldk-java-classes.jar "ldk-java-bins/${LDK_GARBAGECOLLECTED_GIT_OVERRIDE}/"
10299
cd ldk-java-bins
103-
git diff --exit-code
100+
if ! git diff --exit-code; then
101+
mv "${LDK_GARBAGECOLLECTED_GIT_OVERRIDE}/"* ./
102+
git checkout "${LDK_GARBAGECOLLECTED_GIT_OVERRIDE}/"
103+
apt-get -y install diffoscope
104+
diffoscope ldk-java-sources.jar "${LDK_GARBAGECOLLECTED_GIT_OVERRIDE}/ldk-java-sources.jar"
105+
diffoscope ldk-java-classes.jar "${LDK_GARBAGECOLLECTED_GIT_OVERRIDE}/ldk-java-classes.jar"
106+
diffoscope ldk-java.jar "${LDK_GARBAGECOLLECTED_GIT_OVERRIDE}/ldk-java.jar"
107+
exit 1
108+
fi
109+
- name: Run Java Tests against built release jar
110+
run: |
111+
mvn install:install-file -Dfile=ldk-java.jar -DgroupId=org.ldk -DartifactId=ldk-java -Dversion=1.0-SNAPSHOT -Dpackaging=jar
112+
cd javatester
113+
mvn package
114+
java -ea -jar target/ldk-java-tests-1.0-SNAPSHOT-jar-with-dependencies.jar
115+
cd ..
104116
105117
android:
106118
runs-on: ubuntu-latest
107119
# Frankly, I'm not really sure why debian and ubuntu differ in the results here, they really shouldn't
108120
container: debian:bullseye
109121
env:
110122
TOOLCHAIN: stable
123+
strategy:
124+
fail-fast: false
111125
steps:
112126
- name: Install rust targets
113127
run: |
@@ -148,6 +162,8 @@ jobs:
148162
git checkout origin/2021-03-java-bindings-base
149163
cd ..
150164
git clone https://github.com/lightningdevkit/ldk-c-bindings
165+
cd ldk-c-bindings
166+
git checkout 0.0.99
151167
- name: Detect current git version
152168
run: |
153169
# We assume the top commit is just a bindings update commit, so we
@@ -179,14 +195,21 @@ jobs:
179195
rm "ldk-java-bins/${LDK_GARBAGECOLLECTED_GIT_OVERRIDE}/LDK-release.aar"
180196
cp LDK-release.aar "ldk-java-bins/${LDK_GARBAGECOLLECTED_GIT_OVERRIDE}/"
181197
cd ldk-java-bins
182-
git diff --exit-code
198+
if ! git diff --exit-code; then
199+
mv "${LDK_GARBAGECOLLECTED_GIT_OVERRIDE}/LDK-release.aar" ./
200+
git checkout "${LDK_GARBAGECOLLECTED_GIT_OVERRIDE}/LDK-release.aar"
201+
apt-get -y install diffoscope
202+
diffoscope LDK-release.aar "${LDK_GARBAGECOLLECTED_GIT_OVERRIDE}/LDK-release.aar"
203+
exit 1
204+
fi
183205
184206
osx:
185207
strategy:
186208
matrix:
187209
include:
188210
- platform: macos-10.15
189211
- platform: macos-11
212+
fail-fast: false
190213
runs-on: ${{ matrix.platform }}
191214
env:
192215
TOOLCHAIN: stable
@@ -213,13 +236,14 @@ jobs:
213236
run: |
214237
git config --global user.email "ldk-ci@example.com"
215238
git config --global user.name "LDK CI"
216-
git clone https://github.com/rust-bitcoin/rust-lightning
239+
# Note this is a different endpoint, as we need one non-upstream commit!
240+
git clone https://git.bitcoin.ninja/rust-lightning
217241
cd rust-lightning
218-
git remote add matt https://git.bitcoin.ninja/rust-lightning
219-
git fetch matt
220-
git merge matt/2021-03-java-bindings-base
242+
git checkout origin/2021-03-java-bindings-base
221243
cd ..
222244
git clone https://github.com/lightningdevkit/ldk-c-bindings
245+
cd ldk-c-bindings
246+
git checkout 0.0.99
223247
- name: Rebuild C bindings with upstream clang, and check the sample app builds + links
224248
run: |
225249
cd ldk-c-bindings

bindingstypes.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ def __init__(self, ty_info, arg_name, arg_conv, arg_conv_name, arg_conv_cleanup,
6565
self.to_hu_conv = to_hu_conv
6666
self.to_hu_conv_name = to_hu_conv_name
6767
self.from_hu_conv = from_hu_conv
68+
# This is set based on docstrings in various contexts:
69+
self.nullable = False
6870

6971
class TraitMethInfo:
7072
def __init__(self, fn_name, self_is_const, ret_ty_info, args_ty, docs):

gen_type_mapping.py

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -87,38 +87,45 @@ def map_type_with_info(self, ty_info, print_void, ret_arr_len, is_free, holds_re
8787
ty_info.subty.requires_clone = False
8888
subty = self.map_type_with_info(ty_info.subty, False, None, is_free, holds_ref)
8989
arg_conv = ty_info.rust_obj + " " + arr_name + "_constr;\n"
90-
arg_conv = arg_conv + arr_name + "_constr." + arr_len + " = " + self.consts.get_native_arr_len_call[0] + arr_name + self.consts.get_native_arr_len_call[1] + ";\n"
91-
arg_conv = arg_conv + "if (" + arr_name + "_constr." + arr_len + " > 0)\n"
90+
pf = ""
91+
if ty_info.is_ptr:
92+
pf = "\t"
93+
arg_conv += ty_info.rust_obj + " *" + arr_name + "_ptr = NULL;\n"
94+
arg_conv += "if (" + self.consts.is_arr_some_check[0] + arr_name + self.consts.is_arr_some_check[1] + ") {\n"
95+
arg_conv += pf + arr_name + "_constr." + arr_len + " = " + self.consts.get_native_arr_len_call[0] + arr_name + self.consts.get_native_arr_len_call[1] + ";\n"
96+
arg_conv += pf + "if (" + arr_name + "_constr." + arr_len + " > 0)\n"
9297
if subty.is_native_primitive:
9398
szof = subty.c_ty
9499
else:
95100
szof = subty.rust_obj
96-
arg_conv = arg_conv + "\t" + arr_name + "_constr." + ty_info.arr_access + " = MALLOC(" + arr_name + "_constr." + arr_len + " * sizeof(" + szof + "), \"" + ty_info.rust_obj + " Elements\");\n"
97-
arg_conv = arg_conv + "else\n"
98-
arg_conv = arg_conv + "\t" + arr_name + "_constr." + ty_info.arr_access + " = NULL;\n"
101+
arg_conv += pf + "\t" + arr_name + "_constr." + ty_info.arr_access + " = MALLOC(" + arr_name + "_constr." + arr_len + " * sizeof(" + szof + "), \"" + ty_info.rust_obj + " Elements\");\n"
102+
arg_conv += pf + "else\n"
103+
arg_conv += pf + "\t" + arr_name + "_constr." + ty_info.arr_access + " = NULL;\n"
99104
get_arr = self.consts.get_native_arr_contents(arr_name, "NO_DEST", arr_name + "_constr." + arr_len, ty_info, False)
100105
if get_arr != None:
101-
arg_conv = arg_conv + subty.c_ty + "* " + arr_name + "_vals = " + get_arr + ";\n"
102-
arg_conv = arg_conv + "for (size_t " + idxc + " = 0; " + idxc + " < " + arr_name + "_constr." + arr_len + "; " + idxc + "++) {\n"
106+
arg_conv += pf + subty.c_ty + "* " + arr_name + "_vals = " + get_arr + ";\n"
107+
arg_conv += pf + "for (size_t " + idxc + " = 0; " + idxc + " < " + arr_name + "_constr." + arr_len + "; " + idxc + "++) {\n"
103108
if get_arr != None:
104-
arg_conv = arg_conv + "\t" + subty.c_ty + " " + conv_name + " = " + arr_name + "_vals[" + idxc + "];"
109+
arg_conv += pf + "\t" + subty.c_ty + " " + conv_name + " = " + arr_name + "_vals[" + idxc + "];"
105110
if subty.arg_conv is not None:
106-
arg_conv = arg_conv + "\n\t" + subty.arg_conv.replace("\n", "\n\t")
111+
arg_conv += "\n\t" + pf + subty.arg_conv.replace("\n", "\n\t" + pf)
107112
else:
108-
arg_conv = arg_conv + "\t" + subty.c_ty + " " + conv_name + " = " + self.consts.get_native_arr_elem(arr_name, idxc, ty_info) + ";\n"
109-
arg_conv = arg_conv + "\t" + subty.arg_conv.replace("\n", "\n\t")
110-
arg_conv = arg_conv + "\n\t" + arr_name + "_constr." + ty_info.arr_access + "[" + idxc + "] = " + subty.arg_conv_name + ";\n}"
113+
arg_conv += pf + "\t" + subty.c_ty + " " + conv_name + " = " + self.consts.get_native_arr_elem(arr_name, idxc, ty_info) + ";\n"
114+
arg_conv += pf + "\t" + subty.arg_conv.replace("\n", "\n\t" + pf)
115+
arg_conv += "\n\t" + pf + arr_name + "_constr." + ty_info.arr_access + "[" + idxc + "] = " + subty.arg_conv_name + ";\n" + pf + "}"
111116
if get_arr != None:
112117
cleanup = self.consts.cleanup_native_arr_ref_contents(arr_name, arr_name + "_vals", arr_name + "_constr." + arr_len, ty_info)
113118
if cleanup is not None:
114-
arg_conv = arg_conv + "\n" + cleanup + ";"
119+
arg_conv += "\n" + pf + cleanup + ";"
115120
if ty_info.is_ptr:
116-
arg_conv_name = "&" + arr_name + "_constr"
121+
arg_conv_name = arr_name + "_ptr"
117122
else:
118123
arg_conv_name = arr_name + "_constr"
119124
arg_conv_cleanup = None
120125
if ty_info.is_ptr:
121-
arg_conv_cleanup = "FREE(" + arr_name + "_constr." + ty_info.arr_access + ");"
126+
arg_conv_cleanup = "if (" + arr_name + "_ptr != NULL) { FREE(" + arr_name + "_constr." + ty_info.arr_access + "); }"
127+
if ty_info.is_ptr:
128+
arg_conv += "\n\t" + arr_name + "_ptr = &" + arr_name + "_constr;\n}"
122129

123130
ret_conv = (ty_info.rust_obj + " " + arr_name + "_var = ", "")
124131
if subty.ret_conv is None:
@@ -159,11 +166,11 @@ def map_type_with_info(self, ty_info, print_void, ret_arr_len, is_free, holds_re
159166
from_hu_conv = None
160167
if subty.from_hu_conv is not None:
161168
if subty.java_ty == "long" and subty.java_hu_ty != "long":
162-
from_hu_conv = ("Arrays.stream(" + arr_name + ").mapToLong(" + conv_name + " -> " + subty.from_hu_conv[0] + ").toArray()", "/* TODO 2 " + subty.java_hu_ty + " */")
169+
from_hu_conv = (arr_name + " != null ? Arrays.stream(" + arr_name + ").mapToLong(" + conv_name + " -> " + subty.from_hu_conv[0] + ").toArray() : null", "/* TODO 2 " + subty.java_hu_ty + " */")
163170
elif subty.java_ty == "long":
164-
from_hu_conv = ("Arrays.stream(" + arr_name + ").map(" + conv_name + " -> " + subty.from_hu_conv[0] + ").toArray()", "/* TODO 2 " + subty.java_hu_ty + " */")
171+
from_hu_conv = (arr_name + " != null ? Arrays.stream(" + arr_name + ").map(" + conv_name + " -> " + subty.from_hu_conv[0] + ").toArray() : null", "/* TODO 2 " + subty.java_hu_ty + " */")
165172
else:
166-
from_hu_conv = ("Arrays.stream(" + arr_name + ").map(" + conv_name + " -> " + subty.from_hu_conv[0] + ").toArray(" + ty_info.java_ty + "::new)", "/* TODO 2 " + subty.java_hu_ty + " */")
173+
from_hu_conv = (arr_name + " != null ? Arrays.stream(" + arr_name + ").map(" + conv_name + " -> " + subty.from_hu_conv[0] + ").toArray(" + ty_info.java_ty + "::new) : null", "/* TODO 2 " + subty.java_hu_ty + " */")
167174

168175
return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
169176
arg_conv = arg_conv, arg_conv_name = arg_conv_name, arg_conv_cleanup = arg_conv_cleanup,
@@ -183,10 +190,13 @@ def map_type_with_info(self, ty_info, print_void, ret_arr_len, is_free, holds_re
183190
ret_conv_name = ty_info.var_name + "_conv",
184191
to_hu_conv = None, to_hu_conv_name = None, from_hu_conv = None)
185192
else:
193+
free_str = ""
194+
if not holds_ref:
195+
free_str = "\nStr_free(" + ty_info.var_name + "_str);"
186196
return ConvInfo(ty_info = ty_info, arg_name = ty_info.var_name,
187197
arg_conv = arg_conv, arg_conv_name = arg_conv_name, arg_conv_cleanup = None,
188198
ret_conv = ("LDKStr " + ty_info.var_name + "_str = ",
189-
";\njstring " + ty_info.var_name + "_conv = " + self.consts.str_ref_to_native_call(ty_info.var_name + "_str." + ty_info.arr_access, ty_info.var_name + "_str." + ty_info.arr_len) + ";"),
199+
";\njstring " + ty_info.var_name + "_conv = " + self.consts.str_ref_to_native_call(ty_info.var_name + "_str." + ty_info.arr_access, ty_info.var_name + "_str." + ty_info.arr_len) + ";" + free_str),
190200
ret_conv_name = ty_info.var_name + "_conv", to_hu_conv = None, to_hu_conv_name = None, from_hu_conv = None)
191201
elif ty_info.var_name == "" and not print_void:
192202
# We don't have a parameter name, and want one, just call it arg
@@ -402,7 +412,7 @@ def map_type_with_info(self, ty_info, print_void, ret_arr_len, is_free, holds_re
402412
arg_conv = "", arg_conv_name = "(LDKu5){ ._0 = " + ty_info.var_name + " }", arg_conv_cleanup = None,
403413
ret_conv = ("uint8_t " + ty_info.var_name + "_val = ", "._0;"), ret_conv_name = ty_info.var_name + "_val",
404414
to_hu_conv = ty_info.java_hu_ty + " " + ty_info.var_name + "_conv = new " + ty_info.java_hu_ty + "(" + ty_info.var_name + ");",
405-
to_hu_conv_name = ty_info.var_name + "_conv", from_hu_conv = (ty_info.var_name + ".ptr", ""))
415+
to_hu_conv_name = ty_info.var_name + "_conv", from_hu_conv = (ty_info.var_name + ".getVal()", ""))
406416

407417
assert ty_info.rust_obj == "LDKTxOut"
408418
if not ty_info.is_ptr and not holds_ref:

0 commit comments

Comments
 (0)