-
Notifications
You must be signed in to change notification settings - Fork 376
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
allow functional tests to be used externally with a dynamic signer factory #3016
base: main
Are you sure you want to change the base?
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3016 +/- ##
==========================================
- Coverage 88.30% 88.30% -0.01%
==========================================
Files 149 151 +2
Lines 112912 113204 +292
Branches 112912 113204 +292
==========================================
+ Hits 99711 99964 +253
- Misses 10716 10754 +38
- Partials 2485 2486 +1 ☔ View full report in Codecov by Sentry. |
1a142e1
to
4077bc2
Compare
ext-test-macro/Cargo.toml
Outdated
@@ -0,0 +1,14 @@ | |||
[package] | |||
name = "ext-test-macro" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we should call this more generally ldk-macros
? Currently, we use bdk-macros
to provide a dual blocking/async interface in lightning-transaction-sync
. However, the bdk-macros
crate is basically going away with BDK 1.0, so we might want to include the corresponding functionality here?
(cc @TheBlueMatt)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm fine with making this generic, I don't really have a strong opinion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
making it generic
4077bc2
to
3a1986c
Compare
@@ -727,6 +725,32 @@ impl HTLCDescriptor { | |||
/// A trait to handle Lightning channel key material without concretizing the channel type or | |||
/// the signature mechanism. | |||
pub trait ChannelSigner { | |||
/// Returns the commitment seed for the channel. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe create a separate trait for these
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, sgtm, some kind of extension trait should do.
9d4e233
to
f341a0c
Compare
lightning/src/util/dyn_signer.rs
Outdated
htlc: &HTLCOutputInCommitment, | ||
secp_ctx: &Secp256k1<secp256k1::All>, | ||
) -> Result<Signature, ()> { | ||
EcdsaChannelSigner::sign_justice_revoked_htlc(&*self.inner, justice_tx, input, amount, per_commitment_key, htlc, secp_ctx) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
name clashes are inconvenient, result in this need to disambiguate, and can't use delegate!
macro
87aadef
to
4efd374
Compare
3c454d0
to
ef8f13d
Compare
lightning-invoice/src/utils.rs
Outdated
let cross_node_seed = [44u8; 32]; | ||
chanmon_cfgs[1].keys_manager.backing = PhantomKeysManager::new(&seed_1, 43, 44, &cross_node_seed); | ||
chanmon_cfgs[2].keys_manager.backing = PhantomKeysManager::new(&seed_2, 43, 44, &cross_node_seed); | ||
chanmon_cfgs[1].keys_manager.backing = make_dyn_keys_interface(&seed_1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm surprised these tests pass? The point is to have the same cross_node_seed across the nodes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make_dyn_keys_interface
does have a constant cross-node seed
@@ -1981,9 +1978,6 @@ where | |||
/// required to access the channel with the `counterparty_node_id`. | |||
/// | |||
/// See `ChannelManager` struct-level documentation for lock order requirements. | |||
#[cfg(not(test))] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general I'd prefer to keep these kinds of things if possible. They're kinda verbose and dumb but I don't really want internal things leaking and someone starting to rely on them being usable across the crate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, right. I put it back.
@@ -727,6 +725,32 @@ impl HTLCDescriptor { | |||
/// A trait to handle Lightning channel key material without concretizing the channel type or | |||
/// the signature mechanism. | |||
pub trait ChannelSigner { | |||
/// Returns the commitment seed for the channel. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, sgtm, some kind of extension trait should do.
lightning/src/util/mod.rs
Outdated
pub mod dyn_signer; | ||
|
||
#[cfg(feature = "std")] | ||
pub mod mut_global; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do these need to be visible outside of test builds?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
lightning/Cargo.toml
Outdated
delegate = "0.12.0" | ||
ext-test-macro = { path = "../ext-test-macro" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar here, can we make these only a part of _test_utils
builds only?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
} | ||
|
||
impl NodeSigner for DynKeysInterface { | ||
delegate! { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Honestly not convinced this actually saves enough typing to be worth it, but whatever.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
more to reduce cognitive load when reading these things... but up to you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How much work is it to just rebuild the macro? Seems like NIHing it would be pretty trivial too?
fd35254
to
2e2df96
Compare
one more idea. it would be nice to collect all the tests of a file into a static array. this would require one of the following to automatically collect the array:
|
84abf70
to
0a29d64
Compare
I pushed a proposal |
49a529e
to
4a102fa
Compare
@@ -94,8 +95,8 @@ fn test_channel_resumption_fail_post_funding() { | |||
assert_eq!(nodes[0].node.get_and_clear_pending_msg_events(), Vec::new()); | |||
} | |||
|
|||
#[test] | |||
fn test_insane_channel_opens() { | |||
#[xtest(feature = "_test_utils")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we could control the feature at the module level, reducing verbosity. the tradeoff is that we'll have to generate the inventory when testing locally, but maybe that's not significant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think its fine. It does read a bit funky, though - I'd read this as "this is a test only if _test_utils
is set", not "this is a public test only if _test_utils
is set". Should we just copy the gate verbatim and make things xtest(any(test, ...))
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so xtest(any(test, feature = "_test_utils"))
?
we would need to figure out semantics of #[xtest]
without qualifiers - that would mean that it's always exposed, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, I think so?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice. Should be ready after the few comments here, I think. Mind cleaning up the commits to include more details in the commit message while you're at it?
} | ||
|
||
impl NodeSigner for DynKeysInterface { | ||
delegate! { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How much work is it to just rebuild the macro? Seems like NIHing it would be pretty trivial too?
@@ -49,10 +49,14 @@ regex = { version = "1.5.6", optional = true } | |||
backtrace = { version = "0.3", optional = true } | |||
|
|||
libm = { version = "0.2", default-features = false } | |||
delegate = "0.12.0" | |||
ext-test-macro = { path = "../ext-test-macro", optional = true } | |||
inventory = { version = "0.3", optional = true } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How much work would it be to just NIH this? Can we just have some global static Vec
listing function pointers and names?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the issue is that you can't call non-const functions before main()
, so it seems like you need to jump through the linker hacks inventory
is doing. and those hacks are target specific, so it wouldn't make a lot of sense to maintain them ourselves.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a different approach would be to only inventory at the module level, requiring the mod
to have an xtest
macro on it. then the inventorying can happen inside the mod
macro invocation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not quite sure I understand what the approach is that you're suggesting, but...sure?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since it's not possible to incrementally add to a global variable without inventory
, I'm suggesting that tests are grouped into:
#[xtest]
mod tests {
...
}
and then the module level macro invocation will collect the tests inside the module in one swoop instead of incrementally.
This will require another level of mod
inside the existing functional test mods. and it will also require adding a level of indent to a couple of thousand lines or so. Is that OK?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, right, duh. I mean in principle we could even wrap the entire crate/top-level module in an #[xtest]
no? We could also just do it on the funtional_tests
/etc modules directly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it has to be a single compilation unit. macros can't iterate on functions that are in another compilation unit, because they are not in the AST when the macro is invoked.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, damn.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so what's the verdict? inventory
or mod
+indent everything?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm fine with the current inventory-based code, I think.
lightning/src/sign/mod.rs
Outdated
@@ -723,6 +722,35 @@ impl HTLCDescriptor { | |||
} | |||
} | |||
|
|||
/// Extension trait for [`ChannelSigner`] to add methods required for functional tests. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If its just for functional tests we should bound on _test_utils
, but its also kinda nice to expose these things on our own InMemorySigner
so maybe we should just say something about helpful utilities for InMemorySigner
that provide more details which may be useful in tests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see if you like the new wording
@@ -0,0 +1,520 @@ | |||
//! A dynamically dispatched signer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Care to break this out of the big xtest commit so that that commit is more mechanical?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
bbfa2f0
to
b1f0fc8
Compare
note that I didn't yet go over all the functional tests in the codebase and ensure they have the |
This basically LGTM I think. Only outstanding items is #3016 (comment) (or some other way of removing the Either way feel free to clean up the git commits for merge.
I don't really care, this is basically a feature for VLS so whatever y'all need. |
b1f0fc8
to
5c3be20
Compare
82828d3
to
717e373
Compare
never mind, was missing a |
I am making |
ec136e5
to
e0a6864
Compare
ldk-macros/Cargo.toml
Outdated
@@ -0,0 +1,17 @@ | |||
[package] | |||
name = "ldk-macros" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that we by now have the lightning-macros
crate. IMO, you'll want to add the required macros there instead of creating yet another ldk-macros
crate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, OK, will do
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
e0a6864
to
a92c915
Compare
this is ready for final review |
getting some out-of-disk-space CI errors... |
a92c915
to
5849f4b
Compare
should we run the xtest PoC only in one of the build variants, to reduce build time? or even make it a separate check?
commit added for this, but it seems to run in only 3 minutes, so maybe it's not worth separating out... |
52aeccc
to
116379f
Compare
DynSigner
xtest
macrosfake_network_test
and others