use crate::FastHashSet;
use anchor_lang::solana_program::instruction::Instruction;
use solana_pubkey::Pubkey;
pub struct DirtyTracker {
writable: FastHashSet<Pubkey>,
read_only: FastHashSet<Pubkey>,
clock_dirty: bool,
pub clock_target_slot: Option<u64>,
}
impl DirtyTracker {
pub fn new() -> Self {
Self {
writable: FastHashSet::default(),
read_only: FastHashSet::default(),
clock_dirty: false,
clock_target_slot: None,
}
}
#[inline]
pub fn record_tx(&mut self, instructions: &[Instruction], fee_payer: &Pubkey) {
self.writable.insert(*fee_payer);
for ix in instructions {
self.read_only.insert(ix.program_id);
for meta in &ix.accounts {
if meta.is_writable {
self.writable.insert(meta.pubkey);
} else {
self.read_only.insert(meta.pubkey);
}
}
}
}
pub fn mark_clock_dirty(&mut self, target_slot: u64) {
self.clock_dirty = true;
self.clock_target_slot = Some(target_slot);
}
pub fn mark_account_dirty(&mut self, pubkey: &Pubkey) {
self.writable.insert(*pubkey);
}
pub fn dirty_accounts(&self) -> &FastHashSet<Pubkey> {
&self.writable
}
pub fn read_accounts(&self) -> &FastHashSet<Pubkey> {
&self.read_only
}
pub fn dirty_count(&self) -> usize {
self.writable.len()
}
pub fn is_clock_dirty(&self) -> bool {
self.clock_dirty
}
pub fn clear(&mut self) {
self.writable.clear();
self.read_only.clear();
self.clock_dirty = false;
self.clock_target_slot = None;
}
}
impl Clone for DirtyTracker {
fn clone(&self) -> Self {
Self::new()
}
}