Skip to content

Commit 2e86a59

Browse files
authored
Merge pull request #2426 from TheBlueMatt/2023-07-proc-macro2-msrv
2 parents c5c5f3f + f38b80a commit 2e86a59

File tree

6 files changed

+146
-28
lines changed

6 files changed

+146
-28
lines changed

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ exclude = [
1414
"lightning-custom-message",
1515
"lightning-transaction-sync",
1616
"no-std-check",
17+
"msrv-no-dev-deps-check",
1718
"bench",
1819
]
1920

ci/ci-tests.sh

+34-8
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,33 @@ set -eox pipefail
44
RUSTC_MINOR_VERSION=$(rustc --version | awk '{ split($2,a,"."); print a[2] }')
55
HOST_PLATFORM="$(rustc --version --verbose | grep "host:" | awk '{ print $2 }')"
66

7-
# Tokio MSRV on versions 1.17 through 1.26 is rustc 1.49. Above 1.26 MSRV is 1.56.
8-
[ "$RUSTC_MINOR_VERSION" -lt 49 ] && cargo update -p tokio --precise "1.14.1" --verbose
9-
[[ "$RUSTC_MINOR_VERSION" -gt 48 && "$RUSTC_MINOR_VERSION" -lt 56 ]] && cargo update -p tokio --precise "1.25.1" --verbose
7+
# Some crates require pinning to meet our MSRV even for our downstream users,
8+
# which we do here.
9+
# Further crates which appear only as dev-dependencies are pinned further down.
10+
function PIN_RELEASE_DEPS {
11+
# Tokio MSRV on versions 1.17 through 1.26 is rustc 1.49. Above 1.26 MSRV is 1.56.
12+
[ "$RUSTC_MINOR_VERSION" -lt 49 ] && cargo update -p tokio --precise "1.14.1" --verbose
13+
[[ "$RUSTC_MINOR_VERSION" -gt 48 && "$RUSTC_MINOR_VERSION" -lt 56 ]] && cargo update -p tokio --precise "1.25.1" --verbose
1014

11-
# Sadly the log crate is always a dependency of tokio until 1.20, and has no reasonable MSRV guarantees
12-
[ "$RUSTC_MINOR_VERSION" -lt 49 ] && cargo update -p log --precise "0.4.18" --verbose
15+
# Sadly the log crate is always a dependency of tokio until 1.20, and has no reasonable MSRV guarantees
16+
[ "$RUSTC_MINOR_VERSION" -lt 49 ] && cargo update -p log --precise "0.4.18" --verbose
17+
18+
# The serde_json crate switched to Rust edition 2021 starting with v1.0.101, i.e., has MSRV of 1.56
19+
[ "$RUSTC_MINOR_VERSION" -lt 56 ] && cargo update -p serde_json --precise "1.0.100" --verbose
20+
21+
return 0 # Don't fail the script if our rustc is higher than the last check
22+
}
23+
24+
PIN_RELEASE_DEPS # pin the release dependencies in our main workspace
1325

1426
# The addr2line v0.20 crate (a dependency of `backtrace` starting with 0.3.68) relies on 1.55+
1527
[ "$RUSTC_MINOR_VERSION" -lt 55 ] && cargo update -p backtrace --precise "0.3.67" --verbose
1628

17-
# The serde_json crate switched to Rust edition 2021 starting with v1.0.101, i.e., has MSRV of 1.56
18-
[ "$RUSTC_MINOR_VERSION" -lt 56 ] && cargo update -p serde_json --precise "1.0.100" --verbose
29+
# The quote crate switched to Rust edition 2021 starting with v1.0.31, i.e., has MSRV of 1.56
30+
[ "$RUSTC_MINOR_VERSION" -lt 56 ] && cargo update -p quote --precise "1.0.30" --verbose
31+
32+
# The proc-macro2 crate switched to Rust edition 2021 starting with v1.0.66, i.e., has MSRV of 1.56
33+
[ "$RUSTC_MINOR_VERSION" -lt 56 ] && cargo update -p proc-macro2 --precise "1.0.65" --verbose
1934

2035
[ "$LDK_COVERAGE_BUILD" != "" ] && export RUSTFLAGS="-C link-dead-code"
2136

@@ -62,7 +77,18 @@ popd
6277
echo -e "\n\nTesting no-std build on a downstream no-std crate"
6378
# check no-std compatibility across dependencies
6479
pushd no-std-check
65-
cargo check --verbose --color always --features lightning-transaction-sync
80+
if [[ $RUSTC_MINOR_VERSION -gt 67 ]]; then
81+
# lightning-transaction-sync's MSRV is 1.67
82+
cargo check --verbose --color always --features lightning-transaction-sync
83+
else
84+
cargo check --verbose --color always
85+
fi
86+
popd
87+
88+
# Test that we can build downstream code with only the "release pins".
89+
pushd msrv-no-dev-deps-check
90+
PIN_RELEASE_DEPS
91+
cargo check
6692
popd
6793

6894
if [ -f "$(which arm-none-eabi-gcc)" ]; then

lightning-net-tokio/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ rustdoc-args = ["--cfg", "docsrs"]
1717
[dependencies]
1818
bitcoin = "0.29.0"
1919
lightning = { version = "0.0.116-rc1", path = "../lightning" }
20-
tokio = { version = "1.0", features = [ "io-util", "macros", "rt", "sync", "net", "time" ] }
20+
tokio = { version = "1.0", features = [ "io-util", "rt", "sync", "net", "time" ] }
2121

2222
[dev-dependencies]
2323
tokio = { version = "1.14", features = [ "io-util", "macros", "rt", "rt-multi-thread", "sync", "net", "time" ] }

lightning-net-tokio/src/lib.rs

+97-19
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,79 @@ use lightning::ln::peer_handler::APeerManager;
4242
use lightning::ln::msgs::NetAddress;
4343

4444
use std::ops::Deref;
45-
use std::task;
45+
use std::task::{self, Poll};
46+
use std::future::Future;
4647
use std::net::SocketAddr;
4748
use std::net::TcpStream as StdTcpStream;
4849
use std::sync::{Arc, Mutex};
4950
use std::sync::atomic::{AtomicU64, Ordering};
5051
use std::time::Duration;
52+
use std::pin::Pin;
5153
use std::hash::Hash;
5254

5355
static ID_COUNTER: AtomicU64 = AtomicU64::new(0);
5456

57+
// We only need to select over multiple futures in one place, and taking on the full `tokio/macros`
58+
// dependency tree in order to do so (which has broken our MSRV before) is excessive. Instead, we
59+
// define a trivial two- and three- select macro with the specific types we need and just use that.
60+
61+
pub(crate) enum SelectorOutput {
62+
A(Option<()>), B(Option<()>), C(tokio::io::Result<usize>),
63+
}
64+
65+
pub(crate) struct TwoSelector<
66+
A: Future<Output=Option<()>> + Unpin, B: Future<Output=Option<()>> + Unpin
67+
> {
68+
pub a: A,
69+
pub b: B,
70+
}
71+
72+
impl<
73+
A: Future<Output=Option<()>> + Unpin, B: Future<Output=Option<()>> + Unpin
74+
> Future for TwoSelector<A, B> {
75+
type Output = SelectorOutput;
76+
fn poll(mut self: Pin<&mut Self>, ctx: &mut task::Context<'_>) -> Poll<SelectorOutput> {
77+
match Pin::new(&mut self.a).poll(ctx) {
78+
Poll::Ready(res) => { return Poll::Ready(SelectorOutput::A(res)); },
79+
Poll::Pending => {},
80+
}
81+
match Pin::new(&mut self.b).poll(ctx) {
82+
Poll::Ready(res) => { return Poll::Ready(SelectorOutput::B(res)); },
83+
Poll::Pending => {},
84+
}
85+
Poll::Pending
86+
}
87+
}
88+
89+
pub(crate) struct ThreeSelector<
90+
A: Future<Output=Option<()>> + Unpin, B: Future<Output=Option<()>> + Unpin, C: Future<Output=tokio::io::Result<usize>> + Unpin
91+
> {
92+
pub a: A,
93+
pub b: B,
94+
pub c: C,
95+
}
96+
97+
impl<
98+
A: Future<Output=Option<()>> + Unpin, B: Future<Output=Option<()>> + Unpin, C: Future<Output=tokio::io::Result<usize>> + Unpin
99+
> Future for ThreeSelector<A, B, C> {
100+
type Output = SelectorOutput;
101+
fn poll(mut self: Pin<&mut Self>, ctx: &mut task::Context<'_>) -> Poll<SelectorOutput> {
102+
match Pin::new(&mut self.a).poll(ctx) {
103+
Poll::Ready(res) => { return Poll::Ready(SelectorOutput::A(res)); },
104+
Poll::Pending => {},
105+
}
106+
match Pin::new(&mut self.b).poll(ctx) {
107+
Poll::Ready(res) => { return Poll::Ready(SelectorOutput::B(res)); },
108+
Poll::Pending => {},
109+
}
110+
match Pin::new(&mut self.c).poll(ctx) {
111+
Poll::Ready(res) => { return Poll::Ready(SelectorOutput::C(res)); },
112+
Poll::Pending => {},
113+
}
114+
Poll::Pending
115+
}
116+
}
117+
55118
/// Connection contains all our internal state for a connection - we hold a reference to the
56119
/// Connection object (in an Arc<Mutex<>>) in each SocketDescriptor we create as well as in the
57120
/// read future (which is returned by schedule_read).
@@ -127,29 +190,44 @@ impl Connection {
127190
}
128191
us_lock.read_paused
129192
};
130-
tokio::select! {
131-
v = write_avail_receiver.recv() => {
193+
// TODO: Drop the Box'ing of the futures once Rust has pin-on-stack support.
194+
let select_result = if read_paused {
195+
TwoSelector {
196+
a: Box::pin(write_avail_receiver.recv()),
197+
b: Box::pin(read_wake_receiver.recv()),
198+
}.await
199+
} else {
200+
ThreeSelector {
201+
a: Box::pin(write_avail_receiver.recv()),
202+
b: Box::pin(read_wake_receiver.recv()),
203+
c: Box::pin(reader.read(&mut buf)),
204+
}.await
205+
};
206+
match select_result {
207+
SelectorOutput::A(v) => {
132208
assert!(v.is_some()); // We can't have dropped the sending end, its in the us Arc!
133209
if peer_manager.as_ref().write_buffer_space_avail(&mut our_descriptor).is_err() {
134210
break Disconnect::CloseConnection;
135211
}
136212
},
137-
_ = read_wake_receiver.recv() => {},
138-
read = reader.read(&mut buf), if !read_paused => match read {
139-
Ok(0) => break Disconnect::PeerDisconnected,
140-
Ok(len) => {
141-
let read_res = peer_manager.as_ref().read_event(&mut our_descriptor, &buf[0..len]);
142-
let mut us_lock = us.lock().unwrap();
143-
match read_res {
144-
Ok(pause_read) => {
145-
if pause_read {
146-
us_lock.read_paused = true;
147-
}
148-
},
149-
Err(_) => break Disconnect::CloseConnection,
150-
}
151-
},
152-
Err(_) => break Disconnect::PeerDisconnected,
213+
SelectorOutput::B(_) => {},
214+
SelectorOutput::C(read) => {
215+
match read {
216+
Ok(0) => break Disconnect::PeerDisconnected,
217+
Ok(len) => {
218+
let read_res = peer_manager.as_ref().read_event(&mut our_descriptor, &buf[0..len]);
219+
let mut us_lock = us.lock().unwrap();
220+
match read_res {
221+
Ok(pause_read) => {
222+
if pause_read {
223+
us_lock.read_paused = true;
224+
}
225+
},
226+
Err(_) => break Disconnect::CloseConnection,
227+
}
228+
},
229+
Err(_) => break Disconnect::PeerDisconnected,
230+
}
153231
},
154232
}
155233
let _ = event_waker.try_send(());

msrv-no-dev-deps-check/Cargo.toml

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[package]
2+
name = "msrv-check"
3+
version = "0.1.0"
4+
edition = "2018"
5+
6+
[dependencies]
7+
lightning = { path = "../lightning" }
8+
lightning-block-sync = { path = "../lightning-block-sync", features = [ "rest-client", "rpc-client" ] }
9+
lightning-invoice = { path = "../lightning-invoice" }
10+
lightning-net-tokio = { path = "../lightning-net-tokio" }
11+
lightning-persister = { path = "../lightning-persister" }
12+
lightning-background-processor = { path = "../lightning-background-processor", features = ["futures"] }
13+
lightning-rapid-gossip-sync = { path = "../lightning-rapid-gossip-sync" }

msrv-no-dev-deps-check/src/lib.rs

Whitespace-only changes.

0 commit comments

Comments
 (0)