Skip to content
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

Drop futures dependency from lightning-block-sync #2141

Merged
merged 4 commits into from
Mar 31, 2023

Conversation

TheBlueMatt
Copy link
Collaborator

Some how I'd understood that futures had reasonable MSRV guarantees (e.g. at least Debian stable), but apparently that isn't actually the case, as they bumped it to upgrade to syn (with apparently no actual features or bugfixes added as a result?) with no minor version bump or any available alternative (unlike Tokio, which does LTS releases).

Luckily its relatively easy to just drop the futures dependency - it means a new connection for each request, which is annoying, but certainly not the end of the world, and its easier than trying to deal with pinning futures.

See rust-lang/futures-rs#2733

@TheBlueMatt
Copy link
Collaborator Author

Note, as an alternative, default-features = false would also fix this, but I'm a bit weary of them just breaking things again because they apparently don't have any MSRV guarantees (somehow I'd thought they did, but I guess I'd confused them simply being conservative int he past for having guarantees).

@TheBlueMatt
Copy link
Collaborator Author

As a further alternative, we could use sync mutexes with an Optional client, using it as a cache, which I think in the common case would avoid fresh connections every time, while avoiding a fresh connection on every call when there's only one call at a time (which is normal).

Some how I'd understood that `futures` had reasonable MSRV
guarantees (e.g. at least Debian stable), but apparently that isn't
actually the case, as they bumped it to upgrade to syn (with
apparently no actual features or bugfixes added as a result?) with
no minor version bump or any available alternative (unlike Tokio,
which does LTS releases).

Luckily its relatively easy to just drop the `futures` dependency -
it means a new connection for each request, which is annoying, but
certainly not the end of the world, and its easier than trying to
deal with pinning `futures`.

See rust-lang/futures-rs#2733
@TheBlueMatt
Copy link
Collaborator Author

Actually, went ahead and did the second because its super trivial.

@TheBlueMatt
Copy link
Collaborator Author

Grr, also need to replace the futures usages in the async BP. I think its quite doable though.

@TheBlueMatt
Copy link
Collaborator Author

Ok, removed it from BP wholesale in two commits. Honestly dunno why we were relying on a whole mess of proc macro in the futures crate to implement select lol.

In general, only one request will be in flight at a time in
`lightning-block-sync`. Ideally we'd only have one connection, but
without using the `futures` mutex type.

Here we solve this narrowly for the one-request-at-a-time case by
caching the connection and takeing the connection out of the cache
while we work on it.
@TheBlueMatt
Copy link
Collaborator Author

That said, I'm open to pushback on the last commit (or the second one) - it does add a trivial use of unsafe, which is trivial, but technically its not required to fix MSRV, it just leaves us open to futures breaking us again in the future.

wpaulino
wpaulino previously approved these changes Mar 30, 2023
lightning-background-processor/src/lib.rs Outdated Show resolved Hide resolved

const DUMMY_WAKER_VTABLE: RawWakerVTable = RawWakerVTable::new(
dummy_waker_clone, dummy_waker_action, dummy_waker_action, dummy_waker_action);
pub(crate) fn dummy_waker() -> Waker { unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &DUMMY_WAKER_VTABLE)) } }
Copy link
Contributor

Choose a reason for hiding this comment

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

what would not introducing this unsafe look like?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Using another crate which has the unsafe in it instead. There's no way to poll a future in rust with zero unsafe. Now, we could consider coming up with some other way to do no-std timers inside an async context outside of polling a timer future, but I'm not 100% sure what is cleaner for users.

@codecov-commenter
Copy link

codecov-commenter commented Mar 30, 2023

Codecov Report

Patch coverage: 80.00% and project coverage change: -0.02 ⚠️

Comparison is base (783e818) 91.38% compared to head (491100d) 91.37%.

📣 This organization is not using Codecov’s GitHub App Integration. We recommend you install it so Codecov can continue to function properly for your repositories. Learn more

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2141      +/-   ##
==========================================
- Coverage   91.38%   91.37%   -0.02%     
==========================================
  Files         102      102              
  Lines       49759    49767       +8     
  Branches    49759    49767       +8     
==========================================
+ Hits        45472    45474       +2     
- Misses       4287     4293       +6     
Impacted Files Coverage Δ
lightning-background-processor/src/lib.rs 77.80% <0.00%> (-0.50%) ⬇️
lightning-block-sync/src/rest.rs 67.18% <100.00%> (+1.61%) ⬆️
lightning-block-sync/src/rpc.rs 77.24% <100.00%> (+0.31%) ⬆️

... and 2 files with indirect coverage changes

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

`futures` recently broke our MSRV by bumping the `syn` major
version in a patch release. This makes it impractical for us to
use, instead here we replace the usage of its `select_biased` macro
with a trivial enum.

Given its simplicity we likely should have done this without ever
taking the dependency.
As `futures` apparently makes no guarantees on MSRVs even in patch
releases we really can't rely on it at all, and while it currently
has an acceptable MSRV without the macros feature, its best to just
remove it wholesale.

Luckily, removing it is relatively trivial, even if it requires
the most trivial of unsafe tags.
@TheBlueMatt
Copy link
Collaborator Author

Addressed arik's comments and squashed.

// not without awaiting, we need a Waker, which needs a vtable...we fill it with dummy values
// but sadly there's a good bit of boilerplate here.
fn dummy_waker_clone(_: *const ()) -> RawWaker { RawWaker::new(core::ptr::null(), &DUMMY_WAKER_VTABLE) }
fn dummy_waker_action(_: *const ()) { }
Copy link
Contributor

Choose a reason for hiding this comment

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

given these are dummies, would it make sense to insert some unreachable!s?

Copy link
Contributor

Choose a reason for hiding this comment

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

Not quite, they're still called, but they're no-op's.

@wpaulino wpaulino merged commit 0e28bcb into lightningdevkit:main Mar 31, 2023
Sign up for free to 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.

4 participants