From a0d74b499d10743ead05722fd2bf6b3681b8f5fe Mon Sep 17 00:00:00 2001 From: jason-nitro Date: Thu, 31 Jul 2025 16:12:21 -0500 Subject: [PATCH 01/15] secp256r1 uses math from OpenSSL, so I just removed it altogether --- precompiles/src/secp256r1.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/precompiles/src/secp256r1.rs b/precompiles/src/secp256r1.rs index f7b31b37512097..3473c02c4a7183 100644 --- a/precompiles/src/secp256r1.rs +++ b/precompiles/src/secp256r1.rs @@ -147,7 +147,7 @@ pub fn verify( _instruction_datas: &[&[u8]], _feature_set: &FeatureSet, ) -> Result<(), PrecompileError> { - Err(PrecompileError::InvalidInstructionDataSize) + Err(PrecompileError::InvalidInstructionDataSize) } fn get_data_slice<'a>( @@ -402,7 +402,7 @@ mod tests { &[&instruction.data], &feature_set ) - .is_ok()); + .is_ok()); // The message is the last field in the instruction data so // changing its last byte will also change the signature validity @@ -416,7 +416,7 @@ mod tests { &[&instruction.data], &feature_set ) - .is_err()); + .is_err()); } #[test] @@ -522,7 +522,7 @@ mod tests { &[&instruction.data], &feature_set ) - .is_ok()); + .is_ok()); break; } } From 6b10426a14193f1bdcfd62cbb0a78704ee89f788 Mon Sep 17 00:00:00 2001 From: jason-nitro Date: Wed, 6 Aug 2025 09:09:10 -0500 Subject: [PATCH 02/15] Changes in progress, pushing so I can use in my local build --- Cargo.toml | 4 +- precompiles/Cargo.toml | 7 +- rpc/src/rpc.rs | 2 +- svm-rent-collector/Cargo.toml | 2 +- svm-rent-collector/src/svm_rent_collector.rs | 2 +- .../src/svm_rent_collector/rent_collector.rs | 96 ++++++++++++++++++- svm/Cargo.toml | 2 +- 7 files changed, 104 insertions(+), 11 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 966654646b5a71..3ef536c690e569 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -182,7 +182,7 @@ agave-banking-stage-ingress-types = { path = "banking-stage-ingress-types", vers agave-cargo-registry = { path = "cargo-registry", version = "=3.0.0" } agave-feature-set = { path = "feature-set", version = "=3.0.0" } agave-geyser-plugin-interface = { path = "geyser-plugin-interface", version = "=3.0.0" } -agave-precompiles = { path = "precompiles", version = "=3.0.0" } +agave-precompiles = { path = "precompiles", version = "=2.2.2" } agave-reserved-account-keys = { path = "reserved-account-keys", version = "=3.0.0" } agave-thread-manager = { path = "thread-manager", version = "=3.0.0" } agave-transaction-view = { path = "transaction-view", version = "=3.0.0" } @@ -487,7 +487,7 @@ solana-quic-definitions = "2.2.1" solana-rayon-threadlimit = { path = "rayon-threadlimit", version = "=3.0.0" } solana-remote-wallet = { path = "remote-wallet", version = "=3.0.0", default-features = false } solana-rent = "2.2.1" -solana-rent-collector = "2.2.1" +solana-rent-collector = { path = "svm-rent-collector", package = "solana-svm-rent-collector", version = "3.0.0" } solana-rent-debits = "2.2.1" solana-reward-info = "2.2.1" solana-rpc = { path = "rpc", version = "=3.0.0" } diff --git a/precompiles/Cargo.toml b/precompiles/Cargo.toml index c2a5a854af7696..bde72900785d99 100644 --- a/precompiles/Cargo.toml +++ b/precompiles/Cargo.toml @@ -1,8 +1,8 @@ [package] -name = "agave-precompiles" +name = "solana-precompiles" description = "Solana precompiled programs." documentation = "https://docs.rs/agave-precompiles" -version = { workspace = true } +version = "2.2.2" authors = { workspace = true } repository = { workspace = true } homepage = { workspace = true } @@ -20,6 +20,7 @@ bincode = { workspace = true } digest = { workspace = true } ed25519-dalek = { workspace = true } libsecp256k1 = { workspace = true } +[target.'cfg(not(target_arch = "riscv32"))'.dependencies] openssl = { workspace = true } sha3 = { workspace = true } solana-ed25519-program = { workspace = true } @@ -28,7 +29,7 @@ solana-precompile-error = { workspace = true } solana-pubkey = { workspace = true } solana-sdk-ids = { workspace = true } solana-secp256k1-program = { workspace = true, features = ["serde"] } -solana-secp256r1-program = { workspace = true, features = ["openssl-vendored"] } +solana-secp256r1-program = { workspace = true } [dev-dependencies] bytemuck = { workspace = true } diff --git a/rpc/src/rpc.rs b/rpc/src/rpc.rs index 1464a290e6c943..45e4d8caa6e67d 100644 --- a/rpc/src/rpc.rs +++ b/rpc/src/rpc.rs @@ -4528,7 +4528,7 @@ pub mod tests { Message, MessageHeader, SimpleAddressLoader, VersionedMessage, }, solana_nonce::{self as nonce, state::DurableNonce}, - solana_program_option::COption, + solana_program_option::COption, solana_program_runtime::{ invoke_context::InvokeContext, loaded_programs::ProgramCacheEntry, diff --git a/svm-rent-collector/Cargo.toml b/svm-rent-collector/Cargo.toml index 7dec6d3a7d6e7d..eb606092c3589b 100644 --- a/svm-rent-collector/Cargo.toml +++ b/svm-rent-collector/Cargo.toml @@ -12,9 +12,9 @@ edition = { workspace = true } [dependencies] solana-account = { workspace = true } solana-clock = { workspace = true } +solana-epoch-schedule = { workspace = true } solana-pubkey = { workspace = true } solana-rent = { workspace = true } -solana-rent-collector = { workspace = true } solana-sdk-ids = { workspace = true } solana-transaction-context = { workspace = true } solana-transaction-error = { workspace = true } diff --git a/svm-rent-collector/src/svm_rent_collector.rs b/svm-rent-collector/src/svm_rent_collector.rs index bba32248bac907..8d21858c7a5396 100644 --- a/svm-rent-collector/src/svm_rent_collector.rs +++ b/svm-rent-collector/src/svm_rent_collector.rs @@ -6,10 +6,10 @@ use { solana_clock::Epoch, solana_pubkey::Pubkey, solana_rent::{Rent, RentDue}, - solana_rent_collector::CollectedInfo, solana_transaction_context::{IndexOfAccount, TransactionContext}, solana_transaction_error::{TransactionError, TransactionResult}, }; +use crate::svm_rent_collector::rent_collector::CollectedInfo; mod rent_collector; diff --git a/svm-rent-collector/src/svm_rent_collector/rent_collector.rs b/svm-rent-collector/src/svm_rent_collector/rent_collector.rs index f308ef11fd64e1..1304405f97c086 100644 --- a/svm-rent-collector/src/svm_rent_collector/rent_collector.rs +++ b/svm-rent-collector/src/svm_rent_collector/rent_collector.rs @@ -1,15 +1,95 @@ //! Implementation of `SVMRentCollector` for `RentCollector` from the Solana //! SDK. +use solana_epoch_schedule::EpochSchedule; use { crate::svm_rent_collector::SVMRentCollector, - solana_account::AccountSharedData, + solana_account::{AccountSharedData, ReadableAccount, WritableAccount}, solana_clock::Epoch, solana_pubkey::Pubkey, solana_rent::{Rent, RentDue}, - solana_rent_collector::{CollectedInfo, RentCollector}, }; +#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)] +pub struct CollectedInfo { + /// Amount of rent collected from account + pub rent_amount: u64, + /// Size of data reclaimed from account (happens when account's lamports go to zero) + pub account_data_len_reclaimed: u64, +} + +pub const RENT_EXEMPT_RENT_EPOCH: Epoch = Epoch::MAX; + +impl RentCollector { + pub fn new( + epoch: Epoch, + epoch_schedule: EpochSchedule, + slots_per_year: f64, + rent: Rent, + ) -> Self { + Self { + epoch, + epoch_schedule, + slots_per_year, + rent, + } + } + + #[must_use = "add to Bank::collected_rent"] + pub fn collect_from_existing_account( + &self, + address: &Pubkey, + account: &mut AccountSharedData, + ) -> CollectedInfo { + match self.calculate_rent_result(address, account) { + RentResult::Exempt => { + account.set_rent_epoch(RENT_EXEMPT_RENT_EPOCH); + CollectedInfo::default() + } + RentResult::NoRentCollectionNow => CollectedInfo::default(), + RentResult::CollectRent { + new_rent_epoch, + rent_due, + } => match account.lamports().checked_sub(rent_due) { + None | Some(0) => { + let account = std::mem::take(account); + CollectedInfo { + rent_amount: account.lamports(), + account_data_len_reclaimed: account.data().len() as u64, + } + } + Some(lamports) => { + account.set_lamports(lamports); + account.set_rent_epoch(new_rent_epoch); + CollectedInfo { + rent_amount: rent_due, + account_data_len_reclaimed: 0u64, + } + } + }, + } + }} + +#[derive(Clone, Debug, PartialEq)] +pub struct RentCollector { + pub epoch: Epoch, + pub epoch_schedule: EpochSchedule, + pub slots_per_year: f64, + pub rent: Rent, +} + +impl Default for RentCollector { + fn default() -> Self { + Self { + epoch: Epoch::default(), + epoch_schedule: EpochSchedule::default(), + // derive default value using GenesisConfig::default() + slots_per_year: 78_890_000.0, + rent: Rent::default(), + } + } +} + impl SVMRentCollector for RentCollector { fn collect_rent(&self, address: &Pubkey, account: &mut AccountSharedData) -> CollectedInfo { self.collect_from_existing_account(address, account) @@ -23,6 +103,18 @@ impl SVMRentCollector for RentCollector { self.get_rent_due(lamports, data_len, account_rent_epoch) } } +#[derive(Debug)] +enum RentResult { + /// this account will never have rent collected from it + Exempt, + /// maybe we collect rent later, but not now + NoRentCollectionNow, + /// collect rent + CollectRent { + new_rent_epoch: Epoch, + rent_due: u64, // lamports, could be 0 + }, +} #[cfg(test)] mod tests { diff --git a/svm/Cargo.toml b/svm/Cargo.toml index 57758d82f63fb5..e96f3be5862c7e 100644 --- a/svm/Cargo.toml +++ b/svm/Cargo.toml @@ -112,7 +112,7 @@ solana-pubkey = { workspace = true, features = ["rand"] } solana-rent = { workspace = true } solana-sbpf = { workspace = true } solana-secp256k1-program = { workspace = true } -solana-secp256r1-program = { workspace = true, features = ["openssl-vendored"] } +solana-secp256r1-program = { workspace = true } solana-signature = { workspace = true, features = ["rand"] } solana-signer = { workspace = true } # See order-crates-for-publishing.py for using this unusual `path = "."` From 995178b46bb75f3c82d7c07d9c7a37b715032139 Mon Sep 17 00:00:00 2001 From: jason-nitro Date: Wed, 6 Aug 2025 09:49:22 -0500 Subject: [PATCH 03/15] ongoing work --- Cargo.toml | 1 + svm/Cargo.toml | 1 - svm/src/account_loader.rs | 4 ++-- svm/src/transaction_account_state_info.rs | 2 +- svm/src/transaction_processor.rs | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3ef536c690e569..94055e8c636f54 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -494,6 +494,7 @@ solana-rpc = { path = "rpc", version = "=3.0.0" } solana-rpc-client = { path = "rpc-client", version = "=3.0.0", default-features = false } solana-rpc-client-api = { path = "rpc-client-api", version = "=3.0.0" } solana-rpc-client-nonce-utils = { path = "rpc-client-nonce-utils", version = "=3.0.0" } +solana-rpc-client-nonce-utils = { path = "rpc-client-nonce-utils", version = "=3.0.0" } solana-rpc-client-types = { path = "rpc-client-types", version = "=3.0.0" } solana-runtime = { path = "runtime", version = "=3.0.0" } solana-runtime-transaction = { path = "runtime-transaction", version = "=3.0.0" } diff --git a/svm/Cargo.toml b/svm/Cargo.toml index e96f3be5862c7e..afa44f9994d9dd 100644 --- a/svm/Cargo.toml +++ b/svm/Cargo.toml @@ -65,7 +65,6 @@ solana-program-pack = { workspace = true } solana-program-runtime = { workspace = true, features = ["metrics"] } solana-pubkey = { workspace = true } solana-rent = { workspace = true } -solana-rent-collector = { workspace = true } solana-rent-debits = { workspace = true } solana-sdk-ids = { workspace = true } solana-slot-hashes = { workspace = true } diff --git a/svm/src/account_loader.rs b/svm/src/account_loader.rs index 8608a8d4dad311..832f37a87b85a3 100644 --- a/svm/src/account_loader.rs +++ b/svm/src/account_loader.rs @@ -22,7 +22,7 @@ use { }, solana_pubkey::Pubkey, solana_rent::RentDue, - solana_rent_collector::{CollectedInfo, RENT_EXEMPT_RENT_EPOCH}, + solana_svm_rent_collector::{CollectedInfo, RENT_EXEMPT_RENT_EPOCH}, solana_rent_debits::RentDebits, solana_sdk_ids::{ bpf_loader_upgradeable, native_loader, @@ -933,7 +933,7 @@ mod tests { }, solana_pubkey::Pubkey, solana_rent::Rent, - solana_rent_collector::{RentCollector, RENT_EXEMPT_RENT_EPOCH}, + solana_svm_rent_collector::{RentCollector, RENT_EXEMPT_RENT_EPOCH}, solana_rent_debits::RentDebits, solana_sdk_ids::{ bpf_loader, bpf_loader_upgradeable, native_loader, system_program, sysvar, diff --git a/svm/src/transaction_account_state_info.rs b/svm/src/transaction_account_state_info.rs index 80d647019f12a0..45c3b8ea2ce0d1 100644 --- a/svm/src/transaction_account_state_info.rs +++ b/svm/src/transaction_account_state_info.rs @@ -79,7 +79,7 @@ mod test { SanitizedMessage, }, solana_rent::Rent, - solana_rent_collector::RentCollector, + solana_svm_rent_collector::RentCollector, solana_signer::Signer, solana_transaction_context::TransactionContext, solana_transaction_error::TransactionError, diff --git a/svm/src/transaction_processor.rs b/svm/src/transaction_processor.rs index 7d00785a6fa492..7581e9e3baa7ec 100644 --- a/svm/src/transaction_processor.rs +++ b/svm/src/transaction_processor.rs @@ -45,7 +45,7 @@ use { sysvar_cache::SysvarCache, }, solana_pubkey::Pubkey, - solana_rent_collector::RentCollector, + solana_svm_rent_collector::RentCollector, solana_sdk_ids::{native_loader, system_program}, solana_svm_callback::TransactionProcessingCallback, solana_svm_feature_set::SVMFeatureSet, @@ -1124,7 +1124,7 @@ mod tests { loaded_programs::{BlockRelation, ProgramCacheEntryType}, }, solana_rent::Rent, - solana_rent_collector::{RentCollector, RENT_EXEMPT_RENT_EPOCH}, + solana_svm_rent_collector::{RentCollector, RENT_EXEMPT_RENT_EPOCH}, solana_rent_debits::RentDebits, solana_sdk_ids::{bpf_loader, system_program, sysvar}, solana_signature::Signature, From 195ee7dcc6633c5e19f326a9e68d2109729d49ce Mon Sep 17 00:00:00 2001 From: jason-nitro Date: Wed, 6 Aug 2025 09:51:35 -0500 Subject: [PATCH 04/15] fix --- Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 94055e8c636f54..3ef536c690e569 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -494,7 +494,6 @@ solana-rpc = { path = "rpc", version = "=3.0.0" } solana-rpc-client = { path = "rpc-client", version = "=3.0.0", default-features = false } solana-rpc-client-api = { path = "rpc-client-api", version = "=3.0.0" } solana-rpc-client-nonce-utils = { path = "rpc-client-nonce-utils", version = "=3.0.0" } -solana-rpc-client-nonce-utils = { path = "rpc-client-nonce-utils", version = "=3.0.0" } solana-rpc-client-types = { path = "rpc-client-types", version = "=3.0.0" } solana-runtime = { path = "runtime", version = "=3.0.0" } solana-runtime-transaction = { path = "runtime-transaction", version = "=3.0.0" } From 7937515428ebb2e58ff7f772781012f1c0b8027e Mon Sep 17 00:00:00 2001 From: jason-nitro Date: Wed, 6 Aug 2025 11:17:38 -0500 Subject: [PATCH 05/15] Update to rent_collector to add needed functions from old implementation --- .../src/svm_rent_collector/rent_collector.rs | 72 ++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/svm-rent-collector/src/svm_rent_collector/rent_collector.rs b/svm-rent-collector/src/svm_rent_collector/rent_collector.rs index 1304405f97c086..c6b15a41cac5b8 100644 --- a/svm-rent-collector/src/svm_rent_collector/rent_collector.rs +++ b/svm-rent-collector/src/svm_rent_collector/rent_collector.rs @@ -68,7 +68,77 @@ impl RentCollector { } }, } - }} + } + + fn calculate_rent_result( + &self, + address: &Pubkey, + account: &impl ReadableAccount, + ) -> RentResult { + if account.rent_epoch() == RENT_EXEMPT_RENT_EPOCH || account.rent_epoch() > self.epoch { + // potentially rent paying account (or known and already marked exempt) + // Maybe collect rent later, leave account alone for now. + return RentResult::NoRentCollectionNow; + } + if !self.should_collect_rent(address, account.executable()) { + // easy to determine this account should not consider having rent collected from it + return RentResult::Exempt; + } + match self.get_rent_due( + account.lamports(), + account.data().len(), + account.rent_epoch(), + ) { + // account will not have rent collected ever + RentDue::Exempt => RentResult::Exempt, + // potentially rent paying account + // Maybe collect rent later, leave account alone for now. + RentDue::Paying(0) => RentResult::NoRentCollectionNow, + // Rent is collected for next epoch. + RentDue::Paying(rent_due) => RentResult::CollectRent { + new_rent_epoch: self.epoch.saturating_add(1), + rent_due, + }, + } + } + + /// true if it is easy to determine this account should consider having rent collected from it + pub fn should_collect_rent(&self, address: &Pubkey, executable: bool) -> bool { + !(executable // executable accounts must be rent-exempt balance + || *address == incinerator::id()) + } + + /// given an account that 'should_collect_rent' + /// returns (amount rent due, is_exempt_from_rent) + pub fn get_rent_due( + &self, + lamports: u64, + data_len: usize, + account_rent_epoch: Epoch, + ) -> RentDue { + if self.rent.is_exempt(lamports, data_len) { + RentDue::Exempt + } else { + let slots_elapsed: u64 = (account_rent_epoch..=self.epoch) + .map(|epoch| { + self.epoch_schedule + .get_slots_in_epoch(epoch.saturating_add(1)) + }) + .sum(); + + // avoid infinite rent in rust 1.45 + let years_elapsed = if self.slots_per_year != 0.0 { + slots_elapsed as f64 / self.slots_per_year + } else { + 0.0 + }; + + // we know this account is not exempt + let due = self.rent.due_amount(data_len, years_elapsed); + RentDue::Paying(due) + } + } +} #[derive(Clone, Debug, PartialEq)] pub struct RentCollector { From 9e12f8dcd85785b460e1dbf2817a486d2c7ea65c Mon Sep 17 00:00:00 2001 From: jason-nitro Date: Wed, 6 Aug 2025 12:35:55 -0500 Subject: [PATCH 06/15] Fixed incinerator dep --- svm-rent-collector/src/svm_rent_collector/rent_collector.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/svm-rent-collector/src/svm_rent_collector/rent_collector.rs b/svm-rent-collector/src/svm_rent_collector/rent_collector.rs index c6b15a41cac5b8..f7e38be5d564d1 100644 --- a/svm-rent-collector/src/svm_rent_collector/rent_collector.rs +++ b/svm-rent-collector/src/svm_rent_collector/rent_collector.rs @@ -105,7 +105,7 @@ impl RentCollector { /// true if it is easy to determine this account should consider having rent collected from it pub fn should_collect_rent(&self, address: &Pubkey, executable: bool) -> bool { !(executable // executable accounts must be rent-exempt balance - || *address == incinerator::id()) + || *address == solana_sdk_ids::incinerator::id()) } /// given an account that 'should_collect_rent' From 3b3d80d5efb5231477355a4605589f015a31defe Mon Sep 17 00:00:00 2001 From: jason-nitro Date: Wed, 6 Aug 2025 12:44:37 -0500 Subject: [PATCH 07/15] update --- transaction-status-client-types/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/transaction-status-client-types/Cargo.toml b/transaction-status-client-types/Cargo.toml index d67ad700d692c4..3ef92904397453 100644 --- a/transaction-status-client-types/Cargo.toml +++ b/transaction-status-client-types/Cargo.toml @@ -24,7 +24,7 @@ solana-commitment-config = { workspace = true } solana-message = { workspace = true } solana-reward-info = { workspace = true, features = ["serde"] } solana-signature = { workspace = true, default-features = false } -solana-transaction = { workspace = true, features = ["serde"] } +solana-transaction = { workspace = true } solana-transaction-context = { workspace = true } solana-transaction-error = { workspace = true, features = ["serde"] } thiserror = { workspace = true } From bcc89744d4ccd2f1331c7cff560ad2475cf1ba2d Mon Sep 17 00:00:00 2001 From: jason-nitro Date: Wed, 6 Aug 2025 13:20:07 -0500 Subject: [PATCH 08/15] publish some new values --- svm-rent-collector/src/lib.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/svm-rent-collector/src/lib.rs b/svm-rent-collector/src/lib.rs index 5038410e9e9f6f..6391e635f508db 100644 --- a/svm-rent-collector/src/lib.rs +++ b/svm-rent-collector/src/lib.rs @@ -4,3 +4,9 @@ pub mod rent_state; pub mod svm_rent_collector; + +pub use svm_rent_collector::rent_collector::{ + CollectedInfo, + RentCollector, + RENT_EXEMPT_RENT_EPOCH, +}; From e44d5b01cbe5dac3489f93cab0f90e1b61c17710 Mon Sep 17 00:00:00 2001 From: jason-nitro Date: Wed, 6 Aug 2025 13:22:30 -0500 Subject: [PATCH 09/15] update --- svm-rent-collector/src/svm_rent_collector.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/svm-rent-collector/src/svm_rent_collector.rs b/svm-rent-collector/src/svm_rent_collector.rs index 8d21858c7a5396..9dfb6fd5185eb2 100644 --- a/svm-rent-collector/src/svm_rent_collector.rs +++ b/svm-rent-collector/src/svm_rent_collector.rs @@ -11,7 +11,7 @@ use { }; use crate::svm_rent_collector::rent_collector::CollectedInfo; -mod rent_collector; +pub mod rent_collector; /// Rent collector trait. Represents an entity that can evaluate the rent state /// of an account, determine rent due, and collect rent. From a06eb33fcf9b3bc0b83694a6888920ca75796096 Mon Sep 17 00:00:00 2001 From: jason-nitro Date: Wed, 6 Aug 2025 14:18:04 -0500 Subject: [PATCH 10/15] undo a serde change --- transaction-status-client-types/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/transaction-status-client-types/Cargo.toml b/transaction-status-client-types/Cargo.toml index 3ef92904397453..d67ad700d692c4 100644 --- a/transaction-status-client-types/Cargo.toml +++ b/transaction-status-client-types/Cargo.toml @@ -24,7 +24,7 @@ solana-commitment-config = { workspace = true } solana-message = { workspace = true } solana-reward-info = { workspace = true, features = ["serde"] } solana-signature = { workspace = true, default-features = false } -solana-transaction = { workspace = true } +solana-transaction = { workspace = true, features = ["serde"] } solana-transaction-context = { workspace = true } solana-transaction-error = { workspace = true, features = ["serde"] } thiserror = { workspace = true } From 7042472fd6aed061e1d5aa0e5eac31abe4512624 Mon Sep 17 00:00:00 2001 From: jason-nitro Date: Wed, 6 Aug 2025 14:59:10 -0500 Subject: [PATCH 11/15] Fix a 32-bit issue that probably should go into the real PR --- programs/bpf_loader/src/syscalls/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/programs/bpf_loader/src/syscalls/mod.rs b/programs/bpf_loader/src/syscalls/mod.rs index b11462d6d37b1f..78c0710b88b170 100644 --- a/programs/bpf_loader/src/syscalls/mod.rs +++ b/programs/bpf_loader/src/syscalls/mod.rs @@ -673,7 +673,8 @@ macro_rules! translate_type_inner { size_of::<$T>() as u64 )?; if !$check_aligned { - Ok(unsafe { std::mem::transmute::(host_addr) }) + // Ok(unsafe { std::mem::transmute::(host_addr) }) + Ok(unsafe { &mut *(host_addr as *mut $T) }) } else if !address_is_aligned::<$T>(host_addr) { Err(SyscallError::UnalignedPointer.into()) } else { From 9f0a161a07471ccc2de4e3ae659b5cc551bc58a1 Mon Sep 17 00:00:00 2001 From: jason-nitro Date: Wed, 6 Aug 2025 18:30:29 -0500 Subject: [PATCH 12/15] Removing zstd from risc builds --- account-decoder-client-types/Cargo.toml | 1 + account-decoder/Cargo.toml | 3 ++- account-decoder/src/lib.rs | 25 ++++++++++++++++++------- storage-bigtable/Cargo.toml | 1 + storage-bigtable/src/compression.rs | 19 +++++++++++++++++-- 5 files changed, 39 insertions(+), 10 deletions(-) diff --git a/account-decoder-client-types/Cargo.toml b/account-decoder-client-types/Cargo.toml index 433ecc37929e7c..f5b11578de8ed7 100644 --- a/account-decoder-client-types/Cargo.toml +++ b/account-decoder-client-types/Cargo.toml @@ -25,4 +25,5 @@ serde_derive = { workspace = true } serde_json = { workspace = true } solana-account = { workspace = true } solana-pubkey = { workspace = true } +[target.'cfg(not(target_arch = "riscv32"))'.dependencies] zstd = { workspace = true, optional = true } diff --git a/account-decoder/Cargo.toml b/account-decoder/Cargo.toml index 38b3c5a2711fd7..f79140fdadbec7 100644 --- a/account-decoder/Cargo.toml +++ b/account-decoder/Cargo.toml @@ -50,7 +50,8 @@ spl-token-2022 = { workspace = true, features = ["no-entrypoint"] } spl-token-group-interface = { workspace = true } spl-token-metadata-interface = { workspace = true } thiserror = { workspace = true } - zstd = { workspace = true } +[target.'cfg(not(target_arch = "riscv32"))'.dependencies] +zstd = { workspace = true } [dev-dependencies] assert_matches = { workspace = true } diff --git a/account-decoder/src/lib.rs b/account-decoder/src/lib.rs index eabf85ae608275..3ddbafacd0737a 100644 --- a/account-decoder/src/lib.rs +++ b/account-decoder/src/lib.rs @@ -66,16 +66,27 @@ pub fn encode_ui_account( encoding, ), UiAccountEncoding::Base64Zstd => { - let mut encoder = zstd::stream::write::Encoder::new(Vec::new(), 0).unwrap(); - match encoder - .write_all(slice_data(account.data(), data_slice_config)) - .and_then(|()| encoder.finish()) + #[cfg(not(target_arch = "riscv32"))] { - Ok(zstd_data) => UiAccountData::Binary(BASE64_STANDARD.encode(zstd_data), encoding), - Err(_) => UiAccountData::Binary( + let mut encoder = zstd::stream::write::Encoder::new(Vec::new(), 0).unwrap(); + match encoder + .write_all(slice_data(account.data(), data_slice_config)) + .and_then(|()| encoder.finish()) + { + Ok(zstd_data) => UiAccountData::Binary(BASE64_STANDARD.encode(zstd_data), encoding), + Err(_) => UiAccountData::Binary( + BASE64_STANDARD.encode(slice_data(account.data(), data_slice_config)), + UiAccountEncoding::Base64, + ), + } + } + #[cfg(target_arch = "riscv32")] + { + // Fallback to regular Base64 on RISC-V + UiAccountData::Binary( BASE64_STANDARD.encode(slice_data(account.data(), data_slice_config)), UiAccountEncoding::Base64, - ), + ) } } UiAccountEncoding::JsonParsed => { diff --git a/storage-bigtable/Cargo.toml b/storage-bigtable/Cargo.toml index eb1cce510b3d20..dce6d189d34e90 100644 --- a/storage-bigtable/Cargo.toml +++ b/storage-bigtable/Cargo.toml @@ -52,6 +52,7 @@ solana-transaction-status = { workspace = true } thiserror = { workspace = true } tokio = { workspace = true } tonic = { workspace = true, features = ["tls", "transport"] } +[target.'cfg(not(target_arch = "riscv32"))'.dependencies] zstd = { workspace = true } [dev-dependencies] diff --git a/storage-bigtable/src/compression.rs b/storage-bigtable/src/compression.rs index a931b707721d0b..5c50b8a3e67fe3 100644 --- a/storage-bigtable/src/compression.rs +++ b/storage-bigtable/src/compression.rs @@ -17,12 +17,19 @@ fn decompress_reader<'a, R: Read + 'a>( ) -> Result, io::Error> { let buf_reader = BufReader::new(stream); let decompress_reader: Box = match method { + #[cfg(not(target_arch = "riscv32"))] CompressionMethod::Bzip2 => Box::new(bzip2::bufread::BzDecoder::new(buf_reader)), + #[cfg(not(target_arch = "riscv32"))] CompressionMethod::Gzip => Box::new(flate2::read::GzDecoder::new(buf_reader)), + #[cfg(not(target_arch = "riscv32"))] CompressionMethod::Zstd => Box::new(zstd::stream::read::Decoder::new(buf_reader)?), + // Fallbacks for RISC-V - treat compressed data as uncompressed + #[cfg(target_arch = "riscv32")] + CompressionMethod::Bzip2 | CompressionMethod::Gzip | CompressionMethod::Zstd => { + Box::new(buf_reader) + } CompressionMethod::NoCompression => Box::new(buf_reader), - }; - Ok(decompress_reader) + }; Ok(decompress_reader) } pub fn decompress(data: &[u8]) -> Result, io::Error> { @@ -45,21 +52,29 @@ pub fn decompress(data: &[u8]) -> Result, io::Error> { pub fn compress(method: CompressionMethod, data: &[u8]) -> Result, io::Error> { let mut compressed_data = bincode::serialize(&method).unwrap(); compressed_data.extend(match method { + #[cfg(not(target_arch = "riscv32"))] CompressionMethod::Bzip2 => { let mut e = bzip2::write::BzEncoder::new(Vec::new(), bzip2::Compression::best()); e.write_all(data)?; e.finish()? } + #[cfg(not(target_arch = "riscv32"))] CompressionMethod::Gzip => { let mut e = flate2::write::GzEncoder::new(Vec::new(), flate2::Compression::default()); e.write_all(data)?; e.finish()? } + #[cfg(not(target_arch = "riscv32"))] CompressionMethod::Zstd => { let mut e = zstd::stream::write::Encoder::new(Vec::new(), 0).unwrap(); e.write_all(data)?; e.finish()? } + // Fallbacks for RISC-V -- return uncompressed data + #[cfg(target_arch = "riscv32")] + CompressionMethod::Bzip2 | CompressionMethod::Gzip | CompressionMethod::Zstd => { + data.to_vec() + } CompressionMethod::NoCompression => data.to_vec(), }); From 0130823cbe50b7c0907176795f767e8e2bbeceaf Mon Sep 17 00:00:00 2001 From: jason-nitro Date: Wed, 6 Aug 2025 18:34:03 -0500 Subject: [PATCH 13/15] Removing zstd from risc builds --- account-decoder-client-types/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/account-decoder-client-types/src/lib.rs b/account-decoder-client-types/src/lib.rs index d501f45631830f..9fbceb8e92c509 100644 --- a/account-decoder-client-types/src/lib.rs +++ b/account-decoder-client-types/src/lib.rs @@ -41,7 +41,7 @@ impl UiAccountData { UiAccountData::Binary(blob, encoding) => match encoding { UiAccountEncoding::Base58 => bs58::decode(blob).into_vec().ok(), UiAccountEncoding::Base64 => BASE64_STANDARD.decode(blob).ok(), - #[cfg(feature = "zstd")] + #[cfg(all(feature = "zstd", not(target_arch = "riscv32")))] UiAccountEncoding::Base64Zstd => { BASE64_STANDARD.decode(blob).ok().and_then(|zstd_data| { let mut data = vec![]; @@ -51,7 +51,7 @@ impl UiAccountData { .ok() }) } - #[cfg(not(feature = "zstd"))] + #[cfg(any(not(feature = "zstd"), target_arch = "riscv32"))] UiAccountEncoding::Base64Zstd => None, UiAccountEncoding::Binary | UiAccountEncoding::JsonParsed => None, }, From f50ca1f9d469220dc4047bb697d33d6054057701 Mon Sep 17 00:00:00 2001 From: jason-nitro Date: Thu, 7 Aug 2025 15:47:17 -0500 Subject: [PATCH 14/15] Lint changes --- account-decoder/src/lib.rs | 4 +++- core/src/banking_stage/consume_worker.rs | 3 +-- measure/src/measure.rs | 2 +- patches/src/lib.rs | 2 +- precompiles/src/secp256k1.rs | 7 +++++-- precompiles/src/secp256r1.rs | 6 +++--- programs/bpf_loader/src/syscalls/cpi.rs | 2 +- rpc/src/rpc.rs | 2 +- storage-bigtable/src/compression.rs | 3 ++- svm-rent-collector/src/lib.rs | 4 +--- svm-rent-collector/src/svm_rent_collector.rs | 3 +-- .../src/svm_rent_collector/rent_collector.rs | 2 +- svm/src/account_loader.rs | 7 ++++--- svm/src/transaction_account_state_info.rs | 2 +- svm/src/transaction_processor.rs | 5 ++--- 15 files changed, 28 insertions(+), 26 deletions(-) diff --git a/account-decoder/src/lib.rs b/account-decoder/src/lib.rs index 3ddbafacd0737a..916a0f5b9f093a 100644 --- a/account-decoder/src/lib.rs +++ b/account-decoder/src/lib.rs @@ -73,7 +73,9 @@ pub fn encode_ui_account( .write_all(slice_data(account.data(), data_slice_config)) .and_then(|()| encoder.finish()) { - Ok(zstd_data) => UiAccountData::Binary(BASE64_STANDARD.encode(zstd_data), encoding), + Ok(zstd_data) => { + UiAccountData::Binary(BASE64_STANDARD.encode(zstd_data), encoding) + } Err(_) => UiAccountData::Binary( BASE64_STANDARD.encode(slice_data(account.data(), data_slice_config)), UiAccountEncoding::Base64, diff --git a/core/src/banking_stage/consume_worker.rs b/core/src/banking_stage/consume_worker.rs index 0217db11468dec..12ef3ede99ee69 100644 --- a/core/src/banking_stage/consume_worker.rs +++ b/core/src/banking_stage/consume_worker.rs @@ -755,8 +755,7 @@ mod tests { solana_poh_config::PohConfig, solana_pubkey::Pubkey, solana_runtime::{ - bank_forks::BankForks, - prioritization_fee_cache::PrioritizationFeeCache, + bank_forks::BankForks, prioritization_fee_cache::PrioritizationFeeCache, vote_sender_types::ReplayVoteReceiver, }, solana_runtime_transaction::runtime_transaction::RuntimeTransaction, diff --git a/measure/src/measure.rs b/measure/src/measure.rs index 8021b1ca9c4b9c..fa9427ab5e26f9 100644 --- a/measure/src/measure.rs +++ b/measure/src/measure.rs @@ -82,7 +82,7 @@ impl fmt::Display for Measure { #[cfg(test)] mod tests { - use {super::*}; + use super::*; // #[test] // fn test_measure() { diff --git a/patches/src/lib.rs b/patches/src/lib.rs index c25ca52e266a9d..077885d7b66736 100644 --- a/patches/src/lib.rs +++ b/patches/src/lib.rs @@ -1 +1 @@ -pub mod time; \ No newline at end of file +pub mod time; diff --git a/precompiles/src/secp256k1.rs b/precompiles/src/secp256k1.rs index 5d66f7f69bb529..f647aa4e08d5c0 100644 --- a/precompiles/src/secp256k1.rs +++ b/precompiles/src/secp256k1.rs @@ -133,7 +133,9 @@ pub mod tests { crate::test_verify_with_alignment, rand0_7::{thread_rng, Rng}, solana_keccak_hasher as keccak, - solana_secp256k1_program::{new_secp256k1_instruction_with_signature, sign_message, DATA_START}, + solana_secp256k1_program::{ + new_secp256k1_instruction_with_signature, sign_message, DATA_START, + }, }; fn test_case( @@ -316,7 +318,8 @@ pub mod tests { &signature, recovery_id, ð_address, - ); let feature_set = FeatureSet::all_enabled(); + ); + let feature_set = FeatureSet::all_enabled(); assert!(test_verify_with_alignment( verify, &instruction.data, diff --git a/precompiles/src/secp256r1.rs b/precompiles/src/secp256r1.rs index 3473c02c4a7183..94fc70b92b6bb7 100644 --- a/precompiles/src/secp256r1.rs +++ b/precompiles/src/secp256r1.rs @@ -402,7 +402,7 @@ mod tests { &[&instruction.data], &feature_set ) - .is_ok()); + .is_ok()); // The message is the last field in the instruction data so // changing its last byte will also change the signature validity @@ -416,7 +416,7 @@ mod tests { &[&instruction.data], &feature_set ) - .is_err()); + .is_err()); } #[test] @@ -522,7 +522,7 @@ mod tests { &[&instruction.data], &feature_set ) - .is_ok()); + .is_ok()); break; } } diff --git a/programs/bpf_loader/src/syscalls/cpi.rs b/programs/bpf_loader/src/syscalls/cpi.rs index 360f9cbba2c381..53fdcf69bd81c8 100644 --- a/programs/bpf_loader/src/syscalls/cpi.rs +++ b/programs/bpf_loader/src/syscalls/cpi.rs @@ -2940,7 +2940,7 @@ mod tests { let lamports_cell_addr = key_addr + mem::size_of::(); let owner_addr = lamports_cell_addr + mem::size_of::>(); let data_cell_addr = owner_addr + mem::size_of::(); - let data_addr = data_cell_addr + mem::size_of::>>(); + let data_addr = data_cell_addr + mem::size_of::>>(); let info = VmAccountInfo { key: key_addr as u64, diff --git a/rpc/src/rpc.rs b/rpc/src/rpc.rs index 45e4d8caa6e67d..1464a290e6c943 100644 --- a/rpc/src/rpc.rs +++ b/rpc/src/rpc.rs @@ -4528,7 +4528,7 @@ pub mod tests { Message, MessageHeader, SimpleAddressLoader, VersionedMessage, }, solana_nonce::{self as nonce, state::DurableNonce}, - solana_program_option::COption, + solana_program_option::COption, solana_program_runtime::{ invoke_context::InvokeContext, loaded_programs::ProgramCacheEntry, diff --git a/storage-bigtable/src/compression.rs b/storage-bigtable/src/compression.rs index 5c50b8a3e67fe3..31a02dfadb851c 100644 --- a/storage-bigtable/src/compression.rs +++ b/storage-bigtable/src/compression.rs @@ -29,7 +29,8 @@ fn decompress_reader<'a, R: Read + 'a>( Box::new(buf_reader) } CompressionMethod::NoCompression => Box::new(buf_reader), - }; Ok(decompress_reader) + }; + Ok(decompress_reader) } pub fn decompress(data: &[u8]) -> Result, io::Error> { diff --git a/svm-rent-collector/src/lib.rs b/svm-rent-collector/src/lib.rs index 6391e635f508db..3e260b602606ed 100644 --- a/svm-rent-collector/src/lib.rs +++ b/svm-rent-collector/src/lib.rs @@ -6,7 +6,5 @@ pub mod rent_state; pub mod svm_rent_collector; pub use svm_rent_collector::rent_collector::{ - CollectedInfo, - RentCollector, - RENT_EXEMPT_RENT_EPOCH, + CollectedInfo, RentCollector, RENT_EXEMPT_RENT_EPOCH, }; diff --git a/svm-rent-collector/src/svm_rent_collector.rs b/svm-rent-collector/src/svm_rent_collector.rs index 9dfb6fd5185eb2..92900e999b245c 100644 --- a/svm-rent-collector/src/svm_rent_collector.rs +++ b/svm-rent-collector/src/svm_rent_collector.rs @@ -1,7 +1,7 @@ //! Plugin trait for rent collection within the Solana SVM. use { - crate::rent_state::RentState, + crate::{rent_state::RentState, svm_rent_collector::rent_collector::CollectedInfo}, solana_account::{AccountSharedData, ReadableAccount}, solana_clock::Epoch, solana_pubkey::Pubkey, @@ -9,7 +9,6 @@ use { solana_transaction_context::{IndexOfAccount, TransactionContext}, solana_transaction_error::{TransactionError, TransactionResult}, }; -use crate::svm_rent_collector::rent_collector::CollectedInfo; pub mod rent_collector; diff --git a/svm-rent-collector/src/svm_rent_collector/rent_collector.rs b/svm-rent-collector/src/svm_rent_collector/rent_collector.rs index f7e38be5d564d1..0b88809422c6e2 100644 --- a/svm-rent-collector/src/svm_rent_collector/rent_collector.rs +++ b/svm-rent-collector/src/svm_rent_collector/rent_collector.rs @@ -1,11 +1,11 @@ //! Implementation of `SVMRentCollector` for `RentCollector` from the Solana //! SDK. -use solana_epoch_schedule::EpochSchedule; use { crate::svm_rent_collector::SVMRentCollector, solana_account::{AccountSharedData, ReadableAccount, WritableAccount}, solana_clock::Epoch, + solana_epoch_schedule::EpochSchedule, solana_pubkey::Pubkey, solana_rent::{Rent, RentDue}, }; diff --git a/svm/src/account_loader.rs b/svm/src/account_loader.rs index 832f37a87b85a3..5531012e3aa52d 100644 --- a/svm/src/account_loader.rs +++ b/svm/src/account_loader.rs @@ -22,7 +22,6 @@ use { }, solana_pubkey::Pubkey, solana_rent::RentDue, - solana_svm_rent_collector::{CollectedInfo, RENT_EXEMPT_RENT_EPOCH}, solana_rent_debits::RentDebits, solana_sdk_ids::{ bpf_loader_upgradeable, native_loader, @@ -30,7 +29,9 @@ use { }, solana_svm_callback::{AccountState, TransactionProcessingCallback}, solana_svm_feature_set::SVMFeatureSet, - solana_svm_rent_collector::svm_rent_collector::SVMRentCollector, + solana_svm_rent_collector::{ + svm_rent_collector::SVMRentCollector, CollectedInfo, RENT_EXEMPT_RENT_EPOCH, + }, solana_svm_transaction::svm_message::SVMMessage, solana_transaction_context::{IndexOfAccount, TransactionAccount}, solana_transaction_error::{TransactionError, TransactionResult as Result}, @@ -933,7 +934,6 @@ mod tests { }, solana_pubkey::Pubkey, solana_rent::Rent, - solana_svm_rent_collector::{RentCollector, RENT_EXEMPT_RENT_EPOCH}, solana_rent_debits::RentDebits, solana_sdk_ids::{ bpf_loader, bpf_loader_upgradeable, native_loader, system_program, sysvar, @@ -941,6 +941,7 @@ mod tests { solana_signature::Signature, solana_signer::Signer, solana_svm_callback::{InvokeContextCallback, TransactionProcessingCallback}, + solana_svm_rent_collector::{RentCollector, RENT_EXEMPT_RENT_EPOCH}, solana_system_transaction::transfer, solana_transaction::{sanitized::SanitizedTransaction, Transaction}, solana_transaction_context::{TransactionAccount, TransactionContext}, diff --git a/svm/src/transaction_account_state_info.rs b/svm/src/transaction_account_state_info.rs index 45c3b8ea2ce0d1..fee4f93a28d608 100644 --- a/svm/src/transaction_account_state_info.rs +++ b/svm/src/transaction_account_state_info.rs @@ -79,8 +79,8 @@ mod test { SanitizedMessage, }, solana_rent::Rent, - solana_svm_rent_collector::RentCollector, solana_signer::Signer, + solana_svm_rent_collector::RentCollector, solana_transaction_context::TransactionContext, solana_transaction_error::TransactionError, }; diff --git a/svm/src/transaction_processor.rs b/svm/src/transaction_processor.rs index 7581e9e3baa7ec..d6f1a8c4bb36c2 100644 --- a/svm/src/transaction_processor.rs +++ b/svm/src/transaction_processor.rs @@ -45,11 +45,10 @@ use { sysvar_cache::SysvarCache, }, solana_pubkey::Pubkey, - solana_svm_rent_collector::RentCollector, solana_sdk_ids::{native_loader, system_program}, solana_svm_callback::TransactionProcessingCallback, solana_svm_feature_set::SVMFeatureSet, - solana_svm_rent_collector::svm_rent_collector::SVMRentCollector, + solana_svm_rent_collector::{svm_rent_collector::SVMRentCollector, RentCollector}, solana_svm_transaction::{svm_message::SVMMessage, svm_transaction::SVMTransaction}, solana_timings::{ExecuteTimingType, ExecuteTimings}, solana_transaction_context::{ExecutionRecord, TransactionContext}, @@ -1124,11 +1123,11 @@ mod tests { loaded_programs::{BlockRelation, ProgramCacheEntryType}, }, solana_rent::Rent, - solana_svm_rent_collector::{RentCollector, RENT_EXEMPT_RENT_EPOCH}, solana_rent_debits::RentDebits, solana_sdk_ids::{bpf_loader, system_program, sysvar}, solana_signature::Signature, solana_svm_callback::{AccountState, InvokeContextCallback}, + solana_svm_rent_collector::{RentCollector, RENT_EXEMPT_RENT_EPOCH}, solana_transaction::{sanitized::SanitizedTransaction, Transaction}, solana_transaction_context::TransactionContext, solana_transaction_error::{TransactionError, TransactionError::DuplicateInstruction}, From f467ecf580a158ebe6ada951df5159624546fc6d Mon Sep 17 00:00:00 2001 From: jason-nitro Date: Fri, 8 Aug 2025 08:50:24 -0500 Subject: [PATCH 15/15] deleted a comment --- programs/bpf_loader/src/syscalls/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/programs/bpf_loader/src/syscalls/mod.rs b/programs/bpf_loader/src/syscalls/mod.rs index 78c0710b88b170..5e16b6a7816f69 100644 --- a/programs/bpf_loader/src/syscalls/mod.rs +++ b/programs/bpf_loader/src/syscalls/mod.rs @@ -673,7 +673,6 @@ macro_rules! translate_type_inner { size_of::<$T>() as u64 )?; if !$check_aligned { - // Ok(unsafe { std::mem::transmute::(host_addr) }) Ok(unsafe { &mut *(host_addr as *mut $T) }) } else if !address_is_aligned::<$T>(host_addr) { Err(SyscallError::UnalignedPointer.into())