Skip to content

Commit

Permalink
soroban-rpc: preflight: Exclude temporary expired entries from Snapsh…
Browse files Browse the repository at this point in the history
…otSource (#980)

* soroban-rpc: preflight: Exclude temporary expired entries from SnapshotSource

* Factor in get_including_persistent_expired

* Add specific error for expired entries and improve error check
  • Loading branch information
2opremio authored Sep 21, 2023
1 parent 8bdbbeb commit f011f52
Showing 1 changed file with 28 additions and 17 deletions.
45 changes: 28 additions & 17 deletions cmd/soroban-rpc/lib/preflight/src/ledger_storage.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use sha2::Digest;
use soroban_env_host::storage::SnapshotSource;
use soroban_env_host::xdr::ContractDataDurability::Persistent;
use soroban_env_host::xdr::ContractDataDurability::{Persistent, Temporary};
use soroban_env_host::xdr::{
ConfigSettingEntry, ConfigSettingId, Error as XdrError, ExpirationEntry, Hash, LedgerEntry,
LedgerEntryData, LedgerKey, LedgerKeyConfigSetting, LedgerKeyExpiration, ReadXdr, ScError,
Expand Down Expand Up @@ -28,6 +28,8 @@ extern "C" {
pub(crate) enum Error {
#[error("not found")]
NotFound,
#[error("entry expired")]
EntryExpired,
#[error("xdr processing error: {0}")]
Xdr(#[from] XdrError),
#[error("nul error: {0}")]
Expand All @@ -43,7 +45,9 @@ pub(crate) enum Error {
impl From<Error> for HostError {
fn from(value: Error) -> Self {
match value {
Error::NotFound => ScError::Storage(ScErrorCode::MissingValue).into(),
Error::NotFound | Error::EntryExpired => {
ScError::Storage(ScErrorCode::MissingValue).into()
}
Error::Xdr(_) => ScError::Value(ScErrorCode::InvalidInput).into(),
_ => ScError::Context(ScErrorCode::InternalError).into(),
}
Expand Down Expand Up @@ -182,7 +186,7 @@ impl LedgerStorage {
&& expiration_seq.is_some()
&& has_expired(expiration_seq.unwrap(), self.current_ledger_sequence)
{
return Err(Error::NotFound);
return Err(Error::EntryExpired);
}

let entry = LedgerEntry::from_xdr(xdr)?;
Expand Down Expand Up @@ -227,28 +231,35 @@ impl LedgerStorage {

impl SnapshotSource for LedgerStorage {
fn get(&self, key: &Rc<LedgerKey>) -> Result<(Rc<LedgerEntry>, Option<u32>), HostError> {
let mut entry_and_expiration =
<LedgerStorage>::get(self, key, self.restore_tracker.is_some())?;
if let Some(ref tracker) = self.restore_tracker {
let mut entry_and_expiration = self.get(key, true)?;
// Explicitly discard temporary expired entries
if let Ok(expirable_entry) =
TryInto::<Box<dyn ExpirableLedgerEntry>>::try_into(&entry_and_expiration)
{
if expirable_entry.durability() == Temporary
&& expirable_entry.has_expired(self.current_ledger_sequence)
{
return Err(HostError::from(Error::EntryExpired));
}
}
// If the entry expired, we modify the expiration to make it seem like it was restored
entry_and_expiration.1 =
tracker.track_and_restore(self.current_ledger_sequence, key, &entry_and_expiration);
return Ok((entry_and_expiration.0.into(), entry_and_expiration.1));
}
Ok((entry_and_expiration.0.into(), entry_and_expiration.1))
let entry_and_expiration =
<LedgerStorage>::get(self, key, false).map_err(HostError::from)?;
return Ok((entry_and_expiration.0.into(), entry_and_expiration.1));
}

fn has(&self, key: &Rc<LedgerKey>) -> Result<bool, HostError> {
let entry_and_expiration =
match <LedgerStorage>::get(self, key, self.restore_tracker.is_some()) {
Err(e) => match e {
Error::NotFound => return Ok(false),
_ => return Err(HostError::from(e)),
},
Ok(le) => le,
};
if let Some(ref tracker) = self.restore_tracker {
_ = tracker.track_and_restore(self.current_ledger_sequence, key, &entry_and_expiration);
let result = <dyn SnapshotSource>::get(self, key);
if let Err(ref host_error) = result {
if host_error.error.is_code(ScErrorCode::MissingValue) {
return Ok(false);
}
}
Ok(true)
return result.map(|_| true);
}
}

0 comments on commit f011f52

Please sign in to comment.