From b4b5d44c4fc088bafbc89ccd38cfa713d5c3554b Mon Sep 17 00:00:00 2001 From: MicaiahReid Date: Tue, 15 Apr 2025 23:06:00 -0400 Subject: [PATCH 1/4] fix(litesvm): update `expire_blockhashes` fn to keep recent blockhashes in sysvars --- crates/litesvm/src/lib.rs | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/crates/litesvm/src/lib.rs b/crates/litesvm/src/lib.rs index 5e88bdc2d..d63d4a7a5 100644 --- a/crates/litesvm/src/lib.rs +++ b/crates/litesvm/src/lib.rs @@ -255,6 +255,7 @@ much easier. #[cfg(feature = "nodejs-internal")] use qualifier_attr::qualifiers; +use solana_clock::MAX_RECENT_BLOCKHASHES; #[allow(deprecated)] use solana_sysvar::recent_blockhashes::IterItem; #[allow(deprecated)] @@ -1234,11 +1235,27 @@ impl LiteSVM { pub fn expire_blockhash(&mut self) { self.latest_blockhash = create_blockhash(&self.latest_blockhash.to_bytes()); #[allow(deprecated)] - self.set_sysvar(&RecentBlockhashes::from_iter([IterItem( - 0, - &self.latest_blockhash, - self.fee_structure.lamports_per_signature, - )])); + { + let blockhashes = self.get_sysvar::(); + let mut entries = vec![]; + entries.push(IterItem( + 0, + &self.latest_blockhash, + self.fee_structure.lamports_per_signature, + )); + for (i, entry) in blockhashes.iter().enumerate() { + if i == MAX_RECENT_BLOCKHASHES - 1 { + break; + } + entries.push(IterItem( + i as u64 + 1, + &entry.blockhash, + entry.fee_calculator.lamports_per_signature, + )); + } + + self.set_sysvar(&RecentBlockhashes::from_iter(entries)); + } } /// Warps the clock to the specified slot. From 60022bb315a5e4795ef193ed0c14492e29a51214 Mon Sep 17 00:00:00 2001 From: MicaiahReid Date: Tue, 15 Apr 2025 23:06:23 -0400 Subject: [PATCH 2/4] fix(litesvm): check all recent blockhashes when checking tx age --- crates/litesvm/src/lib.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/crates/litesvm/src/lib.rs b/crates/litesvm/src/lib.rs index d63d4a7a5..420067210 100644 --- a/crates/litesvm/src/lib.rs +++ b/crates/litesvm/src/lib.rs @@ -1292,7 +1292,7 @@ impl LiteSVM { tx: &SanitizedTransaction, ) -> solana_transaction_error::TransactionResult<()> { let recent_blockhash = tx.message().recent_blockhash(); - if recent_blockhash == &self.latest_blockhash + if self.check_blockhash_is_recent(recent_blockhash) || self.check_transaction_for_nonce( tx, &DurableNonce::from_blockhash(&self.latest_blockhash), @@ -1309,6 +1309,13 @@ impl LiteSVM { } } + fn check_blockhash_is_recent(&self, recent_blockhash: &Hash) -> bool { + #[allow(deprecated)] + self.get_sysvar::() + .iter() + .any(|entry| entry.blockhash == *recent_blockhash) + } + fn check_message_for_nonce(&self, message: &SanitizedMessage) -> bool { message .get_durable_nonce() From 522095009711b701ca0034969cea61a3d0f0717d Mon Sep 17 00:00:00 2001 From: MicaiahReid Date: Fri, 18 Apr 2025 09:58:19 -0400 Subject: [PATCH 3/4] chore(litesvm): initialize recent blockhashes entries with capacity --- crates/litesvm/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/litesvm/src/lib.rs b/crates/litesvm/src/lib.rs index 420067210..a1f54f505 100644 --- a/crates/litesvm/src/lib.rs +++ b/crates/litesvm/src/lib.rs @@ -1237,7 +1237,8 @@ impl LiteSVM { #[allow(deprecated)] { let blockhashes = self.get_sysvar::(); - let mut entries = vec![]; + let max_entries_len = blockhashes.len().min(MAX_RECENT_BLOCKHASHES); + let mut entries = Vec::with_capacity(max_entries_len); entries.push(IterItem( 0, &self.latest_blockhash, From d0a3b619fd5a5233884fbabc22a56879ecd43fc9 Mon Sep 17 00:00:00 2001 From: MicaiahReid Date: Fri, 18 Apr 2025 09:59:25 -0400 Subject: [PATCH 4/4] chore: cargo fmt --- crates/litesvm/src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crates/litesvm/src/lib.rs b/crates/litesvm/src/lib.rs index a1f54f505..32059d392 100644 --- a/crates/litesvm/src/lib.rs +++ b/crates/litesvm/src/lib.rs @@ -255,7 +255,6 @@ much easier. #[cfg(feature = "nodejs-internal")] use qualifier_attr::qualifiers; -use solana_clock::MAX_RECENT_BLOCKHASHES; #[allow(deprecated)] use solana_sysvar::recent_blockhashes::IterItem; #[allow(deprecated)] @@ -280,7 +279,7 @@ use { create_program_runtime_environment_v1, create_program_runtime_environment_v2, }, solana_builtins::BUILTINS, - solana_clock::Clock, + solana_clock::{Clock, MAX_RECENT_BLOCKHASHES}, solana_compute_budget::{ compute_budget::ComputeBudget, compute_budget_limits::ComputeBudgetLimits, },