Skip to content

Commit

Permalink
mitigate the endless loop that occurred when transfers can't be prope…
Browse files Browse the repository at this point in the history
…rly sorted
  • Loading branch information
jaensen committed Sep 6, 2023
1 parent 159a951 commit ed04007
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 4 deletions.
19 changes: 15 additions & 4 deletions src/graph/flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ fn create_sorted_transfers(
let simplified_transfers = simplify_transfers(transfers);
call_context.log_message(format!("After simplification: {}", simplified_transfers.len()).as_str());

sort_transfers(simplified_transfers)
sort_transfers(call_context, simplified_transfers)
}

fn find_pair_to_simplify(transfers: &Vec<Edge>) -> Option<(usize, usize)> {
Expand All @@ -208,7 +208,7 @@ fn simplify_transfers(mut transfers: Vec<Edge>) -> Vec<Edge> {
transfers
}

fn sort_transfers(transfers: Vec<Edge>) -> Vec<Edge> {
fn sort_transfers(context:&CallContext, transfers: Vec<Edge>) -> Vec<Edge> {
// We have to sort the transfers to satisfy the following condition:
// A user can send away their own tokens only after it has received all (trust) transfers.

Expand All @@ -217,15 +217,26 @@ fn sort_transfers(transfers: Vec<Edge>) -> Vec<Edge> {
*receives_to_wait_for.entry(e.to).or_default() += 1;
receives_to_wait_for.entry(e.from).or_default();
}

let mut result = Vec::new();
let mut queue = transfers.into_iter().collect::<VecDeque<Edge>>();
let mut no_progress_counter = 0; // counts iterations without progress

while let Some(e) = queue.pop_front() {
//println!("queue size: {}", queue.len());
if *receives_to_wait_for.get(&e.from).unwrap() == 0 {
*receives_to_wait_for.get_mut(&e.to).unwrap() -= 1;
result.push(e)
result.push(e);
no_progress_counter = 0; // reset counter when we make progress
} else {
queue.push_back(e);
no_progress_counter += 1;

// If we've looped through all entries without progress, break
if no_progress_counter == queue.len() {
context.log_message(format!("Loop detected! No valid order can be found.").as_str());
result.clear();
break;
}
}
}
result
Expand Down
4 changes: 4 additions & 0 deletions src/rpc/call_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ impl CallContext {
pub fn log_message(&self, message: &str) {
self.log(" ", Some(&format!(" {}", message)), None);
}

pub fn log_warning(&self, message: &str) {
self.log(" ! ", Some(&format!(" {}", message)), None);
}
}

impl Drop for CallContext {
Expand Down

0 comments on commit ed04007

Please sign in to comment.