-
Notifications
You must be signed in to change notification settings - Fork 228
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
Implement full-duplex secret connection #938
Conversation
Signed-off-by: Thane Thomson <[email protected]>
Signed-off-by: Thane Thomson <[email protected]>
Signed-off-by: Thane Thomson <[email protected]>
This adds a `TcpStream`-based test for parallelizing operations on a `SecretConnection`. I used `TcpStream` instead of the buffered reader in the other tests because it wasn't feasible to implement the `TryClone` trait for that buffered pipe implementation. Signed-off-by: Thane Thomson <[email protected]>
Signed-off-by: Thane Thomson <[email protected]>
Signed-off-by: Thane Thomson <[email protected]>
Signed-off-by: Thane Thomson <[email protected]>
Codecov Report
@@ Coverage Diff @@
## master #938 +/- ##
=======================================
Coverage 70.6% 70.7%
=======================================
Files 203 205 +2
Lines 16312 16432 +120
=======================================
+ Hits 11524 11624 +100
- Misses 4788 4808 +20
Continue to review full report at Codecov.
|
p2p/src/transport.rs
Outdated
fn try_clone(&self) -> Result<Self, Self::Error> { | ||
// Uses the TcpStream struct's method. See | ||
// https://doc.rust-lang.org/stable/book/ch19-03-advanced-traits.html#fully-qualified-syntax-for-disambiguation-calling-methods-with-the-same-name | ||
self.try_clone() |
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.
Would it be simpler if we just use TcpStream::try_clone(self)
here and not having to explain in the comment?
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 wasn't obvious to me whether the TcpStream
's try_clone
method was going to be called here or the TryClone
trait's try_clone
, so I thought I'd leave a comment here for posterity to explain it.
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.
Oh, also, I tried explicitly calling TcpStream::try_clone(self)
here and clippy complains that the better approach is to use Self::try_clone(self)
, which, to me, isn't nearly as clear as TcpStream::try_clone(self)
.
p2p/src/secret_connection.rs
Outdated
@@ -452,6 +496,23 @@ where | |||
} | |||
} | |||
|
|||
impl<IoHandler: TryClone> TryClone for SecretConnection<IoHandler> { |
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.
What is the advantage of using this trait as compared to holding an Arc<IoHandler>
and Clone
?
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 #938 (comment)
p2p/src/secret_connection.rs
Outdated
if let Err(err) = res { | ||
return Err(io::Error::new(io::ErrorKind::Other, err.to_string())); | ||
} | ||
self.send_nonce.increment(); | ||
send_state.send_nonce.increment(); |
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.
Should we have higher level abstraction to guarantee that the nonce is always incremented after being acquired? Or should it never be incremented at all if there is error? Would the state be inconsistent if the line above or below returns error prematurely?
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.
@tony-iqlusion, what's your take on this?
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.
Preventing nonce reuse is the most important thing as it fails catastrophically with ChaCha20Poly1305, but also if it's ever incremented without being used it will be out-of-sync with the peer and abort the connection that way.
So it's best to have a sort of simple state machine that aborts the whole connection on errors, and if that can wipe the nonce somehow that's best, but so long as you can prevent repeat nonce reuse that's probably the most important thing.
p2p/src/secret_connection.rs
Outdated
let mut recv_state = self | ||
.recv_state | ||
.lock() | ||
.expect("failed to obtain lock on secret connection recv state"); |
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.
Should we return error result here instead of panicking? Same for the other uses of .expect()
.
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 would we (and should we be able to) recover from such an error?
My understanding is that, when Mutex::lock
fails, it's due to a panic while the lock is held by another thread.
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.
Sounds reasonable. Perhaps we can add a comment here that we are panicking because a poisoned mutex is unrecoverable. This is mainly to distinguish it from the other uses of .expect
in the same file, which IMO should be refactored to return Result::Err
instead.
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.
Fortunately in the new iteration there's no need for mutexes any more 😁
I've converted this back to a draft PR while I rework things a bit as per Tony's suggestions. |
Signed-off-by: Thane Thomson <[email protected]>
Signed-off-by: Thane Thomson <[email protected]>
Signed-off-by: Thane Thomson <[email protected]>
Signed-off-by: Thane Thomson <[email protected]>
Signed-off-by: Thane Thomson <[email protected]>
…nd receiving halves Signed-off-by: Thane Thomson <[email protected]>
Signed-off-by: Thane Thomson <[email protected]>
Signed-off-by: Thane Thomson <[email protected]>
Signed-off-by: Thane Thomson <[email protected]>
Signed-off-by: Thane Thomson <[email protected]>
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.
Looks good now!
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.
Very sensible, mostly left some clarifying questions. Are the concerns addressed wrt nonce handling in #938 (comment)?
p2p/src/secret_connection.rs
Outdated
debug_assert!(!chunk.is_empty(), "chunk is empty"); | ||
debug_assert!( |
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 we only want to guard against these conditions in debug 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.
Good question. @tony-iqlusion?
I'm not at all familiar with the low-level details of ChaCha20Poly1305. @tony-iqlusion, does this mean that, if there's any failure to read from/write to a |
This introduces the internal encryption assertions at runtime regardless of build type. This may introduce a small performance hit, but it's probably worth it to ensure correctness. Effectively this is keeping an eye on the code in the `encrypt_and_write` fn to ensure its correctness. Signed-off-by: Thane Thomson <[email protected]>
Signed-off-by: Thane Thomson <[email protected]>
Signed-off-by: Thane Thomson <[email protected]>
Signed-off-by: Thane Thomson <[email protected]>
Signed-off-by: Thane Thomson <[email protected]>
Signed-off-by: Thane Thomson <[email protected]>
…m constraints Signed-off-by: Thane Thomson <[email protected]>
The latest commits build incrementally on previous ones, so review shouldn't be too complex. One question though for those who've done/seen this sort of performance benchmarking in Rust before: what's the potential performance hit of loading an |
Vanishingly small compared to the system call overhead of an I/O operation. On x86(-64) in particular, the architecture provides a strongly consistent memory model, which means Things are a bit more complicated on e.g. ARM, where it will require flushing (potentially multicore) CPU pipelines, but again, minuscule compare to the overhead of a system call. |
Sounds good, thanks for the insight @tony-iqlusion! 🙏 |
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.
With #905 (comment) in mind should the internals and the handles acquired from a split
be named Reader
and Writer
respectively? Esp. as they implement Read
and Write
and receiver and sender can be reserved for abstractions which offer full messages as they input/output.
Signed-off-by: Thane Thomson <[email protected]>
Signed-off-by: Thane Thomson <[email protected]>
I've been trying to figure out which set of idioms (either "send/receive" or "read/write") should apply where, and it seems to me like "read/write" seems more general than "send/receive" (e.g. the latter doesn't make too much sense when interacting with the filesystem). Networked entities seem to send/receive more than read/write. This is probably due to the fact that low-level socket functions like But either way, as long as it's consistent, I'd be fine with it. My issue in #905 (comment) was that it was inconsistent. |
Signed-off-by: Thane Thomson <[email protected]>
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.
🏌 😜 🏷 🏉
* Implement full-duplex secret connection (#938) * Implement thread-safe cloning of a secret connection Signed-off-by: Thane Thomson <[email protected]> * Expand documentation for SecretConnection on threading considerations Signed-off-by: Thane Thomson <[email protected]> * Extract peer construction into its own method Signed-off-by: Thane Thomson <[email protected]> * Add test for cloned SecretConnection This adds a `TcpStream`-based test for parallelizing operations on a `SecretConnection`. I used `TcpStream` instead of the buffered reader in the other tests because it wasn't feasible to implement the `TryClone` trait for that buffered pipe implementation. Signed-off-by: Thane Thomson <[email protected]> * Add more messages to test Signed-off-by: Thane Thomson <[email protected]> * Expand comment for clarity Signed-off-by: Thane Thomson <[email protected]> * Add .changelog entry Signed-off-by: Thane Thomson <[email protected]> * Restore half-duplex operations Signed-off-by: Thane Thomson <[email protected]> * Extract encrypt/decrypt fns as independent methods Signed-off-by: Thane Thomson <[email protected]> * Remove unnecessary trait bounds Signed-off-by: Thane Thomson <[email protected]> * Extract send/receive state Signed-off-by: Thane Thomson <[email protected]> * Extract read/write functionality as standalone methods Signed-off-by: Thane Thomson <[email protected]> * Add logic to facilitate splitting SecretConnection into its sending and receiving halves Signed-off-by: Thane Thomson <[email protected]> * Restore split SecretConnection test using new semantics Signed-off-by: Thane Thomson <[email protected]> * Update changelog entry Signed-off-by: Thane Thomson <[email protected]> * Update docs for `SecretConnection` Signed-off-by: Thane Thomson <[email protected]> * Condense error reporting Signed-off-by: Thane Thomson <[email protected]> * Extract TryClone trait into its own crate As per the discussion at #938 (comment), this extracts the `TryClone` trait into a new crate called `tendermint-std-ext` in the `std-ext` directory. This new crate is intended to contain any code that we need that extends the Rust standard library. Signed-off-by: Thane Thomson <[email protected]> * Reorder imports Signed-off-by: Thane Thomson <[email protected]> * Assert validation regardless of debug build This introduces the internal encryption assertions at runtime regardless of build type. This may introduce a small performance hit, but it's probably worth it to ensure correctness. Effectively this is keeping an eye on the code in the `encrypt_and_write` fn to ensure its correctness. Signed-off-by: Thane Thomson <[email protected]> * Remove remote_pubkey optionality from sender/receiver halves Signed-off-by: Thane Thomson <[email protected]> * Update SecretConnection docs with comment content Signed-off-by: Thane Thomson <[email protected]> * Fix doc link to TryClone trait Signed-off-by: Thane Thomson <[email protected]> * Fix doc link to TryClone trait Signed-off-by: Thane Thomson <[email protected]> * Add docs on SecretConnection failures and connection integrity Signed-off-by: Thane Thomson <[email protected]> * Synchronize sending/receiving failures to comply with crypto algorithm constraints Signed-off-by: Thane Thomson <[email protected]> * Rename try_split method to split for SecretConnection Signed-off-by: Thane Thomson <[email protected]> * Remove redundant field name prefixes Signed-off-by: Thane Thomson <[email protected]> * Fix broken link in docs Signed-off-by: Thane Thomson <[email protected]> * Fix recent clippy errors on `master` (#941) * Fix needless borrows in codebase Signed-off-by: Thane Thomson <[email protected]> * Ignore needless collect warning (we do actually seem to need it) Signed-off-by: Thane Thomson <[email protected]> * Remove trailing semicolon in macro to fix docs compiling Signed-off-by: Thane Thomson <[email protected]>
* Use flex-error for tendermint * Use flex-error for p2p * Use flex-error for light-client * Use flex-error for light_client::predicates * Fix lint * Use flex-error for builder and io errors * Use flex-error for rpc errors * Use flex-error for protobuf errors * Use flex-error for abci * Fix test_bisection_no_witness_left * Fix build errors in all-features * Fix failing tests * Fix more failures * Fix tungstenite error under wasm target * Fix incoming_fixtures test * Fix conflict * Update flex-error to v0.4.0 * set std feature in flex-error instead of individual crates * Add flex-error patch to tools/Cargo.toml * Use published version of flex-error v0.4.1 * Enable flex-error/eyre_tracer feature by default * Add .changelog entry (#940) Signed-off-by: Thane Thomson <[email protected]> * flex-error: resolve conflicts with `master` (#945) * Implement full-duplex secret connection (#938) * Implement thread-safe cloning of a secret connection Signed-off-by: Thane Thomson <[email protected]> * Expand documentation for SecretConnection on threading considerations Signed-off-by: Thane Thomson <[email protected]> * Extract peer construction into its own method Signed-off-by: Thane Thomson <[email protected]> * Add test for cloned SecretConnection This adds a `TcpStream`-based test for parallelizing operations on a `SecretConnection`. I used `TcpStream` instead of the buffered reader in the other tests because it wasn't feasible to implement the `TryClone` trait for that buffered pipe implementation. Signed-off-by: Thane Thomson <[email protected]> * Add more messages to test Signed-off-by: Thane Thomson <[email protected]> * Expand comment for clarity Signed-off-by: Thane Thomson <[email protected]> * Add .changelog entry Signed-off-by: Thane Thomson <[email protected]> * Restore half-duplex operations Signed-off-by: Thane Thomson <[email protected]> * Extract encrypt/decrypt fns as independent methods Signed-off-by: Thane Thomson <[email protected]> * Remove unnecessary trait bounds Signed-off-by: Thane Thomson <[email protected]> * Extract send/receive state Signed-off-by: Thane Thomson <[email protected]> * Extract read/write functionality as standalone methods Signed-off-by: Thane Thomson <[email protected]> * Add logic to facilitate splitting SecretConnection into its sending and receiving halves Signed-off-by: Thane Thomson <[email protected]> * Restore split SecretConnection test using new semantics Signed-off-by: Thane Thomson <[email protected]> * Update changelog entry Signed-off-by: Thane Thomson <[email protected]> * Update docs for `SecretConnection` Signed-off-by: Thane Thomson <[email protected]> * Condense error reporting Signed-off-by: Thane Thomson <[email protected]> * Extract TryClone trait into its own crate As per the discussion at #938 (comment), this extracts the `TryClone` trait into a new crate called `tendermint-std-ext` in the `std-ext` directory. This new crate is intended to contain any code that we need that extends the Rust standard library. Signed-off-by: Thane Thomson <[email protected]> * Reorder imports Signed-off-by: Thane Thomson <[email protected]> * Assert validation regardless of debug build This introduces the internal encryption assertions at runtime regardless of build type. This may introduce a small performance hit, but it's probably worth it to ensure correctness. Effectively this is keeping an eye on the code in the `encrypt_and_write` fn to ensure its correctness. Signed-off-by: Thane Thomson <[email protected]> * Remove remote_pubkey optionality from sender/receiver halves Signed-off-by: Thane Thomson <[email protected]> * Update SecretConnection docs with comment content Signed-off-by: Thane Thomson <[email protected]> * Fix doc link to TryClone trait Signed-off-by: Thane Thomson <[email protected]> * Fix doc link to TryClone trait Signed-off-by: Thane Thomson <[email protected]> * Add docs on SecretConnection failures and connection integrity Signed-off-by: Thane Thomson <[email protected]> * Synchronize sending/receiving failures to comply with crypto algorithm constraints Signed-off-by: Thane Thomson <[email protected]> * Rename try_split method to split for SecretConnection Signed-off-by: Thane Thomson <[email protected]> * Remove redundant field name prefixes Signed-off-by: Thane Thomson <[email protected]> * Fix broken link in docs Signed-off-by: Thane Thomson <[email protected]> * Fix recent clippy errors on `master` (#941) * Fix needless borrows in codebase Signed-off-by: Thane Thomson <[email protected]> * Ignore needless collect warning (we do actually seem to need it) Signed-off-by: Thane Thomson <[email protected]> * Remove trailing semicolon in macro to fix docs compiling Signed-off-by: Thane Thomson <[email protected]> * Remove unnecessary macros Signed-off-by: Thane Thomson <[email protected]> * Correct error messages Signed-off-by: Thane Thomson <[email protected]> Co-authored-by: Thane Thomson <[email protected]> Co-authored-by: Thane Thomson <[email protected]>
* Implement thread-safe cloning of a secret connection Signed-off-by: Thane Thomson <[email protected]> * Expand documentation for SecretConnection on threading considerations Signed-off-by: Thane Thomson <[email protected]> * Extract peer construction into its own method Signed-off-by: Thane Thomson <[email protected]> * Add test for cloned SecretConnection This adds a `TcpStream`-based test for parallelizing operations on a `SecretConnection`. I used `TcpStream` instead of the buffered reader in the other tests because it wasn't feasible to implement the `TryClone` trait for that buffered pipe implementation. Signed-off-by: Thane Thomson <[email protected]> * Add more messages to test Signed-off-by: Thane Thomson <[email protected]> * Expand comment for clarity Signed-off-by: Thane Thomson <[email protected]> * Add .changelog entry Signed-off-by: Thane Thomson <[email protected]> * Restore half-duplex operations Signed-off-by: Thane Thomson <[email protected]> * Extract encrypt/decrypt fns as independent methods Signed-off-by: Thane Thomson <[email protected]> * Remove unnecessary trait bounds Signed-off-by: Thane Thomson <[email protected]> * Extract send/receive state Signed-off-by: Thane Thomson <[email protected]> * Extract read/write functionality as standalone methods Signed-off-by: Thane Thomson <[email protected]> * Add logic to facilitate splitting SecretConnection into its sending and receiving halves Signed-off-by: Thane Thomson <[email protected]> * Restore split SecretConnection test using new semantics Signed-off-by: Thane Thomson <[email protected]> * Update changelog entry Signed-off-by: Thane Thomson <[email protected]> * Update docs for `SecretConnection` Signed-off-by: Thane Thomson <[email protected]> * Condense error reporting Signed-off-by: Thane Thomson <[email protected]> * Extract TryClone trait into its own crate As per the discussion at informalsystems/tendermint-rs#938 (comment), this extracts the `TryClone` trait into a new crate called `tendermint-std-ext` in the `std-ext` directory. This new crate is intended to contain any code that we need that extends the Rust standard library. Signed-off-by: Thane Thomson <[email protected]> * Reorder imports Signed-off-by: Thane Thomson <[email protected]> * Assert validation regardless of debug build This introduces the internal encryption assertions at runtime regardless of build type. This may introduce a small performance hit, but it's probably worth it to ensure correctness. Effectively this is keeping an eye on the code in the `encrypt_and_write` fn to ensure its correctness. Signed-off-by: Thane Thomson <[email protected]> * Remove remote_pubkey optionality from sender/receiver halves Signed-off-by: Thane Thomson <[email protected]> * Update SecretConnection docs with comment content Signed-off-by: Thane Thomson <[email protected]> * Fix doc link to TryClone trait Signed-off-by: Thane Thomson <[email protected]> * Fix doc link to TryClone trait Signed-off-by: Thane Thomson <[email protected]> * Add docs on SecretConnection failures and connection integrity Signed-off-by: Thane Thomson <[email protected]> * Synchronize sending/receiving failures to comply with crypto algorithm constraints Signed-off-by: Thane Thomson <[email protected]> * Rename try_split method to split for SecretConnection Signed-off-by: Thane Thomson <[email protected]> * Remove redundant field name prefixes Signed-off-by: Thane Thomson <[email protected]> * Fix broken link in docs Signed-off-by: Thane Thomson <[email protected]>
* Use flex-error for tendermint * Use flex-error for p2p * Use flex-error for light-client * Use flex-error for light_client::predicates * Fix lint * Use flex-error for builder and io errors * Use flex-error for rpc errors * Use flex-error for protobuf errors * Use flex-error for abci * Fix test_bisection_no_witness_left * Fix build errors in all-features * Fix failing tests * Fix more failures * Fix tungstenite error under wasm target * Fix incoming_fixtures test * Fix conflict * Update flex-error to v0.4.0 * set std feature in flex-error instead of individual crates * Add flex-error patch to tools/Cargo.toml * Use published version of flex-error v0.4.1 * Enable flex-error/eyre_tracer feature by default * Add .changelog entry (#940) Signed-off-by: Thane Thomson <[email protected]> * flex-error: resolve conflicts with `master` (#945) * Implement full-duplex secret connection (#938) * Implement thread-safe cloning of a secret connection Signed-off-by: Thane Thomson <[email protected]> * Expand documentation for SecretConnection on threading considerations Signed-off-by: Thane Thomson <[email protected]> * Extract peer construction into its own method Signed-off-by: Thane Thomson <[email protected]> * Add test for cloned SecretConnection This adds a `TcpStream`-based test for parallelizing operations on a `SecretConnection`. I used `TcpStream` instead of the buffered reader in the other tests because it wasn't feasible to implement the `TryClone` trait for that buffered pipe implementation. Signed-off-by: Thane Thomson <[email protected]> * Add more messages to test Signed-off-by: Thane Thomson <[email protected]> * Expand comment for clarity Signed-off-by: Thane Thomson <[email protected]> * Add .changelog entry Signed-off-by: Thane Thomson <[email protected]> * Restore half-duplex operations Signed-off-by: Thane Thomson <[email protected]> * Extract encrypt/decrypt fns as independent methods Signed-off-by: Thane Thomson <[email protected]> * Remove unnecessary trait bounds Signed-off-by: Thane Thomson <[email protected]> * Extract send/receive state Signed-off-by: Thane Thomson <[email protected]> * Extract read/write functionality as standalone methods Signed-off-by: Thane Thomson <[email protected]> * Add logic to facilitate splitting SecretConnection into its sending and receiving halves Signed-off-by: Thane Thomson <[email protected]> * Restore split SecretConnection test using new semantics Signed-off-by: Thane Thomson <[email protected]> * Update changelog entry Signed-off-by: Thane Thomson <[email protected]> * Update docs for `SecretConnection` Signed-off-by: Thane Thomson <[email protected]> * Condense error reporting Signed-off-by: Thane Thomson <[email protected]> * Extract TryClone trait into its own crate As per the discussion at informalsystems/tendermint-rs#938 (comment), this extracts the `TryClone` trait into a new crate called `tendermint-std-ext` in the `std-ext` directory. This new crate is intended to contain any code that we need that extends the Rust standard library. Signed-off-by: Thane Thomson <[email protected]> * Reorder imports Signed-off-by: Thane Thomson <[email protected]> * Assert validation regardless of debug build This introduces the internal encryption assertions at runtime regardless of build type. This may introduce a small performance hit, but it's probably worth it to ensure correctness. Effectively this is keeping an eye on the code in the `encrypt_and_write` fn to ensure its correctness. Signed-off-by: Thane Thomson <[email protected]> * Remove remote_pubkey optionality from sender/receiver halves Signed-off-by: Thane Thomson <[email protected]> * Update SecretConnection docs with comment content Signed-off-by: Thane Thomson <[email protected]> * Fix doc link to TryClone trait Signed-off-by: Thane Thomson <[email protected]> * Fix doc link to TryClone trait Signed-off-by: Thane Thomson <[email protected]> * Add docs on SecretConnection failures and connection integrity Signed-off-by: Thane Thomson <[email protected]> * Synchronize sending/receiving failures to comply with crypto algorithm constraints Signed-off-by: Thane Thomson <[email protected]> * Rename try_split method to split for SecretConnection Signed-off-by: Thane Thomson <[email protected]> * Remove redundant field name prefixes Signed-off-by: Thane Thomson <[email protected]> * Fix broken link in docs Signed-off-by: Thane Thomson <[email protected]> * Fix recent clippy errors on `master` (#941) * Fix needless borrows in codebase Signed-off-by: Thane Thomson <[email protected]> * Ignore needless collect warning (we do actually seem to need it) Signed-off-by: Thane Thomson <[email protected]> * Remove trailing semicolon in macro to fix docs compiling Signed-off-by: Thane Thomson <[email protected]> * Remove unnecessary macros Signed-off-by: Thane Thomson <[email protected]> * Correct error messages Signed-off-by: Thane Thomson <[email protected]> Co-authored-by: Thane Thomson <[email protected]> Co-authored-by: Thane Thomson <[email protected]>
Work towards #814
Something like this is necessary for the MConnection to be able to safely read from and write to the underlying stream from multiple threads (e.g. one thread for reading, one thread for writing).
.changelog/