Sort transfers.

This commit is contained in:
chriseth 2022-12-21 13:16:55 +01:00
parent ffba4f1f4c
commit 4171afe31e

View file

@ -3,8 +3,8 @@ use crate::graph::{as_trust_node, Node};
use crate::types::edge::EdgeDB; use crate::types::edge::EdgeDB;
use crate::types::{Address, Edge, U256}; use crate::types::{Address, Edge, U256};
use std::cmp::min; use std::cmp::min;
use std::collections::VecDeque; use std::collections::{BTreeMap, HashSet};
use std::collections::{BTreeMap, HashMap, HashSet}; use std::collections::{HashMap, VecDeque};
use std::fmt::Write; use std::fmt::Write;
pub fn compute_flow( pub fn compute_flow(
@ -67,7 +67,8 @@ pub fn compute_flow(
println!("Num transfers: {}", transfers.len()); println!("Num transfers: {}", transfers.len());
let simplified_transfers = simplify_transfers(transfers); let simplified_transfers = simplify_transfers(transfers);
println!("After simplification: {}", simplified_transfers.len()); println!("After simplification: {}", simplified_transfers.len());
(flow, simplified_transfers) let sorted_transfers = sort_transfers(simplified_transfers);
(flow, sorted_transfers)
} }
pub fn transfers_to_dot(edges: &Vec<Edge>) -> String { pub fn transfers_to_dot(edges: &Vec<Edge>) -> String {
@ -486,6 +487,29 @@ fn simplify_transfers(mut transfers: Vec<Edge>) -> Vec<Edge> {
.collect::<Vec<_>>() .collect::<Vec<_>>()
} }
fn sort_transfers(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.
let mut receives_to_wait_for: HashMap<Address, u64> = HashMap::new();
for e in &transfers {
*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>>();
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)
} else {
queue.push_back(e);
}
}
result
}
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::*; use super::*;