diff --git a/CHANGELOG.md b/CHANGELOG.md index ea0bddf9..cdb4a63c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### Fixed +- Keep the sysvar cache unchanged when `LiteSVM::set_account` rejects invalid sysvar data. The rejected write used to drop that sysvar from the cache, so the next transaction panicked ([#436](https://github.com/LiteSVM/litesvm/pull/436)). - Return an error instead of panicking from `litesvm_token::get_spl_account` (and the `*Checked` token helpers that read the mint through it) when the account data is shorter than the requested state ([#433](https://github.com/LiteSVM/litesvm/pull/433)). ## [0.18.0] - 2026-10-09 diff --git a/crates/litesvm/src/accounts_db.rs b/crates/litesvm/src/accounts_db.rs index 320797d9..894d0adf 100644 --- a/crates/litesvm/src/accounts_db.rs +++ b/crates/litesvm/src/accounts_db.rs @@ -60,6 +60,7 @@ fn handle_sysvar( where T: Sysvar + DeserializeOwned, { + let _parsed = T::deserialize_from(account.data()).map_err(|_| err_variant)?; cache.reset(); cache.fill_missing_entries(|pubkey, set_sysvar| { if *pubkey == address { @@ -68,7 +69,6 @@ where set_sysvar(acc.data()) } }); - let _parsed = T::deserialize_from(account.data()).map_err(|_| err_variant)?; Ok(()) } diff --git a/crates/litesvm/tests/rent.rs b/crates/litesvm/tests/rent.rs index bf728fa8..b1de82bc 100644 --- a/crates/litesvm/tests/rent.rs +++ b/crates/litesvm/tests/rent.rs @@ -6,7 +6,10 @@ use { FeatureSet, }, litesvm::LiteSVM, + solana_account::Account, + solana_address::Address, solana_rent::{Rent, DEFAULT_LAMPORTS_PER_BYTE}, + solana_sdk_ids::sysvar, }; fn rent_with(feature_set: FeatureSet) -> Rent { @@ -84,3 +87,20 @@ fn legacy_rent_representation_without_the_threshold_feature() { Rent::default().minimum_balance(123) ); } + +#[test] +fn rejected_rent_write_keeps_the_cached_rent() { + let mut svm = LiteSVM::new(); + let min_balance = svm.minimum_balance_for_rent_exemption(0); + let invalid_rent = Account { + lamports: 1, + data: vec![0; 3], + owner: sysvar::id(), + executable: false, + rent_epoch: 0, + }; + + assert!(svm.set_account(sysvar::rent::id(), invalid_rent).is_err()); + assert_eq!(svm.minimum_balance_for_rent_exemption(0), min_balance); + svm.airdrop(&Address::new_unique(), min_balance).unwrap(); +}