-
Notifications
You must be signed in to change notification settings - Fork 385
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
Scorer serialization #1146
Scorer serialization #1146
Conversation
Codecov Report
@@ Coverage Diff @@
## main #1146 +/- ##
==========================================
- Coverage 90.22% 90.15% -0.07%
==========================================
Files 70 70
Lines 36361 36224 -137
==========================================
- Hits 32805 32658 -147
- Misses 3556 3566 +10
Continue to review full report at Codecov.
|
I'm not really sure if I buy that we care about |
bc516ff
to
fc1323b
Compare
I made I'm gonna need the parameterization to test this, though, so there really isn't much extra needed to support no-std. I think it's mostly just one line of code in |
lightning/src/routing/scorer.rs
Outdated
fn elapsed(&self) -> Duration; | ||
} | ||
|
||
impl<C: Clock + Sub<Duration, Output = C>> ScorerUsingClock<C> { |
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.
Why not just make the Sub
requirement a direct parent of Clock
?
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 point. Done!
fc1323b
to
d465e4a
Compare
lightning/src/routing/scorer.rs
Outdated
#[inline] | ||
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> { | ||
self.undecayed_penalty_msat.write(w)?; | ||
(duration_since_epoch() - self.last_failed.elapsed()).write(w) |
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.
Hmm, I wonder if we should document somewhere that an LDK node serialized by std
should never be deserialized by no-std
and vice versa. Seems like some weird negative durations could occur here in those situations
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.
Updated docs about mixing types being undefined. Also, moved duration_since_epoch
into Time
trait to make the association clearer.
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.
Shaping up! Just these last few comments I think.
lightning/src/routing/scorer.rs
Outdated
channel_failures: HashMap<u64, (u64, Instant)>, | ||
#[cfg(feature = "no-std")] | ||
channel_failures: HashMap<u64, u64>, | ||
channel_failures: HashMap<u64, ChannelFailure<C>>, |
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.
Wondering if we'll need a mutex/multi-threaded access to channel_failures
if we're gonna be persisting it in the background
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.
No need to change anything since the scorer will be accessed using a LockableScore
(e.g., a Mutex
).
lightning/src/routing/scorer.rs
Outdated
channel_failures: HashMap<u64, (u64, Instant)>, | ||
#[cfg(feature = "no-std")] | ||
channel_failures: HashMap<u64, u64>, | ||
channel_failures: HashMap<u64, ChannelFailure<C>>, |
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.
Seems self.channel_failures
may grow over time, may be nice to have a TODO for pruning 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.
Good observation. I suppose a scorer should be notified of changes to the NetworkGraph
to allow for this. Added a TODO.
lightning/src/routing/scorer.rs
Outdated
/// A clock that is always present, now or after time has passed. | ||
pub struct AlwaysPresent; | ||
|
||
impl Clock for AlwaysPresent { |
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.
IMO Instant
would be clearer than Clock
for this API, though not sure what ScorerUsingClock
would be renamed to 🤔
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.
Renamed Clock
to Time
which is more consistent with how SystemTime
and Instant
are described. Also, renamed AlwaysPresent
to Eternity
(i.e., where time has no meaning) since "present" in the former could have been read with a different meaning (e.g., a field that is always present).
This also will work better with testing where time will be read from a Clock
, which the tests will advance as needed.
5713d28
to
73ffbcf
Compare
73ffbcf
to
960854c
Compare
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.
LGTM!
I think a new warning may have been introduced ("unused variable: network_graph
")
lightning/src/routing/scorer.rs
Outdated
fn now() -> Self; | ||
|
||
/// Returns the amount of time elapsed since the clock was created. | ||
/// Returns the amount of time elapsed since created. |
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.
nit: prefer slightly more explicit "since this Time
instance was created"
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.
Used the less verbose self
.
/// # Note | ||
/// | ||
/// When time is an [`Eternity`], as is default when enabling feature `no-std`, it will never | ||
/// elapse. Therefore, this penalty will never decay. |
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.
nit: s/this penalty/failure_penalty_msat
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.
That wouldn't be accurate since failure_penalty_msat
is added each time the channel fails to relay a payment, i.e., "this penalty" is referring to "any accumulated channel failure penalties". I've re-worded a bit and included a link to failure_penalty_msat
.
960854c
to
6f9c9e5
Compare
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.
Can you squash?
Move channel failure penalty logic into a ChannelFailure abstraction. This encapsulates the logic for accumulating penalties and decaying them over time. It also is responsible for the no-std behavior. This cleans up Scorer and will make it easier to serialize it.
Scorer uses time to determine how much to penalize a channel after a failure occurs. Parameterizing it by time cleans up the code such that no-std support is in a single AlwaysPresent struct, which implements the Time trait. Time is implemented for std::time::Instant when std is available. This parameterization also allows for deterministic testing since a clock could be devised to advance forward as needed.
Scorer should be serialized to retain penalty data between restarts. Implement (de)serialization for Scorer by serializing last failure times as duration since the UNIX epoch. For no-std, the zero-Duration is used.
6f9c9e5
to
ae210e7
Compare
Squashed without diff, will land after CI:
|
Scorer
should be serialized to retain penalty data between restarts. Implement (de)serialization forScorer
by serializing last failure times as duration since the UNIX epoch. For no-std, the zero-Duration
is used.Parameterize
Scorer
with a newClock
trait to simplify no-std support and allow for tesing without using a real clock.Based on #1144.
TODO: Test
Scorer
now that it can be parameterized by a fakeClock
.