Skip to content

Commit

Permalink
Add a scoring decay method to the ScoreUpdate trait
Browse files Browse the repository at this point in the history
Rather than relying on fetching the current time during
routefinding, here we introduce a new trait method to `ScoreUpdate`
to do so. This largely mirrors what we do with the `NetworkGraph`,
and allows us to take on much more expensive operations (floating
point exponentiation) in our decaying.
  • Loading branch information
TheBlueMatt committed Dec 13, 2023
1 parent 6c366cf commit b84842a
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 2 deletions.
21 changes: 19 additions & 2 deletions lightning-background-processor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ macro_rules! define_run_body {
let mut last_scorer_persist_call = $get_timer(SCORER_PERSIST_TIMER);
let mut last_rebroadcast_call = $get_timer(REBROADCAST_TIMER);
let mut have_pruned = false;
let mut have_decayed_scorer = false;

loop {
$process_channel_manager_events;
Expand Down Expand Up @@ -401,9 +402,24 @@ macro_rules! define_run_body {
last_prune_call = $get_timer(prune_timer);
}

if !have_decayed_scorer {
if let Some(ref scorer) = $scorer {
if let Some(duration_since_epoch) = $time_fetch() {
log_trace!($logger, "Calling time_passed on scorer at startup");
scorer.write_lock().time_passed(duration_since_epoch);
}
}
have_decayed_scorer = true;
}

if $timer_elapsed(&mut last_scorer_persist_call, SCORER_PERSIST_TIMER) {
if let Some(ref scorer) = $scorer {
log_trace!($logger, "Persisting scorer");
if let Some(duration_since_epoch) = $time_fetch() {
log_trace!($logger, "Calling time_passed and persisting scorer");
scorer.write_lock().time_passed(duration_since_epoch);
} else {
log_trace!($logger, "Persisting scorer");
}
if let Err(e) = $persister.persist_scorer(&scorer) {
log_error!($logger, "Error: Failed to persist scorer, check your disk and permissions {}", e)
}
Expand Down Expand Up @@ -1208,6 +1224,7 @@ mod tests {
}
}
}
fn time_passed(&mut self, _: Duration) {}
}

#[cfg(c_bindings)]
Expand Down Expand Up @@ -1616,7 +1633,7 @@ mod tests {

loop {
let log_entries = nodes[0].logger.lines.lock().unwrap();
let expected_log = "Persisting scorer".to_string();
let expected_log = "Calling time_passed and persisting scorer".to_string();
if log_entries.get(&("lightning_background_processor", expected_log)).is_some() {
break
}
Expand Down
18 changes: 18 additions & 0 deletions lightning/src/routing/scoring.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,12 @@ pub trait ScoreUpdate {

/// Handles updating channel penalties after a probe over the given path succeeded.
fn probe_successful(&mut self, path: &Path, duration_since_epoch: Duration);

/// Scorers may wish to reduce their certainty of channel liquidity information over time.
/// Thus, this method is provided to allow scorers to observe the passage of time - the holder
/// of this object should call this method regularly (generally via the
/// `lightning-background-processor` crate).
fn time_passed(&mut self, duration_since_epoch: Duration);
}

/// A trait which can both lookup and update routing channel penalty scores.
Expand Down Expand Up @@ -160,6 +166,10 @@ impl<S: ScoreUpdate, T: DerefMut<Target=S>> ScoreUpdate for T {
fn probe_successful(&mut self, path: &Path, duration_since_epoch: Duration) {
self.deref_mut().probe_successful(path, duration_since_epoch)
}

fn time_passed(&mut self, duration_since_epoch: Duration) {
self.deref_mut().time_passed(duration_since_epoch)
}
}
} }

Expand Down Expand Up @@ -361,6 +371,10 @@ impl<'a, T: Score> ScoreUpdate for MultiThreadedScoreLockWrite<'a, T> {
fn probe_successful(&mut self, path: &Path, duration_since_epoch: Duration) {
self.0.probe_successful(path, duration_since_epoch)
}

fn time_passed(&mut self, duration_since_epoch: Duration) {
self.0.time_passed(duration_since_epoch)
}
}


Expand Down Expand Up @@ -406,6 +420,8 @@ impl ScoreUpdate for FixedPenaltyScorer {
fn probe_failed(&mut self, _path: &Path, _short_channel_id: u64, _duration_since_epoch: Duration) {}

fn probe_successful(&mut self, _path: &Path, _duration_since_epoch: Duration) {}

fn time_passed(&mut self, _duration_since_epoch: Duration) {}
}

impl Writeable for FixedPenaltyScorer {
Expand Down Expand Up @@ -1463,6 +1479,8 @@ impl<G: Deref<Target = NetworkGraph<L>>, L: Deref, T: Time> ScoreUpdate for Prob
fn probe_successful(&mut self, path: &Path, duration_since_epoch: Duration) {
self.payment_path_failed(path, u64::max_value(), duration_since_epoch)
}

fn time_passed(&mut self, _duration_since_epoch: Duration) {}
}

#[cfg(c_bindings)]
Expand Down
2 changes: 2 additions & 0 deletions lightning/src/util/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1357,6 +1357,8 @@ impl ScoreUpdate for TestScorer {
fn probe_failed(&mut self, _actual_path: &Path, _: u64, _duration_since_epoch: Duration) {}

fn probe_successful(&mut self, _actual_path: &Path, _duration_since_epoch: Duration) {}

fn time_passed(&mut self, _duration_since_epoch: Duration) {}
}

impl Drop for TestScorer {
Expand Down

0 comments on commit b84842a

Please sign in to comment.