-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* limit assets per address * evict old values * improve testing * make dispensed map thread local * update rust version * make tokio test-util a dev dep * evict less than day * more review comments * add dispense tracker * use mark_in_progress * remove from in progress on err * Update tests/dispense.rs Co-authored-by: Brandon Vrooman <brandon.vrooman@gmail.com> * only track if tx succeeds * remove on empty wallet * make sure to remove in prog on the right err --------- Co-authored-by: Brandon Vrooman <brandon.vrooman@gmail.com>
- Loading branch information
Showing
8 changed files
with
341 additions
and
77 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
use std::{ | ||
cmp::Ordering, | ||
collections::{BinaryHeap, HashMap, HashSet}, | ||
}; | ||
|
||
use fuel_types::Address; | ||
|
||
#[derive(Debug, Eq, PartialEq)] | ||
pub struct Entry { | ||
address: Address, | ||
timestamp: u64, | ||
} | ||
|
||
impl Ord for Entry { | ||
fn cmp(&self, other: &Self) -> Ordering { | ||
other.timestamp.cmp(&self.timestamp) | ||
} | ||
} | ||
|
||
impl PartialOrd for Entry { | ||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> { | ||
Some(self.cmp(other)) | ||
} | ||
} | ||
|
||
pub trait Clock: std::fmt::Debug + Send + Sync { | ||
fn now(&self) -> u64; | ||
} | ||
|
||
#[derive(Debug)] | ||
pub struct TokioTime {} | ||
|
||
impl Clock for TokioTime { | ||
fn now(&self) -> u64 { | ||
tokio::time::Instant::now().elapsed().as_secs() | ||
} | ||
} | ||
|
||
#[derive(Debug)] | ||
pub struct DispenseTracker { | ||
tracked: HashMap<Address, u64>, | ||
queue: BinaryHeap<Entry>, | ||
in_progress: HashSet<Address>, | ||
clock: Box<dyn Clock>, | ||
} | ||
|
||
impl Default for DispenseTracker { | ||
fn default() -> Self { | ||
Self { | ||
tracked: HashMap::default(), | ||
queue: BinaryHeap::default(), | ||
in_progress: HashSet::default(), | ||
clock: Box::new(TokioTime {}), | ||
} | ||
} | ||
} | ||
|
||
impl DispenseTracker { | ||
pub fn new(clock: impl Clock + 'static) -> Self { | ||
Self { | ||
tracked: HashMap::new(), | ||
queue: BinaryHeap::new(), | ||
in_progress: HashSet::new(), | ||
clock: Box::new(clock), | ||
} | ||
} | ||
|
||
pub fn track(&mut self, address: Address) { | ||
self.in_progress.remove(&address); | ||
|
||
let timestamp = self.clock.now(); | ||
self.tracked.insert(address, timestamp); | ||
self.queue.push(Entry { address, timestamp }); | ||
} | ||
|
||
pub fn mark_in_progress(&mut self, address: Address) { | ||
self.in_progress.insert(address); | ||
} | ||
|
||
pub fn remove_in_progress(&mut self, address: &Address) { | ||
self.in_progress.remove(address); | ||
} | ||
|
||
pub fn evict_expired_entries(&mut self, eviction_duration: u64) { | ||
let now = self.clock.now(); | ||
|
||
while let Some(oldest_entry) = self.queue.peek() { | ||
if now - oldest_entry.timestamp > eviction_duration { | ||
let removed_entry = self.queue.pop().unwrap(); | ||
self.tracked.remove(&removed_entry.address); | ||
} else { | ||
break; | ||
} | ||
} | ||
} | ||
|
||
pub fn has_tracked(&self, address: &Address) -> bool { | ||
self.tracked.get(address).is_some() || self.in_progress.contains(address) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.