From 031451bfe19940fb1fdfe81852adf3cbf5052ff7 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Wed, 25 Jun 2025 08:53:41 +0300 Subject: [PATCH 01/86] initial wrapping of the cov logic --- Cargo.lock | 98 +- Cargo.toml | 3 +- crates/litesvm/Cargo.toml | 3 + crates/litesvm/src/accounts_db.rs | 2 +- crates/litesvm/src/lib.rs | 174 +++- crates/litesvm/test_programs/Cargo.lock | 910 +++++++++++++++++- crates/litesvm/test_programs/Cargo.toml | 1 + .../litesvm/test_programs/counter/Cargo.toml | 5 + .../litesvm/test_programs/counter/src/lib.rs | 370 +++++++ crates/litesvm/tests/counter_test.rs | 10 +- 10 files changed, 1545 insertions(+), 31 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ae5b1b37..e27e4317 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2362,9 +2362,9 @@ checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" [[package]] name = "libloading" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" +checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" dependencies = [ "cfg-if", "windows-targets 0.52.6", @@ -2500,7 +2500,7 @@ dependencies = [ "solana-program-option", "solana-program-pack", "solana-program-runtime", - "solana-program-test", + "solana-program-test 2.2.4", "solana-pubkey", "solana-rent", "solana-reserved-account-keys", @@ -2522,6 +2522,7 @@ dependencies = [ "solana-transaction-context", "solana-transaction-error", "solana-vote-program", + "solts-rs", "spl-associated-token-account-client", "spl-token", "test-log", @@ -5657,6 +5658,43 @@ dependencies = [ "thiserror 2.0.12", ] +[[package]] +name = "solana-program-test" +version = "2.2.4" +dependencies = [ + "assert_matches", + "async-trait", + "base64 0.22.1", + "bincode", + "chrono-humanize", + "crossbeam-channel", + "log", + "serde", + "solana-accounts-db", + "solana-banks-client", + "solana-banks-interface", + "solana-banks-server", + "solana-bpf-loader-program", + "solana-compute-budget", + "solana-feature-set", + "solana-inline-spl", + "solana-instruction", + "solana-log-collector", + "solana-logger", + "solana-program-runtime", + "solana-runtime", + "solana-sbpf", + "solana-sdk", + "solana-sdk-ids", + "solana-stake-program", + "solana-svm", + "solana-timings", + "solana-vote-program", + "test-case", + "thiserror 2.0.12", + "tokio", +] + [[package]] name = "solana-program-test" version = "2.2.4" @@ -7085,6 +7123,23 @@ dependencies = [ "zeroize", ] +[[package]] +name = "solts-rs" +version = "0.1.0" +dependencies = [ + "base64 0.22.1", + "bincode", + "borsh 1.5.7", + "bs58", + "jsonrpc-core", + "lazy_static", + "libloading", + "serde", + "solana-program-test 2.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "solana-sdk", + "tokio", +] + [[package]] name = "spinning_top" version = "0.3.0" @@ -7604,6 +7659,39 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" +[[package]] +name = "test-case" +version = "3.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb2550dd13afcd286853192af8601920d959b14c401fcece38071d53bf0768a8" +dependencies = [ + "test-case-macros", +] + +[[package]] +name = "test-case-core" +version = "3.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adcb7fd841cd518e279be3d5a3eb0636409487998a4aff22f3de87b81e88384f" +dependencies = [ + "cfg-if", + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "test-case-macros" +version = "3.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", + "test-case-core", +] + [[package]] name = "test-log" version = "0.2.17" @@ -7744,9 +7832,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.44.1" +version = "1.45.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a" +checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779" dependencies = [ "backtrace", "bytes", diff --git a/Cargo.toml b/Cargo.toml index 70f63c11..7aad185a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -59,7 +59,8 @@ solana-program-error = "2.2" solana-program-option = "2.2" solana-program-pack = "2.2" solana-program-runtime = ">=2.2,<=2.2.4" -solana-program-test = "2.2" +#solana-program-test = "2.2" +solana-program-test = { path = "./solana-program-test" } solana-pubkey = "2.2" solana-rent = "2.2" solana-reserved-account-keys = "2.2" diff --git a/crates/litesvm/Cargo.toml b/crates/litesvm/Cargo.toml index d3a4a098..4f091e77 100644 --- a/crates/litesvm/Cargo.toml +++ b/crates/litesvm/Cargo.toml @@ -70,6 +70,9 @@ solana-transaction-context.workspace = true solana-transaction-error.workspace = true solana-vote-program.workspace = true thiserror.workspace = true +solts-rs = { path = "/Users/boris/projects/solana/solts-rs" } +solana-program-test.workspace = true +tokio.workspace = true [dev-dependencies] criterion.workspace = true diff --git a/crates/litesvm/src/accounts_db.rs b/crates/litesvm/src/accounts_db.rs index 06b186a6..0790ae8f 100644 --- a/crates/litesvm/src/accounts_db.rs +++ b/crates/litesvm/src/accounts_db.rs @@ -59,7 +59,7 @@ where #[derive(Clone, Default)] pub(crate) struct AccountsDb { - inner: HashMap, + pub inner: HashMap, pub(crate) programs_cache: ProgramCacheForTxBatch, pub(crate) sysvar_cache: SysvarCache, } diff --git a/crates/litesvm/src/lib.rs b/crates/litesvm/src/lib.rs index 5e88bdc2..a7bcdc55 100644 --- a/crates/litesvm/src/lib.rs +++ b/crates/litesvm/src/lib.rs @@ -253,12 +253,19 @@ much easier. */ +use std::str::FromStr; + +use crate::pt::{NativeProgram, Pt}; #[cfg(feature = "nodejs-internal")] use qualifier_attr::qualifiers; +use solana_program_test::{processor, ProgramTest}; +use solana_pubkey::pubkey; #[allow(deprecated)] use solana_sysvar::recent_blockhashes::IterItem; #[allow(deprecated)] use solana_sysvar::{fees::Fees, recent_blockhashes::RecentBlockhashes}; +use solts_rs::loader::Loader; + use { crate::{ accounts_db::AccountsDb, @@ -337,6 +344,7 @@ mod format_logs; mod history; mod message_processor; mod precompiles; +mod pt; mod spl; mod utils; @@ -352,6 +360,7 @@ pub struct LiteSVM { blockhash_check: bool, fee_structure: FeeStructure, log_bytes_limit: Option, + pt: Option, } impl Default for LiteSVM { @@ -367,6 +376,7 @@ impl Default for LiteSVM { blockhash_check: false, fee_structure: FeeStructure::default(), log_bytes_limit: Some(10_000), + pt: None, } } } @@ -913,8 +923,56 @@ impl LiteSVM { .collect::>, TransactionError>>(); match maybe_program_indices { Ok(program_indices) => { - let mut context = self.create_transaction_context(compute_budget, accounts); - let mut tx_result = process_message( + let mut context = self.create_transaction_context(compute_budget, accounts.clone()); + + // TEST ----- + // let mut program_test_context = Box::leak(Box::new( + // self.create_transaction_context(compute_budget, accounts), + // )); + // let mut program_test_program_cache_for_tx_batch = + // Box::leak(Box::new(program_cache_for_tx_batch.clone())); + // let mut program_test_invoke_context = Box::leak(Box::new(InvokeContext::new( + // &mut program_test_context, + // &mut program_test_program_cache_for_tx_batch, + // EnvironmentConfig::new( + // *blockhash, + // self.fee_structure.lamports_per_signature, + // 0, + // &|_| 0, + // Arc::new(self.feature_set.clone()), + // &self.accounts.sysvar_cache, + // ), + // Some(LogCollector::new_ref()), + // compute_budget, + // ))); + // println!( + // "SETTING INVOKE CONTEXT!: {:#?}", + // program_test_invoke_context.transaction_context + // ); + // solana_program_test::set_invoke_context(&mut program_test_invoke_context); // TODO: Make this fn public and uncomment + + let my_tx = tx.clone().to_versioned_transaction(); + let mut program_test_context = + self.create_transaction_context(compute_budget, accounts); + let mut program_test_program_cache_for_tx_batch = + program_cache_for_tx_batch.clone(); + let mut program_test_invoke_context = InvokeContext::new( + &mut program_test_context, + &mut program_test_program_cache_for_tx_batch, + EnvironmentConfig::new( + *blockhash, + self.fee_structure.lamports_per_signature, + 0, + &|_| 0, + Arc::new(self.feature_set.clone()), + &self.accounts.sysvar_cache, + ), + Some(LogCollector::new_ref()), + compute_budget, + ); + // TEST ----- + + let mut tx_result: Result<(), TransactionError> = process_message( tx.message(), &program_indices, &mut InvokeContext::new( @@ -936,6 +994,15 @@ impl LiteSVM { ) .map(|_| ()); + println!("ORIGINAL TX DONE"); + if let Some(pt) = &self.pt { + pt.send_transaction( + &mut program_test_invoke_context, + my_tx, + self.accounts.clone(), + ); + } + if let Err(err) = self.check_accounts_rent(tx, &context) { tx_result = Err(err); }; @@ -1137,14 +1204,107 @@ impl LiteSVM { }) } + #[allow(dead_code)] + fn my_execute_tx(tx: VersionedTransaction, accounts: AccountsDb) { + println!("-----------------------------------------------------------------------------------------------------"); + println!("-----------------------------------------------------------------------------------------------------"); + println!("-----------------------------------------------------------------------------------------------------"); + println!("-----------------------------------------------------------------------------------------------------"); + println!("-----------------------------------------------------------------------------------------------------"); + let mut pt_native = ProgramTest::default(); + pt_native.prefer_bpf(false); + + let so_path = "/Users/boris/projects/litesvm/crates/litesvm/test_programs/target/debug/libcounter.dylib"; + let programs = [( + Pubkey::from_str("GtdambwDgHWrDJdVPBkEHGhCwokqgAoch162teUjJse2").unwrap(), + "counter", + )]; + let mut loader = Loader::new(); + for (program_id, program_name) in &programs { + println!( + "Adding native program {} with id: {}", + program_name, program_id + ); + loader.add(so_path, &program_name, &program_id).unwrap(); + pt_native.add_program( + &program_name, + *program_id, + processor!(solts_rs::loader::entry_wrapper), + ); + } + println!("Loaded: {:?}", loader); + // let rt = tokio::runtime::Builder::new_current_thread() + // .enable_time() + // .build() + // .unwrap(); + let rt = tokio::runtime::Runtime::new().unwrap(); + rt.block_on(async { + let mut pt_context = pt_native.start_with_context().await; + // let counter_address = pubkey!("J39wvrFY2AkoAUCke5347RMNk3ditxZfVidoZ7U6Fguf"); + // let program_id = pubkey!("GtdambwDgHWrDJdVPBkEHGhCwokqgAoch162teUjJse2"); + // let _ = pt_context + // .set_account(&counter_address, &AccountSharedData::new(5, 4, &program_id)); + loader.adjust_stubs().unwrap(); + for (account_address, account) in &accounts.inner { + // println!("Account: {:#?} data: {:#?}", account_address, account); + let to_add = programs + .iter() + .find(|(id, _)| id == account.owner()) + .is_some(); + if to_add == true { + pt_context.set_account(account_address, account); + } + } + let recent_blockhash = pt_context + .banks_client + .get_latest_blockhash() + .await + .unwrap(); + println!("PREPARING TRANS: {:#?}", tx); + let mut trans = tx.clone().into_legacy_transaction().unwrap(); + let payer = pt_context.payer; + println!("Payer: {}", payer.pubkey()); + trans.message.recent_blockhash = recent_blockhash; + trans.message.account_keys[0] = payer.pubkey().clone(); + trans.sign(&[&payer], recent_blockhash); + let versioned_tx = VersionedTransaction::from(trans); + println!("TRANS AFTER SIGN: {:#?}", versioned_tx); + + let res = pt_context + .banks_client + .process_transaction(versioned_tx) + .await; + println!("OUR TX RES: {:?}", res); + let acc = pt_context + .banks_client + .get_account(pubkey!("J39wvrFY2AkoAUCke5347RMNk3ditxZfVidoZ7U6Fguf")) + .await + .unwrap(); + if acc.is_some() { + println!("ACCOUNT IS HERE!"); + } + println!("#################################### END"); + println!("#################################### END"); + println!("#################################### END"); + println!("#################################### END"); + }); + } + + pub fn add_native_program(&mut self, programs: Vec) { + self.pt = Some(Pt::new(programs)); + } + /// Submits a signed transaction. pub fn send_transaction(&mut self, tx: impl Into) -> TransactionResult { + println!("Send transaction!"); let log_collector = LogCollector { bytes_limit: self.log_bytes_limit, ..Default::default() }; let log_collector = Rc::new(RefCell::new(log_collector)); let vtx: VersionedTransaction = tx.into(); + // let my_tx = vtx.clone(); + // let my_accounts = self.accounts.clone(); let ExecutionResult { post_accounts, tx_result, @@ -1182,7 +1342,15 @@ impl LiteSVM { .sync_accounts(post_accounts) .expect("It shouldn't be possible to write invalid sysvars in send_transaction."); - TransactionResult::Ok(meta) + let res = TransactionResult::Ok(meta); + + // OUR LOGIC HERE + // Self::my_execute_tx(my_tx, my_accounts); + // if let Some(pt) = &self.pt { + // pt.send_transaction(my_tx, my_accounts); + // } + + res } } diff --git a/crates/litesvm/test_programs/Cargo.lock b/crates/litesvm/test_programs/Cargo.lock index 86ec2042..a60b6156 100644 --- a/crates/litesvm/test_programs/Cargo.lock +++ b/crates/litesvm/test_programs/Cargo.lock @@ -8,17 +8,35 @@ version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ - "getrandom", + "getrandom 0.2.15", "once_cell", "version_check", ] +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + [[package]] name = "autocfg" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +[[package]] +name = "base64" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" + [[package]] name = "base64" version = "0.22.1" @@ -40,6 +58,29 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" +[[package]] +name = "blake3" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", + "digest 0.10.7", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + [[package]] name = "block-buffer" version = "0.10.4" @@ -59,6 +100,16 @@ dependencies = [ "hashbrown 0.11.2", ] +[[package]] +name = "borsh" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115e54d64eb62cdebad391c19efc9dce4981c690c85a33a12199d99bb9546fee" +dependencies = [ + "borsh-derive 0.10.4", + "hashbrown 0.11.2", +] + [[package]] name = "borsh" version = "1.5.5" @@ -75,8 +126,21 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6441c552f230375d18e3cc377677914d2ca2b0d36e52129fe15450a2dce46775" dependencies = [ - "borsh-derive-internal", - "borsh-schema-derive-internal", + "borsh-derive-internal 0.9.3", + "borsh-schema-derive-internal 0.9.3", + "proc-macro-crate 0.1.5", + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "borsh-derive" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831213f80d9423998dd696e2c5345aba6be7a0bd8cd19e31c5243e13df1cef89" +dependencies = [ + "borsh-derive-internal 0.10.4", + "borsh-schema-derive-internal 0.10.4", "proc-macro-crate 0.1.5", "proc-macro2", "syn 1.0.109", @@ -106,6 +170,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "borsh-derive-internal" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65d6ba50644c98714aa2a70d13d7df3cd75cd2b523a2b452bf010443800976b3" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "borsh-schema-derive-internal" version = "0.9.3" @@ -117,6 +192,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "borsh-schema-derive-internal" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "276691d96f063427be83e6692b86148e488ebba9f48f77788724ca027ba3b6d4" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "bs58" version = "0.5.1" @@ -159,6 +245,15 @@ dependencies = [ "syn 2.0.98", ] +[[package]] +name = "cc" +version = "1.2.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d487aa071b5f64da6f19a3e848e3578944b726ee5a4854b82172f02aa876bfdc" +dependencies = [ + "shlex", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -171,16 +266,45 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + +[[package]] +name = "console_log" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89f72f65e8501878b8a004d5a1afb780987e2ce2b4532c562e367a72c57499f" +dependencies = [ + "log", + "web-sys", +] + +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + [[package]] name = "counter" version = "0.1.0" dependencies = [ "borsh 0.9.3", "solana-account-info", + "solana-clock", "solana-msg", + "solana-program", "solana-program-entrypoint", "solana-program-error", "solana-pubkey", + "solana-sysvar", ] [[package]] @@ -192,6 +316,12 @@ dependencies = [ "libc", ] +[[package]] +name = "crunchy" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" + [[package]] name = "crypto-common" version = "0.1.6" @@ -202,14 +332,52 @@ dependencies = [ "typenum", ] +[[package]] +name = "curve25519-dalek" +version = "4.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest 0.10.7", + "fiat-crypto", + "rand_core 0.6.4", + "rustc_version", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.98", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + [[package]] name = "digest" version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer", + "block-buffer 0.10.4", "crypto-common", + "subtle", ] [[package]] @@ -234,6 +402,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + [[package]] name = "five8_const" version = "0.1.3" @@ -259,6 +433,17 @@ dependencies = [ "version_check", ] +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + [[package]] name = "getrandom" version = "0.2.15" @@ -268,7 +453,7 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "wasm-bindgen", ] @@ -307,6 +492,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + [[package]] name = "lazy_static" version = "1.5.0" @@ -319,6 +513,52 @@ version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +[[package]] +name = "libsecp256k1" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9d220bc1feda2ac231cb78c3d26f27676b8cf82c96971f7aeef3d0cf2797c73" +dependencies = [ + "arrayref", + "base64 0.12.3", + "digest 0.9.0", + "libsecp256k1-core", + "libsecp256k1-gen-ecmult", + "libsecp256k1-gen-genmult", + "rand 0.7.3", + "serde", + "sha2 0.9.9", +] + +[[package]] +name = "libsecp256k1-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0f6ab710cec28cef759c5f18671a27dae2a5f952cdaaee1d8e2908cb2478a80" +dependencies = [ + "crunchy", + "digest 0.9.0", + "subtle", +] + +[[package]] +name = "libsecp256k1-gen-ecmult" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccab96b584d38fac86a83f07e659f0deafd0253dc096dab5a36d53efe653c5c3" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "libsecp256k1-gen-genmult" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67abfe149395e3aa1c48a2beb32b068e2334402df8181f818d3aee2b304c4f5d" +dependencies = [ + "libsecp256k1-core", +] + [[package]] name = "litesvm-clock-example" version = "0.0.0" @@ -353,6 +593,45 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.98", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -368,6 +647,12 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + [[package]] name = "parking_lot" version = "0.12.3" @@ -391,6 +676,15 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + [[package]] name = "proc-macro-crate" version = "0.1.5" @@ -427,6 +721,77 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.15", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + [[package]] name = "redox_syscall" version = "0.5.2" @@ -436,6 +801,15 @@ dependencies = [ "bitflags", ] +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + [[package]] name = "rustversion" version = "1.0.17" @@ -448,6 +822,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "semver" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" + [[package]] name = "serde" version = "1.0.217" @@ -457,6 +837,15 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde_bytes" +version = "0.11.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8437fd221bde2d4ca316d61b90e337e9e702b3820b87d63caa9ba6c02bd06d96" +dependencies = [ + "serde", +] + [[package]] name = "serde_derive" version = "1.0.217" @@ -468,6 +857,19 @@ dependencies = [ "syn 2.0.98", ] +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + [[package]] name = "sha2" version = "0.10.8" @@ -476,26 +878,74 @@ checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", - "digest", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "smallvec" version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +[[package]] +name = "solana-account" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f949fe4edaeaea78c844023bfc1c898e0b1f5a100f8a8d2d0f85d0a7b090258" +dependencies = [ + "solana-account-info", + "solana-clock", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", +] + [[package]] name = "solana-account-info" version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e0c17d606a298a205fae325489fbed88ee6dc4463c111672172327e741c8905d" dependencies = [ + "bincode", + "serde", "solana-program-error", "solana-program-memory", "solana-pubkey", ] +[[package]] +name = "solana-address-lookup-table-interface" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1673f67efe870b64a65cb39e6194be5b26527691ce5922909939961a6e6b395" +dependencies = [ + "bincode", + "bytemuck", + "serde", + "serde_derive", + "solana-clock", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", + "solana-slot-hashes", +] + [[package]] name = "solana-atomic-u64" version = "2.2.1" @@ -505,6 +955,50 @@ dependencies = [ "parking_lot", ] +[[package]] +name = "solana-big-mod-exp" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75db7f2bbac3e62cfd139065d15bcda9e2428883ba61fc8d27ccb251081e7567" +dependencies = [ + "num-bigint", + "num-traits", + "solana-define-syscall", +] + +[[package]] +name = "solana-bincode" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19a3787b8cf9c9fe3dd360800e8b70982b9e5a8af9e11c354b6665dd4a003adc" +dependencies = [ + "bincode", + "serde", + "solana-instruction", +] + +[[package]] +name = "solana-blake3-hasher" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a0801e25a1b31a14494fc80882a036be0ffd290efc4c2d640bfcca120a4672" +dependencies = [ + "blake3", + "solana-define-syscall", + "solana-hash", + "solana-sanitize", +] + +[[package]] +name = "solana-borsh" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "718333bcd0a1a7aed6655aa66bef8d7fb047944922b2d3a18f49cbc13e73d004" +dependencies = [ + "borsh 0.10.4", + "borsh 1.5.5", +] + [[package]] name = "solana-clock" version = "2.2.1" @@ -548,30 +1042,70 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf784bb2cb3e02cac9801813c30187344228d2ae952534902108f6150573a33d" [[package]] -name = "solana-epoch-rewards" +name = "solana-epoch-rewards" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b575d3dd323b9ea10bb6fe89bf6bf93e249b215ba8ed7f68f1a3633f384db7" +dependencies = [ + "serde", + "serde_derive", + "solana-hash", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-epoch-schedule" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fce071fbddecc55d727b1d7ed16a629afe4f6e4c217bc8d00af3b785f6f67ed" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-sysvar-id", +] + +[[package]] +name = "solana-example-mocks" version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b575d3dd323b9ea10bb6fe89bf6bf93e249b215ba8ed7f68f1a3633f384db7" +checksum = "84461d56cbb8bb8d539347151e0525b53910102e4bced875d49d5139708e39d3" dependencies = [ "serde", "serde_derive", + "solana-address-lookup-table-interface", + "solana-clock", "solana-hash", + "solana-instruction", + "solana-keccak-hasher", + "solana-message", + "solana-nonce", + "solana-pubkey", "solana-sdk-ids", - "solana-sdk-macro", - "solana-sysvar-id", + "solana-system-interface", + "thiserror", ] [[package]] -name = "solana-epoch-schedule" -version = "2.2.1" +name = "solana-feature-gate-interface" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fce071fbddecc55d727b1d7ed16a629afe4f6e4c217bc8d00af3b785f6f67ed" +checksum = "43f5c5382b449e8e4e3016fb05e418c53d57782d8b5c30aa372fc265654b956d" dependencies = [ + "bincode", "serde", "serde_derive", + "solana-account", + "solana-account-info", + "solana-instruction", + "solana-program-error", + "solana-pubkey", + "solana-rent", "solana-sdk-ids", - "solana-sdk-macro", - "solana-sysvar-id", + "solana-system-interface", ] [[package]] @@ -591,6 +1125,7 @@ version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf7bcb14392900fe02e4e34e90234fbf0c673d4e327888410ba99fa2ba0f4e99" dependencies = [ + "borsh 1.5.5", "bs58", "bytemuck", "bytemuck_derive", @@ -609,7 +1144,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ce496a475e5062ba5de97215ab39d9c358f9c9df4bb7f3a45a1f1a8bd9065ed" dependencies = [ "bincode", - "getrandom", + "borsh 1.5.5", + "getrandom 0.2.15", "js-sys", "num-traits", "serde", @@ -636,6 +1172,18 @@ dependencies = [ "solana-sysvar-id", ] +[[package]] +name = "solana-keccak-hasher" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7aeb957fbd42a451b99235df4942d96db7ef678e8d5061ef34c9b34cae12f79" +dependencies = [ + "sha3", + "solana-define-syscall", + "solana-hash", + "solana-sanitize", +] + [[package]] name = "solana-last-restart-slot" version = "2.2.1" @@ -649,6 +1197,73 @@ dependencies = [ "solana-sysvar-id", ] +[[package]] +name = "solana-loader-v2-interface" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8ab08006dad78ae7cd30df8eea0539e207d08d91eaefb3e1d49a446e1c49654" +dependencies = [ + "serde", + "serde_bytes", + "serde_derive", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", +] + +[[package]] +name = "solana-loader-v3-interface" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4be76cfa9afd84ca2f35ebc09f0da0f0092935ccdac0595d98447f259538c2" +dependencies = [ + "serde", + "serde_bytes", + "serde_derive", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", + "solana-system-interface", +] + +[[package]] +name = "solana-loader-v4-interface" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "706a777242f1f39a83e2a96a2a6cb034cb41169c6ecbee2cf09cb873d9659e7e" +dependencies = [ + "serde", + "serde_bytes", + "serde_derive", + "solana-instruction", + "solana-pubkey", + "solana-sdk-ids", + "solana-system-interface", +] + +[[package]] +name = "solana-message" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1796aabce376ff74bf89b78d268fa5e683d7d7a96a0a4e4813ec34de49d5314b" +dependencies = [ + "bincode", + "blake3", + "lazy_static", + "serde", + "serde_derive", + "solana-bincode", + "solana-hash", + "solana-instruction", + "solana-pubkey", + "solana-sanitize", + "solana-sdk-ids", + "solana-short-vec", + "solana-system-interface", + "solana-transaction-error", + "wasm-bindgen", +] + [[package]] name = "solana-msg" version = "2.2.1" @@ -658,6 +1273,106 @@ dependencies = [ "solana-define-syscall", ] +[[package]] +name = "solana-native-token" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61515b880c36974053dd499c0510066783f0cc6ac17def0c7ef2a244874cf4a9" + +[[package]] +name = "solana-nonce" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703e22eb185537e06204a5bd9d509b948f0066f2d1d814a6f475dafb3ddf1325" +dependencies = [ + "serde", + "serde_derive", + "solana-fee-calculator", + "solana-hash", + "solana-pubkey", + "solana-sha256-hasher", +] + +[[package]] +name = "solana-program" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "586469467e93ceb79048f8d8e3a619bf61d05396ee7de95cb40280301a589d05" +dependencies = [ + "bincode", + "blake3", + "borsh 0.10.4", + "borsh 1.5.5", + "bs58", + "bytemuck", + "console_error_panic_hook", + "console_log", + "getrandom 0.2.15", + "lazy_static", + "log", + "memoffset", + "num-bigint", + "num-derive", + "num-traits", + "rand 0.8.5", + "serde", + "serde_bytes", + "serde_derive", + "solana-account-info", + "solana-address-lookup-table-interface", + "solana-atomic-u64", + "solana-big-mod-exp", + "solana-bincode", + "solana-blake3-hasher", + "solana-borsh", + "solana-clock", + "solana-cpi", + "solana-decode-error", + "solana-define-syscall", + "solana-epoch-rewards", + "solana-epoch-schedule", + "solana-example-mocks", + "solana-feature-gate-interface", + "solana-fee-calculator", + "solana-hash", + "solana-instruction", + "solana-instructions-sysvar", + "solana-keccak-hasher", + "solana-last-restart-slot", + "solana-loader-v2-interface", + "solana-loader-v3-interface", + "solana-loader-v4-interface", + "solana-message", + "solana-msg", + "solana-native-token", + "solana-nonce", + "solana-program-entrypoint", + "solana-program-error", + "solana-program-memory", + "solana-program-option", + "solana-program-pack", + "solana-pubkey", + "solana-rent", + "solana-sanitize", + "solana-sdk-ids", + "solana-sdk-macro", + "solana-secp256k1-recover", + "solana-serde-varint", + "solana-serialize-utils", + "solana-sha256-hasher", + "solana-short-vec", + "solana-slot-hashes", + "solana-slot-history", + "solana-stable-layout", + "solana-stake-interface", + "solana-system-interface", + "solana-sysvar", + "solana-sysvar-id", + "solana-vote-interface", + "thiserror", + "wasm-bindgen", +] + [[package]] name = "solana-program-entrypoint" version = "2.2.1" @@ -678,6 +1393,8 @@ checksum = "d8ae2c1a8d0d4ae865882d5770a7ebca92bab9c685e43f0461682c6c05a35bfa" dependencies = [ "borsh 1.5.5", "num-traits", + "serde", + "serde_derive", "solana-decode-error", "solana-instruction", "solana-msg", @@ -694,15 +1411,35 @@ dependencies = [ "solana-define-syscall", ] +[[package]] +name = "solana-program-option" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc677a2e9bc616eda6dbdab834d463372b92848b2bfe4a1ed4e4b4adba3397d0" + +[[package]] +name = "solana-program-pack" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "319f0ef15e6e12dc37c597faccb7d62525a509fec5f6975ecb9419efddeb277b" +dependencies = [ + "solana-program-error", +] + [[package]] name = "solana-pubkey" version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40db1ff5a0f8aea2c158d78ab5f2cf897848964251d1df42fef78efd3c85b863" dependencies = [ + "borsh 0.10.4", + "borsh 1.5.5", "bs58", + "bytemuck", + "bytemuck_derive", + "curve25519-dalek", "five8_const", - "getrandom", + "getrandom 0.2.15", "js-sys", "num-traits", "serde", @@ -755,6 +1492,26 @@ dependencies = [ "syn 2.0.98", ] +[[package]] +name = "solana-secp256k1-recover" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baa3120b6cdaa270f39444f5093a90a7b03d296d362878f7a6991d6de3bbe496" +dependencies = [ + "libsecp256k1", + "solana-define-syscall", + "thiserror", +] + +[[package]] +name = "solana-serde-varint" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a7e155eba458ecfb0107b98236088c3764a09ddf0201ec29e52a0be40857113" +dependencies = [ + "serde", +] + [[package]] name = "solana-serialize-utils" version = "2.2.1" @@ -772,11 +1529,20 @@ version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0037386961c0d633421f53560ad7c80675c0447cba4d1bb66d60974dd486c7ea" dependencies = [ - "sha2", + "sha2 0.10.8", "solana-define-syscall", "solana-hash", ] +[[package]] +name = "solana-short-vec" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c54c66f19b9766a56fa0057d060de8378676cb64987533fa088861858fc5a69" +dependencies = [ + "serde", +] + [[package]] name = "solana-slot-hashes" version = "2.2.1" @@ -819,6 +1585,8 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5269e89fde216b4d7e1d1739cf5303f8398a1ff372a81232abbee80e554a838c" dependencies = [ + "borsh 0.10.4", + "borsh 1.5.5", "num-traits", "serde", "serde_derive", @@ -854,8 +1622,10 @@ version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf6b44740d7f0c9f375d045c165bc0aab4a90658f92d6835aeb0649afaeaff9a" dependencies = [ - "base64", + "base64 0.22.1", "bincode", + "bytemuck", + "bytemuck_derive", "lazy_static", "serde", "serde_derive", @@ -893,6 +1663,46 @@ dependencies = [ "solana-sdk-ids", ] +[[package]] +name = "solana-transaction-error" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "222a9dc8fdb61c6088baab34fc3a8b8473a03a7a5fd404ed8dd502fa79b67cb1" +dependencies = [ + "solana-instruction", + "solana-sanitize", +] + +[[package]] +name = "solana-vote-interface" +version = "2.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef4f08746f154458f28b98330c0d55cb431e2de64ee4b8efc98dcbe292e0672b" +dependencies = [ + "bincode", + "num-derive", + "num-traits", + "serde", + "serde_derive", + "solana-clock", + "solana-decode-error", + "solana-hash", + "solana-instruction", + "solana-pubkey", + "solana-rent", + "solana-sdk-ids", + "solana-serde-varint", + "solana-serialize-utils", + "solana-short-vec", + "solana-system-interface", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "syn" version = "1.0.109" @@ -915,6 +1725,26 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "thiserror" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.98", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -974,6 +1804,12 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -1038,6 +1874,16 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "web-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "windows-targets" version = "0.52.5" @@ -1110,3 +1956,29 @@ checksum = "59690dea168f2198d1a3b0cac23b8063efcd11012f10ae4698f284808c8ef603" dependencies = [ "memchr", ] + +[[package]] +name = "zerocopy" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.98", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" diff --git a/crates/litesvm/test_programs/Cargo.toml b/crates/litesvm/test_programs/Cargo.toml index e45595bf..62ea0097 100644 --- a/crates/litesvm/test_programs/Cargo.toml +++ b/crates/litesvm/test_programs/Cargo.toml @@ -11,6 +11,7 @@ solana-program-entrypoint = "2.2" solana-program-error = "2.2" solana-pubkey = "2.2" solana-sysvar = { version = "2.2", features = ["bincode"] } +solana-program = "2.2" [profile.release] overflow-checks = true diff --git a/crates/litesvm/test_programs/counter/Cargo.toml b/crates/litesvm/test_programs/counter/Cargo.toml index d2b81902..5ada6aba 100644 --- a/crates/litesvm/test_programs/counter/Cargo.toml +++ b/crates/litesvm/test_programs/counter/Cargo.toml @@ -18,3 +18,8 @@ solana-msg.workspace = true solana-program-entrypoint.workspace = true solana-program-error = { workspace = true, features = ["borsh"] } solana-pubkey.workspace = true +solana-program.workspace = true +#solana-program-test.workspace = true + +solana-clock = { workspace = true } +solana-sysvar = { workspace = true } diff --git a/crates/litesvm/test_programs/counter/src/lib.rs b/crates/litesvm/test_programs/counter/src/lib.rs index 2b0d20ff..2cf0bf0d 100644 --- a/crates/litesvm/test_programs/counter/src/lib.rs +++ b/crates/litesvm/test_programs/counter/src/lib.rs @@ -4,6 +4,8 @@ use { solana_msg::msg, solana_program_error::{ProgramError, ProgramResult}, solana_pubkey::{declare_id, Pubkey}, + solana_clock::Clock, + solana_sysvar::Sysvar, }; mod state; @@ -23,8 +25,11 @@ pub fn process_instruction( instruction_data: &[u8], ) -> ProgramResult { let (instruction_discriminant, instruction_data_inner) = instruction_data.split_at(1); + msg!("accounts: {:#?}, instdata: {:#?}", accounts, instruction_data); match instruction_discriminant[0] { 0 => { + let got_clock = Clock::get()?; + msg!("Clock timestamp: {:?}", got_clock); msg!("Instruction: Increment"); process_increment_counter(accounts, instruction_data_inner)?; } @@ -53,3 +58,368 @@ pub fn process_increment_counter( msg!("Counter state incremented to {:?}", counter.count); Ok(()) } + +#[no_mangle] +pub unsafe extern "C" fn get_rust_entrypoint() -> *const () { + println!("get_rust_entrypoint() in counter!"); + process_instruction as *const () +} + +#[repr(C)] +pub struct CInstruction { + pub program_id: [u8; 32], + pub accounts_ptr: *const solana_program::instruction::AccountMeta, + pub accounts_len: usize, + pub data_ptr: *const u8, + pub data_len: usize, +} + +impl CInstruction { + pub fn from(instr: &solana_program::instruction::Instruction) -> Self { + CInstruction { + program_id: instr.program_id.to_bytes(), + accounts_ptr: instr.accounts.as_ptr(), + accounts_len: instr.accounts.len(), + data_ptr: instr.data.as_ptr(), + data_len: instr.data.len(), + } + } + + pub fn to_instruction( + cinstr: &CInstruction, + ) -> solana_program::instruction::Instruction { + let accounts: Vec = Vec::from(unsafe { + std::slice::from_raw_parts(cinstr.accounts_ptr as *mut _, cinstr.accounts_len) + }); + let data = Vec::from(unsafe { + std::slice::from_raw_parts(cinstr.data_ptr as *mut _, cinstr.data_len) + }); + solana_program::instruction::Instruction { + program_id: Pubkey::new_from_array(cinstr.program_id), + accounts, + data, + } + } +} + +#[repr(C)] +pub struct CBytes { + pub ptr: *const u8, + pub len: usize, +} + +#[repr(C)] +pub struct CBytesArray { + pub ptr: *const CBytes, + pub len: usize, +} + +#[repr(C)] +pub struct CBytesArrayArray { + pub ptr: *const CBytesArray, + pub len: usize, +} + +impl CBytesArrayArray { + pub fn from(input: &[&[&[u8]]]) -> CBytesArrayArray { + let mut outer = Vec::new(); + let mut all_cbytes = Vec::new(); // To hold all CBytes flat + + for inner in input { + let mut inner_cbytes = Vec::new(); + for slice in *inner { + inner_cbytes.push(CBytes { + ptr: slice.as_ptr(), + len: slice.len(), + }); + } + + let inner_ptr = inner_cbytes.as_ptr(); + all_cbytes.push(inner_cbytes); // store to keep memory alive + + outer.push(CBytesArray { + ptr: inner_ptr, + len: inner.len(), + }); + } + + let outer_ptr = outer.as_ptr(); + // TODO: LEAK IT TO PRESERVE IT! FIX + // ensure memory lives + outer.leak(); + all_cbytes.leak(); + + CBytesArrayArray { + ptr: outer_ptr, + len: input.len(), + } + } + + pub fn to_array_array_array(c: &CBytesArrayArray) -> Vec> { + let mut result = Vec::new(); + for i in 0..c.len { + let c_inner = unsafe { &*c.ptr.add(i) }; + let mut inner = Vec::new(); + + for j in 0..c_inner.len { + let c_bytes = unsafe { &*c_inner.ptr.add(j) }; + let slice = unsafe { std::slice::from_raw_parts(c_bytes.ptr, c_bytes.len) }; + inner.push(slice); + } + + result.push(inner); + } + result + } + + pub fn convert<'a>(input: &'a Vec>) -> Vec<&'a [&'a [u8]]> { + input.iter().map(|inner| inner.as_slice()).collect() + } +} + +#[repr(C)] +pub struct CAccountInfoSlice { + pub ptr: *const CAccountInfo, + pub len: usize, +} + +#[repr(C)] +pub struct CAccountInfo { + pub key: *const u8, // [u8; 32] + pub lamports: *mut u64, + pub data: *mut u8, + pub data_len: usize, + pub owner: *const u8, // [u8; 32] + pub rent_epoch: u64, + pub is_signer: bool, + pub is_writable: bool, + pub executable: bool, +} + +impl CAccountInfoSlice { + fn to_c_account_info_slice<'a, 'b>(ais: &'a [AccountInfo<'b>]) -> CAccountInfoSlice { + let mut c_infos = Vec::with_capacity(ais.len()); + + for ai in ais { + let lamports_ref = &mut *ai.lamports.borrow_mut(); + let data_ref = &mut *ai.data.borrow_mut(); + + c_infos.push(CAccountInfo { + key: ai.key.as_ref().as_ptr(), + lamports: *lamports_ref as *mut u64, + data: data_ref.as_mut_ptr(), + data_len: data_ref.len(), + owner: ai.owner.as_ref().as_ptr(), + rent_epoch: ai.rent_epoch, + is_signer: ai.is_signer, + is_writable: ai.is_writable, + executable: ai.executable, + }); + } + + let slice = CAccountInfoSlice { + ptr: c_infos.as_ptr(), + len: c_infos.len(), + }; + + // TODO: Fix - leak to preserve it. + c_infos.leak(); + slice + } + + pub fn reconstruct_account_infos(slice: &CAccountInfoSlice) -> Vec> { + let mut result = Vec::with_capacity(slice.len); + + unsafe { + for i in 0..slice.len { + let cai = &*slice.ptr.add(i); + + let lamports = std::rc::Rc::new(std::cell::RefCell::new(&mut *cai.lamports)); + let data = std::rc::Rc::new(std::cell::RefCell::new( + std::slice::from_raw_parts_mut(cai.data, cai.data_len), + )); + + result.push(AccountInfo { + key: &*(cai.key as *const Pubkey), + lamports, + data, + owner: &*(cai.owner as *const Pubkey), + rent_epoch: cai.rent_epoch, + is_signer: cai.is_signer, + is_writable: cai.is_writable, + executable: cai.executable, + }); + } + } + + result + } +} + +#[repr(C)] +pub struct SyscallStubsApi { + pub sol_log: extern "C" fn(msg_ptr: *const u8, len: usize), + pub sol_log_compute_units: extern "C" fn(), + pub sol_remaining_compute_units: extern "C" fn() -> u64, + pub sol_invoke_signed: extern "C" fn( + instruction: CInstruction, + account_infos: *mut CAccountInfoSlice, + signers_seeds: CBytesArrayArray, + ) -> i64, + pub sol_get_clock_sysvar: extern "C" fn(var_addr: *mut u8) -> u64, + pub sol_get_epoch_schedule_sysvar: extern "C" fn(var_addr: *mut u8) -> u64, + pub sol_get_fees_sysvar: extern "C" fn(var_addr: *mut u8) -> u64, + pub sol_get_rent_sysvar: extern "C" fn(var_addr: *mut u8) -> u64, + pub sol_get_last_restart_slot: extern "C" fn(var_addr: *mut u8) -> u64, + pub sol_memcpy: extern "C" fn(dst: *mut u8, src: *const u8, n: usize), + pub sol_memmove: extern "C" fn(dst: *mut u8, src: *const u8, n: usize), + pub sol_memcmp: extern "C" fn(s1: *const u8, s2: *const u8, n: usize, result: *mut i32), + pub sol_memset: extern "C" fn(s: *mut u8, c: u8, n: usize), + // pub sol_get_return_data: extern "C" fn() -> Option<(Pubkey, Vec)>, + pub sol_set_return_data: extern "C" fn(data_ptr: *const u8, len: usize), + // pub sol_log_data: extern "C" fn(data: &[&[u8]]), + // pub sol_get_processed_sibling_instruction: extern "C" fn(index: usize) -> Option, + pub sol_get_stack_height: extern "C" fn() -> u64, + pub sol_get_epoch_rewards_sysvar: extern "C" fn(var_addr: *mut u8) -> u64, +} + +#[repr(C)] +pub struct MySyscallStubs { + pub stubs_api: SyscallStubsApi, +} + +#[cfg(not(target_os = "solana"))] +impl solana_program::program_stubs::SyscallStubs for MySyscallStubs { + fn sol_get_clock_sysvar(&self, var_addr: *mut u8) -> u64 { + println!("sol_get_clock_sysvar called"); + let res = (self.stubs_api.sol_get_clock_sysvar)(var_addr); + println!("after sol_get_clock_sysvar"); + res + } + fn sol_get_epoch_rewards_sysvar(&self, var_addr: *mut u8) -> u64 { + (self.stubs_api.sol_get_epoch_rewards_sysvar)(var_addr) + } + fn sol_get_epoch_schedule_sysvar(&self, var_addr: *mut u8) -> u64 { + (self.stubs_api.sol_get_epoch_schedule_sysvar)(var_addr) + } + fn sol_get_fees_sysvar(&self, var_addr: *mut u8) -> u64 { + (self.stubs_api.sol_get_fees_sysvar)(var_addr) + } + fn sol_get_last_restart_slot(&self, var_addr: *mut u8) -> u64 { + (self.stubs_api.sol_get_last_restart_slot)(var_addr) + } + fn sol_get_processed_sibling_instruction( + &self, + _index: usize, + ) -> Option { + println!("sol_get_processed_sibling_instruction called!"); + unimplemented!() + } + fn sol_get_rent_sysvar(&self, var_addr: *mut u8) -> u64 { + (self.stubs_api.sol_get_rent_sysvar)(var_addr) + } + fn sol_get_return_data(&self) -> Option<(Pubkey, Vec)> { + println!("sol_get_return_data called!"); + unimplemented!() + } + fn sol_get_stack_height(&self) -> u64 { + (self.stubs_api.sol_get_stack_height)() + } + fn sol_invoke_signed( + &self, + instruction: &solana_program::instruction::Instruction, + account_infos: &[AccountInfo], + signers_seeds: &[&[&[u8]]], + ) -> ProgramResult { + println!("sol_invoke_signed called!"); + println!("FAV: instruction {:#?}", instruction); + println!("FAV: signers: {:#?}", signers_seeds); + println!("FAV: account_infos: {:#?}", account_infos); + // // TEST + // for ai in account_infos.iter() { + // Box::leak(Box::new(Rc::clone(&ai.lamports))); + // Box::leak(Box::new(Rc::clone(&ai.data))); + // } + // // TEST + let cinstr = CInstruction::from(&instruction); + let caccountinfos = + &mut CAccountInfoSlice::to_c_account_info_slice(&account_infos) as *mut _; + let cbytesarrayarray = CBytesArrayArray::from(&signers_seeds); + for ai in account_infos.iter() { + println!("FAV BEFORE ai: {} -> lamports: {}", ai.key, ai.lamports()); + println!("FAV BEFORE ai: {} -> data.len: {}", ai.key, ai.data_len()); + println!( + "FAV BEFORE ai: {} -> data.ptr: {:p}", + ai.key, + ai.data.as_ptr() + ); + } + (self.stubs_api.sol_invoke_signed)(cinstr, caccountinfos, cbytesarrayarray); + for (i, ai) in account_infos.iter().enumerate() { + println!("FAV AFTER ai: {} -> lamports: {}", ai.key, ai.lamports()); + println!("FAV AFTER ai: {} -> data.len: {}", ai.key, ai.data_len()); + println!( + "FAV AFTER ai: {} -> data.ptr: {:p}", + ai.key, + ai.data.as_ptr() + ); + + // After the transaction the data might have changed, so update it. + // We expect that the remote has updated it accordingly. + let cai: *mut CAccountInfo = unsafe { (*caccountinfos).ptr.add(i) } as *mut _; + let data_ptr = (*ai.data.borrow_mut()).as_mut_ptr(); + let data_len = unsafe { (*cai).data_len }; + let new_slice = unsafe { std::slice::from_raw_parts_mut(data_ptr, data_len) }; + println!( + "Data's len has changed to new_slice.len(): {}", + new_slice.len() + ); + (*ai.data.borrow_mut()) = new_slice; + } + println!("DONE!"); + Ok(()) + } + fn sol_log(&self, message: &str) { + let len = message.len(); + let msg_ptr = message.as_ptr(); + (self.stubs_api.sol_log)(msg_ptr, len); + } + fn sol_log_compute_units(&self) { + (self.stubs_api.sol_log_compute_units)(); + } + fn sol_log_data(&self, _fields: &[&[u8]]) { + println!("sol_log_data called!"); + unimplemented!() + } + unsafe fn sol_memcmp(&self, s1: *const u8, s2: *const u8, n: usize, result: *mut i32) { + (self.stubs_api.sol_memcmp)(s1, s2, n, result); + } + unsafe fn sol_memcpy(&self, dst: *mut u8, src: *const u8, n: usize) { + (self.stubs_api.sol_memcpy)(dst, src, n); + } + unsafe fn sol_memmove(&self, dst: *mut u8, src: *const u8, n: usize) { + (self.stubs_api.sol_memmove)(dst, src, n); + } + unsafe fn sol_memset(&self, s: *mut u8, c: u8, n: usize) { + (self.stubs_api.sol_memset)(s, c, n); + } + fn sol_remaining_compute_units(&self) -> u64 { + (self.stubs_api.sol_remaining_compute_units)() + } + fn sol_set_return_data(&self, data: &[u8]) { + let len = data.len(); + let data_ptr = data.as_ptr(); + (self.stubs_api.sol_set_return_data)(data_ptr, len); + } +} + +#[cfg(not(target_os = "solana"))] +#[no_mangle] +pub extern "C" fn set_stubs(stubs_api: SyscallStubsApi) { + println!("Calling set_stubs in counter!"); + let stubs = Box::new(MySyscallStubs { stubs_api }); + let _ = solana_program::program_stubs::set_syscall_stubs(stubs); + // let _ = solana_program::program_stubs::set_syscall_stubs(Box::new( + // solana_program_test::SyscallStubs {}, + // )); +} \ No newline at end of file diff --git a/crates/litesvm/tests/counter_test.rs b/crates/litesvm/tests/counter_test.rs index 9b9ad047..d12eeccb 100644 --- a/crates/litesvm/tests/counter_test.rs +++ b/crates/litesvm/tests/counter_test.rs @@ -15,7 +15,7 @@ use { solana_signer::Signer, solana_transaction::{versioned::VersionedTransaction, Transaction}, solana_transaction_error::TransactionError, - std::path::PathBuf, + std::{path::PathBuf, str::FromStr}, }; const NUM_GREETINGS: u8 = 127; @@ -29,6 +29,12 @@ fn read_counter_program() -> Vec { #[test] pub fn integration_test() { let mut svm = LiteSVM::new(); + svm.add_native_program(vec![( + Pubkey::from_str("GtdambwDgHWrDJdVPBkEHGhCwokqgAoch162teUjJse2").unwrap(), + "counter".into(), + "/Users/boris/projects/litesvm/crates/litesvm/test_programs/target/debug/libcounter.dylib" + .into(), + )]); let payer_kp = Keypair::new(); let payer_pk = payer_kp.pubkey(); let program_id = pubkey!("GtdambwDgHWrDJdVPBkEHGhCwokqgAoch162teUjJse2"); @@ -39,7 +45,7 @@ pub fn integration_test() { let _ = svm.set_account( counter_address, Account { - lamports: 5, + lamports: 5000000, data: vec![0_u8; std::mem::size_of::()], owner: program_id, ..Default::default() From 80719f479d20e79277504b6ca418479fe176e2fd Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Wed, 25 Jun 2025 09:09:06 +0300 Subject: [PATCH 02/86] improve the error handling --- crates/litesvm/src/lib.rs | 10 +++++++--- crates/litesvm/tests/counter_test.rs | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/crates/litesvm/src/lib.rs b/crates/litesvm/src/lib.rs index a7bcdc55..a2505bbe 100644 --- a/crates/litesvm/src/lib.rs +++ b/crates/litesvm/src/lib.rs @@ -996,7 +996,7 @@ impl LiteSVM { println!("ORIGINAL TX DONE"); if let Some(pt) = &self.pt { - pt.send_transaction( + let _ = pt.send_transaction( &mut program_test_invoke_context, my_tx, self.accounts.clone(), @@ -1290,8 +1290,12 @@ impl LiteSVM { }); } - pub fn add_native_program(&mut self, programs: Vec) { - self.pt = Some(Pt::new(programs)); + pub fn add_native_program( + &mut self, + programs: Vec, + ) -> Result<(), Box> { + self.pt = Some(Pt::new(programs)?); + Ok(()) } /// Submits a signed transaction. diff --git a/crates/litesvm/tests/counter_test.rs b/crates/litesvm/tests/counter_test.rs index d12eeccb..9f9eb2c5 100644 --- a/crates/litesvm/tests/counter_test.rs +++ b/crates/litesvm/tests/counter_test.rs @@ -29,7 +29,7 @@ fn read_counter_program() -> Vec { #[test] pub fn integration_test() { let mut svm = LiteSVM::new(); - svm.add_native_program(vec![( + let _ = svm.add_native_program(vec![( Pubkey::from_str("GtdambwDgHWrDJdVPBkEHGhCwokqgAoch162teUjJse2").unwrap(), "counter".into(), "/Users/boris/projects/litesvm/crates/litesvm/test_programs/target/debug/libcounter.dylib" From cb0c68a87130a06faa0526e4b4cb94b450d38dcf Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Wed, 25 Jun 2025 09:25:15 +0300 Subject: [PATCH 03/86] clean a little bit --- crates/litesvm/src/lib.rs | 41 +++------------------------------------ 1 file changed, 3 insertions(+), 38 deletions(-) diff --git a/crates/litesvm/src/lib.rs b/crates/litesvm/src/lib.rs index a2505bbe..6786e810 100644 --- a/crates/litesvm/src/lib.rs +++ b/crates/litesvm/src/lib.rs @@ -925,32 +925,7 @@ impl LiteSVM { Ok(program_indices) => { let mut context = self.create_transaction_context(compute_budget, accounts.clone()); - // TEST ----- - // let mut program_test_context = Box::leak(Box::new( - // self.create_transaction_context(compute_budget, accounts), - // )); - // let mut program_test_program_cache_for_tx_batch = - // Box::leak(Box::new(program_cache_for_tx_batch.clone())); - // let mut program_test_invoke_context = Box::leak(Box::new(InvokeContext::new( - // &mut program_test_context, - // &mut program_test_program_cache_for_tx_batch, - // EnvironmentConfig::new( - // *blockhash, - // self.fee_structure.lamports_per_signature, - // 0, - // &|_| 0, - // Arc::new(self.feature_set.clone()), - // &self.accounts.sysvar_cache, - // ), - // Some(LogCollector::new_ref()), - // compute_budget, - // ))); - // println!( - // "SETTING INVOKE CONTEXT!: {:#?}", - // program_test_invoke_context.transaction_context - // ); - // solana_program_test::set_invoke_context(&mut program_test_invoke_context); // TODO: Make this fn public and uncomment - + // TODO: Refactor let my_tx = tx.clone().to_versioned_transaction(); let mut program_test_context = self.create_transaction_context(compute_budget, accounts); @@ -970,7 +945,7 @@ impl LiteSVM { Some(LogCollector::new_ref()), compute_budget, ); - // TEST ----- + // TODO: Refactor let mut tx_result: Result<(), TransactionError> = process_message( tx.message(), @@ -1307,8 +1282,6 @@ impl LiteSVM { }; let log_collector = Rc::new(RefCell::new(log_collector)); let vtx: VersionedTransaction = tx.into(); - // let my_tx = vtx.clone(); - // let my_accounts = self.accounts.clone(); let ExecutionResult { post_accounts, tx_result, @@ -1346,15 +1319,7 @@ impl LiteSVM { .sync_accounts(post_accounts) .expect("It shouldn't be possible to write invalid sysvars in send_transaction."); - let res = TransactionResult::Ok(meta); - - // OUR LOGIC HERE - // Self::my_execute_tx(my_tx, my_accounts); - // if let Some(pt) = &self.pt { - // pt.send_transaction(my_tx, my_accounts); - // } - - res + TransactionResult::Ok(meta) } } From 03b8db6a0ce177a1eccaf8df1e8a2f4cc9aa1b99 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Wed, 25 Jun 2025 09:26:02 +0300 Subject: [PATCH 04/86] add the gen_cov.sh for testing --- crates/litesvm/tests/gen_cov.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100755 crates/litesvm/tests/gen_cov.sh diff --git a/crates/litesvm/tests/gen_cov.sh b/crates/litesvm/tests/gen_cov.sh new file mode 100755 index 00000000..a464e226 --- /dev/null +++ b/crates/litesvm/tests/gen_cov.sh @@ -0,0 +1,10 @@ +rm -rf /Users/boris/projects/litesvm/crates/litesvm/tests/profraw/ +export LLVM_PROFILE_FILE="/Users/boris/projects/litesvm/crates/litesvm/tests/profraw/%p-%m.profraw" +mkdir -p /Users/boris/projects/litesvm/crates/litesvm/tests/profraw +RUSTFLAGS="--emit=llvm-ir -Z coverage-options=mcdc -C instrument-coverage" cargo +nightly test -- --nocapture --exact integration_test +llvm-profdata merge -sparse profraw/*.profraw -o merged.profdata +llvm-cov show \ + /Users/boris/projects/litesvm/crates/litesvm/test_programs/target/debug/libcounter.dylib \ + -instr-profile=merged.profdata \ + --format=html -output-dir=htmlcov +#open htmlcov/index.html From 1b2182b5d59ff39790b9bff981d52e3eeda3a105 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Wed, 25 Jun 2025 09:26:44 +0300 Subject: [PATCH 05/86] forgotten file.... --- crates/litesvm/src/pt.rs | 112 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 crates/litesvm/src/pt.rs diff --git a/crates/litesvm/src/pt.rs b/crates/litesvm/src/pt.rs new file mode 100644 index 00000000..c6ae681a --- /dev/null +++ b/crates/litesvm/src/pt.rs @@ -0,0 +1,112 @@ +use std::{cell::RefCell, error::Error, sync::Arc}; + +use solana_account::ReadableAccount; +use solana_program_test::{ + processor, set_invoke_context, InvokeContext, ProgramTest, ProgramTestContext, +}; +use solana_pubkey::Pubkey; +use solana_signer::Signer; +use solana_transaction::versioned::VersionedTransaction; +use solts_rs::loader::Loader; +use tokio::runtime::Runtime; + +use crate::accounts_db::AccountsDb; +pub type PtError = Result>; +pub type ProgramName = String; +pub type Path = String; +pub type NativeProgram = (Pubkey, ProgramName, Path); + +#[derive(Clone)] +pub struct Pt { + pub programs: Vec, + pub pt_context: Arc>, + rt: Arc>, +} + +impl Pt { + pub fn new(programs: Vec) -> PtError { + let static_programs = Box::leak(Box::new(programs.clone())); + let mut pt_native = ProgramTest::default(); + pt_native.prefer_bpf(false); + + let mut loader = Loader::new(); + for (program_id, program_name, so_path) in static_programs.iter() { + println!( + "Adding native program {} with id: {}", + program_name, program_id + ); + loader.add(&so_path, &program_name, &program_id)?; + pt_native.add_program( + program_name, + *program_id, + processor!(solts_rs::loader::entry_wrapper), + ); + } + println!("Loaded: {:?}", loader); + + let rt = tokio::runtime::Runtime::new()?; + let pt_context = rt.block_on(async move { + let pt_context = pt_native.start_with_context().await; + pt_context + }); + loader.adjust_stubs()?; + Ok(Self { + pt_context: Arc::new(RefCell::new(pt_context)), + programs, + rt: Arc::new(Box::new(rt)), + }) + } + + pub fn send_transaction( + &self, + mut invoke_context: &mut InvokeContext, + tx: VersionedTransaction, + accounts_db: AccountsDb, + ) -> PtError<()> { + set_invoke_context(&mut invoke_context); + let _: PtError<()> = self.rt.block_on(async { + for (account_address, account) in &accounts_db.inner { + // println!("Account: {:#?} data: {:#?}", account_address, account); + let to_add = self + .programs + .iter() + .find(|(id, _, _)| id == account.owner()) + .is_some(); + if to_add == true { + self.pt_context + .borrow_mut() + .set_account(account_address, account); + } + } + let recent_blockhash = self + .pt_context + .borrow() + .banks_client + .get_latest_blockhash() + .await?; + + println!("PREPARING TRANS: {:#?}", tx); + let mut trans = tx + .clone() + .into_legacy_transaction() + .ok_or("Can't convert to legacy tx".to_string())?; + let payer = &self.pt_context.borrow().payer; + println!("TRANS PAYER: {}", payer.pubkey()); + trans.message.recent_blockhash = recent_blockhash; + trans.message.account_keys[0] = payer.pubkey().clone(); + trans.sign(&[&payer], recent_blockhash); + let versioned_tx = VersionedTransaction::from(trans); + println!("TRANS AFTER SIGN: {:#?}", versioned_tx); + + let res = self + .pt_context + .borrow() + .banks_client + .process_transaction(versioned_tx) + .await; + println!("OUR TX RES: {:?}", res); + Ok(()) + }); + Ok(()) + } +} From 7af278f72d63ce740ae5baa8a1d7c124a45a58b3 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Wed, 25 Jun 2025 09:28:47 +0300 Subject: [PATCH 06/86] cleaning up --- crates/litesvm/src/lib.rs | 86 --------------------------------------- 1 file changed, 86 deletions(-) diff --git a/crates/litesvm/src/lib.rs b/crates/litesvm/src/lib.rs index 6786e810..1233b2db 100644 --- a/crates/litesvm/src/lib.rs +++ b/crates/litesvm/src/lib.rs @@ -1179,92 +1179,6 @@ impl LiteSVM { }) } - #[allow(dead_code)] - fn my_execute_tx(tx: VersionedTransaction, accounts: AccountsDb) { - println!("-----------------------------------------------------------------------------------------------------"); - println!("-----------------------------------------------------------------------------------------------------"); - println!("-----------------------------------------------------------------------------------------------------"); - println!("-----------------------------------------------------------------------------------------------------"); - println!("-----------------------------------------------------------------------------------------------------"); - let mut pt_native = ProgramTest::default(); - pt_native.prefer_bpf(false); - - let so_path = "/Users/boris/projects/litesvm/crates/litesvm/test_programs/target/debug/libcounter.dylib"; - let programs = [( - Pubkey::from_str("GtdambwDgHWrDJdVPBkEHGhCwokqgAoch162teUjJse2").unwrap(), - "counter", - )]; - let mut loader = Loader::new(); - for (program_id, program_name) in &programs { - println!( - "Adding native program {} with id: {}", - program_name, program_id - ); - loader.add(so_path, &program_name, &program_id).unwrap(); - pt_native.add_program( - &program_name, - *program_id, - processor!(solts_rs::loader::entry_wrapper), - ); - } - println!("Loaded: {:?}", loader); - // let rt = tokio::runtime::Builder::new_current_thread() - // .enable_time() - // .build() - // .unwrap(); - let rt = tokio::runtime::Runtime::new().unwrap(); - rt.block_on(async { - let mut pt_context = pt_native.start_with_context().await; - // let counter_address = pubkey!("J39wvrFY2AkoAUCke5347RMNk3ditxZfVidoZ7U6Fguf"); - // let program_id = pubkey!("GtdambwDgHWrDJdVPBkEHGhCwokqgAoch162teUjJse2"); - // let _ = pt_context - // .set_account(&counter_address, &AccountSharedData::new(5, 4, &program_id)); - loader.adjust_stubs().unwrap(); - for (account_address, account) in &accounts.inner { - // println!("Account: {:#?} data: {:#?}", account_address, account); - let to_add = programs - .iter() - .find(|(id, _)| id == account.owner()) - .is_some(); - if to_add == true { - pt_context.set_account(account_address, account); - } - } - let recent_blockhash = pt_context - .banks_client - .get_latest_blockhash() - .await - .unwrap(); - println!("PREPARING TRANS: {:#?}", tx); - let mut trans = tx.clone().into_legacy_transaction().unwrap(); - let payer = pt_context.payer; - println!("Payer: {}", payer.pubkey()); - trans.message.recent_blockhash = recent_blockhash; - trans.message.account_keys[0] = payer.pubkey().clone(); - trans.sign(&[&payer], recent_blockhash); - let versioned_tx = VersionedTransaction::from(trans); - println!("TRANS AFTER SIGN: {:#?}", versioned_tx); - - let res = pt_context - .banks_client - .process_transaction(versioned_tx) - .await; - println!("OUR TX RES: {:?}", res); - let acc = pt_context - .banks_client - .get_account(pubkey!("J39wvrFY2AkoAUCke5347RMNk3ditxZfVidoZ7U6Fguf")) - .await - .unwrap(); - if acc.is_some() { - println!("ACCOUNT IS HERE!"); - } - println!("#################################### END"); - println!("#################################### END"); - println!("#################################### END"); - println!("#################################### END"); - }); - } - pub fn add_native_program( &mut self, programs: Vec, From e772c1678df032fe41bebf5749a6997f48c80339 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Wed, 25 Jun 2025 11:30:10 +0300 Subject: [PATCH 07/86] Start using the sol-stubs crate --- Cargo.lock | 8 + crates/litesvm/test_programs/Cargo.lock | 8 + crates/litesvm/test_programs/Cargo.toml | 1 + .../litesvm/test_programs/counter/Cargo.toml | 1 + .../litesvm/test_programs/counter/src/lib.rs | 367 +----------------- 5 files changed, 21 insertions(+), 364 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e27e4317..9c8e0cbb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4178,6 +4178,13 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "sol-stubs" +version = "0.1.0" +dependencies = [ + "lazy_static", +] + [[package]] name = "solana-account" version = "2.2.1" @@ -7135,6 +7142,7 @@ dependencies = [ "lazy_static", "libloading", "serde", + "sol-stubs", "solana-program-test 2.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "solana-sdk", "tokio", diff --git a/crates/litesvm/test_programs/Cargo.lock b/crates/litesvm/test_programs/Cargo.lock index a60b6156..31b2d7e1 100644 --- a/crates/litesvm/test_programs/Cargo.lock +++ b/crates/litesvm/test_programs/Cargo.lock @@ -297,6 +297,7 @@ name = "counter" version = "0.1.0" dependencies = [ "borsh 0.9.3", + "sol-stubs", "solana-account-info", "solana-clock", "solana-msg", @@ -903,6 +904,13 @@ version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +[[package]] +name = "sol-stubs" +version = "0.1.0" +dependencies = [ + "lazy_static", +] + [[package]] name = "solana-account" version = "2.2.1" diff --git a/crates/litesvm/test_programs/Cargo.toml b/crates/litesvm/test_programs/Cargo.toml index 62ea0097..34d0f135 100644 --- a/crates/litesvm/test_programs/Cargo.toml +++ b/crates/litesvm/test_programs/Cargo.toml @@ -12,6 +12,7 @@ solana-program-error = "2.2" solana-pubkey = "2.2" solana-sysvar = { version = "2.2", features = ["bincode"] } solana-program = "2.2" +sol-stubs = { path = "/Users/boris/projects/solana/sol-stubs" } [profile.release] overflow-checks = true diff --git a/crates/litesvm/test_programs/counter/Cargo.toml b/crates/litesvm/test_programs/counter/Cargo.toml index 5ada6aba..0e86a924 100644 --- a/crates/litesvm/test_programs/counter/Cargo.toml +++ b/crates/litesvm/test_programs/counter/Cargo.toml @@ -20,6 +20,7 @@ solana-program-error = { workspace = true, features = ["borsh"] } solana-pubkey.workspace = true solana-program.workspace = true #solana-program-test.workspace = true +sol-stubs = { path = "/Users/boris/projects/solana/sol-stubs" } solana-clock = { workspace = true } solana-sysvar = { workspace = true } diff --git a/crates/litesvm/test_programs/counter/src/lib.rs b/crates/litesvm/test_programs/counter/src/lib.rs index 2cf0bf0d..94d6eba2 100644 --- a/crates/litesvm/test_programs/counter/src/lib.rs +++ b/crates/litesvm/test_programs/counter/src/lib.rs @@ -59,367 +59,6 @@ pub fn process_increment_counter( Ok(()) } -#[no_mangle] -pub unsafe extern "C" fn get_rust_entrypoint() -> *const () { - println!("get_rust_entrypoint() in counter!"); - process_instruction as *const () -} - -#[repr(C)] -pub struct CInstruction { - pub program_id: [u8; 32], - pub accounts_ptr: *const solana_program::instruction::AccountMeta, - pub accounts_len: usize, - pub data_ptr: *const u8, - pub data_len: usize, -} - -impl CInstruction { - pub fn from(instr: &solana_program::instruction::Instruction) -> Self { - CInstruction { - program_id: instr.program_id.to_bytes(), - accounts_ptr: instr.accounts.as_ptr(), - accounts_len: instr.accounts.len(), - data_ptr: instr.data.as_ptr(), - data_len: instr.data.len(), - } - } - - pub fn to_instruction( - cinstr: &CInstruction, - ) -> solana_program::instruction::Instruction { - let accounts: Vec = Vec::from(unsafe { - std::slice::from_raw_parts(cinstr.accounts_ptr as *mut _, cinstr.accounts_len) - }); - let data = Vec::from(unsafe { - std::slice::from_raw_parts(cinstr.data_ptr as *mut _, cinstr.data_len) - }); - solana_program::instruction::Instruction { - program_id: Pubkey::new_from_array(cinstr.program_id), - accounts, - data, - } - } -} - -#[repr(C)] -pub struct CBytes { - pub ptr: *const u8, - pub len: usize, -} - -#[repr(C)] -pub struct CBytesArray { - pub ptr: *const CBytes, - pub len: usize, -} - -#[repr(C)] -pub struct CBytesArrayArray { - pub ptr: *const CBytesArray, - pub len: usize, -} - -impl CBytesArrayArray { - pub fn from(input: &[&[&[u8]]]) -> CBytesArrayArray { - let mut outer = Vec::new(); - let mut all_cbytes = Vec::new(); // To hold all CBytes flat - - for inner in input { - let mut inner_cbytes = Vec::new(); - for slice in *inner { - inner_cbytes.push(CBytes { - ptr: slice.as_ptr(), - len: slice.len(), - }); - } - - let inner_ptr = inner_cbytes.as_ptr(); - all_cbytes.push(inner_cbytes); // store to keep memory alive - - outer.push(CBytesArray { - ptr: inner_ptr, - len: inner.len(), - }); - } - - let outer_ptr = outer.as_ptr(); - // TODO: LEAK IT TO PRESERVE IT! FIX - // ensure memory lives - outer.leak(); - all_cbytes.leak(); - - CBytesArrayArray { - ptr: outer_ptr, - len: input.len(), - } - } - - pub fn to_array_array_array(c: &CBytesArrayArray) -> Vec> { - let mut result = Vec::new(); - for i in 0..c.len { - let c_inner = unsafe { &*c.ptr.add(i) }; - let mut inner = Vec::new(); - - for j in 0..c_inner.len { - let c_bytes = unsafe { &*c_inner.ptr.add(j) }; - let slice = unsafe { std::slice::from_raw_parts(c_bytes.ptr, c_bytes.len) }; - inner.push(slice); - } - - result.push(inner); - } - result - } - - pub fn convert<'a>(input: &'a Vec>) -> Vec<&'a [&'a [u8]]> { - input.iter().map(|inner| inner.as_slice()).collect() - } -} - -#[repr(C)] -pub struct CAccountInfoSlice { - pub ptr: *const CAccountInfo, - pub len: usize, -} - -#[repr(C)] -pub struct CAccountInfo { - pub key: *const u8, // [u8; 32] - pub lamports: *mut u64, - pub data: *mut u8, - pub data_len: usize, - pub owner: *const u8, // [u8; 32] - pub rent_epoch: u64, - pub is_signer: bool, - pub is_writable: bool, - pub executable: bool, -} - -impl CAccountInfoSlice { - fn to_c_account_info_slice<'a, 'b>(ais: &'a [AccountInfo<'b>]) -> CAccountInfoSlice { - let mut c_infos = Vec::with_capacity(ais.len()); - - for ai in ais { - let lamports_ref = &mut *ai.lamports.borrow_mut(); - let data_ref = &mut *ai.data.borrow_mut(); - - c_infos.push(CAccountInfo { - key: ai.key.as_ref().as_ptr(), - lamports: *lamports_ref as *mut u64, - data: data_ref.as_mut_ptr(), - data_len: data_ref.len(), - owner: ai.owner.as_ref().as_ptr(), - rent_epoch: ai.rent_epoch, - is_signer: ai.is_signer, - is_writable: ai.is_writable, - executable: ai.executable, - }); - } - - let slice = CAccountInfoSlice { - ptr: c_infos.as_ptr(), - len: c_infos.len(), - }; - - // TODO: Fix - leak to preserve it. - c_infos.leak(); - slice - } - - pub fn reconstruct_account_infos(slice: &CAccountInfoSlice) -> Vec> { - let mut result = Vec::with_capacity(slice.len); - - unsafe { - for i in 0..slice.len { - let cai = &*slice.ptr.add(i); - - let lamports = std::rc::Rc::new(std::cell::RefCell::new(&mut *cai.lamports)); - let data = std::rc::Rc::new(std::cell::RefCell::new( - std::slice::from_raw_parts_mut(cai.data, cai.data_len), - )); - - result.push(AccountInfo { - key: &*(cai.key as *const Pubkey), - lamports, - data, - owner: &*(cai.owner as *const Pubkey), - rent_epoch: cai.rent_epoch, - is_signer: cai.is_signer, - is_writable: cai.is_writable, - executable: cai.executable, - }); - } - } - - result - } -} - -#[repr(C)] -pub struct SyscallStubsApi { - pub sol_log: extern "C" fn(msg_ptr: *const u8, len: usize), - pub sol_log_compute_units: extern "C" fn(), - pub sol_remaining_compute_units: extern "C" fn() -> u64, - pub sol_invoke_signed: extern "C" fn( - instruction: CInstruction, - account_infos: *mut CAccountInfoSlice, - signers_seeds: CBytesArrayArray, - ) -> i64, - pub sol_get_clock_sysvar: extern "C" fn(var_addr: *mut u8) -> u64, - pub sol_get_epoch_schedule_sysvar: extern "C" fn(var_addr: *mut u8) -> u64, - pub sol_get_fees_sysvar: extern "C" fn(var_addr: *mut u8) -> u64, - pub sol_get_rent_sysvar: extern "C" fn(var_addr: *mut u8) -> u64, - pub sol_get_last_restart_slot: extern "C" fn(var_addr: *mut u8) -> u64, - pub sol_memcpy: extern "C" fn(dst: *mut u8, src: *const u8, n: usize), - pub sol_memmove: extern "C" fn(dst: *mut u8, src: *const u8, n: usize), - pub sol_memcmp: extern "C" fn(s1: *const u8, s2: *const u8, n: usize, result: *mut i32), - pub sol_memset: extern "C" fn(s: *mut u8, c: u8, n: usize), - // pub sol_get_return_data: extern "C" fn() -> Option<(Pubkey, Vec)>, - pub sol_set_return_data: extern "C" fn(data_ptr: *const u8, len: usize), - // pub sol_log_data: extern "C" fn(data: &[&[u8]]), - // pub sol_get_processed_sibling_instruction: extern "C" fn(index: usize) -> Option, - pub sol_get_stack_height: extern "C" fn() -> u64, - pub sol_get_epoch_rewards_sysvar: extern "C" fn(var_addr: *mut u8) -> u64, -} - -#[repr(C)] -pub struct MySyscallStubs { - pub stubs_api: SyscallStubsApi, -} - -#[cfg(not(target_os = "solana"))] -impl solana_program::program_stubs::SyscallStubs for MySyscallStubs { - fn sol_get_clock_sysvar(&self, var_addr: *mut u8) -> u64 { - println!("sol_get_clock_sysvar called"); - let res = (self.stubs_api.sol_get_clock_sysvar)(var_addr); - println!("after sol_get_clock_sysvar"); - res - } - fn sol_get_epoch_rewards_sysvar(&self, var_addr: *mut u8) -> u64 { - (self.stubs_api.sol_get_epoch_rewards_sysvar)(var_addr) - } - fn sol_get_epoch_schedule_sysvar(&self, var_addr: *mut u8) -> u64 { - (self.stubs_api.sol_get_epoch_schedule_sysvar)(var_addr) - } - fn sol_get_fees_sysvar(&self, var_addr: *mut u8) -> u64 { - (self.stubs_api.sol_get_fees_sysvar)(var_addr) - } - fn sol_get_last_restart_slot(&self, var_addr: *mut u8) -> u64 { - (self.stubs_api.sol_get_last_restart_slot)(var_addr) - } - fn sol_get_processed_sibling_instruction( - &self, - _index: usize, - ) -> Option { - println!("sol_get_processed_sibling_instruction called!"); - unimplemented!() - } - fn sol_get_rent_sysvar(&self, var_addr: *mut u8) -> u64 { - (self.stubs_api.sol_get_rent_sysvar)(var_addr) - } - fn sol_get_return_data(&self) -> Option<(Pubkey, Vec)> { - println!("sol_get_return_data called!"); - unimplemented!() - } - fn sol_get_stack_height(&self) -> u64 { - (self.stubs_api.sol_get_stack_height)() - } - fn sol_invoke_signed( - &self, - instruction: &solana_program::instruction::Instruction, - account_infos: &[AccountInfo], - signers_seeds: &[&[&[u8]]], - ) -> ProgramResult { - println!("sol_invoke_signed called!"); - println!("FAV: instruction {:#?}", instruction); - println!("FAV: signers: {:#?}", signers_seeds); - println!("FAV: account_infos: {:#?}", account_infos); - // // TEST - // for ai in account_infos.iter() { - // Box::leak(Box::new(Rc::clone(&ai.lamports))); - // Box::leak(Box::new(Rc::clone(&ai.data))); - // } - // // TEST - let cinstr = CInstruction::from(&instruction); - let caccountinfos = - &mut CAccountInfoSlice::to_c_account_info_slice(&account_infos) as *mut _; - let cbytesarrayarray = CBytesArrayArray::from(&signers_seeds); - for ai in account_infos.iter() { - println!("FAV BEFORE ai: {} -> lamports: {}", ai.key, ai.lamports()); - println!("FAV BEFORE ai: {} -> data.len: {}", ai.key, ai.data_len()); - println!( - "FAV BEFORE ai: {} -> data.ptr: {:p}", - ai.key, - ai.data.as_ptr() - ); - } - (self.stubs_api.sol_invoke_signed)(cinstr, caccountinfos, cbytesarrayarray); - for (i, ai) in account_infos.iter().enumerate() { - println!("FAV AFTER ai: {} -> lamports: {}", ai.key, ai.lamports()); - println!("FAV AFTER ai: {} -> data.len: {}", ai.key, ai.data_len()); - println!( - "FAV AFTER ai: {} -> data.ptr: {:p}", - ai.key, - ai.data.as_ptr() - ); - - // After the transaction the data might have changed, so update it. - // We expect that the remote has updated it accordingly. - let cai: *mut CAccountInfo = unsafe { (*caccountinfos).ptr.add(i) } as *mut _; - let data_ptr = (*ai.data.borrow_mut()).as_mut_ptr(); - let data_len = unsafe { (*cai).data_len }; - let new_slice = unsafe { std::slice::from_raw_parts_mut(data_ptr, data_len) }; - println!( - "Data's len has changed to new_slice.len(): {}", - new_slice.len() - ); - (*ai.data.borrow_mut()) = new_slice; - } - println!("DONE!"); - Ok(()) - } - fn sol_log(&self, message: &str) { - let len = message.len(); - let msg_ptr = message.as_ptr(); - (self.stubs_api.sol_log)(msg_ptr, len); - } - fn sol_log_compute_units(&self) { - (self.stubs_api.sol_log_compute_units)(); - } - fn sol_log_data(&self, _fields: &[&[u8]]) { - println!("sol_log_data called!"); - unimplemented!() - } - unsafe fn sol_memcmp(&self, s1: *const u8, s2: *const u8, n: usize, result: *mut i32) { - (self.stubs_api.sol_memcmp)(s1, s2, n, result); - } - unsafe fn sol_memcpy(&self, dst: *mut u8, src: *const u8, n: usize) { - (self.stubs_api.sol_memcpy)(dst, src, n); - } - unsafe fn sol_memmove(&self, dst: *mut u8, src: *const u8, n: usize) { - (self.stubs_api.sol_memmove)(dst, src, n); - } - unsafe fn sol_memset(&self, s: *mut u8, c: u8, n: usize) { - (self.stubs_api.sol_memset)(s, c, n); - } - fn sol_remaining_compute_units(&self) -> u64 { - (self.stubs_api.sol_remaining_compute_units)() - } - fn sol_set_return_data(&self, data: &[u8]) { - let len = data.len(); - let data_ptr = data.as_ptr(); - (self.stubs_api.sol_set_return_data)(data_ptr, len); - } -} - -#[cfg(not(target_os = "solana"))] -#[no_mangle] -pub extern "C" fn set_stubs(stubs_api: SyscallStubsApi) { - println!("Calling set_stubs in counter!"); - let stubs = Box::new(MySyscallStubs { stubs_api }); - let _ = solana_program::program_stubs::set_syscall_stubs(stubs); - // let _ = solana_program::program_stubs::set_syscall_stubs(Box::new( - // solana_program_test::SyscallStubs {}, - // )); -} \ No newline at end of file +use solana_program::instruction::AccountMeta; +use solana_program::instruction::Instruction; +sol_stubs::declare_sol_app_stubs!(process_instruction); \ No newline at end of file From 509d0c79d76e5b8d21bfa56c83d4f28b690dfffd Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Wed, 25 Jun 2025 12:25:25 +0300 Subject: [PATCH 08/86] integrate the loader part --- Cargo.lock | 61 ++----------------- crates/litesvm/Cargo.toml | 5 +- crates/litesvm/src/lib.rs | 6 +- crates/litesvm/src/pt.rs | 12 ++-- .../test_programs/clock-example/src/lib.rs | 7 +-- .../litesvm/test_programs/counter/src/lib.rs | 10 ++- .../litesvm/test_programs/failure/src/lib.rs | 3 +- 7 files changed, 26 insertions(+), 78 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9c8e0cbb..fbe562f5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2463,10 +2463,13 @@ dependencies = [ "ed25519-dalek", "indexmap", "itertools 0.14.0", + "lazy_static", + "libloading", "libsecp256k1", "log", "qualifier_attr", "serde", + "sol-stubs", "solana-account", "solana-address-lookup-table-interface", "solana-bpf-loader-program", @@ -2500,7 +2503,7 @@ dependencies = [ "solana-program-option", "solana-program-pack", "solana-program-runtime", - "solana-program-test 2.2.4", + "solana-program-test", "solana-pubkey", "solana-rent", "solana-reserved-account-keys", @@ -2522,7 +2525,6 @@ dependencies = [ "solana-transaction-context", "solana-transaction-error", "solana-vote-program", - "solts-rs", "spl-associated-token-account-client", "spl-token", "test-log", @@ -5702,43 +5704,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "solana-program-test" -version = "2.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15cedbd823f64af662551bb801687ea98067bbddf06e0394876a40485542667" -dependencies = [ - "assert_matches", - "async-trait", - "base64 0.22.1", - "bincode", - "chrono-humanize", - "crossbeam-channel", - "log", - "serde", - "solana-accounts-db", - "solana-banks-client", - "solana-banks-interface", - "solana-banks-server", - "solana-bpf-loader-program", - "solana-compute-budget", - "solana-feature-set", - "solana-inline-spl", - "solana-instruction", - "solana-log-collector", - "solana-logger", - "solana-program-runtime", - "solana-runtime", - "solana-sbpf", - "solana-sdk", - "solana-sdk-ids", - "solana-svm", - "solana-timings", - "solana-vote-program", - "thiserror 2.0.12", - "tokio", -] - [[package]] name = "solana-pubkey" version = "2.2.1" @@ -7130,24 +7095,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "solts-rs" -version = "0.1.0" -dependencies = [ - "base64 0.22.1", - "bincode", - "borsh 1.5.7", - "bs58", - "jsonrpc-core", - "lazy_static", - "libloading", - "serde", - "sol-stubs", - "solana-program-test 2.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-sdk", - "tokio", -] - [[package]] name = "spinning_top" version = "0.3.0" diff --git a/crates/litesvm/Cargo.toml b/crates/litesvm/Cargo.toml index 4f091e77..9279f897 100644 --- a/crates/litesvm/Cargo.toml +++ b/crates/litesvm/Cargo.toml @@ -70,7 +70,10 @@ solana-transaction-context.workspace = true solana-transaction-error.workspace = true solana-vote-program.workspace = true thiserror.workspace = true -solts-rs = { path = "/Users/boris/projects/solana/solts-rs" } +# solts-rs = { path = "/Users/boris/projects/solana/solts-rs" } +libloading = "0.8.8" +lazy_static = "1.5.0" +sol-stubs = { path = "/Users/boris/projects/solana/sol-stubs" } solana-program-test.workspace = true tokio.workspace = true diff --git a/crates/litesvm/src/lib.rs b/crates/litesvm/src/lib.rs index 1233b2db..50e353ac 100644 --- a/crates/litesvm/src/lib.rs +++ b/crates/litesvm/src/lib.rs @@ -253,18 +253,14 @@ much easier. */ -use std::str::FromStr; use crate::pt::{NativeProgram, Pt}; #[cfg(feature = "nodejs-internal")] use qualifier_attr::qualifiers; -use solana_program_test::{processor, ProgramTest}; -use solana_pubkey::pubkey; #[allow(deprecated)] use solana_sysvar::recent_blockhashes::IterItem; #[allow(deprecated)] use solana_sysvar::{fees::Fees, recent_blockhashes::RecentBlockhashes}; -use solts_rs::loader::Loader; use { crate::{ @@ -342,10 +338,12 @@ pub mod types; mod accounts_db; mod format_logs; mod history; +mod loader; mod message_processor; mod precompiles; mod pt; mod spl; +mod stubs; mod utils; #[derive(Clone)] diff --git a/crates/litesvm/src/pt.rs b/crates/litesvm/src/pt.rs index c6ae681a..799535d1 100644 --- a/crates/litesvm/src/pt.rs +++ b/crates/litesvm/src/pt.rs @@ -7,10 +7,12 @@ use solana_program_test::{ use solana_pubkey::Pubkey; use solana_signer::Signer; use solana_transaction::versioned::VersionedTransaction; -use solts_rs::loader::Loader; use tokio::runtime::Runtime; -use crate::accounts_db::AccountsDb; +use crate::{ + accounts_db::AccountsDb, + loader::{self, Loader}, +}; pub type PtError = Result>; pub type ProgramName = String; pub type Path = String; @@ -36,11 +38,7 @@ impl Pt { program_name, program_id ); loader.add(&so_path, &program_name, &program_id)?; - pt_native.add_program( - program_name, - *program_id, - processor!(solts_rs::loader::entry_wrapper), - ); + pt_native.add_program(program_name, *program_id, processor!(loader::entry_wrapper)); } println!("Loaded: {:?}", loader); diff --git a/crates/litesvm/test_programs/clock-example/src/lib.rs b/crates/litesvm/test_programs/clock-example/src/lib.rs index 30bd77ae..566aa284 100644 --- a/crates/litesvm/test_programs/clock-example/src/lib.rs +++ b/crates/litesvm/test_programs/clock-example/src/lib.rs @@ -1,9 +1,6 @@ use { - solana_account_info::AccountInfo, - solana_clock::Clock, - solana_program_error::ProgramResult, - solana_pubkey::Pubkey, - solana_sysvar::Sysvar, + solana_account_info::AccountInfo, solana_clock::Clock, solana_program_error::ProgramResult, + solana_pubkey::Pubkey, solana_sysvar::Sysvar, }; solana_program_entrypoint::entrypoint!(process_instruction); diff --git a/crates/litesvm/test_programs/counter/src/lib.rs b/crates/litesvm/test_programs/counter/src/lib.rs index 94d6eba2..82d0be82 100644 --- a/crates/litesvm/test_programs/counter/src/lib.rs +++ b/crates/litesvm/test_programs/counter/src/lib.rs @@ -1,10 +1,10 @@ use borsh::{BorshDeserialize, BorshSerialize}; use { solana_account_info::{next_account_info, AccountInfo}, + solana_clock::Clock, solana_msg::msg, solana_program_error::{ProgramError, ProgramResult}, solana_pubkey::{declare_id, Pubkey}, - solana_clock::Clock, solana_sysvar::Sysvar, }; @@ -25,7 +25,11 @@ pub fn process_instruction( instruction_data: &[u8], ) -> ProgramResult { let (instruction_discriminant, instruction_data_inner) = instruction_data.split_at(1); - msg!("accounts: {:#?}, instdata: {:#?}", accounts, instruction_data); + msg!( + "accounts: {:#?}, instdata: {:#?}", + accounts, + instruction_data + ); match instruction_discriminant[0] { 0 => { let got_clock = Clock::get()?; @@ -61,4 +65,4 @@ pub fn process_increment_counter( use solana_program::instruction::AccountMeta; use solana_program::instruction::Instruction; -sol_stubs::declare_sol_app_stubs!(process_instruction); \ No newline at end of file +sol_stubs::declare_sol_app_stubs!(process_instruction); diff --git a/crates/litesvm/test_programs/failure/src/lib.rs b/crates/litesvm/test_programs/failure/src/lib.rs index 0676af80..ee517497 100644 --- a/crates/litesvm/test_programs/failure/src/lib.rs +++ b/crates/litesvm/test_programs/failure/src/lib.rs @@ -2,7 +2,8 @@ use solana_program_entrypoint::entrypoint; use { - solana_account_info::AccountInfo, solana_program_error::{ProgramError, ProgramResult}, + solana_account_info::AccountInfo, + solana_program_error::{ProgramError, ProgramResult}, solana_pubkey::{declare_id, Pubkey}, }; From 188c00255a49629e39f37c30f0fad65adbe70013 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Wed, 25 Jun 2025 12:28:12 +0300 Subject: [PATCH 09/86] forgotten files.. --- crates/litesvm/src/lib.rs | 1 - crates/litesvm/src/loader.rs | 147 +++++++++++++++++++++++++++++++++++ crates/litesvm/src/stubs.rs | 100 ++++++++++++++++++++++++ 3 files changed, 247 insertions(+), 1 deletion(-) create mode 100644 crates/litesvm/src/loader.rs create mode 100644 crates/litesvm/src/stubs.rs diff --git a/crates/litesvm/src/lib.rs b/crates/litesvm/src/lib.rs index 50e353ac..3feeebb4 100644 --- a/crates/litesvm/src/lib.rs +++ b/crates/litesvm/src/lib.rs @@ -253,7 +253,6 @@ much easier. */ - use crate::pt::{NativeProgram, Pt}; #[cfg(feature = "nodejs-internal")] use qualifier_attr::qualifiers; diff --git a/crates/litesvm/src/loader.rs b/crates/litesvm/src/loader.rs new file mode 100644 index 00000000..a1b3b144 --- /dev/null +++ b/crates/litesvm/src/loader.rs @@ -0,0 +1,147 @@ +use std::{ + collections::HashMap, + sync::{atomic::AtomicPtr, Mutex}, +}; + +use crate::stubs::{StubsManager, SyscallStubsApi, UnimplementedSyscallStubs, WrapperSyscallStubs}; +use libloading::{Library, Symbol}; +use solana_program_error::{ProgramError, ProgramResult}; +use solana_pubkey::Pubkey; +use solana_sysvar::{program_stubs::set_syscall_stubs, slot_history::AccountInfo}; + +pub type CommonResult = Result>; +type ProgramCEntrypoint = unsafe extern "C" fn(input: *mut u8) -> u64; +type ProgramRustEntryPoint = unsafe extern "C" fn() -> *const (); +type ProgramSetSyscallStubsApi = unsafe extern "C" fn(stubs_api: SyscallStubsApi); + +lazy_static::lazy_static! { + pub static ref PROGRAMS_MAP: Mutex>> = Mutex::new(HashMap::new()); +} + +pub fn entry_wrapper<'info>( + program_id: &Pubkey, + accounts: &[AccountInfo<'info>], + data: &[u8], +) -> ProgramResult { + println!("entry_wrapper called"); + let map = PROGRAMS_MAP.lock().unwrap(); + let entry = map + .get(&*program_id) + .unwrap() + .load(std::sync::atomic::Ordering::Relaxed); + let fn_ptr = entry as *const (); + let entry: for<'a, 'b, 'info2, 'c> fn( + &'a Pubkey, + &'b [AccountInfo<'info2>], + &'c [u8], + ) -> ProgramResult = unsafe { std::mem::transmute(fn_ptr) }; + entry(program_id, accounts, data) +} + +#[derive(Debug)] +pub struct Loader { + libs: HashMap, +} + +impl Loader { + pub fn new() -> Self { + Self { + libs: HashMap::new(), + } + } + + /// NB: This function must be called after ProgramTest .start/start_context() method! + /// Only after starting we have the appropriate SYSCALL_STUBS initialized. + pub fn adjust_stubs(&self) -> CommonResult<()> { + println!("Adjusting stubs!"); + // So in ProgramTest's start() ...: + // setup_bank() has passed and we have the appropriate stubs! + // First to get them put there unimplemented stubs for a moment. + let program_test_stubs = set_syscall_stubs(Box::new(UnimplementedSyscallStubs {})); + // Store the good ones in our global variable! + StubsManager::my_set_syscall_stubs(program_test_stubs); + // Now create an instance so that program_test's stubs are backed with ours - the wrapper uses our global variable! + set_syscall_stubs(Box::new(WrapperSyscallStubs {})); + + // Now for each program set the appropriate stubs + for (program_id, _) in self.libs.iter() { + // Now create the C interface so that the smart contracts can reach our SYSCALL_STUBS! + let stubs_api = SyscallStubsApi::new(); + // Pass it to the loaded smart contract! + self.set_syscall_stubs_api(&program_id, stubs_api)?; + } + Ok(()) + } + + pub fn add( + &mut self, + so_path: &str, + program_name: &str, + program_id: &Pubkey, + ) -> CommonResult<()> { + let lib = unsafe { Library::new(so_path)? }; + self.libs + .insert(*program_id, (program_name.to_string(), lib)); + + let fn_ptr = self.get_rust_entrypoint(&program_id)?; + let mut map = PROGRAMS_MAP.lock().unwrap(); + map.insert(program_id.clone(), AtomicPtr::new(fn_ptr as *mut _)); + Ok(()) + } + + pub fn set_syscall_stubs_api( + &self, + program_id: &Pubkey, + stubs_api: SyscallStubsApi, + ) -> CommonResult<()> { + let func: Symbol = unsafe { + self.libs + .get(program_id) + .ok_or("No such program_id".to_string())? + .1 + .get(b"set_stubs")? + }; + unsafe { func(stubs_api) }; + Ok(()) + } + + pub fn get_entrypoint( + &self, + program_id: &Pubkey, + ) -> CommonResult> { + let func: Symbol = unsafe { + self.libs + .get(program_id) + .ok_or("No such program_id".to_string())? + .1 + .get(b"entrypoint")? + }; + Ok(func) + } + + pub fn get_rust_entrypoint( + &self, + program_id: &Pubkey, + ) -> CommonResult< + for<'a, 'b, 'info, 'c> fn( + &'a Pubkey, + &'b [AccountInfo<'info>], + &'c [u8], + ) -> Result<(), ProgramError>, + > { + let func: Symbol = unsafe { + self.libs + .get(program_id) + .ok_or("No such program_id".to_string())? + .1 + .get(b"get_rust_entrypoint")? + }; + let fn_ptr = unsafe { func() }; + let rust_fn: for<'a, 'b, 'info, 'c> fn( + &'a Pubkey, + &'b [AccountInfo<'info>], + &'c [u8], + ) -> Result<(), ProgramError> = unsafe { std::mem::transmute(fn_ptr) }; + Ok(rust_fn) + } +} diff --git a/crates/litesvm/src/stubs.rs b/crates/litesvm/src/stubs.rs new file mode 100644 index 00000000..df31bf63 --- /dev/null +++ b/crates/litesvm/src/stubs.rs @@ -0,0 +1,100 @@ +use std::sync::{Arc, RwLock}; + +use sol_stubs::declare_sol_loader_stubs; +use solana_program_error::ProgramResult; +use solana_sysvar::program_stubs::SyscallStubs; + +use solana_instruction::AccountMeta; +use solana_instruction::Instruction; +use solana_pubkey::Pubkey; +use solana_sysvar::slot_history::AccountInfo; +declare_sol_loader_stubs!(); + +pub struct StubsManager; +impl StubsManager { + pub fn my_set_syscall_stubs(syscall_stubs: Box) -> Box { + std::mem::replace(&mut SYSCALL_STUBS.write().unwrap(), syscall_stubs) + } +} + +pub struct WrapperSyscallStubs {} +impl SyscallStubs for WrapperSyscallStubs { + fn sol_get_clock_sysvar(&self, var_addr: *mut u8) -> u64 { + println!("Wrapper sol_get_clock_sysvar"); + SYSCALL_STUBS.read().unwrap().sol_get_clock_sysvar(var_addr) + } + fn sol_get_epoch_rewards_sysvar(&self, var_addr: *mut u8) -> u64 { + SYSCALL_STUBS + .read() + .unwrap() + .sol_get_epoch_rewards_sysvar(var_addr) + } + fn sol_get_epoch_schedule_sysvar(&self, var_addr: *mut u8) -> u64 { + SYSCALL_STUBS + .read() + .unwrap() + .sol_get_epoch_schedule_sysvar(var_addr) + } + fn sol_get_fees_sysvar(&self, var_addr: *mut u8) -> u64 { + SYSCALL_STUBS.read().unwrap().sol_get_fees_sysvar(var_addr) + } + fn sol_get_last_restart_slot(&self, var_addr: *mut u8) -> u64 { + SYSCALL_STUBS + .read() + .unwrap() + .sol_get_last_restart_slot(var_addr) + } + fn sol_get_processed_sibling_instruction(&self, index: usize) -> Option { + SYSCALL_STUBS + .read() + .unwrap() + .sol_get_processed_sibling_instruction(index) + } + fn sol_get_rent_sysvar(&self, var_addr: *mut u8) -> u64 { + SYSCALL_STUBS.read().unwrap().sol_get_rent_sysvar(var_addr) + } + fn sol_get_return_data(&self) -> Option<(Pubkey, Vec)> { + SYSCALL_STUBS.read().unwrap().sol_get_return_data() + } + fn sol_get_stack_height(&self) -> u64 { + SYSCALL_STUBS.read().unwrap().sol_get_stack_height() + } + fn sol_invoke_signed( + &self, + instruction: &Instruction, + account_infos: &[AccountInfo], + signers_seeds: &[&[&[u8]]], + ) -> ProgramResult { + SYSCALL_STUBS + .read() + .unwrap() + .sol_invoke_signed(instruction, account_infos, signers_seeds) + } + fn sol_log(&self, message: &str) { + SYSCALL_STUBS.read().unwrap().sol_log(message); + } + fn sol_log_compute_units(&self) { + SYSCALL_STUBS.read().unwrap().sol_log_compute_units(); + } + fn sol_log_data(&self, fields: &[&[u8]]) { + SYSCALL_STUBS.read().unwrap().sol_log_data(fields); + } + unsafe fn sol_memcmp(&self, s1: *const u8, s2: *const u8, n: usize, result: *mut i32) { + unsafe { SYSCALL_STUBS.read().unwrap().sol_memcmp(s1, s2, n, result) }; + } + unsafe fn sol_memcpy(&self, dst: *mut u8, src: *const u8, n: usize) { + unsafe { SYSCALL_STUBS.read().unwrap().sol_memcpy(dst, src, n) }; + } + unsafe fn sol_memmove(&self, dst: *mut u8, src: *const u8, n: usize) { + unsafe { SYSCALL_STUBS.read().unwrap().sol_memmove(dst, src, n) }; + } + unsafe fn sol_memset(&self, s: *mut u8, c: u8, n: usize) { + unsafe { SYSCALL_STUBS.read().unwrap().sol_memset(s, c, n) }; + } + fn sol_remaining_compute_units(&self) -> u64 { + SYSCALL_STUBS.read().unwrap().sol_remaining_compute_units() + } + fn sol_set_return_data(&self, data: &[u8]) { + SYSCALL_STUBS.read().unwrap().sol_set_return_data(data); + } +} From f8e1b2f12e68068166e1a66d9e909f37b3062b66 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Wed, 25 Jun 2025 12:35:19 +0300 Subject: [PATCH 10/86] silence warnings --- crates/litesvm/src/loader.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/litesvm/src/loader.rs b/crates/litesvm/src/loader.rs index a1b3b144..e00e2dc0 100644 --- a/crates/litesvm/src/loader.rs +++ b/crates/litesvm/src/loader.rs @@ -10,6 +10,7 @@ use solana_pubkey::Pubkey; use solana_sysvar::{program_stubs::set_syscall_stubs, slot_history::AccountInfo}; pub type CommonResult = Result>; +#[allow(dead_code)] type ProgramCEntrypoint = unsafe extern "C" fn(input: *mut u8) -> u64; type ProgramRustEntryPoint = unsafe extern "C" fn() -> *const (); type ProgramSetSyscallStubsApi = unsafe extern "C" fn(stubs_api: SyscallStubsApi); @@ -105,6 +106,7 @@ impl Loader { Ok(()) } + #[allow(dead_code)] pub fn get_entrypoint( &self, program_id: &Pubkey, From 3361af8486670db6bff48064c02be36d47afcfe1 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Wed, 25 Jun 2025 12:39:33 +0300 Subject: [PATCH 11/86] remove wrongly added dep in failure's example --- crates/litesvm/test_programs/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/litesvm/test_programs/Cargo.toml b/crates/litesvm/test_programs/Cargo.toml index 34d0f135..62ea0097 100644 --- a/crates/litesvm/test_programs/Cargo.toml +++ b/crates/litesvm/test_programs/Cargo.toml @@ -12,7 +12,6 @@ solana-program-error = "2.2" solana-pubkey = "2.2" solana-sysvar = { version = "2.2", features = ["bincode"] } solana-program = "2.2" -sol-stubs = { path = "/Users/boris/projects/solana/sol-stubs" } [profile.release] overflow-checks = true From 58938da59edc78bc904d77b85ce4510102ae38fe Mon Sep 17 00:00:00 2001 From: vlady-kotsev Date: Wed, 25 Jun 2025 14:51:31 +0300 Subject: [PATCH 12/86] poc: modify litesvm in order to generate ts test coverage --- Cargo.lock | 127 +-- Cargo.toml | 5 +- crates/lite-coverage/Cargo.toml | 29 + crates/lite-coverage/src/lib.rs | 6 + crates/lite-coverage/src/lite_coverage.rs | 101 +++ crates/lite-coverage/src/loader.rs | 130 +++ crates/lite-coverage/src/stubs.rs | 100 +++ crates/lite-coverage/src/types.rs | 7 + crates/litesvm/Cargo.toml | 2 +- crates/litesvm/src/lib.rs | 179 +++- crates/litesvm/src/pt.rs | 112 --- crates/node-litesvm/litesvm/index.ts | 945 +++++++++++----------- crates/node-litesvm/litesvm/internal.d.ts | 1 + crates/node-litesvm/src/lib.rs | 26 +- 14 files changed, 1051 insertions(+), 719 deletions(-) create mode 100644 crates/lite-coverage/Cargo.toml create mode 100644 crates/lite-coverage/src/lib.rs create mode 100644 crates/lite-coverage/src/lite_coverage.rs create mode 100644 crates/lite-coverage/src/loader.rs create mode 100644 crates/lite-coverage/src/stubs.rs create mode 100644 crates/lite-coverage/src/types.rs delete mode 100644 crates/litesvm/src/pt.rs diff --git a/Cargo.lock b/Cargo.lock index e27e4317..fbc6112d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2447,6 +2447,33 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413" +[[package]] +name = "lite-coverage" +version = "0.1.0" +dependencies = [ + "base64 0.22.1", + "bincode", + "borsh 1.5.7", + "bs58", + "jsonrpc-core", + "lazy_static", + "libloading", + "serde", + "sol-stubs", + "solana-account", + "solana-instruction", + "solana-keypair", + "solana-program", + "solana-program-error", + "solana-program-test", + "solana-pubkey", + "solana-sdk-ids", + "solana-signer", + "solana-sysvar", + "solana-transaction", + "tokio", +] + [[package]] name = "litemap" version = "0.7.5" @@ -2464,6 +2491,7 @@ dependencies = [ "indexmap", "itertools 0.14.0", "libsecp256k1", + "lite-coverage", "log", "qualifier_attr", "serde", @@ -2500,7 +2528,7 @@ dependencies = [ "solana-program-option", "solana-program-pack", "solana-program-runtime", - "solana-program-test 2.2.4", + "solana-program-test", "solana-pubkey", "solana-rent", "solana-reserved-account-keys", @@ -2522,7 +2550,6 @@ dependencies = [ "solana-transaction-context", "solana-transaction-error", "solana-vote-program", - "solts-rs", "spl-associated-token-account-client", "spl-token", "test-log", @@ -4178,6 +4205,13 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "sol-stubs" +version = "0.1.0" +dependencies = [ + "lazy_static", +] + [[package]] name = "solana-account" version = "2.2.1" @@ -5661,45 +5695,6 @@ dependencies = [ [[package]] name = "solana-program-test" version = "2.2.4" -dependencies = [ - "assert_matches", - "async-trait", - "base64 0.22.1", - "bincode", - "chrono-humanize", - "crossbeam-channel", - "log", - "serde", - "solana-accounts-db", - "solana-banks-client", - "solana-banks-interface", - "solana-banks-server", - "solana-bpf-loader-program", - "solana-compute-budget", - "solana-feature-set", - "solana-inline-spl", - "solana-instruction", - "solana-log-collector", - "solana-logger", - "solana-program-runtime", - "solana-runtime", - "solana-sbpf", - "solana-sdk", - "solana-sdk-ids", - "solana-stake-program", - "solana-svm", - "solana-timings", - "solana-vote-program", - "test-case", - "thiserror 2.0.12", - "tokio", -] - -[[package]] -name = "solana-program-test" -version = "2.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15cedbd823f64af662551bb801687ea98067bbddf06e0394876a40485542667" dependencies = [ "assert_matches", "async-trait", @@ -7123,23 +7118,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "solts-rs" -version = "0.1.0" -dependencies = [ - "base64 0.22.1", - "bincode", - "borsh 1.5.7", - "bs58", - "jsonrpc-core", - "lazy_static", - "libloading", - "serde", - "solana-program-test 2.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "solana-sdk", - "tokio", -] - [[package]] name = "spinning_top" version = "0.3.0" @@ -7659,39 +7637,6 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" -[[package]] -name = "test-case" -version = "3.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb2550dd13afcd286853192af8601920d959b14c401fcece38071d53bf0768a8" -dependencies = [ - "test-case-macros", -] - -[[package]] -name = "test-case-core" -version = "3.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adcb7fd841cd518e279be3d5a3eb0636409487998a4aff22f3de87b81e88384f" -dependencies = [ - "cfg-if", - "proc-macro2", - "quote", - "syn 2.0.100", -] - -[[package]] -name = "test-case-macros" -version = "3.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.100", - "test-case-core", -] - [[package]] name = "test-log" version = "0.2.17" diff --git a/Cargo.toml b/Cargo.toml index 7aad185a..7ca65cb3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,7 +60,7 @@ solana-program-option = "2.2" solana-program-pack = "2.2" solana-program-runtime = ">=2.2,<=2.2.4" #solana-program-test = "2.2" -solana-program-test = { path = "./solana-program-test" } +solana-program-test = { path = "../program-test" } solana-pubkey = "2.2" solana-rent = "2.2" solana-reserved-account-keys = "2.2" @@ -90,7 +90,8 @@ spl-token-2022 = "7.0.0" test-log = "0.2" thiserror = "2.0" tokio = "1.35" - +lite-coverage = { path = "crates/lite-coverage" } +sol-stubs = { path = "../sol-stubs" } [profile.bench] debug = true diff --git a/crates/lite-coverage/Cargo.toml b/crates/lite-coverage/Cargo.toml new file mode 100644 index 00000000..0681e4a0 --- /dev/null +++ b/crates/lite-coverage/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "lite-coverage" +version = "0.1.0" +edition = "2021" +[lib] +path = "src/lib.rs" + +[dependencies] +libloading = "0.8.8" +base64 = "0.22.1" +bincode = { workspace = true } +serde = { workspace = true } +jsonrpc-core = "18.0.0" +bs58 = { version = "0.5.1", default-features = false } +borsh = "1.5.7" +solana-program-test = { workspace = true } +solana-account = { workspace = true } +solana-program = { workspace = true } +solana-keypair = { workspace = true } +solana-signer = { workspace = true } +solana-transaction = { workspace = true } +solana-instruction = { workspace = true } +solana-pubkey = { workspace = true } +solana-program-error = { workspace = true } +solana-sysvar = { workspace = true } +solana-sdk-ids = { workspace = true } +tokio = { workspace = true } +lazy_static = "1.5.0" +sol-stubs = { workspace = true } diff --git a/crates/lite-coverage/src/lib.rs b/crates/lite-coverage/src/lib.rs new file mode 100644 index 00000000..815bd6e0 --- /dev/null +++ b/crates/lite-coverage/src/lib.rs @@ -0,0 +1,6 @@ +mod lite_coverage; +mod loader; +mod stubs; +mod types; +pub use lite_coverage::*; +pub use types::*; diff --git a/crates/lite-coverage/src/lite_coverage.rs b/crates/lite-coverage/src/lite_coverage.rs new file mode 100644 index 00000000..2b5e3818 --- /dev/null +++ b/crates/lite-coverage/src/lite_coverage.rs @@ -0,0 +1,101 @@ +use crate::{ + loader::{entrypoint, Loader}, + types::{LiteCoverageError, NativeProgram}, +}; +use { + solana_account::AccountSharedData, + solana_program::pubkey::Pubkey, + solana_program_test::{processor, ProgramTest, ProgramTestContext}, + solana_signer::Signer, + solana_transaction::versioned::VersionedTransaction, + std::{cell::RefCell, sync::Arc}, + tokio::runtime::Runtime, +}; + +#[derive(Clone)] +pub struct LiteCoverage { + pub programs: Vec, + pub pt_context: Arc>, + rt: Arc>, +} + +impl LiteCoverage { + pub fn new(programs: Vec) -> LiteCoverageError { + let static_programs = Box::leak(Box::new(programs.clone())); + let mut program_test = ProgramTest::default(); + program_test.prefer_bpf(false); + + let mut loader = Loader::new(); + for (program_id, program_name, so_path) in static_programs.iter() { + println!( + "Adding native program {} with id: {}", + program_name, program_id + ); + loader.add_program(&so_path, &program_name, &program_id)?; + program_test.add_program(program_name, *program_id, processor!(entrypoint)); + } + println!("Loaded: {:?}", loader); + + let rt = tokio::runtime::Runtime::new()?; + let pt_context = rt.block_on(async move { + let pt_context = program_test.start_with_context().await; + pt_context + }); + loader.adjust_stubs()?; + Ok(Self { + pt_context: Arc::new(RefCell::new(pt_context)), + programs, + rt: Arc::new(Box::new(rt)), + }) + } + + pub fn add_account(&self, account_pubkey: &Pubkey, account_data: &AccountSharedData) { + self.pt_context + .borrow_mut() + .set_account(account_pubkey, account_data); + } + + async fn re_sign_tx( + &self, + tx: &VersionedTransaction, + ) -> LiteCoverageError { + // TODO tx must be resigned for all signers + let payer = &self.pt_context.borrow().payer; + let recent_blockhash = self + .pt_context + .borrow() + .banks_client + .get_latest_blockhash() + .await?; + + let mut trans = tx.clone().into_legacy_transaction().unwrap(); + trans.message.recent_blockhash = recent_blockhash.clone(); + trans.message.account_keys[0] = payer.pubkey().clone(); + trans.sign(&[&payer], recent_blockhash.clone()); + Ok(VersionedTransaction::from(trans)) + } + + pub fn send_transaction( + &self, + tx: VersionedTransaction, + accounts: &[(Pubkey, AccountSharedData)], + ) -> LiteCoverageError<()> { + let _: LiteCoverageError<()> = self.rt.block_on(async { + for (account_pubkey, account_data) in accounts { + self.add_account(account_pubkey, account_data); + } + let re_signed_tx = self.re_sign_tx(&tx).await?; + + let res = self + .pt_context + .borrow() + .banks_client + .process_transaction_with_metadata(re_signed_tx) + .await?; + + println!("OUR TX RES: {:?}", res); + Ok(()) + }); + Ok(()) + } +} diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs new file mode 100644 index 00000000..57bedd8a --- /dev/null +++ b/crates/lite-coverage/src/loader.rs @@ -0,0 +1,130 @@ +use crate::{stubs::{StubsManager, SyscallStubsApi, UnimplementedSyscallStubs, WrapperSyscallStubs}, types::LiteCoverageError}; +use libloading::{Library, Symbol}; +use solana_program::{ + account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError, + program_stubs::set_syscall_stubs, pubkey::Pubkey, +}; +use std::{ + collections::HashMap, + sync::{atomic::AtomicPtr, Mutex}, +}; + +// type ProgramCEntrypoint = unsafe extern "C" fn(input: *mut u8) -> u64; +type ProgramRustEntryPoint = unsafe extern "C" fn() -> *const (); +type ProgramSetSyscallStubsApi = unsafe extern "C" fn(stubs_api: SyscallStubsApi); + +lazy_static::lazy_static! ( + pub static ref PROGRAMS_MAP: Mutex>> = Mutex::new(HashMap::new()); +); + +pub fn entrypoint<'info>( + program_id: &Pubkey, + accounts: &[AccountInfo<'info>], + data: &[u8], +) -> ProgramResult { + let map = PROGRAMS_MAP.lock().unwrap(); + let entry = map + .get(&*program_id) + .unwrap() + .load(std::sync::atomic::Ordering::Relaxed); + let fn_ptr = entry as *const (); + let entry: for<'a, 'b, 'info2, 'c> fn( + &'a Pubkey, + &'b [AccountInfo<'info2>], + &'c [u8], + ) -> ProgramResult = unsafe { std::mem::transmute(fn_ptr) }; + entry(program_id, accounts, data) +} + +#[derive(Debug, Default)] +pub struct Loader { + libs: HashMap, +} + +impl Loader { + pub fn new() -> Self { + Self { + libs: HashMap::new(), + } + } + + /// NB: This function must be called after ProgramTest .start/start_context() method! + /// Only after starting we have the appropriate SYSCALL_STUBS initialized. + pub fn adjust_stubs(&self) -> LiteCoverageError<()> { + // So in ProgramTest's start() ...: + // setup_bank() has passed and we have the appropriate stubs! + // First to get them put there unimplemented stubs for a moment. + let program_test_stubs = set_syscall_stubs(Box::new(UnimplementedSyscallStubs {})); + // Store the good ones in our global variable! + StubsManager::my_set_syscall_stubs(program_test_stubs); + // Now create an instance so that program_test's stubs are backed with ours - the wrapper uses our global variable! + set_syscall_stubs(Box::new(WrapperSyscallStubs {})); + + // Now for each program set the appropriate stubs + for (program_id, _) in self.libs.iter() { + // Now create the C interface so that the solana programs can reach our SYSCALL_STUBS! + let stubs_api = SyscallStubsApi::new(); + // Pass it to the loaded smart contract! + self.set_syscall_stubs_api(&program_id, stubs_api)?; + } + Ok(()) + } + + pub fn add_program( + &mut self, + so_path: &str, + program_name: &str, + program_id: &Pubkey, + ) -> LiteCoverageError<()> { + let lib = unsafe { Library::new(so_path)? }; + self.libs + .insert(*program_id, (program_name.to_string(), lib)); + + let fn_ptr = self.get_rust_entrypoint(&program_id)?; + let mut programs_map = PROGRAMS_MAP.lock().unwrap(); + programs_map.insert(program_id.clone(), AtomicPtr::new(fn_ptr as *mut _)); + Ok(()) + } + + pub fn set_syscall_stubs_api( + &self, + program_id: &Pubkey, + stubs_api: SyscallStubsApi, + ) -> LiteCoverageError<()> { + let func: Symbol = unsafe { + self.libs + .get(program_id) + .ok_or("No such program_id".to_string())? + .1 + .get(b"set_stubs")? + }; + unsafe { func(stubs_api) }; + Ok(()) + } + + fn get_rust_entrypoint( + &self, + program_id: &Pubkey, + ) -> LiteCoverageError< + for<'a, 'b, 'info, 'c> fn( + &'a Pubkey, + &'b [AccountInfo<'info>], + &'c [u8], + ) -> Result<(), ProgramError>, + > { + let func: Symbol = unsafe { + self.libs + .get(program_id) + .ok_or("No such program_id".to_string())? + .1 + .get(b"get_rust_entrypoint")? + }; + let fn_ptr = unsafe { func() }; + let rust_fn: for<'a, 'b, 'info, 'c> fn( + &'a Pubkey, + &'b [AccountInfo<'info>], + &'c [u8], + ) -> Result<(), ProgramError> = unsafe { std::mem::transmute(fn_ptr) }; + Ok(rust_fn) + } +} diff --git a/crates/lite-coverage/src/stubs.rs b/crates/lite-coverage/src/stubs.rs new file mode 100644 index 00000000..df31bf63 --- /dev/null +++ b/crates/lite-coverage/src/stubs.rs @@ -0,0 +1,100 @@ +use std::sync::{Arc, RwLock}; + +use sol_stubs::declare_sol_loader_stubs; +use solana_program_error::ProgramResult; +use solana_sysvar::program_stubs::SyscallStubs; + +use solana_instruction::AccountMeta; +use solana_instruction::Instruction; +use solana_pubkey::Pubkey; +use solana_sysvar::slot_history::AccountInfo; +declare_sol_loader_stubs!(); + +pub struct StubsManager; +impl StubsManager { + pub fn my_set_syscall_stubs(syscall_stubs: Box) -> Box { + std::mem::replace(&mut SYSCALL_STUBS.write().unwrap(), syscall_stubs) + } +} + +pub struct WrapperSyscallStubs {} +impl SyscallStubs for WrapperSyscallStubs { + fn sol_get_clock_sysvar(&self, var_addr: *mut u8) -> u64 { + println!("Wrapper sol_get_clock_sysvar"); + SYSCALL_STUBS.read().unwrap().sol_get_clock_sysvar(var_addr) + } + fn sol_get_epoch_rewards_sysvar(&self, var_addr: *mut u8) -> u64 { + SYSCALL_STUBS + .read() + .unwrap() + .sol_get_epoch_rewards_sysvar(var_addr) + } + fn sol_get_epoch_schedule_sysvar(&self, var_addr: *mut u8) -> u64 { + SYSCALL_STUBS + .read() + .unwrap() + .sol_get_epoch_schedule_sysvar(var_addr) + } + fn sol_get_fees_sysvar(&self, var_addr: *mut u8) -> u64 { + SYSCALL_STUBS.read().unwrap().sol_get_fees_sysvar(var_addr) + } + fn sol_get_last_restart_slot(&self, var_addr: *mut u8) -> u64 { + SYSCALL_STUBS + .read() + .unwrap() + .sol_get_last_restart_slot(var_addr) + } + fn sol_get_processed_sibling_instruction(&self, index: usize) -> Option { + SYSCALL_STUBS + .read() + .unwrap() + .sol_get_processed_sibling_instruction(index) + } + fn sol_get_rent_sysvar(&self, var_addr: *mut u8) -> u64 { + SYSCALL_STUBS.read().unwrap().sol_get_rent_sysvar(var_addr) + } + fn sol_get_return_data(&self) -> Option<(Pubkey, Vec)> { + SYSCALL_STUBS.read().unwrap().sol_get_return_data() + } + fn sol_get_stack_height(&self) -> u64 { + SYSCALL_STUBS.read().unwrap().sol_get_stack_height() + } + fn sol_invoke_signed( + &self, + instruction: &Instruction, + account_infos: &[AccountInfo], + signers_seeds: &[&[&[u8]]], + ) -> ProgramResult { + SYSCALL_STUBS + .read() + .unwrap() + .sol_invoke_signed(instruction, account_infos, signers_seeds) + } + fn sol_log(&self, message: &str) { + SYSCALL_STUBS.read().unwrap().sol_log(message); + } + fn sol_log_compute_units(&self) { + SYSCALL_STUBS.read().unwrap().sol_log_compute_units(); + } + fn sol_log_data(&self, fields: &[&[u8]]) { + SYSCALL_STUBS.read().unwrap().sol_log_data(fields); + } + unsafe fn sol_memcmp(&self, s1: *const u8, s2: *const u8, n: usize, result: *mut i32) { + unsafe { SYSCALL_STUBS.read().unwrap().sol_memcmp(s1, s2, n, result) }; + } + unsafe fn sol_memcpy(&self, dst: *mut u8, src: *const u8, n: usize) { + unsafe { SYSCALL_STUBS.read().unwrap().sol_memcpy(dst, src, n) }; + } + unsafe fn sol_memmove(&self, dst: *mut u8, src: *const u8, n: usize) { + unsafe { SYSCALL_STUBS.read().unwrap().sol_memmove(dst, src, n) }; + } + unsafe fn sol_memset(&self, s: *mut u8, c: u8, n: usize) { + unsafe { SYSCALL_STUBS.read().unwrap().sol_memset(s, c, n) }; + } + fn sol_remaining_compute_units(&self) -> u64 { + SYSCALL_STUBS.read().unwrap().sol_remaining_compute_units() + } + fn sol_set_return_data(&self, data: &[u8]) { + SYSCALL_STUBS.read().unwrap().sol_set_return_data(data); + } +} diff --git a/crates/lite-coverage/src/types.rs b/crates/lite-coverage/src/types.rs new file mode 100644 index 00000000..d0877560 --- /dev/null +++ b/crates/lite-coverage/src/types.rs @@ -0,0 +1,7 @@ +use solana_program::pubkey::Pubkey; +use std::error::Error; + +pub type LiteCoverageError = Result>; +pub type ProgramName = String; +pub type Path = String; +pub type NativeProgram = (Pubkey, ProgramName, Path); diff --git a/crates/litesvm/Cargo.toml b/crates/litesvm/Cargo.toml index 4f091e77..574fe1d1 100644 --- a/crates/litesvm/Cargo.toml +++ b/crates/litesvm/Cargo.toml @@ -70,7 +70,7 @@ solana-transaction-context.workspace = true solana-transaction-error.workspace = true solana-vote-program.workspace = true thiserror.workspace = true -solts-rs = { path = "/Users/boris/projects/solana/solts-rs" } +lite-coverage = { workspace = true } solana-program-test.workspace = true tokio.workspace = true diff --git a/crates/litesvm/src/lib.rs b/crates/litesvm/src/lib.rs index 1233b2db..f08de515 100644 --- a/crates/litesvm/src/lib.rs +++ b/crates/litesvm/src/lib.rs @@ -253,18 +253,14 @@ much easier. */ -use std::str::FromStr; - -use crate::pt::{NativeProgram, Pt}; +pub use lite_coverage::{LiteCoverage, LiteCoverageError, NativeProgram}; #[cfg(feature = "nodejs-internal")] use qualifier_attr::qualifiers; -use solana_program_test::{processor, ProgramTest}; -use solana_pubkey::pubkey; -#[allow(deprecated)] -use solana_sysvar::recent_blockhashes::IterItem; #[allow(deprecated)] -use solana_sysvar::{fees::Fees, recent_blockhashes::RecentBlockhashes}; -use solts_rs::loader::Loader; +use solana_sysvar::{ + fees::Fees, recent_blockhashes::IterItem, recent_blockhashes::RecentBlockhashes, +}; +// use sol_coverage::loader::Loader; use { crate::{ @@ -344,7 +340,7 @@ mod format_logs; mod history; mod message_processor; mod precompiles; -mod pt; + mod spl; mod utils; @@ -360,7 +356,7 @@ pub struct LiteSVM { blockhash_check: bool, fee_structure: FeeStructure, log_bytes_limit: Option, - pt: Option, + lite_coverage: Option, } impl Default for LiteSVM { @@ -376,7 +372,7 @@ impl Default for LiteSVM { blockhash_check: false, fee_structure: FeeStructure::default(), log_bytes_limit: Some(10_000), - pt: None, + lite_coverage: None, } } } @@ -678,7 +674,30 @@ impl LiteSVM { Ok(()) } - /// Adds am SBF program to the test environment. + // /// Adds an SBF program to the test environment from the file specified. + // pub fn add_coverage_program_from_file( + // &mut self, + // program_id: Pubkey, + // program_path: impl AsRef, + // lib_path: impl AsRef, + // ) -> Result<(), std::io::Error> { + // let program_bytes = std::fs::read(program_path)?; + // self + // // maybe load here ? + + // match self.pt { + // Some(_pt) => { + // // TODO: Implement coverage program loading + // Ok(()) + // } + // None => Err(std::io::Error::new( + // std::io::ErrorKind::Other, + // "No program test set", + // )), + // } + // } + + /// Adds an SBF program to the test environment. pub fn add_program(&mut self, program_id: Pubkey, program_bytes: &[u8]) { let program_len = program_bytes.len(); let lamports = self.minimum_balance_for_rent_exemption(program_len); @@ -926,26 +945,7 @@ impl LiteSVM { let mut context = self.create_transaction_context(compute_budget, accounts.clone()); // TODO: Refactor - let my_tx = tx.clone().to_versioned_transaction(); - let mut program_test_context = - self.create_transaction_context(compute_budget, accounts); - let mut program_test_program_cache_for_tx_batch = - program_cache_for_tx_batch.clone(); - let mut program_test_invoke_context = InvokeContext::new( - &mut program_test_context, - &mut program_test_program_cache_for_tx_batch, - EnvironmentConfig::new( - *blockhash, - self.fee_structure.lamports_per_signature, - 0, - &|_| 0, - Arc::new(self.feature_set.clone()), - &self.accounts.sysvar_cache, - ), - Some(LogCollector::new_ref()), - compute_budget, - ); - // TODO: Refactor + let tx_copy = tx.clone().to_versioned_transaction(); let mut tx_result: Result<(), TransactionError> = process_message( tx.message(), @@ -970,12 +970,24 @@ impl LiteSVM { .map(|_| ()); println!("ORIGINAL TX DONE"); - if let Some(pt) = &self.pt { - let _ = pt.send_transaction( - &mut program_test_invoke_context, - my_tx, - self.accounts.clone(), - ); + + if let Some(lite_coverage) = &self.lite_coverage { + // Sync Sysvars + self.sync_sysvars_with_lite_coverage(); + + let account_keys = tx.message().static_account_keys(); + let mut tx_accounts: Vec<(Pubkey, AccountSharedData)> = + Vec::with_capacity(account_keys.len()); + for account_key in account_keys { + let account = self.get_account(account_key); + if let Some(account) = account { + if !account.executable() { + tx_accounts.push((*account_key, account.into())); + } + } + } + + let _ = lite_coverage.send_transaction(tx_copy, &tx_accounts); } if let Err(err) = self.check_accounts_rent(tx, &context) { @@ -994,6 +1006,88 @@ impl LiteSVM { } } + pub fn sync_sysvars_with_lite_coverage(&self) { + let clock_sysvar = self.get_sysvar::(); + self.lite_coverage + .as_ref() + .unwrap() + .pt_context + .borrow_mut() + .set_sysvar(&clock_sysvar); + + let epoch_schedule_sysvar = self.get_sysvar::(); + self.lite_coverage + .as_ref() + .unwrap() + .pt_context + .borrow_mut() + .set_sysvar(&epoch_schedule_sysvar); + + let fees_sysvar = self.get_sysvar::(); + self.lite_coverage + .as_ref() + .unwrap() + .pt_context + .borrow_mut() + .set_sysvar(&fees_sysvar); + + let rent_sysvar = self.get_sysvar::(); + self.lite_coverage + .as_ref() + .unwrap() + .pt_context + .borrow_mut() + .set_sysvar(&rent_sysvar); + + let epoch_rewards_sysvar = self.get_sysvar::(); + self.lite_coverage + .as_ref() + .unwrap() + .pt_context + .borrow_mut() + .set_sysvar(&epoch_rewards_sysvar); + + let recent_blockhashes_sysvar = self.get_sysvar::(); + self.lite_coverage + .as_ref() + .unwrap() + .pt_context + .borrow_mut() + .set_sysvar(&recent_blockhashes_sysvar); + + let slot_hashed_sysvar = self.get_sysvar::(); + self.lite_coverage + .as_ref() + .unwrap() + .pt_context + .borrow_mut() + .set_sysvar(&slot_hashed_sysvar); + + let slot_history_sysvar = self.get_sysvar::(); + self.lite_coverage + .as_ref() + .unwrap() + .pt_context + .borrow_mut() + .set_sysvar(&slot_history_sysvar); + + let stake_history_sysvar = self.get_sysvar::(); + self.lite_coverage + .as_ref() + .unwrap() + .pt_context + .borrow_mut() + .set_sysvar(&stake_history_sysvar); + + let last_restart_slot_sysvar = self.get_sysvar::(); + self.lite_coverage + .as_ref() + .unwrap() + .pt_context + .borrow_mut() + .set_sysvar(&last_restart_slot_sysvar); + } + fn check_accounts_rent( &self, tx: &SanitizedTransaction, @@ -1179,11 +1273,8 @@ impl LiteSVM { }) } - pub fn add_native_program( - &mut self, - programs: Vec, - ) -> Result<(), Box> { - self.pt = Some(Pt::new(programs)?); + pub fn with_coverage(&mut self, programs: Vec) -> LiteCoverageError<()> { + self.lite_coverage = Some(LiteCoverage::new(programs)?); Ok(()) } diff --git a/crates/litesvm/src/pt.rs b/crates/litesvm/src/pt.rs deleted file mode 100644 index c6ae681a..00000000 --- a/crates/litesvm/src/pt.rs +++ /dev/null @@ -1,112 +0,0 @@ -use std::{cell::RefCell, error::Error, sync::Arc}; - -use solana_account::ReadableAccount; -use solana_program_test::{ - processor, set_invoke_context, InvokeContext, ProgramTest, ProgramTestContext, -}; -use solana_pubkey::Pubkey; -use solana_signer::Signer; -use solana_transaction::versioned::VersionedTransaction; -use solts_rs::loader::Loader; -use tokio::runtime::Runtime; - -use crate::accounts_db::AccountsDb; -pub type PtError = Result>; -pub type ProgramName = String; -pub type Path = String; -pub type NativeProgram = (Pubkey, ProgramName, Path); - -#[derive(Clone)] -pub struct Pt { - pub programs: Vec, - pub pt_context: Arc>, - rt: Arc>, -} - -impl Pt { - pub fn new(programs: Vec) -> PtError { - let static_programs = Box::leak(Box::new(programs.clone())); - let mut pt_native = ProgramTest::default(); - pt_native.prefer_bpf(false); - - let mut loader = Loader::new(); - for (program_id, program_name, so_path) in static_programs.iter() { - println!( - "Adding native program {} with id: {}", - program_name, program_id - ); - loader.add(&so_path, &program_name, &program_id)?; - pt_native.add_program( - program_name, - *program_id, - processor!(solts_rs::loader::entry_wrapper), - ); - } - println!("Loaded: {:?}", loader); - - let rt = tokio::runtime::Runtime::new()?; - let pt_context = rt.block_on(async move { - let pt_context = pt_native.start_with_context().await; - pt_context - }); - loader.adjust_stubs()?; - Ok(Self { - pt_context: Arc::new(RefCell::new(pt_context)), - programs, - rt: Arc::new(Box::new(rt)), - }) - } - - pub fn send_transaction( - &self, - mut invoke_context: &mut InvokeContext, - tx: VersionedTransaction, - accounts_db: AccountsDb, - ) -> PtError<()> { - set_invoke_context(&mut invoke_context); - let _: PtError<()> = self.rt.block_on(async { - for (account_address, account) in &accounts_db.inner { - // println!("Account: {:#?} data: {:#?}", account_address, account); - let to_add = self - .programs - .iter() - .find(|(id, _, _)| id == account.owner()) - .is_some(); - if to_add == true { - self.pt_context - .borrow_mut() - .set_account(account_address, account); - } - } - let recent_blockhash = self - .pt_context - .borrow() - .banks_client - .get_latest_blockhash() - .await?; - - println!("PREPARING TRANS: {:#?}", tx); - let mut trans = tx - .clone() - .into_legacy_transaction() - .ok_or("Can't convert to legacy tx".to_string())?; - let payer = &self.pt_context.borrow().payer; - println!("TRANS PAYER: {}", payer.pubkey()); - trans.message.recent_blockhash = recent_blockhash; - trans.message.account_keys[0] = payer.pubkey().clone(); - trans.sign(&[&payer], recent_blockhash); - let versioned_tx = VersionedTransaction::from(trans); - println!("TRANS AFTER SIGN: {:#?}", versioned_tx); - - let res = self - .pt_context - .borrow() - .banks_client - .process_transaction(versioned_tx) - .await; - println!("OUR TX RES: {:?}", res); - Ok(()) - }); - Ok(()) - } -} diff --git a/crates/node-litesvm/litesvm/index.ts b/crates/node-litesvm/litesvm/index.ts index 547e65e7..8856b926 100644 --- a/crates/node-litesvm/litesvm/index.ts +++ b/crates/node-litesvm/litesvm/index.ts @@ -1,87 +1,87 @@ import { - Account, - AddressAndAccount, - Clock, - ComputeBudget, - EpochRewards, - EpochSchedule, - FailedTransactionMetadata, - FeatureSet, - SimulatedTransactionInfo as SimulatedTransactionInfoInner, - LiteSvm as LiteSVMInner, - Rent, - SlotHash, - SlotHistory, - StakeHistory, - TransactionMetadata, + Account, + AddressAndAccount, + Clock, + ComputeBudget, + EpochRewards, + EpochSchedule, + FailedTransactionMetadata, + FeatureSet, + SimulatedTransactionInfo as SimulatedTransactionInfoInner, + LiteSvm as LiteSVMInner, + Rent, + SlotHash, + SlotHistory, + StakeHistory, + TransactionMetadata, } from "./internal"; export { - Account, - Clock, - ComputeBudget, - EpochRewards, - EpochSchedule, - FailedTransactionMetadata, - FeatureSet, - InnerInstruction, - Rent, - SlotHash, - SlotHistory, - SlotHistoryCheck, - StakeHistory, - StakeHistoryEntry, - TransactionMetadata, - TransactionReturnData, + Account, + Clock, + ComputeBudget, + EpochRewards, + EpochSchedule, + FailedTransactionMetadata, + FeatureSet, + InnerInstruction, + Rent, + SlotHash, + SlotHistory, + SlotHistoryCheck, + StakeHistory, + StakeHistoryEntry, + TransactionMetadata, + TransactionReturnData, } from "./internal"; import { - AccountInfo, - PublicKey, - Transaction, - VersionedTransaction, + AccountInfo, + PublicKey, + Transaction, + VersionedTransaction, } from "@solana/web3.js"; export type AccountInfoBytes = AccountInfo; function toAccountInfo(acc: Account): AccountInfoBytes { - const owner = new PublicKey(acc.owner()); - return { - executable: acc.executable(), - owner, - lamports: Number(acc.lamports()), - data: acc.data(), - rentEpoch: Number(acc.rentEpoch()), - }; + const owner = new PublicKey(acc.owner()); + return { + executable: acc.executable(), + owner, + lamports: Number(acc.lamports()), + data: acc.data(), + rentEpoch: Number(acc.rentEpoch()), + }; } function fromAccountInfo(acc: AccountInfoBytes): Account { - const maybeRentEpoch = acc.rentEpoch; - const rentEpoch = maybeRentEpoch || 0; - return new Account( - BigInt(acc.lamports), - acc.data, - acc.owner.toBytes(), - acc.executable, - BigInt(rentEpoch), - ); + const maybeRentEpoch = acc.rentEpoch; + const rentEpoch = maybeRentEpoch || 0; + return new Account( + BigInt(acc.lamports), + acc.data, + acc.owner.toBytes(), + acc.executable, + BigInt(rentEpoch) + ); } function convertAddressAndAccount( - val: AddressAndAccount, + val: AddressAndAccount ): [PublicKey, Account] { - return [new PublicKey(val.address), val.account()]; + return [new PublicKey(val.address), val.account()]; } export class SimulatedTransactionInfo { - constructor(inner: SimulatedTransactionInfoInner) { - this.inner = inner; - } - private inner: SimulatedTransactionInfoInner; - meta(): TransactionMetadata { - return this.inner.meta(); - } - postAccounts(): [PublicKey, Account][] { - return this.inner.postAccounts().map(convertAddressAndAccount); - } + constructor(inner: SimulatedTransactionInfoInner) { + this.inner = inner; + } + private inner: SimulatedTransactionInfoInner; + meta(): TransactionMetadata { + return this.inner.meta(); + } + postAccounts(): [PublicKey, Account][] { + return this.inner.postAccounts().map(convertAddressAndAccount); + } } /** @@ -90,408 +90,417 @@ export class SimulatedTransactionInfo { * Use this to send transactions, query accounts and configure the runtime. */ export class LiteSVM { - /** Create a new LiteSVM instance with standard functionality enabled */ - constructor() { - const inner = new LiteSVMInner(); - this.inner = inner; - } - private inner: LiteSVMInner; - - /** Create a new LiteSVM instance with minimal functionality enabled */ - static default(): LiteSVM { - const svm = new LiteSVM(); - const inner = LiteSVMInner.default(); - svm.inner = inner; - return svm; - } - - /** - * Set the compute budget - * @param budget - The new compute budget - * @returns The modified LiteSVM instance - */ - withComputeBudget(budget: ComputeBudget): LiteSVM { - this.inner.setComputeBudget(budget); - return this; - } - - /** - * Enable or disable sigverify - * @param sigverify - if false, transaction signatures will not be checked. - * @returns The modified LiteSVM instance - */ - withSigverify(sigverify: boolean): LiteSVM { - this.inner.setSigverify(sigverify); - return this; - } - - /** - * Enables or disables transaction blockhash checking. - * @param check - If false, the blockhash check will be skipped - * @returns The modified LiteSVM instance - */ - withBlockhashCheck(check: boolean): LiteSVM { - this.inner.setBlockhashCheck(check); - return this; - } - - /** - * Sets up the standard sysvars. - * @returns The modified LiteSVM instance - */ - withSysvars(): LiteSVM { - this.inner.setSysvars(); - return this; - } - - /** - * Set the FeatureSet used by the VM instance. - * @param featureSet The FeatureSet to use. - * @returns The modified LiteSVM instance - */ - withFeatureSet(featureSet: FeatureSet): LiteSVM { - this.inner.setFeatureSet(featureSet); - return this; - } - - /** - * Adds the standard builtin programs. Use `withFeatureSet` beforehand to change change what builtins are added. - * @returns The modified LiteSVM instance - */ - withBuiltins(): LiteSVM { - this.inner.setBuiltins(); - return this; - } - - /** - * Changes the initial lamports in LiteSVM's airdrop account. - * @param lamports - The number of lamports to set in the airdrop account - * @returns The modified LiteSVM instance - */ - withLamports(lamports: bigint): LiteSVM { - this.inner.setLamports(lamports); - return this; - } - - /** - * Adds the standard SPL programs. - * @returns The modified LiteSVM instance - */ - withSplPrograms(): LiteSVM { - this.inner.setSplPrograms(); - return this; - } - - /** - * Changes the capacity of the transaction history. - * @param capacity - How many transactions to store in history. - * Set this to 0 to disable transaction history and allow duplicate transactions. - * @returns The modified LiteSVM instance - */ - withTransactionHistory(capacity: bigint): LiteSVM { - this.inner.setTransactionHistory(capacity); - return this; - } - - /** - * Set a limit for transaction logs, beyond which they will be truncated. - * @param limit - The limit in bytes. If null, no limit is enforced. - * @returns The modified LiteSVM instance - */ - withLogBytesLimit(limit?: bigint): LiteSVM { - this.inner.setLogBytesLimit(limit); - return this; - } - - /** - * Adds the standard precompiles. Use `withFeatureSet` beforehand to change change what builtins are added. - * @returns The modified LiteSVM instance - */ - withPrecompiles(): LiteSVM { - this.inner.setPrecompiles(); - return this; - } - - /** - * Calculates the minimum balance required to make an account with specified data length rent exempt. - * @param dataLen - The number of bytes in the account. - * @returns The required balance in lamports - */ - minimumBalanceForRentExemption(dataLen: bigint): bigint { - return this.inner.minimumBalanceForRentExemption(dataLen); - } - - /** - * Return the account at the given address. - * If the account is not found, None is returned. - * @param address - The account address to look up. - * @returns The account object, if the account exists. - */ - getAccount(address: PublicKey): AccountInfoBytes | null { - const inner = this.inner.getAccount(address.toBytes()); - return inner === null ? null : toAccountInfo(inner); - } - - /** - * Create or overwrite an account, subverting normal runtime checks. - * - * This method exists to make it easier to set up artificial situations - * that would be difficult to replicate by sending individual transactions. - * Beware that it can be used to create states that would not be reachable - * by sending transactions! - * - * @param address - The address to write to. - * @param account - The account object to write. - */ - setAccount(address: PublicKey, account: AccountInfoBytes) { - this.inner.setAccount(address.toBytes(), fromAccountInfo(account)); - } - - /** - * Gets the balance of the provided account address. - * @param address - The account address. - * @returns The account's balance in lamports. - */ - getBalance(address: PublicKey): bigint | null { - return this.inner.getBalance(address.toBytes()); - } - - /** - * Gets the latest blockhash. - * Since LiteSVM doesn't have blocks, this is an arbitrary value controlled by LiteSVM - * @returns The designated latest blockhash. - */ - latestBlockhash(): string { - return this.inner.latestBlockhash(); - } - - /** - * Gets a transaction from the transaction history. - * @param signature - The transaction signature bytes - * @returns The transaction, if it is found in the history. - */ - getTransaction( - signature: Uint8Array, - ): TransactionMetadata | FailedTransactionMetadata | null { - return this.inner.getTransaction(signature); - } - - /** - * Airdrops the lamport amount specified to the given address. - * @param address The airdrop recipient. - * @param lamports - The amount to airdrop. - * @returns The transaction result. - */ - airdrop( - address: PublicKey, - lamports: bigint, - ): TransactionMetadata | FailedTransactionMetadata | null { - return this.inner.airdrop(address.toBytes(), lamports); - } - - /** - * Adds an SBF program to the test environment from the file specified. - * @param programId - The program ID. - * @param path - The path to the .so file. - */ - addProgramFromFile(programId: PublicKey, path: string) { - return this.inner.addProgramFromFile(programId.toBytes(), path); - } - - /** - * Adds am SBF program to the test environment. - * @param programId - The program ID. - * @param programBytes - The raw bytes of the compiled program. - */ - addProgram(programId: PublicKey, programBytes: Uint8Array) { - return this.inner.addProgram(programId.toBytes(), programBytes); - } - - /** - * Processes a transaction and returns the result. - * @param tx - The transaction to send. - * @returns TransactionMetadata if the transaction succeeds, else FailedTransactionMetadata - */ - sendTransaction( - tx: Transaction | VersionedTransaction, - ): TransactionMetadata | FailedTransactionMetadata { - const internal = this.inner; - const serialized = tx.serialize({ - requireAllSignatures: true, - verifySignatures: internal.getSigverify(), - }); - - if (tx instanceof Transaction) { - return internal.sendLegacyTransaction(serialized); - } else { - return internal.sendVersionedTransaction(serialized); - } - } - - /** - * Simulates a transaction - * @param tx The transaction to simulate - * @returns SimulatedTransactionInfo if simulation succeeds, else FailedTransactionMetadata - */ - simulateTransaction( - tx: Transaction | VersionedTransaction, - ): FailedTransactionMetadata | SimulatedTransactionInfo { - const internal = this.inner; - const serialized = tx.serialize({ - requireAllSignatures: true, - verifySignatures: internal.getSigverify(), - }); - const inner = - tx instanceof Transaction - ? internal.simulateLegacyTransaction(serialized) - : internal.simulateVersionedTransaction(serialized); - return inner instanceof FailedTransactionMetadata - ? inner - : new SimulatedTransactionInfo(inner); - } - - /** - * Expires the current blockhash. - * The return value of `latestBlockhash()` will be different after calling this. - */ - expireBlockhash() { - this.inner.expireBlockhash(); - } - - /** - * Warps the clock to the specified slot. This is a convenience wrapper - * around `setClock()`. - * @param slot - The new slot. - */ - warpToSlot(slot: bigint) { - this.inner.warpToSlot(slot); - } - - /** - * Get the cluster clock. - * @returns the clock object. - */ - getClock(): Clock { - return this.inner.getClock(); - } - - /** - * Overwrite the clock sysvar. - * @param clock - The clock object. - */ - setClock(clock: Clock) { - this.inner.setClock(clock); - } - - /** - * Get the EpochRewards sysvar. - * @returns the EpochRewards object. - */ - getEpochRewards(): EpochRewards { - return this.inner.getEpochRewards(); - } - - /** - * Overwrite the EpochRewards sysvar. - * @param rewards - The EpochRewards object. - */ - setEpochRewards(rewards: EpochRewards) { - this.inner.setEpochRewards(rewards); - } - - /** - * Get the EpochSchedule sysvar. - * @returns the EpochSchedule object. - */ - getEpochSchedule(): EpochSchedule { - return this.inner.getEpochSchedule(); - } - - /** - * Overwrite the EpochSchedule sysvar. - * @param schedule - The EpochSchedule object. - */ - setEpochSchedule(schedule: EpochSchedule) { - this.inner.setEpochSchedule(schedule); - } - - /** - * Get the last restart slot sysvar. - * @returns the last restart slot. - */ - getLastRestartSlot(): bigint { - return this.inner.getLastRestartSlot(); - } - - /** - * Overwrite the last restart slot sysvar. - * @param slot - The last restart slot. - */ - setLastRestartSlot(slot: bigint) { - this.inner.setLastRestartSlot(slot); - } - - /** - * Get the cluster rent. - * @returns The rent object. - */ - getRent(): Rent { - return this.inner.getRent(); - } - - /** - * Overwrite the rent sysvar. - * @param rent - The new rent object. - */ - setRent(rent: Rent) { - this.inner.setRent(rent); - } - - /** - * Get the SlotHashes sysvar. - * @returns The SlotHash array. - */ - getSlotHashes(): SlotHash[] { - return this.inner.getSlotHashes(); - } - - /** - * Overwrite the SlotHashes sysvar. - * @param hashes - The SlotHash array. - */ - setSlotHashes(hashes: SlotHash[]) { - this.inner.setSlotHashes(hashes); - } - - /** - * Get the SlotHistory sysvar. - * @returns The SlotHistory object. - */ - getSlotHistory(): SlotHistory { - return this.inner.getSlotHistory(); - } - - /** - * Overwrite the SlotHistory sysvar. - * @param history - The SlotHistory object - */ - setSlotHistory(history: SlotHistory) { - this.inner.setSlotHistory(history); - } - - /** - * Get the StakeHistory sysvar. - * @returns The StakeHistory object. - */ - getStakeHistory(): StakeHistory { - return this.inner.getStakeHistory(); - } - - /** - * Overwrite the StakeHistory sysvar. - * @param history - The StakeHistory object - */ - setStakeHistory(history: StakeHistory) { - this.inner.setStakeHistory(history); - } + /** Create a new LiteSVM instance with standard functionality enabled */ + constructor() { + const inner = new LiteSVMInner(); + this.inner = inner; + } + private inner: LiteSVMInner; + + /** Create a new LiteSVM instance with minimal functionality enabled */ + static default(): LiteSVM { + const svm = new LiteSVM(); + const inner = LiteSVMInner.default(); + svm.inner = inner; + return svm; + } + + /** + * Set the compute budget + * @param budget - The new compute budget + * @returns The modified LiteSVM instance + */ + withComputeBudget(budget: ComputeBudget): LiteSVM { + this.inner.setComputeBudget(budget); + return this; + } + + /** + * Enable or disable sigverify + * @param sigverify - if false, transaction signatures will not be checked. + * @returns The modified LiteSVM instance + */ + withSigverify(sigverify: boolean): LiteSVM { + this.inner.setSigverify(sigverify); + return this; + } + + /** + * Enables or disables transaction blockhash checking. + * @param check - If false, the blockhash check will be skipped + * @returns The modified LiteSVM instance + */ + withBlockhashCheck(check: boolean): LiteSVM { + this.inner.setBlockhashCheck(check); + return this; + } + + /** + * Sets up the standard sysvars. + * @returns The modified LiteSVM instance + */ + withSysvars(): LiteSVM { + this.inner.setSysvars(); + return this; + } + + /** + * Set the FeatureSet used by the VM instance. + * @param featureSet The FeatureSet to use. + * @returns The modified LiteSVM instance + */ + withFeatureSet(featureSet: FeatureSet): LiteSVM { + this.inner.setFeatureSet(featureSet); + return this; + } + + /** + * Adds the standard builtin programs. Use `withFeatureSet` beforehand to change change what builtins are added. + * @returns The modified LiteSVM instance + */ + withBuiltins(): LiteSVM { + this.inner.setBuiltins(); + return this; + } + + /** + * Changes the initial lamports in LiteSVM's airdrop account. + * @param lamports - The number of lamports to set in the airdrop account + * @returns The modified LiteSVM instance + */ + withLamports(lamports: bigint): LiteSVM { + this.inner.setLamports(lamports); + return this; + } + + /** + * Adds the standard SPL programs. + * @returns The modified LiteSVM instance + */ + withSplPrograms(): LiteSVM { + this.inner.setSplPrograms(); + return this; + } + + /** + * Changes the capacity of the transaction history. + * @param capacity - How many transactions to store in history. + * Set this to 0 to disable transaction history and allow duplicate transactions. + * @returns The modified LiteSVM instance + */ + withTransactionHistory(capacity: bigint): LiteSVM { + this.inner.setTransactionHistory(capacity); + return this; + } + + /** + * Set a limit for transaction logs, beyond which they will be truncated. + * @param limit - The limit in bytes. If null, no limit is enforced. + * @returns The modified LiteSVM instance + */ + withLogBytesLimit(limit?: bigint): LiteSVM { + this.inner.setLogBytesLimit(limit); + return this; + } + + /** + * Adds the standard precompiles. Use `withFeatureSet` beforehand to change change what builtins are added. + * @returns The modified LiteSVM instance + */ + withPrecompiles(): LiteSVM { + this.inner.setPrecompiles(); + return this; + } + + /** + * Calculates the minimum balance required to make an account with specified data length rent exempt. + * @param dataLen - The number of bytes in the account. + * @returns The required balance in lamports + */ + minimumBalanceForRentExemption(dataLen: bigint): bigint { + return this.inner.minimumBalanceForRentExemption(dataLen); + } + + /** + * Return the account at the given address. + * If the account is not found, None is returned. + * @param address - The account address to look up. + * @returns The account object, if the account exists. + */ + getAccount(address: PublicKey): AccountInfoBytes | null { + const inner = this.inner.getAccount(address.toBytes()); + return inner === null ? null : toAccountInfo(inner); + } + + /** + * Create or overwrite an account, subverting normal runtime checks. + * + * This method exists to make it easier to set up artificial situations + * that would be difficult to replicate by sending individual transactions. + * Beware that it can be used to create states that would not be reachable + * by sending transactions! + * + * @param address - The address to write to. + * @param account - The account object to write. + */ + setAccount(address: PublicKey, account: AccountInfoBytes) { + this.inner.setAccount(address.toBytes(), fromAccountInfo(account)); + } + + /** + * Gets the balance of the provided account address. + * @param address - The account address. + * @returns The account's balance in lamports. + */ + getBalance(address: PublicKey): bigint | null { + return this.inner.getBalance(address.toBytes()); + } + + /** + * Gets the latest blockhash. + * Since LiteSVM doesn't have blocks, this is an arbitrary value controlled by LiteSVM + * @returns The designated latest blockhash. + */ + latestBlockhash(): string { + return this.inner.latestBlockhash(); + } + + /** + * Gets a transaction from the transaction history. + * @param signature - The transaction signature bytes + * @returns The transaction, if it is found in the history. + */ + getTransaction( + signature: Uint8Array + ): TransactionMetadata | FailedTransactionMetadata | null { + return this.inner.getTransaction(signature); + } + + /** + * Airdrops the lamport amount specified to the given address. + * @param address The airdrop recipient. + * @param lamports - The amount to airdrop. + * @returns The transaction result. + */ + airdrop( + address: PublicKey, + lamports: bigint + ): TransactionMetadata | FailedTransactionMetadata | null { + return this.inner.airdrop(address.toBytes(), lamports); + } + + /** + * Adds an SBF program to the test environment from the file specified. + * @param programId - The program ID. + * @param path - The path to the .so file. + */ + addProgramFromFile(programId: PublicKey, path: string) { + return this.inner.addProgramFromFile(programId.toBytes(), path); + } + + /** + * Adds an SBF program to the test environment from the file specified. + * @param programId - The program ID. + * @param path - The path to the .so file. + */ + withCoverage(programName: string, programId: Uint8Array, path: string) { + return this.inner.withCoverage(programName, programId, path); + } + + /** + * Adds am SBF program to the test environment. + * @param programId - The program ID. + * @param programBytes - The raw bytes of the compiled program. + */ + addProgram(programId: PublicKey, programBytes: Uint8Array) { + return this.inner.addProgram(programId.toBytes(), programBytes); + } + + /** + * Processes a transaction and returns the result. + * @param tx - The transaction to send. + * @returns TransactionMetadata if the transaction succeeds, else FailedTransactionMetadata + */ + sendTransaction( + tx: Transaction | VersionedTransaction + ): TransactionMetadata | FailedTransactionMetadata { + const internal = this.inner; + const serialized = tx.serialize({ + requireAllSignatures: true, + verifySignatures: internal.getSigverify(), + }); + + if (tx instanceof Transaction) { + return internal.sendLegacyTransaction(serialized); + } else { + return internal.sendVersionedTransaction(serialized); + } + } + + /** + * Simulates a transaction + * @param tx The transaction to simulate + * @returns SimulatedTransactionInfo if simulation succeeds, else FailedTransactionMetadata + */ + simulateTransaction( + tx: Transaction | VersionedTransaction + ): FailedTransactionMetadata | SimulatedTransactionInfo { + const internal = this.inner; + const serialized = tx.serialize({ + requireAllSignatures: true, + verifySignatures: internal.getSigverify(), + }); + const inner = + tx instanceof Transaction + ? internal.simulateLegacyTransaction(serialized) + : internal.simulateVersionedTransaction(serialized); + return inner instanceof FailedTransactionMetadata + ? inner + : new SimulatedTransactionInfo(inner); + } + + /** + * Expires the current blockhash. + * The return value of `latestBlockhash()` will be different after calling this. + */ + expireBlockhash() { + this.inner.expireBlockhash(); + } + + /** + * Warps the clock to the specified slot. This is a convenience wrapper + * around `setClock()`. + * @param slot - The new slot. + */ + warpToSlot(slot: bigint) { + this.inner.warpToSlot(slot); + } + + /** + * Get the cluster clock. + * @returns the clock object. + */ + getClock(): Clock { + return this.inner.getClock(); + } + + /** + * Overwrite the clock sysvar. + * @param clock - The clock object. + */ + setClock(clock: Clock) { + this.inner.setClock(clock); + } + + /** + * Get the EpochRewards sysvar. + * @returns the EpochRewards object. + */ + getEpochRewards(): EpochRewards { + return this.inner.getEpochRewards(); + } + + /** + * Overwrite the EpochRewards sysvar. + * @param rewards - The EpochRewards object. + */ + setEpochRewards(rewards: EpochRewards) { + this.inner.setEpochRewards(rewards); + } + + /** + * Get the EpochSchedule sysvar. + * @returns the EpochSchedule object. + */ + getEpochSchedule(): EpochSchedule { + return this.inner.getEpochSchedule(); + } + + /** + * Overwrite the EpochSchedule sysvar. + * @param schedule - The EpochSchedule object. + */ + setEpochSchedule(schedule: EpochSchedule) { + this.inner.setEpochSchedule(schedule); + } + + /** + * Get the last restart slot sysvar. + * @returns the last restart slot. + */ + getLastRestartSlot(): bigint { + return this.inner.getLastRestartSlot(); + } + + /** + * Overwrite the last restart slot sysvar. + * @param slot - The last restart slot. + */ + setLastRestartSlot(slot: bigint) { + this.inner.setLastRestartSlot(slot); + } + + /** + * Get the cluster rent. + * @returns The rent object. + */ + getRent(): Rent { + return this.inner.getRent(); + } + + /** + * Overwrite the rent sysvar. + * @param rent - The new rent object. + */ + setRent(rent: Rent) { + this.inner.setRent(rent); + } + + /** + * Get the SlotHashes sysvar. + * @returns The SlotHash array. + */ + getSlotHashes(): SlotHash[] { + return this.inner.getSlotHashes(); + } + + /** + * Overwrite the SlotHashes sysvar. + * @param hashes - The SlotHash array. + */ + setSlotHashes(hashes: SlotHash[]) { + this.inner.setSlotHashes(hashes); + } + + /** + * Get the SlotHistory sysvar. + * @returns The SlotHistory object. + */ + getSlotHistory(): SlotHistory { + return this.inner.getSlotHistory(); + } + + /** + * Overwrite the SlotHistory sysvar. + * @param history - The SlotHistory object + */ + setSlotHistory(history: SlotHistory) { + this.inner.setSlotHistory(history); + } + + /** + * Get the StakeHistory sysvar. + * @returns The StakeHistory object. + */ + getStakeHistory(): StakeHistory { + return this.inner.getStakeHistory(); + } + + /** + * Overwrite the StakeHistory sysvar. + * @param history - The StakeHistory object + */ + setStakeHistory(history: StakeHistory) { + this.inner.setStakeHistory(history); + } } diff --git a/crates/node-litesvm/litesvm/internal.d.ts b/crates/node-litesvm/litesvm/internal.d.ts index 76b5fec0..261f5ddc 100644 --- a/crates/node-litesvm/litesvm/internal.d.ts +++ b/crates/node-litesvm/litesvm/internal.d.ts @@ -556,6 +556,7 @@ export declare class LiteSvm { airdrop(pubkey: Uint8Array, lamports: bigint): TransactionMetadata | FailedTransactionMetadata | null /** Adds am SBF program to the test environment from the file specified. */ addProgramFromFile(programId: Uint8Array, path: string): void + withCoverage(programName: string, programId: Uint8Array, path: string): void /** Adds am SBF program to the test environment. */ addProgram(programId: Uint8Array, programBytes: Uint8Array): void sendLegacyTransaction(txBytes: Uint8Array): TransactionMetadata | FailedTransactionMetadata diff --git a/crates/node-litesvm/src/lib.rs b/crates/node-litesvm/src/lib.rs index 87556fc5..53f64964 100644 --- a/crates/node-litesvm/src/lib.rs +++ b/crates/node-litesvm/src/lib.rs @@ -22,13 +22,14 @@ use { SimulatedTransactionInfo as SimulatedTransactionInfoOriginal, TransactionResult as TransactionResultOriginal, }, - LiteSVM as LiteSVMOriginal, + LiteSVM as LiteSVMOriginal, NativeProgram, }, napi::bindgen_prelude::*, solana_clock::Clock as ClockOriginal, solana_epoch_rewards::EpochRewards as EpochRewardsOriginal, solana_epoch_schedule::EpochSchedule as EpochScheduleOriginal, solana_last_restart_slot::LastRestartSlot, + solana_pubkey::Pubkey, solana_rent::Rent as RentOriginal, solana_signature::Signature, solana_slot_hashes::SlotHashes, @@ -234,6 +235,29 @@ impl LiteSvm { }) } + #[napi] + pub fn with_coverage( + &mut self, + program_name: String, + program_id: Uint8Array, + path: String, + ) -> Result<()> { + let program_pubkey: Pubkey = Pubkey::new_from_array( + program_id + .to_vec() + .try_into() + .map_err(|_| Error::new(Status::InvalidArg, "Program ID must be 32 bytes"))?, + ); + let program: NativeProgram = (program_pubkey, program_name, path); + self.0.with_coverage(vec![program]).map_err(|e| { + Error::new( + Status::GenericFailure, + format!("Failed to set programs for coverage: {e}"), + ) + })?; + Ok(()) + } + #[napi] /// Adds am SBF program to the test environment. pub fn add_program(&mut self, program_id: Uint8Array, program_bytes: &[u8]) { From b0b9d3046b8fa6fa0577a75103f8d5702a441f6d Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Wed, 25 Jun 2025 17:30:10 +0300 Subject: [PATCH 13/86] go on with refactoring stubs --- Cargo.toml | 1 + crates/litesvm/Cargo.toml | 2 +- crates/litesvm/src/pt.rs | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7aad185a..13ab56df 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -90,6 +90,7 @@ spl-token-2022 = "7.0.0" test-log = "0.2" thiserror = "2.0" tokio = "1.35" +sol-stubs = { path = "/Users/boris/projects/solana/sol-stubs" } [profile.bench] debug = true diff --git a/crates/litesvm/Cargo.toml b/crates/litesvm/Cargo.toml index 9279f897..e1a66d0f 100644 --- a/crates/litesvm/Cargo.toml +++ b/crates/litesvm/Cargo.toml @@ -73,7 +73,7 @@ thiserror.workspace = true # solts-rs = { path = "/Users/boris/projects/solana/solts-rs" } libloading = "0.8.8" lazy_static = "1.5.0" -sol-stubs = { path = "/Users/boris/projects/solana/sol-stubs" } +sol-stubs.workspace = true solana-program-test.workspace = true tokio.workspace = true diff --git a/crates/litesvm/src/pt.rs b/crates/litesvm/src/pt.rs index 799535d1..7e926387 100644 --- a/crates/litesvm/src/pt.rs +++ b/crates/litesvm/src/pt.rs @@ -57,11 +57,11 @@ impl Pt { pub fn send_transaction( &self, - mut invoke_context: &mut InvokeContext, + mut _invoke_context: &mut InvokeContext, tx: VersionedTransaction, accounts_db: AccountsDb, ) -> PtError<()> { - set_invoke_context(&mut invoke_context); + // set_invoke_context(&mut invoke_context); let _: PtError<()> = self.rt.block_on(async { for (account_address, account) in &accounts_db.inner { // println!("Account: {:#?} data: {:#?}", account_address, account); From 919071d8986ea7c22b588f27581d28519743c88d Mon Sep 17 00:00:00 2001 From: vlady-kotsev Date: Thu, 26 Jun 2025 12:57:49 +0300 Subject: [PATCH 14/86] poc: add third party programs and sysvars sync --- crates/lite-coverage/src/lite_coverage.rs | 10 ++++- crates/lite-coverage/src/types.rs | 1 + crates/litesvm/src/lib.rs | 42 ++++++++++++-------- crates/node-litesvm/litesvm/index.ts | 9 +++-- crates/node-litesvm/litesvm/internal.d.ts | 2 +- crates/node-litesvm/src/lib.rs | 48 +++++++++++++++++------ 6 files changed, 79 insertions(+), 33 deletions(-) diff --git a/crates/lite-coverage/src/lite_coverage.rs b/crates/lite-coverage/src/lite_coverage.rs index 2b5e3818..034ee246 100644 --- a/crates/lite-coverage/src/lite_coverage.rs +++ b/crates/lite-coverage/src/lite_coverage.rs @@ -1,6 +1,7 @@ use crate::{ loader::{entrypoint, Loader}, types::{LiteCoverageError, NativeProgram}, + AdditionalProgram, }; use { solana_account::AccountSharedData, @@ -20,10 +21,17 @@ pub struct LiteCoverage { } impl LiteCoverage { - pub fn new(programs: Vec) -> LiteCoverageError { + pub fn new( + programs: Vec, + additional_programs: Vec, + ) -> LiteCoverageError { let static_programs = Box::leak(Box::new(programs.clone())); let mut program_test = ProgramTest::default(); program_test.prefer_bpf(false); + for (pubkey, name) in additional_programs.into_iter() { + let name = Box::leak(Box::new(name)); + program_test.add_upgradeable_program_to_genesis(name, &pubkey); + } let mut loader = Loader::new(); for (program_id, program_name, so_path) in static_programs.iter() { diff --git a/crates/lite-coverage/src/types.rs b/crates/lite-coverage/src/types.rs index d0877560..98ef5710 100644 --- a/crates/lite-coverage/src/types.rs +++ b/crates/lite-coverage/src/types.rs @@ -5,3 +5,4 @@ pub type LiteCoverageError = Result>; pub type ProgramName = String; pub type Path = String; pub type NativeProgram = (Pubkey, ProgramName, Path); +pub type AdditionalProgram = (Pubkey, ProgramName); diff --git a/crates/litesvm/src/lib.rs b/crates/litesvm/src/lib.rs index f08de515..ebfeb185 100644 --- a/crates/litesvm/src/lib.rs +++ b/crates/litesvm/src/lib.rs @@ -253,6 +253,7 @@ much easier. */ +use lite_coverage::AdditionalProgram; pub use lite_coverage::{LiteCoverage, LiteCoverageError, NativeProgram}; #[cfg(feature = "nodejs-internal")] use qualifier_attr::qualifiers; @@ -260,7 +261,6 @@ use qualifier_attr::qualifiers; use solana_sysvar::{ fees::Fees, recent_blockhashes::IterItem, recent_blockhashes::RecentBlockhashes, }; -// use sol_coverage::loader::Loader; use { crate::{ @@ -945,7 +945,7 @@ impl LiteSVM { let mut context = self.create_transaction_context(compute_budget, accounts.clone()); // TODO: Refactor - let tx_copy = tx.clone().to_versioned_transaction(); + let tx_copy = tx.clone(); let mut tx_result: Result<(), TransactionError> = process_message( tx.message(), @@ -974,20 +974,11 @@ impl LiteSVM { if let Some(lite_coverage) = &self.lite_coverage { // Sync Sysvars self.sync_sysvars_with_lite_coverage(); + // Sync Accounts + let tx_accounts = self.sync_accounts_with_lite_coverage(&tx_copy); - let account_keys = tx.message().static_account_keys(); - let mut tx_accounts: Vec<(Pubkey, AccountSharedData)> = - Vec::with_capacity(account_keys.len()); - for account_key in account_keys { - let account = self.get_account(account_key); - if let Some(account) = account { - if !account.executable() { - tx_accounts.push((*account_key, account.into())); - } - } - } - - let _ = lite_coverage.send_transaction(tx_copy, &tx_accounts); + let _ = lite_coverage + .send_transaction(tx_copy.to_versioned_transaction(), &tx_accounts); } if let Err(err) = self.check_accounts_rent(tx, &context) { @@ -1088,6 +1079,23 @@ impl LiteSVM { .set_sysvar(&last_restart_slot_sysvar); } + pub fn sync_accounts_with_lite_coverage( + &self, + tx: &SanitizedTransaction, + ) -> Vec<(Pubkey, AccountSharedData)> { + let account_keys = tx.message().static_account_keys(); + let mut tx_accounts: Vec<(Pubkey, AccountSharedData)> = + Vec::with_capacity(account_keys.len()); + for account_key in account_keys { + let account = self.get_account(account_key); + if let Some(account) = account { + if !account.executable() { + tx_accounts.push((*account_key, account.into())); + } + } + } + tx_accounts + } fn check_accounts_rent( &self, tx: &SanitizedTransaction, @@ -1273,8 +1281,8 @@ impl LiteSVM { }) } - pub fn with_coverage(&mut self, programs: Vec) -> LiteCoverageError<()> { - self.lite_coverage = Some(LiteCoverage::new(programs)?); + pub fn with_coverage(&mut self, programs: Vec, additional_programs: Vec) -> LiteCoverageError<()> { + self.lite_coverage = Some(LiteCoverage::new(programs, additional_programs)?); Ok(()) } diff --git a/crates/node-litesvm/litesvm/index.ts b/crates/node-litesvm/litesvm/index.ts index 8856b926..6cc0cd23 100644 --- a/crates/node-litesvm/litesvm/index.ts +++ b/crates/node-litesvm/litesvm/index.ts @@ -299,12 +299,15 @@ export class LiteSVM { } /** - * Adds an SBF program to the test environment from the file specified. + * TODO add some good description * @param programId - The program ID. * @param path - The path to the .so file. */ - withCoverage(programName: string, programId: Uint8Array, path: string) { - return this.inner.withCoverage(programName, programId, path); + withCoverage( + programs: Array<[string, Uint8Array, string]>, + additionalPrograms: Array<[string, Uint8Array]> + ) { + return this.inner.withCoverage(programs, additionalPrograms); } /** diff --git a/crates/node-litesvm/litesvm/internal.d.ts b/crates/node-litesvm/litesvm/internal.d.ts index 261f5ddc..5f6eed7c 100644 --- a/crates/node-litesvm/litesvm/internal.d.ts +++ b/crates/node-litesvm/litesvm/internal.d.ts @@ -556,7 +556,7 @@ export declare class LiteSvm { airdrop(pubkey: Uint8Array, lamports: bigint): TransactionMetadata | FailedTransactionMetadata | null /** Adds am SBF program to the test environment from the file specified. */ addProgramFromFile(programId: Uint8Array, path: string): void - withCoverage(programName: string, programId: Uint8Array, path: string): void + withCoverage(programs: Array<[string, Uint8Array, string]>, additionalPrograms: Array<[string, Uint8Array]>): void /** Adds am SBF program to the test environment. */ addProgram(programId: Uint8Array, programBytes: Uint8Array): void sendLegacyTransaction(txBytes: Uint8Array): TransactionMetadata | FailedTransactionMetadata diff --git a/crates/node-litesvm/src/lib.rs b/crates/node-litesvm/src/lib.rs index 53f64964..683feeaa 100644 --- a/crates/node-litesvm/src/lib.rs +++ b/crates/node-litesvm/src/lib.rs @@ -238,18 +238,44 @@ impl LiteSvm { #[napi] pub fn with_coverage( &mut self, - program_name: String, - program_id: Uint8Array, - path: String, + programs: Vec<(String, Uint8Array, String)>, + additional_programs: Vec<(String, Uint8Array)>, ) -> Result<()> { - let program_pubkey: Pubkey = Pubkey::new_from_array( - program_id - .to_vec() - .try_into() - .map_err(|_| Error::new(Status::InvalidArg, "Program ID must be 32 bytes"))?, - ); - let program: NativeProgram = (program_pubkey, program_name, path); - self.0.with_coverage(vec![program]).map_err(|e| { + let programs: Vec<(Pubkey, String, String)> = programs + .iter() + .map(|p| { + ( + Pubkey::new_from_array( + p.1.to_vec() + .try_into() + .map_err(|_| { + Error::new(Status::InvalidArg, "Program ID must be 32 bytes") + }) + .unwrap(), + ), + p.0.clone(), + p.2.clone(), + ) + }) + .collect(); + let additional_programs: Vec<(Pubkey, String)> = additional_programs + .iter() + .map(|ap| { + ( + Pubkey::new_from_array( + ap.1.to_vec() + .try_into() + .map_err(|_| { + Error::new(Status::InvalidArg, "Program ID must be 32 bytes") + }) + .unwrap(), + ), + ap.0.clone(), + ) + }) + .collect(); + + self.0.with_coverage(programs, additional_programs).map_err(|e| { Error::new( Status::GenericFailure, format!("Failed to set programs for coverage: {e}"), From 0cda9784926af162ee9d9ae750b5cb72ceaf7a4d Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Fri, 27 Jun 2025 09:41:23 +0300 Subject: [PATCH 15/86] 0) Take into account if there's lite-coverage or not when syncing 1) Refrain from unwraps() 2) Revise pubs 3) fmt --- crates/litesvm/src/lib.rs | 188 ++++++++++++++++----------------- crates/node-litesvm/src/lib.rs | 14 +-- 2 files changed, 101 insertions(+), 101 deletions(-) diff --git a/crates/litesvm/src/lib.rs b/crates/litesvm/src/lib.rs index ebfeb185..a10e1b9b 100644 --- a/crates/litesvm/src/lib.rs +++ b/crates/litesvm/src/lib.rs @@ -944,8 +944,13 @@ impl LiteSVM { Ok(program_indices) => { let mut context = self.create_transaction_context(compute_budget, accounts.clone()); - // TODO: Refactor - let tx_copy = tx.clone(); + let tx_lite_coverage = || { + if self.lite_coverage.is_some() { + Some(tx.clone()) + } else { + None + } + }; let mut tx_result: Result<(), TransactionError> = process_message( tx.message(), @@ -971,15 +976,9 @@ impl LiteSVM { println!("ORIGINAL TX DONE"); - if let Some(lite_coverage) = &self.lite_coverage { - // Sync Sysvars - self.sync_sysvars_with_lite_coverage(); - // Sync Accounts - let tx_accounts = self.sync_accounts_with_lite_coverage(&tx_copy); - - let _ = lite_coverage - .send_transaction(tx_copy.to_versioned_transaction(), &tx_accounts); - } + tx_lite_coverage().map(|tx_copy| { + self.send_transaction_lite_coverage(tx_copy); + }); if let Err(err) = self.check_accounts_rent(tx, &context) { tx_result = Err(err); @@ -997,89 +996,84 @@ impl LiteSVM { } } - pub fn sync_sysvars_with_lite_coverage(&self) { - let clock_sysvar = self.get_sysvar::(); - self.lite_coverage - .as_ref() - .unwrap() - .pt_context - .borrow_mut() - .set_sysvar(&clock_sysvar); - - let epoch_schedule_sysvar = self.get_sysvar::(); - self.lite_coverage - .as_ref() - .unwrap() - .pt_context - .borrow_mut() - .set_sysvar(&epoch_schedule_sysvar); - - let fees_sysvar = self.get_sysvar::(); - self.lite_coverage - .as_ref() - .unwrap() - .pt_context - .borrow_mut() - .set_sysvar(&fees_sysvar); - - let rent_sysvar = self.get_sysvar::(); - self.lite_coverage - .as_ref() - .unwrap() - .pt_context - .borrow_mut() - .set_sysvar(&rent_sysvar); - - let epoch_rewards_sysvar = self.get_sysvar::(); - self.lite_coverage - .as_ref() - .unwrap() - .pt_context - .borrow_mut() - .set_sysvar(&epoch_rewards_sysvar); - - let recent_blockhashes_sysvar = self.get_sysvar::(); - self.lite_coverage - .as_ref() - .unwrap() - .pt_context - .borrow_mut() - .set_sysvar(&recent_blockhashes_sysvar); - - let slot_hashed_sysvar = self.get_sysvar::(); - self.lite_coverage - .as_ref() - .unwrap() - .pt_context - .borrow_mut() - .set_sysvar(&slot_hashed_sysvar); - - let slot_history_sysvar = self.get_sysvar::(); - self.lite_coverage - .as_ref() - .unwrap() - .pt_context - .borrow_mut() - .set_sysvar(&slot_history_sysvar); - - let stake_history_sysvar = self.get_sysvar::(); - self.lite_coverage - .as_ref() - .unwrap() - .pt_context - .borrow_mut() - .set_sysvar(&stake_history_sysvar); - - let last_restart_slot_sysvar = self.get_sysvar::(); - self.lite_coverage - .as_ref() - .unwrap() - .pt_context - .borrow_mut() - .set_sysvar(&last_restart_slot_sysvar); - } - - pub fn sync_accounts_with_lite_coverage( + fn send_transaction_lite_coverage(&self, tx: SanitizedTransaction) { + self.lite_coverage.as_ref().map(|lite_coverage| { + // Sync Sysvars + self.sync_sysvars_with_lite_coverage(); + // Sync Accounts + let tx_accounts = self.collect_accounts_for_lite_coverage(&tx); + + let _ = lite_coverage.send_transaction(tx.to_versioned_transaction(), &tx_accounts); + }); + } + + fn sync_sysvars_with_lite_coverage(&self) { + self.lite_coverage.as_ref().map(|lite_coverage| { + let clock_sysvar = self.get_sysvar::(); + lite_coverage + .pt_context + .borrow_mut() + .set_sysvar(&clock_sysvar); + + let epoch_schedule_sysvar = self.get_sysvar::(); + lite_coverage + .pt_context + .borrow_mut() + .set_sysvar(&epoch_schedule_sysvar); + + #[allow(deprecated)] + let fees_sysvar = self.get_sysvar::(); + lite_coverage + .pt_context + .borrow_mut() + .set_sysvar(&fees_sysvar); + + let rent_sysvar = self.get_sysvar::(); + lite_coverage + .pt_context + .borrow_mut() + .set_sysvar(&rent_sysvar); + + let epoch_rewards_sysvar = self.get_sysvar::(); + lite_coverage + .pt_context + .borrow_mut() + .set_sysvar(&epoch_rewards_sysvar); + + #[allow(deprecated)] + let recent_blockhashes_sysvar = self.get_sysvar::(); + lite_coverage + .pt_context + .borrow_mut() + .set_sysvar(&recent_blockhashes_sysvar); + + let slot_hashed_sysvar = self.get_sysvar::(); + lite_coverage + .pt_context + .borrow_mut() + .set_sysvar(&slot_hashed_sysvar); + + let slot_history_sysvar = self.get_sysvar::(); + lite_coverage + .pt_context + .borrow_mut() + .set_sysvar(&slot_history_sysvar); + + let stake_history_sysvar = self.get_sysvar::(); + lite_coverage + .pt_context + .borrow_mut() + .set_sysvar(&stake_history_sysvar); + + let last_restart_slot_sysvar = self.get_sysvar::(); + lite_coverage + .pt_context + .borrow_mut() + .set_sysvar(&last_restart_slot_sysvar); + }); + } + + fn collect_accounts_for_lite_coverage( &self, tx: &SanitizedTransaction, ) -> Vec<(Pubkey, AccountSharedData)> { @@ -1281,7 +1275,11 @@ impl LiteSVM { }) } - pub fn with_coverage(&mut self, programs: Vec, additional_programs: Vec) -> LiteCoverageError<()> { + pub fn with_coverage( + &mut self, + programs: Vec, + additional_programs: Vec, + ) -> LiteCoverageError<()> { self.lite_coverage = Some(LiteCoverage::new(programs, additional_programs)?); Ok(()) } diff --git a/crates/node-litesvm/src/lib.rs b/crates/node-litesvm/src/lib.rs index 683feeaa..90086d87 100644 --- a/crates/node-litesvm/src/lib.rs +++ b/crates/node-litesvm/src/lib.rs @@ -275,12 +275,14 @@ impl LiteSvm { }) .collect(); - self.0.with_coverage(programs, additional_programs).map_err(|e| { - Error::new( - Status::GenericFailure, - format!("Failed to set programs for coverage: {e}"), - ) - })?; + self.0 + .with_coverage(programs, additional_programs) + .map_err(|e| { + Error::new( + Status::GenericFailure, + format!("Failed to set programs for coverage: {e}"), + ) + })?; Ok(()) } From 4b50f01a0e692890dad6af2ea64e8ced41cad692 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Fri, 27 Jun 2025 10:27:24 +0300 Subject: [PATCH 16/86] relocate files so that the merge with poc is less painful --- crates/{litesvm/src/pt.rs => lite-coverage/src/lite_coverage.rs} | 0 crates/{litesvm => lite-coverage}/src/loader.rs | 0 crates/{litesvm => lite-coverage}/src/stubs.rs | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename crates/{litesvm/src/pt.rs => lite-coverage/src/lite_coverage.rs} (100%) rename crates/{litesvm => lite-coverage}/src/loader.rs (100%) rename crates/{litesvm => lite-coverage}/src/stubs.rs (100%) diff --git a/crates/litesvm/src/pt.rs b/crates/lite-coverage/src/lite_coverage.rs similarity index 100% rename from crates/litesvm/src/pt.rs rename to crates/lite-coverage/src/lite_coverage.rs diff --git a/crates/litesvm/src/loader.rs b/crates/lite-coverage/src/loader.rs similarity index 100% rename from crates/litesvm/src/loader.rs rename to crates/lite-coverage/src/loader.rs diff --git a/crates/litesvm/src/stubs.rs b/crates/lite-coverage/src/stubs.rs similarity index 100% rename from crates/litesvm/src/stubs.rs rename to crates/lite-coverage/src/stubs.rs From fffa97b6c0660e6059d632915eed6fbcd8366a72 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Fri, 27 Jun 2025 10:40:02 +0300 Subject: [PATCH 17/86] revert stuff done in test_programs --- crates/litesvm/test_programs/Cargo.lock | 924 +----------------- crates/litesvm/test_programs/Cargo.toml | 1 - .../test_programs/clock-example/src/lib.rs | 7 +- .../litesvm/test_programs/counter/Cargo.toml | 6 - .../litesvm/test_programs/counter/src/lib.rs | 13 - .../litesvm/test_programs/failure/src/lib.rs | 3 +- 6 files changed, 28 insertions(+), 926 deletions(-) diff --git a/crates/litesvm/test_programs/Cargo.lock b/crates/litesvm/test_programs/Cargo.lock index 31b2d7e1..86ec2042 100644 --- a/crates/litesvm/test_programs/Cargo.lock +++ b/crates/litesvm/test_programs/Cargo.lock @@ -8,35 +8,17 @@ version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ - "getrandom 0.2.15", + "getrandom", "once_cell", "version_check", ] -[[package]] -name = "arrayref" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" - -[[package]] -name = "arrayvec" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" - [[package]] name = "autocfg" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" -[[package]] -name = "base64" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" - [[package]] name = "base64" version = "0.22.1" @@ -58,29 +40,6 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" -[[package]] -name = "blake3" -version = "1.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0" -dependencies = [ - "arrayref", - "arrayvec", - "cc", - "cfg-if", - "constant_time_eq", - "digest 0.10.7", -] - -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "generic-array", -] - [[package]] name = "block-buffer" version = "0.10.4" @@ -100,16 +59,6 @@ dependencies = [ "hashbrown 0.11.2", ] -[[package]] -name = "borsh" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "115e54d64eb62cdebad391c19efc9dce4981c690c85a33a12199d99bb9546fee" -dependencies = [ - "borsh-derive 0.10.4", - "hashbrown 0.11.2", -] - [[package]] name = "borsh" version = "1.5.5" @@ -126,21 +75,8 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6441c552f230375d18e3cc377677914d2ca2b0d36e52129fe15450a2dce46775" dependencies = [ - "borsh-derive-internal 0.9.3", - "borsh-schema-derive-internal 0.9.3", - "proc-macro-crate 0.1.5", - "proc-macro2", - "syn 1.0.109", -] - -[[package]] -name = "borsh-derive" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "831213f80d9423998dd696e2c5345aba6be7a0bd8cd19e31c5243e13df1cef89" -dependencies = [ - "borsh-derive-internal 0.10.4", - "borsh-schema-derive-internal 0.10.4", + "borsh-derive-internal", + "borsh-schema-derive-internal", "proc-macro-crate 0.1.5", "proc-macro2", "syn 1.0.109", @@ -170,17 +106,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "borsh-derive-internal" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65d6ba50644c98714aa2a70d13d7df3cd75cd2b523a2b452bf010443800976b3" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "borsh-schema-derive-internal" version = "0.9.3" @@ -192,17 +117,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "borsh-schema-derive-internal" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "276691d96f063427be83e6692b86148e488ebba9f48f77788724ca027ba3b6d4" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "bs58" version = "0.5.1" @@ -245,15 +159,6 @@ dependencies = [ "syn 2.0.98", ] -[[package]] -name = "cc" -version = "1.2.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d487aa071b5f64da6f19a3e848e3578944b726ee5a4854b82172f02aa876bfdc" -dependencies = [ - "shlex", -] - [[package]] name = "cfg-if" version = "1.0.0" @@ -266,46 +171,16 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" -[[package]] -name = "console_error_panic_hook" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" -dependencies = [ - "cfg-if", - "wasm-bindgen", -] - -[[package]] -name = "console_log" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89f72f65e8501878b8a004d5a1afb780987e2ce2b4532c562e367a72c57499f" -dependencies = [ - "log", - "web-sys", -] - -[[package]] -name = "constant_time_eq" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" - [[package]] name = "counter" version = "0.1.0" dependencies = [ "borsh 0.9.3", - "sol-stubs", "solana-account-info", - "solana-clock", "solana-msg", - "solana-program", "solana-program-entrypoint", "solana-program-error", "solana-pubkey", - "solana-sysvar", ] [[package]] @@ -317,12 +192,6 @@ dependencies = [ "libc", ] -[[package]] -name = "crunchy" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" - [[package]] name = "crypto-common" version = "0.1.6" @@ -333,52 +202,14 @@ dependencies = [ "typenum", ] -[[package]] -name = "curve25519-dalek" -version = "4.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" -dependencies = [ - "cfg-if", - "cpufeatures", - "curve25519-dalek-derive", - "digest 0.10.7", - "fiat-crypto", - "rand_core 0.6.4", - "rustc_version", - "subtle", - "zeroize", -] - -[[package]] -name = "curve25519-dalek-derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.98", -] - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] - [[package]] name = "digest" version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer 0.10.4", + "block-buffer", "crypto-common", - "subtle", ] [[package]] @@ -403,12 +234,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" -[[package]] -name = "fiat-crypto" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" - [[package]] name = "five8_const" version = "0.1.3" @@ -434,17 +259,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - [[package]] name = "getrandom" version = "0.2.15" @@ -454,7 +268,7 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "wasm-bindgen", ] @@ -493,15 +307,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "keccak" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" -dependencies = [ - "cpufeatures", -] - [[package]] name = "lazy_static" version = "1.5.0" @@ -514,52 +319,6 @@ version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" -[[package]] -name = "libsecp256k1" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9d220bc1feda2ac231cb78c3d26f27676b8cf82c96971f7aeef3d0cf2797c73" -dependencies = [ - "arrayref", - "base64 0.12.3", - "digest 0.9.0", - "libsecp256k1-core", - "libsecp256k1-gen-ecmult", - "libsecp256k1-gen-genmult", - "rand 0.7.3", - "serde", - "sha2 0.9.9", -] - -[[package]] -name = "libsecp256k1-core" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0f6ab710cec28cef759c5f18671a27dae2a5f952cdaaee1d8e2908cb2478a80" -dependencies = [ - "crunchy", - "digest 0.9.0", - "subtle", -] - -[[package]] -name = "libsecp256k1-gen-ecmult" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccab96b584d38fac86a83f07e659f0deafd0253dc096dab5a36d53efe653c5c3" -dependencies = [ - "libsecp256k1-core", -] - -[[package]] -name = "libsecp256k1-gen-genmult" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67abfe149395e3aa1c48a2beb32b068e2334402df8181f818d3aee2b304c4f5d" -dependencies = [ - "libsecp256k1-core", -] - [[package]] name = "litesvm-clock-example" version = "0.0.0" @@ -594,45 +353,6 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" -[[package]] -name = "memoffset" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num-bigint" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" -dependencies = [ - "num-integer", - "num-traits", -] - -[[package]] -name = "num-derive" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.98", -] - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - [[package]] name = "num-traits" version = "0.2.19" @@ -648,12 +368,6 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" -[[package]] -name = "opaque-debug" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" - [[package]] name = "parking_lot" version = "0.12.3" @@ -677,15 +391,6 @@ dependencies = [ "windows-targets", ] -[[package]] -name = "ppv-lite86" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] - [[package]] name = "proc-macro-crate" version = "0.1.5" @@ -722,77 +427,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom 0.1.16", - "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.15", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core 0.5.1", -] - [[package]] name = "redox_syscall" version = "0.5.2" @@ -802,15 +436,6 @@ dependencies = [ "bitflags", ] -[[package]] -name = "rustc_version" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" -dependencies = [ - "semver", -] - [[package]] name = "rustversion" version = "1.0.17" @@ -823,12 +448,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "semver" -version = "1.0.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" - [[package]] name = "serde" version = "1.0.217" @@ -838,15 +457,6 @@ dependencies = [ "serde_derive", ] -[[package]] -name = "serde_bytes" -version = "0.11.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8437fd221bde2d4ca316d61b90e337e9e702b3820b87d63caa9ba6c02bd06d96" -dependencies = [ - "serde", -] - [[package]] name = "serde_derive" version = "1.0.217" @@ -858,19 +468,6 @@ dependencies = [ "syn 2.0.98", ] -[[package]] -name = "sha2" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", -] - [[package]] name = "sha2" version = "0.10.8" @@ -879,81 +476,26 @@ checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.7", + "digest", ] -[[package]] -name = "sha3" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" -dependencies = [ - "digest 0.10.7", - "keccak", -] - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - [[package]] name = "smallvec" version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" -[[package]] -name = "sol-stubs" -version = "0.1.0" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "solana-account" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f949fe4edaeaea78c844023bfc1c898e0b1f5a100f8a8d2d0f85d0a7b090258" -dependencies = [ - "solana-account-info", - "solana-clock", - "solana-instruction", - "solana-pubkey", - "solana-sdk-ids", -] - [[package]] name = "solana-account-info" version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e0c17d606a298a205fae325489fbed88ee6dc4463c111672172327e741c8905d" dependencies = [ - "bincode", - "serde", "solana-program-error", "solana-program-memory", "solana-pubkey", ] -[[package]] -name = "solana-address-lookup-table-interface" -version = "2.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1673f67efe870b64a65cb39e6194be5b26527691ce5922909939961a6e6b395" -dependencies = [ - "bincode", - "bytemuck", - "serde", - "serde_derive", - "solana-clock", - "solana-instruction", - "solana-pubkey", - "solana-sdk-ids", - "solana-slot-hashes", -] - [[package]] name = "solana-atomic-u64" version = "2.2.1" @@ -963,50 +505,6 @@ dependencies = [ "parking_lot", ] -[[package]] -name = "solana-big-mod-exp" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75db7f2bbac3e62cfd139065d15bcda9e2428883ba61fc8d27ccb251081e7567" -dependencies = [ - "num-bigint", - "num-traits", - "solana-define-syscall", -] - -[[package]] -name = "solana-bincode" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19a3787b8cf9c9fe3dd360800e8b70982b9e5a8af9e11c354b6665dd4a003adc" -dependencies = [ - "bincode", - "serde", - "solana-instruction", -] - -[[package]] -name = "solana-blake3-hasher" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a0801e25a1b31a14494fc80882a036be0ffd290efc4c2d640bfcca120a4672" -dependencies = [ - "blake3", - "solana-define-syscall", - "solana-hash", - "solana-sanitize", -] - -[[package]] -name = "solana-borsh" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718333bcd0a1a7aed6655aa66bef8d7fb047944922b2d3a18f49cbc13e73d004" -dependencies = [ - "borsh 0.10.4", - "borsh 1.5.5", -] - [[package]] name = "solana-clock" version = "2.2.1" @@ -1045,75 +543,35 @@ dependencies = [ [[package]] name = "solana-define-syscall" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf784bb2cb3e02cac9801813c30187344228d2ae952534902108f6150573a33d" - -[[package]] -name = "solana-epoch-rewards" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b575d3dd323b9ea10bb6fe89bf6bf93e249b215ba8ed7f68f1a3633f384db7" -dependencies = [ - "serde", - "serde_derive", - "solana-hash", - "solana-sdk-ids", - "solana-sdk-macro", - "solana-sysvar-id", -] - -[[package]] -name = "solana-epoch-schedule" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fce071fbddecc55d727b1d7ed16a629afe4f6e4c217bc8d00af3b785f6f67ed" -dependencies = [ - "serde", - "serde_derive", - "solana-sdk-ids", - "solana-sdk-macro", - "solana-sysvar-id", -] +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf784bb2cb3e02cac9801813c30187344228d2ae952534902108f6150573a33d" [[package]] -name = "solana-example-mocks" +name = "solana-epoch-rewards" version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84461d56cbb8bb8d539347151e0525b53910102e4bced875d49d5139708e39d3" +checksum = "86b575d3dd323b9ea10bb6fe89bf6bf93e249b215ba8ed7f68f1a3633f384db7" dependencies = [ "serde", "serde_derive", - "solana-address-lookup-table-interface", - "solana-clock", "solana-hash", - "solana-instruction", - "solana-keccak-hasher", - "solana-message", - "solana-nonce", - "solana-pubkey", "solana-sdk-ids", - "solana-system-interface", - "thiserror", + "solana-sdk-macro", + "solana-sysvar-id", ] [[package]] -name = "solana-feature-gate-interface" -version = "2.2.2" +name = "solana-epoch-schedule" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f5c5382b449e8e4e3016fb05e418c53d57782d8b5c30aa372fc265654b956d" +checksum = "3fce071fbddecc55d727b1d7ed16a629afe4f6e4c217bc8d00af3b785f6f67ed" dependencies = [ - "bincode", "serde", "serde_derive", - "solana-account", - "solana-account-info", - "solana-instruction", - "solana-program-error", - "solana-pubkey", - "solana-rent", "solana-sdk-ids", - "solana-system-interface", + "solana-sdk-macro", + "solana-sysvar-id", ] [[package]] @@ -1133,7 +591,6 @@ version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf7bcb14392900fe02e4e34e90234fbf0c673d4e327888410ba99fa2ba0f4e99" dependencies = [ - "borsh 1.5.5", "bs58", "bytemuck", "bytemuck_derive", @@ -1152,8 +609,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ce496a475e5062ba5de97215ab39d9c358f9c9df4bb7f3a45a1f1a8bd9065ed" dependencies = [ "bincode", - "borsh 1.5.5", - "getrandom 0.2.15", + "getrandom", "js-sys", "num-traits", "serde", @@ -1180,18 +636,6 @@ dependencies = [ "solana-sysvar-id", ] -[[package]] -name = "solana-keccak-hasher" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7aeb957fbd42a451b99235df4942d96db7ef678e8d5061ef34c9b34cae12f79" -dependencies = [ - "sha3", - "solana-define-syscall", - "solana-hash", - "solana-sanitize", -] - [[package]] name = "solana-last-restart-slot" version = "2.2.1" @@ -1205,73 +649,6 @@ dependencies = [ "solana-sysvar-id", ] -[[package]] -name = "solana-loader-v2-interface" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8ab08006dad78ae7cd30df8eea0539e207d08d91eaefb3e1d49a446e1c49654" -dependencies = [ - "serde", - "serde_bytes", - "serde_derive", - "solana-instruction", - "solana-pubkey", - "solana-sdk-ids", -] - -[[package]] -name = "solana-loader-v3-interface" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4be76cfa9afd84ca2f35ebc09f0da0f0092935ccdac0595d98447f259538c2" -dependencies = [ - "serde", - "serde_bytes", - "serde_derive", - "solana-instruction", - "solana-pubkey", - "solana-sdk-ids", - "solana-system-interface", -] - -[[package]] -name = "solana-loader-v4-interface" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "706a777242f1f39a83e2a96a2a6cb034cb41169c6ecbee2cf09cb873d9659e7e" -dependencies = [ - "serde", - "serde_bytes", - "serde_derive", - "solana-instruction", - "solana-pubkey", - "solana-sdk-ids", - "solana-system-interface", -] - -[[package]] -name = "solana-message" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1796aabce376ff74bf89b78d268fa5e683d7d7a96a0a4e4813ec34de49d5314b" -dependencies = [ - "bincode", - "blake3", - "lazy_static", - "serde", - "serde_derive", - "solana-bincode", - "solana-hash", - "solana-instruction", - "solana-pubkey", - "solana-sanitize", - "solana-sdk-ids", - "solana-short-vec", - "solana-system-interface", - "solana-transaction-error", - "wasm-bindgen", -] - [[package]] name = "solana-msg" version = "2.2.1" @@ -1281,106 +658,6 @@ dependencies = [ "solana-define-syscall", ] -[[package]] -name = "solana-native-token" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61515b880c36974053dd499c0510066783f0cc6ac17def0c7ef2a244874cf4a9" - -[[package]] -name = "solana-nonce" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703e22eb185537e06204a5bd9d509b948f0066f2d1d814a6f475dafb3ddf1325" -dependencies = [ - "serde", - "serde_derive", - "solana-fee-calculator", - "solana-hash", - "solana-pubkey", - "solana-sha256-hasher", -] - -[[package]] -name = "solana-program" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "586469467e93ceb79048f8d8e3a619bf61d05396ee7de95cb40280301a589d05" -dependencies = [ - "bincode", - "blake3", - "borsh 0.10.4", - "borsh 1.5.5", - "bs58", - "bytemuck", - "console_error_panic_hook", - "console_log", - "getrandom 0.2.15", - "lazy_static", - "log", - "memoffset", - "num-bigint", - "num-derive", - "num-traits", - "rand 0.8.5", - "serde", - "serde_bytes", - "serde_derive", - "solana-account-info", - "solana-address-lookup-table-interface", - "solana-atomic-u64", - "solana-big-mod-exp", - "solana-bincode", - "solana-blake3-hasher", - "solana-borsh", - "solana-clock", - "solana-cpi", - "solana-decode-error", - "solana-define-syscall", - "solana-epoch-rewards", - "solana-epoch-schedule", - "solana-example-mocks", - "solana-feature-gate-interface", - "solana-fee-calculator", - "solana-hash", - "solana-instruction", - "solana-instructions-sysvar", - "solana-keccak-hasher", - "solana-last-restart-slot", - "solana-loader-v2-interface", - "solana-loader-v3-interface", - "solana-loader-v4-interface", - "solana-message", - "solana-msg", - "solana-native-token", - "solana-nonce", - "solana-program-entrypoint", - "solana-program-error", - "solana-program-memory", - "solana-program-option", - "solana-program-pack", - "solana-pubkey", - "solana-rent", - "solana-sanitize", - "solana-sdk-ids", - "solana-sdk-macro", - "solana-secp256k1-recover", - "solana-serde-varint", - "solana-serialize-utils", - "solana-sha256-hasher", - "solana-short-vec", - "solana-slot-hashes", - "solana-slot-history", - "solana-stable-layout", - "solana-stake-interface", - "solana-system-interface", - "solana-sysvar", - "solana-sysvar-id", - "solana-vote-interface", - "thiserror", - "wasm-bindgen", -] - [[package]] name = "solana-program-entrypoint" version = "2.2.1" @@ -1401,8 +678,6 @@ checksum = "d8ae2c1a8d0d4ae865882d5770a7ebca92bab9c685e43f0461682c6c05a35bfa" dependencies = [ "borsh 1.5.5", "num-traits", - "serde", - "serde_derive", "solana-decode-error", "solana-instruction", "solana-msg", @@ -1419,35 +694,15 @@ dependencies = [ "solana-define-syscall", ] -[[package]] -name = "solana-program-option" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc677a2e9bc616eda6dbdab834d463372b92848b2bfe4a1ed4e4b4adba3397d0" - -[[package]] -name = "solana-program-pack" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "319f0ef15e6e12dc37c597faccb7d62525a509fec5f6975ecb9419efddeb277b" -dependencies = [ - "solana-program-error", -] - [[package]] name = "solana-pubkey" version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40db1ff5a0f8aea2c158d78ab5f2cf897848964251d1df42fef78efd3c85b863" dependencies = [ - "borsh 0.10.4", - "borsh 1.5.5", "bs58", - "bytemuck", - "bytemuck_derive", - "curve25519-dalek", "five8_const", - "getrandom 0.2.15", + "getrandom", "js-sys", "num-traits", "serde", @@ -1500,26 +755,6 @@ dependencies = [ "syn 2.0.98", ] -[[package]] -name = "solana-secp256k1-recover" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baa3120b6cdaa270f39444f5093a90a7b03d296d362878f7a6991d6de3bbe496" -dependencies = [ - "libsecp256k1", - "solana-define-syscall", - "thiserror", -] - -[[package]] -name = "solana-serde-varint" -version = "2.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a7e155eba458ecfb0107b98236088c3764a09ddf0201ec29e52a0be40857113" -dependencies = [ - "serde", -] - [[package]] name = "solana-serialize-utils" version = "2.2.1" @@ -1537,20 +772,11 @@ version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0037386961c0d633421f53560ad7c80675c0447cba4d1bb66d60974dd486c7ea" dependencies = [ - "sha2 0.10.8", + "sha2", "solana-define-syscall", "solana-hash", ] -[[package]] -name = "solana-short-vec" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c54c66f19b9766a56fa0057d060de8378676cb64987533fa088861858fc5a69" -dependencies = [ - "serde", -] - [[package]] name = "solana-slot-hashes" version = "2.2.1" @@ -1593,8 +819,6 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5269e89fde216b4d7e1d1739cf5303f8398a1ff372a81232abbee80e554a838c" dependencies = [ - "borsh 0.10.4", - "borsh 1.5.5", "num-traits", "serde", "serde_derive", @@ -1630,10 +854,8 @@ version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf6b44740d7f0c9f375d045c165bc0aab4a90658f92d6835aeb0649afaeaff9a" dependencies = [ - "base64 0.22.1", + "base64", "bincode", - "bytemuck", - "bytemuck_derive", "lazy_static", "serde", "serde_derive", @@ -1671,46 +893,6 @@ dependencies = [ "solana-sdk-ids", ] -[[package]] -name = "solana-transaction-error" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "222a9dc8fdb61c6088baab34fc3a8b8473a03a7a5fd404ed8dd502fa79b67cb1" -dependencies = [ - "solana-instruction", - "solana-sanitize", -] - -[[package]] -name = "solana-vote-interface" -version = "2.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef4f08746f154458f28b98330c0d55cb431e2de64ee4b8efc98dcbe292e0672b" -dependencies = [ - "bincode", - "num-derive", - "num-traits", - "serde", - "serde_derive", - "solana-clock", - "solana-decode-error", - "solana-hash", - "solana-instruction", - "solana-pubkey", - "solana-rent", - "solana-sdk-ids", - "solana-serde-varint", - "solana-serialize-utils", - "solana-short-vec", - "solana-system-interface", -] - -[[package]] -name = "subtle" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" - [[package]] name = "syn" version = "1.0.109" @@ -1733,26 +915,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "thiserror" -version = "2.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "2.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.98", -] - [[package]] name = "tinyvec" version = "1.6.0" @@ -1812,12 +974,6 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -1882,16 +1038,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "web-sys" -version = "0.3.77" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - [[package]] name = "windows-targets" version = "0.52.5" @@ -1964,29 +1110,3 @@ checksum = "59690dea168f2198d1a3b0cac23b8063efcd11012f10ae4698f284808c8ef603" dependencies = [ "memchr", ] - -[[package]] -name = "zerocopy" -version = "0.8.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.98", -] - -[[package]] -name = "zeroize" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" diff --git a/crates/litesvm/test_programs/Cargo.toml b/crates/litesvm/test_programs/Cargo.toml index 62ea0097..e45595bf 100644 --- a/crates/litesvm/test_programs/Cargo.toml +++ b/crates/litesvm/test_programs/Cargo.toml @@ -11,7 +11,6 @@ solana-program-entrypoint = "2.2" solana-program-error = "2.2" solana-pubkey = "2.2" solana-sysvar = { version = "2.2", features = ["bincode"] } -solana-program = "2.2" [profile.release] overflow-checks = true diff --git a/crates/litesvm/test_programs/clock-example/src/lib.rs b/crates/litesvm/test_programs/clock-example/src/lib.rs index 566aa284..30bd77ae 100644 --- a/crates/litesvm/test_programs/clock-example/src/lib.rs +++ b/crates/litesvm/test_programs/clock-example/src/lib.rs @@ -1,6 +1,9 @@ use { - solana_account_info::AccountInfo, solana_clock::Clock, solana_program_error::ProgramResult, - solana_pubkey::Pubkey, solana_sysvar::Sysvar, + solana_account_info::AccountInfo, + solana_clock::Clock, + solana_program_error::ProgramResult, + solana_pubkey::Pubkey, + solana_sysvar::Sysvar, }; solana_program_entrypoint::entrypoint!(process_instruction); diff --git a/crates/litesvm/test_programs/counter/Cargo.toml b/crates/litesvm/test_programs/counter/Cargo.toml index 0e86a924..d2b81902 100644 --- a/crates/litesvm/test_programs/counter/Cargo.toml +++ b/crates/litesvm/test_programs/counter/Cargo.toml @@ -18,9 +18,3 @@ solana-msg.workspace = true solana-program-entrypoint.workspace = true solana-program-error = { workspace = true, features = ["borsh"] } solana-pubkey.workspace = true -solana-program.workspace = true -#solana-program-test.workspace = true -sol-stubs = { path = "/Users/boris/projects/solana/sol-stubs" } - -solana-clock = { workspace = true } -solana-sysvar = { workspace = true } diff --git a/crates/litesvm/test_programs/counter/src/lib.rs b/crates/litesvm/test_programs/counter/src/lib.rs index 82d0be82..2b0d20ff 100644 --- a/crates/litesvm/test_programs/counter/src/lib.rs +++ b/crates/litesvm/test_programs/counter/src/lib.rs @@ -1,11 +1,9 @@ use borsh::{BorshDeserialize, BorshSerialize}; use { solana_account_info::{next_account_info, AccountInfo}, - solana_clock::Clock, solana_msg::msg, solana_program_error::{ProgramError, ProgramResult}, solana_pubkey::{declare_id, Pubkey}, - solana_sysvar::Sysvar, }; mod state; @@ -25,15 +23,8 @@ pub fn process_instruction( instruction_data: &[u8], ) -> ProgramResult { let (instruction_discriminant, instruction_data_inner) = instruction_data.split_at(1); - msg!( - "accounts: {:#?}, instdata: {:#?}", - accounts, - instruction_data - ); match instruction_discriminant[0] { 0 => { - let got_clock = Clock::get()?; - msg!("Clock timestamp: {:?}", got_clock); msg!("Instruction: Increment"); process_increment_counter(accounts, instruction_data_inner)?; } @@ -62,7 +53,3 @@ pub fn process_increment_counter( msg!("Counter state incremented to {:?}", counter.count); Ok(()) } - -use solana_program::instruction::AccountMeta; -use solana_program::instruction::Instruction; -sol_stubs::declare_sol_app_stubs!(process_instruction); diff --git a/crates/litesvm/test_programs/failure/src/lib.rs b/crates/litesvm/test_programs/failure/src/lib.rs index ee517497..0676af80 100644 --- a/crates/litesvm/test_programs/failure/src/lib.rs +++ b/crates/litesvm/test_programs/failure/src/lib.rs @@ -2,8 +2,7 @@ use solana_program_entrypoint::entrypoint; use { - solana_account_info::AccountInfo, - solana_program_error::{ProgramError, ProgramResult}, + solana_account_info::AccountInfo, solana_program_error::{ProgramError, ProgramResult}, solana_pubkey::{declare_id, Pubkey}, }; From 0c5e662dff72aca62daf9f894719a74da5e19694 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Fri, 27 Jun 2025 10:42:28 +0300 Subject: [PATCH 18/86] revert stuff done in tests --- crates/litesvm/tests/counter_test.rs | 10 ++-------- crates/litesvm/tests/gen_cov.sh | 10 ---------- 2 files changed, 2 insertions(+), 18 deletions(-) delete mode 100755 crates/litesvm/tests/gen_cov.sh diff --git a/crates/litesvm/tests/counter_test.rs b/crates/litesvm/tests/counter_test.rs index 9f9eb2c5..9b9ad047 100644 --- a/crates/litesvm/tests/counter_test.rs +++ b/crates/litesvm/tests/counter_test.rs @@ -15,7 +15,7 @@ use { solana_signer::Signer, solana_transaction::{versioned::VersionedTransaction, Transaction}, solana_transaction_error::TransactionError, - std::{path::PathBuf, str::FromStr}, + std::path::PathBuf, }; const NUM_GREETINGS: u8 = 127; @@ -29,12 +29,6 @@ fn read_counter_program() -> Vec { #[test] pub fn integration_test() { let mut svm = LiteSVM::new(); - let _ = svm.add_native_program(vec![( - Pubkey::from_str("GtdambwDgHWrDJdVPBkEHGhCwokqgAoch162teUjJse2").unwrap(), - "counter".into(), - "/Users/boris/projects/litesvm/crates/litesvm/test_programs/target/debug/libcounter.dylib" - .into(), - )]); let payer_kp = Keypair::new(); let payer_pk = payer_kp.pubkey(); let program_id = pubkey!("GtdambwDgHWrDJdVPBkEHGhCwokqgAoch162teUjJse2"); @@ -45,7 +39,7 @@ pub fn integration_test() { let _ = svm.set_account( counter_address, Account { - lamports: 5000000, + lamports: 5, data: vec![0_u8; std::mem::size_of::()], owner: program_id, ..Default::default() diff --git a/crates/litesvm/tests/gen_cov.sh b/crates/litesvm/tests/gen_cov.sh deleted file mode 100755 index a464e226..00000000 --- a/crates/litesvm/tests/gen_cov.sh +++ /dev/null @@ -1,10 +0,0 @@ -rm -rf /Users/boris/projects/litesvm/crates/litesvm/tests/profraw/ -export LLVM_PROFILE_FILE="/Users/boris/projects/litesvm/crates/litesvm/tests/profraw/%p-%m.profraw" -mkdir -p /Users/boris/projects/litesvm/crates/litesvm/tests/profraw -RUSTFLAGS="--emit=llvm-ir -Z coverage-options=mcdc -C instrument-coverage" cargo +nightly test -- --nocapture --exact integration_test -llvm-profdata merge -sparse profraw/*.profraw -o merged.profdata -llvm-cov show \ - /Users/boris/projects/litesvm/crates/litesvm/test_programs/target/debug/libcounter.dylib \ - -instr-profile=merged.profdata \ - --format=html -output-dir=htmlcov -#open htmlcov/index.html From 805850072bc537e94095a2769f3e75c1ff9364c1 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Fri, 27 Jun 2025 11:04:30 +0300 Subject: [PATCH 19/86] start using the github repos for sol-stubs and program-test should you encounter issues with cargo fetching: mkdir -p .cargo vi .cargo/config.toml and add [net] git-fetch-with-cli = true --- Cargo.lock | 2 ++ Cargo.toml | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fbc6112d..bdd21423 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4208,6 +4208,7 @@ dependencies = [ [[package]] name = "sol-stubs" version = "0.1.0" +source = "git+ssh://git@github.com/procdump/sol-stubs.git?branch=refactor#944d40d32e57cf1169dfc444ffd63affe0403720" dependencies = [ "lazy_static", ] @@ -5695,6 +5696,7 @@ dependencies = [ [[package]] name = "solana-program-test" version = "2.2.4" +source = "git+ssh://git@github.com/vlady-kotsev/program-test.git#453e6f1bacc9dadc1911e2f411a1c7c44ca85124" dependencies = [ "assert_matches", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index 7ca65cb3..1e438836 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,7 +60,7 @@ solana-program-option = "2.2" solana-program-pack = "2.2" solana-program-runtime = ">=2.2,<=2.2.4" #solana-program-test = "2.2" -solana-program-test = { path = "../program-test" } +solana-program-test = { git = "ssh://git@github.com/vlady-kotsev/program-test.git" } solana-pubkey = "2.2" solana-rent = "2.2" solana-reserved-account-keys = "2.2" @@ -91,7 +91,8 @@ test-log = "0.2" thiserror = "2.0" tokio = "1.35" lite-coverage = { path = "crates/lite-coverage" } -sol-stubs = { path = "../sol-stubs" } +sol-stubs = { git = "ssh://git@github.com/procdump/sol-stubs.git", branch = "refactor" } + [profile.bench] debug = true From 1a48c51655aa414b4b611fc5be8c66e841721a77 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Fri, 27 Jun 2025 11:29:23 +0300 Subject: [PATCH 20/86] Remove more unwraps and instead bail out gracefully. --- crates/lite-coverage/src/loader.rs | 5 +- crates/node-litesvm/litesvm/internal.d.ts | 4 ++ crates/node-litesvm/src/lib.rs | 74 ++++++++++------------- 3 files changed, 40 insertions(+), 43 deletions(-) diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index 57bedd8a..0eae0440 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -1,4 +1,7 @@ -use crate::{stubs::{StubsManager, SyscallStubsApi, UnimplementedSyscallStubs, WrapperSyscallStubs}, types::LiteCoverageError}; +use crate::{ + stubs::{StubsManager, SyscallStubsApi, UnimplementedSyscallStubs, WrapperSyscallStubs}, + types::LiteCoverageError, +}; use libloading::{Library, Symbol}; use solana_program::{ account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError, diff --git a/crates/node-litesvm/litesvm/internal.d.ts b/crates/node-litesvm/litesvm/internal.d.ts index 5f6eed7c..e2fdfbce 100644 --- a/crates/node-litesvm/litesvm/internal.d.ts +++ b/crates/node-litesvm/litesvm/internal.d.ts @@ -556,6 +556,10 @@ export declare class LiteSvm { airdrop(pubkey: Uint8Array, lamports: bigint): TransactionMetadata | FailedTransactionMetadata | null /** Adds am SBF program to the test environment from the file specified. */ addProgramFromFile(programId: Uint8Array, path: string): void + /** + * Load native programs as well as additional SBF programs in order to + * provide code coverage. + */ withCoverage(programs: Array<[string, Uint8Array, string]>, additionalPrograms: Array<[string, Uint8Array]>): void /** Adds am SBF program to the test environment. */ addProgram(programId: Uint8Array, programBytes: Uint8Array): void diff --git a/crates/node-litesvm/src/lib.rs b/crates/node-litesvm/src/lib.rs index 90086d87..3d202bc7 100644 --- a/crates/node-litesvm/src/lib.rs +++ b/crates/node-litesvm/src/lib.rs @@ -22,7 +22,7 @@ use { SimulatedTransactionInfo as SimulatedTransactionInfoOriginal, TransactionResult as TransactionResultOriginal, }, - LiteSVM as LiteSVMOriginal, NativeProgram, + LiteSVM as LiteSVMOriginal, }, napi::bindgen_prelude::*, solana_clock::Clock as ClockOriginal, @@ -236,53 +236,43 @@ impl LiteSvm { } #[napi] + /// Load native programs as well as additional SBF programs in order to + /// provide code coverage. pub fn with_coverage( &mut self, programs: Vec<(String, Uint8Array, String)>, additional_programs: Vec<(String, Uint8Array)>, ) -> Result<()> { - let programs: Vec<(Pubkey, String, String)> = programs - .iter() - .map(|p| { - ( - Pubkey::new_from_array( - p.1.to_vec() - .try_into() - .map_err(|_| { - Error::new(Status::InvalidArg, "Program ID must be 32 bytes") - }) - .unwrap(), - ), - p.0.clone(), - p.2.clone(), - ) - }) - .collect(); - let additional_programs: Vec<(Pubkey, String)> = additional_programs - .iter() - .map(|ap| { - ( - Pubkey::new_from_array( - ap.1.to_vec() - .try_into() - .map_err(|_| { - Error::new(Status::InvalidArg, "Program ID must be 32 bytes") - }) - .unwrap(), - ), - ap.0.clone(), - ) - }) - .collect(); + let mut progs: Vec<(Pubkey, String, String)> = vec![]; + for p in programs { + progs.push(( + Pubkey::new_from_array( + p.1.to_vec().try_into().map_err(|_| { + Error::new(Status::InvalidArg, "Program ID must be 32 bytes") + })?, + ), + p.0.clone(), + p.2.clone(), + )); + } + let mut additional_progs: Vec<(Pubkey, String)> = vec![]; + for ap in additional_programs { + additional_progs.push(( + Pubkey::new_from_array( + ap.1.to_vec().try_into().map_err(|_| { + Error::new(Status::InvalidArg, "Program ID must be 32 bytes") + })?, + ), + ap.0.clone(), + )); + } - self.0 - .with_coverage(programs, additional_programs) - .map_err(|e| { - Error::new( - Status::GenericFailure, - format!("Failed to set programs for coverage: {e}"), - ) - })?; + self.0.with_coverage(progs, additional_progs).map_err(|e| { + Error::new( + Status::GenericFailure, + format!("Failed to set programs for coverage: {e}"), + ) + })?; Ok(()) } From e18476a5510b9cd9e8b59d33218a5c45984a0329 Mon Sep 17 00:00:00 2001 From: vlady-kotsev Date: Mon, 30 Jun 2025 11:31:43 +0300 Subject: [PATCH 21/86] feat: copy instructions sysvar account to program test --- Cargo.lock | 3 +-- Cargo.toml | 5 ++++- crates/litesvm/src/lib.rs | 6 ++++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bdd21423..2b570379 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6807,8 +6807,7 @@ dependencies = [ [[package]] name = "solana-transaction-context" version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5022de04cbba05377f68bf848c8c1322ead733f88a657bf792bb40f3257b8218" +source = "git+ssh://git@github.com/vlady-kotsev/solana-transaction-context.git#3d709b99740c444f8f0ac8cf491da2396264be4a" dependencies = [ "bincode", "serde", diff --git a/Cargo.toml b/Cargo.toml index 1e438836..6a3a1a5c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -81,7 +81,7 @@ solana-sysvar = "2.2" solana-sysvar-id = "2.2" solana-timings = "2.2" solana-transaction = "2.2" -solana-transaction-context = "2.2" +solana-transaction-context = { git = "ssh://git@github.com/vlady-kotsev/solana-transaction-context.git" } solana-transaction-error = "2.2" solana-vote-program = "2.2" spl-associated-token-account-client = "2.0" @@ -108,3 +108,6 @@ codegen-units = 1 [workspace.lints.clippy] result_large_err = "allow" + +[patch.crates-io] +solana-transaction-context = { git = "ssh://git@github.com/vlady-kotsev/solana-transaction-context.git" } diff --git a/crates/litesvm/src/lib.rs b/crates/litesvm/src/lib.rs index a10e1b9b..ed58fe0d 100644 --- a/crates/litesvm/src/lib.rs +++ b/crates/litesvm/src/lib.rs @@ -1088,6 +1088,12 @@ impl LiteSVM { } } } + // include instructions_sysvar account + let ix_account = construct_instructions_account(tx.message()); + tx_accounts.push(( + Pubkey::from_str_const("Sysvar1nstructions1111111111111111111111111"), + ix_account, + )); tx_accounts } fn check_accounts_rent( From 2edd7ea8bfb1412f7cd9e8d142113b5b77477fea Mon Sep 17 00:00:00 2001 From: vlady-kotsev Date: Mon, 30 Jun 2025 11:51:51 +0300 Subject: [PATCH 22/86] fix: dependencies --- Cargo.lock | 968 ++++++++++++++++++++++++++++++----------------------- Cargo.toml | 2 +- 2 files changed, 548 insertions(+), 422 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2b570379..52c826bc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,9 +13,9 @@ dependencies = [ [[package]] name = "adler2" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "aead" @@ -71,15 +71,15 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.11" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", - "getrandom 0.2.15", + "getrandom 0.3.3", "once_cell", "version_check", - "zerocopy 0.7.35", + "zerocopy", ] [[package]] @@ -138,9 +138,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.18" +version = "0.6.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" dependencies = [ "anstyle", "anstyle-parse", @@ -153,44 +153,44 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" +checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" [[package]] name = "anstyle-parse" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" dependencies = [ "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.7" +version = "3.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" +checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" dependencies = [ "anstyle", - "once_cell", + "once_cell_polyfill", "windows-sys 0.59.0", ] [[package]] name = "anyhow" -version = "1.0.97" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" +checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" [[package]] name = "aquamarine" @@ -203,7 +203,7 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -399,9 +399,9 @@ dependencies = [ [[package]] name = "async-compression" -version = "0.4.22" +version = "0.4.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59a194f9d963d8099596278594b3107448656ba73831c9d8c783e613ce86da64" +checksum = "40f6024f3f856663b45fd0c9b6f2024034a702f453549449e0d84a305900dad4" dependencies = [ "brotli", "flate2", @@ -430,7 +430,7 @@ checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -446,15 +446,15 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "backtrace" -version = "0.3.74" +version = "0.3.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" dependencies = [ "addr2line", "cfg-if", @@ -506,9 +506,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" dependencies = [ "serde", ] @@ -524,9 +524,9 @@ dependencies = [ [[package]] name = "blake3" -version = "1.8.0" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34a796731680be7931955498a16a10b2270c7762963d5d570fdbfe02dcbf314f" +checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0" dependencies = [ "arrayref", "arrayvec", @@ -597,7 +597,7 @@ dependencies = [ "proc-macro-crate 3.3.0", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -624,9 +624,9 @@ dependencies = [ [[package]] name = "brotli" -version = "7.0.0" +version = "8.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc97b8f16f944bba54f0433f07e30be199b6dc2bd25937444bbad560bcea29bd" +checksum = "9991eea70ea4f293524138648e41ee89b0b2b12ddef3b255effa43c8056e0e0d" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -635,9 +635,9 @@ dependencies = [ [[package]] name = "brotli-decompressor" -version = "4.0.2" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74fa05ad7d803d413eb8380983b092cbbaf9a85f151b871360e7b00cd7060b37" +checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -654,9 +654,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.17.0" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "bv" @@ -670,9 +670,9 @@ dependencies = [ [[package]] name = "bytemuck" -version = "1.22.0" +version = "1.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6b1fc10dbac614ebc03540c9dbd60e83887fda27794998c6528f1782047d540" +checksum = "5c76a5792e44e4abe34d3abf15636779261d45a7450612059293d1d2cfc63422" dependencies = [ "bytemuck_derive", ] @@ -685,7 +685,7 @@ checksum = "7ecc273b49b3205b83d648f0690daa588925572cc5063745bfe547fe7ec8e1a1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -738,9 +738,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.17" +version = "1.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a" +checksum = "d487aa071b5f64da6f19a3e848e3578944b726ee5a4854b82172f02aa876bfdc" dependencies = [ "jobserver", "libc", @@ -755,9 +755,9 @@ checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" [[package]] name = "cfg_aliases" @@ -773,14 +773,14 @@ checksum = "45565fc9416b9896014f5732ac776f810ee53a66730c17e4020c3ec064a8f88f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] name = "chrono" -version = "0.4.40" +version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" dependencies = [ "android-tzdata", "iana-time-zone", @@ -839,18 +839,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.34" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e958897981290da2a852763fe9cdb89cd36977a5d729023127095fa94d95e2ff" +checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.34" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83b0f35019843db2160b5bb19ae09b4e6411ac33fc6a712003c33e03090e2489" +checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e" dependencies = [ "anstyle", "clap_lex", @@ -858,15 +858,15 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" [[package]] name = "colorchoice" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" [[package]] name = "combine" @@ -960,9 +960,9 @@ dependencies = [ [[package]] name = "core-foundation" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" dependencies = [ "core-foundation-sys", "libc", @@ -1030,9 +1030,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.14" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" dependencies = [ "crossbeam-utils", ] @@ -1064,9 +1064,9 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crunchy" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "crypto-common" @@ -1096,7 +1096,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" dependencies = [ "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -1147,7 +1147,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -1171,7 +1171,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -1182,7 +1182,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -1201,9 +1201,9 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "575f75dfd25738df5b91b8e43e14d44bda14637a58fae779fd2b064f8bf3e010" +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" [[package]] name = "der-parser" @@ -1221,9 +1221,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.4.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cfac68e08048ae1883171632c2aef3ebc555621ae56fbccce1cbf22dd7f058" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" dependencies = [ "powerfmt", ] @@ -1288,7 +1288,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -1311,7 +1311,7 @@ checksum = "a6cbae11b3de8fce2a456e8ea3dada226b35fe791f0dc1d360c0941f0bb681f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -1358,7 +1358,7 @@ dependencies = [ "derivation-path", "ed25519-dalek", "hmac 0.12.1", - "sha2 0.10.8", + "sha2 0.10.9", ] [[package]] @@ -1411,7 +1411,7 @@ checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -1424,7 +1424,7 @@ dependencies = [ "num-traits", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -1451,9 +1451,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.7" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3716d7a920fb4fac5d84e9d4bce8ceb321e9414b4409da61b07b75c1e3d0697" +checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" dependencies = [ "anstream", "anstyle", @@ -1469,12 +1469,12 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.10" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" +checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -1504,6 +1504,18 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "fastbloom" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27cea6e7f512d43b098939ff4d5a5d6fe3db07971e1d05176fe26c642d33f5b8" +dependencies = [ + "getrandom 0.3.3", + "rand 0.9.1", + "siphasher 1.0.1", + "wide", +] + [[package]] name = "fastrand" version = "2.3.0" @@ -1551,9 +1563,9 @@ checksum = "2551bf44bc5f776c15044b9b94153a00198be06743e262afaaa61f11ac7523a5" [[package]] name = "flate2" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc" +checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" dependencies = [ "crc32fast", "miniz_oxide", @@ -1660,7 +1672,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -1734,22 +1746,22 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "js-sys", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi 0.11.1+wasi-snapshot-preview1", "wasm-bindgen", ] [[package]] name = "getrandom" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" dependencies = [ "cfg-if", "js-sys", @@ -1800,15 +1812,15 @@ dependencies = [ "indexmap", "slab", "tokio", - "tokio-util 0.7.14", + "tokio-util 0.7.15", "tracing", ] [[package]] name = "half" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7db2ff139bba50379da6aa0766b52fdcb62cb5b263009b09ed58ba604e14bbd1" +checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" dependencies = [ "cfg-if", "crunchy", @@ -1840,9 +1852,9 @@ checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "hashbrown" -version = "0.15.2" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" [[package]] name = "heck" @@ -1861,15 +1873,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - -[[package]] -name = "hermit-abi" -version = "0.5.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbd780fe5cc30f81464441920d82ac8740e2e46b29a6fad543ddd075229ce37e" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" [[package]] name = "histogram" @@ -1987,9 +1993,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.62" +version = "0.1.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2fd658b06e56721792c5df4475705b6cda790e9298d19d2f8af083457bcd127" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -2011,21 +2017,22 @@ dependencies = [ [[package]] name = "icu_collections" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" dependencies = [ "displaydoc", + "potential_utf", "yoke", "zerofrom", "zerovec", ] [[package]] -name = "icu_locid" -version = "1.5.0" +name = "icu_locale_core" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" dependencies = [ "displaydoc", "litemap", @@ -2034,31 +2041,11 @@ dependencies = [ "zerovec", ] -[[package]] -name = "icu_locid_transform" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" -dependencies = [ - "displaydoc", - "icu_locid", - "icu_locid_transform_data", - "icu_provider", - "tinystr", - "zerovec", -] - -[[package]] -name = "icu_locid_transform_data" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d" - [[package]] name = "icu_normalizer" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" dependencies = [ "displaydoc", "icu_collections", @@ -2066,67 +2053,54 @@ dependencies = [ "icu_properties", "icu_provider", "smallvec", - "utf16_iter", - "utf8_iter", - "write16", "zerovec", ] [[package]] name = "icu_normalizer_data" -version = "1.5.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7" +checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" [[package]] name = "icu_properties" -version = "1.5.1" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" dependencies = [ "displaydoc", "icu_collections", - "icu_locid_transform", + "icu_locale_core", "icu_properties_data", "icu_provider", - "tinystr", + "potential_utf", + "zerotrie", "zerovec", ] [[package]] name = "icu_properties_data" -version = "1.5.1" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2" +checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" [[package]] name = "icu_provider" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" dependencies = [ "displaydoc", - "icu_locid", - "icu_provider_macros", + "icu_locale_core", "stable_deref_trait", "tinystr", "writeable", "yoke", "zerofrom", + "zerotrie", "zerovec", ] -[[package]] -name = "icu_provider_macros" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.100", -] - [[package]] name = "ident_case" version = "1.0.1" @@ -2146,9 +2120,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" dependencies = [ "icu_normalizer", "icu_properties", @@ -2191,18 +2165,18 @@ dependencies = [ [[package]] name = "index_list" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa38453685e5fe724fd23ff6c1a158c1e2ca21ce0c2718fa11e96e70e99fd4de" +checksum = "8f05caee923b644542e92a659bfceb868a4053fb7d4230ef2141931e8b01e91a" [[package]] name = "indexmap" -version = "2.8.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" +checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" dependencies = [ "equivalent", - "hashbrown 0.15.2", + "hashbrown 0.15.4", ] [[package]] @@ -2239,7 +2213,7 @@ version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" dependencies = [ - "hermit-abi 0.5.0", + "hermit-abi 0.5.2", "libc", "windows-sys 0.59.0", ] @@ -2307,10 +2281,11 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "jobserver" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" dependencies = [ + "getrandom 0.3.3", "libc", ] @@ -2356,9 +2331,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.171" +version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" [[package]] name = "libloading" @@ -2367,16 +2342,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" dependencies = [ "cfg-if", - "windows-targets 0.52.6", + "windows-targets 0.53.2", ] [[package]] name = "libredox" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +checksum = "1580801010e535496706ba011c15f8532df6b42297d2e471fec38ceadd8c0638" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "libc", "redox_syscall", ] @@ -2443,9 +2418,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" [[package]] name = "lite-coverage" @@ -2476,9 +2451,9 @@ dependencies = [ [[package]] name = "litemap" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" +checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" [[package]] name = "litesvm" @@ -2627,9 +2602,9 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" dependencies = [ "autocfg", "scopeguard", @@ -2641,6 +2616,12 @@ version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + [[package]] name = "lz4" version = "1.28.1" @@ -2671,9 +2652,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.4" +version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" [[package]] name = "memmap2" @@ -2729,22 +2710,22 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.8.5" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", ] [[package]] name = "mio" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" dependencies = [ "libc", - "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.52.0", + "wasi 0.11.1+wasi-snapshot-preview1", + "windows-sys 0.59.0", ] [[package]] @@ -2801,7 +2782,7 @@ version = "2.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55740c4ae1d8696773c78fdafd5d0e5fe9bc9f1b071c7ba493ba5c413a9184f3" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "ctor", "napi-derive", "napi-sys", @@ -2810,9 +2791,9 @@ dependencies = [ [[package]] name = "napi-build" -version = "2.1.6" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28acfa557c083f6e254a786e01ba253fc56f18ee000afcd4f79af735f73a6da" +checksum = "44e0e3177307063d3e7e55b7dd7b648cca9d7f46daa35422c0d98cc2bf48c2c1" [[package]] name = "napi-derive" @@ -2825,7 +2806,7 @@ dependencies = [ "napi-derive-backend", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -2840,7 +2821,7 @@ dependencies = [ "quote", "regex", "semver", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -2858,7 +2839,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "cfg-if", "cfg_aliases", "libc", @@ -2962,7 +2943,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -3008,33 +2989,34 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" dependencies = [ - "hermit-abi 0.3.9", + "hermit-abi 0.5.2", "libc", ] [[package]] name = "num_enum" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" +checksum = "a973b4e44ce6cad84ce69d797acf9a044532e4184c4f267913d1b546a0727b7a" dependencies = [ "num_enum_derive", + "rustversion", ] [[package]] name = "num_enum_derive" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" +checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d" dependencies = [ "proc-macro-crate 3.3.0", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -3067,6 +3049,12 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +[[package]] +name = "once_cell_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" + [[package]] name = "oorandom" version = "11.1.5" @@ -3081,11 +3069,11 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.71" +version = "0.10.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd" +checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "cfg-if", "foreign-types", "libc", @@ -3102,7 +3090,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -3113,18 +3101,18 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-src" -version = "300.4.2+3.4.1" +version = "300.5.0+3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168ce4e058f975fe43e89d9ccf78ca668601887ae736090aacc23ae353c298e2" +checksum = "e8ce546f549326b0e6052b649198487d91320875da901e7bd11a06d1ee3f9c2f" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.106" +version = "0.9.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bb61ea9811cc39e3c2069f40b8b8e2e70d8569b361f879786cc7ed48b777cdd" +checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571" dependencies = [ "cc", "libc", @@ -3166,9 +3154,9 @@ checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" dependencies = [ "lock_api", "parking_lot_core", @@ -3176,9 +3164,9 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.10" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" dependencies = [ "cfg-if", "libc", @@ -3243,7 +3231,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -3306,9 +3294,18 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" +checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" + +[[package]] +name = "potential_utf" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +dependencies = [ + "zerovec", +] [[package]] name = "powerfmt" @@ -3322,7 +3319,7 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ - "zerocopy 0.8.24", + "zerocopy", ] [[package]] @@ -3396,9 +3393,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.94" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] @@ -3420,29 +3417,29 @@ checksum = "9e2e25ee72f5b24d773cae88422baddefff7714f97aab68d96fe2b6fc4a28fb2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] name = "quanta" -version = "0.12.5" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bd1fe6824cea6538803de3ff1bc0cf3949024db3d43c9643024bfb33a807c0e" +checksum = "f3ab5a9d756f0d97bdc89019bd2e4ea098cf9cde50ee7564dde6b81ccc8f06c7" dependencies = [ "crossbeam-utils", "libc", "once_cell", "raw-cpuid", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi 0.11.1+wasi-snapshot-preview1", "web-sys", "winapi", ] [[package]] name = "quinn" -version = "0.11.7" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3bd15a6f2967aef83887dcb9fec0014580467e33720d073560cf015a5683012" +checksum = "626214629cda6781b6dc1d316ba307189c85ba657213ce642d9c77670f8202c8" dependencies = [ "bytes", "cfg_aliases", @@ -3450,7 +3447,7 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash", - "rustls 0.23.25", + "rustls 0.23.28", "socket2", "thiserror 2.0.12", "tokio", @@ -3460,16 +3457,18 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.10" +version = "0.11.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b820744eb4dc9b57a3398183639c511b5a26d2ed702cedd3febaa1393caa22cc" +checksum = "49df843a9161c85bb8aae55f101bc0bac8bcafd637a620d9122fd7e0b2f7422e" dependencies = [ "bytes", - "getrandom 0.3.2", - "rand 0.9.0", + "fastbloom", + "getrandom 0.3.3", + "lru-slab", + "rand 0.9.1", "ring", "rustc-hash", - "rustls 0.23.25", + "rustls 0.23.28", "rustls-pki-types", "rustls-platform-verifier", "slab", @@ -3481,9 +3480,9 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.11" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "541d0f57c6ec747a90738a52741d3221f7960e8ac2f0ff4b1a63680e033b4ab5" +checksum = "fcebb1209ee276352ef14ff8732e24cc2b02bbac986cd74a4c81bcb2f9881970" dependencies = [ "cfg_aliases", "libc", @@ -3504,9 +3503,9 @@ dependencies = [ [[package]] name = "r-efi" -version = "5.2.0" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] name = "rand" @@ -3534,13 +3533,12 @@ dependencies = [ [[package]] name = "rand" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" +checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.3", - "zerocopy 0.8.24", ] [[package]] @@ -3588,7 +3586,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.15", + "getrandom 0.2.16", ] [[package]] @@ -3597,7 +3595,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "getrandom 0.3.2", + "getrandom 0.3.3", ] [[package]] @@ -3624,7 +3622,7 @@ version = "11.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6df7ab838ed27997ba19a4664507e6f82b41fe6e20be42929332156e5e85146" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", ] [[package]] @@ -3649,11 +3647,11 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.10" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" +checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", ] [[package]] @@ -3734,7 +3732,7 @@ dependencies = [ "system-configuration", "tokio", "tokio-rustls", - "tokio-util 0.7.14", + "tokio-util 0.7.15", "tower-service", "url", "wasm-bindgen", @@ -3767,7 +3765,7 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.15", + "getrandom 0.2.16", "libc", "untrusted", "windows-sys 0.52.0", @@ -3775,9 +3773,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.24" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f" [[package]] name = "rustc-hash" @@ -3805,11 +3803,11 @@ dependencies = [ [[package]] name = "rustix" -version = "1.0.3" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e56a18552996ac8d29ecc3b190b4fdbb2d91ca4ec396de7bbffaf43f3d637e96" +checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "errno", "libc", "linux-raw-sys", @@ -3830,14 +3828,14 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.25" +version = "0.23.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "822ee9188ac4ec04a2f0531e55d035fb2de73f18b41a63c70c2712503b6fb13c" +checksum = "7160e3e10bf4535308537f3c4e1641468cd0e485175d6163087c0393c7d46643" dependencies = [ "once_cell", "ring", "rustls-pki-types", - "rustls-webpki 0.103.1", + "rustls-webpki 0.103.3", "subtle", "zeroize", ] @@ -3865,31 +3863,32 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" +checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" dependencies = [ "web-time", + "zeroize", ] [[package]] name = "rustls-platform-verifier" -version = "0.5.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5467026f437b4cb2a533865eaa73eb840019a0916f4b9ec563c6e617e086c9" +checksum = "19787cda76408ec5404443dc8b31795c87cd8fec49762dc75fa727740d34acc1" dependencies = [ - "core-foundation 0.10.0", + "core-foundation 0.10.1", "core-foundation-sys", "jni", "log", "once_cell", - "rustls 0.23.25", + "rustls 0.23.28", "rustls-native-certs", "rustls-platform-verifier-android", - "rustls-webpki 0.103.1", + "rustls-webpki 0.103.3", "security-framework", "security-framework-sys", - "webpki-root-certs", + "webpki-root-certs 0.26.11", "windows-sys 0.59.0", ] @@ -3911,9 +3910,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.1" +version = "0.103.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fef8b8769aaccf73098557a87cd1816b4f9c7c16811c9c77142aa695c16f2c03" +checksum = "e4a72fe2bcf7a6ac6fd7d0b9e5cb68aeb7d4c0a0271730218b3e92d43b4eb435" dependencies = [ "ring", "rustls-pki-types", @@ -3922,9 +3921,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.20" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" +checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" [[package]] name = "ryu" @@ -3932,6 +3931,15 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +[[package]] +name = "safe_arch" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b02de82ddbe1b636e6170c21be622223aea188ef2e139be0a5b219ec215323" +dependencies = [ + "bytemuck", +] + [[package]] name = "same-file" version = "1.0.6" @@ -3972,8 +3980,8 @@ version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316" dependencies = [ - "bitflags 2.9.0", - "core-foundation 0.10.0", + "bitflags 2.9.1", + "core-foundation 0.10.1", "core-foundation-sys", "libc", "security-framework-sys", @@ -4039,7 +4047,7 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -4068,9 +4076,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.12.0" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6b6f7f2fcb69f747921f79f3926bd1e203fce4fef62c268dd3abfb6d86029aa" +checksum = "bf65a400f8f66fb7b0552869ad70157166676db75ed8181f8104ea91cf9d0b42" dependencies = [ "serde", "serde_derive", @@ -4079,14 +4087,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.12.0" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d00caa5193a3c8362ac2b73be6b9e768aa5a4b2f721d8f4b339600c3cb51f8e" +checksum = "81679d9ed988d5e9a5e6531dc3f2c28efbd639cbd1dfb628df08edea6004da77" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -4115,9 +4123,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.8" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", "cpufeatures", @@ -4151,9 +4159,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" -version = "1.4.2" +version = "1.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" dependencies = [ "libc", ] @@ -4170,6 +4178,12 @@ version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" +[[package]] +name = "siphasher" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" + [[package]] name = "sized-chunks" version = "0.6.5" @@ -4182,24 +4196,21 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg", -] +checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" [[package]] name = "smallvec" -version = "1.14.0" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "socket2" -version = "0.5.9" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" dependencies = [ "libc", "windows-sys 0.52.0", @@ -4208,7 +4219,7 @@ dependencies = [ [[package]] name = "sol-stubs" version = "0.1.0" -source = "git+ssh://git@github.com/procdump/sol-stubs.git?branch=refactor#944d40d32e57cf1169dfc444ffd63affe0403720" +source = "git+ssh://git@github.com/procdump/sol-stubs.git?branch=refactor#394190d3a700f0420eaca8d220686e948cd78895" dependencies = [ "lazy_static", ] @@ -4846,9 +4857,9 @@ dependencies = [ [[package]] name = "solana-decode-error" -version = "2.2.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a6a6383af236708048f8bd8d03db8ca4ff7baf4a48e5d580f4cce545925470" +checksum = "8c781686a18db2f942e70913f7ca15dc120ec38dcab42ff7557db2c70c625a35" dependencies = [ "num-traits", ] @@ -4872,9 +4883,9 @@ dependencies = [ [[package]] name = "solana-ed25519-program" -version = "2.2.1" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0c4dfce08d71d8f1e9b7d1b4e2c7101a8109903ad481acbbc1119a73d459f2" +checksum = "a1feafa1691ea3ae588f99056f4bdd1293212c7ece28243d7da257c443e84753" dependencies = [ "bytemuck", "bytemuck_derive", @@ -4915,7 +4926,7 @@ version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96c5fd2662ae7574810904585fd443545ed2b568dbd304b25a31e79ccc76e81b" dependencies = [ - "siphasher", + "siphasher 0.3.11", "solana-hash", "solana-pubkey", ] @@ -5108,7 +5119,7 @@ checksum = "9ce496a475e5062ba5de97215ab39d9c358f9c9df4bb7f3a45a1f1a8bd9065ed" dependencies = [ "bincode", "borsh 1.5.7", - "getrandom 0.2.15", + "getrandom 0.2.16", "js-sys", "num-traits", "serde", @@ -5124,7 +5135,7 @@ version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "427f2d0d6dc0bb49f16cef5e7f975180d2e80aab9bdd3b2af68e2d029ec63f43" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "solana-account-info", "solana-instruction", "solana-program-error", @@ -5420,7 +5431,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "004f2d2daf407b3ec1a1ca5ec34b3ccdfd6866dd2d3c7d0715004a96e4b6d127" dependencies = [ "bincode", - "bitflags 2.9.0", + "bitflags 2.9.1", "cfg_eval", "serde", "serde_derive", @@ -5483,9 +5494,9 @@ dependencies = [ [[package]] name = "solana-precompile-error" -version = "2.2.1" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ff64daa2933c22982b323d88d0cdf693201ef56ac381ae16737fd5f579e07d6" +checksum = "4d87b2c1f5de77dfe2b175ee8dd318d196aaca4d0f66f02842f80c852811f9f8" dependencies = [ "num-traits", "solana-decode-error", @@ -5533,7 +5544,7 @@ dependencies = [ "bytemuck", "console_error_panic_hook", "console_log", - "getrandom 0.2.15", + "getrandom 0.2.16", "lazy_static", "log", "memoffset", @@ -5613,9 +5624,9 @@ dependencies = [ [[package]] name = "solana-program-error" -version = "2.2.1" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8ae2c1a8d0d4ae865882d5770a7ebca92bab9c685e43f0461682c6c05a35bfa" +checksum = "9ee2e0217d642e2ea4bee237f37bd61bb02aec60da3647c48ff88f6556ade775" dependencies = [ "borsh 1.5.7", "num-traits", @@ -5696,7 +5707,7 @@ dependencies = [ [[package]] name = "solana-program-test" version = "2.2.4" -source = "git+ssh://git@github.com/vlady-kotsev/program-test.git#453e6f1bacc9dadc1911e2f411a1c7c44ca85124" +source = "git+ssh://git@github.com/vlady-kotsev/program-test.git?branch=feat/processed-sibling#0f88d67ee59eb6f247ffbece98c12fc2369b3753" dependencies = [ "assert_matches", "async-trait", @@ -5724,6 +5735,7 @@ dependencies = [ "solana-sdk-ids", "solana-svm", "solana-timings", + "solana-transaction-context", "solana-vote-program", "thiserror 2.0.12", "tokio", @@ -5742,7 +5754,7 @@ dependencies = [ "bytemuck_derive", "curve25519-dalek 4.1.3", "five8_const", - "getrandom 0.2.15", + "getrandom 0.2.16", "js-sys", "num-traits", "rand 0.8.5", @@ -5797,7 +5809,7 @@ dependencies = [ "log", "quinn", "quinn-proto", - "rustls 0.23.25", + "rustls 0.23.28", "solana-connection-cache", "solana-keypair", "solana-measure", @@ -5875,9 +5887,9 @@ dependencies = [ [[package]] name = "solana-reserved-account-keys" -version = "2.2.1" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b293f4246626c0e0a991531f08848a713ada965612e99dc510963f04d12cae7" +checksum = "e4b22ea19ca2a3f28af7cd047c914abf833486bf7a7c4a10fc652fff09b385b1" dependencies = [ "lazy_static", "solana-feature-set", @@ -6200,7 +6212,7 @@ dependencies = [ "bs58", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -6235,9 +6247,9 @@ dependencies = [ [[package]] name = "solana-secp256r1-program" -version = "2.2.1" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9ea9282950921611bd9e0200da7236fbb1d4f8388942f8451bd55e9f3cb228f" +checksum = "cf903cbdc36a161533812f90acfccdb434ed48982bd5dd71f3217930572c4a80" dependencies = [ "bytemuck", "openssl", @@ -6270,7 +6282,7 @@ checksum = "36187af2324f079f65a675ec22b31c24919cb4ac22c79472e85d819db9bbbc15" dependencies = [ "hmac 0.12.1", "pbkdf2", - "sha2 0.10.8", + "sha2 0.10.9", ] [[package]] @@ -6327,7 +6339,7 @@ version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0037386961c0d633421f53560ad7c80675c0447cba4d1bb66d60974dd486c7ea" dependencies = [ - "sha2 0.10.8", + "sha2 0.10.9", "solana-define-syscall", "solana-hash", ] @@ -6488,7 +6500,7 @@ dependencies = [ "quinn", "quinn-proto", "rand 0.8.5", - "rustls 0.23.25", + "rustls 0.23.28", "smallvec", "socket2", "solana-keypair", @@ -6507,7 +6519,7 @@ dependencies = [ "solana-transaction-metrics-tracker", "thiserror 2.0.12", "tokio", - "tokio-util 0.7.14", + "tokio-util 0.7.15", "x509-parser", ] @@ -6735,7 +6747,7 @@ version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec21c6c242ee93642aa50b829f5727470cdbdf6b461fb7323fe4bc31d1b54c08" dependencies = [ - "rustls 0.23.25", + "rustls 0.23.28", "solana-keypair", "solana-pubkey", "solana-signer", @@ -7158,7 +7170,7 @@ checksum = "d9e8418ea6269dcfb01c712f0444d2c75542c04448b480e87de59d2865edc750" dependencies = [ "quote", "spl-discriminator-syn", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -7169,8 +7181,8 @@ checksum = "8c1f05593b7ca9eac7caca309720f2eafb96355e037e6d373b909a80fe7b69b9" dependencies = [ "proc-macro2", "quote", - "sha2 0.10.8", - "syn 2.0.100", + "sha2 0.10.9", + "syn 2.0.104", "thiserror 1.0.69", ] @@ -7242,8 +7254,8 @@ checksum = "e6d375dd76c517836353e093c2dbb490938ff72821ab568b545fd30ab3256b3e" dependencies = [ "proc-macro2", "quote", - "sha2 0.10.8", - "syn 2.0.100", + "sha2 0.10.9", + "syn 2.0.104", ] [[package]] @@ -7496,9 +7508,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.100" +version = "2.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" dependencies = [ "proc-macro2", "quote", @@ -7525,13 +7537,13 @@ dependencies = [ [[package]] name = "synstructure" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -7612,12 +7624,12 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.19.1" +version = "3.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf" +checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" dependencies = [ "fastrand", - "getrandom 0.3.2", + "getrandom 0.3.3", "once_cell", "rustix", "windows-sys 0.59.0", @@ -7644,7 +7656,7 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7f46083d221181166e5b6f6b1e5f1d499f3a76888826e6cb1d057554157cd0f" dependencies = [ - "env_logger 0.11.7", + "env_logger 0.11.8", "test-log-macros", "tracing-subscriber", ] @@ -7657,7 +7669,7 @@ checksum = "888d0c3c6db53c0fdab160d2ed5e12ba745383d3e85813f2ea0f2b1475ab553f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -7686,7 +7698,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -7697,17 +7709,16 @@ checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] name = "thread_local" -version = "1.1.8" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" dependencies = [ "cfg-if", - "once_cell", ] [[package]] @@ -7743,9 +7754,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.7.6" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" dependencies = [ "displaydoc", "zerovec", @@ -7802,7 +7813,7 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -7874,9 +7885,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.14" +version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b9590b93e6fcc1739458317cccd391ad3955e2bde8913edf6f95f9e65a8f034" +checksum = "66a539a9ad6d5d281510d5bd368c973d636c02dbf8a67300bfb6b950696ad7df" dependencies = [ "bytes", "futures-core", @@ -7896,15 +7907,15 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.8" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" [[package]] name = "toml_edit" -version = "0.22.24" +version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ "indexmap", "toml_datetime", @@ -7931,20 +7942,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.28" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" +checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] name = "tracing-core" -version = "0.1.33" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" dependencies = [ "once_cell", "valuable", @@ -8044,9 +8055,9 @@ checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-width" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" +checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c" [[package]] name = "unicode-xid" @@ -8106,12 +8117,6 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" -[[package]] -name = "utf16_iter" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" - [[package]] name = "utf8_iter" version = "1.0.4" @@ -8175,9 +8180,9 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasi" @@ -8210,7 +8215,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", "wasm-bindgen-shared", ] @@ -8245,7 +8250,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -8281,9 +8286,18 @@ dependencies = [ [[package]] name = "webpki-root-certs" -version = "0.26.8" +version = "0.26.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75c7f0ef91146ebfb530314f5f1d24528d7f0767efbfd31dce919275413e393e" +dependencies = [ + "webpki-root-certs 1.0.1", +] + +[[package]] +name = "webpki-root-certs" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09aed61f5e8d2c18344b3faa33a4c837855fe56642757754775548fee21386c4" +checksum = "86138b15b2b7d561bc4469e77027b8dd005a43dc502e9031d1f5afc8ce1f280e" dependencies = [ "rustls-pki-types", ] @@ -8303,6 +8317,16 @@ version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" +[[package]] +name = "wide" +version = "0.7.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce5da8ecb62bcd8ec8b7ea19f69a51275e91299be594ea5cc6ef7819e16cd03" +dependencies = [ + "bytemuck", + "safe_arch", +] + [[package]] name = "winapi" version = "0.3.9" @@ -8336,18 +8360,62 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-core" -version = "0.52.0" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" dependencies = [ - "windows-targets 0.52.6", + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "windows-interface" +version = "0.59.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", ] [[package]] name = "windows-link" -version = "0.1.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link", +] [[package]] name = "windows-sys" @@ -8385,6 +8453,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.2", +] + [[package]] name = "windows-targets" version = "0.42.2" @@ -8424,13 +8501,29 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm", + "windows_i686_gnullvm 0.52.6", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", "windows_x86_64_msvc 0.52.6", ] +[[package]] +name = "windows-targets" +version = "0.53.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef" +dependencies = [ + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -8449,6 +8542,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -8467,6 +8566,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -8485,12 +8590,24 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -8509,6 +8626,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -8527,6 +8650,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" @@ -8545,6 +8674,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -8563,11 +8698,17 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + [[package]] name = "winnow" -version = "0.7.4" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e97b544156e9bebe1a0ffbc03484fc1ffe3100cbce3ffb17eac35f7cdd7ab36" +checksum = "74c7b26e3480b707944fc872477815d29a8e429d2f93a1ce000f5fa84a15cbcd" dependencies = [ "memchr", ] @@ -8588,20 +8729,14 @@ version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", ] -[[package]] -name = "write16" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" - [[package]] name = "writeable" -version = "0.5.5" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" +checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" [[package]] name = "x509-parser" @@ -8623,9 +8758,9 @@ dependencies = [ [[package]] name = "xattr" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d65cbf2f12c15564212d48f4e3dfb87923d25d611f2aed18f4cb23f0413d89e" +checksum = "af3a19837351dc82ba89f8a125e22a3c475f05aba604acc023d62b2739ae2909" dependencies = [ "libc", "rustix", @@ -8633,9 +8768,9 @@ dependencies = [ [[package]] name = "yoke" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" dependencies = [ "serde", "stable_deref_trait", @@ -8645,54 +8780,34 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", - "synstructure 0.13.1", + "syn 2.0.104", + "synstructure 0.13.2", ] [[package]] name = "zerocopy" -version = "0.7.35" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" dependencies = [ - "zerocopy-derive 0.7.35", -] - -[[package]] -name = "zerocopy" -version = "0.8.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" -dependencies = [ - "zerocopy-derive 0.8.24", + "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.35" +version = "0.8.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] @@ -8712,8 +8827,8 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", - "synstructure 0.13.1", + "syn 2.0.104", + "synstructure 0.13.2", ] [[package]] @@ -8733,14 +8848,25 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", +] + +[[package]] +name = "zerotrie" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", ] [[package]] name = "zerovec" -version = "0.10.4" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" dependencies = [ "yoke", "zerofrom", @@ -8749,13 +8875,13 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.10.3" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.104", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 6a3a1a5c..e9493647 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,7 +60,7 @@ solana-program-option = "2.2" solana-program-pack = "2.2" solana-program-runtime = ">=2.2,<=2.2.4" #solana-program-test = "2.2" -solana-program-test = { git = "ssh://git@github.com/vlady-kotsev/program-test.git" } +solana-program-test = { git = "ssh://git@github.com/vlady-kotsev/program-test.git", branch = "feat/processed-sibling" } solana-pubkey = "2.2" solana-rent = "2.2" solana-reserved-account-keys = "2.2" From 4d2b3dd0ad18454cdfdeb728129c904b457ea868 Mon Sep 17 00:00:00 2001 From: vlady-kotsev Date: Mon, 30 Jun 2025 17:05:29 +0300 Subject: [PATCH 23/86] feat: add setter for payer --- Cargo.lock | 37 ++++++++++++----------- Cargo.toml | 9 ++---- crates/lite-coverage/src/lite_coverage.rs | 5 +++ crates/litesvm/src/lib.rs | 3 +- crates/node-litesvm/Cargo.toml | 4 +-- crates/node-litesvm/litesvm/index.ts | 5 +-- crates/node-litesvm/litesvm/internal.d.ts | 2 +- crates/node-litesvm/src/lib.rs | 19 +++++++++--- 8 files changed, 49 insertions(+), 35 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 52c826bc..6b500cc1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -902,15 +902,15 @@ dependencies = [ [[package]] name = "console" -version = "0.15.11" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" +checksum = "2e09ced7ebbccb63b4c65413d821f2e00ce54c5ca4514ddc6b3c892fdbcbc69d" dependencies = [ "encode_unicode", "libc", "once_cell", "unicode-width", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -2181,14 +2181,14 @@ dependencies = [ [[package]] name = "indicatif" -version = "0.17.11" +version = "0.17.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "183b3088984b400f4cfac3620d5e076c84da5364016b4f49473de574b2586235" +checksum = "4adb2ee6ad319a912210a36e56e3623555817bcc877a7e6e8802d1d69c4d8056" dependencies = [ "console", - "number_prefix", "portable-atomic", "unicode-width", + "unit-prefix", "web-time", ] @@ -2566,6 +2566,7 @@ dependencies = [ "solana-feature-set", "solana-hash", "solana-instruction", + "solana-keypair", "solana-last-restart-slot", "solana-message", "solana-precompiles", @@ -2791,9 +2792,9 @@ dependencies = [ [[package]] name = "napi-build" -version = "2.2.1" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44e0e3177307063d3e7e55b7dd7b648cca9d7f46daa35422c0d98cc2bf48c2c1" +checksum = "fff539e61c5e3dd4d7d283610662f5d672c2aea0f158df78af694f13dbb3287b" [[package]] name = "napi-derive" @@ -3019,12 +3020,6 @@ dependencies = [ "syn 2.0.104", ] -[[package]] -name = "number_prefix" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" - [[package]] name = "object" version = "0.36.7" @@ -4219,7 +4214,7 @@ dependencies = [ [[package]] name = "sol-stubs" version = "0.1.0" -source = "git+ssh://git@github.com/procdump/sol-stubs.git?branch=refactor#394190d3a700f0420eaca8d220686e948cd78895" +source = "git+ssh://git@github.com/procdump/sol-stubs.git?branch=master#394190d3a700f0420eaca8d220686e948cd78895" dependencies = [ "lazy_static", ] @@ -5707,7 +5702,7 @@ dependencies = [ [[package]] name = "solana-program-test" version = "2.2.4" -source = "git+ssh://git@github.com/vlady-kotsev/program-test.git?branch=feat/processed-sibling#0f88d67ee59eb6f247ffbece98c12fc2369b3753" +source = "git+ssh://git@github.com/vlady-kotsev/program-test.git#06de41f1dce54e1cbef0d7bd5860dffebf035eb3" dependencies = [ "assert_matches", "async-trait", @@ -5735,7 +5730,6 @@ dependencies = [ "solana-sdk-ids", "solana-svm", "solana-timings", - "solana-transaction-context", "solana-vote-program", "thiserror 2.0.12", "tokio", @@ -6819,7 +6813,8 @@ dependencies = [ [[package]] name = "solana-transaction-context" version = "2.2.1" -source = "git+ssh://git@github.com/vlady-kotsev/solana-transaction-context.git#3d709b99740c444f8f0ac8cf491da2396264be4a" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5022de04cbba05377f68bf848c8c1322ead733f88a657bf792bb40f3257b8218" dependencies = [ "bincode", "serde", @@ -8065,6 +8060,12 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +[[package]] +name = "unit-prefix" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "323402cff2dd658f39ca17c789b502021b3f18707c91cdf22e3838e1b4023817" + [[package]] name = "universal-hash" version = "0.5.1" diff --git a/Cargo.toml b/Cargo.toml index e9493647..1b209c7d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,7 +60,7 @@ solana-program-option = "2.2" solana-program-pack = "2.2" solana-program-runtime = ">=2.2,<=2.2.4" #solana-program-test = "2.2" -solana-program-test = { git = "ssh://git@github.com/vlady-kotsev/program-test.git", branch = "feat/processed-sibling" } +solana-program-test = { git = "ssh://git@github.com/vlady-kotsev/program-test.git" } solana-pubkey = "2.2" solana-rent = "2.2" solana-reserved-account-keys = "2.2" @@ -81,7 +81,7 @@ solana-sysvar = "2.2" solana-sysvar-id = "2.2" solana-timings = "2.2" solana-transaction = "2.2" -solana-transaction-context = { git = "ssh://git@github.com/vlady-kotsev/solana-transaction-context.git" } +solana-transaction-context = "=2.2.1" solana-transaction-error = "2.2" solana-vote-program = "2.2" spl-associated-token-account-client = "2.0" @@ -91,7 +91,7 @@ test-log = "0.2" thiserror = "2.0" tokio = "1.35" lite-coverage = { path = "crates/lite-coverage" } -sol-stubs = { git = "ssh://git@github.com/procdump/sol-stubs.git", branch = "refactor" } +sol-stubs = { git = "ssh://git@github.com/procdump/sol-stubs.git", branch = "master" } [profile.bench] debug = true @@ -108,6 +108,3 @@ codegen-units = 1 [workspace.lints.clippy] result_large_err = "allow" - -[patch.crates-io] -solana-transaction-context = { git = "ssh://git@github.com/vlady-kotsev/solana-transaction-context.git" } diff --git a/crates/lite-coverage/src/lite_coverage.rs b/crates/lite-coverage/src/lite_coverage.rs index 034ee246..b32c7709 100644 --- a/crates/lite-coverage/src/lite_coverage.rs +++ b/crates/lite-coverage/src/lite_coverage.rs @@ -1,3 +1,5 @@ +use solana_keypair::Keypair; + use crate::{ loader::{entrypoint, Loader}, types::{LiteCoverageError, NativeProgram}, @@ -24,10 +26,13 @@ impl LiteCoverage { pub fn new( programs: Vec, additional_programs: Vec, + payer: Keypair, ) -> LiteCoverageError { let static_programs = Box::leak(Box::new(programs.clone())); let mut program_test = ProgramTest::default(); program_test.prefer_bpf(false); + program_test.set_payer(payer); + for (pubkey, name) in additional_programs.into_iter() { let name = Box::leak(Box::new(name)); program_test.add_upgradeable_program_to_genesis(name, &pubkey); diff --git a/crates/litesvm/src/lib.rs b/crates/litesvm/src/lib.rs index ed58fe0d..a503553e 100644 --- a/crates/litesvm/src/lib.rs +++ b/crates/litesvm/src/lib.rs @@ -1285,8 +1285,9 @@ impl LiteSVM { &mut self, programs: Vec, additional_programs: Vec, + payer: Keypair, ) -> LiteCoverageError<()> { - self.lite_coverage = Some(LiteCoverage::new(programs, additional_programs)?); + self.lite_coverage = Some(LiteCoverage::new(programs, additional_programs, payer)?); Ok(()) } diff --git a/crates/node-litesvm/Cargo.toml b/crates/node-litesvm/Cargo.toml index b94ab52b..aad689b8 100644 --- a/crates/node-litesvm/Cargo.toml +++ b/crates/node-litesvm/Cargo.toml @@ -25,7 +25,7 @@ solana-hash = { workspace = true } solana-instruction = { workspace = true } solana-last-restart-slot = { workspace = true } solana-message = { workspace = true } -solana-precompiles = { workspace = true, features = ["openssl-vendored"]} +solana-precompiles = { workspace = true, features = ["openssl-vendored"] } solana-pubkey = { workspace = true } solana-rent = { workspace = true } solana-signature = { workspace = true } @@ -36,6 +36,6 @@ solana-sysvar = { workspace = true } solana-transaction = { workspace = true } solana-transaction-context = { workspace = true } solana-transaction-error = { workspace = true } - +solana-keypair = { workspace = true } [build-dependencies] napi-build = "2.0.1" diff --git a/crates/node-litesvm/litesvm/index.ts b/crates/node-litesvm/litesvm/index.ts index 6cc0cd23..df811417 100644 --- a/crates/node-litesvm/litesvm/index.ts +++ b/crates/node-litesvm/litesvm/index.ts @@ -305,9 +305,10 @@ export class LiteSVM { */ withCoverage( programs: Array<[string, Uint8Array, string]>, - additionalPrograms: Array<[string, Uint8Array]> + additionalPrograms: Array<[string, Uint8Array]>, + payer: Uint8Array ) { - return this.inner.withCoverage(programs, additionalPrograms); + return this.inner.withCoverage(programs, additionalPrograms, payer); } /** diff --git a/crates/node-litesvm/litesvm/internal.d.ts b/crates/node-litesvm/litesvm/internal.d.ts index e2fdfbce..bc2d612c 100644 --- a/crates/node-litesvm/litesvm/internal.d.ts +++ b/crates/node-litesvm/litesvm/internal.d.ts @@ -560,7 +560,7 @@ export declare class LiteSvm { * Load native programs as well as additional SBF programs in order to * provide code coverage. */ - withCoverage(programs: Array<[string, Uint8Array, string]>, additionalPrograms: Array<[string, Uint8Array]>): void + withCoverage(programs: Array<[string, Uint8Array, string]>, additionalPrograms: Array<[string, Uint8Array]>, payer: Uint8Array): void /** Adds am SBF program to the test environment. */ addProgram(programId: Uint8Array, programBytes: Uint8Array): void sendLegacyTransaction(txBytes: Uint8Array): TransactionMetadata | FailedTransactionMetadata diff --git a/crates/node-litesvm/src/lib.rs b/crates/node-litesvm/src/lib.rs index 3d202bc7..b0619dfe 100644 --- a/crates/node-litesvm/src/lib.rs +++ b/crates/node-litesvm/src/lib.rs @@ -28,6 +28,7 @@ use { solana_clock::Clock as ClockOriginal, solana_epoch_rewards::EpochRewards as EpochRewardsOriginal, solana_epoch_schedule::EpochSchedule as EpochScheduleOriginal, + solana_keypair::Keypair, solana_last_restart_slot::LastRestartSlot, solana_pubkey::Pubkey, solana_rent::Rent as RentOriginal, @@ -242,6 +243,7 @@ impl LiteSvm { &mut self, programs: Vec<(String, Uint8Array, String)>, additional_programs: Vec<(String, Uint8Array)>, + payer: Uint8Array, ) -> Result<()> { let mut progs: Vec<(Pubkey, String, String)> = vec![]; for p in programs { @@ -267,12 +269,19 @@ impl LiteSvm { )); } - self.0.with_coverage(progs, additional_progs).map_err(|e| { - Error::new( - Status::GenericFailure, - format!("Failed to set programs for coverage: {e}"), + self.0 + .with_coverage( + progs, + additional_progs, + Keypair::from_bytes(&payer) + .map_err(|_| Error::new(Status::InvalidArg, "Invalid Payer Keypair bytes"))?, ) - })?; + .map_err(|e| { + Error::new( + Status::GenericFailure, + format!("Failed to set programs for coverage: {e}"), + ) + })?; Ok(()) } From 54735cf39013ebecfcb96909d8729755d796d73f Mon Sep 17 00:00:00 2001 From: vlady-kotsev Date: Mon, 30 Jun 2025 22:49:55 +0300 Subject: [PATCH 24/86] fix: redundant code, ease dependency --- Cargo.toml | 2 +- crates/litesvm/src/lib.rs | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 1b209c7d..5a33827b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -81,7 +81,7 @@ solana-sysvar = "2.2" solana-sysvar-id = "2.2" solana-timings = "2.2" solana-transaction = "2.2" -solana-transaction-context = "=2.2.1" +solana-transaction-context = "2.2" solana-transaction-error = "2.2" solana-vote-program = "2.2" spl-associated-token-account-client = "2.0" diff --git a/crates/litesvm/src/lib.rs b/crates/litesvm/src/lib.rs index a503553e..bf68ade6 100644 --- a/crates/litesvm/src/lib.rs +++ b/crates/litesvm/src/lib.rs @@ -1088,12 +1088,6 @@ impl LiteSVM { } } } - // include instructions_sysvar account - let ix_account = construct_instructions_account(tx.message()); - tx_accounts.push(( - Pubkey::from_str_const("Sysvar1nstructions1111111111111111111111111"), - ix_account, - )); tx_accounts } fn check_accounts_rent( From 8eda7861ab7be71450f07c8b0a8490c480de9801 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Tue, 1 Jul 2025 08:52:29 +0300 Subject: [PATCH 25/86] revert back Cargo.lock - just cargo update -p sol-stubs and solana-program-test --- Cargo.lock | 987 +++++++++++++++++++++++------------------------------ 1 file changed, 431 insertions(+), 556 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6b500cc1..9c035320 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,9 +13,9 @@ dependencies = [ [[package]] name = "adler2" -version = "2.0.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "aead" @@ -71,15 +71,15 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.12" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", - "getrandom 0.3.3", + "getrandom 0.2.15", "once_cell", "version_check", - "zerocopy", + "zerocopy 0.7.35", ] [[package]] @@ -138,9 +138,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.19" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", @@ -153,44 +153,44 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.11" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" -version = "0.2.7" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.3" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.9" +version = "3.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" +checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" dependencies = [ "anstyle", - "once_cell_polyfill", + "once_cell", "windows-sys 0.59.0", ] [[package]] name = "anyhow" -version = "1.0.98" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" +checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" [[package]] name = "aquamarine" @@ -203,7 +203,7 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.100", ] [[package]] @@ -399,9 +399,9 @@ dependencies = [ [[package]] name = "async-compression" -version = "0.4.25" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40f6024f3f856663b45fd0c9b6f2024034a702f453549449e0d84a305900dad4" +checksum = "59a194f9d963d8099596278594b3107448656ba73831c9d8c783e613ce86da64" dependencies = [ "brotli", "flate2", @@ -430,7 +430,7 @@ checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.100", ] [[package]] @@ -446,15 +446,15 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.5.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "backtrace" -version = "0.3.75" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", "cfg-if", @@ -506,9 +506,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.1" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" +checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" dependencies = [ "serde", ] @@ -524,9 +524,9 @@ dependencies = [ [[package]] name = "blake3" -version = "1.8.2" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0" +checksum = "34a796731680be7931955498a16a10b2270c7762963d5d570fdbfe02dcbf314f" dependencies = [ "arrayref", "arrayvec", @@ -597,7 +597,7 @@ dependencies = [ "proc-macro-crate 3.3.0", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.100", ] [[package]] @@ -624,9 +624,9 @@ dependencies = [ [[package]] name = "brotli" -version = "8.0.1" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9991eea70ea4f293524138648e41ee89b0b2b12ddef3b255effa43c8056e0e0d" +checksum = "cc97b8f16f944bba54f0433f07e30be199b6dc2bd25937444bbad560bcea29bd" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -635,9 +635,9 @@ dependencies = [ [[package]] name = "brotli-decompressor" -version = "5.0.0" +version = "4.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03" +checksum = "74fa05ad7d803d413eb8380983b092cbbaf9a85f151b871360e7b00cd7060b37" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -654,9 +654,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.19.0" +version = "3.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" [[package]] name = "bv" @@ -670,9 +670,9 @@ dependencies = [ [[package]] name = "bytemuck" -version = "1.23.1" +version = "1.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c76a5792e44e4abe34d3abf15636779261d45a7450612059293d1d2cfc63422" +checksum = "b6b1fc10dbac614ebc03540c9dbd60e83887fda27794998c6528f1782047d540" dependencies = [ "bytemuck_derive", ] @@ -685,7 +685,7 @@ checksum = "7ecc273b49b3205b83d648f0690daa588925572cc5063745bfe547fe7ec8e1a1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.100", ] [[package]] @@ -738,9 +738,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.27" +version = "1.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d487aa071b5f64da6f19a3e848e3578944b726ee5a4854b82172f02aa876bfdc" +checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a" dependencies = [ "jobserver", "libc", @@ -755,9 +755,9 @@ checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" [[package]] name = "cfg-if" -version = "1.0.1" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cfg_aliases" @@ -773,14 +773,14 @@ checksum = "45565fc9416b9896014f5732ac776f810ee53a66730c17e4020c3ec064a8f88f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.100", ] [[package]] name = "chrono" -version = "0.4.41" +version = "0.4.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" dependencies = [ "android-tzdata", "iana-time-zone", @@ -839,18 +839,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.40" +version = "4.5.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f" +checksum = "e958897981290da2a852763fe9cdb89cd36977a5d729023127095fa94d95e2ff" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.40" +version = "4.5.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e" +checksum = "83b0f35019843db2160b5bb19ae09b4e6411ac33fc6a712003c33e03090e2489" dependencies = [ "anstyle", "clap_lex", @@ -858,15 +858,15 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.5" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "colorchoice" -version = "1.0.4" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "combine" @@ -902,15 +902,15 @@ dependencies = [ [[package]] name = "console" -version = "0.16.0" +version = "0.15.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e09ced7ebbccb63b4c65413d821f2e00ce54c5ca4514ddc6b3c892fdbcbc69d" +checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" dependencies = [ "encode_unicode", "libc", "once_cell", "unicode-width", - "windows-sys 0.60.2", + "windows-sys 0.59.0", ] [[package]] @@ -960,9 +960,9 @@ dependencies = [ [[package]] name = "core-foundation" -version = "0.10.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" dependencies = [ "core-foundation-sys", "libc", @@ -1030,9 +1030,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.15" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471" dependencies = [ "crossbeam-utils", ] @@ -1064,9 +1064,9 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crunchy" -version = "0.2.4" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" +checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" [[package]] name = "crypto-common" @@ -1096,7 +1096,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" dependencies = [ "quote", - "syn 2.0.104", + "syn 2.0.100", ] [[package]] @@ -1147,7 +1147,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.100", ] [[package]] @@ -1171,7 +1171,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.104", + "syn 2.0.100", ] [[package]] @@ -1182,7 +1182,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core", "quote", - "syn 2.0.104", + "syn 2.0.100", ] [[package]] @@ -1201,9 +1201,9 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.9.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" +checksum = "575f75dfd25738df5b91b8e43e14d44bda14637a58fae779fd2b064f8bf3e010" [[package]] name = "der-parser" @@ -1221,9 +1221,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +checksum = "28cfac68e08048ae1883171632c2aef3ebc555621ae56fbccce1cbf22dd7f058" dependencies = [ "powerfmt", ] @@ -1288,7 +1288,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.100", ] [[package]] @@ -1311,7 +1311,7 @@ checksum = "a6cbae11b3de8fce2a456e8ea3dada226b35fe791f0dc1d360c0941f0bb681f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.100", ] [[package]] @@ -1358,7 +1358,7 @@ dependencies = [ "derivation-path", "ed25519-dalek", "hmac 0.12.1", - "sha2 0.10.9", + "sha2 0.10.8", ] [[package]] @@ -1411,7 +1411,7 @@ checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.100", ] [[package]] @@ -1424,7 +1424,7 @@ dependencies = [ "num-traits", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.100", ] [[package]] @@ -1451,9 +1451,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.8" +version = "0.11.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" +checksum = "c3716d7a920fb4fac5d84e9d4bce8ceb321e9414b4409da61b07b75c1e3d0697" dependencies = [ "anstream", "anstyle", @@ -1469,12 +1469,12 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.13" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.59.0", ] [[package]] @@ -1504,18 +1504,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "fastbloom" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27cea6e7f512d43b098939ff4d5a5d6fe3db07971e1d05176fe26c642d33f5b8" -dependencies = [ - "getrandom 0.3.3", - "rand 0.9.1", - "siphasher 1.0.1", - "wide", -] - [[package]] name = "fastrand" version = "2.3.0" @@ -1563,9 +1551,9 @@ checksum = "2551bf44bc5f776c15044b9b94153a00198be06743e262afaaa61f11ac7523a5" [[package]] name = "flate2" -version = "1.1.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" +checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc" dependencies = [ "crc32fast", "miniz_oxide", @@ -1672,7 +1660,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.100", ] [[package]] @@ -1746,22 +1734,22 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.16" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "js-sys", "libc", - "wasi 0.11.1+wasi-snapshot-preview1", + "wasi 0.11.0+wasi-snapshot-preview1", "wasm-bindgen", ] [[package]] name = "getrandom" -version = "0.3.3" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" dependencies = [ "cfg-if", "js-sys", @@ -1812,15 +1800,15 @@ dependencies = [ "indexmap", "slab", "tokio", - "tokio-util 0.7.15", + "tokio-util 0.7.14", "tracing", ] [[package]] name = "half" -version = "2.6.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" +checksum = "7db2ff139bba50379da6aa0766b52fdcb62cb5b263009b09ed58ba604e14bbd1" dependencies = [ "cfg-if", "crunchy", @@ -1852,9 +1840,9 @@ checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "hashbrown" -version = "0.15.4" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" [[package]] name = "heck" @@ -1873,9 +1861,15 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.5.2" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hermit-abi" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbd780fe5cc30f81464441920d82ac8740e2e46b29a6fad543ddd075229ce37e" [[package]] name = "histogram" @@ -1993,9 +1987,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.63" +version = "0.1.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +checksum = "b2fd658b06e56721792c5df4475705b6cda790e9298d19d2f8af083457bcd127" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -2017,22 +2011,21 @@ dependencies = [ [[package]] name = "icu_collections" -version = "2.0.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" dependencies = [ "displaydoc", - "potential_utf", "yoke", "zerofrom", "zerovec", ] [[package]] -name = "icu_locale_core" -version = "2.0.0" +name = "icu_locid" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" dependencies = [ "displaydoc", "litemap", @@ -2041,11 +2034,31 @@ dependencies = [ "zerovec", ] +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d" + [[package]] name = "icu_normalizer" -version = "2.0.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" dependencies = [ "displaydoc", "icu_collections", @@ -2053,54 +2066,67 @@ dependencies = [ "icu_properties", "icu_provider", "smallvec", + "utf16_iter", + "utf8_iter", + "write16", "zerovec", ] [[package]] name = "icu_normalizer_data" -version = "2.0.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" +checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7" [[package]] name = "icu_properties" -version = "2.0.1" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" dependencies = [ "displaydoc", "icu_collections", - "icu_locale_core", + "icu_locid_transform", "icu_properties_data", "icu_provider", - "potential_utf", - "zerotrie", + "tinystr", "zerovec", ] [[package]] name = "icu_properties_data" -version = "2.0.1" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" +checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2" [[package]] name = "icu_provider" -version = "2.0.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" dependencies = [ "displaydoc", - "icu_locale_core", + "icu_locid", + "icu_provider_macros", "stable_deref_trait", "tinystr", "writeable", "yoke", "zerofrom", - "zerotrie", "zerovec", ] +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -2120,9 +2146,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" dependencies = [ "icu_normalizer", "icu_properties", @@ -2165,30 +2191,30 @@ dependencies = [ [[package]] name = "index_list" -version = "0.2.16" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f05caee923b644542e92a659bfceb868a4053fb7d4230ef2141931e8b01e91a" +checksum = "fa38453685e5fe724fd23ff6c1a158c1e2ca21ce0c2718fa11e96e70e99fd4de" [[package]] name = "indexmap" -version = "2.10.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" +checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" dependencies = [ "equivalent", - "hashbrown 0.15.4", + "hashbrown 0.15.2", ] [[package]] name = "indicatif" -version = "0.17.12" +version = "0.17.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4adb2ee6ad319a912210a36e56e3623555817bcc877a7e6e8802d1d69c4d8056" +checksum = "183b3088984b400f4cfac3620d5e076c84da5364016b4f49473de574b2586235" dependencies = [ "console", + "number_prefix", "portable-atomic", "unicode-width", - "unit-prefix", "web-time", ] @@ -2213,7 +2239,7 @@ version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" dependencies = [ - "hermit-abi 0.5.2", + "hermit-abi 0.5.0", "libc", "windows-sys 0.59.0", ] @@ -2281,11 +2307,10 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "jobserver" -version = "0.1.33" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" dependencies = [ - "getrandom 0.3.3", "libc", ] @@ -2331,9 +2356,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.174" +version = "0.2.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" +checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" [[package]] name = "libloading" @@ -2342,16 +2367,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" dependencies = [ "cfg-if", - "windows-targets 0.53.2", + "windows-targets 0.52.6", ] [[package]] name = "libredox" -version = "0.1.4" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1580801010e535496706ba011c15f8532df6b42297d2e471fec38ceadd8c0638" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "libc", "redox_syscall", ] @@ -2418,9 +2443,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.9.4" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" +checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413" [[package]] name = "lite-coverage" @@ -2451,9 +2476,9 @@ dependencies = [ [[package]] name = "litemap" -version = "0.8.0" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" +checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" [[package]] name = "litesvm" @@ -2603,9 +2628,9 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.13" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -2617,12 +2642,6 @@ version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" -[[package]] -name = "lru-slab" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" - [[package]] name = "lz4" version = "1.28.1" @@ -2653,9 +2672,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.5" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memmap2" @@ -2711,22 +2730,22 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.8.9" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" dependencies = [ "adler2", ] [[package]] name = "mio" -version = "1.0.4" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ "libc", - "wasi 0.11.1+wasi-snapshot-preview1", - "windows-sys 0.59.0", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.52.0", ] [[package]] @@ -2783,7 +2802,7 @@ version = "2.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55740c4ae1d8696773c78fdafd5d0e5fe9bc9f1b071c7ba493ba5c413a9184f3" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "ctor", "napi-derive", "napi-sys", @@ -2792,9 +2811,9 @@ dependencies = [ [[package]] name = "napi-build" -version = "2.2.2" +version = "2.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fff539e61c5e3dd4d7d283610662f5d672c2aea0f158df78af694f13dbb3287b" +checksum = "e28acfa557c083f6e254a786e01ba253fc56f18ee000afcd4f79af735f73a6da" [[package]] name = "napi-derive" @@ -2807,7 +2826,7 @@ dependencies = [ "napi-derive-backend", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.100", ] [[package]] @@ -2822,7 +2841,7 @@ dependencies = [ "quote", "regex", "semver", - "syn 2.0.104", + "syn 2.0.100", ] [[package]] @@ -2840,7 +2859,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "cfg-if", "cfg_aliases", "libc", @@ -2944,7 +2963,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.100", ] [[package]] @@ -2990,36 +3009,41 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.17.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.5.2", + "hermit-abi 0.3.9", "libc", ] [[package]] name = "num_enum" -version = "0.7.4" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a973b4e44ce6cad84ce69d797acf9a044532e4184c4f267913d1b546a0727b7a" +checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" dependencies = [ "num_enum_derive", - "rustversion", ] [[package]] name = "num_enum_derive" -version = "0.7.4" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d" +checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ "proc-macro-crate 3.3.0", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.100", ] +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + [[package]] name = "object" version = "0.36.7" @@ -3044,12 +3068,6 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" -[[package]] -name = "once_cell_polyfill" -version = "1.70.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" - [[package]] name = "oorandom" version = "11.1.5" @@ -3064,11 +3082,11 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.73" +version = "0.10.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" +checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "cfg-if", "foreign-types", "libc", @@ -3085,7 +3103,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.100", ] [[package]] @@ -3096,18 +3114,18 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-src" -version = "300.5.0+3.5.0" +version = "300.4.2+3.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8ce546f549326b0e6052b649198487d91320875da901e7bd11a06d1ee3f9c2f" +checksum = "168ce4e058f975fe43e89d9ccf78ca668601887ae736090aacc23ae353c298e2" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.109" +version = "0.9.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571" +checksum = "8bb61ea9811cc39e3c2069f40b8b8e2e70d8569b361f879786cc7ed48b777cdd" dependencies = [ "cc", "libc", @@ -3149,9 +3167,9 @@ checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" -version = "0.12.4" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -3159,9 +3177,9 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.11" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", @@ -3226,7 +3244,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.100", ] [[package]] @@ -3289,18 +3307,9 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" - -[[package]] -name = "potential_utf" -version = "0.1.2" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" -dependencies = [ - "zerovec", -] +checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" [[package]] name = "powerfmt" @@ -3314,7 +3323,7 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ - "zerocopy", + "zerocopy 0.8.24", ] [[package]] @@ -3388,9 +3397,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.95" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" dependencies = [ "unicode-ident", ] @@ -3412,29 +3421,29 @@ checksum = "9e2e25ee72f5b24d773cae88422baddefff7714f97aab68d96fe2b6fc4a28fb2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.100", ] [[package]] name = "quanta" -version = "0.12.6" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3ab5a9d756f0d97bdc89019bd2e4ea098cf9cde50ee7564dde6b81ccc8f06c7" +checksum = "3bd1fe6824cea6538803de3ff1bc0cf3949024db3d43c9643024bfb33a807c0e" dependencies = [ "crossbeam-utils", "libc", "once_cell", "raw-cpuid", - "wasi 0.11.1+wasi-snapshot-preview1", + "wasi 0.11.0+wasi-snapshot-preview1", "web-sys", "winapi", ] [[package]] name = "quinn" -version = "0.11.8" +version = "0.11.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "626214629cda6781b6dc1d316ba307189c85ba657213ce642d9c77670f8202c8" +checksum = "c3bd15a6f2967aef83887dcb9fec0014580467e33720d073560cf015a5683012" dependencies = [ "bytes", "cfg_aliases", @@ -3442,7 +3451,7 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash", - "rustls 0.23.28", + "rustls 0.23.25", "socket2", "thiserror 2.0.12", "tokio", @@ -3452,18 +3461,16 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.12" +version = "0.11.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49df843a9161c85bb8aae55f101bc0bac8bcafd637a620d9122fd7e0b2f7422e" +checksum = "b820744eb4dc9b57a3398183639c511b5a26d2ed702cedd3febaa1393caa22cc" dependencies = [ "bytes", - "fastbloom", - "getrandom 0.3.3", - "lru-slab", - "rand 0.9.1", + "getrandom 0.3.2", + "rand 0.9.0", "ring", "rustc-hash", - "rustls 0.23.28", + "rustls 0.23.25", "rustls-pki-types", "rustls-platform-verifier", "slab", @@ -3475,9 +3482,9 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.13" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcebb1209ee276352ef14ff8732e24cc2b02bbac986cd74a4c81bcb2f9881970" +checksum = "541d0f57c6ec747a90738a52741d3221f7960e8ac2f0ff4b1a63680e033b4ab5" dependencies = [ "cfg_aliases", "libc", @@ -3498,9 +3505,9 @@ dependencies = [ [[package]] name = "r-efi" -version = "5.3.0" +version = "5.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" [[package]] name = "rand" @@ -3528,12 +3535,13 @@ dependencies = [ [[package]] name = "rand" -version = "0.9.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" +checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.3", + "zerocopy 0.8.24", ] [[package]] @@ -3581,7 +3589,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.15", ] [[package]] @@ -3590,7 +3598,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.3.2", ] [[package]] @@ -3617,7 +3625,7 @@ version = "11.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6df7ab838ed27997ba19a4664507e6f82b41fe6e20be42929332156e5e85146" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", ] [[package]] @@ -3642,11 +3650,11 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.13" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6" +checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", ] [[package]] @@ -3727,7 +3735,7 @@ dependencies = [ "system-configuration", "tokio", "tokio-rustls", - "tokio-util 0.7.15", + "tokio-util 0.7.14", "tower-service", "url", "wasm-bindgen", @@ -3760,7 +3768,7 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.16", + "getrandom 0.2.15", "libc", "untrusted", "windows-sys 0.52.0", @@ -3768,9 +3776,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.25" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" @@ -3798,11 +3806,11 @@ dependencies = [ [[package]] name = "rustix" -version = "1.0.7" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" +checksum = "e56a18552996ac8d29ecc3b190b4fdbb2d91ca4ec396de7bbffaf43f3d637e96" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "errno", "libc", "linux-raw-sys", @@ -3823,14 +3831,14 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.28" +version = "0.23.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7160e3e10bf4535308537f3c4e1641468cd0e485175d6163087c0393c7d46643" +checksum = "822ee9188ac4ec04a2f0531e55d035fb2de73f18b41a63c70c2712503b6fb13c" dependencies = [ "once_cell", "ring", "rustls-pki-types", - "rustls-webpki 0.103.3", + "rustls-webpki 0.103.1", "subtle", "zeroize", ] @@ -3858,32 +3866,31 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.12.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" dependencies = [ "web-time", - "zeroize", ] [[package]] name = "rustls-platform-verifier" -version = "0.5.3" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19787cda76408ec5404443dc8b31795c87cd8fec49762dc75fa727740d34acc1" +checksum = "4a5467026f437b4cb2a533865eaa73eb840019a0916f4b9ec563c6e617e086c9" dependencies = [ - "core-foundation 0.10.1", + "core-foundation 0.10.0", "core-foundation-sys", "jni", "log", "once_cell", - "rustls 0.23.28", + "rustls 0.23.25", "rustls-native-certs", "rustls-platform-verifier-android", - "rustls-webpki 0.103.3", + "rustls-webpki 0.103.1", "security-framework", "security-framework-sys", - "webpki-root-certs 0.26.11", + "webpki-root-certs", "windows-sys 0.59.0", ] @@ -3905,9 +3912,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.3" +version = "0.103.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4a72fe2bcf7a6ac6fd7d0b9e5cb68aeb7d4c0a0271730218b3e92d43b4eb435" +checksum = "fef8b8769aaccf73098557a87cd1816b4f9c7c16811c9c77142aa695c16f2c03" dependencies = [ "ring", "rustls-pki-types", @@ -3916,9 +3923,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.21" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" +checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" [[package]] name = "ryu" @@ -3926,15 +3933,6 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" -[[package]] -name = "safe_arch" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b02de82ddbe1b636e6170c21be622223aea188ef2e139be0a5b219ec215323" -dependencies = [ - "bytemuck", -] - [[package]] name = "same-file" version = "1.0.6" @@ -3975,8 +3973,8 @@ version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316" dependencies = [ - "bitflags 2.9.1", - "core-foundation 0.10.1", + "bitflags 2.9.0", + "core-foundation 0.10.0", "core-foundation-sys", "libc", "security-framework-sys", @@ -4042,7 +4040,7 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.100", ] [[package]] @@ -4071,9 +4069,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.13.0" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf65a400f8f66fb7b0552869ad70157166676db75ed8181f8104ea91cf9d0b42" +checksum = "d6b6f7f2fcb69f747921f79f3926bd1e203fce4fef62c268dd3abfb6d86029aa" dependencies = [ "serde", "serde_derive", @@ -4082,14 +4080,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.13.0" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81679d9ed988d5e9a5e6531dc3f2c28efbd639cbd1dfb628df08edea6004da77" +checksum = "8d00caa5193a3c8362ac2b73be6b9e768aa5a4b2f721d8f4b339600c3cb51f8e" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.100", ] [[package]] @@ -4118,9 +4116,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.9" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", @@ -4154,9 +4152,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" -version = "1.4.5" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] @@ -4173,12 +4171,6 @@ version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" -[[package]] -name = "siphasher" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" - [[package]] name = "sized-chunks" version = "0.6.5" @@ -4191,21 +4183,24 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.10" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] [[package]] name = "smallvec" -version = "1.15.1" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" [[package]] name = "socket2" -version = "0.5.10" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef" dependencies = [ "libc", "windows-sys 0.52.0", @@ -4852,9 +4847,9 @@ dependencies = [ [[package]] name = "solana-decode-error" -version = "2.3.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c781686a18db2f942e70913f7ca15dc120ec38dcab42ff7557db2c70c625a35" +checksum = "10a6a6383af236708048f8bd8d03db8ca4ff7baf4a48e5d580f4cce545925470" dependencies = [ "num-traits", ] @@ -4878,9 +4873,9 @@ dependencies = [ [[package]] name = "solana-ed25519-program" -version = "2.2.3" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1feafa1691ea3ae588f99056f4bdd1293212c7ece28243d7da257c443e84753" +checksum = "0c0c4dfce08d71d8f1e9b7d1b4e2c7101a8109903ad481acbbc1119a73d459f2" dependencies = [ "bytemuck", "bytemuck_derive", @@ -4921,7 +4916,7 @@ version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96c5fd2662ae7574810904585fd443545ed2b568dbd304b25a31e79ccc76e81b" dependencies = [ - "siphasher 0.3.11", + "siphasher", "solana-hash", "solana-pubkey", ] @@ -5114,7 +5109,7 @@ checksum = "9ce496a475e5062ba5de97215ab39d9c358f9c9df4bb7f3a45a1f1a8bd9065ed" dependencies = [ "bincode", "borsh 1.5.7", - "getrandom 0.2.16", + "getrandom 0.2.15", "js-sys", "num-traits", "serde", @@ -5130,7 +5125,7 @@ version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "427f2d0d6dc0bb49f16cef5e7f975180d2e80aab9bdd3b2af68e2d029ec63f43" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", "solana-account-info", "solana-instruction", "solana-program-error", @@ -5426,7 +5421,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "004f2d2daf407b3ec1a1ca5ec34b3ccdfd6866dd2d3c7d0715004a96e4b6d127" dependencies = [ "bincode", - "bitflags 2.9.1", + "bitflags 2.9.0", "cfg_eval", "serde", "serde_derive", @@ -5489,9 +5484,9 @@ dependencies = [ [[package]] name = "solana-precompile-error" -version = "2.2.2" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d87b2c1f5de77dfe2b175ee8dd318d196aaca4d0f66f02842f80c852811f9f8" +checksum = "4ff64daa2933c22982b323d88d0cdf693201ef56ac381ae16737fd5f579e07d6" dependencies = [ "num-traits", "solana-decode-error", @@ -5539,7 +5534,7 @@ dependencies = [ "bytemuck", "console_error_panic_hook", "console_log", - "getrandom 0.2.16", + "getrandom 0.2.15", "lazy_static", "log", "memoffset", @@ -5619,9 +5614,9 @@ dependencies = [ [[package]] name = "solana-program-error" -version = "2.2.2" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ee2e0217d642e2ea4bee237f37bd61bb02aec60da3647c48ff88f6556ade775" +checksum = "d8ae2c1a8d0d4ae865882d5770a7ebca92bab9c685e43f0461682c6c05a35bfa" dependencies = [ "borsh 1.5.7", "num-traits", @@ -5748,7 +5743,7 @@ dependencies = [ "bytemuck_derive", "curve25519-dalek 4.1.3", "five8_const", - "getrandom 0.2.16", + "getrandom 0.2.15", "js-sys", "num-traits", "rand 0.8.5", @@ -5803,7 +5798,7 @@ dependencies = [ "log", "quinn", "quinn-proto", - "rustls 0.23.28", + "rustls 0.23.25", "solana-connection-cache", "solana-keypair", "solana-measure", @@ -5881,9 +5876,9 @@ dependencies = [ [[package]] name = "solana-reserved-account-keys" -version = "2.2.2" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4b22ea19ca2a3f28af7cd047c914abf833486bf7a7c4a10fc652fff09b385b1" +checksum = "2b293f4246626c0e0a991531f08848a713ada965612e99dc510963f04d12cae7" dependencies = [ "lazy_static", "solana-feature-set", @@ -6206,7 +6201,7 @@ dependencies = [ "bs58", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.100", ] [[package]] @@ -6241,9 +6236,9 @@ dependencies = [ [[package]] name = "solana-secp256r1-program" -version = "2.2.3" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf903cbdc36a161533812f90acfccdb434ed48982bd5dd71f3217930572c4a80" +checksum = "c9ea9282950921611bd9e0200da7236fbb1d4f8388942f8451bd55e9f3cb228f" dependencies = [ "bytemuck", "openssl", @@ -6276,7 +6271,7 @@ checksum = "36187af2324f079f65a675ec22b31c24919cb4ac22c79472e85d819db9bbbc15" dependencies = [ "hmac 0.12.1", "pbkdf2", - "sha2 0.10.9", + "sha2 0.10.8", ] [[package]] @@ -6333,7 +6328,7 @@ version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0037386961c0d633421f53560ad7c80675c0447cba4d1bb66d60974dd486c7ea" dependencies = [ - "sha2 0.10.9", + "sha2 0.10.8", "solana-define-syscall", "solana-hash", ] @@ -6494,7 +6489,7 @@ dependencies = [ "quinn", "quinn-proto", "rand 0.8.5", - "rustls 0.23.28", + "rustls 0.23.25", "smallvec", "socket2", "solana-keypair", @@ -6513,7 +6508,7 @@ dependencies = [ "solana-transaction-metrics-tracker", "thiserror 2.0.12", "tokio", - "tokio-util 0.7.15", + "tokio-util 0.7.14", "x509-parser", ] @@ -6741,7 +6736,7 @@ version = "2.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec21c6c242ee93642aa50b829f5727470cdbdf6b461fb7323fe4bc31d1b54c08" dependencies = [ - "rustls 0.23.28", + "rustls 0.23.25", "solana-keypair", "solana-pubkey", "solana-signer", @@ -7165,7 +7160,7 @@ checksum = "d9e8418ea6269dcfb01c712f0444d2c75542c04448b480e87de59d2865edc750" dependencies = [ "quote", "spl-discriminator-syn", - "syn 2.0.104", + "syn 2.0.100", ] [[package]] @@ -7176,8 +7171,8 @@ checksum = "8c1f05593b7ca9eac7caca309720f2eafb96355e037e6d373b909a80fe7b69b9" dependencies = [ "proc-macro2", "quote", - "sha2 0.10.9", - "syn 2.0.104", + "sha2 0.10.8", + "syn 2.0.100", "thiserror 1.0.69", ] @@ -7249,8 +7244,8 @@ checksum = "e6d375dd76c517836353e093c2dbb490938ff72821ab568b545fd30ab3256b3e" dependencies = [ "proc-macro2", "quote", - "sha2 0.10.9", - "syn 2.0.104", + "sha2 0.10.8", + "syn 2.0.100", ] [[package]] @@ -7503,9 +7498,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.104" +version = "2.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" dependencies = [ "proc-macro2", "quote", @@ -7532,13 +7527,13 @@ dependencies = [ [[package]] name = "synstructure" -version = "0.13.2" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.100", ] [[package]] @@ -7619,12 +7614,12 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.20.0" +version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" +checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf" dependencies = [ "fastrand", - "getrandom 0.3.3", + "getrandom 0.3.2", "once_cell", "rustix", "windows-sys 0.59.0", @@ -7651,7 +7646,7 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7f46083d221181166e5b6f6b1e5f1d499f3a76888826e6cb1d057554157cd0f" dependencies = [ - "env_logger 0.11.8", + "env_logger 0.11.7", "test-log-macros", "tracing-subscriber", ] @@ -7664,7 +7659,7 @@ checksum = "888d0c3c6db53c0fdab160d2ed5e12ba745383d3e85813f2ea0f2b1475ab553f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.100", ] [[package]] @@ -7693,7 +7688,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.100", ] [[package]] @@ -7704,16 +7699,17 @@ checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.100", ] [[package]] name = "thread_local" -version = "1.1.9" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" dependencies = [ "cfg-if", + "once_cell", ] [[package]] @@ -7749,9 +7745,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.8.1" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" dependencies = [ "displaydoc", "zerovec", @@ -7808,7 +7804,7 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.100", ] [[package]] @@ -7880,9 +7876,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.15" +version = "0.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66a539a9ad6d5d281510d5bd368c973d636c02dbf8a67300bfb6b950696ad7df" +checksum = "6b9590b93e6fcc1739458317cccd391ad3955e2bde8913edf6f95f9e65a8f034" dependencies = [ "bytes", "futures-core", @@ -7902,15 +7898,15 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.11" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" [[package]] name = "toml_edit" -version = "0.22.27" +version = "0.22.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" dependencies = [ "indexmap", "toml_datetime", @@ -7937,20 +7933,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.30" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.100", ] [[package]] name = "tracing-core" -version = "0.1.34" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", "valuable", @@ -8050,9 +8046,9 @@ checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-width" -version = "0.2.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" [[package]] name = "unicode-xid" @@ -8060,12 +8056,6 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" -[[package]] -name = "unit-prefix" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "323402cff2dd658f39ca17c789b502021b3f18707c91cdf22e3838e1b4023817" - [[package]] name = "universal-hash" version = "0.5.1" @@ -8118,6 +8108,12 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + [[package]] name = "utf8_iter" version = "1.0.4" @@ -8181,9 +8177,9 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "wasi" -version = "0.11.1+wasi-snapshot-preview1" +version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasi" @@ -8216,7 +8212,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.100", "wasm-bindgen-shared", ] @@ -8251,7 +8247,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.100", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -8287,18 +8283,9 @@ dependencies = [ [[package]] name = "webpki-root-certs" -version = "0.26.11" +version = "0.26.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75c7f0ef91146ebfb530314f5f1d24528d7f0767efbfd31dce919275413e393e" -dependencies = [ - "webpki-root-certs 1.0.1", -] - -[[package]] -name = "webpki-root-certs" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86138b15b2b7d561bc4469e77027b8dd005a43dc502e9031d1f5afc8ce1f280e" +checksum = "09aed61f5e8d2c18344b3faa33a4c837855fe56642757754775548fee21386c4" dependencies = [ "rustls-pki-types", ] @@ -8318,16 +8305,6 @@ version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" -[[package]] -name = "wide" -version = "0.7.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ce5da8ecb62bcd8ec8b7ea19f69a51275e91299be594ea5cc6ef7819e16cd03" -dependencies = [ - "bytemuck", - "safe_arch", -] - [[package]] name = "winapi" version = "0.3.9" @@ -8361,62 +8338,18 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-core" -version = "0.61.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" -dependencies = [ - "windows-implement", - "windows-interface", - "windows-link", - "windows-result", - "windows-strings", -] - -[[package]] -name = "windows-implement" -version = "0.60.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.104", -] - -[[package]] -name = "windows-interface" -version = "0.59.1" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.104", + "windows-targets 0.52.6", ] [[package]] name = "windows-link" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" - -[[package]] -name = "windows-result" -version = "0.3.4" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-strings" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" -dependencies = [ - "windows-link", -] +checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" [[package]] name = "windows-sys" @@ -8454,15 +8387,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.2", -] - [[package]] name = "windows-targets" version = "0.42.2" @@ -8502,29 +8426,13 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", + "windows_i686_gnullvm", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", "windows_x86_64_msvc 0.52.6", ] -[[package]] -name = "windows-targets" -version = "0.53.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef" -dependencies = [ - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", -] - [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -8543,12 +8451,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" - [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -8567,12 +8469,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" - [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -8591,24 +8487,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" -[[package]] -name = "windows_i686_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" - [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" - [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -8627,12 +8511,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_i686_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" - [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -8651,12 +8529,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" - [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" @@ -8675,12 +8547,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" - [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -8699,17 +8565,11 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" - [[package]] name = "winnow" -version = "0.7.11" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74c7b26e3480b707944fc872477815d29a8e429d2f93a1ce000f5fa84a15cbcd" +checksum = "0e97b544156e9bebe1a0ffbc03484fc1ffe3100cbce3ffb17eac35f7cdd7ab36" dependencies = [ "memchr", ] @@ -8730,14 +8590,20 @@ version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.9.0", ] +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + [[package]] name = "writeable" -version = "0.6.1" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" [[package]] name = "x509-parser" @@ -8759,9 +8625,9 @@ dependencies = [ [[package]] name = "xattr" -version = "1.5.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af3a19837351dc82ba89f8a125e22a3c475f05aba604acc023d62b2739ae2909" +checksum = "0d65cbf2f12c15564212d48f4e3dfb87923d25d611f2aed18f4cb23f0413d89e" dependencies = [ "libc", "rustix", @@ -8769,9 +8635,9 @@ dependencies = [ [[package]] name = "yoke" -version = "0.8.0" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" dependencies = [ "serde", "stable_deref_trait", @@ -8781,34 +8647,54 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.0" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", - "synstructure 0.13.2", + "syn 2.0.100", + "synstructure 0.13.1", ] [[package]] name = "zerocopy" -version = "0.8.26" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "zerocopy-derive 0.7.35", +] + +[[package]] +name = "zerocopy" +version = "0.8.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" +dependencies = [ + "zerocopy-derive 0.8.24", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ - "zerocopy-derive", + "proc-macro2", + "quote", + "syn 2.0.100", ] [[package]] name = "zerocopy-derive" -version = "0.8.26" +version = "0.8.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.100", ] [[package]] @@ -8828,8 +8714,8 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", - "synstructure 0.13.2", + "syn 2.0.100", + "synstructure 0.13.1", ] [[package]] @@ -8849,25 +8735,14 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", -] - -[[package]] -name = "zerotrie" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", + "syn 2.0.100", ] [[package]] name = "zerovec" -version = "0.11.2" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" dependencies = [ "yoke", "zerofrom", @@ -8876,13 +8751,13 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.1" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.100", ] [[package]] From 5939de80d3979476de1ac3b9b9cc004834af9c09 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Tue, 1 Jul 2025 09:24:27 +0300 Subject: [PATCH 26/86] Start using the solana-program-test cov branch. --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9c035320..36f6460c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5697,7 +5697,7 @@ dependencies = [ [[package]] name = "solana-program-test" version = "2.2.4" -source = "git+ssh://git@github.com/vlady-kotsev/program-test.git#06de41f1dce54e1cbef0d7bd5860dffebf035eb3" +source = "git+ssh://git@github.com/vlady-kotsev/program-test.git?branch=cov#01aff425901bad4972a9cb74c8f9890f8b6bba63" dependencies = [ "assert_matches", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index 5a33827b..12c0aa05 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,7 +60,7 @@ solana-program-option = "2.2" solana-program-pack = "2.2" solana-program-runtime = ">=2.2,<=2.2.4" #solana-program-test = "2.2" -solana-program-test = { git = "ssh://git@github.com/vlady-kotsev/program-test.git" } +solana-program-test = { git = "ssh://git@github.com/vlady-kotsev/program-test.git", branch = "cov" } solana-pubkey = "2.2" solana-rent = "2.2" solana-reserved-account-keys = "2.2" From 5df1851b6ba2dfc621c0fb17159a50c660eb0c2d Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Tue, 1 Jul 2025 11:25:47 +0300 Subject: [PATCH 27/86] Start using the reworks as done for solana-program-stubs --- Cargo.lock | 18 +++++++++--------- Cargo.toml | 2 +- crates/lite-coverage/Cargo.toml | 2 +- crates/lite-coverage/src/stubs.rs | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 36f6460c..54480002 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2459,12 +2459,12 @@ dependencies = [ "lazy_static", "libloading", "serde", - "sol-stubs", "solana-account", "solana-instruction", "solana-keypair", "solana-program", "solana-program-error", + "solana-program-stubs", "solana-program-test", "solana-pubkey", "solana-sdk-ids", @@ -4206,14 +4206,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "sol-stubs" -version = "0.1.0" -source = "git+ssh://git@github.com/procdump/sol-stubs.git?branch=master#394190d3a700f0420eaca8d220686e948cd78895" -dependencies = [ - "lazy_static", -] - [[package]] name = "solana-account" version = "2.2.1" @@ -5694,6 +5686,14 @@ dependencies = [ "thiserror 2.0.12", ] +[[package]] +name = "solana-program-stubs" +version = "0.1.0" +source = "git+ssh://git@github.com/procdump/sol-stubs.git?branch=master#e232923f5bd1866e7d2e07e678d704c429d32808" +dependencies = [ + "lazy_static", +] + [[package]] name = "solana-program-test" version = "2.2.4" diff --git a/Cargo.toml b/Cargo.toml index 12c0aa05..907d225d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -91,7 +91,7 @@ test-log = "0.2" thiserror = "2.0" tokio = "1.35" lite-coverage = { path = "crates/lite-coverage" } -sol-stubs = { git = "ssh://git@github.com/procdump/sol-stubs.git", branch = "master" } +solana-program-stubs = { git = "ssh://git@github.com/procdump/sol-stubs.git", branch = "master", features = [ "loader_stubs" ] } [profile.bench] debug = true diff --git a/crates/lite-coverage/Cargo.toml b/crates/lite-coverage/Cargo.toml index 0681e4a0..1a4eef74 100644 --- a/crates/lite-coverage/Cargo.toml +++ b/crates/lite-coverage/Cargo.toml @@ -26,4 +26,4 @@ solana-sysvar = { workspace = true } solana-sdk-ids = { workspace = true } tokio = { workspace = true } lazy_static = "1.5.0" -sol-stubs = { workspace = true } +solana-program-stubs = { workspace = true } diff --git a/crates/lite-coverage/src/stubs.rs b/crates/lite-coverage/src/stubs.rs index df31bf63..9a17c799 100644 --- a/crates/lite-coverage/src/stubs.rs +++ b/crates/lite-coverage/src/stubs.rs @@ -1,7 +1,7 @@ use std::sync::{Arc, RwLock}; -use sol_stubs::declare_sol_loader_stubs; use solana_program_error::ProgramResult; +use solana_program_stubs::declare_sol_loader_stubs; use solana_sysvar::program_stubs::SyscallStubs; use solana_instruction::AccountMeta; From 44c6bfdc7580cd5e4137f93e00db8f8823a1344f Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Tue, 1 Jul 2025 15:06:26 +0300 Subject: [PATCH 28/86] start using the latest solana-program-stubs without concrete location of the main types (Instruction, Metadata, Pubkey, SyscallStubs, etc..) --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 54480002..cb7826ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5689,7 +5689,7 @@ dependencies = [ [[package]] name = "solana-program-stubs" version = "0.1.0" -source = "git+ssh://git@github.com/procdump/sol-stubs.git?branch=master#e232923f5bd1866e7d2e07e678d704c429d32808" +source = "git+ssh://git@github.com/procdump/sol-stubs.git?branch=master#17547701a7266fe092a2b1063e5797f0a6b385e9" dependencies = [ "lazy_static", ] From bd646add2374e334670e8e7262ff2721ed96beca Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Fri, 4 Jul 2025 14:09:58 +0300 Subject: [PATCH 29/86] Report some log events respecting env var details passed by anchor. THe idea is to provide caller with information that litesvm is used and hence unleash the coverage stats. --- crates/lite-coverage/src/lite_coverage.rs | 34 ++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/crates/lite-coverage/src/lite_coverage.rs b/crates/lite-coverage/src/lite_coverage.rs index b32c7709..48479afa 100644 --- a/crates/lite-coverage/src/lite_coverage.rs +++ b/crates/lite-coverage/src/lite_coverage.rs @@ -1,3 +1,5 @@ +use std::io::Write; + use solana_keypair::Keypair; use crate::{ @@ -33,7 +35,7 @@ impl LiteCoverage { program_test.prefer_bpf(false); program_test.set_payer(payer); - for (pubkey, name) in additional_programs.into_iter() { + for (pubkey, name) in additional_programs.clone().into_iter() { let name = Box::leak(Box::new(name)); program_test.add_upgradeable_program_to_genesis(name, &pubkey); } @@ -55,6 +57,9 @@ impl LiteCoverage { pt_context }); loader.adjust_stubs()?; + + LiteCoverage::log_anchor_test_event_artifacts(programs.clone(), additional_programs)?; + Ok(Self { pt_context: Arc::new(RefCell::new(pt_context)), programs, @@ -111,4 +116,31 @@ impl LiteCoverage { }); Ok(()) } + + fn log_anchor_test_event_artifacts( + progs: Vec, + additional_progs: Vec, + ) -> LiteCoverageError<()> { + if let Ok(report_events) = std::env::var("ANCHOR_TEST_CODE_COVERAGE_REPORT_EVENTS") { + if report_events == "true" { + if let Ok(event_file) = + std::env::var("ANCHOR_TEST_CODE_COVERAGE_ARTIFACTS_EVENT_FILE") + { + let mut file = std::fs::OpenOptions::new() + .create(true) + .append(true) + .write(true) + .open(format!("{}.{}.log", event_file, std::process::id()))?; + file.write_all("litesvm=true\n".as_bytes())?; + for (pubkey, name, path) in &progs { + file.write_all(format!("{}={},{}\n", name, pubkey, path).as_bytes())?; + } + for (pubkey, name) in &additional_progs { + file.write_all(format!("{}={}\n", name, pubkey).as_bytes())?; + } + } + } + } + Ok(()) + } } From a2b1e33c792bf5ef46df0ed4629be02de08cdd5f Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Tue, 8 Jul 2025 15:50:03 +0300 Subject: [PATCH 30/86] use latest stubs with lamports updated accordingly --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index cb7826ec..9f94ae61 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5689,7 +5689,7 @@ dependencies = [ [[package]] name = "solana-program-stubs" version = "0.1.0" -source = "git+ssh://git@github.com/procdump/sol-stubs.git?branch=master#17547701a7266fe092a2b1063e5797f0a6b385e9" +source = "git+ssh://git@github.com/procdump/sol-stubs.git?branch=master#05243055504ca5fdc0b20694f8bf36a160738a68" dependencies = [ "lazy_static", ] From 8ee63c94afd0bdf45f48e968fd5ddcad1bbb59fd Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Wed, 9 Jul 2025 15:17:58 +0300 Subject: [PATCH 31/86] Silence clippy. --- crates/lite-coverage/src/lite_coverage.rs | 66 +++++++------ crates/lite-coverage/src/loader.rs | 30 +++--- crates/lite-coverage/src/types.rs | 42 ++++++++- crates/litesvm/src/lib.rs | 107 ++++++++-------------- 4 files changed, 131 insertions(+), 114 deletions(-) diff --git a/crates/lite-coverage/src/lite_coverage.rs b/crates/lite-coverage/src/lite_coverage.rs index 48479afa..0a736768 100644 --- a/crates/lite-coverage/src/lite_coverage.rs +++ b/crates/lite-coverage/src/lite_coverage.rs @@ -1,11 +1,11 @@ -use std::io::Write; +use std::{io::Write, rc::Rc}; use solana_keypair::Keypair; use crate::{ loader::{entrypoint, Loader}, types::{LiteCoverageError, NativeProgram}, - AdditionalProgram, + AdditionalProgram, ProgramTestContextHandle, }; use { solana_account::AccountSharedData, @@ -20,8 +20,8 @@ use { #[derive(Clone)] pub struct LiteCoverage { pub programs: Vec, - pub pt_context: Arc>, - rt: Arc>, + pub pt_context: Rc>>, + rt: Arc, } impl LiteCoverage { @@ -46,31 +46,37 @@ impl LiteCoverage { "Adding native program {} with id: {}", program_name, program_id ); - loader.add_program(&so_path, &program_name, &program_id)?; + loader.add_program(so_path, program_name, program_id)?; program_test.add_program(program_name, *program_id, processor!(entrypoint)); } println!("Loaded: {:?}", loader); let rt = tokio::runtime::Runtime::new()?; - let pt_context = rt.block_on(async move { - let pt_context = program_test.start_with_context().await; - pt_context - }); + let pt_context = rt.block_on(async move { program_test.start_with_context().await }); loader.adjust_stubs()?; LiteCoverage::log_anchor_test_event_artifacts(programs.clone(), additional_programs)?; Ok(Self { - pt_context: Arc::new(RefCell::new(pt_context)), + pt_context: Rc::new(RefCell::new(Some(pt_context))), programs, - rt: Arc::new(Box::new(rt)), + rt: Arc::new(rt), }) } + pub fn get_program_test_context(&self) -> ProgramTestContextHandle { + assert!( + self.pt_context.borrow().is_some(), + "ProgramTestContext is already acquired!" + ); + ProgramTestContextHandle::new(Rc::clone(&self.pt_context)) + } + pub fn add_account(&self, account_pubkey: &Pubkey, account_data: &AccountSharedData) { - self.pt_context - .borrow_mut() - .set_account(account_pubkey, account_data); + let mut pt_context = self.get_program_test_context(); + if let Some(ctx) = &mut *pt_context { + ctx.set_account(account_pubkey, account_data); + } } async fn re_sign_tx( @@ -78,18 +84,19 @@ impl LiteCoverage { tx: &VersionedTransaction, ) -> LiteCoverageError { // TODO tx must be resigned for all signers - let payer = &self.pt_context.borrow().payer; - let recent_blockhash = self - .pt_context - .borrow() - .banks_client - .get_latest_blockhash() - .await?; + let pt_context = self.get_program_test_context(); + let ctx = pt_context + .as_ref() + .ok_or(Box::::from( + "Missing ProgramTestContext", + ))?; + let payer = ctx.payer.insecure_clone(); + let recent_blockhash = ctx.banks_client.get_latest_blockhash().await?; let mut trans = tx.clone().into_legacy_transaction().unwrap(); - trans.message.recent_blockhash = recent_blockhash.clone(); - trans.message.account_keys[0] = payer.pubkey().clone(); - trans.sign(&[&payer], recent_blockhash.clone()); + trans.message.recent_blockhash = recent_blockhash; + trans.message.account_keys[0] = payer.pubkey(); + trans.sign(&[&payer], recent_blockhash); Ok(VersionedTransaction::from(trans)) } @@ -104,9 +111,14 @@ impl LiteCoverage { } let re_signed_tx = self.re_sign_tx(&tx).await?; - let res = self - .pt_context - .borrow() + let pt_context = self.get_program_test_context(); + let ctx = + pt_context + .as_ref() + .ok_or(Box::::from( + "Missing ProgramTestContext", + ))?; + let res = ctx .banks_client .process_transaction_with_metadata(re_signed_tx) .await?; diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index 0eae0440..7528394e 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -15,6 +15,11 @@ use std::{ // type ProgramCEntrypoint = unsafe extern "C" fn(input: *mut u8) -> u64; type ProgramRustEntryPoint = unsafe extern "C" fn() -> *const (); type ProgramSetSyscallStubsApi = unsafe extern "C" fn(stubs_api: SyscallStubsApi); +type Entrypoint = for<'a, 'b, 'info, 'c> fn( + &'a Pubkey, + &'b [AccountInfo<'info>], + &'c [u8], +) -> Result<(), ProgramError>; lazy_static::lazy_static! ( pub static ref PROGRAMS_MAP: Mutex>> = Mutex::new(HashMap::new()); @@ -27,7 +32,7 @@ pub fn entrypoint<'info>( ) -> ProgramResult { let map = PROGRAMS_MAP.lock().unwrap(); let entry = map - .get(&*program_id) + .get(program_id) .unwrap() .load(std::sync::atomic::Ordering::Relaxed); let fn_ptr = entry as *const (); @@ -68,7 +73,7 @@ impl Loader { // Now create the C interface so that the solana programs can reach our SYSCALL_STUBS! let stubs_api = SyscallStubsApi::new(); // Pass it to the loaded smart contract! - self.set_syscall_stubs_api(&program_id, stubs_api)?; + self.set_syscall_stubs_api(program_id, stubs_api)?; } Ok(()) } @@ -83,9 +88,9 @@ impl Loader { self.libs .insert(*program_id, (program_name.to_string(), lib)); - let fn_ptr = self.get_rust_entrypoint(&program_id)?; + let fn_ptr = self.get_rust_entrypoint(program_id)?; let mut programs_map = PROGRAMS_MAP.lock().unwrap(); - programs_map.insert(program_id.clone(), AtomicPtr::new(fn_ptr as *mut _)); + programs_map.insert(*program_id, AtomicPtr::new(fn_ptr as *mut _)); Ok(()) } @@ -105,16 +110,7 @@ impl Loader { Ok(()) } - fn get_rust_entrypoint( - &self, - program_id: &Pubkey, - ) -> LiteCoverageError< - for<'a, 'b, 'info, 'c> fn( - &'a Pubkey, - &'b [AccountInfo<'info>], - &'c [u8], - ) -> Result<(), ProgramError>, - > { + fn get_rust_entrypoint(&self, program_id: &Pubkey) -> LiteCoverageError { let func: Symbol = unsafe { self.libs .get(program_id) @@ -123,11 +119,7 @@ impl Loader { .get(b"get_rust_entrypoint")? }; let fn_ptr = unsafe { func() }; - let rust_fn: for<'a, 'b, 'info, 'c> fn( - &'a Pubkey, - &'b [AccountInfo<'info>], - &'c [u8], - ) -> Result<(), ProgramError> = unsafe { std::mem::transmute(fn_ptr) }; + let rust_fn: Entrypoint = unsafe { std::mem::transmute(fn_ptr) }; Ok(rust_fn) } } diff --git a/crates/lite-coverage/src/types.rs b/crates/lite-coverage/src/types.rs index 98ef5710..56319c05 100644 --- a/crates/lite-coverage/src/types.rs +++ b/crates/lite-coverage/src/types.rs @@ -1,8 +1,48 @@ use solana_program::pubkey::Pubkey; -use std::error::Error; +use solana_program_test::ProgramTestContext; +use std::{ + cell::RefCell, + error::Error, + ops::{Deref, DerefMut}, + rc::Rc, +}; pub type LiteCoverageError = Result>; pub type ProgramName = String; pub type Path = String; pub type NativeProgram = (Pubkey, ProgramName, Path); pub type AdditionalProgram = (Pubkey, ProgramName); + +pub struct ProgramTestContextHandle { + ctx: Option, + owner: Rc>>, +} + +impl ProgramTestContextHandle { + pub fn new(owner: Rc>>) -> Self { + // Take the context from the owner + let ctx = owner.take(); + Self { ctx, owner } + } +} + +impl Drop for ProgramTestContextHandle { + fn drop(&mut self) { + // Return the context back to the owner + *self.owner.borrow_mut() = self.ctx.take(); + } +} + +impl Deref for ProgramTestContextHandle { + type Target = Option; + + fn deref(&self) -> &Self::Target { + &self.ctx + } +} + +impl DerefMut for ProgramTestContextHandle { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.ctx + } +} diff --git a/crates/litesvm/src/lib.rs b/crates/litesvm/src/lib.rs index bf68ade6..194bd81d 100644 --- a/crates/litesvm/src/lib.rs +++ b/crates/litesvm/src/lib.rs @@ -976,9 +976,9 @@ impl LiteSVM { println!("ORIGINAL TX DONE"); - tx_lite_coverage().map(|tx_copy| { + if let Some(tx_copy) = tx_lite_coverage() { self.send_transaction_lite_coverage(tx_copy); - }); + } if let Err(err) = self.check_accounts_rent(tx, &context) { tx_result = Err(err); @@ -997,80 +997,53 @@ impl LiteSVM { } fn send_transaction_lite_coverage(&self, tx: SanitizedTransaction) { - self.lite_coverage.as_ref().map(|lite_coverage| { + if let Some(lite_coverage) = self.lite_coverage.as_ref() { // Sync Sysvars self.sync_sysvars_with_lite_coverage(); // Sync Accounts let tx_accounts = self.collect_accounts_for_lite_coverage(&tx); let _ = lite_coverage.send_transaction(tx.to_versioned_transaction(), &tx_accounts); - }); + } } fn sync_sysvars_with_lite_coverage(&self) { - self.lite_coverage.as_ref().map(|lite_coverage| { - let clock_sysvar = self.get_sysvar::(); - lite_coverage - .pt_context - .borrow_mut() - .set_sysvar(&clock_sysvar); - - let epoch_schedule_sysvar = self.get_sysvar::(); - lite_coverage - .pt_context - .borrow_mut() - .set_sysvar(&epoch_schedule_sysvar); - - #[allow(deprecated)] - let fees_sysvar = self.get_sysvar::(); - lite_coverage - .pt_context - .borrow_mut() - .set_sysvar(&fees_sysvar); - - let rent_sysvar = self.get_sysvar::(); - lite_coverage - .pt_context - .borrow_mut() - .set_sysvar(&rent_sysvar); - - let epoch_rewards_sysvar = self.get_sysvar::(); - lite_coverage - .pt_context - .borrow_mut() - .set_sysvar(&epoch_rewards_sysvar); - - #[allow(deprecated)] - let recent_blockhashes_sysvar = self.get_sysvar::(); - lite_coverage - .pt_context - .borrow_mut() - .set_sysvar(&recent_blockhashes_sysvar); - - let slot_hashed_sysvar = self.get_sysvar::(); - lite_coverage - .pt_context - .borrow_mut() - .set_sysvar(&slot_hashed_sysvar); - - let slot_history_sysvar = self.get_sysvar::(); - lite_coverage - .pt_context - .borrow_mut() - .set_sysvar(&slot_history_sysvar); - - let stake_history_sysvar = self.get_sysvar::(); - lite_coverage - .pt_context - .borrow_mut() - .set_sysvar(&stake_history_sysvar); - - let last_restart_slot_sysvar = self.get_sysvar::(); - lite_coverage - .pt_context - .borrow_mut() - .set_sysvar(&last_restart_slot_sysvar); - }); + if let Some(lite_coverage) = self.lite_coverage.as_ref() { + let pt_context = lite_coverage.get_program_test_context(); + if let Some(ctx) = &*pt_context { + let clock_sysvar = self.get_sysvar::(); + ctx.set_sysvar(&clock_sysvar); + + let epoch_schedule_sysvar = self.get_sysvar::(); + ctx.set_sysvar(&epoch_schedule_sysvar); + + #[allow(deprecated)] + let fees_sysvar = self.get_sysvar::(); + ctx.set_sysvar(&fees_sysvar); + + let rent_sysvar = self.get_sysvar::(); + ctx.set_sysvar(&rent_sysvar); + + let epoch_rewards_sysvar = self.get_sysvar::(); + ctx.set_sysvar(&epoch_rewards_sysvar); + + #[allow(deprecated)] + let recent_blockhashes_sysvar = self.get_sysvar::(); + ctx.set_sysvar(&recent_blockhashes_sysvar); + + let slot_hashed_sysvar = self.get_sysvar::(); + ctx.set_sysvar(&slot_hashed_sysvar); + + let slot_history_sysvar = self.get_sysvar::(); + ctx.set_sysvar(&slot_history_sysvar); + + let stake_history_sysvar = self.get_sysvar::(); + ctx.set_sysvar(&stake_history_sysvar); + + let last_restart_slot_sysvar = self.get_sysvar::(); + ctx.set_sysvar(&last_restart_slot_sysvar); + } + } } fn collect_accounts_for_lite_coverage( From c23fe556d8bab7e55bc5b502bf0257e0bab4d2b6 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Wed, 9 Jul 2025 16:12:05 +0300 Subject: [PATCH 32/86] Use latest stubs --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 9f94ae61..4cc69e77 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5689,7 +5689,7 @@ dependencies = [ [[package]] name = "solana-program-stubs" version = "0.1.0" -source = "git+ssh://git@github.com/procdump/sol-stubs.git?branch=master#05243055504ca5fdc0b20694f8bf36a160738a68" +source = "git+ssh://git@github.com/procdump/sol-stubs.git?branch=master#143d0ee25a36f1d1f986614de174a54a8554259c" dependencies = [ "lazy_static", ] From eb0982c316f8257343317f2e02ecc137fc7f12cf Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Mon, 14 Jul 2025 09:57:51 +0300 Subject: [PATCH 33/86] Initial commit adapting pinocchio programs. Moreover the entrypoint logic is unified. Still messy - let's clean up next --- Cargo.lock | 5 +- Cargo.toml | 1 + crates/lite-coverage/Cargo.toml | 2 + crates/lite-coverage/src/loader.rs | 176 +++++++++++++++++++++++++---- crates/litesvm/Cargo.toml | 1 + 5 files changed, 159 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4cc69e77..4590595c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2460,9 +2460,11 @@ dependencies = [ "libloading", "serde", "solana-account", + "solana-bpf-loader-program", "solana-instruction", "solana-keypair", "solana-program", + "solana-program-entrypoint", "solana-program-error", "solana-program-stubs", "solana-program-test", @@ -2524,6 +2526,7 @@ dependencies = [ "solana-nonce", "solana-nonce-account", "solana-precompiles", + "solana-program-entrypoint", "solana-program-error", "solana-program-option", "solana-program-pack", @@ -5697,7 +5700,7 @@ dependencies = [ [[package]] name = "solana-program-test" version = "2.2.4" -source = "git+ssh://git@github.com/vlady-kotsev/program-test.git?branch=cov#01aff425901bad4972a9cb74c8f9890f8b6bba63" +source = "git+ssh://git@github.com/vlady-kotsev/program-test.git?branch=cov#4c23a39b9a2ad60494ac5b5da1c8dfb699c855ed" dependencies = [ "assert_matches", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index 907d225d..17f01fce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -56,6 +56,7 @@ solana-nonce-account = "2.2" solana-precompiles = "2.2" solana-program = "2.2" solana-program-error = "2.2" +solana-program-entrypoint = "2.2" solana-program-option = "2.2" solana-program-pack = "2.2" solana-program-runtime = ">=2.2,<=2.2.4" diff --git a/crates/lite-coverage/Cargo.toml b/crates/lite-coverage/Cargo.toml index 1a4eef74..c6e32c77 100644 --- a/crates/lite-coverage/Cargo.toml +++ b/crates/lite-coverage/Cargo.toml @@ -15,6 +15,7 @@ bs58 = { version = "0.5.1", default-features = false } borsh = "1.5.7" solana-program-test = { workspace = true } solana-account = { workspace = true } +solana-bpf-loader-program.workspace = true solana-program = { workspace = true } solana-keypair = { workspace = true } solana-signer = { workspace = true } @@ -22,6 +23,7 @@ solana-transaction = { workspace = true } solana-instruction = { workspace = true } solana-pubkey = { workspace = true } solana-program-error = { workspace = true } +solana-program-entrypoint = { workspace = true } solana-sysvar = { workspace = true } solana-sdk-ids = { workspace = true } tokio = { workspace = true } diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index 7528394e..39af9583 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -2,6 +2,7 @@ use crate::{ stubs::{StubsManager, SyscallStubsApi, UnimplementedSyscallStubs, WrapperSyscallStubs}, types::LiteCoverageError, }; +use core::str; use libloading::{Library, Symbol}; use solana_program::{ account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError, @@ -12,14 +13,8 @@ use std::{ sync::{atomic::AtomicPtr, Mutex}, }; -// type ProgramCEntrypoint = unsafe extern "C" fn(input: *mut u8) -> u64; -type ProgramRustEntryPoint = unsafe extern "C" fn() -> *const (); +type ProgramEntrypoint = unsafe extern "C" fn(input: *mut u8) -> u64; type ProgramSetSyscallStubsApi = unsafe extern "C" fn(stubs_api: SyscallStubsApi); -type Entrypoint = for<'a, 'b, 'info, 'c> fn( - &'a Pubkey, - &'b [AccountInfo<'info>], - &'c [u8], -) -> Result<(), ProgramError>; lazy_static::lazy_static! ( pub static ref PROGRAMS_MAP: Mutex>> = Mutex::new(HashMap::new()); @@ -28,7 +23,7 @@ lazy_static::lazy_static! ( pub fn entrypoint<'info>( program_id: &Pubkey, accounts: &[AccountInfo<'info>], - data: &[u8], + _data: &[u8], ) -> ProgramResult { let map = PROGRAMS_MAP.lock().unwrap(); let entry = map @@ -36,12 +31,123 @@ pub fn entrypoint<'info>( .unwrap() .load(std::sync::atomic::Ordering::Relaxed); let fn_ptr = entry as *const (); - let entry: for<'a, 'b, 'info2, 'c> fn( - &'a Pubkey, - &'b [AccountInfo<'info2>], - &'c [u8], - ) -> ProgramResult = unsafe { std::mem::transmute(fn_ptr) }; - entry(program_id, accounts, data) + let entry: ProgramEntrypoint = unsafe { std::mem::transmute(fn_ptr) }; + + // Serialize entrypoint parameters with SBF ABI + let invoke_context: &solana_program_test::InvokeContext<'_> = + solana_program_test::get_invoke_context() as &_; + let transaction_context = &invoke_context.transaction_context; + let instruction_context = transaction_context + .get_current_instruction_context() + .map_err(|_| ProgramError::InvalidArgument)?; + + let (mut parameter_bytes, _, _) = + solana_bpf_loader_program::serialization::serialize_parameters( + transaction_context, + instruction_context, + true, // copy_account_data // There is no VM so direct mapping can not be implemented here + ) + .map_err(|_| ProgramError::InvalidArgument)?; + + let ix_input_before = parameter_bytes.as_slice().to_vec(); + let res = unsafe { entry(parameter_bytes.as_slice().as_ptr() as *mut _) }; + if ix_input_before != parameter_bytes.as_slice() { + // Deserialize data back into instruction params + let (_, updated_account_infos, _) = unsafe { + solana_program_entrypoint::deserialize( + &mut parameter_bytes.as_slice_mut()[0] as *mut u8, + ) + }; + + // println!( + // "DIFFERENT inputs, is data different: {}", + // data != updated_data + // ); + // Persist the changes + println!( + "accounts.len(): {}, updated_account_infos.len(): {}", + accounts.len(), + updated_account_infos.len() + ); + let _ = std::fs::write( + "/tmp/new_accounts.txt", + format!("{:#?}", updated_account_infos), + ); + // #[allow(clippy::transmute_ptr_to_ptr)] + // #[allow(mutable_transmutes)] + // let accounts = unsafe { std::mem::transmute::<&[AccountInfo<'info>], &mut [AccountInfo<'info>]>(accounts) }; + let len = accounts.len(); + for i in 0..len { + (**accounts[i].lamports.borrow_mut()) = updated_account_infos[i].lamports(); + let new_data = updated_account_infos[i].data.borrow_mut().to_vec(); + let boxed: Box<[u8]> = new_data.into_boxed_slice(); + let leaked = Box::leak(Box::new(boxed)); + *accounts[i].data.borrow_mut() = leaked; + + // unsafe { + // (*accounts)[i].is_signer = updated_account_infos[i].is_signer; + // (*accounts)[i].is_writable = updated_account_infos[i].is_writable; + // (*accounts)[i].executable = updated_account_infos[i].executable; + // (*accounts)[i].rent_epoch = updated_account_infos[i].rent_epoch; + // } + #[allow(clippy::transmute_ptr_to_ptr)] + #[allow(mutable_transmutes)] + let account_info_mut = + unsafe { std::mem::transmute::<&Pubkey, &mut Pubkey>(accounts[i].key) }; + *account_info_mut = *updated_account_infos[i].key; + #[allow(clippy::transmute_ptr_to_ptr)] + #[allow(mutable_transmutes)] + let account_info_mut = + unsafe { std::mem::transmute::<&Pubkey, &mut Pubkey>(accounts[i].owner) }; + *account_info_mut = *updated_account_infos[i].owner; + // #[allow(clippy::transmute_ptr_to_ptr)] + // #[allow(mutable_transmutes)] + // let account_info_mut = + // unsafe { std::mem::transmute::<&u64, &mut u64>(&accounts[i].rent_epoch) }; + // *account_info_mut = updated_account_infos[i].rent_epoch; + // #[allow(clippy::transmute_ptr_to_ptr)] + // #[allow(mutable_transmutes)] + // let account_info_mut = + // unsafe { std::mem::transmute::<&bool, &mut bool>(&accounts[i].is_signer) }; + // *account_info_mut = updated_account_infos[i].is_signer; + // #[allow(clippy::transmute_ptr_to_ptr)] + // #[allow(mutable_transmutes)] + // let account_info_mut = + // unsafe { std::mem::transmute::<&bool, &mut bool>(&accounts[i].is_writable) }; + // *account_info_mut = updated_account_infos[i].is_writable; + // #[allow(clippy::transmute_ptr_to_ptr)] + // #[allow(mutable_transmutes)] + // let account_info_mut = + // unsafe { std::mem::transmute::<&bool, &mut bool>(&accounts[i].executable) }; + // *account_info_mut = updated_account_infos[i].executable; + } + // for (dst, src) in accounts.iter().zip(updated_account_infos.iter()) { + // println!("account {} updated: {}", dst.key, src.key); + + // **dst.lamports.borrow_mut() = src.lamports(); + // { + // let src_data = src.data.borrow_mut(); + // let mut dst_data = dst.data.borrow_mut(); + // println!("NEW LEN: {}, OLD LEN: {}", src_data.len(), dst_data.len()); + + // let _ = std::mem::replace(&mut dst_data, src_data); + // } + // } + + // let _ = std::fs::write("/tmp/old_accounts.txt", format!("{:#02x?}", accounts)); + // let _ = std::fs::write("/tmp/old_data.txt", format!("{:#02x?}", data)); + // let _ = std::fs::write("/tmp/new_data.txt", format!("{:#02x?}", _updated_data)); + // panic!("STOP"); + // // if data != updated_data { + // // let mut_ref_data: &mut [u8] = unsafe { std::mem::transmute(data) }; + // // } + } + + if res == 0 { + Ok(()) + } else { + Err(ProgramError::Custom(res as _)) + } } #[derive(Debug, Default)] @@ -88,9 +194,9 @@ impl Loader { self.libs .insert(*program_id, (program_name.to_string(), lib)); - let fn_ptr = self.get_rust_entrypoint(program_id)?; + let entrypoint = self.get_entrypoint(program_id)?; let mut programs_map = PROGRAMS_MAP.lock().unwrap(); - programs_map.insert(*program_id, AtomicPtr::new(fn_ptr as *mut _)); + programs_map.insert(*program_id, AtomicPtr::new(entrypoint as *mut _)); Ok(()) } @@ -99,27 +205,47 @@ impl Loader { program_id: &Pubkey, stubs_api: SyscallStubsApi, ) -> LiteCoverageError<()> { - let func: Symbol = unsafe { + let res: Result, libloading::Error> = unsafe { self.libs .get(program_id) .ok_or("No such program_id".to_string())? .1 - .get(b"set_stubs")? + .get(b"set_stubs") }; - unsafe { func(stubs_api) }; + match res { + Ok(func) => unsafe { func(stubs_api) }, + Err(e) => { + // REVISIT: The idea behind is this to try working with stubs + // and if not neccesary (as is the case with pinocchio as it + // seems for now) to continue + println!("Can't set stubs, error: {}! Go on", e); + } + } Ok(()) } - fn get_rust_entrypoint(&self, program_id: &Pubkey) -> LiteCoverageError { - let func: Symbol = unsafe { + fn get_entrypoint(&self, program_id: &Pubkey) -> LiteCoverageError { + let entrypoint: Symbol = unsafe { self.libs .get(program_id) .ok_or("No such program_id".to_string())? .1 - .get(b"get_rust_entrypoint")? + .get(b"entrypoint")? }; - let fn_ptr = unsafe { func() }; - let rust_fn: Entrypoint = unsafe { std::mem::transmute(fn_ptr) }; - Ok(rust_fn) + Ok(*entrypoint) } } + +// REVISIT: pinocchio's single syscall impl for now +#[no_mangle] +pub extern "C" fn sol_log_(msg: *const u8, len: u64) { + let message = unsafe { std::slice::from_raw_parts(msg, len as _) }; + let m = str::from_utf8(&message).unwrap(); + crate::stubs::SYSCALL_STUBS.read().unwrap().sol_log(&m); +} + +#[no_mangle] +pub extern "C" fn sol_log_pubkey(_pubkey: *const u8) { + println!("Unimplemented sol_log_pubkey syscall!"); +} +// REVISIT diff --git a/crates/litesvm/Cargo.toml b/crates/litesvm/Cargo.toml index 574fe1d1..a688e998 100644 --- a/crates/litesvm/Cargo.toml +++ b/crates/litesvm/Cargo.toml @@ -48,6 +48,7 @@ solana-nonce.workspace = true solana-nonce-account.workspace = true solana-precompiles.workspace = true solana-program-error.workspace = true +solana-program-entrypoint.workspace = true solana-program-runtime.workspace = true solana-pubkey.workspace = true solana-rent.workspace = true From ee51ead145e29bd7a6efa8b1cf5842246ecbb893 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Mon, 14 Jul 2025 10:37:54 +0300 Subject: [PATCH 34/86] clean up the entrypoint stuff a little bit --- crates/lite-coverage/src/loader.rs | 102 ++++++++--------------------- 1 file changed, 29 insertions(+), 73 deletions(-) diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index 39af9583..c5dae1fe 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -49,98 +49,54 @@ pub fn entrypoint<'info>( ) .map_err(|_| ProgramError::InvalidArgument)?; - let ix_input_before = parameter_bytes.as_slice().to_vec(); let res = unsafe { entry(parameter_bytes.as_slice().as_ptr() as *mut _) }; - if ix_input_before != parameter_bytes.as_slice() { - // Deserialize data back into instruction params - let (_, updated_account_infos, _) = unsafe { - solana_program_entrypoint::deserialize( - &mut parameter_bytes.as_slice_mut()[0] as *mut u8, - ) - }; - // println!( - // "DIFFERENT inputs, is data different: {}", - // data != updated_data - // ); - // Persist the changes - println!( - "accounts.len(): {}, updated_account_infos.len(): {}", - accounts.len(), - updated_account_infos.len() - ); - let _ = std::fs::write( - "/tmp/new_accounts.txt", - format!("{:#?}", updated_account_infos), - ); - // #[allow(clippy::transmute_ptr_to_ptr)] - // #[allow(mutable_transmutes)] - // let accounts = unsafe { std::mem::transmute::<&[AccountInfo<'info>], &mut [AccountInfo<'info>]>(accounts) }; - let len = accounts.len(); - for i in 0..len { + // Deserialize data back into instruction params + let (_, updated_account_infos, _) = unsafe { + solana_program_entrypoint::deserialize(&mut parameter_bytes.as_slice_mut()[0] as *mut u8) + }; + + let len = accounts.len(); + for i in 0..len { + if accounts[i].lamports() != updated_account_infos[i].lamports() { + // Lamports have changed - update. (**accounts[i].lamports.borrow_mut()) = updated_account_infos[i].lamports(); + } + if *accounts[i].data.borrow() != *updated_account_infos[i].data.borrow() { + // Account data has changed - update. let new_data = updated_account_infos[i].data.borrow_mut().to_vec(); let boxed: Box<[u8]> = new_data.into_boxed_slice(); let leaked = Box::leak(Box::new(boxed)); *accounts[i].data.borrow_mut() = leaked; + } - // unsafe { - // (*accounts)[i].is_signer = updated_account_infos[i].is_signer; - // (*accounts)[i].is_writable = updated_account_infos[i].is_writable; - // (*accounts)[i].executable = updated_account_infos[i].executable; - // (*accounts)[i].rent_epoch = updated_account_infos[i].rent_epoch; - // } + // https://github.com/anza-xyz/agave/blob/master/program-test/src/lib.rs#L359 + // NB: https://doc.rust-lang.org/nomicon/transmutes.html + // Transmuting an & to &mut is Undefined Behavior. + // While certain usages may appear safe, note that the Rust + // optimizer is free to assume that a shared reference won't + // change through its lifetime and thus such transmutation will + // run afoul of those assumptions. So: + // - Transmuting an & to &mut is always Undefined Behavior. + // - No you can't do it. + // - No you're not special. + if accounts[i].key != updated_account_infos[i].key { + // Account key has changed - update. #[allow(clippy::transmute_ptr_to_ptr)] #[allow(mutable_transmutes)] let account_info_mut = unsafe { std::mem::transmute::<&Pubkey, &mut Pubkey>(accounts[i].key) }; *account_info_mut = *updated_account_infos[i].key; + } + + if accounts[i].owner != updated_account_infos[i].owner { + // Account owner has changed - update. #[allow(clippy::transmute_ptr_to_ptr)] #[allow(mutable_transmutes)] let account_info_mut = unsafe { std::mem::transmute::<&Pubkey, &mut Pubkey>(accounts[i].owner) }; *account_info_mut = *updated_account_infos[i].owner; - // #[allow(clippy::transmute_ptr_to_ptr)] - // #[allow(mutable_transmutes)] - // let account_info_mut = - // unsafe { std::mem::transmute::<&u64, &mut u64>(&accounts[i].rent_epoch) }; - // *account_info_mut = updated_account_infos[i].rent_epoch; - // #[allow(clippy::transmute_ptr_to_ptr)] - // #[allow(mutable_transmutes)] - // let account_info_mut = - // unsafe { std::mem::transmute::<&bool, &mut bool>(&accounts[i].is_signer) }; - // *account_info_mut = updated_account_infos[i].is_signer; - // #[allow(clippy::transmute_ptr_to_ptr)] - // #[allow(mutable_transmutes)] - // let account_info_mut = - // unsafe { std::mem::transmute::<&bool, &mut bool>(&accounts[i].is_writable) }; - // *account_info_mut = updated_account_infos[i].is_writable; - // #[allow(clippy::transmute_ptr_to_ptr)] - // #[allow(mutable_transmutes)] - // let account_info_mut = - // unsafe { std::mem::transmute::<&bool, &mut bool>(&accounts[i].executable) }; - // *account_info_mut = updated_account_infos[i].executable; } - // for (dst, src) in accounts.iter().zip(updated_account_infos.iter()) { - // println!("account {} updated: {}", dst.key, src.key); - - // **dst.lamports.borrow_mut() = src.lamports(); - // { - // let src_data = src.data.borrow_mut(); - // let mut dst_data = dst.data.borrow_mut(); - // println!("NEW LEN: {}, OLD LEN: {}", src_data.len(), dst_data.len()); - - // let _ = std::mem::replace(&mut dst_data, src_data); - // } - // } - - // let _ = std::fs::write("/tmp/old_accounts.txt", format!("{:#02x?}", accounts)); - // let _ = std::fs::write("/tmp/old_data.txt", format!("{:#02x?}", data)); - // let _ = std::fs::write("/tmp/new_data.txt", format!("{:#02x?}", _updated_data)); - // panic!("STOP"); - // // if data != updated_data { - // // let mut_ref_data: &mut [u8] = unsafe { std::mem::transmute(data) }; - // // } } if res == 0 { From 21147c67a5e7ae05f8989b8dc3d573e9c7cff03a Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Mon, 14 Jul 2025 10:38:35 +0300 Subject: [PATCH 35/86] len -> accounts_len --- crates/lite-coverage/src/loader.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index c5dae1fe..aa1807d5 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -56,8 +56,8 @@ pub fn entrypoint<'info>( solana_program_entrypoint::deserialize(&mut parameter_bytes.as_slice_mut()[0] as *mut u8) }; - let len = accounts.len(); - for i in 0..len { + let accounts_len = accounts.len(); + for i in 0..accounts_len { if accounts[i].lamports() != updated_account_infos[i].lamports() { // Lamports have changed - update. (**accounts[i].lamports.borrow_mut()) = updated_account_infos[i].lamports(); From 3c3319b7dc7c94de48fe7f5d5535a755730c5026 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Mon, 14 Jul 2025 12:53:14 +0300 Subject: [PATCH 36/86] silence clippy warnings --- crates/lite-coverage/src/loader.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index aa1807d5..525d0a19 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -20,11 +20,7 @@ lazy_static::lazy_static! ( pub static ref PROGRAMS_MAP: Mutex>> = Mutex::new(HashMap::new()); ); -pub fn entrypoint<'info>( - program_id: &Pubkey, - accounts: &[AccountInfo<'info>], - _data: &[u8], -) -> ProgramResult { +pub fn entrypoint(program_id: &Pubkey, accounts: &[AccountInfo], _data: &[u8]) -> ProgramResult { let map = PROGRAMS_MAP.lock().unwrap(); let entry = map .get(program_id) @@ -196,8 +192,8 @@ impl Loader { #[no_mangle] pub extern "C" fn sol_log_(msg: *const u8, len: u64) { let message = unsafe { std::slice::from_raw_parts(msg, len as _) }; - let m = str::from_utf8(&message).unwrap(); - crate::stubs::SYSCALL_STUBS.read().unwrap().sol_log(&m); + let m = str::from_utf8(message).unwrap(); + crate::stubs::SYSCALL_STUBS.read().unwrap().sol_log(m); } #[no_mangle] From a321b1716e15c0b54ead538182accc6e8c634e1e Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Mon, 14 Jul 2025 15:22:49 +0300 Subject: [PATCH 37/86] refactor the entrypoint code: - do the updates only if result of instruction is success i.e 0 - instead of transmute grab access to the underlying ptr to the key and owner, cast to *mut u8 and then do the change. Clippy see no issues here, miri however still reports UB. --- crates/lite-coverage/src/loader.rs | 81 ++++++++++++++---------------- 1 file changed, 38 insertions(+), 43 deletions(-) diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index 525d0a19..a0640837 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -46,56 +46,51 @@ pub fn entrypoint(program_id: &Pubkey, accounts: &[AccountInfo], _data: &[u8]) - .map_err(|_| ProgramError::InvalidArgument)?; let res = unsafe { entry(parameter_bytes.as_slice().as_ptr() as *mut _) }; + if res == 0 { + // Deserialize data back into instruction params + let (_, updated_account_infos, _) = unsafe { + solana_program_entrypoint::deserialize( + &mut parameter_bytes.as_slice_mut()[0] as *mut u8, + ) + }; - // Deserialize data back into instruction params - let (_, updated_account_infos, _) = unsafe { - solana_program_entrypoint::deserialize(&mut parameter_bytes.as_slice_mut()[0] as *mut u8) - }; - - let accounts_len = accounts.len(); - for i in 0..accounts_len { - if accounts[i].lamports() != updated_account_infos[i].lamports() { - // Lamports have changed - update. - (**accounts[i].lamports.borrow_mut()) = updated_account_infos[i].lamports(); - } - if *accounts[i].data.borrow() != *updated_account_infos[i].data.borrow() { - // Account data has changed - update. - let new_data = updated_account_infos[i].data.borrow_mut().to_vec(); - let boxed: Box<[u8]> = new_data.into_boxed_slice(); - let leaked = Box::leak(Box::new(boxed)); - *accounts[i].data.borrow_mut() = leaked; - } + let accounts_len = accounts.len(); + for i in 0..accounts_len { + if accounts[i].lamports() != updated_account_infos[i].lamports() { + // Lamports have changed - update. + (**accounts[i].lamports.borrow_mut()) = updated_account_infos[i].lamports(); + } + if *accounts[i].data.borrow() != *updated_account_infos[i].data.borrow() { + // Account data has changed - update. + let new_data = updated_account_infos[i].data.borrow_mut().to_vec(); + let boxed: Box<[u8]> = new_data.into_boxed_slice(); + let leaked = Box::leak(Box::new(boxed)); + *accounts[i].data.borrow_mut() = leaked; + } - // https://github.com/anza-xyz/agave/blob/master/program-test/src/lib.rs#L359 - // NB: https://doc.rust-lang.org/nomicon/transmutes.html - // Transmuting an & to &mut is Undefined Behavior. - // While certain usages may appear safe, note that the Rust - // optimizer is free to assume that a shared reference won't - // change through its lifetime and thus such transmutation will - // run afoul of those assumptions. So: - // - Transmuting an & to &mut is always Undefined Behavior. - // - No you can't do it. - // - No you're not special. - if accounts[i].key != updated_account_infos[i].key { // Account key has changed - update. - #[allow(clippy::transmute_ptr_to_ptr)] - #[allow(mutable_transmutes)] - let account_info_mut = - unsafe { std::mem::transmute::<&Pubkey, &mut Pubkey>(accounts[i].key) }; - *account_info_mut = *updated_account_infos[i].key; - } + let key_mut_ptr = accounts[i].key.as_array().as_ptr() as *mut u8; + updated_account_infos[i] + .key + .as_array() + .iter() + .enumerate() + .for_each(|(i, b)| { + unsafe { *key_mut_ptr.add(i) = *b }; + }); - if accounts[i].owner != updated_account_infos[i].owner { // Account owner has changed - update. - #[allow(clippy::transmute_ptr_to_ptr)] - #[allow(mutable_transmutes)] - let account_info_mut = - unsafe { std::mem::transmute::<&Pubkey, &mut Pubkey>(accounts[i].owner) }; - *account_info_mut = *updated_account_infos[i].owner; + let owner_mut_ptr = accounts[i].owner.as_array().as_ptr() as *mut u8; + updated_account_infos[i] + .owner + .as_array() + .iter() + .enumerate() + .for_each(|(i, b)| { + unsafe { *owner_mut_ptr.add(i) = *b }; + }); } - } - if res == 0 { Ok(()) } else { Err(ProgramError::Custom(res as _)) From 5580a72b7719dc5d3cb59d5bd7d0bd1befa23154 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Mon, 14 Jul 2025 16:10:18 +0300 Subject: [PATCH 38/86] str::from_utf8 requires an unwrap - hence use lossy String variant --- crates/lite-coverage/src/loader.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index a0640837..94d2759c 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -183,12 +183,12 @@ impl Loader { } } -// REVISIT: pinocchio's single syscall impl for now +// REVISIT: pinocchio's syscalls impls are here for now #[no_mangle] pub extern "C" fn sol_log_(msg: *const u8, len: u64) { let message = unsafe { std::slice::from_raw_parts(msg, len as _) }; - let m = str::from_utf8(message).unwrap(); - crate::stubs::SYSCALL_STUBS.read().unwrap().sol_log(m); + let m = String::from_utf8_lossy(message); + crate::stubs::SYSCALL_STUBS.read().unwrap().sol_log(&m); } #[no_mangle] From 5a725b5ee55fe16d246bc0a4494a980fd84afcc7 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Mon, 14 Jul 2025 16:16:54 +0300 Subject: [PATCH 39/86] pinocchio: impl sol_log_pubkey syscall to use solana-program-test's SYSCALL_STUBS --- crates/lite-coverage/src/loader.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index 94d2759c..b20c6358 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -192,7 +192,15 @@ pub extern "C" fn sol_log_(msg: *const u8, len: u64) { } #[no_mangle] -pub extern "C" fn sol_log_pubkey(_pubkey: *const u8) { - println!("Unimplemented sol_log_pubkey syscall!"); +pub extern "C" fn sol_log_pubkey(pubkey: *const u8) { + let pubkey = unsafe { + let mut inner = [0u8; 32]; + std::ptr::copy_nonoverlapping(pubkey, inner.as_mut_ptr(), 32); + Pubkey::new_from_array(inner) + }; + crate::stubs::SYSCALL_STUBS + .read() + .unwrap() + .sol_log(&pubkey.to_string()); } // REVISIT From 03b148b881d852a79f9d00e0d4d3f698cd200417 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Mon, 14 Jul 2025 16:23:28 +0300 Subject: [PATCH 40/86] pinocchio: sol_log_compute_units_, sol_remaining_compute_units --- crates/lite-coverage/src/loader.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index b20c6358..d7416c07 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -191,6 +191,22 @@ pub extern "C" fn sol_log_(msg: *const u8, len: u64) { crate::stubs::SYSCALL_STUBS.read().unwrap().sol_log(&m); } +#[no_mangle] +pub extern "C" fn sol_log_compute_units_() { + crate::stubs::SYSCALL_STUBS + .read() + .unwrap() + .sol_log_compute_units(); +} + +#[no_mangle] +pub extern "C" fn sol_remaining_compute_units() -> u64 { + crate::stubs::SYSCALL_STUBS + .read() + .unwrap() + .sol_remaining_compute_units() +} + #[no_mangle] pub extern "C" fn sol_log_pubkey(pubkey: *const u8) { let pubkey = unsafe { From 8a3028224615827dd1df0a93c5182118546c76cd Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Mon, 14 Jul 2025 16:28:08 +0300 Subject: [PATCH 41/86] pinocchio: sol_memcmp/memset/memmove/memcpy --- crates/lite-coverage/src/loader.rs | 40 ++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index d7416c07..cb0c0e82 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -207,6 +207,46 @@ pub extern "C" fn sol_remaining_compute_units() -> u64 { .sol_remaining_compute_units() } +#[no_mangle] +pub extern "C" fn sol_memcpy_(dst: *mut u8, src: *const u8, n: u64) { + unsafe { + crate::stubs::SYSCALL_STUBS + .read() + .unwrap() + .sol_memcpy(dst, src, n as _); + } +} + +#[no_mangle] +pub extern "C" fn sol_memmove_(dst: *mut u8, src: *const u8, n: u64) { + unsafe { + crate::stubs::SYSCALL_STUBS + .read() + .unwrap() + .sol_memmove(dst, src, n as _); + } +} + +#[no_mangle] +pub extern "C" fn sol_memcmp_(s1: *const u8, s2: *const u8, n: u64, result: *mut i32) { + unsafe { + crate::stubs::SYSCALL_STUBS + .read() + .unwrap() + .sol_memcmp(s1, s2, n as _, result); + } +} + +#[no_mangle] +pub extern "C" fn sol_memset_(s: *mut u8, c: u8, n: u64) { + unsafe { + crate::stubs::SYSCALL_STUBS + .read() + .unwrap() + .sol_memset(s, c, n as _); + } +} + #[no_mangle] pub extern "C" fn sol_log_pubkey(pubkey: *const u8) { let pubkey = unsafe { From 0af88a594160199d725e2f1138c64af6ae2aa66b Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Mon, 14 Jul 2025 16:30:41 +0300 Subject: [PATCH 42/86] pinocchio: sol_get_stack_height --- crates/lite-coverage/src/loader.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index cb0c0e82..28282241 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -247,6 +247,14 @@ pub extern "C" fn sol_memset_(s: *mut u8, c: u8, n: u64) { } } +#[no_mangle] +pub extern "C" fn sol_get_stack_height() -> u64 { + crate::stubs::SYSCALL_STUBS + .read() + .unwrap() + .sol_get_stack_height() +} + #[no_mangle] pub extern "C" fn sol_log_pubkey(pubkey: *const u8) { let pubkey = unsafe { From 01788bec6d86211d201a888eb767b30fd55cd095 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Mon, 14 Jul 2025 16:35:12 +0300 Subject: [PATCH 43/86] pinocchio: sol_get_clock_sysvar --- crates/lite-coverage/src/loader.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index 28282241..77d8a7ed 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -255,6 +255,14 @@ pub extern "C" fn sol_get_stack_height() -> u64 { .sol_get_stack_height() } +#[no_mangle] +pub extern "C" fn sol_get_clock_sysvar(addr: *mut u8) -> u64 { + crate::stubs::SYSCALL_STUBS + .read() + .unwrap() + .sol_get_clock_sysvar(addr) +} + #[no_mangle] pub extern "C" fn sol_log_pubkey(pubkey: *const u8) { let pubkey = unsafe { From c7f0e784b2b7e50247bc967a76d7d7f902992844 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Mon, 14 Jul 2025 16:37:27 +0300 Subject: [PATCH 44/86] pinocchio: sol_get_epoch_schedule_sysvar, sol_get_fees_sysvar, sol_get_rent_sysvar, sol_get_epoch_rewards_sysvar --- crates/lite-coverage/src/loader.rs | 32 ++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index 77d8a7ed..39dac0f5 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -263,6 +263,38 @@ pub extern "C" fn sol_get_clock_sysvar(addr: *mut u8) -> u64 { .sol_get_clock_sysvar(addr) } +#[no_mangle] +pub extern "C" fn sol_get_epoch_schedule_sysvar(addr: *mut u8) -> u64 { + crate::stubs::SYSCALL_STUBS + .read() + .unwrap() + .sol_get_epoch_schedule_sysvar(addr) +} + +#[no_mangle] +pub extern "C" fn sol_get_fees_sysvar(addr: *mut u8) -> u64 { + crate::stubs::SYSCALL_STUBS + .read() + .unwrap() + .sol_get_fees_sysvar(addr) +} + +#[no_mangle] +pub extern "C" fn sol_get_rent_sysvar(addr: *mut u8) -> u64 { + crate::stubs::SYSCALL_STUBS + .read() + .unwrap() + .sol_get_rent_sysvar(addr) +} + +#[no_mangle] +pub extern "C" fn sol_get_epoch_rewards_sysvar(addr: *mut u8) -> u64 { + crate::stubs::SYSCALL_STUBS + .read() + .unwrap() + .sol_get_epoch_rewards_sysvar(addr) +} + #[no_mangle] pub extern "C" fn sol_log_pubkey(pubkey: *const u8) { let pubkey = unsafe { From 59263524f32494cebb4558e0771ecf3bdc6a50a2 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Mon, 14 Jul 2025 16:39:10 +0300 Subject: [PATCH 45/86] pinocchio: sol_get_last_restart_slot --- crates/lite-coverage/src/loader.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index 39dac0f5..5a5e4c42 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -295,6 +295,14 @@ pub extern "C" fn sol_get_epoch_rewards_sysvar(addr: *mut u8) -> u64 { .sol_get_epoch_rewards_sysvar(addr) } +#[no_mangle] +pub extern "C" fn sol_get_last_restart_slot(addr: *mut u8) -> u64 { + crate::stubs::SYSCALL_STUBS + .read() + .unwrap() + .sol_get_last_restart_slot(addr) +} + #[no_mangle] pub extern "C" fn sol_log_pubkey(pubkey: *const u8) { let pubkey = unsafe { From 5b580c734ac055297862512e776163ea179615d9 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Mon, 14 Jul 2025 16:40:46 +0300 Subject: [PATCH 46/86] pinocchio: sol_get_epoch_stake --- crates/lite-coverage/src/loader.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index 5a5e4c42..92e8457e 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -303,6 +303,14 @@ pub extern "C" fn sol_get_last_restart_slot(addr: *mut u8) -> u64 { .sol_get_last_restart_slot(addr) } +#[no_mangle] +pub extern "C" fn sol_get_epoch_stake(vote_address: *const u8) -> u64 { + crate::stubs::SYSCALL_STUBS + .read() + .unwrap() + .sol_get_epoch_stake(vote_address) +} + #[no_mangle] pub extern "C" fn sol_log_pubkey(pubkey: *const u8) { let pubkey = unsafe { From 753ed532e0e8f629cf0bfe5280b6ab5727db493d Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Mon, 14 Jul 2025 16:44:25 +0300 Subject: [PATCH 47/86] pinocchio: sol_get_sysvar --- crates/lite-coverage/src/loader.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index 92e8457e..747ab2f7 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -311,6 +311,21 @@ pub extern "C" fn sol_get_epoch_stake(vote_address: *const u8) -> u64 { .sol_get_epoch_stake(vote_address) } +#[no_mangle] +pub extern "C" fn sol_get_sysvar( + sysvar_id_addr: *const u8, + result: *mut u8, + offset: u64, + length: u64, +) -> u64 { + crate::stubs::SYSCALL_STUBS.read().unwrap().sol_get_sysvar( + sysvar_id_addr, + result, + offset, + length, + ) +} + #[no_mangle] pub extern "C" fn sol_log_pubkey(pubkey: *const u8) { let pubkey = unsafe { From 775734f84853f190433a1444d0c72a278b338d29 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Mon, 14 Jul 2025 16:46:58 +0300 Subject: [PATCH 48/86] pinocchio: sol_set_return_data --- crates/lite-coverage/src/loader.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index 747ab2f7..24246d24 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -326,6 +326,15 @@ pub extern "C" fn sol_get_sysvar( ) } +#[no_mangle] +pub extern "C" fn sol_set_return_data(data: *const u8, length: u64) { + let slice = unsafe { std::slice::from_raw_parts(data, length as _) }; + crate::stubs::SYSCALL_STUBS + .read() + .unwrap() + .sol_set_return_data(slice); +} + #[no_mangle] pub extern "C" fn sol_log_pubkey(pubkey: *const u8) { let pubkey = unsafe { From fc80faa4203dbf98e86aa038859c34fbc0a97e94 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Mon, 14 Jul 2025 17:04:26 +0300 Subject: [PATCH 49/86] pinocchio: sol_get_return_data --- crates/lite-coverage/src/loader.rs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index 24246d24..ee51ebd2 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -335,6 +335,31 @@ pub extern "C" fn sol_set_return_data(data: *const u8, length: u64) { .sol_set_return_data(slice); } +#[no_mangle] +pub extern "C" fn sol_get_return_data(data: *mut u8, length: u64, program_id: *mut Pubkey) -> u64 { + let ret_data = crate::stubs::SYSCALL_STUBS + .read() + .unwrap() + .sol_get_return_data(); + + match ret_data { + None => 0, + Some((key, src)) => { + // Judging from the signature we're expected to copy the data. + // Let's check if there's enough space. + let src_len = src.len() as _; + if src_len > length { + return 0; + } + unsafe { + *program_id = key; + std::ptr::copy_nonoverlapping(src.as_ptr(), data, length as _); + }; + src_len + } + } +} + #[no_mangle] pub extern "C" fn sol_log_pubkey(pubkey: *const u8) { let pubkey = unsafe { From d7231a73c17a604a936b7d44d33243761d500416 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Tue, 15 Jul 2025 09:00:50 +0300 Subject: [PATCH 50/86] Pinocchio apps tend to 'repurpose' i.e change value of bytes in the input buffer. This breaks canonical deserialization - so make a copy of the input and advance on it while collecting values from the new input. --- crates/lite-coverage/src/lib.rs | 1 + crates/lite-coverage/src/loader.rs | 13 ++- crates/lite-coverage/src/sbf.rs | 124 +++++++++++++++++++++++++++++ 3 files changed, 136 insertions(+), 2 deletions(-) create mode 100644 crates/lite-coverage/src/sbf.rs diff --git a/crates/lite-coverage/src/lib.rs b/crates/lite-coverage/src/lib.rs index 815bd6e0..2839cbfa 100644 --- a/crates/lite-coverage/src/lib.rs +++ b/crates/lite-coverage/src/lib.rs @@ -1,5 +1,6 @@ mod lite_coverage; mod loader; +mod sbf; mod stubs; mod types; pub use lite_coverage::*; diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index ee51ebd2..158712ee 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -1,4 +1,5 @@ use crate::{ + sbf, stubs::{StubsManager, SyscallStubsApi, UnimplementedSyscallStubs, WrapperSyscallStubs}, types::LiteCoverageError, }; @@ -45,11 +46,19 @@ pub fn entrypoint(program_id: &Pubkey, accounts: &[AccountInfo], _data: &[u8]) - ) .map_err(|_| ProgramError::InvalidArgument)?; + // Make a copy prior to calling the entrypoint fn, we'll use it + // for deserialization of the post-instruction updated input. + let mut parameter_bytes_copy = parameter_bytes.clone(); let res = unsafe { entry(parameter_bytes.as_slice().as_ptr() as *mut _) }; if res == 0 { - // Deserialize data back into instruction params + // Deserialize data back into instruction params advancing on the old input + // while using values from the new input. The reason for this is that + // some programs may repurpose and change the value of bytes in the old input which + // in the end may break the canonical deserialization. + // So try to to do our best to extract what we need while following the correct format. let (_, updated_account_infos, _) = unsafe { - solana_program_entrypoint::deserialize( + sbf::deserialize_updated_account_infos( + &mut parameter_bytes_copy.as_slice_mut()[0] as *const u8, &mut parameter_bytes.as_slice_mut()[0] as *mut u8, ) }; diff --git a/crates/lite-coverage/src/sbf.rs b/crates/lite-coverage/src/sbf.rs new file mode 100644 index 00000000..bf1343a8 --- /dev/null +++ b/crates/lite-coverage/src/sbf.rs @@ -0,0 +1,124 @@ +// Adapted from solana-program-entrypoint +// https://solana.com/docs/programs/faq#input-parameter-serialization + +use solana_program_entrypoint::{BPF_ALIGN_OF_U128, MAX_PERMITTED_DATA_INCREASE, NON_DUP_MARKER}; +use solana_pubkey::Pubkey; +use solana_sysvar::slot_history::AccountInfo; + +#[allow(clippy::arithmetic_side_effects)] +#[inline(always)] // this reduces CU usage by half! +unsafe fn deserialize_account_info<'a>( + mut offset: usize, + new_input: *mut u8, +) -> (AccountInfo<'a>, usize) { + #[allow(clippy::cast_ptr_alignment)] + let is_signer = *(new_input.add(offset) as *const u8) != 0; + offset += size_of::(); + + #[allow(clippy::cast_ptr_alignment)] + let is_writable = *(new_input.add(offset) as *const u8) != 0; + offset += size_of::(); + + #[allow(clippy::cast_ptr_alignment)] + let executable = *(new_input.add(offset) as *const u8) != 0; + offset += size_of::(); + + // padding + offset += size_of::(); + + let key: &Pubkey = &*(new_input.add(offset) as *const Pubkey); + offset += size_of::(); + + let owner: &Pubkey = &*(new_input.add(offset) as *const Pubkey); + offset += size_of::(); + + #[allow(clippy::cast_ptr_alignment)] + let lamports = std::rc::Rc::new(std::cell::RefCell::new( + &mut *(new_input.add(offset) as *mut u64), + )); + offset += size_of::(); + + #[allow(clippy::cast_ptr_alignment)] + let data_len = *(new_input.add(offset) as *const u64) as usize; + offset += size_of::(); + + let data = std::rc::Rc::new(std::cell::RefCell::new({ + std::slice::from_raw_parts_mut(new_input.add(offset), data_len) + })); + offset += data_len + MAX_PERMITTED_DATA_INCREASE; + offset += (offset as *const u8).align_offset(BPF_ALIGN_OF_U128); // padding + + #[allow(clippy::cast_ptr_alignment)] + let rent_epoch = *(new_input.add(offset) as *const u64); + offset += size_of::(); + + ( + AccountInfo { + key, + is_signer, + is_writable, + lamports, + data, + owner, + executable, + rent_epoch, + }, + offset, + ) +} + +#[allow(clippy::arithmetic_side_effects)] +#[inline(always)] // this reduces CU usage +unsafe fn deserialize_instruction_data<'a>(input: *mut u8, mut offset: usize) -> (&'a [u8], usize) { + #[allow(clippy::cast_ptr_alignment)] + let instruction_data_len = *(input.add(offset) as *const u64) as usize; + offset += size_of::(); + + let instruction_data = { std::slice::from_raw_parts(input.add(offset), instruction_data_len) }; + offset += instruction_data_len; + + (instruction_data, offset) +} + +#[allow(clippy::arithmetic_side_effects)] +pub unsafe fn deserialize_updated_account_infos<'a>( + old_input: *const u8, + new_input: *mut u8, +) -> (&'a Pubkey, Vec>, &'a [u8]) { + let mut offset: usize = 0; + + // Number of accounts present + + #[allow(clippy::cast_ptr_alignment)] + let num_accounts = *(old_input.add(offset) as *const u64) as usize; + offset += size_of::(); + + // Account Infos + + let mut accounts = Vec::with_capacity(num_accounts); + for _ in 0..num_accounts { + let dup_info = *(old_input.add(offset) as *const u8); + offset += size_of::(); + if dup_info == NON_DUP_MARKER { + let (account_info, new_offset) = deserialize_account_info(offset, new_input); + offset = new_offset; + accounts.push(account_info); + } else { + offset += 7; // padding + + // Duplicate account, clone the original + accounts.push(accounts[dup_info as usize].clone()); + } + } + + // Instruction data + + let (instruction_data, new_offset) = deserialize_instruction_data(new_input, offset); + offset = new_offset; + + // Program Id + + let program_id: &Pubkey = &*(new_input.add(offset) as *const Pubkey); + + (program_id, accounts, instruction_data) +} From 6bf023d961ec3e19f0c14c1fda405a25809a7af3 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Tue, 15 Jul 2025 10:17:06 +0300 Subject: [PATCH 51/86] pinocchio: sol_log_data RETHINK STUBS: probably this is a better way to handle &[&[u8]] instead of how it was done in the solana-program-stubs --- crates/lite-coverage/src/loader.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index 158712ee..b406fb43 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -369,6 +369,22 @@ pub extern "C" fn sol_get_return_data(data: *mut u8, length: u64, program_id: *m } } +#[no_mangle] +pub extern "C" fn sol_log_data(data: *const u8, data_len: u64) { + // reinterpret the buffer as a fat pointer to (*const u8, usize) pairs + let fat_ptrs = data as *const (*const u8, usize); + let mut v: Vec<&[u8]> = Vec::with_capacity(data_len as _); + for i in 0..data_len { + let (data_ptr, len) = unsafe { *fat_ptrs.add(i as _) }; + let slice = unsafe { std::slice::from_raw_parts(data_ptr, len) }; + v.push(slice); + } + crate::stubs::SYSCALL_STUBS + .read() + .unwrap() + .sol_log_data(&v[..]); +} + #[no_mangle] pub extern "C" fn sol_log_pubkey(pubkey: *const u8) { let pubkey = unsafe { From c4a87bad446e84d98ca4ec59fd2f2cadd01fb96f Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Tue, 15 Jul 2025 14:14:06 +0300 Subject: [PATCH 52/86] pinocchio: sol_get_processed_sibling_instruction --- crates/lite-coverage/src/loader.rs | 52 ++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index b406fb43..cdbe987a 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -5,6 +5,7 @@ use crate::{ }; use core::str; use libloading::{Library, Symbol}; +use solana_instruction::{AccountMeta, ProcessedSiblingInstruction}; use solana_program::{ account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError, program_stubs::set_syscall_stubs, pubkey::Pubkey, @@ -385,6 +386,57 @@ pub extern "C" fn sol_log_data(data: *const u8, data_len: u64) { .sol_log_data(&v[..]); } +#[no_mangle] +pub extern "C" fn sol_get_processed_sibling_instruction( + index: u64, + meta: *mut ProcessedSiblingInstruction, + program_id: *mut Pubkey, + data: *mut u8, + accounts: *mut AccountMeta, +) -> u64 { + let instruction = crate::stubs::SYSCALL_STUBS + .read() + .unwrap() + .sol_get_processed_sibling_instruction(index as _); + match instruction { + None => 0, // 0 - No processed sibling instruction. + Some(instr) => { + let data_len = instr.data.len(); + let accounts_len = instr.accounts.len(); + unsafe { + if (*meta).accounts_len == 0 && (*meta).data_len == 0 { + // Caller is wondering how many to allocate. + // https://github.com/anza-xyz/solana-sdk/blob/master/instruction/src/syscalls.rs#L32 + (*meta).data_len = data_len as _; + (*meta).accounts_len = accounts_len as _; + *program_id = instr.program_id; + + // 1 - Return the allocation details so that caller can prepare. + return 1; + } + } + + // Caller is ready with the allocation. + // But first - a little sanity check. + unsafe { + if (*meta).data_len != data_len as u64 + || (*meta).accounts_len != accounts_len as u64 + || *program_id != instr.program_id + { + return 0; + } + + // Now just copy the data and the account metas. + std::ptr::copy_nonoverlapping(instr.data.as_ptr(), data, data_len); + // NB: Mind that Pinocchio uses its AccountMeta with + // &Pubkey instead of Pubkey in it - which seems not quite right. + std::ptr::copy_nonoverlapping(instr.accounts.as_ptr(), accounts, accounts_len); + } + 2 // 2 - All good. + } + } +} + #[no_mangle] pub extern "C" fn sol_log_pubkey(pubkey: *const u8) { let pubkey = unsafe { From 38f51c174b0eaedf7dea545af2f28e627982e4b8 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Tue, 15 Jul 2025 14:15:14 +0300 Subject: [PATCH 53/86] silence cargo clippy --- crates/lite-coverage/src/sbf.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/lite-coverage/src/sbf.rs b/crates/lite-coverage/src/sbf.rs index bf1343a8..349f202a 100644 --- a/crates/lite-coverage/src/sbf.rs +++ b/crates/lite-coverage/src/sbf.rs @@ -97,7 +97,7 @@ pub unsafe fn deserialize_updated_account_infos<'a>( let mut accounts = Vec::with_capacity(num_accounts); for _ in 0..num_accounts { - let dup_info = *(old_input.add(offset) as *const u8); + let dup_info = *(old_input.add(offset)); offset += size_of::(); if dup_info == NON_DUP_MARKER { let (account_info, new_offset) = deserialize_account_info(offset, new_input); From f50a6f3818d3d4844cbb0cddf21b0dc6bf69ce54 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Tue, 15 Jul 2025 15:16:36 +0300 Subject: [PATCH 54/86] pinocchio's AccountMeta actually holds a reference to Pubkey and take that into account - else we will 100% get a segfault. --- crates/lite-coverage/src/loader.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index cdbe987a..fdc792ec 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -5,7 +5,7 @@ use crate::{ }; use core::str; use libloading::{Library, Symbol}; -use solana_instruction::{AccountMeta, ProcessedSiblingInstruction}; +use solana_instruction::{BorrowedAccountMeta, ProcessedSiblingInstruction}; use solana_program::{ account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError, program_stubs::set_syscall_stubs, pubkey::Pubkey, @@ -392,7 +392,7 @@ pub extern "C" fn sol_get_processed_sibling_instruction( meta: *mut ProcessedSiblingInstruction, program_id: *mut Pubkey, data: *mut u8, - accounts: *mut AccountMeta, + accounts: *mut BorrowedAccountMeta, ) -> u64 { let instruction = crate::stubs::SYSCALL_STUBS .read() @@ -428,9 +428,14 @@ pub extern "C" fn sol_get_processed_sibling_instruction( // Now just copy the data and the account metas. std::ptr::copy_nonoverlapping(instr.data.as_ptr(), data, data_len); - // NB: Mind that Pinocchio uses its AccountMeta with - // &Pubkey instead of Pubkey in it - which seems not quite right. - std::ptr::copy_nonoverlapping(instr.accounts.as_ptr(), accounts, accounts_len); + // Now copy the account metas taking into consideration that pubkey is a borrow! + // https://github.com/anza-xyz/pinocchio/blob/main/sdk/pinocchio/src/instruction.rs#L116 + for i in 0..instr.accounts.len() { + let account_meta = accounts.add(i); + (*account_meta).is_signer = instr.accounts[i].is_signer; + (*account_meta).is_writable = instr.accounts[i].is_writable; + (*account_meta).pubkey = Box::leak(Box::new(instr.accounts[i].pubkey)); + } } 2 // 2 - All good. } From eaa0753f0b41c89dbb3f3c286901776a1f00ef0f Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Tue, 15 Jul 2025 15:22:02 +0300 Subject: [PATCH 55/86] pinocchio: declare our own BorrowedAccountMeta so that we mark it as repr(C). Solana's isn't mark unfortunately. --- crates/lite-coverage/src/loader.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index fdc792ec..65904824 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -5,7 +5,7 @@ use crate::{ }; use core::str; use libloading::{Library, Symbol}; -use solana_instruction::{BorrowedAccountMeta, ProcessedSiblingInstruction}; +use solana_instruction::ProcessedSiblingInstruction; use solana_program::{ account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError, program_stubs::set_syscall_stubs, pubkey::Pubkey, @@ -386,6 +386,13 @@ pub extern "C" fn sol_log_data(data: *const u8, data_len: u64) { .sol_log_data(&v[..]); } +#[repr(C)] +pub struct BorrowedAccountMeta<'a> { + pub pubkey: &'a Pubkey, + pub is_signer: bool, + pub is_writable: bool, +} + #[no_mangle] pub extern "C" fn sol_get_processed_sibling_instruction( index: u64, From 05186a8434028c06ea4cb531088f958d5a1effdb Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Tue, 15 Jul 2025 15:51:57 +0300 Subject: [PATCH 56/86] Pinocchio's AccountMeta layout: 1) pubkey is a borrow 2) is_writable is before is_signer ProcessedSiblingInstruction is the same. TODO: maybe import pinocchio to skip redeclarations? --- crates/lite-coverage/src/loader.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index 65904824..da7d8805 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -5,7 +5,7 @@ use crate::{ }; use core::str; use libloading::{Library, Symbol}; -use solana_instruction::ProcessedSiblingInstruction; +use solana_instruction::{AccountMeta, ProcessedSiblingInstruction}; use solana_program::{ account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError, program_stubs::set_syscall_stubs, pubkey::Pubkey, @@ -386,11 +386,16 @@ pub extern "C" fn sol_log_data(data: *const u8, data_len: u64) { .sol_log_data(&v[..]); } +// Pinocchio's layout: +// 1) pubkey is a borrow +// 2) is_writable is before is_signer +// ProcessedSiblingInstruction is the same. +// TODO: maybe import pinocchio to skip redeclarations? #[repr(C)] pub struct BorrowedAccountMeta<'a> { pub pubkey: &'a Pubkey, - pub is_signer: bool, pub is_writable: bool, + pub is_signer: bool, } #[no_mangle] From 3f7283060409b6551d4d3d3f97984f7ce40a11b9 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Wed, 16 Jul 2025 09:43:54 +0300 Subject: [PATCH 57/86] pinocchio: syscalls in place but let's try to clean up more --- crates/lite-coverage/src/loader.rs | 175 ++++++++++++++++++++++++++--- 1 file changed, 158 insertions(+), 17 deletions(-) diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index da7d8805..ab086b4f 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -5,7 +5,7 @@ use crate::{ }; use core::str; use libloading::{Library, Symbol}; -use solana_instruction::{AccountMeta, ProcessedSiblingInstruction}; +use solana_instruction::{AccountMeta, Instruction}; use solana_program::{ account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError, program_stubs::set_syscall_stubs, pubkey::Pubkey, @@ -355,14 +355,19 @@ pub extern "C" fn sol_get_return_data(data: *mut u8, length: u64, program_id: *m match ret_data { None => 0, Some((key, src)) => { - // Judging from the signature we're expected to copy the data. + // Caller is wondering how many to allocate. + if length == 0 { + unsafe { *program_id = key }; + return src.len() as _; + } + + // Caller is ready with the allocation - we're expected to copy the data. // Let's check if there's enough space. let src_len = src.len() as _; - if src_len > length { + if src_len > length || unsafe { *program_id } != key { return 0; } unsafe { - *program_id = key; std::ptr::copy_nonoverlapping(src.as_ptr(), data, length as _); }; src_len @@ -373,11 +378,11 @@ pub extern "C" fn sol_get_return_data(data: *mut u8, length: u64, program_id: *m #[no_mangle] pub extern "C" fn sol_log_data(data: *const u8, data_len: u64) { // reinterpret the buffer as a fat pointer to (*const u8, usize) pairs - let fat_ptrs = data as *const (*const u8, usize); + let fat_ptrs = data as *const (*const u8, u64); let mut v: Vec<&[u8]> = Vec::with_capacity(data_len as _); for i in 0..data_len { let (data_ptr, len) = unsafe { *fat_ptrs.add(i as _) }; - let slice = unsafe { std::slice::from_raw_parts(data_ptr, len) }; + let slice = unsafe { std::slice::from_raw_parts(data_ptr, len as _) }; v.push(slice); } crate::stubs::SYSCALL_STUBS @@ -386,14 +391,15 @@ pub extern "C" fn sol_log_data(data: *const u8, data_len: u64) { .sol_log_data(&v[..]); } -// Pinocchio's layout: -// 1) pubkey is a borrow -// 2) is_writable is before is_signer -// ProcessedSiblingInstruction is the same. -// TODO: maybe import pinocchio to skip redeclarations? #[repr(C)] -pub struct BorrowedAccountMeta<'a> { - pub pubkey: &'a Pubkey, +pub struct CProcessedSiblingInstruction { + pub data_len: u64, + pub accounts_len: u64, +} + +#[repr(C)] +pub struct CAccountMeta { + pub pubkey: *const u8, pub is_writable: bool, pub is_signer: bool, } @@ -401,10 +407,10 @@ pub struct BorrowedAccountMeta<'a> { #[no_mangle] pub extern "C" fn sol_get_processed_sibling_instruction( index: u64, - meta: *mut ProcessedSiblingInstruction, + meta: *mut CProcessedSiblingInstruction, program_id: *mut Pubkey, data: *mut u8, - accounts: *mut BorrowedAccountMeta, + accounts: *mut CAccountMeta, ) -> u64 { let instruction = crate::stubs::SYSCALL_STUBS .read() @@ -440,13 +446,14 @@ pub extern "C" fn sol_get_processed_sibling_instruction( // Now just copy the data and the account metas. std::ptr::copy_nonoverlapping(instr.data.as_ptr(), data, data_len); - // Now copy the account metas taking into consideration that pubkey is a borrow! + // Now copy the account metas taking into consideration that pubkey is a *const u8. // https://github.com/anza-xyz/pinocchio/blob/main/sdk/pinocchio/src/instruction.rs#L116 for i in 0..instr.accounts.len() { let account_meta = accounts.add(i); (*account_meta).is_signer = instr.accounts[i].is_signer; (*account_meta).is_writable = instr.accounts[i].is_writable; - (*account_meta).pubkey = Box::leak(Box::new(instr.accounts[i].pubkey)); + (*account_meta).pubkey = + Box::leak(Box::new(instr.accounts[i].pubkey)) as *const _ as *const u8; } } 2 // 2 - All good. @@ -454,6 +461,140 @@ pub extern "C" fn sol_get_processed_sibling_instruction( } } +#[repr(C)] +#[derive(Clone)] +pub struct CAccountInfo { + // Public key of the account. + key: *const Pubkey, + + // Number of lamports owned by this account. + lamports: *const u64, + + // Length of data in bytes. + data_len: u64, + + // On-chain data within this account. + data: *const u8, + + // Program that owns this account. + owner: *const Pubkey, + + // The epoch at which this account will next owe rent. + rent_epoch: u64, + + // Transaction was signed by this account's key? + is_signer: bool, + + // Is the account writable? + is_writable: bool, + + // This account's data contains a loaded program (and is now read-only). + executable: bool, +} + +#[repr(C)] +struct CInstruction { + /// Public key of the program. + program_id: *const Pubkey, + + /// Accounts expected by the program instruction. + accounts: *const CAccountMeta, + + /// Number of accounts expected by the program instruction. + accounts_len: u64, + + /// Data expected by the program instruction. + data: *const u8, + + /// Length of the data expected by the program instruction. + data_len: u64, +} + +#[no_mangle] +pub extern "C" fn sol_invoke_signed_c( + instruction_addr: *const u8, + account_infos_addr: *const u8, + account_infos_len: u64, + signers_seeds_addr: *const u8, + signers_seeds_len: u64, +) -> u64 { + // instruction + let cinstr = instruction_addr as *const CInstruction; + let instruction = unsafe { + Instruction { + program_id: *(*cinstr).program_id.clone(), + accounts: { + (0..(*cinstr).accounts_len) + .into_iter() + .map(|i| { + let cam = (*cinstr).accounts.add(i as _); + AccountMeta { + pubkey: Pubkey::new_from_array(*(*(*cam).pubkey as *const [u8; 32])), + is_signer: (*cam).is_signer, + is_writable: (*cam).is_writable, + } + }) + .collect() + }, + data: { + let slice = std::slice::from_raw_parts((*cinstr).data, (*cinstr).data_len as _); + slice.to_vec() + }, + } + }; + + // account_infos + let ai_fat_ptr = account_infos_addr as *const (*const CAccountInfo, u64); + let mut account_infos: Vec> = vec![]; + for i in 0..account_infos_len { + let (cai, _) = unsafe { *ai_fat_ptr.add(i as _) }; + let ai = unsafe { + AccountInfo { + key: &*(*cai).key, + lamports: std::rc::Rc::new(std::cell::RefCell::new( + &mut *((*cai).lamports as *mut _), + )), + data: { + let slice = + std::slice::from_raw_parts_mut((*cai).data as _, (*cai).data_len as _); + std::rc::Rc::new(std::cell::RefCell::new(slice)) + }, + owner: &*(*cai).owner, + rent_epoch: (*cai).rent_epoch, + is_signer: (*cai).is_signer, + is_writable: (*cai).is_writable, + executable: (*cai).executable, + } + }; + account_infos.push(ai); + } + + // signers_seeds + let q_fat_ptr = signers_seeds_addr as *const (*const u8, u64); + let mut qv: Vec> = vec![]; + for q in 0..signers_seeds_len { + let (q_data_ptr, q_data_len) = unsafe { *q_fat_ptr.add(q as _) }; + let mut pv: Vec<&[u8]> = vec![]; + for p in 0..q_data_len { + let p_fat_ptr = q_data_ptr as *const (*const u8, u64); + let (p_data_ptr, p_data_len) = unsafe { *p_fat_ptr.add(p as _) }; + let slice = unsafe { std::slice::from_raw_parts(p_data_ptr, p_data_len as usize) }; + pv.push(slice); + } + qv.push(pv); + } + + let signers_seeds: Vec<_> = qv.iter().map(|e| &e[..]).collect(); + match crate::stubs::SYSCALL_STUBS + .read() + .unwrap() + .sol_invoke_signed(&instruction, &account_infos[..], &signers_seeds[..]) + { + Ok(_) => 0, + Err(e) => e.into(), + } +} + #[no_mangle] pub extern "C" fn sol_log_pubkey(pubkey: *const u8) { let pubkey = unsafe { From c0eb1d99db596cdc0e1c4b0947aee0b3e9df978e Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Wed, 16 Jul 2025 10:06:52 +0300 Subject: [PATCH 58/86] pinocchio: syscalls clean up --- crates/lite-coverage/src/loader.rs | 43 ++++++++++++++---------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index ab086b4f..f87f2fbd 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -345,8 +345,11 @@ pub extern "C" fn sol_set_return_data(data: *const u8, length: u64) { .sol_set_return_data(slice); } +pub const PUBKEY_BYTES: usize = 32; +pub type CPubkey = [u8; PUBKEY_BYTES]; + #[no_mangle] -pub extern "C" fn sol_get_return_data(data: *mut u8, length: u64, program_id: *mut Pubkey) -> u64 { +pub extern "C" fn sol_get_return_data(data: *mut u8, length: u64, program_id: *mut CPubkey) -> u64 { let ret_data = crate::stubs::SYSCALL_STUBS .read() .unwrap() @@ -357,14 +360,14 @@ pub extern "C" fn sol_get_return_data(data: *mut u8, length: u64, program_id: *m Some((key, src)) => { // Caller is wondering how many to allocate. if length == 0 { - unsafe { *program_id = key }; + unsafe { *program_id = *key.as_array() }; return src.len() as _; } // Caller is ready with the allocation - we're expected to copy the data. // Let's check if there's enough space. let src_len = src.len() as _; - if src_len > length || unsafe { *program_id } != key { + if src_len > length || unsafe { *program_id } != *key.as_array() { return 0; } unsafe { @@ -399,7 +402,7 @@ pub struct CProcessedSiblingInstruction { #[repr(C)] pub struct CAccountMeta { - pub pubkey: *const u8, + pub pubkey: *const CPubkey, pub is_writable: bool, pub is_signer: bool, } @@ -408,7 +411,7 @@ pub struct CAccountMeta { pub extern "C" fn sol_get_processed_sibling_instruction( index: u64, meta: *mut CProcessedSiblingInstruction, - program_id: *mut Pubkey, + program_id: *mut CPubkey, data: *mut u8, accounts: *mut CAccountMeta, ) -> u64 { @@ -427,7 +430,7 @@ pub extern "C" fn sol_get_processed_sibling_instruction( // https://github.com/anza-xyz/solana-sdk/blob/master/instruction/src/syscalls.rs#L32 (*meta).data_len = data_len as _; (*meta).accounts_len = accounts_len as _; - *program_id = instr.program_id; + *program_id = *instr.program_id.as_array(); // 1 - Return the allocation details so that caller can prepare. return 1; @@ -439,7 +442,7 @@ pub extern "C" fn sol_get_processed_sibling_instruction( unsafe { if (*meta).data_len != data_len as u64 || (*meta).accounts_len != accounts_len as u64 - || *program_id != instr.program_id + || *program_id != *instr.program_id.as_array() { return 0; } @@ -452,8 +455,8 @@ pub extern "C" fn sol_get_processed_sibling_instruction( let account_meta = accounts.add(i); (*account_meta).is_signer = instr.accounts[i].is_signer; (*account_meta).is_writable = instr.accounts[i].is_writable; - (*account_meta).pubkey = - Box::leak(Box::new(instr.accounts[i].pubkey)) as *const _ as *const u8; + (*account_meta).pubkey = Box::leak(Box::new(instr.accounts[i].pubkey)) + as *const _ as *const [u8; 32]; } } 2 // 2 - All good. @@ -462,10 +465,9 @@ pub extern "C" fn sol_get_processed_sibling_instruction( } #[repr(C)] -#[derive(Clone)] pub struct CAccountInfo { // Public key of the account. - key: *const Pubkey, + key: *const CPubkey, // Number of lamports owned by this account. lamports: *const u64, @@ -477,7 +479,7 @@ pub struct CAccountInfo { data: *const u8, // Program that owns this account. - owner: *const Pubkey, + owner: *const CPubkey, // The epoch at which this account will next owe rent. rent_epoch: u64, @@ -495,7 +497,7 @@ pub struct CAccountInfo { #[repr(C)] struct CInstruction { /// Public key of the program. - program_id: *const Pubkey, + program_id: *const CPubkey, /// Accounts expected by the program instruction. accounts: *const CAccountMeta, @@ -522,14 +524,13 @@ pub extern "C" fn sol_invoke_signed_c( let cinstr = instruction_addr as *const CInstruction; let instruction = unsafe { Instruction { - program_id: *(*cinstr).program_id.clone(), + program_id: Pubkey::new_from_array(*(*cinstr).program_id), accounts: { (0..(*cinstr).accounts_len) - .into_iter() .map(|i| { let cam = (*cinstr).accounts.add(i as _); AccountMeta { - pubkey: Pubkey::new_from_array(*(*(*cam).pubkey as *const [u8; 32])), + pubkey: Pubkey::new_from_array(*(*cam).pubkey), is_signer: (*cam).is_signer, is_writable: (*cam).is_writable, } @@ -550,7 +551,7 @@ pub extern "C" fn sol_invoke_signed_c( let (cai, _) = unsafe { *ai_fat_ptr.add(i as _) }; let ai = unsafe { AccountInfo { - key: &*(*cai).key, + key: &*((*cai).key as *const Pubkey), lamports: std::rc::Rc::new(std::cell::RefCell::new( &mut *((*cai).lamports as *mut _), )), @@ -559,7 +560,7 @@ pub extern "C" fn sol_invoke_signed_c( std::slice::from_raw_parts_mut((*cai).data as _, (*cai).data_len as _); std::rc::Rc::new(std::cell::RefCell::new(slice)) }, - owner: &*(*cai).owner, + owner: &*((*cai).owner as *const Pubkey), rent_epoch: (*cai).rent_epoch, is_signer: (*cai).is_signer, is_writable: (*cai).is_writable, @@ -597,11 +598,7 @@ pub extern "C" fn sol_invoke_signed_c( #[no_mangle] pub extern "C" fn sol_log_pubkey(pubkey: *const u8) { - let pubkey = unsafe { - let mut inner = [0u8; 32]; - std::ptr::copy_nonoverlapping(pubkey, inner.as_mut_ptr(), 32); - Pubkey::new_from_array(inner) - }; + let pubkey = unsafe { &*(pubkey as *const Pubkey) }; crate::stubs::SYSCALL_STUBS .read() .unwrap() From 561d6b134fffd804e1b2aae4797a83a9d929bf4d Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Wed, 16 Jul 2025 11:42:43 +0300 Subject: [PATCH 59/86] pinocchio: invoke_signed_c left - revise the rest of course --- crates/lite-coverage/src/loader.rs | 209 +++++++++++++++++++++++++++++ 1 file changed, 209 insertions(+) diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index f87f2fbd..e9f2271b 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -401,12 +401,23 @@ pub struct CProcessedSiblingInstruction { } #[repr(C)] +#[derive(Clone)] pub struct CAccountMeta { pub pubkey: *const CPubkey, pub is_writable: bool, pub is_signer: bool, } +impl Default for CAccountMeta { + fn default() -> Self { + Self { + pubkey: &[0u8; 32], + is_writable: false, + is_signer: false, + } + } +} + #[no_mangle] pub extern "C" fn sol_get_processed_sibling_instruction( index: u64, @@ -604,4 +615,202 @@ pub extern "C" fn sol_log_pubkey(pubkey: *const u8) { .unwrap() .sol_log(&pubkey.to_string()); } + +#[repr(C)] +pub struct SyscallStubsApi2 { + pub sol_log_: extern "C" fn(message: *const u8, len: u64), + pub sol_log_compute_units_: extern "C" fn(), + pub sol_remaining_compute_units: extern "C" fn() -> u64, + pub sol_invoke_signed_c: extern "C" fn( + instruction_addr: *const u8, + account_infos_addr: *const u8, + account_infos_len: u64, + signers_seeds_addr: *const u8, + signers_seeds_len: u64, + ) -> u64, + pub sol_get_clock_sysvar: extern "C" fn(addr: *mut u8) -> u64, + pub sol_get_epoch_schedule_sysvar: extern "C" fn(addr: *mut u8) -> u64, + pub sol_get_fees_sysvar: extern "C" fn(addr: *mut u8) -> u64, + pub sol_get_rent_sysvar: extern "C" fn(addr: *mut u8) -> u64, + pub sol_get_last_restart_slot: extern "C" fn(addr: *mut u8) -> u64, + pub sol_get_sysvar: + extern "C" fn(sysvar_id_addr: *const u8, result: *mut u8, offset: u64, length: u64) -> u64, + pub sol_memcpy_: extern "C" fn(dst: *mut u8, src: *const u8, n: u64), + pub sol_memmove_: extern "C" fn(dst: *mut u8, src: *const u8, n: u64), + pub sol_memcmp_: extern "C" fn(s1: *const u8, s2: *const u8, n: u64, result: *mut i32), + pub sol_memset_: extern "C" fn(s: *mut u8, c: u8, n: u64), + pub sol_get_return_data: + extern "C" fn(data: *mut u8, length: u64, program_id: *mut CPubkey) -> u64, + pub sol_set_return_data: extern "C" fn(data: *const u8, length: u64), + pub sol_log_data: extern "C" fn(data: *const u8, data_len: u64), + pub sol_get_processed_sibling_instruction: extern "C" fn( + index: u64, + meta: *mut CProcessedSiblingInstruction, + program_id: *mut CPubkey, + data: *mut u8, + accounts: *mut CAccountMeta, + ) -> u64, + pub sol_get_stack_height: extern "C" fn() -> u64, + pub sol_get_epoch_rewards_sysvar: extern "C" fn(addr: *mut u8) -> u64, + pub sol_get_epoch_stake: extern "C" fn(vote_address: *const u8) -> u64, +} + +impl SyscallStubsApi2 { + pub fn new() -> Self { + Self { + sol_get_clock_sysvar, + sol_get_epoch_rewards_sysvar, + sol_get_epoch_schedule_sysvar, + sol_get_fees_sysvar, + sol_get_last_restart_slot, + sol_get_rent_sysvar, + sol_get_stack_height, + sol_log_, + sol_log_compute_units_, + sol_memcmp_, + sol_memcpy_, + sol_memmove_, + sol_memset_, + sol_remaining_compute_units, + sol_get_return_data, + sol_set_return_data, + sol_log_data, + sol_invoke_signed_c, + sol_get_processed_sibling_instruction, + sol_get_epoch_stake, + sol_get_sysvar, + } + } +} + +#[repr(C)] +pub struct SolAppSyscallStubs2 { + pub stubs_api2: SyscallStubsApi2, +} + +impl solana_sysvar::program_stubs::SyscallStubs for SolAppSyscallStubs2 { + fn sol_get_clock_sysvar(&self, var_addr: *mut u8) -> u64 { + (self.stubs_api2.sol_get_clock_sysvar)(var_addr) + } + fn sol_get_epoch_rewards_sysvar(&self, var_addr: *mut u8) -> u64 { + (self.stubs_api2.sol_get_epoch_rewards_sysvar)(var_addr) + } + fn sol_get_epoch_schedule_sysvar(&self, var_addr: *mut u8) -> u64 { + (self.stubs_api2.sol_get_epoch_schedule_sysvar)(var_addr) + } + fn sol_get_epoch_stake(&self, vote_address: *const u8) -> u64 { + (self.stubs_api2.sol_get_epoch_stake)(vote_address) + } + fn sol_get_fees_sysvar(&self, var_addr: *mut u8) -> u64 { + (self.stubs_api2.sol_get_fees_sysvar)(var_addr) + } + fn sol_get_last_restart_slot(&self, var_addr: *mut u8) -> u64 { + (self.stubs_api2.sol_get_last_restart_slot)(var_addr) + } + fn sol_get_rent_sysvar(&self, var_addr: *mut u8) -> u64 { + (self.stubs_api2.sol_get_rent_sysvar)(var_addr) + } + fn sol_get_stack_height(&self) -> u64 { + (self.stubs_api2.sol_get_stack_height)() + } + fn sol_remaining_compute_units(&self) -> u64 { + (self.stubs_api2.sol_remaining_compute_units)() + } + unsafe fn sol_memcmp(&self, s1: *const u8, s2: *const u8, n: usize, result: *mut i32) { + (self.stubs_api2.sol_memcmp_)(s1, s2, n as u64, result); + } + unsafe fn sol_memcpy(&self, dst: *mut u8, src: *const u8, n: usize) { + (self.stubs_api2.sol_memcpy_)(dst, src, n as u64) + } + unsafe fn sol_memmove(&self, dst: *mut u8, src: *const u8, n: usize) { + (self.stubs_api2.sol_memmove_)(dst, src, n as u64) + } + unsafe fn sol_memset(&self, s: *mut u8, c: u8, n: usize) { + (self.stubs_api2.sol_memset_)(s, c, n as u64) + } + fn sol_get_sysvar( + &self, + sysvar_id_addr: *const u8, + var_addr: *mut u8, + offset: u64, + length: u64, + ) -> u64 { + (self.stubs_api2.sol_get_sysvar)(sysvar_id_addr, var_addr, offset, length) + } + fn sol_log_compute_units(&self) { + (self.stubs_api2.sol_log_compute_units_)() + } + fn sol_log(&self, message: &str) { + (self.stubs_api2.sol_log_)(message.as_ptr(), message.len() as u64) + } + fn sol_log_data(&self, fields: &[&[u8]]) { + (self.stubs_api2.sol_log_data)(fields.as_ptr() as *const u8, fields.len() as u64); + } + fn sol_set_return_data(&self, data: &[u8]) { + (self.stubs_api2.sol_set_return_data)(data.as_ptr(), data.len() as u64); + } + fn sol_get_return_data(&self) -> Option<(Pubkey, Vec)> { + let mut program_id = [0u8; 32]; + let data_bytes_to_alloc = + (self.stubs_api2.sol_get_return_data)(&mut u8::default(), 0, &mut program_id); + if data_bytes_to_alloc == 0 { + return None; + } + let mut vdata = vec![0u8; data_bytes_to_alloc as usize]; + let same_bytes_num_expected = (self.stubs_api2.sol_get_return_data)( + vdata.as_mut_ptr(), + vdata.len() as _, + &mut program_id, + ); + if same_bytes_num_expected == data_bytes_to_alloc { + return Some((Pubkey::new_from_array(program_id), vdata)); + } else { + None + } + } + fn sol_get_processed_sibling_instruction(&self, index: usize) -> Option { + let mut meta = CProcessedSiblingInstruction { + accounts_len: 0, + data_len: 0, + }; + let mut program_id = [0u8; 32]; + if 1 == (self.stubs_api2.sol_get_processed_sibling_instruction)( + index as _, + &mut meta, + &mut program_id, + &mut u8::default(), + &mut CAccountMeta::default(), + ) { + let accounts_to_alloc = meta.accounts_len; + let data_bytes_to_alloc = meta.data_len; + let mut caccount_metas = vec![CAccountMeta::default(); accounts_to_alloc as _]; + let mut vdata = vec![0u8; data_bytes_to_alloc as _]; + let res = (self.stubs_api2.sol_get_processed_sibling_instruction)( + index as _, + &mut meta, + &mut program_id, + vdata.as_mut_ptr(), + caccount_metas.as_mut_ptr(), + ); + if res != 0 && res != 1 { + let mut account_metas = vec![]; + for cai in &caccount_metas { + let pubkey = unsafe { *Box::from_raw(cai.pubkey as *mut _) }; + let account_meta = AccountMeta { + is_signer: cai.is_signer, + is_writable: cai.is_writable, + pubkey: Pubkey::new_from_array(pubkey), + }; + account_metas.push(account_meta); + } + return Some(Instruction { + accounts: account_metas, + data: vdata, + program_id: program_id.into(), + }); + } + } + None + } +} // REVISIT From 32694b569f257bfe679ed038e12b9728a19c2ac7 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Wed, 16 Jul 2025 13:04:50 +0300 Subject: [PATCH 60/86] pinocchio: sol_invoke_signed, NB: after this func data len will probably still be stale at caller --- crates/lite-coverage/src/loader.rs | 50 ++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index e9f2271b..2b74ce08 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -812,5 +812,55 @@ impl solana_sysvar::program_stubs::SyscallStubs for SolAppSyscallStubs2 { } None } + fn sol_invoke_signed( + &self, + instruction: &Instruction, + account_infos: &[AccountInfo], + signers_seeds: &[&[&[u8]]], + ) -> ProgramResult { + let mut caccounts = vec![]; + for account_meta in &instruction.accounts { + let caccount = CAccountMeta { + is_signer: account_meta.is_signer, + is_writable: account_meta.is_writable, + pubkey: &account_meta.pubkey as *const _ as *const CPubkey, + }; + caccounts.push(caccount); + } + let cinstr = CInstruction { + program_id: &instruction.program_id as *const _ as *const CPubkey, + accounts_len: instruction.accounts.len() as _, + data_len: instruction.data.len() as _, + accounts: caccounts.as_ptr(), + data: instruction.data.as_ptr(), + }; + let mut caccount_infos = vec![]; + for account_info in account_infos { + let caccount_info = CAccountInfo { + is_signer: account_info.is_signer, + is_writable: account_info.is_writable, + executable: account_info.executable, + rent_epoch: account_info.rent_epoch, + data_len: account_info.data_len() as _, + data: account_info.data.borrow().as_ptr(), + lamports: *account_info.lamports.borrow(), + key: account_info.key as *const _ as *const CPubkey, + owner: account_info.owner as *const _ as *const CPubkey, + }; + caccount_infos.push(caccount_info); + } + let res = (self.stubs_api2.sol_invoke_signed_c)( + &cinstr as *const _ as *const u8, + caccount_infos.as_ptr() as *const u8, + caccount_infos.len() as _, + signers_seeds.as_ptr() as *const u8, + signers_seeds.len() as _, + ); + if res == 0 { + Ok(()) + } else { + Err(ProgramError::Custom(res as _)) + } + } } // REVISIT From bcd07c7fdad290f742f010df2c8e7b3a4720c244 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Wed, 16 Jul 2025 13:06:13 +0300 Subject: [PATCH 61/86] silence clippy --- crates/lite-coverage/src/loader.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index 2b74ce08..93675000 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -763,7 +763,7 @@ impl solana_sysvar::program_stubs::SyscallStubs for SolAppSyscallStubs2 { &mut program_id, ); if same_bytes_num_expected == data_bytes_to_alloc { - return Some((Pubkey::new_from_array(program_id), vdata)); + Some((Pubkey::new_from_array(program_id), vdata)) } else { None } From 9a358d908bb741165ad40200a0c9c10a615c84ee Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Thu, 17 Jul 2025 13:05:42 +0300 Subject: [PATCH 62/86] relocate stubs to the solana-program-stubs loader macro --- Cargo.lock | 2 +- Cargo.toml | 2 +- crates/lite-coverage/src/loader.rs | 681 +---------------------------- crates/lite-coverage/src/stubs.rs | 7 +- 4 files changed, 10 insertions(+), 682 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4590595c..4944142b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5692,7 +5692,7 @@ dependencies = [ [[package]] name = "solana-program-stubs" version = "0.1.0" -source = "git+ssh://git@github.com/procdump/sol-stubs.git?branch=master#143d0ee25a36f1d1f986614de174a54a8554259c" +source = "git+ssh://git@github.com/procdump/sol-stubs.git?branch=stubsv2_pinocchio#511d8edc359aefa5b78ae64222b9cda1e3a36c9c" dependencies = [ "lazy_static", ] diff --git a/Cargo.toml b/Cargo.toml index 17f01fce..886ea11e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -92,7 +92,7 @@ test-log = "0.2" thiserror = "2.0" tokio = "1.35" lite-coverage = { path = "crates/lite-coverage" } -solana-program-stubs = { git = "ssh://git@github.com/procdump/sol-stubs.git", branch = "master", features = [ "loader_stubs" ] } +solana-program-stubs = { git = "ssh://git@github.com/procdump/sol-stubs.git", branch = "stubsv2_pinocchio", features = [ "loader_stubs" ] } [profile.bench] debug = true diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index 93675000..14f2c614 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -1,11 +1,10 @@ use crate::{ sbf, - stubs::{StubsManager, SyscallStubsApi, UnimplementedSyscallStubs, WrapperSyscallStubs}, + stubs::{StubsManager, SyscallStubsApi2, UnimplementedSyscallStubs, WrapperSyscallStubs}, types::LiteCoverageError, }; use core::str; use libloading::{Library, Symbol}; -use solana_instruction::{AccountMeta, Instruction}; use solana_program::{ account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError, program_stubs::set_syscall_stubs, pubkey::Pubkey, @@ -16,7 +15,7 @@ use std::{ }; type ProgramEntrypoint = unsafe extern "C" fn(input: *mut u8) -> u64; -type ProgramSetSyscallStubsApi = unsafe extern "C" fn(stubs_api: SyscallStubsApi); +type ProgramSetSyscallStubsApi = unsafe extern "C" fn(stubs_api: SyscallStubsApi2); lazy_static::lazy_static! ( pub static ref PROGRAMS_MAP: Mutex>> = Mutex::new(HashMap::new()); @@ -134,7 +133,7 @@ impl Loader { // Now for each program set the appropriate stubs for (program_id, _) in self.libs.iter() { // Now create the C interface so that the solana programs can reach our SYSCALL_STUBS! - let stubs_api = SyscallStubsApi::new(); + let stubs_api = SyscallStubsApi2::new(); // Pass it to the loaded smart contract! self.set_syscall_stubs_api(program_id, stubs_api)?; } @@ -160,7 +159,7 @@ impl Loader { pub fn set_syscall_stubs_api( &self, program_id: &Pubkey, - stubs_api: SyscallStubsApi, + stubs_api: SyscallStubsApi2, ) -> LiteCoverageError<()> { let res: Result, libloading::Error> = unsafe { self.libs @@ -192,675 +191,3 @@ impl Loader { Ok(*entrypoint) } } - -// REVISIT: pinocchio's syscalls impls are here for now -#[no_mangle] -pub extern "C" fn sol_log_(msg: *const u8, len: u64) { - let message = unsafe { std::slice::from_raw_parts(msg, len as _) }; - let m = String::from_utf8_lossy(message); - crate::stubs::SYSCALL_STUBS.read().unwrap().sol_log(&m); -} - -#[no_mangle] -pub extern "C" fn sol_log_compute_units_() { - crate::stubs::SYSCALL_STUBS - .read() - .unwrap() - .sol_log_compute_units(); -} - -#[no_mangle] -pub extern "C" fn sol_remaining_compute_units() -> u64 { - crate::stubs::SYSCALL_STUBS - .read() - .unwrap() - .sol_remaining_compute_units() -} - -#[no_mangle] -pub extern "C" fn sol_memcpy_(dst: *mut u8, src: *const u8, n: u64) { - unsafe { - crate::stubs::SYSCALL_STUBS - .read() - .unwrap() - .sol_memcpy(dst, src, n as _); - } -} - -#[no_mangle] -pub extern "C" fn sol_memmove_(dst: *mut u8, src: *const u8, n: u64) { - unsafe { - crate::stubs::SYSCALL_STUBS - .read() - .unwrap() - .sol_memmove(dst, src, n as _); - } -} - -#[no_mangle] -pub extern "C" fn sol_memcmp_(s1: *const u8, s2: *const u8, n: u64, result: *mut i32) { - unsafe { - crate::stubs::SYSCALL_STUBS - .read() - .unwrap() - .sol_memcmp(s1, s2, n as _, result); - } -} - -#[no_mangle] -pub extern "C" fn sol_memset_(s: *mut u8, c: u8, n: u64) { - unsafe { - crate::stubs::SYSCALL_STUBS - .read() - .unwrap() - .sol_memset(s, c, n as _); - } -} - -#[no_mangle] -pub extern "C" fn sol_get_stack_height() -> u64 { - crate::stubs::SYSCALL_STUBS - .read() - .unwrap() - .sol_get_stack_height() -} - -#[no_mangle] -pub extern "C" fn sol_get_clock_sysvar(addr: *mut u8) -> u64 { - crate::stubs::SYSCALL_STUBS - .read() - .unwrap() - .sol_get_clock_sysvar(addr) -} - -#[no_mangle] -pub extern "C" fn sol_get_epoch_schedule_sysvar(addr: *mut u8) -> u64 { - crate::stubs::SYSCALL_STUBS - .read() - .unwrap() - .sol_get_epoch_schedule_sysvar(addr) -} - -#[no_mangle] -pub extern "C" fn sol_get_fees_sysvar(addr: *mut u8) -> u64 { - crate::stubs::SYSCALL_STUBS - .read() - .unwrap() - .sol_get_fees_sysvar(addr) -} - -#[no_mangle] -pub extern "C" fn sol_get_rent_sysvar(addr: *mut u8) -> u64 { - crate::stubs::SYSCALL_STUBS - .read() - .unwrap() - .sol_get_rent_sysvar(addr) -} - -#[no_mangle] -pub extern "C" fn sol_get_epoch_rewards_sysvar(addr: *mut u8) -> u64 { - crate::stubs::SYSCALL_STUBS - .read() - .unwrap() - .sol_get_epoch_rewards_sysvar(addr) -} - -#[no_mangle] -pub extern "C" fn sol_get_last_restart_slot(addr: *mut u8) -> u64 { - crate::stubs::SYSCALL_STUBS - .read() - .unwrap() - .sol_get_last_restart_slot(addr) -} - -#[no_mangle] -pub extern "C" fn sol_get_epoch_stake(vote_address: *const u8) -> u64 { - crate::stubs::SYSCALL_STUBS - .read() - .unwrap() - .sol_get_epoch_stake(vote_address) -} - -#[no_mangle] -pub extern "C" fn sol_get_sysvar( - sysvar_id_addr: *const u8, - result: *mut u8, - offset: u64, - length: u64, -) -> u64 { - crate::stubs::SYSCALL_STUBS.read().unwrap().sol_get_sysvar( - sysvar_id_addr, - result, - offset, - length, - ) -} - -#[no_mangle] -pub extern "C" fn sol_set_return_data(data: *const u8, length: u64) { - let slice = unsafe { std::slice::from_raw_parts(data, length as _) }; - crate::stubs::SYSCALL_STUBS - .read() - .unwrap() - .sol_set_return_data(slice); -} - -pub const PUBKEY_BYTES: usize = 32; -pub type CPubkey = [u8; PUBKEY_BYTES]; - -#[no_mangle] -pub extern "C" fn sol_get_return_data(data: *mut u8, length: u64, program_id: *mut CPubkey) -> u64 { - let ret_data = crate::stubs::SYSCALL_STUBS - .read() - .unwrap() - .sol_get_return_data(); - - match ret_data { - None => 0, - Some((key, src)) => { - // Caller is wondering how many to allocate. - if length == 0 { - unsafe { *program_id = *key.as_array() }; - return src.len() as _; - } - - // Caller is ready with the allocation - we're expected to copy the data. - // Let's check if there's enough space. - let src_len = src.len() as _; - if src_len > length || unsafe { *program_id } != *key.as_array() { - return 0; - } - unsafe { - std::ptr::copy_nonoverlapping(src.as_ptr(), data, length as _); - }; - src_len - } - } -} - -#[no_mangle] -pub extern "C" fn sol_log_data(data: *const u8, data_len: u64) { - // reinterpret the buffer as a fat pointer to (*const u8, usize) pairs - let fat_ptrs = data as *const (*const u8, u64); - let mut v: Vec<&[u8]> = Vec::with_capacity(data_len as _); - for i in 0..data_len { - let (data_ptr, len) = unsafe { *fat_ptrs.add(i as _) }; - let slice = unsafe { std::slice::from_raw_parts(data_ptr, len as _) }; - v.push(slice); - } - crate::stubs::SYSCALL_STUBS - .read() - .unwrap() - .sol_log_data(&v[..]); -} - -#[repr(C)] -pub struct CProcessedSiblingInstruction { - pub data_len: u64, - pub accounts_len: u64, -} - -#[repr(C)] -#[derive(Clone)] -pub struct CAccountMeta { - pub pubkey: *const CPubkey, - pub is_writable: bool, - pub is_signer: bool, -} - -impl Default for CAccountMeta { - fn default() -> Self { - Self { - pubkey: &[0u8; 32], - is_writable: false, - is_signer: false, - } - } -} - -#[no_mangle] -pub extern "C" fn sol_get_processed_sibling_instruction( - index: u64, - meta: *mut CProcessedSiblingInstruction, - program_id: *mut CPubkey, - data: *mut u8, - accounts: *mut CAccountMeta, -) -> u64 { - let instruction = crate::stubs::SYSCALL_STUBS - .read() - .unwrap() - .sol_get_processed_sibling_instruction(index as _); - match instruction { - None => 0, // 0 - No processed sibling instruction. - Some(instr) => { - let data_len = instr.data.len(); - let accounts_len = instr.accounts.len(); - unsafe { - if (*meta).accounts_len == 0 && (*meta).data_len == 0 { - // Caller is wondering how many to allocate. - // https://github.com/anza-xyz/solana-sdk/blob/master/instruction/src/syscalls.rs#L32 - (*meta).data_len = data_len as _; - (*meta).accounts_len = accounts_len as _; - *program_id = *instr.program_id.as_array(); - - // 1 - Return the allocation details so that caller can prepare. - return 1; - } - } - - // Caller is ready with the allocation. - // But first - a little sanity check. - unsafe { - if (*meta).data_len != data_len as u64 - || (*meta).accounts_len != accounts_len as u64 - || *program_id != *instr.program_id.as_array() - { - return 0; - } - - // Now just copy the data and the account metas. - std::ptr::copy_nonoverlapping(instr.data.as_ptr(), data, data_len); - // Now copy the account metas taking into consideration that pubkey is a *const u8. - // https://github.com/anza-xyz/pinocchio/blob/main/sdk/pinocchio/src/instruction.rs#L116 - for i in 0..instr.accounts.len() { - let account_meta = accounts.add(i); - (*account_meta).is_signer = instr.accounts[i].is_signer; - (*account_meta).is_writable = instr.accounts[i].is_writable; - (*account_meta).pubkey = Box::leak(Box::new(instr.accounts[i].pubkey)) - as *const _ as *const [u8; 32]; - } - } - 2 // 2 - All good. - } - } -} - -#[repr(C)] -pub struct CAccountInfo { - // Public key of the account. - key: *const CPubkey, - - // Number of lamports owned by this account. - lamports: *const u64, - - // Length of data in bytes. - data_len: u64, - - // On-chain data within this account. - data: *const u8, - - // Program that owns this account. - owner: *const CPubkey, - - // The epoch at which this account will next owe rent. - rent_epoch: u64, - - // Transaction was signed by this account's key? - is_signer: bool, - - // Is the account writable? - is_writable: bool, - - // This account's data contains a loaded program (and is now read-only). - executable: bool, -} - -#[repr(C)] -struct CInstruction { - /// Public key of the program. - program_id: *const CPubkey, - - /// Accounts expected by the program instruction. - accounts: *const CAccountMeta, - - /// Number of accounts expected by the program instruction. - accounts_len: u64, - - /// Data expected by the program instruction. - data: *const u8, - - /// Length of the data expected by the program instruction. - data_len: u64, -} - -#[no_mangle] -pub extern "C" fn sol_invoke_signed_c( - instruction_addr: *const u8, - account_infos_addr: *const u8, - account_infos_len: u64, - signers_seeds_addr: *const u8, - signers_seeds_len: u64, -) -> u64 { - // instruction - let cinstr = instruction_addr as *const CInstruction; - let instruction = unsafe { - Instruction { - program_id: Pubkey::new_from_array(*(*cinstr).program_id), - accounts: { - (0..(*cinstr).accounts_len) - .map(|i| { - let cam = (*cinstr).accounts.add(i as _); - AccountMeta { - pubkey: Pubkey::new_from_array(*(*cam).pubkey), - is_signer: (*cam).is_signer, - is_writable: (*cam).is_writable, - } - }) - .collect() - }, - data: { - let slice = std::slice::from_raw_parts((*cinstr).data, (*cinstr).data_len as _); - slice.to_vec() - }, - } - }; - - // account_infos - let ai_fat_ptr = account_infos_addr as *const (*const CAccountInfo, u64); - let mut account_infos: Vec> = vec![]; - for i in 0..account_infos_len { - let (cai, _) = unsafe { *ai_fat_ptr.add(i as _) }; - let ai = unsafe { - AccountInfo { - key: &*((*cai).key as *const Pubkey), - lamports: std::rc::Rc::new(std::cell::RefCell::new( - &mut *((*cai).lamports as *mut _), - )), - data: { - let slice = - std::slice::from_raw_parts_mut((*cai).data as _, (*cai).data_len as _); - std::rc::Rc::new(std::cell::RefCell::new(slice)) - }, - owner: &*((*cai).owner as *const Pubkey), - rent_epoch: (*cai).rent_epoch, - is_signer: (*cai).is_signer, - is_writable: (*cai).is_writable, - executable: (*cai).executable, - } - }; - account_infos.push(ai); - } - - // signers_seeds - let q_fat_ptr = signers_seeds_addr as *const (*const u8, u64); - let mut qv: Vec> = vec![]; - for q in 0..signers_seeds_len { - let (q_data_ptr, q_data_len) = unsafe { *q_fat_ptr.add(q as _) }; - let mut pv: Vec<&[u8]> = vec![]; - for p in 0..q_data_len { - let p_fat_ptr = q_data_ptr as *const (*const u8, u64); - let (p_data_ptr, p_data_len) = unsafe { *p_fat_ptr.add(p as _) }; - let slice = unsafe { std::slice::from_raw_parts(p_data_ptr, p_data_len as usize) }; - pv.push(slice); - } - qv.push(pv); - } - - let signers_seeds: Vec<_> = qv.iter().map(|e| &e[..]).collect(); - match crate::stubs::SYSCALL_STUBS - .read() - .unwrap() - .sol_invoke_signed(&instruction, &account_infos[..], &signers_seeds[..]) - { - Ok(_) => 0, - Err(e) => e.into(), - } -} - -#[no_mangle] -pub extern "C" fn sol_log_pubkey(pubkey: *const u8) { - let pubkey = unsafe { &*(pubkey as *const Pubkey) }; - crate::stubs::SYSCALL_STUBS - .read() - .unwrap() - .sol_log(&pubkey.to_string()); -} - -#[repr(C)] -pub struct SyscallStubsApi2 { - pub sol_log_: extern "C" fn(message: *const u8, len: u64), - pub sol_log_compute_units_: extern "C" fn(), - pub sol_remaining_compute_units: extern "C" fn() -> u64, - pub sol_invoke_signed_c: extern "C" fn( - instruction_addr: *const u8, - account_infos_addr: *const u8, - account_infos_len: u64, - signers_seeds_addr: *const u8, - signers_seeds_len: u64, - ) -> u64, - pub sol_get_clock_sysvar: extern "C" fn(addr: *mut u8) -> u64, - pub sol_get_epoch_schedule_sysvar: extern "C" fn(addr: *mut u8) -> u64, - pub sol_get_fees_sysvar: extern "C" fn(addr: *mut u8) -> u64, - pub sol_get_rent_sysvar: extern "C" fn(addr: *mut u8) -> u64, - pub sol_get_last_restart_slot: extern "C" fn(addr: *mut u8) -> u64, - pub sol_get_sysvar: - extern "C" fn(sysvar_id_addr: *const u8, result: *mut u8, offset: u64, length: u64) -> u64, - pub sol_memcpy_: extern "C" fn(dst: *mut u8, src: *const u8, n: u64), - pub sol_memmove_: extern "C" fn(dst: *mut u8, src: *const u8, n: u64), - pub sol_memcmp_: extern "C" fn(s1: *const u8, s2: *const u8, n: u64, result: *mut i32), - pub sol_memset_: extern "C" fn(s: *mut u8, c: u8, n: u64), - pub sol_get_return_data: - extern "C" fn(data: *mut u8, length: u64, program_id: *mut CPubkey) -> u64, - pub sol_set_return_data: extern "C" fn(data: *const u8, length: u64), - pub sol_log_data: extern "C" fn(data: *const u8, data_len: u64), - pub sol_get_processed_sibling_instruction: extern "C" fn( - index: u64, - meta: *mut CProcessedSiblingInstruction, - program_id: *mut CPubkey, - data: *mut u8, - accounts: *mut CAccountMeta, - ) -> u64, - pub sol_get_stack_height: extern "C" fn() -> u64, - pub sol_get_epoch_rewards_sysvar: extern "C" fn(addr: *mut u8) -> u64, - pub sol_get_epoch_stake: extern "C" fn(vote_address: *const u8) -> u64, -} - -impl SyscallStubsApi2 { - pub fn new() -> Self { - Self { - sol_get_clock_sysvar, - sol_get_epoch_rewards_sysvar, - sol_get_epoch_schedule_sysvar, - sol_get_fees_sysvar, - sol_get_last_restart_slot, - sol_get_rent_sysvar, - sol_get_stack_height, - sol_log_, - sol_log_compute_units_, - sol_memcmp_, - sol_memcpy_, - sol_memmove_, - sol_memset_, - sol_remaining_compute_units, - sol_get_return_data, - sol_set_return_data, - sol_log_data, - sol_invoke_signed_c, - sol_get_processed_sibling_instruction, - sol_get_epoch_stake, - sol_get_sysvar, - } - } -} - -#[repr(C)] -pub struct SolAppSyscallStubs2 { - pub stubs_api2: SyscallStubsApi2, -} - -impl solana_sysvar::program_stubs::SyscallStubs for SolAppSyscallStubs2 { - fn sol_get_clock_sysvar(&self, var_addr: *mut u8) -> u64 { - (self.stubs_api2.sol_get_clock_sysvar)(var_addr) - } - fn sol_get_epoch_rewards_sysvar(&self, var_addr: *mut u8) -> u64 { - (self.stubs_api2.sol_get_epoch_rewards_sysvar)(var_addr) - } - fn sol_get_epoch_schedule_sysvar(&self, var_addr: *mut u8) -> u64 { - (self.stubs_api2.sol_get_epoch_schedule_sysvar)(var_addr) - } - fn sol_get_epoch_stake(&self, vote_address: *const u8) -> u64 { - (self.stubs_api2.sol_get_epoch_stake)(vote_address) - } - fn sol_get_fees_sysvar(&self, var_addr: *mut u8) -> u64 { - (self.stubs_api2.sol_get_fees_sysvar)(var_addr) - } - fn sol_get_last_restart_slot(&self, var_addr: *mut u8) -> u64 { - (self.stubs_api2.sol_get_last_restart_slot)(var_addr) - } - fn sol_get_rent_sysvar(&self, var_addr: *mut u8) -> u64 { - (self.stubs_api2.sol_get_rent_sysvar)(var_addr) - } - fn sol_get_stack_height(&self) -> u64 { - (self.stubs_api2.sol_get_stack_height)() - } - fn sol_remaining_compute_units(&self) -> u64 { - (self.stubs_api2.sol_remaining_compute_units)() - } - unsafe fn sol_memcmp(&self, s1: *const u8, s2: *const u8, n: usize, result: *mut i32) { - (self.stubs_api2.sol_memcmp_)(s1, s2, n as u64, result); - } - unsafe fn sol_memcpy(&self, dst: *mut u8, src: *const u8, n: usize) { - (self.stubs_api2.sol_memcpy_)(dst, src, n as u64) - } - unsafe fn sol_memmove(&self, dst: *mut u8, src: *const u8, n: usize) { - (self.stubs_api2.sol_memmove_)(dst, src, n as u64) - } - unsafe fn sol_memset(&self, s: *mut u8, c: u8, n: usize) { - (self.stubs_api2.sol_memset_)(s, c, n as u64) - } - fn sol_get_sysvar( - &self, - sysvar_id_addr: *const u8, - var_addr: *mut u8, - offset: u64, - length: u64, - ) -> u64 { - (self.stubs_api2.sol_get_sysvar)(sysvar_id_addr, var_addr, offset, length) - } - fn sol_log_compute_units(&self) { - (self.stubs_api2.sol_log_compute_units_)() - } - fn sol_log(&self, message: &str) { - (self.stubs_api2.sol_log_)(message.as_ptr(), message.len() as u64) - } - fn sol_log_data(&self, fields: &[&[u8]]) { - (self.stubs_api2.sol_log_data)(fields.as_ptr() as *const u8, fields.len() as u64); - } - fn sol_set_return_data(&self, data: &[u8]) { - (self.stubs_api2.sol_set_return_data)(data.as_ptr(), data.len() as u64); - } - fn sol_get_return_data(&self) -> Option<(Pubkey, Vec)> { - let mut program_id = [0u8; 32]; - let data_bytes_to_alloc = - (self.stubs_api2.sol_get_return_data)(&mut u8::default(), 0, &mut program_id); - if data_bytes_to_alloc == 0 { - return None; - } - let mut vdata = vec![0u8; data_bytes_to_alloc as usize]; - let same_bytes_num_expected = (self.stubs_api2.sol_get_return_data)( - vdata.as_mut_ptr(), - vdata.len() as _, - &mut program_id, - ); - if same_bytes_num_expected == data_bytes_to_alloc { - Some((Pubkey::new_from_array(program_id), vdata)) - } else { - None - } - } - fn sol_get_processed_sibling_instruction(&self, index: usize) -> Option { - let mut meta = CProcessedSiblingInstruction { - accounts_len: 0, - data_len: 0, - }; - let mut program_id = [0u8; 32]; - if 1 == (self.stubs_api2.sol_get_processed_sibling_instruction)( - index as _, - &mut meta, - &mut program_id, - &mut u8::default(), - &mut CAccountMeta::default(), - ) { - let accounts_to_alloc = meta.accounts_len; - let data_bytes_to_alloc = meta.data_len; - let mut caccount_metas = vec![CAccountMeta::default(); accounts_to_alloc as _]; - let mut vdata = vec![0u8; data_bytes_to_alloc as _]; - let res = (self.stubs_api2.sol_get_processed_sibling_instruction)( - index as _, - &mut meta, - &mut program_id, - vdata.as_mut_ptr(), - caccount_metas.as_mut_ptr(), - ); - if res != 0 && res != 1 { - let mut account_metas = vec![]; - for cai in &caccount_metas { - let pubkey = unsafe { *Box::from_raw(cai.pubkey as *mut _) }; - let account_meta = AccountMeta { - is_signer: cai.is_signer, - is_writable: cai.is_writable, - pubkey: Pubkey::new_from_array(pubkey), - }; - account_metas.push(account_meta); - } - return Some(Instruction { - accounts: account_metas, - data: vdata, - program_id: program_id.into(), - }); - } - } - None - } - fn sol_invoke_signed( - &self, - instruction: &Instruction, - account_infos: &[AccountInfo], - signers_seeds: &[&[&[u8]]], - ) -> ProgramResult { - let mut caccounts = vec![]; - for account_meta in &instruction.accounts { - let caccount = CAccountMeta { - is_signer: account_meta.is_signer, - is_writable: account_meta.is_writable, - pubkey: &account_meta.pubkey as *const _ as *const CPubkey, - }; - caccounts.push(caccount); - } - let cinstr = CInstruction { - program_id: &instruction.program_id as *const _ as *const CPubkey, - accounts_len: instruction.accounts.len() as _, - data_len: instruction.data.len() as _, - accounts: caccounts.as_ptr(), - data: instruction.data.as_ptr(), - }; - let mut caccount_infos = vec![]; - for account_info in account_infos { - let caccount_info = CAccountInfo { - is_signer: account_info.is_signer, - is_writable: account_info.is_writable, - executable: account_info.executable, - rent_epoch: account_info.rent_epoch, - data_len: account_info.data_len() as _, - data: account_info.data.borrow().as_ptr(), - lamports: *account_info.lamports.borrow(), - key: account_info.key as *const _ as *const CPubkey, - owner: account_info.owner as *const _ as *const CPubkey, - }; - caccount_infos.push(caccount_info); - } - let res = (self.stubs_api2.sol_invoke_signed_c)( - &cinstr as *const _ as *const u8, - caccount_infos.as_ptr() as *const u8, - caccount_infos.len() as _, - signers_seeds.as_ptr() as *const u8, - signers_seeds.len() as _, - ); - if res == 0 { - Ok(()) - } else { - Err(ProgramError::Custom(res as _)) - } - } -} -// REVISIT diff --git a/crates/lite-coverage/src/stubs.rs b/crates/lite-coverage/src/stubs.rs index 9a17c799..bd6a7e02 100644 --- a/crates/lite-coverage/src/stubs.rs +++ b/crates/lite-coverage/src/stubs.rs @@ -1,14 +1,15 @@ use std::sync::{Arc, RwLock}; use solana_program_error::ProgramResult; -use solana_program_stubs::declare_sol_loader_stubs; +use solana_program_stubs::declare_sol_loader_stubsv2; use solana_sysvar::program_stubs::SyscallStubs; -use solana_instruction::AccountMeta; use solana_instruction::Instruction; +use solana_program::instruction::AccountMeta; use solana_pubkey::Pubkey; use solana_sysvar::slot_history::AccountInfo; -declare_sol_loader_stubs!(); + +declare_sol_loader_stubsv2!(); pub struct StubsManager; impl StubsManager { From aeaf0e00edb0e9a4fd166cba824fb0cbf805cc7e Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Thu, 17 Jul 2025 13:27:51 +0300 Subject: [PATCH 63/86] latest stubs --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 4944142b..3e7f5254 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5692,7 +5692,7 @@ dependencies = [ [[package]] name = "solana-program-stubs" version = "0.1.0" -source = "git+ssh://git@github.com/procdump/sol-stubs.git?branch=stubsv2_pinocchio#511d8edc359aefa5b78ae64222b9cda1e3a36c9c" +source = "git+ssh://git@github.com/procdump/sol-stubs.git?branch=stubsv2_pinocchio#50f40cfae35aa8c2e5e27a259752946514da9190" dependencies = [ "lazy_static", ] From 1ee5e6a9fdc57b37e2b15d9b1b681657a43291cc Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Thu, 17 Jul 2025 14:53:50 +0300 Subject: [PATCH 64/86] Trim printlns in favor of using workspace's log. Then with RUST_LOG=info we can see notable msgs. --- crates/lite-coverage/Cargo.toml | 1 + crates/lite-coverage/src/lite_coverage.rs | 11 ++++++----- crates/lite-coverage/src/loader.rs | 2 +- crates/lite-coverage/src/stubs.rs | 1 - crates/litesvm/src/lib.rs | 3 --- 5 files changed, 8 insertions(+), 10 deletions(-) diff --git a/crates/lite-coverage/Cargo.toml b/crates/lite-coverage/Cargo.toml index c6e32c77..97fd0552 100644 --- a/crates/lite-coverage/Cargo.toml +++ b/crates/lite-coverage/Cargo.toml @@ -29,3 +29,4 @@ solana-sdk-ids = { workspace = true } tokio = { workspace = true } lazy_static = "1.5.0" solana-program-stubs = { workspace = true } +log.workspace = true diff --git a/crates/lite-coverage/src/lite_coverage.rs b/crates/lite-coverage/src/lite_coverage.rs index 0a736768..b0b906af 100644 --- a/crates/lite-coverage/src/lite_coverage.rs +++ b/crates/lite-coverage/src/lite_coverage.rs @@ -42,14 +42,15 @@ impl LiteCoverage { let mut loader = Loader::new(); for (program_id, program_name, so_path) in static_programs.iter() { - println!( - "Adding native program {} with id: {}", - program_name, program_id + log::info!( + "Adding native program {} with program id: {}", + program_name, + program_id ); loader.add_program(so_path, program_name, program_id)?; program_test.add_program(program_name, *program_id, processor!(entrypoint)); } - println!("Loaded: {:?}", loader); + log::info!("Loaded: {:?}", loader); let rt = tokio::runtime::Runtime::new()?; let pt_context = rt.block_on(async move { program_test.start_with_context().await }); @@ -123,7 +124,7 @@ impl LiteCoverage { .process_transaction_with_metadata(re_signed_tx) .await?; - println!("OUR TX RES: {:?}", res); + log::info!("LiteCoverage transaction result: {:#?}", res); Ok(()) }); Ok(()) diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index 14f2c614..e55b2579 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -174,7 +174,7 @@ impl Loader { // REVISIT: The idea behind is this to try working with stubs // and if not neccesary (as is the case with pinocchio as it // seems for now) to continue - println!("Can't set stubs, error: {}! Go on", e); + log::warn!("Can't set stubs, error: {}! Proceed forward..", e); } } Ok(()) diff --git a/crates/lite-coverage/src/stubs.rs b/crates/lite-coverage/src/stubs.rs index bd6a7e02..39cf2bdf 100644 --- a/crates/lite-coverage/src/stubs.rs +++ b/crates/lite-coverage/src/stubs.rs @@ -21,7 +21,6 @@ impl StubsManager { pub struct WrapperSyscallStubs {} impl SyscallStubs for WrapperSyscallStubs { fn sol_get_clock_sysvar(&self, var_addr: *mut u8) -> u64 { - println!("Wrapper sol_get_clock_sysvar"); SYSCALL_STUBS.read().unwrap().sol_get_clock_sysvar(var_addr) } fn sol_get_epoch_rewards_sysvar(&self, var_addr: *mut u8) -> u64 { diff --git a/crates/litesvm/src/lib.rs b/crates/litesvm/src/lib.rs index 194bd81d..ad35113a 100644 --- a/crates/litesvm/src/lib.rs +++ b/crates/litesvm/src/lib.rs @@ -974,8 +974,6 @@ impl LiteSVM { ) .map(|_| ()); - println!("ORIGINAL TX DONE"); - if let Some(tx_copy) = tx_lite_coverage() { self.send_transaction_lite_coverage(tx_copy); } @@ -1260,7 +1258,6 @@ impl LiteSVM { /// Submits a signed transaction. pub fn send_transaction(&mut self, tx: impl Into) -> TransactionResult { - println!("Send transaction!"); let log_collector = LogCollector { bytes_limit: self.log_bytes_limit, ..Default::default() From dc58526c53f006b00fabe73b8a9f15e9ca0f7b0e Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Thu, 17 Jul 2025 14:55:40 +0300 Subject: [PATCH 65/86] log --- Cargo.lock | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.lock b/Cargo.lock index 3e7f5254..93bcd450 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2458,6 +2458,7 @@ dependencies = [ "jsonrpc-core", "lazy_static", "libloading", + "log", "serde", "solana-account", "solana-bpf-loader-program", From 81eeffb783411db4a34280dfe770e8ddcd10b526 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Thu, 17 Jul 2025 15:03:24 +0300 Subject: [PATCH 66/86] Remove unneeded pub added in the early dev attempts. --- crates/litesvm/src/accounts_db.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/litesvm/src/accounts_db.rs b/crates/litesvm/src/accounts_db.rs index 0790ae8f..06b186a6 100644 --- a/crates/litesvm/src/accounts_db.rs +++ b/crates/litesvm/src/accounts_db.rs @@ -59,7 +59,7 @@ where #[derive(Clone, Default)] pub(crate) struct AccountsDb { - pub inner: HashMap, + inner: HashMap, pub(crate) programs_cache: ProgramCacheForTxBatch, pub(crate) sysvar_cache: SysvarCache, } From ad78b12e1d66c93a18820c1ac70d70a29ec2cd6b Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Thu, 17 Jul 2025 15:08:16 +0300 Subject: [PATCH 67/86] More cleanups as well as add comments. --- crates/litesvm/src/lib.rs | 26 ++------------------------ 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/crates/litesvm/src/lib.rs b/crates/litesvm/src/lib.rs index ad35113a..f7f1b4d8 100644 --- a/crates/litesvm/src/lib.rs +++ b/crates/litesvm/src/lib.rs @@ -674,29 +674,6 @@ impl LiteSVM { Ok(()) } - // /// Adds an SBF program to the test environment from the file specified. - // pub fn add_coverage_program_from_file( - // &mut self, - // program_id: Pubkey, - // program_path: impl AsRef, - // lib_path: impl AsRef, - // ) -> Result<(), std::io::Error> { - // let program_bytes = std::fs::read(program_path)?; - // self - // // maybe load here ? - - // match self.pt { - // Some(_pt) => { - // // TODO: Implement coverage program loading - // Ok(()) - // } - // None => Err(std::io::Error::new( - // std::io::ErrorKind::Other, - // "No program test set", - // )), - // } - // } - /// Adds an SBF program to the test environment. pub fn add_program(&mut self, program_id: Pubkey, program_bytes: &[u8]) { let program_len = program_bytes.len(); @@ -942,7 +919,7 @@ impl LiteSVM { .collect::>, TransactionError>>(); match maybe_program_indices { Ok(program_indices) => { - let mut context = self.create_transaction_context(compute_budget, accounts.clone()); + let mut context = self.create_transaction_context(compute_budget, accounts); let tx_lite_coverage = || { if self.lite_coverage.is_some() { @@ -1246,6 +1223,7 @@ impl LiteSVM { }) } + /// Attach programs for obtaining code coverage. pub fn with_coverage( &mut self, programs: Vec, From 45c9f29a3745d372d77913c9fa951b0b4d543278 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Thu, 17 Jul 2025 15:10:59 +0300 Subject: [PATCH 68/86] remove unneeded type spec --- crates/litesvm/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/litesvm/src/lib.rs b/crates/litesvm/src/lib.rs index f7f1b4d8..c57f2370 100644 --- a/crates/litesvm/src/lib.rs +++ b/crates/litesvm/src/lib.rs @@ -929,7 +929,7 @@ impl LiteSVM { } }; - let mut tx_result: Result<(), TransactionError> = process_message( + let mut tx_result = process_message( tx.message(), &program_indices, &mut InvokeContext::new( From b7664f14a4234802bde916c16ec1c31ed35d68df Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Thu, 17 Jul 2025 15:36:34 +0300 Subject: [PATCH 69/86] Comments --- crates/lite-coverage/src/lite_coverage.rs | 11 +++++++++++ crates/lite-coverage/src/loader.rs | 18 +++++++++++++----- crates/lite-coverage/src/stubs.rs | 1 + crates/lite-coverage/src/types.rs | 1 + 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/crates/lite-coverage/src/lite_coverage.rs b/crates/lite-coverage/src/lite_coverage.rs index b0b906af..edfdab83 100644 --- a/crates/lite-coverage/src/lite_coverage.rs +++ b/crates/lite-coverage/src/lite_coverage.rs @@ -17,6 +17,7 @@ use { tokio::runtime::Runtime, }; +/// Main object to look after code coverage. #[derive(Clone)] pub struct LiteCoverage { pub programs: Vec, @@ -25,6 +26,7 @@ pub struct LiteCoverage { } impl LiteCoverage { + /// Get an instance to the main code coverage object. pub fn new( programs: Vec, additional_programs: Vec, @@ -65,6 +67,7 @@ impl LiteCoverage { }) } + /// Get a handle to the ProgramTestContext. pub fn get_program_test_context(&self) -> ProgramTestContextHandle { assert!( self.pt_context.borrow().is_some(), @@ -73,6 +76,7 @@ impl LiteCoverage { ProgramTestContextHandle::new(Rc::clone(&self.pt_context)) } + /// Add an account to the ProgramTestContext. pub fn add_account(&self, account_pubkey: &Pubkey, account_data: &AccountSharedData) { let mut pt_context = self.get_program_test_context(); if let Some(ctx) = &mut *pt_context { @@ -80,6 +84,7 @@ impl LiteCoverage { } } + /// Sign with our payer while also using our latest blockhash. async fn re_sign_tx( &self, tx: &VersionedTransaction, @@ -101,6 +106,8 @@ impl LiteCoverage { Ok(VersionedTransaction::from(trans)) } + /// Send the transaction to the natively loaded SBF avatars already prepared for + /// obtaining code coverage. pub fn send_transaction( &self, tx: VersionedTransaction, @@ -130,6 +137,10 @@ impl LiteCoverage { Ok(()) } + /// Log some events provided that some anchor envvars are globally set. + /// This is useful for anchor to know that it's litesvm that's actually used. + /// With this information anchor can go further visualizing the code coverage results + /// or bail out. fn log_anchor_test_event_artifacts( progs: Vec, additional_progs: Vec, diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index e55b2579..aa3bcd54 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -21,6 +21,8 @@ lazy_static::lazy_static! ( pub static ref PROGRAMS_MAP: Mutex>> = Mutex::new(HashMap::new()); ); +/// ProgramTest invokes this entrypoint to dispatch to the right entrypoint +/// of the natively loaded SBF avatars. pub fn entrypoint(program_id: &Pubkey, accounts: &[AccountInfo], _data: &[u8]) -> ProgramResult { let map = PROGRAMS_MAP.lock().unwrap(); let entry = map @@ -106,21 +108,24 @@ pub fn entrypoint(program_id: &Pubkey, accounts: &[AccountInfo], _data: &[u8]) - } } +/// A loader object to track loaded SBF avatars. #[derive(Debug, Default)] -pub struct Loader { +pub(crate) struct Loader { libs: HashMap, } impl Loader { - pub fn new() -> Self { + // Get an instance to a loader. + pub(crate) fn new() -> Self { Self { libs: HashMap::new(), } } + /// Adjust stubs for the natively loaded SBF avatars. /// NB: This function must be called after ProgramTest .start/start_context() method! /// Only after starting we have the appropriate SYSCALL_STUBS initialized. - pub fn adjust_stubs(&self) -> LiteCoverageError<()> { + pub(crate) fn adjust_stubs(&self) -> LiteCoverageError<()> { // So in ProgramTest's start() ...: // setup_bank() has passed and we have the appropriate stubs! // First to get them put there unimplemented stubs for a moment. @@ -140,7 +145,8 @@ impl Loader { Ok(()) } - pub fn add_program( + /// Load natively a SBF avatar. + pub(crate) fn add_program( &mut self, so_path: &str, program_name: &str, @@ -156,7 +162,8 @@ impl Loader { Ok(()) } - pub fn set_syscall_stubs_api( + /// Set stubs at the natively loaded SBF avatar. + pub(crate) fn set_syscall_stubs_api( &self, program_id: &Pubkey, stubs_api: SyscallStubsApi2, @@ -180,6 +187,7 @@ impl Loader { Ok(()) } + /// Obtain the entrypoint for this program_id. fn get_entrypoint(&self, program_id: &Pubkey) -> LiteCoverageError { let entrypoint: Symbol = unsafe { self.libs diff --git a/crates/lite-coverage/src/stubs.rs b/crates/lite-coverage/src/stubs.rs index 39cf2bdf..f0e7b1d7 100644 --- a/crates/lite-coverage/src/stubs.rs +++ b/crates/lite-coverage/src/stubs.rs @@ -11,6 +11,7 @@ use solana_sysvar::slot_history::AccountInfo; declare_sol_loader_stubsv2!(); +/// Main logic behind the StubsManager is explained in loader::adjust_stubs. pub struct StubsManager; impl StubsManager { pub fn my_set_syscall_stubs(syscall_stubs: Box) -> Box { diff --git a/crates/lite-coverage/src/types.rs b/crates/lite-coverage/src/types.rs index 56319c05..d2bd6393 100644 --- a/crates/lite-coverage/src/types.rs +++ b/crates/lite-coverage/src/types.rs @@ -13,6 +13,7 @@ pub type Path = String; pub type NativeProgram = (Pubkey, ProgramName, Path); pub type AdditionalProgram = (Pubkey, ProgramName); +/// ProgramTestContextHandle to reconcile sync with async in terms of RefCell borrows. pub struct ProgramTestContextHandle { ctx: Option, owner: Rc>>, From 22ad117b06e280ab1067c2c00706830e166a9e10 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Thu, 17 Jul 2025 15:39:04 +0300 Subject: [PATCH 70/86] more pubs -> pub(crate) as global awareness isn't necessary --- crates/lite-coverage/src/sbf.rs | 2 +- crates/lite-coverage/src/stubs.rs | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/crates/lite-coverage/src/sbf.rs b/crates/lite-coverage/src/sbf.rs index 349f202a..902611af 100644 --- a/crates/lite-coverage/src/sbf.rs +++ b/crates/lite-coverage/src/sbf.rs @@ -81,7 +81,7 @@ unsafe fn deserialize_instruction_data<'a>(input: *mut u8, mut offset: usize) -> } #[allow(clippy::arithmetic_side_effects)] -pub unsafe fn deserialize_updated_account_infos<'a>( +pub(crate) unsafe fn deserialize_updated_account_infos<'a>( old_input: *const u8, new_input: *mut u8, ) -> (&'a Pubkey, Vec>, &'a [u8]) { diff --git a/crates/lite-coverage/src/stubs.rs b/crates/lite-coverage/src/stubs.rs index f0e7b1d7..4b3fee5d 100644 --- a/crates/lite-coverage/src/stubs.rs +++ b/crates/lite-coverage/src/stubs.rs @@ -14,7 +14,9 @@ declare_sol_loader_stubsv2!(); /// Main logic behind the StubsManager is explained in loader::adjust_stubs. pub struct StubsManager; impl StubsManager { - pub fn my_set_syscall_stubs(syscall_stubs: Box) -> Box { + pub(crate) fn my_set_syscall_stubs( + syscall_stubs: Box, + ) -> Box { std::mem::replace(&mut SYSCALL_STUBS.write().unwrap(), syscall_stubs) } } From ec94adec254d2ff93988ac69e1d2eab565b4d9c1 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Thu, 17 Jul 2025 16:45:51 +0300 Subject: [PATCH 71/86] use latest solana-program-test --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 93bcd450..ef7c709d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5701,7 +5701,7 @@ dependencies = [ [[package]] name = "solana-program-test" version = "2.2.4" -source = "git+ssh://git@github.com/vlady-kotsev/program-test.git?branch=cov#4c23a39b9a2ad60494ac5b5da1c8dfb699c855ed" +source = "git+ssh://git@github.com/vlady-kotsev/program-test.git?branch=cov#d2399b3ef867f62bed7220fb2128ee7888393b70" dependencies = [ "assert_matches", "async-trait", From 370ab4c71f5351d9372a4f39cae5f4e4b26afe43 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Thu, 17 Jul 2025 16:50:54 +0300 Subject: [PATCH 72/86] remove newline --- crates/litesvm/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/litesvm/src/lib.rs b/crates/litesvm/src/lib.rs index c57f2370..dd68c0fc 100644 --- a/crates/litesvm/src/lib.rs +++ b/crates/litesvm/src/lib.rs @@ -340,7 +340,6 @@ mod format_logs; mod history; mod message_processor; mod precompiles; - mod spl; mod utils; From 8d9bf7c7c94c1b0e3d5ef22f346a581942063753 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Thu, 17 Jul 2025 16:54:34 +0300 Subject: [PATCH 73/86] Bring this typo back. It may harm our PR. --- crates/litesvm/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/litesvm/src/lib.rs b/crates/litesvm/src/lib.rs index dd68c0fc..c17aa6fc 100644 --- a/crates/litesvm/src/lib.rs +++ b/crates/litesvm/src/lib.rs @@ -673,7 +673,7 @@ impl LiteSVM { Ok(()) } - /// Adds an SBF program to the test environment. + /// Adds am SBF program to the test environment. pub fn add_program(&mut self, program_id: Pubkey, program_bytes: &[u8]) { let program_len = program_bytes.len(); let lamports = self.minimum_balance_for_rent_exemption(program_len); From 99b3afb3657f5f5ae7a41698e515668952d52ca6 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Fri, 18 Jul 2025 10:16:32 +0300 Subject: [PATCH 74/86] Make LiteCoverage::new() a singleton. ProgramTest is pretty much restricted likewise. --- crates/lite-coverage/src/lite_coverage.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/crates/lite-coverage/src/lite_coverage.rs b/crates/lite-coverage/src/lite_coverage.rs index edfdab83..ed549582 100644 --- a/crates/lite-coverage/src/lite_coverage.rs +++ b/crates/lite-coverage/src/lite_coverage.rs @@ -26,12 +26,25 @@ pub struct LiteCoverage { } impl LiteCoverage { - /// Get an instance to the main code coverage object. + /// Get a singleton instance to the main code coverage object. pub fn new( programs: Vec, additional_programs: Vec, payer: Keypair, ) -> LiteCoverageError { + { + use std::sync::Once; + static SINGLETON: Once = Once::new(); + + if SINGLETON.is_completed() == false { + SINGLETON.call_once(|| {}); + } else { + return Err(Box::::from( + "LiteCoverage is singleton, please use only one instance of LiteSVM", + )); + } + } + let static_programs = Box::leak(Box::new(programs.clone())); let mut program_test = ProgramTest::default(); program_test.prefer_bpf(false); From dc21d82ab22d4c05294afbf8151d95502bb928d9 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Fri, 18 Jul 2025 11:24:50 +0300 Subject: [PATCH 75/86] Come up with the sbf_avatar_path based on the program_name passed. Next - remove the path passed. --- crates/lite-coverage/src/lite_coverage.rs | 2 +- crates/lite-coverage/src/loader.rs | 42 +++++++++++++++++++++-- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/crates/lite-coverage/src/lite_coverage.rs b/crates/lite-coverage/src/lite_coverage.rs index ed549582..a58b36aa 100644 --- a/crates/lite-coverage/src/lite_coverage.rs +++ b/crates/lite-coverage/src/lite_coverage.rs @@ -58,7 +58,7 @@ impl LiteCoverage { let mut loader = Loader::new(); for (program_id, program_name, so_path) in static_programs.iter() { log::info!( - "Adding native program {} with program id: {}", + "Adding native program (SBF avatar) '{}' with program id: {}", program_name, program_id ); diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index aa3bcd54..75cd0195 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -11,6 +11,7 @@ use solana_program::{ }; use std::{ collections::HashMap, + path::PathBuf, sync::{atomic::AtomicPtr, Mutex}, }; @@ -115,6 +116,11 @@ pub(crate) struct Loader { } impl Loader { + #[cfg(target_os = "macos")] + pub(crate) const SBF_AVATAR_EXT: &str = "dylib"; + #[cfg(target_os = "linux")] + pub(crate) const SBF_AVATAR_EXT: &str = "so"; + // Get an instance to a loader. pub(crate) fn new() -> Self { Self { @@ -145,14 +151,46 @@ impl Loader { Ok(()) } + fn default_sbf_avatar_dirs() -> Vec { + let mut search_path = vec![]; + search_path.push(PathBuf::from("target/debug")); + search_path.push(PathBuf::from("tests/coverage_fixtures")); + log::info!(r#"SBF avatars .so|dylib search path: {:?}"#, search_path); + search_path + } + + fn find_sbf_avatar_file(program_name: &str) -> Option { + for dir in Loader::default_sbf_avatar_dirs() { + let candidate = dir.join(format!("lib{program_name}.{}", Loader::SBF_AVATAR_EXT)); + if candidate.exists() { + let sbf_avatar_path = candidate.to_string_lossy().to_string(); + log::info!("SBF avatar found @ {}", sbf_avatar_path); + return Some(sbf_avatar_path); + } + } + None + } + /// Load natively a SBF avatar. pub(crate) fn add_program( &mut self, - so_path: &str, + _so_path: &str, program_name: &str, program_id: &Pubkey, ) -> LiteCoverageError<()> { - let lib = unsafe { Library::new(so_path)? }; + // Come up with the so_path of the SBF avatar based on the program_name. + // For example: target/debug/libcounter.dylib if program_name is 'counter'. + let sbf_avatar_path = Loader::find_sbf_avatar_file(program_name).ok_or(Box::< + dyn std::error::Error + Send + Sync, + >::from( + r#" +LiteCoverage Loader: Can't find any SBF avatar for program '{program_name}' +For example - looking for: +'target/debug/libcounter.{so|dylib}' if program_name is 'counter' where +the extension .so would be on Linux or .dylib would be on MacOS. +"#, + ))?; + let lib = unsafe { Library::new(sbf_avatar_path)? }; self.libs .insert(*program_id, (program_name.to_string(), lib)); From 6b520ee4ae5f3e8f9632b30d1490f27683cf4b47 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Fri, 18 Jul 2025 11:40:18 +0300 Subject: [PATCH 76/86] Dispose of the unused so_path for the sbf avatars --- crates/lite-coverage/src/lite_coverage.rs | 8 ++++---- crates/lite-coverage/src/loader.rs | 1 - crates/lite-coverage/src/types.rs | 3 +-- crates/node-litesvm/litesvm/index.ts | 9 +++++---- crates/node-litesvm/litesvm/internal.d.ts | 2 +- crates/node-litesvm/src/lib.rs | 5 ++--- 6 files changed, 13 insertions(+), 15 deletions(-) diff --git a/crates/lite-coverage/src/lite_coverage.rs b/crates/lite-coverage/src/lite_coverage.rs index a58b36aa..71c5e6e4 100644 --- a/crates/lite-coverage/src/lite_coverage.rs +++ b/crates/lite-coverage/src/lite_coverage.rs @@ -56,13 +56,13 @@ impl LiteCoverage { } let mut loader = Loader::new(); - for (program_id, program_name, so_path) in static_programs.iter() { + for (program_id, program_name) in static_programs.iter() { log::info!( "Adding native program (SBF avatar) '{}' with program id: {}", program_name, program_id ); - loader.add_program(so_path, program_name, program_id)?; + loader.add_program(program_name, program_id)?; program_test.add_program(program_name, *program_id, processor!(entrypoint)); } log::info!("Loaded: {:?}", loader); @@ -169,8 +169,8 @@ impl LiteCoverage { .write(true) .open(format!("{}.{}.log", event_file, std::process::id()))?; file.write_all("litesvm=true\n".as_bytes())?; - for (pubkey, name, path) in &progs { - file.write_all(format!("{}={},{}\n", name, pubkey, path).as_bytes())?; + for (pubkey, name) in &progs { + file.write_all(format!("{}={}\n", name, pubkey).as_bytes())?; } for (pubkey, name) in &additional_progs { file.write_all(format!("{}={}\n", name, pubkey).as_bytes())?; diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index 75cd0195..d20baa5d 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -174,7 +174,6 @@ impl Loader { /// Load natively a SBF avatar. pub(crate) fn add_program( &mut self, - _so_path: &str, program_name: &str, program_id: &Pubkey, ) -> LiteCoverageError<()> { diff --git a/crates/lite-coverage/src/types.rs b/crates/lite-coverage/src/types.rs index d2bd6393..ff94156b 100644 --- a/crates/lite-coverage/src/types.rs +++ b/crates/lite-coverage/src/types.rs @@ -9,8 +9,7 @@ use std::{ pub type LiteCoverageError = Result>; pub type ProgramName = String; -pub type Path = String; -pub type NativeProgram = (Pubkey, ProgramName, Path); +pub type NativeProgram = (Pubkey, ProgramName); pub type AdditionalProgram = (Pubkey, ProgramName); /// ProgramTestContextHandle to reconcile sync with async in terms of RefCell borrows. diff --git a/crates/node-litesvm/litesvm/index.ts b/crates/node-litesvm/litesvm/index.ts index df811417..2d39980c 100644 --- a/crates/node-litesvm/litesvm/index.ts +++ b/crates/node-litesvm/litesvm/index.ts @@ -299,12 +299,13 @@ export class LiteSVM { } /** - * TODO add some good description - * @param programId - The program ID. - * @param path - The path to the .so file. + * Adds a SBF avatar (i.e native program) necessary for generating code coverage. + * @param programs - an array of program names. + * @param additionalPrograms - an array of additional SBF programs to load. + * @param payer - payer for the transactions, should be the same as used with the LiteSVM object. */ withCoverage( - programs: Array<[string, Uint8Array, string]>, + programs: Array<[string, Uint8Array]>, additionalPrograms: Array<[string, Uint8Array]>, payer: Uint8Array ) { diff --git a/crates/node-litesvm/litesvm/internal.d.ts b/crates/node-litesvm/litesvm/internal.d.ts index bc2d612c..e6f398d5 100644 --- a/crates/node-litesvm/litesvm/internal.d.ts +++ b/crates/node-litesvm/litesvm/internal.d.ts @@ -560,7 +560,7 @@ export declare class LiteSvm { * Load native programs as well as additional SBF programs in order to * provide code coverage. */ - withCoverage(programs: Array<[string, Uint8Array, string]>, additionalPrograms: Array<[string, Uint8Array]>, payer: Uint8Array): void + withCoverage(programs: Array<[string, Uint8Array]>, additionalPrograms: Array<[string, Uint8Array]>, payer: Uint8Array): void /** Adds am SBF program to the test environment. */ addProgram(programId: Uint8Array, programBytes: Uint8Array): void sendLegacyTransaction(txBytes: Uint8Array): TransactionMetadata | FailedTransactionMetadata diff --git a/crates/node-litesvm/src/lib.rs b/crates/node-litesvm/src/lib.rs index b0619dfe..a7228bb4 100644 --- a/crates/node-litesvm/src/lib.rs +++ b/crates/node-litesvm/src/lib.rs @@ -241,11 +241,11 @@ impl LiteSvm { /// provide code coverage. pub fn with_coverage( &mut self, - programs: Vec<(String, Uint8Array, String)>, + programs: Vec<(String, Uint8Array)>, additional_programs: Vec<(String, Uint8Array)>, payer: Uint8Array, ) -> Result<()> { - let mut progs: Vec<(Pubkey, String, String)> = vec![]; + let mut progs: Vec<(Pubkey, String)> = vec![]; for p in programs { progs.push(( Pubkey::new_from_array( @@ -254,7 +254,6 @@ impl LiteSvm { })?, ), p.0.clone(), - p.2.clone(), )); } let mut additional_progs: Vec<(Pubkey, String)> = vec![]; From a42dbbce2ef17d8d8e977faf4df32e051cc4dddf Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Fri, 18 Jul 2025 11:41:33 +0300 Subject: [PATCH 77/86] silence cargo clippy --- crates/lite-coverage/src/lite_coverage.rs | 2 +- crates/lite-coverage/src/loader.rs | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/crates/lite-coverage/src/lite_coverage.rs b/crates/lite-coverage/src/lite_coverage.rs index 71c5e6e4..9522a1aa 100644 --- a/crates/lite-coverage/src/lite_coverage.rs +++ b/crates/lite-coverage/src/lite_coverage.rs @@ -36,7 +36,7 @@ impl LiteCoverage { use std::sync::Once; static SINGLETON: Once = Once::new(); - if SINGLETON.is_completed() == false { + if !SINGLETON.is_completed() { SINGLETON.call_once(|| {}); } else { return Err(Box::::from( diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index d20baa5d..2c19001d 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -152,9 +152,10 @@ impl Loader { } fn default_sbf_avatar_dirs() -> Vec { - let mut search_path = vec![]; - search_path.push(PathBuf::from("target/debug")); - search_path.push(PathBuf::from("tests/coverage_fixtures")); + let search_path = vec![ + PathBuf::from("target/debug"), + PathBuf::from("tests/coverage_fixtures"), + ]; log::info!(r#"SBF avatars .so|dylib search path: {:?}"#, search_path); search_path } From d45149eb9f5ffe91e5b89643c4492dfc25a352f6 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Fri, 18 Jul 2025 12:04:31 +0300 Subject: [PATCH 78/86] Fix the error msg propagated to caller if unable to find SBF avatar. --- crates/lite-coverage/src/loader.rs | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index 2c19001d..08b95725 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -180,16 +180,17 @@ impl Loader { ) -> LiteCoverageError<()> { // Come up with the so_path of the SBF avatar based on the program_name. // For example: target/debug/libcounter.dylib if program_name is 'counter'. - let sbf_avatar_path = Loader::find_sbf_avatar_file(program_name).ok_or(Box::< - dyn std::error::Error + Send + Sync, - >::from( - r#" -LiteCoverage Loader: Can't find any SBF avatar for program '{program_name}' -For example - looking for: -'target/debug/libcounter.{so|dylib}' if program_name is 'counter' where -the extension .so would be on Linux or .dylib would be on MacOS. -"#, - ))?; + let sbf_avatar_path = + Loader::find_sbf_avatar_file(program_name).ok_or(Box::< + dyn std::error::Error + Send + Sync, + >::from(format!( + r#"LiteCoverage Loader: Can't find any SBF avatar for program '{program_name}'. +For example - looking for 'target/debug/libcounter.so|dylib' or +'tests/coverage_fixtures/libcounter.so|dylib' if program_name is 'counter' where +the extension .so would be on Linux or .dylib would be on MacOS. Mind that +symbolic links are also fine as with the case of using some programs built externally. +"# + )))?; let lib = unsafe { Library::new(sbf_avatar_path)? }; self.libs .insert(*program_id, (program_name.to_string(), lib)); From 0388adefe79c4e3105e277c5a33caa35469c3e9a Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Mon, 21 Jul 2025 10:42:36 +0000 Subject: [PATCH 79/86] =?UTF-8?q?Keep=20the=20Library=20handle=20around=20?= =?UTF-8?q?when=20loading=20a=20shared=20object.=20This=20fixes=20a=20segf?= =?UTF-8?q?ault=20on=20Linux=20while=20still=20working=20on=20MacOS.=20The?= =?UTF-8?q?=20reason:=20-=20Linux=20-=20When=20the=20Library=20(from=20lib?= =?UTF-8?q?loading)=20is=20dropped,=20it=20calls=20dlclose(),=20which=20im?= =?UTF-8?q?mediately=20unloads=20the=20.so=20from=20memory.=20-=20MacOS=20?= =?UTF-8?q?-=20The=20system's=20dlclose()=20is=20effectively=20a=20no-op?= =?UTF-8?q?=20=E2=80=94=20it=20doesn't=20actually=20unload=20the=20library?= =?UTF-8?q?=20from=20memory=20in=20most=20cases.=20This=20makes=20macOS=20?= =?UTF-8?q?more=20permissive=20but=20also=20more=20misleading=20=E2=80=94?= =?UTF-8?q?=20it=20hides=20bugs=20that=20will=20break=20on=20Linux.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/lite-coverage/src/lite_coverage.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crates/lite-coverage/src/lite_coverage.rs b/crates/lite-coverage/src/lite_coverage.rs index 9522a1aa..40775b1a 100644 --- a/crates/lite-coverage/src/lite_coverage.rs +++ b/crates/lite-coverage/src/lite_coverage.rs @@ -23,6 +23,8 @@ pub struct LiteCoverage { pub programs: Vec, pub pt_context: Rc>>, rt: Arc, + #[allow(dead_code)] + loader: Rc, } impl LiteCoverage { @@ -77,6 +79,7 @@ impl LiteCoverage { pt_context: Rc::new(RefCell::new(Some(pt_context))), programs, rt: Arc::new(rt), + loader: Rc::new(loader), }) } From 939a849b0b260195b80a436ca30929abb0cd4ec2 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Tue, 22 Jul 2025 08:51:10 +0300 Subject: [PATCH 80/86] Now that the stubs api is a stubsv2 and it is renamed to just stubs start using it through the master branches of solana-program-stubs. --- Cargo.lock | 2 +- Cargo.toml | 2 +- crates/lite-coverage/src/loader.rs | 8 ++++---- crates/lite-coverage/src/stubs.rs | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ef7c709d..d39e4f55 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5693,7 +5693,7 @@ dependencies = [ [[package]] name = "solana-program-stubs" version = "0.1.0" -source = "git+ssh://git@github.com/procdump/sol-stubs.git?branch=stubsv2_pinocchio#50f40cfae35aa8c2e5e27a259752946514da9190" +source = "git+ssh://git@github.com/procdump/sol-stubs.git#16cc5e0b3f084330d27e5c2a4c4c352531667c35" dependencies = [ "lazy_static", ] diff --git a/Cargo.toml b/Cargo.toml index 886ea11e..c979e30a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -92,7 +92,7 @@ test-log = "0.2" thiserror = "2.0" tokio = "1.35" lite-coverage = { path = "crates/lite-coverage" } -solana-program-stubs = { git = "ssh://git@github.com/procdump/sol-stubs.git", branch = "stubsv2_pinocchio", features = [ "loader_stubs" ] } +solana-program-stubs = { git = "ssh://git@github.com/procdump/sol-stubs.git", features = [ "loader_stubs" ] } [profile.bench] debug = true diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index 08b95725..e0cdbed8 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -1,6 +1,6 @@ use crate::{ sbf, - stubs::{StubsManager, SyscallStubsApi2, UnimplementedSyscallStubs, WrapperSyscallStubs}, + stubs::{StubsManager, SyscallStubsApi, UnimplementedSyscallStubs, WrapperSyscallStubs}, types::LiteCoverageError, }; use core::str; @@ -16,7 +16,7 @@ use std::{ }; type ProgramEntrypoint = unsafe extern "C" fn(input: *mut u8) -> u64; -type ProgramSetSyscallStubsApi = unsafe extern "C" fn(stubs_api: SyscallStubsApi2); +type ProgramSetSyscallStubsApi = unsafe extern "C" fn(stubs_api: SyscallStubsApi); lazy_static::lazy_static! ( pub static ref PROGRAMS_MAP: Mutex>> = Mutex::new(HashMap::new()); @@ -144,7 +144,7 @@ impl Loader { // Now for each program set the appropriate stubs for (program_id, _) in self.libs.iter() { // Now create the C interface so that the solana programs can reach our SYSCALL_STUBS! - let stubs_api = SyscallStubsApi2::new(); + let stubs_api = SyscallStubsApi::new(); // Pass it to the loaded smart contract! self.set_syscall_stubs_api(program_id, stubs_api)?; } @@ -205,7 +205,7 @@ symbolic links are also fine as with the case of using some programs built exter pub(crate) fn set_syscall_stubs_api( &self, program_id: &Pubkey, - stubs_api: SyscallStubsApi2, + stubs_api: SyscallStubsApi, ) -> LiteCoverageError<()> { let res: Result, libloading::Error> = unsafe { self.libs diff --git a/crates/lite-coverage/src/stubs.rs b/crates/lite-coverage/src/stubs.rs index 4b3fee5d..29c360b8 100644 --- a/crates/lite-coverage/src/stubs.rs +++ b/crates/lite-coverage/src/stubs.rs @@ -1,7 +1,7 @@ use std::sync::{Arc, RwLock}; use solana_program_error::ProgramResult; -use solana_program_stubs::declare_sol_loader_stubsv2; +use solana_program_stubs::declare_sol_loader_stubs; use solana_sysvar::program_stubs::SyscallStubs; use solana_instruction::Instruction; @@ -9,7 +9,7 @@ use solana_program::instruction::AccountMeta; use solana_pubkey::Pubkey; use solana_sysvar::slot_history::AccountInfo; -declare_sol_loader_stubsv2!(); +declare_sol_loader_stubs!(); /// Main logic behind the StubsManager is explained in loader::adjust_stubs. pub struct StubsManager; From b3b6588a14db609fb559a8f6178e7bceb770fe28 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Tue, 22 Jul 2025 16:16:30 +0300 Subject: [PATCH 81/86] Start using the published solana-program-stubs crate --- Cargo.lock | 3 ++- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 921fde36..7ee5c727 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5734,7 +5734,8 @@ dependencies = [ [[package]] name = "solana-program-stubs" version = "0.1.0" -source = "git+ssh://git@github.com/procdump/sol-stubs.git#16cc5e0b3f084330d27e5c2a4c4c352531667c35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92919225911e3dcfe67af6d012aa567ac812945db97b15141859bf4e28fa117c" dependencies = [ "lazy_static", ] diff --git a/Cargo.toml b/Cargo.toml index 5f2a4d9f..9ded9846 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -92,7 +92,7 @@ test-log = "0.2" thiserror = "2.0" tokio = "1.35" lite-coverage = { path = "crates/lite-coverage" } -solana-program-stubs = { git = "ssh://git@github.com/procdump/sol-stubs.git", features = [ "loader_stubs" ] } +solana-program-stubs = { version = "0.1.0", features = [ "loader_stubs" ] } [profile.bench] debug = true From f96adf4734f23ccd10c15fa891c70eb4872e5147 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Tue, 22 Jul 2025 16:19:37 +0300 Subject: [PATCH 82/86] Start using the solana-program-test at limechain --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7ee5c727..3029ea9b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5743,7 +5743,7 @@ dependencies = [ [[package]] name = "solana-program-test" version = "2.2.4" -source = "git+ssh://git@github.com/vlady-kotsev/program-test.git?branch=cov#d2399b3ef867f62bed7220fb2128ee7888393b70" +source = "git+https://github.com/LimeChain/program-test.git#674912ed8959fda0b703dfd406b31a81767e9a76" dependencies = [ "assert_matches", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index 9ded9846..3fe5bd94 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -62,7 +62,7 @@ solana-program-option = "2.2" solana-program-pack = "2.2" solana-program-runtime = ">=2.2,<=2.2.4" #solana-program-test = "2.2" -solana-program-test = { git = "ssh://git@github.com/vlady-kotsev/program-test.git", branch = "cov" } +solana-program-test = { git = "https://github.com/LimeChain/program-test.git" } solana-pubkey = "2.2" solana-rent = "2.2" solana-runtime-transaction = "2.2" From 415f32c57375d385d510aeef6ea646d5966b8ab0 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Thu, 24 Jul 2025 09:44:12 +0300 Subject: [PATCH 83/86] Bugfix: when advancing for accounts on the new_input buffer use the original_data_len as done in solana-bpf-loader-program's deserialize_parameters_aligned. Mind that the padding in the input should hold the original_data_len but nevertheless have the lens from the serialized account meta data after the serialization. --- crates/lite-coverage/src/loader.rs | 17 +++++++---------- crates/lite-coverage/src/sbf.rs | 21 ++++++++++++++------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index e0cdbed8..a54ddd5b 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -41,28 +41,25 @@ pub fn entrypoint(program_id: &Pubkey, accounts: &[AccountInfo], _data: &[u8]) - .get_current_instruction_context() .map_err(|_| ProgramError::InvalidArgument)?; - let (mut parameter_bytes, _, _) = + let (mut parameter_bytes, _mem_region, serialized_account_meta_data) = solana_bpf_loader_program::serialization::serialize_parameters( transaction_context, instruction_context, true, // copy_account_data // There is no VM so direct mapping can not be implemented here ) .map_err(|_| ProgramError::InvalidArgument)?; + let original_data_lens: Vec<_> = serialized_account_meta_data + .iter() + .map(|sam| sam.original_data_len) + .collect(); - // Make a copy prior to calling the entrypoint fn, we'll use it - // for deserialization of the post-instruction updated input. - let mut parameter_bytes_copy = parameter_bytes.clone(); let res = unsafe { entry(parameter_bytes.as_slice().as_ptr() as *mut _) }; if res == 0 { - // Deserialize data back into instruction params advancing on the old input - // while using values from the new input. The reason for this is that - // some programs may repurpose and change the value of bytes in the old input which - // in the end may break the canonical deserialization. - // So try to to do our best to extract what we need while following the correct format. + // Deserialize data back into instruction params. let (_, updated_account_infos, _) = unsafe { sbf::deserialize_updated_account_infos( - &mut parameter_bytes_copy.as_slice_mut()[0] as *const u8, &mut parameter_bytes.as_slice_mut()[0] as *mut u8, + &original_data_lens, ) }; diff --git a/crates/lite-coverage/src/sbf.rs b/crates/lite-coverage/src/sbf.rs index 902611af..be826119 100644 --- a/crates/lite-coverage/src/sbf.rs +++ b/crates/lite-coverage/src/sbf.rs @@ -10,6 +10,7 @@ use solana_sysvar::slot_history::AccountInfo; unsafe fn deserialize_account_info<'a>( mut offset: usize, new_input: *mut u8, + original_data_len: usize, ) -> (AccountInfo<'a>, usize) { #[allow(clippy::cast_ptr_alignment)] let is_signer = *(new_input.add(offset) as *const u8) != 0; @@ -23,7 +24,10 @@ unsafe fn deserialize_account_info<'a>( let executable = *(new_input.add(offset) as *const u8) != 0; offset += size_of::(); - // padding + // padding or original_data_len + let _original_data_len_from_new_input = *(new_input.add(offset) as *const u32); + // TODO: Put this assert? Does pinocchio update the padding to the original data len? + // assert!(original_data_len == _original_data_len_from_new_input as usize); offset += size_of::(); let key: &Pubkey = &*(new_input.add(offset) as *const Pubkey); @@ -45,7 +49,8 @@ unsafe fn deserialize_account_info<'a>( let data = std::rc::Rc::new(std::cell::RefCell::new({ std::slice::from_raw_parts_mut(new_input.add(offset), data_len) })); - offset += data_len + MAX_PERMITTED_DATA_INCREASE; + // use original_data_len when advancing as done at deserialize_parameters_aligned + offset += original_data_len + MAX_PERMITTED_DATA_INCREASE; offset += (offset as *const u8).align_offset(BPF_ALIGN_OF_U128); // padding #[allow(clippy::cast_ptr_alignment)] @@ -82,25 +87,27 @@ unsafe fn deserialize_instruction_data<'a>(input: *mut u8, mut offset: usize) -> #[allow(clippy::arithmetic_side_effects)] pub(crate) unsafe fn deserialize_updated_account_infos<'a>( - old_input: *const u8, new_input: *mut u8, + original_data_lens: &Vec, ) -> (&'a Pubkey, Vec>, &'a [u8]) { let mut offset: usize = 0; // Number of accounts present #[allow(clippy::cast_ptr_alignment)] - let num_accounts = *(old_input.add(offset) as *const u64) as usize; + let num_accounts = *(new_input.add(offset) as *const u64) as usize; offset += size_of::(); // Account Infos let mut accounts = Vec::with_capacity(num_accounts); - for _ in 0..num_accounts { - let dup_info = *(old_input.add(offset)); + for i in 0..num_accounts { + let dup_info = *(new_input.add(offset)); offset += size_of::(); if dup_info == NON_DUP_MARKER { - let (account_info, new_offset) = deserialize_account_info(offset, new_input); + let original_data_len = original_data_lens[i]; + let (account_info, new_offset) = + deserialize_account_info(offset, new_input, original_data_len); offset = new_offset; accounts.push(account_info); } else { From e94cc5a0499a5d11746a3229be4ec61667e53696 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Thu, 24 Jul 2025 11:11:45 +0300 Subject: [PATCH 84/86] Silence cargo clippy --- crates/lite-coverage/src/sbf.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/lite-coverage/src/sbf.rs b/crates/lite-coverage/src/sbf.rs index be826119..2e80e149 100644 --- a/crates/lite-coverage/src/sbf.rs +++ b/crates/lite-coverage/src/sbf.rs @@ -88,7 +88,7 @@ unsafe fn deserialize_instruction_data<'a>(input: *mut u8, mut offset: usize) -> #[allow(clippy::arithmetic_side_effects)] pub(crate) unsafe fn deserialize_updated_account_infos<'a>( new_input: *mut u8, - original_data_lens: &Vec, + original_data_lens: &[usize], ) -> (&'a Pubkey, Vec>, &'a [u8]) { let mut offset: usize = 0; @@ -101,6 +101,7 @@ pub(crate) unsafe fn deserialize_updated_account_infos<'a>( // Account Infos let mut accounts = Vec::with_capacity(num_accounts); + #[allow(clippy::needless_range_loop)] for i in 0..num_accounts { let dup_info = *(new_input.add(offset)); offset += size_of::(); From e2afe0b9536747d2fc08d5e19454409793275929 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Wed, 30 Jul 2025 10:00:18 +0300 Subject: [PATCH 85/86] Equalize ProgramTestContext's recent blockhash with transaction's. This avoids the need to pre-sign with payer as done before. --- Cargo.lock | 4 +++- crates/lite-coverage/src/lite_coverage.rs | 25 +++++++++-------------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3029ea9b..7d41b97c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5743,7 +5743,7 @@ dependencies = [ [[package]] name = "solana-program-test" version = "2.2.4" -source = "git+https://github.com/LimeChain/program-test.git#674912ed8959fda0b703dfd406b31a81767e9a76" +source = "git+https://github.com/LimeChain/program-test.git#7186116f37576557960adabd3fb5b491650a0b01" dependencies = [ "assert_matches", "async-trait", @@ -6098,6 +6098,7 @@ dependencies = [ "solana-svm", "solana-svm-rent-collector", "solana-svm-transaction", + "solana-system-program", "solana-timings", "solana-transaction-status-client-types", "solana-unified-scheduler-logic", @@ -6568,6 +6569,7 @@ dependencies = [ "itertools 0.12.1", "log", "percentage", + "qualifier_attr", "serde", "serde_derive", "solana-account", diff --git a/crates/lite-coverage/src/lite_coverage.rs b/crates/lite-coverage/src/lite_coverage.rs index 40775b1a..58154aaf 100644 --- a/crates/lite-coverage/src/lite_coverage.rs +++ b/crates/lite-coverage/src/lite_coverage.rs @@ -11,7 +11,6 @@ use { solana_account::AccountSharedData, solana_program::pubkey::Pubkey, solana_program_test::{processor, ProgramTest, ProgramTestContext}, - solana_signer::Signer, solana_transaction::versioned::VersionedTransaction, std::{cell::RefCell, sync::Arc}, tokio::runtime::Runtime, @@ -100,26 +99,22 @@ impl LiteCoverage { } } - /// Sign with our payer while also using our latest blockhash. - async fn re_sign_tx( + /// Register the transaction's recent blockhash into ProgramTestContext. + /// This avoids the need to pre-sign with payer. + async fn register_recent_blockhash_from_transaction( &self, tx: &VersionedTransaction, - ) -> LiteCoverageError { - // TODO tx must be resigned for all signers + ) -> LiteCoverageError<()> { let pt_context = self.get_program_test_context(); let ctx = pt_context .as_ref() .ok_or(Box::::from( "Missing ProgramTestContext", ))?; - let payer = ctx.payer.insecure_clone(); - let recent_blockhash = ctx.banks_client.get_latest_blockhash().await?; - - let mut trans = tx.clone().into_legacy_transaction().unwrap(); - trans.message.recent_blockhash = recent_blockhash; - trans.message.account_keys[0] = payer.pubkey(); - trans.sign(&[&payer], recent_blockhash); - Ok(VersionedTransaction::from(trans)) + + let trans = tx.clone().into_legacy_transaction().unwrap(); + ctx.register_recent_blockhash(&trans.message.recent_blockhash, None); + Ok(()) } /// Send the transaction to the natively loaded SBF avatars already prepared for @@ -133,7 +128,7 @@ impl LiteCoverage { for (account_pubkey, account_data) in accounts { self.add_account(account_pubkey, account_data); } - let re_signed_tx = self.re_sign_tx(&tx).await?; + self.register_recent_blockhash_from_transaction(&tx).await?; let pt_context = self.get_program_test_context(); let ctx = @@ -144,7 +139,7 @@ impl LiteCoverage { ))?; let res = ctx .banks_client - .process_transaction_with_metadata(re_signed_tx) + .process_transaction_with_metadata(tx) .await?; log::info!("LiteCoverage transaction result: {:#?}", res); From 4c8394ef34926c59804e50c56d2f2ed15d582285 Mon Sep 17 00:00:00 2001 From: Boris Astardzhiev Date: Tue, 19 Aug 2025 10:46:01 +0300 Subject: [PATCH 86/86] Adapt to 2.3. TODO: solana-program-test --- Cargo.lock | 4 +--- Cargo.toml | 2 +- crates/lite-coverage/Cargo.toml | 3 +-- crates/lite-coverage/src/lite_coverage.rs | 2 +- crates/lite-coverage/src/loader.rs | 14 +++++++++----- crates/lite-coverage/src/stubs.rs | 3 +-- crates/lite-coverage/src/types.rs | 2 +- crates/node-litesvm/litesvm/internal.d.ts | 5 +++++ crates/node-litesvm/src/lib.rs | 2 +- 9 files changed, 21 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a93fd79e..643cbf03 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2553,12 +2553,11 @@ dependencies = [ "log", "serde", "solana-account", - "solana-bpf-loader-program", "solana-instruction", "solana-keypair", - "solana-program", "solana-program-entrypoint", "solana-program-error", + "solana-program-runtime", "solana-program-stubs", "solana-program-test", "solana-pubkey", @@ -6671,7 +6670,6 @@ dependencies = [ "itertools 0.12.1", "log", "percentage", - "qualifier_attr", "serde", "serde_derive", "solana-account", diff --git a/Cargo.toml b/Cargo.toml index 1874751c..e6a7a644 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,7 +57,7 @@ solana-nonce = "2.2" solana-nonce-account = "2.2" solana-precompile-error = "2.2" solana-program-error = "2.2" -solana-program-entrypoint = "2.2" +solana-program-entrypoint = "2.3" solana-program-option = "2.2" solana-program-pack = "2.2" solana-program-runtime = "2.3" diff --git a/crates/lite-coverage/Cargo.toml b/crates/lite-coverage/Cargo.toml index 97fd0552..2a357e9b 100644 --- a/crates/lite-coverage/Cargo.toml +++ b/crates/lite-coverage/Cargo.toml @@ -13,10 +13,9 @@ serde = { workspace = true } jsonrpc-core = "18.0.0" bs58 = { version = "0.5.1", default-features = false } borsh = "1.5.7" +solana-program-runtime = { workspace = true } solana-program-test = { workspace = true } solana-account = { workspace = true } -solana-bpf-loader-program.workspace = true -solana-program = { workspace = true } solana-keypair = { workspace = true } solana-signer = { workspace = true } solana-transaction = { workspace = true } diff --git a/crates/lite-coverage/src/lite_coverage.rs b/crates/lite-coverage/src/lite_coverage.rs index 58154aaf..039b51e3 100644 --- a/crates/lite-coverage/src/lite_coverage.rs +++ b/crates/lite-coverage/src/lite_coverage.rs @@ -1,6 +1,7 @@ use std::{io::Write, rc::Rc}; use solana_keypair::Keypair; +use solana_pubkey::Pubkey; use crate::{ loader::{entrypoint, Loader}, @@ -9,7 +10,6 @@ use crate::{ }; use { solana_account::AccountSharedData, - solana_program::pubkey::Pubkey, solana_program_test::{processor, ProgramTest, ProgramTestContext}, solana_transaction::versioned::VersionedTransaction, std::{cell::RefCell, sync::Arc}, diff --git a/crates/lite-coverage/src/loader.rs b/crates/lite-coverage/src/loader.rs index a54ddd5b..60fdfb08 100644 --- a/crates/lite-coverage/src/loader.rs +++ b/crates/lite-coverage/src/loader.rs @@ -5,10 +5,9 @@ use crate::{ }; use core::str; use libloading::{Library, Symbol}; -use solana_program::{ - account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError, - program_stubs::set_syscall_stubs, pubkey::Pubkey, -}; +use solana_program_error::{ProgramError, ProgramResult}; +use solana_pubkey::Pubkey; +use solana_sysvar::{program_stubs::set_syscall_stubs, slot_history::AccountInfo}; use std::{ collections::HashMap, path::PathBuf, @@ -41,11 +40,16 @@ pub fn entrypoint(program_id: &Pubkey, accounts: &[AccountInfo], _data: &[u8]) - .get_current_instruction_context() .map_err(|_| ProgramError::InvalidArgument)?; + let mask_out_rent_epoch_in_vm_serialization = invoke_context + .get_feature_set() + .mask_out_rent_epoch_in_vm_serialization; + let (mut parameter_bytes, _mem_region, serialized_account_meta_data) = - solana_bpf_loader_program::serialization::serialize_parameters( + solana_program_runtime::serialization::serialize_parameters( transaction_context, instruction_context, true, // copy_account_data // There is no VM so direct mapping can not be implemented here + mask_out_rent_epoch_in_vm_serialization, ) .map_err(|_| ProgramError::InvalidArgument)?; let original_data_lens: Vec<_> = serialized_account_meta_data diff --git a/crates/lite-coverage/src/stubs.rs b/crates/lite-coverage/src/stubs.rs index 29c360b8..795b3c38 100644 --- a/crates/lite-coverage/src/stubs.rs +++ b/crates/lite-coverage/src/stubs.rs @@ -4,8 +4,7 @@ use solana_program_error::ProgramResult; use solana_program_stubs::declare_sol_loader_stubs; use solana_sysvar::program_stubs::SyscallStubs; -use solana_instruction::Instruction; -use solana_program::instruction::AccountMeta; +use solana_instruction::{AccountMeta, Instruction}; use solana_pubkey::Pubkey; use solana_sysvar::slot_history::AccountInfo; diff --git a/crates/lite-coverage/src/types.rs b/crates/lite-coverage/src/types.rs index ff94156b..13fcf621 100644 --- a/crates/lite-coverage/src/types.rs +++ b/crates/lite-coverage/src/types.rs @@ -1,5 +1,5 @@ -use solana_program::pubkey::Pubkey; use solana_program_test::ProgramTestContext; +use solana_pubkey::Pubkey; use std::{ cell::RefCell, error::Error, diff --git a/crates/node-litesvm/litesvm/internal.d.ts b/crates/node-litesvm/litesvm/internal.d.ts index b6cc323b..dc7e57d3 100644 --- a/crates/node-litesvm/litesvm/internal.d.ts +++ b/crates/node-litesvm/litesvm/internal.d.ts @@ -315,6 +315,11 @@ export declare class LiteSvm { airdrop(pubkey: Uint8Array, lamports: bigint): TransactionMetadata | FailedTransactionMetadata | null /** Adds am SBF program to the test environment from the file specified. */ addProgramFromFile(programId: Uint8Array, path: string): void + /** + * Load native programs as well as additional SBF programs in order to + * provide code coverage. + */ + withCoverage(programs: Array<[string, Uint8Array]>, additionalPrograms: Array<[string, Uint8Array]>, payer: Uint8Array): void /** Adds am SBF program to the test environment. */ addProgram(programId: Uint8Array, programBytes: Uint8Array): void sendLegacyTransaction(txBytes: Uint8Array): TransactionMetadata | FailedTransactionMetadata diff --git a/crates/node-litesvm/src/lib.rs b/crates/node-litesvm/src/lib.rs index 58e51dc0..d417a54f 100644 --- a/crates/node-litesvm/src/lib.rs +++ b/crates/node-litesvm/src/lib.rs @@ -272,7 +272,7 @@ impl LiteSvm { .with_coverage( progs, additional_progs, - Keypair::from_bytes(&payer) + Keypair::try_from(&payer[..]) .map_err(|_| Error::new(Status::InvalidArg, "Invalid Payer Keypair bytes"))?, ) .map_err(|e| {