Skip to content

Commit

Permalink
ChainData: update account InsertAfter bug (#30)
Browse files Browse the repository at this point in the history
ChainData: update account InsertAfter bug
  • Loading branch information
farnyser authored Aug 15, 2024
1 parent 0d1f700 commit 126c2aa
Showing 1 changed file with 83 additions and 16 deletions.
99 changes: 83 additions & 16 deletions connector/src/chain_data.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use crate::chain_data::SlotVectorEffect::*;
use log::{info, trace};
use log::trace;
use smallvec::{smallvec, SmallVec};
use solana_sdk::clock::Slot;
use warp::trace;
use {
solana_sdk::account::{AccountSharedData, ReadableAccount},
solana_sdk::pubkey::Pubkey,
Expand All @@ -13,6 +12,7 @@ use crate::metrics::*;

#[derive(Clone, Copy, Debug, PartialEq)]
pub enum SlotStatus {
// aka Finalized
Rooted,
Confirmed,
Processed,
Expand Down Expand Up @@ -85,7 +85,12 @@ impl Default for ChainData {
impl ChainData {
#[tracing::instrument(skip_all, level = "trace")]
pub fn update_slot(&mut self, new_slotdata: SlotData) {
let SlotData { slot: new_slot, parent: new_parent, status: new_status, .. } = new_slotdata;
let SlotData {
slot: new_slot,
parent: new_parent,
status: new_status,
..
} = new_slotdata;

trace!("update_slot from newslot {:?}", new_slot);
let new_processed_head = new_slot > self.newest_processed_slot;
Expand Down Expand Up @@ -121,12 +126,22 @@ impl ChainData {
let v = o.into_mut();
parent_update = v.parent != new_parent && new_parent.is_some();
if parent_update {
trace!("update parent of slot {}: {}->{}", new_slot, v.parent.unwrap_or(0), new_parent.unwrap_or(0));
trace!(
"update parent of slot {}: {}->{}",
new_slot,
v.parent.unwrap_or(0),
new_parent.unwrap_or(0)
);
}
v.parent = v.parent.or(new_parent);
// Never decrease the slot status
if v.status == SlotStatus::Processed || new_status == SlotStatus::Rooted {
trace!("update status of slot {}: {:?}->{:?}", new_slot, v.status, new_status);
trace!(
"update status of slot {}: {:?}->{:?}",
new_slot,
v.status,
new_status
);
v.status = new_status;
}
}
Expand Down Expand Up @@ -176,12 +191,11 @@ impl ChainData {
self.best_chain_slot,
&self.slots,
)
.map(|w| w.slot)
// no rooted write found: produce no effect, since writes > newest_rooted_slot are retained anyway
.unwrap_or(self.newest_rooted_slot + 1);
writes.retain(|w| {
w.slot == newest_rooted_write_slot || w.slot > self.newest_rooted_slot
});
.map(|w| w.slot)
// no rooted write found: produce no effect, since writes > newest_rooted_slot are retained anyway
.unwrap_or(self.newest_rooted_slot + 1);
writes
.retain(|w| w.slot == newest_rooted_write_slot || w.slot > self.newest_rooted_slot);
self.account_versions_stored += writes.len();
self.account_bytes_stored +=
writes.iter().map(|w| w.account.data().len()).sum::<usize>()
Expand Down Expand Up @@ -223,7 +237,7 @@ impl ChainData {
InsertAfter(pos) => {
self.account_versions_stored += 1;
self.account_bytes_stored += account.account.data().len();
v.insert(pos, account);
v.insert(pos + 1, account);
}
DoNothing => {}
}
Expand All @@ -244,6 +258,7 @@ impl ChainData {
.unwrap_or(write.slot <= self.newest_rooted_slot || write.slot > self.best_chain_slot)
}

// rooted=finalized
fn newest_rooted_write<'a>(
writes: &'a [AccountData],
newest_rooted_slot: u64,
Expand Down Expand Up @@ -328,6 +343,7 @@ impl ChainData {
self.best_chain_slot
}

// aka newest finalized
pub fn newest_rooted_slot(&self) -> u64 {
self.newest_rooted_slot
}
Expand Down Expand Up @@ -431,15 +447,67 @@ impl ChainDataMetrics {

#[cfg(test)]
mod tests {
use std::path::PathBuf;
use crate::chain_data::{update_slotvec_logic, SlotVectorEffect::*};
use crate::chain_data::{AccountData, ChainData, SlotData, SlotStatus};
use solana_sdk::account::{AccountSharedData, ReadableAccount};
use solana_sdk::clock::Slot;
use solana_sdk::pubkey::Pubkey;
use std::str::FromStr;
use csv::ReaderBuilder;
use solana_sdk::commitment_config::CommitmentLevel;

#[test]
pub fn test_loosing_account_write() {
let owner = Pubkey::from_str("675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8").unwrap();
let my_account = Pubkey::new_unique();
let mut chain_data = ChainData::new();

chain_data.update_account(
my_account,
AccountData {
slot: 123,
write_version: 1,
account: AccountSharedData::new(100, 100 /*space*/, &owner),
},
j,
);

chain_data.update_slot(SlotData {
slot: 123,
parent: None,
status: SlotStatus::Rooted, // =finalized
chain: 0,
});

chain_data.update_account(
my_account,
AccountData {
slot: 128,
write_version: 1,
account: AccountSharedData::new(101, 101 /*space*/, &owner),
},
);

chain_data.update_slot(SlotData {
slot: 128,
parent: Some(123),
status: SlotStatus::Processed,
chain: 0,
});

assert_eq!(chain_data.newest_rooted_slot(), 123);
assert_eq!(chain_data.best_chain_slot(), 128);
assert_eq!(chain_data.account(&my_account).unwrap().slot, 128);

chain_data.update_slot(SlotData {
slot: 129,
parent: Some(128),
status: SlotStatus::Processed,
chain: 0,
});

assert_eq!(chain_data.newest_rooted_slot(), 123);
assert_eq!(chain_data.best_chain_slot(), 129);
assert_eq!(chain_data.account(&my_account).unwrap().slot, 128);
}

#[test]
pub fn test_move_slot_to_finalized() {
Expand Down Expand Up @@ -672,5 +740,4 @@ mod tests {
},
]
}

}

0 comments on commit 126c2aa

Please sign in to comment.