Skip to content

Expose ChannelManager/Monitor read methods in bindings - #768

Merged
TheBlueMatt merged 13 commits into
lightningdevkit:mainfrom
TheBlueMatt:2020-12-chanman-bindings-deser
Feb 3, 2021
Merged

Expose ChannelManager/Monitor read methods in bindings#768
TheBlueMatt merged 13 commits into
lightningdevkit:mainfrom
TheBlueMatt:2020-12-chanman-bindings-deser

Conversation

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Based on #767 (and #761), this finally exposes ChannelManager read methods that were missed in the early bindings work. There's also a few nice cleanups of the C++ wrappers, though they are code-wise trivial. As with #767, between each bindings builder update the changes to the bindings are committed, though those commits may be squashed before merge.

@codecov

codecovBot commented Dec 31, 2020

Copy link
Copy Markdown

Codecov Report

Merging #768 (a4f5bf3) into main (c7ddcd3) will decrease coverage by 0.00%.
The diff coverage is n/a.

Impacted file tree graph

@@ Coverage Diff @@## main #768 +/- ##
==========================================
- Coverage 90.79% 90.78% -0.01% 
==========================================
Files 38 38 Lines 23168 23168 ==========================================
- Hits 21036 21034 -2 - Misses 2132 2134 +2 
Impacted FilesCoverage Δ
lightning/src/ln/chan_utils.rs97.33% <ø> (ø)
lightning/src/routing/router.rs95.57% <ø> (ø)
lightning/src/ln/functional_tests.rs96.96% <0.00%> (-0.04%)⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c7ddcd3...5d045de. Read the comment docs.

@TheBlueMatt
TheBlueMattforce-pushed the 2020-12-chanman-bindings-deser branch from 748542d to c326bcbCompareJanuary 1, 2021 01:46

@jkczyzjkczyz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm getting some compilation warnings and errors likely related to c++11 not being specified somewhere:

++ which valgrind
+ '[' -x '' ']'
+ echo 'WARNING: Please install valgrind for more testing'
WARNING: Please install valgrind for more testing
+ CLANGOPTS='-Wall -Wno-nullability-completeness -pthread'
+ clang++ -Wall -Wno-nullability-completeness -pthread demo.cpp target/debug/libldk.a -ldl
In file included from demo.cpp:5:
./include/lightningpp.hpp:7:24: warning: deleted function definitions are a C++11 extension [-Wc++11-extensions]
Event(const Event&) = delete;
^
./include/lightningpp.hpp:8:13: warning: rvalue references are a C++11 extension [-Wc++11-extensions]
Event(Event&& o) : self(o.self) { memset(&o, 0, sizeof(Event)); }
^
./include/lightningpp.hpp:9:16: warning: rvalue references are a C++11 extension [-Wc++11-extensions]
Event(LDKEvent&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKEvent)); }
^
./include/lightningpp.hpp:10:22: warning: reference qualifiers on functions are a C++11 extension [-Wc++11-extensions]
operator LDKEvent() && { LDKEvent res = self; memset(&self, 0, sizeof(LDKEvent)); return res; }
^
./include/lightningpp.hpp:12:24: warning: rvalue references are a C++11 extension [-Wc++11-extensions]
Event& operator=(Event&& o) { Event_free(self); self = o.self; memset(&o, 0, sizeof(Event)); return *this; }
^

...

demo.cpp:119:23: error: default initialization of an object of const type 'const LDKFeeEstimator' without a user-provided default constructor
const LDKFeeEstimator fee_est {
^
= {}
demo.cpp:119:30: error: expected ';' after top level declarator
const LDKFeeEstimator fee_est {
^
;
demo.cpp:134:58: error: a space is required between consecutive right angle brackets (use '> >')
std::vector<std::pair<LDK::OutPoint, LDK::ChannelMonitor>> mons;
^~
> >
demo.cpp:139:8: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
for (auto& mon : mons) {
^
demo.cpp:139:18: warning: range-based for loop is a C++11 extension [-Wc++11-extensions]
for (auto& mon : mons) {
^
demo.cpp:147:22: error: no matching constructor for initialization of 'LDK::ChannelMonitor'
LDK::ChannelMonitor mon(std::move(monitor_arg));
^ ~~~~~~~~~~~~~~~~~~~~~~
./include/lightningpp.hpp:304:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitor' to 'const LDK::ChannelMonitor' for 1st argument
ChannelMonitor(const ChannelMonitor&) = delete;
^
./include/lightningpp.hpp:305:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitor' to 'LDK::ChannelMonitor' for 1st argument
ChannelMonitor(ChannelMonitor&& o) : self(o.self) { memset(&o, 0, sizeof(ChannelMonitor)); }
^
./include/lightningpp.hpp:306:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitor' to 'LDKChannelMonitor &&' for 1st argument
ChannelMonitor(LDKChannelMonitor&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKChannelMonitor)); }
^
demo.cpp:148:16: error: no matching constructor for initialization of 'LDK::OutPoint'
LDK::OutPoint funding_txo(std::move(funding_txo_arg));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~
./include/lightningpp.hpp:334:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'const LDK::OutPoint' for 1st argument
OutPoint(const OutPoint&) = delete;
^
./include/lightningpp.hpp:335:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'LDK::OutPoint' for 1st argument
OutPoint(OutPoint&& o) : self(o.self) { memset(&o, 0, sizeof(OutPoint)); }
^
./include/lightningpp.hpp:336:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'LDKOutPoint &&' for 1st argument
OutPoint(LDKOutPoint&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKOutPoint)); }
^
demo.cpp:159:28: error: no matching constructor for initialization of 'LDK::ChannelMonitorUpdate'
LDK::ChannelMonitorUpdate update(std::move(monitor_arg));
^ ~~~~~~~~~~~~~~~~~~~~~~
./include/lightningpp.hpp:230:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitorUpdate' to 'const LDK::ChannelMonitorUpdate' for 1st argument
ChannelMonitorUpdate(const ChannelMonitorUpdate&) = delete;
^
./include/lightningpp.hpp:231:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitorUpdate' to 'LDK::ChannelMonitorUpdate' for 1st argument
ChannelMonitorUpdate(ChannelMonitorUpdate&& o) : self(o.self) { memset(&o, 0, sizeof(ChannelMonitorUpdate)); }
^
./include/lightningpp.hpp:232:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitorUpdate' to 'LDKChannelMonitorUpdate &&' for 1st argument
ChannelMonitorUpdate(LDKChannelMonitorUpdate&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKChannelMonitorUpdate)); }
^
demo.cpp:160:16: error: no matching constructor for initialization of 'LDK::OutPoint'
LDK::OutPoint funding_txo(std::move(funding_txo_arg));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~
./include/lightningpp.hpp:334:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'const LDK::OutPoint' for 1st argument
OutPoint(const OutPoint&) = delete;
^
./include/lightningpp.hpp:335:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'LDK::OutPoint' for 1st argument
OutPoint(OutPoint&& o) : self(o.self) { memset(&o, 0, sizeof(OutPoint)); }
^
./include/lightningpp.hpp:336:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'LDKOutPoint &&' for 1st argument
OutPoint(LDKOutPoint&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKOutPoint)); }
^
demo.cpp:166:7: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
for (auto& mon : arg->mons) {
^
demo.cpp:166:17: warning: range-based for loop is a C++11 extension [-Wc++11-extensions]
for (auto& mon : arg->mons) {
^
demo.cpp:187:32: error: expected '(' for function-style cast or type construction
return LDKCVec_MonitorEventZ {
~~~~~~~~~~~~~~~~~~~~~ ^
demo.cpp:239:31: error: expected '(' for function-style cast or type construction
sock1 = LDKSocketDescriptor {
~~~~~~~~~~~~~~~~~~~ ^
demo.cpp:249:31: error: expected '(' for function-style cast or type construction
sock2 = LDKSocketDescriptor {
~~~~~~~~~~~~~~~~~~~ ^
demo.cpp:259:8: error: no matching constructor for initialization of 'std::thread'
t1 = std::thread(&sock_read_data_thread, pipefds_2_to_1[0], &sock1, &net1);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:408:9: note: candidate constructor template not viable: requires single argument '__f', but 4 arguments were provided
thread::thread(_Fp __f)
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:289:5: note: candidate constructor not viable: requires 1 argument, but 4 were provided
thread(const thread&);
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:296:5: note: candidate constructor not viable: requires 0 arguments, but 4 were provided
thread() _NOEXCEPT : __t_(_LIBCPP_NULL_THREAD) {}
^
demo.cpp:260:8: error: no matching constructor for initialization of 'std::thread'
t2 = std::thread(&sock_read_data_thread, pipefds_1_to_2[0], &sock2, &net2);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:408:9: note: candidate constructor template not viable: requires single argument '__f', but 4 arguments were provided
thread::thread(_Fp __f)
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:289:5: note: candidate constructor not viable: requires 1 argument, but 4 were provided
thread(const thread&);
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:296:5: note: candidate constructor not viable: requires 0 arguments, but 4 were provided
thread() _NOEXCEPT : __t_(_LIBCPP_NULL_THREAD) {}
^
demo.cpp:268:3: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
auto writelen = write(pipefds_1_to_2[1], con_res->contents.result->data, con_res->contents.result->datalen);
^
demo.cpp:299:35: error: expected ';' at end of declaration
LDKBroadcasterInterface broadcast {
^
;
demo.cpp:306:19: error: expected ';' at end of declaration
LDKLogger logger1 {
^
;
demo.cpp:314:15: error: expected ';' at end of declaration
LDKWatch mon1 {
^
;
demo.cpp:325:19: error: expected ';' at end of declaration
LDKLogger logger2 {
^
;
demo.cpp:333:15: error: expected ';' at end of declaration
LDKWatch mon2 {
^
;
demo.cpp:344:38: error: expected '(' for function-style cast or type construction
LDK::CVec_u8Z cm1_ser = LDKCVec_u8Z {}; // ChannelManager 1 serialization at the end of the ser-des scope
~~~~~~~~~~~ ^
demo.cpp:345:38: error: expected '(' for function-style cast or type construction
LDK::CVec_u8Z cm2_ser = LDKCVec_u8Z {}; // ChannelManager 2 serialization at the end of the ser-des scope
~~~~~~~~~~~ ^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
900 warnings and 20 errors generated.

}
pub extern "C" fn ChannelMonitorUpdate_read(ser: crate::c_types::u8slice) -> crate::c_types::derived::CResult_ChannelMonitorUpdateDecodeErrorZ {
let res = crate::c_types::deserialize_obj(ser);
let mut local_res = match res { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::chain::channelmonitor::ChannelMonitorUpdate { inner: Box::into_raw(Box::new(o)), is_owned: true } }), Err(mut e) => crate::c_types::CResultTempl::err( { crate::ln::msgs::DecodeError { inner: Box::into_raw(Box::new(e)), is_owned: true } }) };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was having no line breaks here intentional?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a number of similar cases across the bindings, especially for template types (vec/result/tuples) - specifically we don't track at what level of indentation we are at that deep into type conversion, so we either have bogus indentation or no indentation. For now its none, but its something we should fix eventually.

Comment threadc-bindings-gen/src/main.rs Outdated
Comment threadc-bindings-gen/src/main.rs
Comment threadgenbindings.sh Outdated
echo "WARNING: Please install valgrind for more testing"
fi

CLANGOPTS="-Wall -Wno-nullability-completeness -pthread"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm seeing a ton of warnings looking to originate from this commit:

++ rustc --version --verbose
++ grep host:
+ HOST_PLATFORM='host: x86_64-apple-darwin'
+ '[' 'host: x86_64-apple-darwin' = 'host: x86_64-apple-darwin' ']'
+ sed -i '' 's/typedef LDKnative.*Import.*LDKnative.*;//g' include/lightning.h
+ gcc -Wall -g -pthread demo.c target/debug/libldk.a -ldl
In file included from demo.c:2:
./include/lightning.h:204:12: warning: pointer is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified) [-Wnullability-completeness]
uint8_t *data;
^
./include/lightning.h:204:12: note: insert '_Nullable' if the pointer may be null
uint8_t *data;
^
_Nullable ./include/lightning.h:204:12: note: insert '_Nonnull' if the pointer should never be null
uint8_t *data;
^
_Nonnull 

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heh, that's an OSX-ism, because gcc is just a symlink to clang...I'll add the warning disable on all the compile calls.

@TheBlueMatt
TheBlueMattforce-pushed the 2020-12-chanman-bindings-deser branch from c326bcb to d08bdf4CompareFebruary 3, 2021 00:55
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Addressed review comments, rebased to fix conflicts but no changes outside of bindings generation code.

We can fail to resolve a part of a tuple, resulting in a panic in
write_template_constructor even if we're calling
`understood_c_type` with the intent of figuring out whether we can
print a type at all. Instead, we should pipe errors back and let
`understood_c_type` return false as a result.
Previously, manual `*_read` implementations were only defined for
types with inner fields, which were set to NULL to indicate read
errors. This prevents exposing `*_read` for several other types,
including tuples (which are needed for `ChannelManager`/
`ChannelMonitors`) and enums (which includes `Event`s, though users
likely never need to call that directly). Further, this means we
don't expose the actual error enum (which is likely no big deal,
but is still nice).
Here, we instead create the `Result<Object, DecodeError>` type and
then pass it through the normal type conversion functions, giving
us access to any types which we can convert normally.
This expands the manual implementation logic for `*_write` and
`*_read` methods to most types, converting the `*_write` path to
the common type-conversion logic to ensure it works.
Note that `*_write_void` is still only implemented for has-inner
types, as its unclear what the `void*` would point to for others.
It just stubs out to `write_rust_path` in this case anyway, which
handles leading-colons just fine, so no need to panic on them.
This is most of the code to expose `ChannelManager`/`ChannelMonitor`
deserialization in our C bindings, using the new infrastructure to
map types in `maybe_convert_trait_impl` and passing generics in
from the callsites.
We also call `maybe_convert_trait_impl` for tuple types, as the
`ChannelManager`/`ChannelMonitor` deserialization returns a
`(BlockHash, T)` to indicate the block hash at which users need to
start resyncing the chain.
The final step to expose them is in the next commit.
This (finally) exposes `ChannelManager`/`ChannelMonitor` _write
methods, which were (needlessly) excluded as the structs themselves
have generic parameters. Sadly, we also now need to parse
`(C-not exported)` doc comments on impl blocks as we otherwise try
to expose _write methods for `&Vec<RouteHop>`, which doesn't work
(and isn't particularly interesting for users anyway). We add such
doc comments there.
This adds a new annotation for objects we take by reference in the
C header indicating the pointers must not be null. We have to
disable some warning clang now dumps that we haven't annotated all
pointers, as cbindgen is not yet able to add a nullable annotation.
Previously, references and pointers ended up identical in C, so
there was little reason to differentiate. With the addition of
nullability annotations, there is a (very slight) reason to prefer
references, so use them in a few places where its a trivial change.
This adds a move-assignment operator (`A& operator=(A&& o)`) to our
C++ wrapper classes as well as requiring an rvalue for the move
auto-convert operator (`operator CStruct()() &&`).
The second makes the C++ wrapper classes much easier to work with
by requiring an explicit `std::move` when the bindings will
automatically move a C++-wrapper object into a C object.
This demonstrates (and tests) the newly-exposed `ChannelManager`
de/serialization functions. Best revewied with -b --color-moved.
There were two issues on OSX - we need to give gcc the clang
warnings flags because `gcc` *is* clang on OSX and we missed an
`-std=c++11` on one of the clang++ calls, causing compile failures.
@TheBlueMatt
TheBlueMattforce-pushed the 2020-12-chanman-bindings-deser branch from d08bdf4 to 5d045deCompareFebruary 3, 2021 15:12
@TheBlueMatt

TheBlueMatt commented Feb 3, 2021

Copy link
Copy Markdown
CollaboratorAuthor

Rebased with no changes (git diff-tree d08bdf44 5d045de8 is empty) - only dropped intermediate binidings updates and rebased on upstream (including 767 merge).

@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Its just bindings, worth merging without more than one ack.

@TheBlueMatt
TheBlueMatt merged commit e4b516d into lightningdevkit:mainFeb 3, 2021
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@TheBlueMatt@jkczyz
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Expose ChannelManager/Monitor read methods in bindings by TheBlueMatt · Pull Request #768 · lightningdevkit/rust-lightning · GitHub
Skip to content

Expose ChannelManager/Monitor read methods in bindings - #768

Merged
TheBlueMatt merged 13 commits into
lightningdevkit:mainfrom
TheBlueMatt:2020-12-chanman-bindings-deser
Feb 3, 2021
Merged

Expose ChannelManager/Monitor read methods in bindings#768
TheBlueMatt merged 13 commits into
lightningdevkit:mainfrom
TheBlueMatt:2020-12-chanman-bindings-deser

Conversation

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Based on #767 (and #761), this finally exposes ChannelManager read methods that were missed in the early bindings work. There's also a few nice cleanups of the C++ wrappers, though they are code-wise trivial. As with #767, between each bindings builder update the changes to the bindings are committed, though those commits may be squashed before merge.

@codecov

codecovBot commented Dec 31, 2020

Copy link
Copy Markdown

Codecov Report

Merging #768 (a4f5bf3) into main (c7ddcd3) will decrease coverage by 0.00%.
The diff coverage is n/a.

Impacted file tree graph

@@ Coverage Diff @@## main #768 +/- ##
==========================================
- Coverage 90.79% 90.78% -0.01% 
==========================================
Files 38 38 Lines 23168 23168 ==========================================
- Hits 21036 21034 -2 - Misses 2132 2134 +2 
Impacted FilesCoverage Δ
lightning/src/ln/chan_utils.rs97.33% <ø> (ø)
lightning/src/routing/router.rs95.57% <ø> (ø)
lightning/src/ln/functional_tests.rs96.96% <0.00%> (-0.04%)⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c7ddcd3...5d045de. Read the comment docs.

@TheBlueMatt
TheBlueMattforce-pushed the 2020-12-chanman-bindings-deser branch from 748542d to c326bcbCompareJanuary 1, 2021 01:46

@jkczyzjkczyz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm getting some compilation warnings and errors likely related to c++11 not being specified somewhere:

++ which valgrind
+ '[' -x '' ']'
+ echo 'WARNING: Please install valgrind for more testing'
WARNING: Please install valgrind for more testing
+ CLANGOPTS='-Wall -Wno-nullability-completeness -pthread'
+ clang++ -Wall -Wno-nullability-completeness -pthread demo.cpp target/debug/libldk.a -ldl
In file included from demo.cpp:5:
./include/lightningpp.hpp:7:24: warning: deleted function definitions are a C++11 extension [-Wc++11-extensions]
Event(const Event&) = delete;
^
./include/lightningpp.hpp:8:13: warning: rvalue references are a C++11 extension [-Wc++11-extensions]
Event(Event&& o) : self(o.self) { memset(&o, 0, sizeof(Event)); }
^
./include/lightningpp.hpp:9:16: warning: rvalue references are a C++11 extension [-Wc++11-extensions]
Event(LDKEvent&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKEvent)); }
^
./include/lightningpp.hpp:10:22: warning: reference qualifiers on functions are a C++11 extension [-Wc++11-extensions]
operator LDKEvent() && { LDKEvent res = self; memset(&self, 0, sizeof(LDKEvent)); return res; }
^
./include/lightningpp.hpp:12:24: warning: rvalue references are a C++11 extension [-Wc++11-extensions]
Event& operator=(Event&& o) { Event_free(self); self = o.self; memset(&o, 0, sizeof(Event)); return *this; }
^

...

demo.cpp:119:23: error: default initialization of an object of const type 'const LDKFeeEstimator' without a user-provided default constructor
const LDKFeeEstimator fee_est {
^
= {}
demo.cpp:119:30: error: expected ';' after top level declarator
const LDKFeeEstimator fee_est {
^
;
demo.cpp:134:58: error: a space is required between consecutive right angle brackets (use '> >')
std::vector<std::pair<LDK::OutPoint, LDK::ChannelMonitor>> mons;
^~
> >
demo.cpp:139:8: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
for (auto& mon : mons) {
^
demo.cpp:139:18: warning: range-based for loop is a C++11 extension [-Wc++11-extensions]
for (auto& mon : mons) {
^
demo.cpp:147:22: error: no matching constructor for initialization of 'LDK::ChannelMonitor'
LDK::ChannelMonitor mon(std::move(monitor_arg));
^ ~~~~~~~~~~~~~~~~~~~~~~
./include/lightningpp.hpp:304:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitor' to 'const LDK::ChannelMonitor' for 1st argument
ChannelMonitor(const ChannelMonitor&) = delete;
^
./include/lightningpp.hpp:305:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitor' to 'LDK::ChannelMonitor' for 1st argument
ChannelMonitor(ChannelMonitor&& o) : self(o.self) { memset(&o, 0, sizeof(ChannelMonitor)); }
^
./include/lightningpp.hpp:306:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitor' to 'LDKChannelMonitor &&' for 1st argument
ChannelMonitor(LDKChannelMonitor&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKChannelMonitor)); }
^
demo.cpp:148:16: error: no matching constructor for initialization of 'LDK::OutPoint'
LDK::OutPoint funding_txo(std::move(funding_txo_arg));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~
./include/lightningpp.hpp:334:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'const LDK::OutPoint' for 1st argument
OutPoint(const OutPoint&) = delete;
^
./include/lightningpp.hpp:335:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'LDK::OutPoint' for 1st argument
OutPoint(OutPoint&& o) : self(o.self) { memset(&o, 0, sizeof(OutPoint)); }
^
./include/lightningpp.hpp:336:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'LDKOutPoint &&' for 1st argument
OutPoint(LDKOutPoint&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKOutPoint)); }
^
demo.cpp:159:28: error: no matching constructor for initialization of 'LDK::ChannelMonitorUpdate'
LDK::ChannelMonitorUpdate update(std::move(monitor_arg));
^ ~~~~~~~~~~~~~~~~~~~~~~
./include/lightningpp.hpp:230:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitorUpdate' to 'const LDK::ChannelMonitorUpdate' for 1st argument
ChannelMonitorUpdate(const ChannelMonitorUpdate&) = delete;
^
./include/lightningpp.hpp:231:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitorUpdate' to 'LDK::ChannelMonitorUpdate' for 1st argument
ChannelMonitorUpdate(ChannelMonitorUpdate&& o) : self(o.self) { memset(&o, 0, sizeof(ChannelMonitorUpdate)); }
^
./include/lightningpp.hpp:232:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitorUpdate' to 'LDKChannelMonitorUpdate &&' for 1st argument
ChannelMonitorUpdate(LDKChannelMonitorUpdate&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKChannelMonitorUpdate)); }
^
demo.cpp:160:16: error: no matching constructor for initialization of 'LDK::OutPoint'
LDK::OutPoint funding_txo(std::move(funding_txo_arg));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~
./include/lightningpp.hpp:334:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'const LDK::OutPoint' for 1st argument
OutPoint(const OutPoint&) = delete;
^
./include/lightningpp.hpp:335:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'LDK::OutPoint' for 1st argument
OutPoint(OutPoint&& o) : self(o.self) { memset(&o, 0, sizeof(OutPoint)); }
^
./include/lightningpp.hpp:336:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'LDKOutPoint &&' for 1st argument
OutPoint(LDKOutPoint&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKOutPoint)); }
^
demo.cpp:166:7: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
for (auto& mon : arg->mons) {
^
demo.cpp:166:17: warning: range-based for loop is a C++11 extension [-Wc++11-extensions]
for (auto& mon : arg->mons) {
^
demo.cpp:187:32: error: expected '(' for function-style cast or type construction
return LDKCVec_MonitorEventZ {
~~~~~~~~~~~~~~~~~~~~~ ^
demo.cpp:239:31: error: expected '(' for function-style cast or type construction
sock1 = LDKSocketDescriptor {
~~~~~~~~~~~~~~~~~~~ ^
demo.cpp:249:31: error: expected '(' for function-style cast or type construction
sock2 = LDKSocketDescriptor {
~~~~~~~~~~~~~~~~~~~ ^
demo.cpp:259:8: error: no matching constructor for initialization of 'std::thread'
t1 = std::thread(&sock_read_data_thread, pipefds_2_to_1[0], &sock1, &net1);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:408:9: note: candidate constructor template not viable: requires single argument '__f', but 4 arguments were provided
thread::thread(_Fp __f)
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:289:5: note: candidate constructor not viable: requires 1 argument, but 4 were provided
thread(const thread&);
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:296:5: note: candidate constructor not viable: requires 0 arguments, but 4 were provided
thread() _NOEXCEPT : __t_(_LIBCPP_NULL_THREAD) {}
^
demo.cpp:260:8: error: no matching constructor for initialization of 'std::thread'
t2 = std::thread(&sock_read_data_thread, pipefds_1_to_2[0], &sock2, &net2);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:408:9: note: candidate constructor template not viable: requires single argument '__f', but 4 arguments were provided
thread::thread(_Fp __f)
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:289:5: note: candidate constructor not viable: requires 1 argument, but 4 were provided
thread(const thread&);
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:296:5: note: candidate constructor not viable: requires 0 arguments, but 4 were provided
thread() _NOEXCEPT : __t_(_LIBCPP_NULL_THREAD) {}
^
demo.cpp:268:3: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
auto writelen = write(pipefds_1_to_2[1], con_res->contents.result->data, con_res->contents.result->datalen);
^
demo.cpp:299:35: error: expected ';' at end of declaration
LDKBroadcasterInterface broadcast {
^
;
demo.cpp:306:19: error: expected ';' at end of declaration
LDKLogger logger1 {
^
;
demo.cpp:314:15: error: expected ';' at end of declaration
LDKWatch mon1 {
^
;
demo.cpp:325:19: error: expected ';' at end of declaration
LDKLogger logger2 {
^
;
demo.cpp:333:15: error: expected ';' at end of declaration
LDKWatch mon2 {
^
;
demo.cpp:344:38: error: expected '(' for function-style cast or type construction
LDK::CVec_u8Z cm1_ser = LDKCVec_u8Z {}; // ChannelManager 1 serialization at the end of the ser-des scope
~~~~~~~~~~~ ^
demo.cpp:345:38: error: expected '(' for function-style cast or type construction
LDK::CVec_u8Z cm2_ser = LDKCVec_u8Z {}; // ChannelManager 2 serialization at the end of the ser-des scope
~~~~~~~~~~~ ^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
900 warnings and 20 errors generated.

}
pub extern "C" fn ChannelMonitorUpdate_read(ser: crate::c_types::u8slice) -> crate::c_types::derived::CResult_ChannelMonitorUpdateDecodeErrorZ {
let res = crate::c_types::deserialize_obj(ser);
let mut local_res = match res { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::chain::channelmonitor::ChannelMonitorUpdate { inner: Box::into_raw(Box::new(o)), is_owned: true } }), Err(mut e) => crate::c_types::CResultTempl::err( { crate::ln::msgs::DecodeError { inner: Box::into_raw(Box::new(e)), is_owned: true } }) };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was having no line breaks here intentional?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a number of similar cases across the bindings, especially for template types (vec/result/tuples) - specifically we don't track at what level of indentation we are at that deep into type conversion, so we either have bogus indentation or no indentation. For now its none, but its something we should fix eventually.

Comment threadc-bindings-gen/src/main.rs Outdated
Comment threadc-bindings-gen/src/main.rs
Comment threadgenbindings.sh Outdated
echo "WARNING: Please install valgrind for more testing"
fi

CLANGOPTS="-Wall -Wno-nullability-completeness -pthread"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm seeing a ton of warnings looking to originate from this commit:

++ rustc --version --verbose
++ grep host:
+ HOST_PLATFORM='host: x86_64-apple-darwin'
+ '[' 'host: x86_64-apple-darwin' = 'host: x86_64-apple-darwin' ']'
+ sed -i '' 's/typedef LDKnative.*Import.*LDKnative.*;//g' include/lightning.h
+ gcc -Wall -g -pthread demo.c target/debug/libldk.a -ldl
In file included from demo.c:2:
./include/lightning.h:204:12: warning: pointer is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified) [-Wnullability-completeness]
uint8_t *data;
^
./include/lightning.h:204:12: note: insert '_Nullable' if the pointer may be null
uint8_t *data;
^
_Nullable ./include/lightning.h:204:12: note: insert '_Nonnull' if the pointer should never be null
uint8_t *data;
^
_Nonnull 

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heh, that's an OSX-ism, because gcc is just a symlink to clang...I'll add the warning disable on all the compile calls.

@TheBlueMatt
TheBlueMattforce-pushed the 2020-12-chanman-bindings-deser branch from c326bcb to d08bdf4CompareFebruary 3, 2021 00:55
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Addressed review comments, rebased to fix conflicts but no changes outside of bindings generation code.

We can fail to resolve a part of a tuple, resulting in a panic in
write_template_constructor even if we're calling
`understood_c_type` with the intent of figuring out whether we can
print a type at all. Instead, we should pipe errors back and let
`understood_c_type` return false as a result.
Previously, manual `*_read` implementations were only defined for
types with inner fields, which were set to NULL to indicate read
errors. This prevents exposing `*_read` for several other types,
including tuples (which are needed for `ChannelManager`/
`ChannelMonitors`) and enums (which includes `Event`s, though users
likely never need to call that directly). Further, this means we
don't expose the actual error enum (which is likely no big deal,
but is still nice).
Here, we instead create the `Result<Object, DecodeError>` type and
then pass it through the normal type conversion functions, giving
us access to any types which we can convert normally.
This expands the manual implementation logic for `*_write` and
`*_read` methods to most types, converting the `*_write` path to
the common type-conversion logic to ensure it works.
Note that `*_write_void` is still only implemented for has-inner
types, as its unclear what the `void*` would point to for others.
It just stubs out to `write_rust_path` in this case anyway, which
handles leading-colons just fine, so no need to panic on them.
This is most of the code to expose `ChannelManager`/`ChannelMonitor`
deserialization in our C bindings, using the new infrastructure to
map types in `maybe_convert_trait_impl` and passing generics in
from the callsites.
We also call `maybe_convert_trait_impl` for tuple types, as the
`ChannelManager`/`ChannelMonitor` deserialization returns a
`(BlockHash, T)` to indicate the block hash at which users need to
start resyncing the chain.
The final step to expose them is in the next commit.
This (finally) exposes `ChannelManager`/`ChannelMonitor` _write
methods, which were (needlessly) excluded as the structs themselves
have generic parameters. Sadly, we also now need to parse
`(C-not exported)` doc comments on impl blocks as we otherwise try
to expose _write methods for `&Vec<RouteHop>`, which doesn't work
(and isn't particularly interesting for users anyway). We add such
doc comments there.
This adds a new annotation for objects we take by reference in the
C header indicating the pointers must not be null. We have to
disable some warning clang now dumps that we haven't annotated all
pointers, as cbindgen is not yet able to add a nullable annotation.
Previously, references and pointers ended up identical in C, so
there was little reason to differentiate. With the addition of
nullability annotations, there is a (very slight) reason to prefer
references, so use them in a few places where its a trivial change.
This adds a move-assignment operator (`A& operator=(A&& o)`) to our
C++ wrapper classes as well as requiring an rvalue for the move
auto-convert operator (`operator CStruct()() &&`).
The second makes the C++ wrapper classes much easier to work with
by requiring an explicit `std::move` when the bindings will
automatically move a C++-wrapper object into a C object.
This demonstrates (and tests) the newly-exposed `ChannelManager`
de/serialization functions. Best revewied with -b --color-moved.
There were two issues on OSX - we need to give gcc the clang
warnings flags because `gcc` *is* clang on OSX and we missed an
`-std=c++11` on one of the clang++ calls, causing compile failures.
@TheBlueMatt
TheBlueMattforce-pushed the 2020-12-chanman-bindings-deser branch from d08bdf4 to 5d045deCompareFebruary 3, 2021 15:12
@TheBlueMatt

TheBlueMatt commented Feb 3, 2021

Copy link
Copy Markdown
CollaboratorAuthor

Rebased with no changes (git diff-tree d08bdf44 5d045de8 is empty) - only dropped intermediate binidings updates and rebased on upstream (including 767 merge).

@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Its just bindings, worth merging without more than one ack.

@TheBlueMatt
TheBlueMatt merged commit e4b516d into lightningdevkit:mainFeb 3, 2021
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@TheBlueMatt@jkczyz
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Expose ChannelManager/Monitor read methods in bindings by TheBlueMatt · Pull Request #768 · lightningdevkit/rust-lightning · GitHub
Skip to content

Expose ChannelManager/Monitor read methods in bindings - #768

Merged
TheBlueMatt merged 13 commits into
lightningdevkit:mainfrom
TheBlueMatt:2020-12-chanman-bindings-deser
Feb 3, 2021
Merged

Expose ChannelManager/Monitor read methods in bindings#768
TheBlueMatt merged 13 commits into
lightningdevkit:mainfrom
TheBlueMatt:2020-12-chanman-bindings-deser

Conversation

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Based on #767 (and #761), this finally exposes ChannelManager read methods that were missed in the early bindings work. There's also a few nice cleanups of the C++ wrappers, though they are code-wise trivial. As with #767, between each bindings builder update the changes to the bindings are committed, though those commits may be squashed before merge.

@codecov

codecovBot commented Dec 31, 2020

Copy link
Copy Markdown

Codecov Report

Merging #768 (a4f5bf3) into main (c7ddcd3) will decrease coverage by 0.00%.
The diff coverage is n/a.

Impacted file tree graph

@@ Coverage Diff @@## main #768 +/- ##
==========================================
- Coverage 90.79% 90.78% -0.01% 
==========================================
Files 38 38 Lines 23168 23168 ==========================================
- Hits 21036 21034 -2 - Misses 2132 2134 +2 
Impacted FilesCoverage Δ
lightning/src/ln/chan_utils.rs97.33% <ø> (ø)
lightning/src/routing/router.rs95.57% <ø> (ø)
lightning/src/ln/functional_tests.rs96.96% <0.00%> (-0.04%)⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c7ddcd3...5d045de. Read the comment docs.

@TheBlueMatt
TheBlueMattforce-pushed the 2020-12-chanman-bindings-deser branch from 748542d to c326bcbCompareJanuary 1, 2021 01:46

@jkczyzjkczyz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm getting some compilation warnings and errors likely related to c++11 not being specified somewhere:

++ which valgrind
+ '[' -x '' ']'
+ echo 'WARNING: Please install valgrind for more testing'
WARNING: Please install valgrind for more testing
+ CLANGOPTS='-Wall -Wno-nullability-completeness -pthread'
+ clang++ -Wall -Wno-nullability-completeness -pthread demo.cpp target/debug/libldk.a -ldl
In file included from demo.cpp:5:
./include/lightningpp.hpp:7:24: warning: deleted function definitions are a C++11 extension [-Wc++11-extensions]
Event(const Event&) = delete;
^
./include/lightningpp.hpp:8:13: warning: rvalue references are a C++11 extension [-Wc++11-extensions]
Event(Event&& o) : self(o.self) { memset(&o, 0, sizeof(Event)); }
^
./include/lightningpp.hpp:9:16: warning: rvalue references are a C++11 extension [-Wc++11-extensions]
Event(LDKEvent&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKEvent)); }
^
./include/lightningpp.hpp:10:22: warning: reference qualifiers on functions are a C++11 extension [-Wc++11-extensions]
operator LDKEvent() && { LDKEvent res = self; memset(&self, 0, sizeof(LDKEvent)); return res; }
^
./include/lightningpp.hpp:12:24: warning: rvalue references are a C++11 extension [-Wc++11-extensions]
Event& operator=(Event&& o) { Event_free(self); self = o.self; memset(&o, 0, sizeof(Event)); return *this; }
^

...

demo.cpp:119:23: error: default initialization of an object of const type 'const LDKFeeEstimator' without a user-provided default constructor
const LDKFeeEstimator fee_est {
^
= {}
demo.cpp:119:30: error: expected ';' after top level declarator
const LDKFeeEstimator fee_est {
^
;
demo.cpp:134:58: error: a space is required between consecutive right angle brackets (use '> >')
std::vector<std::pair<LDK::OutPoint, LDK::ChannelMonitor>> mons;
^~
> >
demo.cpp:139:8: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
for (auto& mon : mons) {
^
demo.cpp:139:18: warning: range-based for loop is a C++11 extension [-Wc++11-extensions]
for (auto& mon : mons) {
^
demo.cpp:147:22: error: no matching constructor for initialization of 'LDK::ChannelMonitor'
LDK::ChannelMonitor mon(std::move(monitor_arg));
^ ~~~~~~~~~~~~~~~~~~~~~~
./include/lightningpp.hpp:304:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitor' to 'const LDK::ChannelMonitor' for 1st argument
ChannelMonitor(const ChannelMonitor&) = delete;
^
./include/lightningpp.hpp:305:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitor' to 'LDK::ChannelMonitor' for 1st argument
ChannelMonitor(ChannelMonitor&& o) : self(o.self) { memset(&o, 0, sizeof(ChannelMonitor)); }
^
./include/lightningpp.hpp:306:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitor' to 'LDKChannelMonitor &&' for 1st argument
ChannelMonitor(LDKChannelMonitor&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKChannelMonitor)); }
^
demo.cpp:148:16: error: no matching constructor for initialization of 'LDK::OutPoint'
LDK::OutPoint funding_txo(std::move(funding_txo_arg));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~
./include/lightningpp.hpp:334:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'const LDK::OutPoint' for 1st argument
OutPoint(const OutPoint&) = delete;
^
./include/lightningpp.hpp:335:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'LDK::OutPoint' for 1st argument
OutPoint(OutPoint&& o) : self(o.self) { memset(&o, 0, sizeof(OutPoint)); }
^
./include/lightningpp.hpp:336:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'LDKOutPoint &&' for 1st argument
OutPoint(LDKOutPoint&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKOutPoint)); }
^
demo.cpp:159:28: error: no matching constructor for initialization of 'LDK::ChannelMonitorUpdate'
LDK::ChannelMonitorUpdate update(std::move(monitor_arg));
^ ~~~~~~~~~~~~~~~~~~~~~~
./include/lightningpp.hpp:230:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitorUpdate' to 'const LDK::ChannelMonitorUpdate' for 1st argument
ChannelMonitorUpdate(const ChannelMonitorUpdate&) = delete;
^
./include/lightningpp.hpp:231:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitorUpdate' to 'LDK::ChannelMonitorUpdate' for 1st argument
ChannelMonitorUpdate(ChannelMonitorUpdate&& o) : self(o.self) { memset(&o, 0, sizeof(ChannelMonitorUpdate)); }
^
./include/lightningpp.hpp:232:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitorUpdate' to 'LDKChannelMonitorUpdate &&' for 1st argument
ChannelMonitorUpdate(LDKChannelMonitorUpdate&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKChannelMonitorUpdate)); }
^
demo.cpp:160:16: error: no matching constructor for initialization of 'LDK::OutPoint'
LDK::OutPoint funding_txo(std::move(funding_txo_arg));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~
./include/lightningpp.hpp:334:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'const LDK::OutPoint' for 1st argument
OutPoint(const OutPoint&) = delete;
^
./include/lightningpp.hpp:335:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'LDK::OutPoint' for 1st argument
OutPoint(OutPoint&& o) : self(o.self) { memset(&o, 0, sizeof(OutPoint)); }
^
./include/lightningpp.hpp:336:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'LDKOutPoint &&' for 1st argument
OutPoint(LDKOutPoint&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKOutPoint)); }
^
demo.cpp:166:7: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
for (auto& mon : arg->mons) {
^
demo.cpp:166:17: warning: range-based for loop is a C++11 extension [-Wc++11-extensions]
for (auto& mon : arg->mons) {
^
demo.cpp:187:32: error: expected '(' for function-style cast or type construction
return LDKCVec_MonitorEventZ {
~~~~~~~~~~~~~~~~~~~~~ ^
demo.cpp:239:31: error: expected '(' for function-style cast or type construction
sock1 = LDKSocketDescriptor {
~~~~~~~~~~~~~~~~~~~ ^
demo.cpp:249:31: error: expected '(' for function-style cast or type construction
sock2 = LDKSocketDescriptor {
~~~~~~~~~~~~~~~~~~~ ^
demo.cpp:259:8: error: no matching constructor for initialization of 'std::thread'
t1 = std::thread(&sock_read_data_thread, pipefds_2_to_1[0], &sock1, &net1);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:408:9: note: candidate constructor template not viable: requires single argument '__f', but 4 arguments were provided
thread::thread(_Fp __f)
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:289:5: note: candidate constructor not viable: requires 1 argument, but 4 were provided
thread(const thread&);
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:296:5: note: candidate constructor not viable: requires 0 arguments, but 4 were provided
thread() _NOEXCEPT : __t_(_LIBCPP_NULL_THREAD) {}
^
demo.cpp:260:8: error: no matching constructor for initialization of 'std::thread'
t2 = std::thread(&sock_read_data_thread, pipefds_1_to_2[0], &sock2, &net2);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:408:9: note: candidate constructor template not viable: requires single argument '__f', but 4 arguments were provided
thread::thread(_Fp __f)
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:289:5: note: candidate constructor not viable: requires 1 argument, but 4 were provided
thread(const thread&);
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:296:5: note: candidate constructor not viable: requires 0 arguments, but 4 were provided
thread() _NOEXCEPT : __t_(_LIBCPP_NULL_THREAD) {}
^
demo.cpp:268:3: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
auto writelen = write(pipefds_1_to_2[1], con_res->contents.result->data, con_res->contents.result->datalen);
^
demo.cpp:299:35: error: expected ';' at end of declaration
LDKBroadcasterInterface broadcast {
^
;
demo.cpp:306:19: error: expected ';' at end of declaration
LDKLogger logger1 {
^
;
demo.cpp:314:15: error: expected ';' at end of declaration
LDKWatch mon1 {
^
;
demo.cpp:325:19: error: expected ';' at end of declaration
LDKLogger logger2 {
^
;
demo.cpp:333:15: error: expected ';' at end of declaration
LDKWatch mon2 {
^
;
demo.cpp:344:38: error: expected '(' for function-style cast or type construction
LDK::CVec_u8Z cm1_ser = LDKCVec_u8Z {}; // ChannelManager 1 serialization at the end of the ser-des scope
~~~~~~~~~~~ ^
demo.cpp:345:38: error: expected '(' for function-style cast or type construction
LDK::CVec_u8Z cm2_ser = LDKCVec_u8Z {}; // ChannelManager 2 serialization at the end of the ser-des scope
~~~~~~~~~~~ ^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
900 warnings and 20 errors generated.

}
pub extern "C" fn ChannelMonitorUpdate_read(ser: crate::c_types::u8slice) -> crate::c_types::derived::CResult_ChannelMonitorUpdateDecodeErrorZ {
let res = crate::c_types::deserialize_obj(ser);
let mut local_res = match res { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::chain::channelmonitor::ChannelMonitorUpdate { inner: Box::into_raw(Box::new(o)), is_owned: true } }), Err(mut e) => crate::c_types::CResultTempl::err( { crate::ln::msgs::DecodeError { inner: Box::into_raw(Box::new(e)), is_owned: true } }) };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was having no line breaks here intentional?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a number of similar cases across the bindings, especially for template types (vec/result/tuples) - specifically we don't track at what level of indentation we are at that deep into type conversion, so we either have bogus indentation or no indentation. For now its none, but its something we should fix eventually.

Comment threadc-bindings-gen/src/main.rs Outdated
Comment threadc-bindings-gen/src/main.rs
Comment threadgenbindings.sh Outdated
echo "WARNING: Please install valgrind for more testing"
fi

CLANGOPTS="-Wall -Wno-nullability-completeness -pthread"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm seeing a ton of warnings looking to originate from this commit:

++ rustc --version --verbose
++ grep host:
+ HOST_PLATFORM='host: x86_64-apple-darwin'
+ '[' 'host: x86_64-apple-darwin' = 'host: x86_64-apple-darwin' ']'
+ sed -i '' 's/typedef LDKnative.*Import.*LDKnative.*;//g' include/lightning.h
+ gcc -Wall -g -pthread demo.c target/debug/libldk.a -ldl
In file included from demo.c:2:
./include/lightning.h:204:12: warning: pointer is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified) [-Wnullability-completeness]
uint8_t *data;
^
./include/lightning.h:204:12: note: insert '_Nullable' if the pointer may be null
uint8_t *data;
^
_Nullable ./include/lightning.h:204:12: note: insert '_Nonnull' if the pointer should never be null
uint8_t *data;
^
_Nonnull 

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heh, that's an OSX-ism, because gcc is just a symlink to clang...I'll add the warning disable on all the compile calls.

@TheBlueMatt
TheBlueMattforce-pushed the 2020-12-chanman-bindings-deser branch from c326bcb to d08bdf4CompareFebruary 3, 2021 00:55
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Addressed review comments, rebased to fix conflicts but no changes outside of bindings generation code.

We can fail to resolve a part of a tuple, resulting in a panic in
write_template_constructor even if we're calling
`understood_c_type` with the intent of figuring out whether we can
print a type at all. Instead, we should pipe errors back and let
`understood_c_type` return false as a result.
Previously, manual `*_read` implementations were only defined for
types with inner fields, which were set to NULL to indicate read
errors. This prevents exposing `*_read` for several other types,
including tuples (which are needed for `ChannelManager`/
`ChannelMonitors`) and enums (which includes `Event`s, though users
likely never need to call that directly). Further, this means we
don't expose the actual error enum (which is likely no big deal,
but is still nice).
Here, we instead create the `Result<Object, DecodeError>` type and
then pass it through the normal type conversion functions, giving
us access to any types which we can convert normally.
This expands the manual implementation logic for `*_write` and
`*_read` methods to most types, converting the `*_write` path to
the common type-conversion logic to ensure it works.
Note that `*_write_void` is still only implemented for has-inner
types, as its unclear what the `void*` would point to for others.
It just stubs out to `write_rust_path` in this case anyway, which
handles leading-colons just fine, so no need to panic on them.
This is most of the code to expose `ChannelManager`/`ChannelMonitor`
deserialization in our C bindings, using the new infrastructure to
map types in `maybe_convert_trait_impl` and passing generics in
from the callsites.
We also call `maybe_convert_trait_impl` for tuple types, as the
`ChannelManager`/`ChannelMonitor` deserialization returns a
`(BlockHash, T)` to indicate the block hash at which users need to
start resyncing the chain.
The final step to expose them is in the next commit.
This (finally) exposes `ChannelManager`/`ChannelMonitor` _write
methods, which were (needlessly) excluded as the structs themselves
have generic parameters. Sadly, we also now need to parse
`(C-not exported)` doc comments on impl blocks as we otherwise try
to expose _write methods for `&Vec<RouteHop>`, which doesn't work
(and isn't particularly interesting for users anyway). We add such
doc comments there.
This adds a new annotation for objects we take by reference in the
C header indicating the pointers must not be null. We have to
disable some warning clang now dumps that we haven't annotated all
pointers, as cbindgen is not yet able to add a nullable annotation.
Previously, references and pointers ended up identical in C, so
there was little reason to differentiate. With the addition of
nullability annotations, there is a (very slight) reason to prefer
references, so use them in a few places where its a trivial change.
This adds a move-assignment operator (`A& operator=(A&& o)`) to our
C++ wrapper classes as well as requiring an rvalue for the move
auto-convert operator (`operator CStruct()() &&`).
The second makes the C++ wrapper classes much easier to work with
by requiring an explicit `std::move` when the bindings will
automatically move a C++-wrapper object into a C object.
This demonstrates (and tests) the newly-exposed `ChannelManager`
de/serialization functions. Best revewied with -b --color-moved.
There were two issues on OSX - we need to give gcc the clang
warnings flags because `gcc` *is* clang on OSX and we missed an
`-std=c++11` on one of the clang++ calls, causing compile failures.
@TheBlueMatt
TheBlueMattforce-pushed the 2020-12-chanman-bindings-deser branch from d08bdf4 to 5d045deCompareFebruary 3, 2021 15:12
@TheBlueMatt

TheBlueMatt commented Feb 3, 2021

Copy link
Copy Markdown
CollaboratorAuthor

Rebased with no changes (git diff-tree d08bdf44 5d045de8 is empty) - only dropped intermediate binidings updates and rebased on upstream (including 767 merge).

@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Its just bindings, worth merging without more than one ack.

@TheBlueMatt
TheBlueMatt merged commit e4b516d into lightningdevkit:mainFeb 3, 2021
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@TheBlueMatt@jkczyz
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Expose ChannelManager/Monitor read methods in bindings by TheBlueMatt · Pull Request #768 · lightningdevkit/rust-lightning · GitHub
Skip to content

Expose ChannelManager/Monitor read methods in bindings - #768

Merged
TheBlueMatt merged 13 commits into
lightningdevkit:mainfrom
TheBlueMatt:2020-12-chanman-bindings-deser
Feb 3, 2021
Merged

Expose ChannelManager/Monitor read methods in bindings#768
TheBlueMatt merged 13 commits into
lightningdevkit:mainfrom
TheBlueMatt:2020-12-chanman-bindings-deser

Conversation

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Based on #767 (and #761), this finally exposes ChannelManager read methods that were missed in the early bindings work. There's also a few nice cleanups of the C++ wrappers, though they are code-wise trivial. As with #767, between each bindings builder update the changes to the bindings are committed, though those commits may be squashed before merge.

@codecov

codecovBot commented Dec 31, 2020

Copy link
Copy Markdown

Codecov Report

Merging #768 (a4f5bf3) into main (c7ddcd3) will decrease coverage by 0.00%.
The diff coverage is n/a.

Impacted file tree graph

@@ Coverage Diff @@## main #768 +/- ##
==========================================
- Coverage 90.79% 90.78% -0.01% 
==========================================
Files 38 38 Lines 23168 23168 ==========================================
- Hits 21036 21034 -2 - Misses 2132 2134 +2 
Impacted FilesCoverage Δ
lightning/src/ln/chan_utils.rs97.33% <ø> (ø)
lightning/src/routing/router.rs95.57% <ø> (ø)
lightning/src/ln/functional_tests.rs96.96% <0.00%> (-0.04%)⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c7ddcd3...5d045de. Read the comment docs.

@TheBlueMatt
TheBlueMattforce-pushed the 2020-12-chanman-bindings-deser branch from 748542d to c326bcbCompareJanuary 1, 2021 01:46

@jkczyzjkczyz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm getting some compilation warnings and errors likely related to c++11 not being specified somewhere:

++ which valgrind
+ '[' -x '' ']'
+ echo 'WARNING: Please install valgrind for more testing'
WARNING: Please install valgrind for more testing
+ CLANGOPTS='-Wall -Wno-nullability-completeness -pthread'
+ clang++ -Wall -Wno-nullability-completeness -pthread demo.cpp target/debug/libldk.a -ldl
In file included from demo.cpp:5:
./include/lightningpp.hpp:7:24: warning: deleted function definitions are a C++11 extension [-Wc++11-extensions]
Event(const Event&) = delete;
^
./include/lightningpp.hpp:8:13: warning: rvalue references are a C++11 extension [-Wc++11-extensions]
Event(Event&& o) : self(o.self) { memset(&o, 0, sizeof(Event)); }
^
./include/lightningpp.hpp:9:16: warning: rvalue references are a C++11 extension [-Wc++11-extensions]
Event(LDKEvent&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKEvent)); }
^
./include/lightningpp.hpp:10:22: warning: reference qualifiers on functions are a C++11 extension [-Wc++11-extensions]
operator LDKEvent() && { LDKEvent res = self; memset(&self, 0, sizeof(LDKEvent)); return res; }
^
./include/lightningpp.hpp:12:24: warning: rvalue references are a C++11 extension [-Wc++11-extensions]
Event& operator=(Event&& o) { Event_free(self); self = o.self; memset(&o, 0, sizeof(Event)); return *this; }
^

...

demo.cpp:119:23: error: default initialization of an object of const type 'const LDKFeeEstimator' without a user-provided default constructor
const LDKFeeEstimator fee_est {
^
= {}
demo.cpp:119:30: error: expected ';' after top level declarator
const LDKFeeEstimator fee_est {
^
;
demo.cpp:134:58: error: a space is required between consecutive right angle brackets (use '> >')
std::vector<std::pair<LDK::OutPoint, LDK::ChannelMonitor>> mons;
^~
> >
demo.cpp:139:8: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
for (auto& mon : mons) {
^
demo.cpp:139:18: warning: range-based for loop is a C++11 extension [-Wc++11-extensions]
for (auto& mon : mons) {
^
demo.cpp:147:22: error: no matching constructor for initialization of 'LDK::ChannelMonitor'
LDK::ChannelMonitor mon(std::move(monitor_arg));
^ ~~~~~~~~~~~~~~~~~~~~~~
./include/lightningpp.hpp:304:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitor' to 'const LDK::ChannelMonitor' for 1st argument
ChannelMonitor(const ChannelMonitor&) = delete;
^
./include/lightningpp.hpp:305:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitor' to 'LDK::ChannelMonitor' for 1st argument
ChannelMonitor(ChannelMonitor&& o) : self(o.self) { memset(&o, 0, sizeof(ChannelMonitor)); }
^
./include/lightningpp.hpp:306:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitor' to 'LDKChannelMonitor &&' for 1st argument
ChannelMonitor(LDKChannelMonitor&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKChannelMonitor)); }
^
demo.cpp:148:16: error: no matching constructor for initialization of 'LDK::OutPoint'
LDK::OutPoint funding_txo(std::move(funding_txo_arg));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~
./include/lightningpp.hpp:334:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'const LDK::OutPoint' for 1st argument
OutPoint(const OutPoint&) = delete;
^
./include/lightningpp.hpp:335:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'LDK::OutPoint' for 1st argument
OutPoint(OutPoint&& o) : self(o.self) { memset(&o, 0, sizeof(OutPoint)); }
^
./include/lightningpp.hpp:336:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'LDKOutPoint &&' for 1st argument
OutPoint(LDKOutPoint&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKOutPoint)); }
^
demo.cpp:159:28: error: no matching constructor for initialization of 'LDK::ChannelMonitorUpdate'
LDK::ChannelMonitorUpdate update(std::move(monitor_arg));
^ ~~~~~~~~~~~~~~~~~~~~~~
./include/lightningpp.hpp:230:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitorUpdate' to 'const LDK::ChannelMonitorUpdate' for 1st argument
ChannelMonitorUpdate(const ChannelMonitorUpdate&) = delete;
^
./include/lightningpp.hpp:231:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitorUpdate' to 'LDK::ChannelMonitorUpdate' for 1st argument
ChannelMonitorUpdate(ChannelMonitorUpdate&& o) : self(o.self) { memset(&o, 0, sizeof(ChannelMonitorUpdate)); }
^
./include/lightningpp.hpp:232:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitorUpdate' to 'LDKChannelMonitorUpdate &&' for 1st argument
ChannelMonitorUpdate(LDKChannelMonitorUpdate&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKChannelMonitorUpdate)); }
^
demo.cpp:160:16: error: no matching constructor for initialization of 'LDK::OutPoint'
LDK::OutPoint funding_txo(std::move(funding_txo_arg));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~
./include/lightningpp.hpp:334:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'const LDK::OutPoint' for 1st argument
OutPoint(const OutPoint&) = delete;
^
./include/lightningpp.hpp:335:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'LDK::OutPoint' for 1st argument
OutPoint(OutPoint&& o) : self(o.self) { memset(&o, 0, sizeof(OutPoint)); }
^
./include/lightningpp.hpp:336:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'LDKOutPoint &&' for 1st argument
OutPoint(LDKOutPoint&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKOutPoint)); }
^
demo.cpp:166:7: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
for (auto& mon : arg->mons) {
^
demo.cpp:166:17: warning: range-based for loop is a C++11 extension [-Wc++11-extensions]
for (auto& mon : arg->mons) {
^
demo.cpp:187:32: error: expected '(' for function-style cast or type construction
return LDKCVec_MonitorEventZ {
~~~~~~~~~~~~~~~~~~~~~ ^
demo.cpp:239:31: error: expected '(' for function-style cast or type construction
sock1 = LDKSocketDescriptor {
~~~~~~~~~~~~~~~~~~~ ^
demo.cpp:249:31: error: expected '(' for function-style cast or type construction
sock2 = LDKSocketDescriptor {
~~~~~~~~~~~~~~~~~~~ ^
demo.cpp:259:8: error: no matching constructor for initialization of 'std::thread'
t1 = std::thread(&sock_read_data_thread, pipefds_2_to_1[0], &sock1, &net1);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:408:9: note: candidate constructor template not viable: requires single argument '__f', but 4 arguments were provided
thread::thread(_Fp __f)
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:289:5: note: candidate constructor not viable: requires 1 argument, but 4 were provided
thread(const thread&);
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:296:5: note: candidate constructor not viable: requires 0 arguments, but 4 were provided
thread() _NOEXCEPT : __t_(_LIBCPP_NULL_THREAD) {}
^
demo.cpp:260:8: error: no matching constructor for initialization of 'std::thread'
t2 = std::thread(&sock_read_data_thread, pipefds_1_to_2[0], &sock2, &net2);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:408:9: note: candidate constructor template not viable: requires single argument '__f', but 4 arguments were provided
thread::thread(_Fp __f)
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:289:5: note: candidate constructor not viable: requires 1 argument, but 4 were provided
thread(const thread&);
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:296:5: note: candidate constructor not viable: requires 0 arguments, but 4 were provided
thread() _NOEXCEPT : __t_(_LIBCPP_NULL_THREAD) {}
^
demo.cpp:268:3: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
auto writelen = write(pipefds_1_to_2[1], con_res->contents.result->data, con_res->contents.result->datalen);
^
demo.cpp:299:35: error: expected ';' at end of declaration
LDKBroadcasterInterface broadcast {
^
;
demo.cpp:306:19: error: expected ';' at end of declaration
LDKLogger logger1 {
^
;
demo.cpp:314:15: error: expected ';' at end of declaration
LDKWatch mon1 {
^
;
demo.cpp:325:19: error: expected ';' at end of declaration
LDKLogger logger2 {
^
;
demo.cpp:333:15: error: expected ';' at end of declaration
LDKWatch mon2 {
^
;
demo.cpp:344:38: error: expected '(' for function-style cast or type construction
LDK::CVec_u8Z cm1_ser = LDKCVec_u8Z {}; // ChannelManager 1 serialization at the end of the ser-des scope
~~~~~~~~~~~ ^
demo.cpp:345:38: error: expected '(' for function-style cast or type construction
LDK::CVec_u8Z cm2_ser = LDKCVec_u8Z {}; // ChannelManager 2 serialization at the end of the ser-des scope
~~~~~~~~~~~ ^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
900 warnings and 20 errors generated.

}
pub extern "C" fn ChannelMonitorUpdate_read(ser: crate::c_types::u8slice) -> crate::c_types::derived::CResult_ChannelMonitorUpdateDecodeErrorZ {
let res = crate::c_types::deserialize_obj(ser);
let mut local_res = match res { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::chain::channelmonitor::ChannelMonitorUpdate { inner: Box::into_raw(Box::new(o)), is_owned: true } }), Err(mut e) => crate::c_types::CResultTempl::err( { crate::ln::msgs::DecodeError { inner: Box::into_raw(Box::new(e)), is_owned: true } }) };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was having no line breaks here intentional?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a number of similar cases across the bindings, especially for template types (vec/result/tuples) - specifically we don't track at what level of indentation we are at that deep into type conversion, so we either have bogus indentation or no indentation. For now its none, but its something we should fix eventually.

Comment threadc-bindings-gen/src/main.rs Outdated
Comment threadc-bindings-gen/src/main.rs
Comment threadgenbindings.sh Outdated
echo "WARNING: Please install valgrind for more testing"
fi

CLANGOPTS="-Wall -Wno-nullability-completeness -pthread"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm seeing a ton of warnings looking to originate from this commit:

++ rustc --version --verbose
++ grep host:
+ HOST_PLATFORM='host: x86_64-apple-darwin'
+ '[' 'host: x86_64-apple-darwin' = 'host: x86_64-apple-darwin' ']'
+ sed -i '' 's/typedef LDKnative.*Import.*LDKnative.*;//g' include/lightning.h
+ gcc -Wall -g -pthread demo.c target/debug/libldk.a -ldl
In file included from demo.c:2:
./include/lightning.h:204:12: warning: pointer is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified) [-Wnullability-completeness]
uint8_t *data;
^
./include/lightning.h:204:12: note: insert '_Nullable' if the pointer may be null
uint8_t *data;
^
_Nullable ./include/lightning.h:204:12: note: insert '_Nonnull' if the pointer should never be null
uint8_t *data;
^
_Nonnull 

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heh, that's an OSX-ism, because gcc is just a symlink to clang...I'll add the warning disable on all the compile calls.

@TheBlueMatt
TheBlueMattforce-pushed the 2020-12-chanman-bindings-deser branch from c326bcb to d08bdf4CompareFebruary 3, 2021 00:55
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Addressed review comments, rebased to fix conflicts but no changes outside of bindings generation code.

We can fail to resolve a part of a tuple, resulting in a panic in
write_template_constructor even if we're calling
`understood_c_type` with the intent of figuring out whether we can
print a type at all. Instead, we should pipe errors back and let
`understood_c_type` return false as a result.
Previously, manual `*_read` implementations were only defined for
types with inner fields, which were set to NULL to indicate read
errors. This prevents exposing `*_read` for several other types,
including tuples (which are needed for `ChannelManager`/
`ChannelMonitors`) and enums (which includes `Event`s, though users
likely never need to call that directly). Further, this means we
don't expose the actual error enum (which is likely no big deal,
but is still nice).
Here, we instead create the `Result<Object, DecodeError>` type and
then pass it through the normal type conversion functions, giving
us access to any types which we can convert normally.
This expands the manual implementation logic for `*_write` and
`*_read` methods to most types, converting the `*_write` path to
the common type-conversion logic to ensure it works.
Note that `*_write_void` is still only implemented for has-inner
types, as its unclear what the `void*` would point to for others.
It just stubs out to `write_rust_path` in this case anyway, which
handles leading-colons just fine, so no need to panic on them.
This is most of the code to expose `ChannelManager`/`ChannelMonitor`
deserialization in our C bindings, using the new infrastructure to
map types in `maybe_convert_trait_impl` and passing generics in
from the callsites.
We also call `maybe_convert_trait_impl` for tuple types, as the
`ChannelManager`/`ChannelMonitor` deserialization returns a
`(BlockHash, T)` to indicate the block hash at which users need to
start resyncing the chain.
The final step to expose them is in the next commit.
This (finally) exposes `ChannelManager`/`ChannelMonitor` _write
methods, which were (needlessly) excluded as the structs themselves
have generic parameters. Sadly, we also now need to parse
`(C-not exported)` doc comments on impl blocks as we otherwise try
to expose _write methods for `&Vec<RouteHop>`, which doesn't work
(and isn't particularly interesting for users anyway). We add such
doc comments there.
This adds a new annotation for objects we take by reference in the
C header indicating the pointers must not be null. We have to
disable some warning clang now dumps that we haven't annotated all
pointers, as cbindgen is not yet able to add a nullable annotation.
Previously, references and pointers ended up identical in C, so
there was little reason to differentiate. With the addition of
nullability annotations, there is a (very slight) reason to prefer
references, so use them in a few places where its a trivial change.
This adds a move-assignment operator (`A& operator=(A&& o)`) to our
C++ wrapper classes as well as requiring an rvalue for the move
auto-convert operator (`operator CStruct()() &&`).
The second makes the C++ wrapper classes much easier to work with
by requiring an explicit `std::move` when the bindings will
automatically move a C++-wrapper object into a C object.
This demonstrates (and tests) the newly-exposed `ChannelManager`
de/serialization functions. Best revewied with -b --color-moved.
There were two issues on OSX - we need to give gcc the clang
warnings flags because `gcc` *is* clang on OSX and we missed an
`-std=c++11` on one of the clang++ calls, causing compile failures.
@TheBlueMatt
TheBlueMattforce-pushed the 2020-12-chanman-bindings-deser branch from d08bdf4 to 5d045deCompareFebruary 3, 2021 15:12
@TheBlueMatt

TheBlueMatt commented Feb 3, 2021

Copy link
Copy Markdown
CollaboratorAuthor

Rebased with no changes (git diff-tree d08bdf44 5d045de8 is empty) - only dropped intermediate binidings updates and rebased on upstream (including 767 merge).

@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Its just bindings, worth merging without more than one ack.

@TheBlueMatt
TheBlueMatt merged commit e4b516d into lightningdevkit:mainFeb 3, 2021
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@TheBlueMatt@jkczyz
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' Expose ChannelManager/Monitor read methods in bindings by TheBlueMatt · Pull Request #768 · lightningdevkit/rust-lightning · GitHub
Skip to content

Expose ChannelManager/Monitor read methods in bindings - #768

Merged
TheBlueMatt merged 13 commits into
lightningdevkit:mainfrom
TheBlueMatt:2020-12-chanman-bindings-deser
Feb 3, 2021
Merged

Expose ChannelManager/Monitor read methods in bindings#768
TheBlueMatt merged 13 commits into
lightningdevkit:mainfrom
TheBlueMatt:2020-12-chanman-bindings-deser

Conversation

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Based on #767 (and #761), this finally exposes ChannelManager read methods that were missed in the early bindings work. There's also a few nice cleanups of the C++ wrappers, though they are code-wise trivial. As with #767, between each bindings builder update the changes to the bindings are committed, though those commits may be squashed before merge.

@codecov

codecovBot commented Dec 31, 2020

Copy link
Copy Markdown

Codecov Report

Merging #768 (a4f5bf3) into main (c7ddcd3) will decrease coverage by 0.00%.
The diff coverage is n/a.

Impacted file tree graph

@@ Coverage Diff @@## main #768 +/- ##
==========================================
- Coverage 90.79% 90.78% -0.01% 
==========================================
Files 38 38 Lines 23168 23168 ==========================================
- Hits 21036 21034 -2 - Misses 2132 2134 +2 
Impacted FilesCoverage Δ
lightning/src/ln/chan_utils.rs97.33% <ø> (ø)
lightning/src/routing/router.rs95.57% <ø> (ø)
lightning/src/ln/functional_tests.rs96.96% <0.00%> (-0.04%)⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c7ddcd3...5d045de. Read the comment docs.

@TheBlueMatt
TheBlueMattforce-pushed the 2020-12-chanman-bindings-deser branch from 748542d to c326bcbCompareJanuary 1, 2021 01:46

@jkczyzjkczyz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm getting some compilation warnings and errors likely related to c++11 not being specified somewhere:

++ which valgrind
+ '[' -x '' ']'
+ echo 'WARNING: Please install valgrind for more testing'
WARNING: Please install valgrind for more testing
+ CLANGOPTS='-Wall -Wno-nullability-completeness -pthread'
+ clang++ -Wall -Wno-nullability-completeness -pthread demo.cpp target/debug/libldk.a -ldl
In file included from demo.cpp:5:
./include/lightningpp.hpp:7:24: warning: deleted function definitions are a C++11 extension [-Wc++11-extensions]
Event(const Event&) = delete;
^
./include/lightningpp.hpp:8:13: warning: rvalue references are a C++11 extension [-Wc++11-extensions]
Event(Event&& o) : self(o.self) { memset(&o, 0, sizeof(Event)); }
^
./include/lightningpp.hpp:9:16: warning: rvalue references are a C++11 extension [-Wc++11-extensions]
Event(LDKEvent&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKEvent)); }
^
./include/lightningpp.hpp:10:22: warning: reference qualifiers on functions are a C++11 extension [-Wc++11-extensions]
operator LDKEvent() && { LDKEvent res = self; memset(&self, 0, sizeof(LDKEvent)); return res; }
^
./include/lightningpp.hpp:12:24: warning: rvalue references are a C++11 extension [-Wc++11-extensions]
Event& operator=(Event&& o) { Event_free(self); self = o.self; memset(&o, 0, sizeof(Event)); return *this; }
^

...

demo.cpp:119:23: error: default initialization of an object of const type 'const LDKFeeEstimator' without a user-provided default constructor
const LDKFeeEstimator fee_est {
^
= {}
demo.cpp:119:30: error: expected ';' after top level declarator
const LDKFeeEstimator fee_est {
^
;
demo.cpp:134:58: error: a space is required between consecutive right angle brackets (use '> >')
std::vector<std::pair<LDK::OutPoint, LDK::ChannelMonitor>> mons;
^~
> >
demo.cpp:139:8: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
for (auto& mon : mons) {
^
demo.cpp:139:18: warning: range-based for loop is a C++11 extension [-Wc++11-extensions]
for (auto& mon : mons) {
^
demo.cpp:147:22: error: no matching constructor for initialization of 'LDK::ChannelMonitor'
LDK::ChannelMonitor mon(std::move(monitor_arg));
^ ~~~~~~~~~~~~~~~~~~~~~~
./include/lightningpp.hpp:304:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitor' to 'const LDK::ChannelMonitor' for 1st argument
ChannelMonitor(const ChannelMonitor&) = delete;
^
./include/lightningpp.hpp:305:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitor' to 'LDK::ChannelMonitor' for 1st argument
ChannelMonitor(ChannelMonitor&& o) : self(o.self) { memset(&o, 0, sizeof(ChannelMonitor)); }
^
./include/lightningpp.hpp:306:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitor' to 'LDKChannelMonitor &&' for 1st argument
ChannelMonitor(LDKChannelMonitor&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKChannelMonitor)); }
^
demo.cpp:148:16: error: no matching constructor for initialization of 'LDK::OutPoint'
LDK::OutPoint funding_txo(std::move(funding_txo_arg));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~
./include/lightningpp.hpp:334:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'const LDK::OutPoint' for 1st argument
OutPoint(const OutPoint&) = delete;
^
./include/lightningpp.hpp:335:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'LDK::OutPoint' for 1st argument
OutPoint(OutPoint&& o) : self(o.self) { memset(&o, 0, sizeof(OutPoint)); }
^
./include/lightningpp.hpp:336:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'LDKOutPoint &&' for 1st argument
OutPoint(LDKOutPoint&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKOutPoint)); }
^
demo.cpp:159:28: error: no matching constructor for initialization of 'LDK::ChannelMonitorUpdate'
LDK::ChannelMonitorUpdate update(std::move(monitor_arg));
^ ~~~~~~~~~~~~~~~~~~~~~~
./include/lightningpp.hpp:230:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitorUpdate' to 'const LDK::ChannelMonitorUpdate' for 1st argument
ChannelMonitorUpdate(const ChannelMonitorUpdate&) = delete;
^
./include/lightningpp.hpp:231:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitorUpdate' to 'LDK::ChannelMonitorUpdate' for 1st argument
ChannelMonitorUpdate(ChannelMonitorUpdate&& o) : self(o.self) { memset(&o, 0, sizeof(ChannelMonitorUpdate)); }
^
./include/lightningpp.hpp:232:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitorUpdate' to 'LDKChannelMonitorUpdate &&' for 1st argument
ChannelMonitorUpdate(LDKChannelMonitorUpdate&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKChannelMonitorUpdate)); }
^
demo.cpp:160:16: error: no matching constructor for initialization of 'LDK::OutPoint'
LDK::OutPoint funding_txo(std::move(funding_txo_arg));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~
./include/lightningpp.hpp:334:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'const LDK::OutPoint' for 1st argument
OutPoint(const OutPoint&) = delete;
^
./include/lightningpp.hpp:335:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'LDK::OutPoint' for 1st argument
OutPoint(OutPoint&& o) : self(o.self) { memset(&o, 0, sizeof(OutPoint)); }
^
./include/lightningpp.hpp:336:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'LDKOutPoint &&' for 1st argument
OutPoint(LDKOutPoint&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKOutPoint)); }
^
demo.cpp:166:7: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
for (auto& mon : arg->mons) {
^
demo.cpp:166:17: warning: range-based for loop is a C++11 extension [-Wc++11-extensions]
for (auto& mon : arg->mons) {
^
demo.cpp:187:32: error: expected '(' for function-style cast or type construction
return LDKCVec_MonitorEventZ {
~~~~~~~~~~~~~~~~~~~~~ ^
demo.cpp:239:31: error: expected '(' for function-style cast or type construction
sock1 = LDKSocketDescriptor {
~~~~~~~~~~~~~~~~~~~ ^
demo.cpp:249:31: error: expected '(' for function-style cast or type construction
sock2 = LDKSocketDescriptor {
~~~~~~~~~~~~~~~~~~~ ^
demo.cpp:259:8: error: no matching constructor for initialization of 'std::thread'
t1 = std::thread(&sock_read_data_thread, pipefds_2_to_1[0], &sock1, &net1);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:408:9: note: candidate constructor template not viable: requires single argument '__f', but 4 arguments were provided
thread::thread(_Fp __f)
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:289:5: note: candidate constructor not viable: requires 1 argument, but 4 were provided
thread(const thread&);
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:296:5: note: candidate constructor not viable: requires 0 arguments, but 4 were provided
thread() _NOEXCEPT : __t_(_LIBCPP_NULL_THREAD) {}
^
demo.cpp:260:8: error: no matching constructor for initialization of 'std::thread'
t2 = std::thread(&sock_read_data_thread, pipefds_1_to_2[0], &sock2, &net2);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:408:9: note: candidate constructor template not viable: requires single argument '__f', but 4 arguments were provided
thread::thread(_Fp __f)
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:289:5: note: candidate constructor not viable: requires 1 argument, but 4 were provided
thread(const thread&);
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:296:5: note: candidate constructor not viable: requires 0 arguments, but 4 were provided
thread() _NOEXCEPT : __t_(_LIBCPP_NULL_THREAD) {}
^
demo.cpp:268:3: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
auto writelen = write(pipefds_1_to_2[1], con_res->contents.result->data, con_res->contents.result->datalen);
^
demo.cpp:299:35: error: expected ';' at end of declaration
LDKBroadcasterInterface broadcast {
^
;
demo.cpp:306:19: error: expected ';' at end of declaration
LDKLogger logger1 {
^
;
demo.cpp:314:15: error: expected ';' at end of declaration
LDKWatch mon1 {
^
;
demo.cpp:325:19: error: expected ';' at end of declaration
LDKLogger logger2 {
^
;
demo.cpp:333:15: error: expected ';' at end of declaration
LDKWatch mon2 {
^
;
demo.cpp:344:38: error: expected '(' for function-style cast or type construction
LDK::CVec_u8Z cm1_ser = LDKCVec_u8Z {}; // ChannelManager 1 serialization at the end of the ser-des scope
~~~~~~~~~~~ ^
demo.cpp:345:38: error: expected '(' for function-style cast or type construction
LDK::CVec_u8Z cm2_ser = LDKCVec_u8Z {}; // ChannelManager 2 serialization at the end of the ser-des scope
~~~~~~~~~~~ ^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
900 warnings and 20 errors generated.

}
pub extern "C" fn ChannelMonitorUpdate_read(ser: crate::c_types::u8slice) -> crate::c_types::derived::CResult_ChannelMonitorUpdateDecodeErrorZ {
let res = crate::c_types::deserialize_obj(ser);
let mut local_res = match res { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::chain::channelmonitor::ChannelMonitorUpdate { inner: Box::into_raw(Box::new(o)), is_owned: true } }), Err(mut e) => crate::c_types::CResultTempl::err( { crate::ln::msgs::DecodeError { inner: Box::into_raw(Box::new(e)), is_owned: true } }) };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was having no line breaks here intentional?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a number of similar cases across the bindings, especially for template types (vec/result/tuples) - specifically we don't track at what level of indentation we are at that deep into type conversion, so we either have bogus indentation or no indentation. For now its none, but its something we should fix eventually.

Comment threadc-bindings-gen/src/main.rs Outdated
Comment threadc-bindings-gen/src/main.rs
Comment threadgenbindings.sh Outdated
echo "WARNING: Please install valgrind for more testing"
fi

CLANGOPTS="-Wall -Wno-nullability-completeness -pthread"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm seeing a ton of warnings looking to originate from this commit:

++ rustc --version --verbose
++ grep host:
+ HOST_PLATFORM='host: x86_64-apple-darwin'
+ '[' 'host: x86_64-apple-darwin' = 'host: x86_64-apple-darwin' ']'
+ sed -i '' 's/typedef LDKnative.*Import.*LDKnative.*;//g' include/lightning.h
+ gcc -Wall -g -pthread demo.c target/debug/libldk.a -ldl
In file included from demo.c:2:
./include/lightning.h:204:12: warning: pointer is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified) [-Wnullability-completeness]
uint8_t *data;
^
./include/lightning.h:204:12: note: insert '_Nullable' if the pointer may be null
uint8_t *data;
^
_Nullable ./include/lightning.h:204:12: note: insert '_Nonnull' if the pointer should never be null
uint8_t *data;
^
_Nonnull 

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heh, that's an OSX-ism, because gcc is just a symlink to clang...I'll add the warning disable on all the compile calls.

@TheBlueMatt
TheBlueMattforce-pushed the 2020-12-chanman-bindings-deser branch from c326bcb to d08bdf4CompareFebruary 3, 2021 00:55
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Addressed review comments, rebased to fix conflicts but no changes outside of bindings generation code.

We can fail to resolve a part of a tuple, resulting in a panic in
write_template_constructor even if we're calling
`understood_c_type` with the intent of figuring out whether we can
print a type at all. Instead, we should pipe errors back and let
`understood_c_type` return false as a result.
Previously, manual `*_read` implementations were only defined for
types with inner fields, which were set to NULL to indicate read
errors. This prevents exposing `*_read` for several other types,
including tuples (which are needed for `ChannelManager`/
`ChannelMonitors`) and enums (which includes `Event`s, though users
likely never need to call that directly). Further, this means we
don't expose the actual error enum (which is likely no big deal,
but is still nice).
Here, we instead create the `Result<Object, DecodeError>` type and
then pass it through the normal type conversion functions, giving
us access to any types which we can convert normally.
This expands the manual implementation logic for `*_write` and
`*_read` methods to most types, converting the `*_write` path to
the common type-conversion logic to ensure it works.
Note that `*_write_void` is still only implemented for has-inner
types, as its unclear what the `void*` would point to for others.
It just stubs out to `write_rust_path` in this case anyway, which
handles leading-colons just fine, so no need to panic on them.
This is most of the code to expose `ChannelManager`/`ChannelMonitor`
deserialization in our C bindings, using the new infrastructure to
map types in `maybe_convert_trait_impl` and passing generics in
from the callsites.
We also call `maybe_convert_trait_impl` for tuple types, as the
`ChannelManager`/`ChannelMonitor` deserialization returns a
`(BlockHash, T)` to indicate the block hash at which users need to
start resyncing the chain.
The final step to expose them is in the next commit.
This (finally) exposes `ChannelManager`/`ChannelMonitor` _write
methods, which were (needlessly) excluded as the structs themselves
have generic parameters. Sadly, we also now need to parse
`(C-not exported)` doc comments on impl blocks as we otherwise try
to expose _write methods for `&Vec<RouteHop>`, which doesn't work
(and isn't particularly interesting for users anyway). We add such
doc comments there.
This adds a new annotation for objects we take by reference in the
C header indicating the pointers must not be null. We have to
disable some warning clang now dumps that we haven't annotated all
pointers, as cbindgen is not yet able to add a nullable annotation.
Previously, references and pointers ended up identical in C, so
there was little reason to differentiate. With the addition of
nullability annotations, there is a (very slight) reason to prefer
references, so use them in a few places where its a trivial change.
This adds a move-assignment operator (`A& operator=(A&& o)`) to our
C++ wrapper classes as well as requiring an rvalue for the move
auto-convert operator (`operator CStruct()() &&`).
The second makes the C++ wrapper classes much easier to work with
by requiring an explicit `std::move` when the bindings will
automatically move a C++-wrapper object into a C object.
This demonstrates (and tests) the newly-exposed `ChannelManager`
de/serialization functions. Best revewied with -b --color-moved.
There were two issues on OSX - we need to give gcc the clang
warnings flags because `gcc` *is* clang on OSX and we missed an
`-std=c++11` on one of the clang++ calls, causing compile failures.
@TheBlueMatt
TheBlueMattforce-pushed the 2020-12-chanman-bindings-deser branch from d08bdf4 to 5d045deCompareFebruary 3, 2021 15:12
@TheBlueMatt

TheBlueMatt commented Feb 3, 2021

Copy link
Copy Markdown
CollaboratorAuthor

Rebased with no changes (git diff-tree d08bdf44 5d045de8 is empty) - only dropped intermediate binidings updates and rebased on upstream (including 767 merge).

@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Its just bindings, worth merging without more than one ack.

@TheBlueMatt
TheBlueMatt merged commit e4b516d into lightningdevkit:mainFeb 3, 2021
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@TheBlueMatt@jkczyz
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Expose ChannelManager/Monitor read methods in bindings by TheBlueMatt · Pull Request #768 · lightningdevkit/rust-lightning · GitHub
Skip to content

Expose ChannelManager/Monitor read methods in bindings - #768

Merged
TheBlueMatt merged 13 commits into
lightningdevkit:mainfrom
TheBlueMatt:2020-12-chanman-bindings-deser
Feb 3, 2021
Merged

Expose ChannelManager/Monitor read methods in bindings#768
TheBlueMatt merged 13 commits into
lightningdevkit:mainfrom
TheBlueMatt:2020-12-chanman-bindings-deser

Conversation

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Based on #767 (and #761), this finally exposes ChannelManager read methods that were missed in the early bindings work. There's also a few nice cleanups of the C++ wrappers, though they are code-wise trivial. As with #767, between each bindings builder update the changes to the bindings are committed, though those commits may be squashed before merge.

@codecov

codecovBot commented Dec 31, 2020

Copy link
Copy Markdown

Codecov Report

Merging #768 (a4f5bf3) into main (c7ddcd3) will decrease coverage by 0.00%.
The diff coverage is n/a.

Impacted file tree graph

@@ Coverage Diff @@## main #768 +/- ##
==========================================
- Coverage 90.79% 90.78% -0.01% 
==========================================
Files 38 38 Lines 23168 23168 ==========================================
- Hits 21036 21034 -2 - Misses 2132 2134 +2 
Impacted FilesCoverage Δ
lightning/src/ln/chan_utils.rs97.33% <ø> (ø)
lightning/src/routing/router.rs95.57% <ø> (ø)
lightning/src/ln/functional_tests.rs96.96% <0.00%> (-0.04%)⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c7ddcd3...5d045de. Read the comment docs.

@TheBlueMatt
TheBlueMattforce-pushed the 2020-12-chanman-bindings-deser branch from 748542d to c326bcbCompareJanuary 1, 2021 01:46

@jkczyzjkczyz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm getting some compilation warnings and errors likely related to c++11 not being specified somewhere:

++ which valgrind
+ '[' -x '' ']'
+ echo 'WARNING: Please install valgrind for more testing'
WARNING: Please install valgrind for more testing
+ CLANGOPTS='-Wall -Wno-nullability-completeness -pthread'
+ clang++ -Wall -Wno-nullability-completeness -pthread demo.cpp target/debug/libldk.a -ldl
In file included from demo.cpp:5:
./include/lightningpp.hpp:7:24: warning: deleted function definitions are a C++11 extension [-Wc++11-extensions]
Event(const Event&) = delete;
^
./include/lightningpp.hpp:8:13: warning: rvalue references are a C++11 extension [-Wc++11-extensions]
Event(Event&& o) : self(o.self) { memset(&o, 0, sizeof(Event)); }
^
./include/lightningpp.hpp:9:16: warning: rvalue references are a C++11 extension [-Wc++11-extensions]
Event(LDKEvent&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKEvent)); }
^
./include/lightningpp.hpp:10:22: warning: reference qualifiers on functions are a C++11 extension [-Wc++11-extensions]
operator LDKEvent() && { LDKEvent res = self; memset(&self, 0, sizeof(LDKEvent)); return res; }
^
./include/lightningpp.hpp:12:24: warning: rvalue references are a C++11 extension [-Wc++11-extensions]
Event& operator=(Event&& o) { Event_free(self); self = o.self; memset(&o, 0, sizeof(Event)); return *this; }
^

...

demo.cpp:119:23: error: default initialization of an object of const type 'const LDKFeeEstimator' without a user-provided default constructor
const LDKFeeEstimator fee_est {
^
= {}
demo.cpp:119:30: error: expected ';' after top level declarator
const LDKFeeEstimator fee_est {
^
;
demo.cpp:134:58: error: a space is required between consecutive right angle brackets (use '> >')
std::vector<std::pair<LDK::OutPoint, LDK::ChannelMonitor>> mons;
^~
> >
demo.cpp:139:8: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
for (auto& mon : mons) {
^
demo.cpp:139:18: warning: range-based for loop is a C++11 extension [-Wc++11-extensions]
for (auto& mon : mons) {
^
demo.cpp:147:22: error: no matching constructor for initialization of 'LDK::ChannelMonitor'
LDK::ChannelMonitor mon(std::move(monitor_arg));
^ ~~~~~~~~~~~~~~~~~~~~~~
./include/lightningpp.hpp:304:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitor' to 'const LDK::ChannelMonitor' for 1st argument
ChannelMonitor(const ChannelMonitor&) = delete;
^
./include/lightningpp.hpp:305:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitor' to 'LDK::ChannelMonitor' for 1st argument
ChannelMonitor(ChannelMonitor&& o) : self(o.self) { memset(&o, 0, sizeof(ChannelMonitor)); }
^
./include/lightningpp.hpp:306:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitor' to 'LDKChannelMonitor &&' for 1st argument
ChannelMonitor(LDKChannelMonitor&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKChannelMonitor)); }
^
demo.cpp:148:16: error: no matching constructor for initialization of 'LDK::OutPoint'
LDK::OutPoint funding_txo(std::move(funding_txo_arg));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~
./include/lightningpp.hpp:334:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'const LDK::OutPoint' for 1st argument
OutPoint(const OutPoint&) = delete;
^
./include/lightningpp.hpp:335:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'LDK::OutPoint' for 1st argument
OutPoint(OutPoint&& o) : self(o.self) { memset(&o, 0, sizeof(OutPoint)); }
^
./include/lightningpp.hpp:336:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'LDKOutPoint &&' for 1st argument
OutPoint(LDKOutPoint&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKOutPoint)); }
^
demo.cpp:159:28: error: no matching constructor for initialization of 'LDK::ChannelMonitorUpdate'
LDK::ChannelMonitorUpdate update(std::move(monitor_arg));
^ ~~~~~~~~~~~~~~~~~~~~~~
./include/lightningpp.hpp:230:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitorUpdate' to 'const LDK::ChannelMonitorUpdate' for 1st argument
ChannelMonitorUpdate(const ChannelMonitorUpdate&) = delete;
^
./include/lightningpp.hpp:231:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitorUpdate' to 'LDK::ChannelMonitorUpdate' for 1st argument
ChannelMonitorUpdate(ChannelMonitorUpdate&& o) : self(o.self) { memset(&o, 0, sizeof(ChannelMonitorUpdate)); }
^
./include/lightningpp.hpp:232:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitorUpdate' to 'LDKChannelMonitorUpdate &&' for 1st argument
ChannelMonitorUpdate(LDKChannelMonitorUpdate&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKChannelMonitorUpdate)); }
^
demo.cpp:160:16: error: no matching constructor for initialization of 'LDK::OutPoint'
LDK::OutPoint funding_txo(std::move(funding_txo_arg));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~
./include/lightningpp.hpp:334:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'const LDK::OutPoint' for 1st argument
OutPoint(const OutPoint&) = delete;
^
./include/lightningpp.hpp:335:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'LDK::OutPoint' for 1st argument
OutPoint(OutPoint&& o) : self(o.self) { memset(&o, 0, sizeof(OutPoint)); }
^
./include/lightningpp.hpp:336:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'LDKOutPoint &&' for 1st argument
OutPoint(LDKOutPoint&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKOutPoint)); }
^
demo.cpp:166:7: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
for (auto& mon : arg->mons) {
^
demo.cpp:166:17: warning: range-based for loop is a C++11 extension [-Wc++11-extensions]
for (auto& mon : arg->mons) {
^
demo.cpp:187:32: error: expected '(' for function-style cast or type construction
return LDKCVec_MonitorEventZ {
~~~~~~~~~~~~~~~~~~~~~ ^
demo.cpp:239:31: error: expected '(' for function-style cast or type construction
sock1 = LDKSocketDescriptor {
~~~~~~~~~~~~~~~~~~~ ^
demo.cpp:249:31: error: expected '(' for function-style cast or type construction
sock2 = LDKSocketDescriptor {
~~~~~~~~~~~~~~~~~~~ ^
demo.cpp:259:8: error: no matching constructor for initialization of 'std::thread'
t1 = std::thread(&sock_read_data_thread, pipefds_2_to_1[0], &sock1, &net1);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:408:9: note: candidate constructor template not viable: requires single argument '__f', but 4 arguments were provided
thread::thread(_Fp __f)
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:289:5: note: candidate constructor not viable: requires 1 argument, but 4 were provided
thread(const thread&);
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:296:5: note: candidate constructor not viable: requires 0 arguments, but 4 were provided
thread() _NOEXCEPT : __t_(_LIBCPP_NULL_THREAD) {}
^
demo.cpp:260:8: error: no matching constructor for initialization of 'std::thread'
t2 = std::thread(&sock_read_data_thread, pipefds_1_to_2[0], &sock2, &net2);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:408:9: note: candidate constructor template not viable: requires single argument '__f', but 4 arguments were provided
thread::thread(_Fp __f)
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:289:5: note: candidate constructor not viable: requires 1 argument, but 4 were provided
thread(const thread&);
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:296:5: note: candidate constructor not viable: requires 0 arguments, but 4 were provided
thread() _NOEXCEPT : __t_(_LIBCPP_NULL_THREAD) {}
^
demo.cpp:268:3: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
auto writelen = write(pipefds_1_to_2[1], con_res->contents.result->data, con_res->contents.result->datalen);
^
demo.cpp:299:35: error: expected ';' at end of declaration
LDKBroadcasterInterface broadcast {
^
;
demo.cpp:306:19: error: expected ';' at end of declaration
LDKLogger logger1 {
^
;
demo.cpp:314:15: error: expected ';' at end of declaration
LDKWatch mon1 {
^
;
demo.cpp:325:19: error: expected ';' at end of declaration
LDKLogger logger2 {
^
;
demo.cpp:333:15: error: expected ';' at end of declaration
LDKWatch mon2 {
^
;
demo.cpp:344:38: error: expected '(' for function-style cast or type construction
LDK::CVec_u8Z cm1_ser = LDKCVec_u8Z {}; // ChannelManager 1 serialization at the end of the ser-des scope
~~~~~~~~~~~ ^
demo.cpp:345:38: error: expected '(' for function-style cast or type construction
LDK::CVec_u8Z cm2_ser = LDKCVec_u8Z {}; // ChannelManager 2 serialization at the end of the ser-des scope
~~~~~~~~~~~ ^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
900 warnings and 20 errors generated.

}
pub extern "C" fn ChannelMonitorUpdate_read(ser: crate::c_types::u8slice) -> crate::c_types::derived::CResult_ChannelMonitorUpdateDecodeErrorZ {
let res = crate::c_types::deserialize_obj(ser);
let mut local_res = match res { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::chain::channelmonitor::ChannelMonitorUpdate { inner: Box::into_raw(Box::new(o)), is_owned: true } }), Err(mut e) => crate::c_types::CResultTempl::err( { crate::ln::msgs::DecodeError { inner: Box::into_raw(Box::new(e)), is_owned: true } }) };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was having no line breaks here intentional?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a number of similar cases across the bindings, especially for template types (vec/result/tuples) - specifically we don't track at what level of indentation we are at that deep into type conversion, so we either have bogus indentation or no indentation. For now its none, but its something we should fix eventually.

Comment threadc-bindings-gen/src/main.rs Outdated
Comment threadc-bindings-gen/src/main.rs
Comment threadgenbindings.sh Outdated
echo "WARNING: Please install valgrind for more testing"
fi

CLANGOPTS="-Wall -Wno-nullability-completeness -pthread"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm seeing a ton of warnings looking to originate from this commit:

++ rustc --version --verbose
++ grep host:
+ HOST_PLATFORM='host: x86_64-apple-darwin'
+ '[' 'host: x86_64-apple-darwin' = 'host: x86_64-apple-darwin' ']'
+ sed -i '' 's/typedef LDKnative.*Import.*LDKnative.*;//g' include/lightning.h
+ gcc -Wall -g -pthread demo.c target/debug/libldk.a -ldl
In file included from demo.c:2:
./include/lightning.h:204:12: warning: pointer is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified) [-Wnullability-completeness]
uint8_t *data;
^
./include/lightning.h:204:12: note: insert '_Nullable' if the pointer may be null
uint8_t *data;
^
_Nullable ./include/lightning.h:204:12: note: insert '_Nonnull' if the pointer should never be null
uint8_t *data;
^
_Nonnull 

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heh, that's an OSX-ism, because gcc is just a symlink to clang...I'll add the warning disable on all the compile calls.

@TheBlueMatt
TheBlueMattforce-pushed the 2020-12-chanman-bindings-deser branch from c326bcb to d08bdf4CompareFebruary 3, 2021 00:55
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Addressed review comments, rebased to fix conflicts but no changes outside of bindings generation code.

We can fail to resolve a part of a tuple, resulting in a panic in
write_template_constructor even if we're calling
`understood_c_type` with the intent of figuring out whether we can
print a type at all. Instead, we should pipe errors back and let
`understood_c_type` return false as a result.
Previously, manual `*_read` implementations were only defined for
types with inner fields, which were set to NULL to indicate read
errors. This prevents exposing `*_read` for several other types,
including tuples (which are needed for `ChannelManager`/
`ChannelMonitors`) and enums (which includes `Event`s, though users
likely never need to call that directly). Further, this means we
don't expose the actual error enum (which is likely no big deal,
but is still nice).
Here, we instead create the `Result<Object, DecodeError>` type and
then pass it through the normal type conversion functions, giving
us access to any types which we can convert normally.
This expands the manual implementation logic for `*_write` and
`*_read` methods to most types, converting the `*_write` path to
the common type-conversion logic to ensure it works.
Note that `*_write_void` is still only implemented for has-inner
types, as its unclear what the `void*` would point to for others.
It just stubs out to `write_rust_path` in this case anyway, which
handles leading-colons just fine, so no need to panic on them.
This is most of the code to expose `ChannelManager`/`ChannelMonitor`
deserialization in our C bindings, using the new infrastructure to
map types in `maybe_convert_trait_impl` and passing generics in
from the callsites.
We also call `maybe_convert_trait_impl` for tuple types, as the
`ChannelManager`/`ChannelMonitor` deserialization returns a
`(BlockHash, T)` to indicate the block hash at which users need to
start resyncing the chain.
The final step to expose them is in the next commit.
This (finally) exposes `ChannelManager`/`ChannelMonitor` _write
methods, which were (needlessly) excluded as the structs themselves
have generic parameters. Sadly, we also now need to parse
`(C-not exported)` doc comments on impl blocks as we otherwise try
to expose _write methods for `&Vec<RouteHop>`, which doesn't work
(and isn't particularly interesting for users anyway). We add such
doc comments there.
This adds a new annotation for objects we take by reference in the
C header indicating the pointers must not be null. We have to
disable some warning clang now dumps that we haven't annotated all
pointers, as cbindgen is not yet able to add a nullable annotation.
Previously, references and pointers ended up identical in C, so
there was little reason to differentiate. With the addition of
nullability annotations, there is a (very slight) reason to prefer
references, so use them in a few places where its a trivial change.
This adds a move-assignment operator (`A& operator=(A&& o)`) to our
C++ wrapper classes as well as requiring an rvalue for the move
auto-convert operator (`operator CStruct()() &&`).
The second makes the C++ wrapper classes much easier to work with
by requiring an explicit `std::move` when the bindings will
automatically move a C++-wrapper object into a C object.
This demonstrates (and tests) the newly-exposed `ChannelManager`
de/serialization functions. Best revewied with -b --color-moved.
There were two issues on OSX - we need to give gcc the clang
warnings flags because `gcc` *is* clang on OSX and we missed an
`-std=c++11` on one of the clang++ calls, causing compile failures.
@TheBlueMatt
TheBlueMattforce-pushed the 2020-12-chanman-bindings-deser branch from d08bdf4 to 5d045deCompareFebruary 3, 2021 15:12
@TheBlueMatt

TheBlueMatt commented Feb 3, 2021

Copy link
Copy Markdown
CollaboratorAuthor

Rebased with no changes (git diff-tree d08bdf44 5d045de8 is empty) - only dropped intermediate binidings updates and rebased on upstream (including 767 merge).

@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Its just bindings, worth merging without more than one ack.

@TheBlueMatt
TheBlueMatt merged commit e4b516d into lightningdevkit:mainFeb 3, 2021
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@TheBlueMatt@jkczyz
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Expose ChannelManager/Monitor read methods in bindings by TheBlueMatt · Pull Request #768 · lightningdevkit/rust-lightning · GitHub
Skip to content

Expose ChannelManager/Monitor read methods in bindings - #768

Merged
TheBlueMatt merged 13 commits into
lightningdevkit:mainfrom
TheBlueMatt:2020-12-chanman-bindings-deser
Feb 3, 2021
Merged

Expose ChannelManager/Monitor read methods in bindings#768
TheBlueMatt merged 13 commits into
lightningdevkit:mainfrom
TheBlueMatt:2020-12-chanman-bindings-deser

Conversation

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Based on #767 (and #761), this finally exposes ChannelManager read methods that were missed in the early bindings work. There's also a few nice cleanups of the C++ wrappers, though they are code-wise trivial. As with #767, between each bindings builder update the changes to the bindings are committed, though those commits may be squashed before merge.

@codecov

codecovBot commented Dec 31, 2020

Copy link
Copy Markdown

Codecov Report

Merging #768 (a4f5bf3) into main (c7ddcd3) will decrease coverage by 0.00%.
The diff coverage is n/a.

Impacted file tree graph

@@ Coverage Diff @@## main #768 +/- ##
==========================================
- Coverage 90.79% 90.78% -0.01% 
==========================================
Files 38 38 Lines 23168 23168 ==========================================
- Hits 21036 21034 -2 - Misses 2132 2134 +2 
Impacted FilesCoverage Δ
lightning/src/ln/chan_utils.rs97.33% <ø> (ø)
lightning/src/routing/router.rs95.57% <ø> (ø)
lightning/src/ln/functional_tests.rs96.96% <0.00%> (-0.04%)⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c7ddcd3...5d045de. Read the comment docs.

@TheBlueMatt
TheBlueMattforce-pushed the 2020-12-chanman-bindings-deser branch from 748542d to c326bcbCompareJanuary 1, 2021 01:46

@jkczyzjkczyz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm getting some compilation warnings and errors likely related to c++11 not being specified somewhere:

++ which valgrind
+ '[' -x '' ']'
+ echo 'WARNING: Please install valgrind for more testing'
WARNING: Please install valgrind for more testing
+ CLANGOPTS='-Wall -Wno-nullability-completeness -pthread'
+ clang++ -Wall -Wno-nullability-completeness -pthread demo.cpp target/debug/libldk.a -ldl
In file included from demo.cpp:5:
./include/lightningpp.hpp:7:24: warning: deleted function definitions are a C++11 extension [-Wc++11-extensions]
Event(const Event&) = delete;
^
./include/lightningpp.hpp:8:13: warning: rvalue references are a C++11 extension [-Wc++11-extensions]
Event(Event&& o) : self(o.self) { memset(&o, 0, sizeof(Event)); }
^
./include/lightningpp.hpp:9:16: warning: rvalue references are a C++11 extension [-Wc++11-extensions]
Event(LDKEvent&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKEvent)); }
^
./include/lightningpp.hpp:10:22: warning: reference qualifiers on functions are a C++11 extension [-Wc++11-extensions]
operator LDKEvent() && { LDKEvent res = self; memset(&self, 0, sizeof(LDKEvent)); return res; }
^
./include/lightningpp.hpp:12:24: warning: rvalue references are a C++11 extension [-Wc++11-extensions]
Event& operator=(Event&& o) { Event_free(self); self = o.self; memset(&o, 0, sizeof(Event)); return *this; }
^

...

demo.cpp:119:23: error: default initialization of an object of const type 'const LDKFeeEstimator' without a user-provided default constructor
const LDKFeeEstimator fee_est {
^
= {}
demo.cpp:119:30: error: expected ';' after top level declarator
const LDKFeeEstimator fee_est {
^
;
demo.cpp:134:58: error: a space is required between consecutive right angle brackets (use '> >')
std::vector<std::pair<LDK::OutPoint, LDK::ChannelMonitor>> mons;
^~
> >
demo.cpp:139:8: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
for (auto& mon : mons) {
^
demo.cpp:139:18: warning: range-based for loop is a C++11 extension [-Wc++11-extensions]
for (auto& mon : mons) {
^
demo.cpp:147:22: error: no matching constructor for initialization of 'LDK::ChannelMonitor'
LDK::ChannelMonitor mon(std::move(monitor_arg));
^ ~~~~~~~~~~~~~~~~~~~~~~
./include/lightningpp.hpp:304:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitor' to 'const LDK::ChannelMonitor' for 1st argument
ChannelMonitor(const ChannelMonitor&) = delete;
^
./include/lightningpp.hpp:305:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitor' to 'LDK::ChannelMonitor' for 1st argument
ChannelMonitor(ChannelMonitor&& o) : self(o.self) { memset(&o, 0, sizeof(ChannelMonitor)); }
^
./include/lightningpp.hpp:306:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitor' to 'LDKChannelMonitor &&' for 1st argument
ChannelMonitor(LDKChannelMonitor&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKChannelMonitor)); }
^
demo.cpp:148:16: error: no matching constructor for initialization of 'LDK::OutPoint'
LDK::OutPoint funding_txo(std::move(funding_txo_arg));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~
./include/lightningpp.hpp:334:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'const LDK::OutPoint' for 1st argument
OutPoint(const OutPoint&) = delete;
^
./include/lightningpp.hpp:335:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'LDK::OutPoint' for 1st argument
OutPoint(OutPoint&& o) : self(o.self) { memset(&o, 0, sizeof(OutPoint)); }
^
./include/lightningpp.hpp:336:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'LDKOutPoint &&' for 1st argument
OutPoint(LDKOutPoint&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKOutPoint)); }
^
demo.cpp:159:28: error: no matching constructor for initialization of 'LDK::ChannelMonitorUpdate'
LDK::ChannelMonitorUpdate update(std::move(monitor_arg));
^ ~~~~~~~~~~~~~~~~~~~~~~
./include/lightningpp.hpp:230:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitorUpdate' to 'const LDK::ChannelMonitorUpdate' for 1st argument
ChannelMonitorUpdate(const ChannelMonitorUpdate&) = delete;
^
./include/lightningpp.hpp:231:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitorUpdate' to 'LDK::ChannelMonitorUpdate' for 1st argument
ChannelMonitorUpdate(ChannelMonitorUpdate&& o) : self(o.self) { memset(&o, 0, sizeof(ChannelMonitorUpdate)); }
^
./include/lightningpp.hpp:232:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitorUpdate' to 'LDKChannelMonitorUpdate &&' for 1st argument
ChannelMonitorUpdate(LDKChannelMonitorUpdate&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKChannelMonitorUpdate)); }
^
demo.cpp:160:16: error: no matching constructor for initialization of 'LDK::OutPoint'
LDK::OutPoint funding_txo(std::move(funding_txo_arg));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~
./include/lightningpp.hpp:334:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'const LDK::OutPoint' for 1st argument
OutPoint(const OutPoint&) = delete;
^
./include/lightningpp.hpp:335:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'LDK::OutPoint' for 1st argument
OutPoint(OutPoint&& o) : self(o.self) { memset(&o, 0, sizeof(OutPoint)); }
^
./include/lightningpp.hpp:336:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'LDKOutPoint &&' for 1st argument
OutPoint(LDKOutPoint&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKOutPoint)); }
^
demo.cpp:166:7: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
for (auto& mon : arg->mons) {
^
demo.cpp:166:17: warning: range-based for loop is a C++11 extension [-Wc++11-extensions]
for (auto& mon : arg->mons) {
^
demo.cpp:187:32: error: expected '(' for function-style cast or type construction
return LDKCVec_MonitorEventZ {
~~~~~~~~~~~~~~~~~~~~~ ^
demo.cpp:239:31: error: expected '(' for function-style cast or type construction
sock1 = LDKSocketDescriptor {
~~~~~~~~~~~~~~~~~~~ ^
demo.cpp:249:31: error: expected '(' for function-style cast or type construction
sock2 = LDKSocketDescriptor {
~~~~~~~~~~~~~~~~~~~ ^
demo.cpp:259:8: error: no matching constructor for initialization of 'std::thread'
t1 = std::thread(&sock_read_data_thread, pipefds_2_to_1[0], &sock1, &net1);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:408:9: note: candidate constructor template not viable: requires single argument '__f', but 4 arguments were provided
thread::thread(_Fp __f)
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:289:5: note: candidate constructor not viable: requires 1 argument, but 4 were provided
thread(const thread&);
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:296:5: note: candidate constructor not viable: requires 0 arguments, but 4 were provided
thread() _NOEXCEPT : __t_(_LIBCPP_NULL_THREAD) {}
^
demo.cpp:260:8: error: no matching constructor for initialization of 'std::thread'
t2 = std::thread(&sock_read_data_thread, pipefds_1_to_2[0], &sock2, &net2);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:408:9: note: candidate constructor template not viable: requires single argument '__f', but 4 arguments were provided
thread::thread(_Fp __f)
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:289:5: note: candidate constructor not viable: requires 1 argument, but 4 were provided
thread(const thread&);
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:296:5: note: candidate constructor not viable: requires 0 arguments, but 4 were provided
thread() _NOEXCEPT : __t_(_LIBCPP_NULL_THREAD) {}
^
demo.cpp:268:3: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
auto writelen = write(pipefds_1_to_2[1], con_res->contents.result->data, con_res->contents.result->datalen);
^
demo.cpp:299:35: error: expected ';' at end of declaration
LDKBroadcasterInterface broadcast {
^
;
demo.cpp:306:19: error: expected ';' at end of declaration
LDKLogger logger1 {
^
;
demo.cpp:314:15: error: expected ';' at end of declaration
LDKWatch mon1 {
^
;
demo.cpp:325:19: error: expected ';' at end of declaration
LDKLogger logger2 {
^
;
demo.cpp:333:15: error: expected ';' at end of declaration
LDKWatch mon2 {
^
;
demo.cpp:344:38: error: expected '(' for function-style cast or type construction
LDK::CVec_u8Z cm1_ser = LDKCVec_u8Z {}; // ChannelManager 1 serialization at the end of the ser-des scope
~~~~~~~~~~~ ^
demo.cpp:345:38: error: expected '(' for function-style cast or type construction
LDK::CVec_u8Z cm2_ser = LDKCVec_u8Z {}; // ChannelManager 2 serialization at the end of the ser-des scope
~~~~~~~~~~~ ^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
900 warnings and 20 errors generated.

}
pub extern "C" fn ChannelMonitorUpdate_read(ser: crate::c_types::u8slice) -> crate::c_types::derived::CResult_ChannelMonitorUpdateDecodeErrorZ {
let res = crate::c_types::deserialize_obj(ser);
let mut local_res = match res { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::chain::channelmonitor::ChannelMonitorUpdate { inner: Box::into_raw(Box::new(o)), is_owned: true } }), Err(mut e) => crate::c_types::CResultTempl::err( { crate::ln::msgs::DecodeError { inner: Box::into_raw(Box::new(e)), is_owned: true } }) };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was having no line breaks here intentional?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a number of similar cases across the bindings, especially for template types (vec/result/tuples) - specifically we don't track at what level of indentation we are at that deep into type conversion, so we either have bogus indentation or no indentation. For now its none, but its something we should fix eventually.

Comment threadc-bindings-gen/src/main.rs Outdated
Comment threadc-bindings-gen/src/main.rs
Comment threadgenbindings.sh Outdated
echo "WARNING: Please install valgrind for more testing"
fi

CLANGOPTS="-Wall -Wno-nullability-completeness -pthread"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm seeing a ton of warnings looking to originate from this commit:

++ rustc --version --verbose
++ grep host:
+ HOST_PLATFORM='host: x86_64-apple-darwin'
+ '[' 'host: x86_64-apple-darwin' = 'host: x86_64-apple-darwin' ']'
+ sed -i '' 's/typedef LDKnative.*Import.*LDKnative.*;//g' include/lightning.h
+ gcc -Wall -g -pthread demo.c target/debug/libldk.a -ldl
In file included from demo.c:2:
./include/lightning.h:204:12: warning: pointer is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified) [-Wnullability-completeness]
uint8_t *data;
^
./include/lightning.h:204:12: note: insert '_Nullable' if the pointer may be null
uint8_t *data;
^
_Nullable ./include/lightning.h:204:12: note: insert '_Nonnull' if the pointer should never be null
uint8_t *data;
^
_Nonnull 

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heh, that's an OSX-ism, because gcc is just a symlink to clang...I'll add the warning disable on all the compile calls.

@TheBlueMatt
TheBlueMattforce-pushed the 2020-12-chanman-bindings-deser branch from c326bcb to d08bdf4CompareFebruary 3, 2021 00:55
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Addressed review comments, rebased to fix conflicts but no changes outside of bindings generation code.

We can fail to resolve a part of a tuple, resulting in a panic in
write_template_constructor even if we're calling
`understood_c_type` with the intent of figuring out whether we can
print a type at all. Instead, we should pipe errors back and let
`understood_c_type` return false as a result.
Previously, manual `*_read` implementations were only defined for
types with inner fields, which were set to NULL to indicate read
errors. This prevents exposing `*_read` for several other types,
including tuples (which are needed for `ChannelManager`/
`ChannelMonitors`) and enums (which includes `Event`s, though users
likely never need to call that directly). Further, this means we
don't expose the actual error enum (which is likely no big deal,
but is still nice).
Here, we instead create the `Result<Object, DecodeError>` type and
then pass it through the normal type conversion functions, giving
us access to any types which we can convert normally.
This expands the manual implementation logic for `*_write` and
`*_read` methods to most types, converting the `*_write` path to
the common type-conversion logic to ensure it works.
Note that `*_write_void` is still only implemented for has-inner
types, as its unclear what the `void*` would point to for others.
It just stubs out to `write_rust_path` in this case anyway, which
handles leading-colons just fine, so no need to panic on them.
This is most of the code to expose `ChannelManager`/`ChannelMonitor`
deserialization in our C bindings, using the new infrastructure to
map types in `maybe_convert_trait_impl` and passing generics in
from the callsites.
We also call `maybe_convert_trait_impl` for tuple types, as the
`ChannelManager`/`ChannelMonitor` deserialization returns a
`(BlockHash, T)` to indicate the block hash at which users need to
start resyncing the chain.
The final step to expose them is in the next commit.
This (finally) exposes `ChannelManager`/`ChannelMonitor` _write
methods, which were (needlessly) excluded as the structs themselves
have generic parameters. Sadly, we also now need to parse
`(C-not exported)` doc comments on impl blocks as we otherwise try
to expose _write methods for `&Vec<RouteHop>`, which doesn't work
(and isn't particularly interesting for users anyway). We add such
doc comments there.
This adds a new annotation for objects we take by reference in the
C header indicating the pointers must not be null. We have to
disable some warning clang now dumps that we haven't annotated all
pointers, as cbindgen is not yet able to add a nullable annotation.
Previously, references and pointers ended up identical in C, so
there was little reason to differentiate. With the addition of
nullability annotations, there is a (very slight) reason to prefer
references, so use them in a few places where its a trivial change.
This adds a move-assignment operator (`A& operator=(A&& o)`) to our
C++ wrapper classes as well as requiring an rvalue for the move
auto-convert operator (`operator CStruct()() &&`).
The second makes the C++ wrapper classes much easier to work with
by requiring an explicit `std::move` when the bindings will
automatically move a C++-wrapper object into a C object.
This demonstrates (and tests) the newly-exposed `ChannelManager`
de/serialization functions. Best revewied with -b --color-moved.
There were two issues on OSX - we need to give gcc the clang
warnings flags because `gcc` *is* clang on OSX and we missed an
`-std=c++11` on one of the clang++ calls, causing compile failures.
@TheBlueMatt
TheBlueMattforce-pushed the 2020-12-chanman-bindings-deser branch from d08bdf4 to 5d045deCompareFebruary 3, 2021 15:12
@TheBlueMatt

TheBlueMatt commented Feb 3, 2021

Copy link
Copy Markdown
CollaboratorAuthor

Rebased with no changes (git diff-tree d08bdf44 5d045de8 is empty) - only dropped intermediate binidings updates and rebased on upstream (including 767 merge).

@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Its just bindings, worth merging without more than one ack.

@TheBlueMatt
TheBlueMatt merged commit e4b516d into lightningdevkit:mainFeb 3, 2021
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@TheBlueMatt@jkczyz
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); Expose ChannelManager/Monitor read methods in bindings by TheBlueMatt · Pull Request #768 · lightningdevkit/rust-lightning · GitHub
Skip to content

Expose ChannelManager/Monitor read methods in bindings - #768

Merged
TheBlueMatt merged 13 commits into
lightningdevkit:mainfrom
TheBlueMatt:2020-12-chanman-bindings-deser
Feb 3, 2021
Merged

Expose ChannelManager/Monitor read methods in bindings#768
TheBlueMatt merged 13 commits into
lightningdevkit:mainfrom
TheBlueMatt:2020-12-chanman-bindings-deser

Conversation

@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Based on #767 (and #761), this finally exposes ChannelManager read methods that were missed in the early bindings work. There's also a few nice cleanups of the C++ wrappers, though they are code-wise trivial. As with #767, between each bindings builder update the changes to the bindings are committed, though those commits may be squashed before merge.

@codecov

codecovBot commented Dec 31, 2020

Copy link
Copy Markdown

Codecov Report

Merging #768 (a4f5bf3) into main (c7ddcd3) will decrease coverage by 0.00%.
The diff coverage is n/a.

Impacted file tree graph

@@ Coverage Diff @@## main #768 +/- ##
==========================================
- Coverage 90.79% 90.78% -0.01% 
==========================================
Files 38 38 Lines 23168 23168 ==========================================
- Hits 21036 21034 -2 - Misses 2132 2134 +2 
Impacted FilesCoverage Δ
lightning/src/ln/chan_utils.rs97.33% <ø> (ø)
lightning/src/routing/router.rs95.57% <ø> (ø)
lightning/src/ln/functional_tests.rs96.96% <0.00%> (-0.04%)⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c7ddcd3...5d045de. Read the comment docs.

@TheBlueMatt
TheBlueMattforce-pushed the 2020-12-chanman-bindings-deser branch from 748542d to c326bcbCompareJanuary 1, 2021 01:46

@jkczyzjkczyz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm getting some compilation warnings and errors likely related to c++11 not being specified somewhere:

++ which valgrind
+ '[' -x '' ']'
+ echo 'WARNING: Please install valgrind for more testing'
WARNING: Please install valgrind for more testing
+ CLANGOPTS='-Wall -Wno-nullability-completeness -pthread'
+ clang++ -Wall -Wno-nullability-completeness -pthread demo.cpp target/debug/libldk.a -ldl
In file included from demo.cpp:5:
./include/lightningpp.hpp:7:24: warning: deleted function definitions are a C++11 extension [-Wc++11-extensions]
Event(const Event&) = delete;
^
./include/lightningpp.hpp:8:13: warning: rvalue references are a C++11 extension [-Wc++11-extensions]
Event(Event&& o) : self(o.self) { memset(&o, 0, sizeof(Event)); }
^
./include/lightningpp.hpp:9:16: warning: rvalue references are a C++11 extension [-Wc++11-extensions]
Event(LDKEvent&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKEvent)); }
^
./include/lightningpp.hpp:10:22: warning: reference qualifiers on functions are a C++11 extension [-Wc++11-extensions]
operator LDKEvent() && { LDKEvent res = self; memset(&self, 0, sizeof(LDKEvent)); return res; }
^
./include/lightningpp.hpp:12:24: warning: rvalue references are a C++11 extension [-Wc++11-extensions]
Event& operator=(Event&& o) { Event_free(self); self = o.self; memset(&o, 0, sizeof(Event)); return *this; }
^

...

demo.cpp:119:23: error: default initialization of an object of const type 'const LDKFeeEstimator' without a user-provided default constructor
const LDKFeeEstimator fee_est {
^
= {}
demo.cpp:119:30: error: expected ';' after top level declarator
const LDKFeeEstimator fee_est {
^
;
demo.cpp:134:58: error: a space is required between consecutive right angle brackets (use '> >')
std::vector<std::pair<LDK::OutPoint, LDK::ChannelMonitor>> mons;
^~
> >
demo.cpp:139:8: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
for (auto& mon : mons) {
^
demo.cpp:139:18: warning: range-based for loop is a C++11 extension [-Wc++11-extensions]
for (auto& mon : mons) {
^
demo.cpp:147:22: error: no matching constructor for initialization of 'LDK::ChannelMonitor'
LDK::ChannelMonitor mon(std::move(monitor_arg));
^ ~~~~~~~~~~~~~~~~~~~~~~
./include/lightningpp.hpp:304:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitor' to 'const LDK::ChannelMonitor' for 1st argument
ChannelMonitor(const ChannelMonitor&) = delete;
^
./include/lightningpp.hpp:305:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitor' to 'LDK::ChannelMonitor' for 1st argument
ChannelMonitor(ChannelMonitor&& o) : self(o.self) { memset(&o, 0, sizeof(ChannelMonitor)); }
^
./include/lightningpp.hpp:306:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitor' to 'LDKChannelMonitor &&' for 1st argument
ChannelMonitor(LDKChannelMonitor&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKChannelMonitor)); }
^
demo.cpp:148:16: error: no matching constructor for initialization of 'LDK::OutPoint'
LDK::OutPoint funding_txo(std::move(funding_txo_arg));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~
./include/lightningpp.hpp:334:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'const LDK::OutPoint' for 1st argument
OutPoint(const OutPoint&) = delete;
^
./include/lightningpp.hpp:335:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'LDK::OutPoint' for 1st argument
OutPoint(OutPoint&& o) : self(o.self) { memset(&o, 0, sizeof(OutPoint)); }
^
./include/lightningpp.hpp:336:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'LDKOutPoint &&' for 1st argument
OutPoint(LDKOutPoint&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKOutPoint)); }
^
demo.cpp:159:28: error: no matching constructor for initialization of 'LDK::ChannelMonitorUpdate'
LDK::ChannelMonitorUpdate update(std::move(monitor_arg));
^ ~~~~~~~~~~~~~~~~~~~~~~
./include/lightningpp.hpp:230:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitorUpdate' to 'const LDK::ChannelMonitorUpdate' for 1st argument
ChannelMonitorUpdate(const ChannelMonitorUpdate&) = delete;
^
./include/lightningpp.hpp:231:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitorUpdate' to 'LDK::ChannelMonitorUpdate' for 1st argument
ChannelMonitorUpdate(ChannelMonitorUpdate&& o) : self(o.self) { memset(&o, 0, sizeof(ChannelMonitorUpdate)); }
^
./include/lightningpp.hpp:232:2: note: candidate constructor not viable: no known conversion from 'LDKChannelMonitorUpdate' to 'LDKChannelMonitorUpdate &&' for 1st argument
ChannelMonitorUpdate(LDKChannelMonitorUpdate&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKChannelMonitorUpdate)); }
^
demo.cpp:160:16: error: no matching constructor for initialization of 'LDK::OutPoint'
LDK::OutPoint funding_txo(std::move(funding_txo_arg));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~
./include/lightningpp.hpp:334:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'const LDK::OutPoint' for 1st argument
OutPoint(const OutPoint&) = delete;
^
./include/lightningpp.hpp:335:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'LDK::OutPoint' for 1st argument
OutPoint(OutPoint&& o) : self(o.self) { memset(&o, 0, sizeof(OutPoint)); }
^
./include/lightningpp.hpp:336:2: note: candidate constructor not viable: no known conversion from 'LDKOutPoint' to 'LDKOutPoint &&' for 1st argument
OutPoint(LDKOutPoint&& m_self) : self(m_self) { memset(&m_self, 0, sizeof(LDKOutPoint)); }
^
demo.cpp:166:7: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
for (auto& mon : arg->mons) {
^
demo.cpp:166:17: warning: range-based for loop is a C++11 extension [-Wc++11-extensions]
for (auto& mon : arg->mons) {
^
demo.cpp:187:32: error: expected '(' for function-style cast or type construction
return LDKCVec_MonitorEventZ {
~~~~~~~~~~~~~~~~~~~~~ ^
demo.cpp:239:31: error: expected '(' for function-style cast or type construction
sock1 = LDKSocketDescriptor {
~~~~~~~~~~~~~~~~~~~ ^
demo.cpp:249:31: error: expected '(' for function-style cast or type construction
sock2 = LDKSocketDescriptor {
~~~~~~~~~~~~~~~~~~~ ^
demo.cpp:259:8: error: no matching constructor for initialization of 'std::thread'
t1 = std::thread(&sock_read_data_thread, pipefds_2_to_1[0], &sock1, &net1);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:408:9: note: candidate constructor template not viable: requires single argument '__f', but 4 arguments were provided
thread::thread(_Fp __f)
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:289:5: note: candidate constructor not viable: requires 1 argument, but 4 were provided
thread(const thread&);
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:296:5: note: candidate constructor not viable: requires 0 arguments, but 4 were provided
thread() _NOEXCEPT : __t_(_LIBCPP_NULL_THREAD) {}
^
demo.cpp:260:8: error: no matching constructor for initialization of 'std::thread'
t2 = std::thread(&sock_read_data_thread, pipefds_1_to_2[0], &sock2, &net2);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:408:9: note: candidate constructor template not viable: requires single argument '__f', but 4 arguments were provided
thread::thread(_Fp __f)
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:289:5: note: candidate constructor not viable: requires 1 argument, but 4 were provided
thread(const thread&);
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:296:5: note: candidate constructor not viable: requires 0 arguments, but 4 were provided
thread() _NOEXCEPT : __t_(_LIBCPP_NULL_THREAD) {}
^
demo.cpp:268:3: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
auto writelen = write(pipefds_1_to_2[1], con_res->contents.result->data, con_res->contents.result->datalen);
^
demo.cpp:299:35: error: expected ';' at end of declaration
LDKBroadcasterInterface broadcast {
^
;
demo.cpp:306:19: error: expected ';' at end of declaration
LDKLogger logger1 {
^
;
demo.cpp:314:15: error: expected ';' at end of declaration
LDKWatch mon1 {
^
;
demo.cpp:325:19: error: expected ';' at end of declaration
LDKLogger logger2 {
^
;
demo.cpp:333:15: error: expected ';' at end of declaration
LDKWatch mon2 {
^
;
demo.cpp:344:38: error: expected '(' for function-style cast or type construction
LDK::CVec_u8Z cm1_ser = LDKCVec_u8Z {}; // ChannelManager 1 serialization at the end of the ser-des scope
~~~~~~~~~~~ ^
demo.cpp:345:38: error: expected '(' for function-style cast or type construction
LDK::CVec_u8Z cm2_ser = LDKCVec_u8Z {}; // ChannelManager 2 serialization at the end of the ser-des scope
~~~~~~~~~~~ ^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
900 warnings and 20 errors generated.

}
pub extern "C" fn ChannelMonitorUpdate_read(ser: crate::c_types::u8slice) -> crate::c_types::derived::CResult_ChannelMonitorUpdateDecodeErrorZ {
let res = crate::c_types::deserialize_obj(ser);
let mut local_res = match res { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::chain::channelmonitor::ChannelMonitorUpdate { inner: Box::into_raw(Box::new(o)), is_owned: true } }), Err(mut e) => crate::c_types::CResultTempl::err( { crate::ln::msgs::DecodeError { inner: Box::into_raw(Box::new(e)), is_owned: true } }) };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was having no line breaks here intentional?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a number of similar cases across the bindings, especially for template types (vec/result/tuples) - specifically we don't track at what level of indentation we are at that deep into type conversion, so we either have bogus indentation or no indentation. For now its none, but its something we should fix eventually.

Comment threadc-bindings-gen/src/main.rs Outdated
Comment threadc-bindings-gen/src/main.rs
Comment threadgenbindings.sh Outdated
echo "WARNING: Please install valgrind for more testing"
fi

CLANGOPTS="-Wall -Wno-nullability-completeness -pthread"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm seeing a ton of warnings looking to originate from this commit:

++ rustc --version --verbose
++ grep host:
+ HOST_PLATFORM='host: x86_64-apple-darwin'
+ '[' 'host: x86_64-apple-darwin' = 'host: x86_64-apple-darwin' ']'
+ sed -i '' 's/typedef LDKnative.*Import.*LDKnative.*;//g' include/lightning.h
+ gcc -Wall -g -pthread demo.c target/debug/libldk.a -ldl
In file included from demo.c:2:
./include/lightning.h:204:12: warning: pointer is missing a nullability type specifier (_Nonnull, _Nullable, or _Null_unspecified) [-Wnullability-completeness]
uint8_t *data;
^
./include/lightning.h:204:12: note: insert '_Nullable' if the pointer may be null
uint8_t *data;
^
_Nullable ./include/lightning.h:204:12: note: insert '_Nonnull' if the pointer should never be null
uint8_t *data;
^
_Nonnull 

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heh, that's an OSX-ism, because gcc is just a symlink to clang...I'll add the warning disable on all the compile calls.

@TheBlueMatt
TheBlueMattforce-pushed the 2020-12-chanman-bindings-deser branch from c326bcb to d08bdf4CompareFebruary 3, 2021 00:55
@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Addressed review comments, rebased to fix conflicts but no changes outside of bindings generation code.

We can fail to resolve a part of a tuple, resulting in a panic in
write_template_constructor even if we're calling
`understood_c_type` with the intent of figuring out whether we can
print a type at all. Instead, we should pipe errors back and let
`understood_c_type` return false as a result.
Previously, manual `*_read` implementations were only defined for
types with inner fields, which were set to NULL to indicate read
errors. This prevents exposing `*_read` for several other types,
including tuples (which are needed for `ChannelManager`/
`ChannelMonitors`) and enums (which includes `Event`s, though users
likely never need to call that directly). Further, this means we
don't expose the actual error enum (which is likely no big deal,
but is still nice).
Here, we instead create the `Result<Object, DecodeError>` type and
then pass it through the normal type conversion functions, giving
us access to any types which we can convert normally.
This expands the manual implementation logic for `*_write` and
`*_read` methods to most types, converting the `*_write` path to
the common type-conversion logic to ensure it works.
Note that `*_write_void` is still only implemented for has-inner
types, as its unclear what the `void*` would point to for others.
It just stubs out to `write_rust_path` in this case anyway, which
handles leading-colons just fine, so no need to panic on them.
This is most of the code to expose `ChannelManager`/`ChannelMonitor`
deserialization in our C bindings, using the new infrastructure to
map types in `maybe_convert_trait_impl` and passing generics in
from the callsites.
We also call `maybe_convert_trait_impl` for tuple types, as the
`ChannelManager`/`ChannelMonitor` deserialization returns a
`(BlockHash, T)` to indicate the block hash at which users need to
start resyncing the chain.
The final step to expose them is in the next commit.
This (finally) exposes `ChannelManager`/`ChannelMonitor` _write
methods, which were (needlessly) excluded as the structs themselves
have generic parameters. Sadly, we also now need to parse
`(C-not exported)` doc comments on impl blocks as we otherwise try
to expose _write methods for `&Vec<RouteHop>`, which doesn't work
(and isn't particularly interesting for users anyway). We add such
doc comments there.
This adds a new annotation for objects we take by reference in the
C header indicating the pointers must not be null. We have to
disable some warning clang now dumps that we haven't annotated all
pointers, as cbindgen is not yet able to add a nullable annotation.
Previously, references and pointers ended up identical in C, so
there was little reason to differentiate. With the addition of
nullability annotations, there is a (very slight) reason to prefer
references, so use them in a few places where its a trivial change.
This adds a move-assignment operator (`A& operator=(A&& o)`) to our
C++ wrapper classes as well as requiring an rvalue for the move
auto-convert operator (`operator CStruct()() &&`).
The second makes the C++ wrapper classes much easier to work with
by requiring an explicit `std::move` when the bindings will
automatically move a C++-wrapper object into a C object.
This demonstrates (and tests) the newly-exposed `ChannelManager`
de/serialization functions. Best revewied with -b --color-moved.
There were two issues on OSX - we need to give gcc the clang
warnings flags because `gcc` *is* clang on OSX and we missed an
`-std=c++11` on one of the clang++ calls, causing compile failures.
@TheBlueMatt
TheBlueMattforce-pushed the 2020-12-chanman-bindings-deser branch from d08bdf4 to 5d045deCompareFebruary 3, 2021 15:12
@TheBlueMatt

TheBlueMatt commented Feb 3, 2021

Copy link
Copy Markdown
CollaboratorAuthor

Rebased with no changes (git diff-tree d08bdf44 5d045de8 is empty) - only dropped intermediate binidings updates and rebased on upstream (including 767 merge).

@TheBlueMatt

Copy link
Copy Markdown
CollaboratorAuthor

Its just bindings, worth merging without more than one ack.

@TheBlueMatt
TheBlueMatt merged commit e4b516d into lightningdevkit:mainFeb 3, 2021
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@TheBlueMatt@jkczyz