Skip to content

Fix Router Serialization Roundtrip #523

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

Merged

Conversation

TheBlueMatt
Copy link
Collaborator

In channel/node announcement/updates, we will read_to_end on the input stream to ensure we store any excess bytes at the end. This is great, until we try to go read a Router that contains a bunch of these messages in them, causing us to read data that is unrelated into the messages. To fix, we modify the Option format to write out the length of the object, and then use a LengthLimitingReader to read the T.

This requires we change the Readable trait to have a template in the read function instead of the trait due to lifetime issues, but this change stands on its own as it makes our Readable/Writeable traits symmetric.

@TheBlueMatt TheBlueMatt force-pushed the 2020-02-router-ser-fix branch from 566bd25 to 0a18f6f Compare February 28, 2020 20:24
@TheBlueMatt TheBlueMatt added this to the 0.0.11 milestone Feb 28, 2020
@TheBlueMatt TheBlueMatt force-pushed the 2020-02-router-ser-fix branch from 0a18f6f to 409ce89 Compare February 28, 2020 21:10
Copy link

@ariard ariard left a comment

Choose a reason for hiding this comment

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

ACK 409ce89

@TheBlueMatt TheBlueMatt force-pushed the 2020-02-router-ser-fix branch from 409ce89 to 4c36578 Compare March 4, 2020 04:04
@TheBlueMatt
Copy link
Collaborator Author

Addressed both comments, also neatly testing the router outbound initial syncs. Or, at least, that they terminate.

@TheBlueMatt TheBlueMatt force-pushed the 2020-02-router-ser-fix branch from 4c36578 to 636d96f Compare March 4, 2020 16:58
@Aleru
Copy link

Aleru commented Mar 4, 2020

ACK 636d96f, I compiled on my machine and the code makes sense to me.

This provides a simple wrapper for deserializing right into an
Arc<ChannelManager>, which improves UX a tiny bit when working with
SimpleArcChannelManager types.
This makes Readable symmetric with Writeable and makes sense -
something which is Readable should be Readable for any stream which
implements std::io::Read, not only for a stream type it decides on.

This solves some lifetime-compatibility issues in trying to read()
from a LengthLimitingReader in arbitrary Readable impls.
This is a cheap way to fix an error in Router serialization
roundtrip due to us calling read_to_end during the read of
channel/node announcement/updates. During normal message reading,
we only have limited bytes to read (specifically the message buffer)
so this is fine, however when we read them inside Router, we have
more data from other fields of the Router available as well. Thus,
we end up reading the entire rest of the Router into one message
field, and failing to deserialize.

Because such fields are always stored in Option<>s, we can simply
use a LengthLimitingStream in the Option<> serialization format and
make only the correct number of bytes available.

By using a variable-length integer for the new field, we avoid
wasting space compared to the existing serialization format.
This tests Router serialization round-trip at the end of each
functional test in the same way we do ChannelMonitors and
ChannelManagers to catch any cases where we were able to get into
a state which would have prevented reading a Router back off disk.

We further walk all of the announcements which both the original
and deserialized Routers would send to peers requesting initial
sync to ensure they match.
@TheBlueMatt TheBlueMatt force-pushed the 2020-02-router-ser-fix branch from 636d96f to 5f3986d Compare March 4, 2020 19:29
@TheBlueMatt
Copy link
Collaborator Author

Rebased on #534 without changes.

@codecov
Copy link

codecov bot commented Mar 4, 2020

Codecov Report

Merging #523 into master will increase coverage by 0.24%.
The diff coverage is 86.33%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #523      +/-   ##
==========================================
+ Coverage   89.73%   89.97%   +0.24%     
==========================================
  Files          33       33              
  Lines       19118    19150      +32     
==========================================
+ Hits        17156    17231      +75     
+ Misses       1962     1919      -43
Impacted Files Coverage Δ
lightning/src/ln/wire.rs 54.54% <100%> (ø) ⬆️
lightning/src/util/events.rs 21.83% <100%> (ø) ⬆️
lightning/src/ln/channelmonitor.rs 93.05% <100%> (+0.01%) ⬆️
lightning/src/ln/router.rs 88.8% <100%> (+3.24%) ⬆️
lightning/src/ln/chan_utils.rs 97.12% <100%> (ø) ⬆️
lightning/src/chain/keysinterface.rs 97.55% <100%> (ø) ⬆️
lightning/src/util/ser_macros.rs 96.59% <100%> (ø) ⬆️
lightning/src/util/enforcing_trait_impls.rs 100% <100%> (ø) ⬆️
lightning/src/ln/features.rs 96.62% <100%> (ø) ⬆️
lightning/src/ln/msgs.rs 83.56% <37.5%> (+1.22%) ⬆️
... and 6 more

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 c1dc8e3...5f3986d. Read the comment docs.

@TheBlueMatt TheBlueMatt merged commit e946357 into lightningdevkit:master Mar 4, 2020
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.

3 participants