From 12729e969b685ed0069b7922a012c5311a8bbfd1 Mon Sep 17 00:00:00 2001 From: Gabriele Picco Date: Thu, 18 Jun 2026 11:59:47 +0200 Subject: [PATCH 1/4] Support sBPF v3 loader programs --- Cargo.lock | 367 ++++++++++++++++------ Cargo.toml | 33 +- svm/src/account_loader.rs | 1 + svm/src/message_processor.rs | 6 +- svm/src/rent_calculator.rs | 2 +- svm/src/transaction_account_state_info.rs | 10 +- svm/src/transaction_commit_result.rs | 3 +- svm/src/transaction_execution_result.rs | 2 +- svm/src/transaction_processor.rs | 70 +++-- transaction-context/Cargo.toml | 2 +- transaction-context/src/lib.rs | 98 +++++- 11 files changed, 441 insertions(+), 153 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f53f042..8ee7421 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,20 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "agave-bls12-381" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "210b1ef312273aa81ccb4c52687d96e3cf07621f3619a7998be20eb9741b08e3" +dependencies = [ + "blst", + "blstrs", + "bytemuck", + "bytemuck_derive", + "group", + "pairing", +] + [[package]] name = "agave-logger" version = "3.1.13" @@ -16,10 +30,11 @@ dependencies = [ [[package]] name = "agave-syscalls" -version = "3.1.12" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5212f0b24fc37d4c844ae25b563d0cf5587d092912820c40f88d4b9b301148f8" +checksum = "84debd4abe0cbab5a6aac2ee50e3969ef0e0961f7dff7e8f96bda0be7998bca2" dependencies = [ + "agave-bls12-381", "bincode", "libsecp256k1", "num-traits", @@ -31,14 +46,14 @@ dependencies = [ "solana-clock", "solana-cpi", "solana-curve25519", - "solana-hash 3.1.0", + "solana-hash 4.2.0", "solana-instruction", "solana-keccak-hasher", "solana-loader-v3-interface", "solana-poseidon", "solana-program-entrypoint", - "solana-program-runtime", - "solana-pubkey 3.0.0", + "solana-program-runtime 4.0.0", + "solana-pubkey 4.1.0", "solana-sbpf", "solana-sdk-ids", "solana-secp256k1-recover", @@ -526,6 +541,34 @@ dependencies = [ "hybrid-array", ] +[[package]] +name = "blst" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcdb4c7013139a150f9fc55d123186dbfaba0d912817466282c73ac49e71fb45" +dependencies = [ + "cc", + "glob", + "threadpool", + "zeroize", +] + +[[package]] +name = "blstrs" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a8a8ed6fefbeef4a8c7b460e4110e12c5e22a5b7cf32621aae6ad650c4dcf29" +dependencies = [ + "blst", + "byte-slice-cast", + "ff", + "group", + "pairing", + "rand_core 0.6.4", + "serde", + "subtle", +] + [[package]] name = "borsh" version = "1.6.1" @@ -575,6 +618,12 @@ dependencies = [ "serde", ] +[[package]] +name = "byte-slice-cast" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7575182f7272186991736b70173b0ea045398f984bf5ebbb3804736ce1330c9d" + [[package]] name = "bytemuck" version = "1.25.0" @@ -1007,9 +1056,9 @@ dependencies = [ [[package]] name = "enum-iterator" -version = "1.5.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fd242f399be1da0a5354aa462d57b4ab2b4ee0683cc552f7c007d2d12d36e94" +checksum = "a4549325971814bda7a44061bf3fe7e487d447cba01e4220a4b454d630d7a016" dependencies = [ "enum-iterator-derive", ] @@ -1096,6 +1145,7 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" dependencies = [ + "bitvec", "rand_core 0.6.4", "subtle", ] @@ -1223,6 +1273,12 @@ dependencies = [ "wasip2", ] +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + [[package]] name = "group" version = "0.13.0" @@ -1230,7 +1286,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", + "rand 0.8.6", "rand_core 0.6.4", + "rand_xorshift", "subtle", ] @@ -1273,6 +1331,12 @@ version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" +[[package]] +name = "hermit-abi" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" + [[package]] name = "hex" version = "0.4.3" @@ -1388,6 +1452,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + [[package]] name = "jiff" version = "0.2.23" @@ -1644,6 +1717,16 @@ dependencies = [ "autocfg", ] +[[package]] +name = "num_cpus" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" +dependencies = [ + "hermit-abi", + "libc", +] + [[package]] name = "num_enum" version = "0.7.6" @@ -1738,6 +1821,15 @@ version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" +[[package]] +name = "pairing" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fec4625e73cf41ef4bb6846cafa6d44736525f442ba45e407c4a000a13996f" +dependencies = [ + "group", +] + [[package]] name = "parking_lot" version = "0.12.5" @@ -1996,6 +2088,15 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand_xorshift" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +dependencies = [ + "rand_core 0.6.4", +] + [[package]] name = "rand_xoshiro" version = "0.6.0" @@ -2378,7 +2479,7 @@ dependencies = [ "solana-program-error", "solana-sanitize", "solana-sha256-hasher", - "wincode", + "wincode 0.5.3", ] [[package]] @@ -2420,7 +2521,7 @@ checksum = "7116e1d942a2432ca3f514625104757ab8a56233787e95144c93950029e31176" dependencies = [ "blake3", "solana-define-syscall 4.0.1", - "solana-hash 4.3.0", + "solana-hash 4.2.0", ] [[package]] @@ -2440,9 +2541,9 @@ dependencies = [ [[package]] name = "solana-bpf-loader-program" -version = "3.1.12" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "044a6c5327755992853454ea5ec495edd987dab53a6f9029e695bf0d43ab55dc" +checksum = "219bfba64973ac9e64aa181f03fd56ac319e2d50d8a23d16c54bbd7fa9807a47" dependencies = [ "agave-syscalls", "bincode", @@ -2455,15 +2556,15 @@ dependencies = [ "solana-loader-v4-interface", "solana-packet", "solana-program-entrypoint", - "solana-program-runtime", - "solana-pubkey 3.0.0", + "solana-program-runtime 4.0.0", + "solana-pubkey 4.1.0", "solana-sbpf", "solana-sdk-ids", "solana-svm-feature-set", "solana-svm-log-collector", "solana-svm-measure", "solana-svm-type-overrides", - "solana-system-interface 2.0.0", + "solana-system-interface 3.1.0", "solana-transaction-context", ] @@ -2482,12 +2583,12 @@ dependencies = [ [[package]] name = "solana-compute-budget" -version = "3.1.12" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55267bed68ed018f6b2fd5e2f7ae694cbcb1a9bfd98b749803e94be7b5f08774" +checksum = "b591fbaed6d9ab4cba6a5a82eb5df208072ced2e5b74c59e9d309ff87af0615f" dependencies = [ "solana-fee-structure", - "solana-program-runtime", + "solana-program-runtime 4.0.0", ] [[package]] @@ -2502,11 +2603,11 @@ dependencies = [ [[package]] name = "solana-compute-budget-program" -version = "3.1.12" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcc87532d1ca1b871204cdb103514182bd9460cea403c16f22ca49e1ba063ea1" +checksum = "a22bcf5088ebe5cb2aa548580d0a466de813032b425707a7745a2a63a7764cdc" dependencies = [ - "solana-program-runtime", + "solana-program-runtime 4.0.0", ] [[package]] @@ -2519,20 +2620,20 @@ dependencies = [ "solana-define-syscall 4.0.1", "solana-instruction", "solana-program-error", - "solana-pubkey 4.2.0", + "solana-pubkey 4.1.0", "solana-stable-layout", ] [[package]] name = "solana-curve25519" -version = "3.1.12" +version = "4.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eb091ac9c1e4d51c3cd1893444aee607cd1b0173c4ba0b557f8960844f44a1b" +checksum = "14b4d2a4bf0d0b0a86c22111917e86e8bd39a7b31420fb2c7d73eb83761fc7af" dependencies = [ "bytemuck", "bytemuck_derive", "curve25519-dalek 4.1.3", - "solana-define-syscall 3.0.0", + "solana-define-syscall 5.1.0", "subtle", "thiserror 2.0.18", ] @@ -2575,7 +2676,7 @@ checksum = "f5e7b0ba210593ba8ddd39d6d234d81795d1671cebf3026baa10d5dc23ac42f0" dependencies = [ "serde", "serde_derive", - "solana-hash 4.3.0", + "solana-hash 4.2.0", "solana-sdk-ids", "solana-sdk-macro", "solana-sysvar-id", @@ -2583,9 +2684,9 @@ dependencies = [ [[package]] name = "solana-epoch-schedule" -version = "3.1.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce264b7b42322325947c4136a09460bf5c73d9aa8262c9b0a2064be63ba8639" +checksum = "6e5481e72cc4d52c169db73e4c0cd16de8bc943078aac587ec4817a75cc6388f" dependencies = [ "serde", "serde_derive", @@ -2613,9 +2714,9 @@ checksum = "5e2abdb1223eea8ec64136f39cb1ffcf257e00f915c957c35c0dd9e3f4e700b0" [[package]] name = "solana-frozen-abi" -version = "3.3.0" +version = "3.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f104c19593391e9b8a6d8eedf4df92ddc7908949ee3740927c05ebef5fed6e2c" +checksum = "20f53dbf77043d26b7a2f5f516f704b35daf9d0be036fe8e64c3f92924292c61" dependencies = [ "bincode", "boxcar", @@ -2635,7 +2736,6 @@ dependencies = [ "sha2 0.10.9", "solana-frozen-abi-macro", "thiserror 2.0.18", - "wincode", ] [[package]] @@ -2655,14 +2755,14 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "337c246447142f660f778cf6cb582beba8e28deb05b3b24bfb9ffd7c562e5f41" dependencies = [ - "solana-hash 4.3.0", + "solana-hash 4.2.0", ] [[package]] name = "solana-hash" -version = "4.3.0" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1b113239362cee7093bfb250467138f079a2a03673181dc15bff6ccd677912d" +checksum = "8064ea1d591ec791be95245058ca40f4f5345d390c200069d0f79bbf55bfae55" dependencies = [ "borsh", "bytemuck", @@ -2672,21 +2772,21 @@ dependencies = [ "serde_derive", "solana-atomic-u64", "solana-sanitize", - "wincode", + "wincode 0.4.9", ] [[package]] name = "solana-instruction" -version = "3.4.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37ebb0ffd19263051bc3f683fcc086134b8ff23af894dcb63f7563c7137b42f1" +checksum = "a97881335fc698deb46c6571945969aae6d93a14e2fff792a368b4fac872f116" dependencies = [ "bincode", "serde", "serde_derive", "solana-define-syscall 5.1.0", "solana-instruction-error", - "solana-pubkey 4.2.0", + "solana-pubkey 4.1.0", ] [[package]] @@ -2727,7 +2827,7 @@ checksum = "ed1c0d16d6fdeba12291a1f068cdf0d479d9bff1141bf44afd7aa9d485f65ef8" dependencies = [ "sha3", "solana-define-syscall 4.0.1", - "solana-hash 4.3.0", + "solana-hash 4.2.0", ] [[package]] @@ -2769,9 +2869,9 @@ dependencies = [ "serde_bytes", "serde_derive", "solana-instruction", - "solana-pubkey 4.2.0", + "solana-pubkey 4.1.0", "solana-sdk-ids", - "solana-system-interface 3.2.0", + "solana-system-interface 3.1.0", ] [[package]] @@ -2791,9 +2891,9 @@ dependencies = [ [[package]] name = "solana-loader-v4-program" -version = "3.1.12" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e88b98ba6b408fe6fcf180784fc378d07ae63100c7dd413ff97474b6de30c5d" +checksum = "4b5191cd34f04e4ec9fd5f2ac8a431ba9ffd6c827511fd35f2cae0256a0c6b12" dependencies = [ "log", "solana-account", @@ -2803,8 +2903,8 @@ dependencies = [ "solana-loader-v3-interface", "solana-loader-v4-interface", "solana-packet", - "solana-program-runtime", - "solana-pubkey 3.0.0", + "solana-program-runtime 4.0.0", + "solana-pubkey 4.1.0", "solana-sbpf", "solana-sdk-ids", "solana-svm-log-collector", @@ -2825,7 +2925,7 @@ dependencies = [ "serde", "serde_derive", "solana-address 2.6.0", - "solana-hash 4.3.0", + "solana-hash 4.2.0", "solana-instruction", "solana-sanitize", "solana-sdk-ids", @@ -2850,15 +2950,15 @@ checksum = "ae8dd4c280dca9d046139eb5b7a5ac9ad10403fbd64964c7d7571214950d758f" [[package]] name = "solana-nonce" -version = "3.2.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d95dbc9f2e33b6c10e231df15cb2a3bff9ea7eab6347f9e316fe75c97fd67bbb" +checksum = "cbc469152a63284ef959b80c59cda015262a021da55d3b8fe42171d89c4b64f8" dependencies = [ "serde", "serde_derive", "solana-fee-calculator", - "solana-hash 4.3.0", - "solana-pubkey 4.2.0", + "solana-hash 4.2.0", + "solana-pubkey 4.1.0", "solana-sha256-hasher", ] @@ -2876,24 +2976,25 @@ dependencies = [ [[package]] name = "solana-packet" -version = "3.0.0" +version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6edf2f25743c95229ac0fdc32f8f5893ef738dbf332c669e9861d33ddb0f469d" +checksum = "0ad62e1045c2347a0c0e219a6ceb0abfe904be622920996bfcac8d116fabe3c7" dependencies = [ "bitflags", + "solana-pubkey 4.1.0", ] [[package]] name = "solana-poseidon" -version = "3.1.12" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44739c6c9f717fd057f7c16fba65fdd3628d4918c61c399520e6f4fba5ad854" +checksum = "737b8ab25bf4cc8e618f80f1fe40709b2ace708bc764a36b8a4c81eea8c07034" dependencies = [ "ark-bn254 0.4.0", "ark-bn254 0.5.0", "light-poseidon 0.2.0", "light-poseidon 0.4.0", - "solana-define-syscall 3.0.0", + "solana-define-syscall 4.0.1", "thiserror 2.0.18", ] @@ -2931,7 +3032,7 @@ dependencies = [ "solana-account-info", "solana-define-syscall 4.0.1", "solana-program-error", - "solana-pubkey 4.2.0", + "solana-pubkey 4.1.0", ] [[package]] @@ -2991,7 +3092,7 @@ dependencies = [ "solana-last-restart-slot", "solana-loader-v3-interface", "solana-program-entrypoint", - "solana-program-runtime", + "solana-program-runtime 4.0.0", "solana-pubkey 3.0.0", "solana-rent", "solana-sbpf", @@ -3016,6 +3117,54 @@ dependencies = [ "thiserror 2.0.18", ] +[[package]] +name = "solana-program-runtime" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6c7f89c89d5ff25f64a41c8cb00478b1d62f941f14a7dd8537c9e50bb2acc92" +dependencies = [ + "base64 0.22.1", + "bincode", + "cfg-if", + "itertools 0.14.0", + "log", + "percentage", + "rand 0.9.4", + "serde", + "solana-account", + "solana-account-info", + "solana-clock", + "solana-epoch-rewards", + "solana-epoch-schedule", + "solana-fee-structure", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-hash 4.2.0", + "solana-instruction", + "solana-last-restart-slot", + "solana-loader-v3-interface", + "solana-program-entrypoint", + "solana-pubkey 4.1.0", + "solana-rent", + "solana-sbpf", + "solana-sdk-ids", + "solana-slot-hashes", + "solana-stable-layout", + "solana-stake-interface", + "solana-svm-callback", + "solana-svm-feature-set", + "solana-svm-log-collector", + "solana-svm-measure", + "solana-svm-timings", + "solana-svm-transaction", + "solana-svm-type-overrides", + "solana-system-interface 3.1.0", + "solana-sysvar", + "solana-sysvar-id", + "solana-transaction-context", + "thiserror 2.0.18", +] + [[package]] name = "solana-pubkey" version = "3.0.0" @@ -3028,9 +3177,9 @@ dependencies = [ [[package]] name = "solana-pubkey" -version = "4.2.0" +version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7db719574990de7e8b0f55a8593ac92a5ccb42c8ce67b3e4bf05b139d5d9ee71" +checksum = "1b06bd918d60111ee1f97de817113e2040ca0cedb740099ee8d646233f6b906c" dependencies = [ "solana-address 2.6.0", ] @@ -3056,9 +3205,9 @@ checksum = "dcf09694a0fc14e5ffb18f9b7b7c0f15ecb6eac5b5610bf76a1853459d19daf9" [[package]] name = "solana-sbpf" -version = "0.13.1" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15b079e08471a9dbfe1e48b2c7439c85aa2a055cbd54eddd8bd257b0a7dbb29" +checksum = "733b3657a0fab205102b799dbe17f85d3972cf984232c1b0b108fa6ba438e382" dependencies = [ "byteorder", "combine", @@ -3151,7 +3300,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d7cc401931d178472358e6b78dc72d031dc08f752d7410f0e8bd259dd6f02fa" dependencies = [ "solana-instruction-error", - "solana-pubkey 4.2.0", + "solana-pubkey 4.1.0", "solana-sanitize", ] @@ -3163,7 +3312,7 @@ checksum = "db7dc3011ea4c0334aaaa7e7128cb390ecf546b28d412e9bf2064680f57f588f" dependencies = [ "sha2 0.10.9", "solana-define-syscall 4.0.1", - "solana-hash 4.3.0", + "solana-hash 4.2.0", ] [[package]] @@ -3177,9 +3326,9 @@ dependencies = [ [[package]] name = "solana-signature" -version = "3.4.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7a73c6e97cc2108be0adf6a6ea326434f8398df9d7eed81da2a4548b69e971c" +checksum = "132a93134f1262aa832f1849b83bec6c9945669b866da18661a427943b9e801e" dependencies = [ "ed25519-dalek 2.2.0", "five8", @@ -3188,7 +3337,7 @@ dependencies = [ "serde-big-array", "serde_derive", "solana-sanitize", - "wincode", + "wincode 0.4.9", ] [[package]] @@ -3210,7 +3359,7 @@ checksum = "2585f70191623887329dfb5078da3a00e15e3980ea67f42c2e10b07028419f43" dependencies = [ "serde", "serde_derive", - "solana-hash 4.3.0", + "solana-hash 4.2.0", "solana-sdk-ids", "solana-sysvar-id", ] @@ -3235,7 +3384,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9f6a291ba063a37780af29e7db14bdd3dc447584d8ba5b3fc4b88e2bbc982fa" dependencies = [ "solana-instruction", - "solana-pubkey 4.2.0", + "solana-pubkey 4.1.0", ] [[package]] @@ -3302,7 +3451,7 @@ dependencies = [ "solana-program-binaries", "solana-program-entrypoint", "solana-program-pack", - "solana-program-runtime", + "solana-program-runtime 4.0.0", "solana-pubkey 3.0.0", "solana-rent", "solana-sbpf", @@ -3335,57 +3484,57 @@ dependencies = [ [[package]] name = "solana-svm-callback" -version = "3.1.12" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb521c7f62db21661267a933f0d311a76b2b744a766b46f5a9a9395ce70f687c" +checksum = "4006b0da7e50cba514ced6b47bcf8f9591552458200e361fd4bdef4068cb2fed" dependencies = [ "solana-account", "solana-clock", "solana-precompile-error", - "solana-pubkey 3.0.0", + "solana-pubkey 4.1.0", ] [[package]] name = "solana-svm-feature-set" -version = "3.1.12" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08924d3b4918008d75a5807e73af8eb9f1c409067c772de518d1dd67dd4c03de" +checksum = "24ea15c0d91403375e3d017cc09780cf138b629abba4ccaaa7cf66b1afea1059" [[package]] name = "solana-svm-log-collector" -version = "3.1.12" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26c071b3e4e9b2f19f15659abc74bd7fcc40cec6d60c1f6024384ff78cb49d40" +checksum = "efb7d3ccd3a51b85807ff16b2f513069e8b55e220b280774a3e9b899bcb81987" dependencies = [ "log", ] [[package]] name = "solana-svm-measure" -version = "3.1.12" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e4f9972c93d50eaa299fadf1bee9de2055d47eef26af589dcefb487f22e71d" +checksum = "d70c9972c1f03cb2bbc64d23dc2079419a66d89b49d6b44f79206530551ddc8c" [[package]] name = "solana-svm-timings" -version = "3.1.12" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c65d4887002f8105f8e49253d0956292c55d66a1a3ee3594e7f90e682ed9521" +checksum = "20f3d66aa88c9001a076362108f7967d6a00d121ba38428e56928935566ed5bd" dependencies = [ "eager", "enum-iterator", - "solana-pubkey 3.0.0", + "solana-pubkey 4.1.0", ] [[package]] name = "solana-svm-transaction" -version = "3.1.13" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ba32fc24c9dc52ebefb481f2c971149a9624fe071803e9e19fa3bebbc0971ce" +checksum = "067861db805d135a6fbe489bf2b74d701f270df8d03afd3257f7d51a2ff3467e" dependencies = [ - "solana-hash 3.1.0", + "solana-hash 4.2.0", "solana-message", - "solana-pubkey 3.0.0", + "solana-pubkey 4.1.0", "solana-sdk-ids", "solana-signature", "solana-transaction", @@ -3393,11 +3542,11 @@ dependencies = [ [[package]] name = "solana-svm-type-overrides" -version = "3.1.12" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa888be46794b88f130508f694e989fb8802c823b9048acd4d0240e9818502fe" +checksum = "8e41661ebf0edcc296b15251c08fee0ad2da3257e6ab86cea2a0a8f6fba642c6" dependencies = [ - "rand 0.8.6", + "rand 0.9.4", "shuttle", ] @@ -3418,9 +3567,9 @@ dependencies = [ [[package]] name = "solana-system-interface" -version = "3.2.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55b54965bf0b76fa8e2b35376583efddd4d916618cfe595bf48c7d7b55a9e628" +checksum = "a95a6f2e23ed861d6444ad4a6d6896c418d7d101b960787e65a8e33157cee81b" dependencies = [ "num-traits", "serde", @@ -3433,9 +3582,9 @@ dependencies = [ [[package]] name = "solana-system-program" -version = "3.1.12" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578e44e2abb14c34efbc0074f9009132f12ff66cc3ab1a7715d24b6801bb7f32" +checksum = "450479004fee3396c88cc4aa2f9b2b8db9c77be42ee7c1c53e6fac9eaec5fd51" dependencies = [ "bincode", "log", @@ -3447,12 +3596,12 @@ dependencies = [ "solana-nonce", "solana-nonce-account", "solana-packet", - "solana-program-runtime", - "solana-pubkey 3.0.0", + "solana-program-runtime 4.0.0", + "solana-pubkey 4.1.0", "solana-sdk-ids", "solana-svm-log-collector", "solana-svm-type-overrides", - "solana-system-interface 2.0.0", + "solana-system-interface 3.1.0", "solana-sysvar", "solana-transaction-context", ] @@ -3489,13 +3638,13 @@ dependencies = [ "solana-epoch-rewards", "solana-epoch-schedule", "solana-fee-calculator", - "solana-hash 4.3.0", + "solana-hash 4.2.0", "solana-instruction", "solana-last-restart-slot", "solana-program-entrypoint", "solana-program-error", "solana-program-memory", - "solana-pubkey 4.2.0", + "solana-pubkey 4.1.0", "solana-rent", "solana-sdk-ids", "solana-sdk-macro", @@ -3524,7 +3673,7 @@ dependencies = [ "serde", "serde_derive", "solana-address 2.6.0", - "solana-hash 4.3.0", + "solana-hash 4.2.0", "solana-instruction", "solana-instruction-error", "solana-message", @@ -3538,7 +3687,7 @@ dependencies = [ [[package]] name = "solana-transaction-context" -version = "3.1.12" +version = "4.0.0" dependencies = [ "bincode", "qualifier_attr", @@ -3729,6 +3878,15 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + [[package]] name = "tinyvec" version = "1.11.0" @@ -3891,6 +4049,19 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "wincode" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "657690780ce23e6f66576a782ffd88eb353512381817029cc1d7a99154bb6d1f" +dependencies = [ + "pastey", + "proc-macro2", + "quote", + "thiserror 2.0.18", + "wincode-derive", +] + [[package]] name = "wincode" version = "0.5.3" diff --git a/Cargo.toml b/Cargo.toml index 56c8527..bd425d5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ edition = "2021" [workspace.dependencies] agave-logger = { version = "3.1", features = ["agave-unstable-api"] } -agave-syscalls = "3.1" +agave-syscalls = "4.0" ahash = "0.8.11" assert_matches = "1.5.0" base64 = "0.22.1" @@ -39,11 +39,11 @@ test-case = "3.3" thiserror = "2.0" solana-account = { path = "solana-account", version = "3.4.0" } solana-account-info = "3.1.1" -solana-bpf-loader-program = "3.1" +solana-bpf-loader-program = "4.0" solana-clock = "3.0.0" -solana-compute-budget = { version = "3.1", features = ["agave-unstable-api"] } +solana-compute-budget = { version = "4.0", features = ["agave-unstable-api"] } solana-compute-budget-interface = "3.0" -solana-compute-budget-program = { version = "3.1", features = [ +solana-compute-budget-program = { version = "4.0", features = [ "agave-unstable-api", ] } solana-ed25519-program = "3.0" @@ -61,7 +61,7 @@ solana-keypair = "3.0" solana-last-restart-slot = "3.0.0" solana-loader-v3-interface = "6.1.0" solana-loader-v4-interface = "3.1" -solana-loader-v4-program = { version = "3.1", features = [ +solana-loader-v4-program = { version = "4.0", features = [ "agave-unstable-api", ] } solana-message = "3.0" @@ -72,10 +72,10 @@ solana-precompile-error = "3.0" solana-program-binaries = { version = "3.1", features = ["agave-unstable-api"] } solana-program-entrypoint = "3.1" solana-program-pack = "3.1" -solana-program-runtime = { path = "program-runtime" } +solana-program-runtime = "4.0" solana-pubkey = "3.0" solana-rent = "3.0" -solana-sbpf = "0.13.1" +solana-sbpf = "0.14.4" solana-sdk-ids = "3.0" solana-secp256k1-program = { version = "3.0", features = ["bincode"] } solana-secp256r1-program = { version = "3.0", features = ["openssl-vendored"] } @@ -84,20 +84,20 @@ solana-signer = "3.0" solana-slot-hashes = "3.0.1" solana-stable-layout = "3.0.1" solana-stake-interface = "2.0.2" -solana-svm-callback = "3.1" -solana-svm-feature-set = "3.1" -solana-svm-log-collector = "3.1" -solana-svm-measure = "3.1" -solana-svm-timings = "3.1" -solana-svm-transaction = "3.1" -solana-svm-type-overrides = "3.1" +solana-svm-callback = "4.0" +solana-svm-feature-set = "4.0" +solana-svm-log-collector = "4.0" +solana-svm-measure = "4.0" +solana-svm-timings = "4.0" +solana-svm-transaction = "4.0" +solana-svm-type-overrides = "4.0" solana-system-interface = "2.0" -solana-system-program = { version = "3.1", features = ["agave-unstable-api"] } +solana-system-program = { version = "4.0", features = ["agave-unstable-api"] } solana-system-transaction = "3.0" solana-sysvar = "3.0" solana-sysvar-id = "3.0" solana-transaction = "3.0" -solana-transaction-context = { path = "transaction-context" } +solana-transaction-context = { path = "transaction-context", version = "4.0" } solana-transaction-error = "3.0" [workspace.lints.rust.unexpected_cfgs] @@ -110,5 +110,4 @@ check-cfg = [ [patch.crates-io] solana-account = { path = "solana-account" } -solana-program-runtime = { path = "program-runtime" } solana-transaction-context = { path = "transaction-context" } diff --git a/svm/src/account_loader.rs b/svm/src/account_loader.rs index 3f99450..72b0f14 100644 --- a/svm/src/account_loader.rs +++ b/svm/src/account_loader.rs @@ -2154,6 +2154,7 @@ mod tests { rent.clone(), compute_budget.max_instruction_stack_depth, compute_budget.max_instruction_trace_length, + sanitized_tx.message().num_instructions(), ); assert_eq!( diff --git a/svm/src/message_processor.rs b/svm/src/message_processor.rs index 348f8b0..ab1b032 100644 --- a/svm/src/message_processor.rs +++ b/svm/src/message_processor.rs @@ -191,7 +191,7 @@ mod tests { create_loadable_account_for_test("mock_system_program"), ), ]; - let mut transaction_context = TransactionContext::new(accounts, Rent::default(), 1, 3); + let mut transaction_context = TransactionContext::new(accounts, Rent::default(), 1, 3, 1); let program_indices = vec![2]; let mut program_cache_for_tx_batch = ProgramCacheForTxBatch::default(); program_cache_for_tx_batch.replenish( @@ -433,7 +433,7 @@ mod tests { create_loadable_account_for_test("mock_system_program"), ), ]; - let mut transaction_context = TransactionContext::new(accounts, Rent::default(), 1, 3); + let mut transaction_context = TransactionContext::new(accounts, Rent::default(), 1, 3, 1); let program_indices = vec![2]; let mut program_cache_for_tx_batch = ProgramCacheForTxBatch::default(); program_cache_for_tx_batch.replenish( @@ -658,7 +658,7 @@ mod tests { (solana_secp256r1_program::id(), secp256r1_account), (mock_program_id, mock_program_account), ]; - let mut transaction_context = TransactionContext::new(accounts, Rent::default(), 1, 4); + let mut transaction_context = TransactionContext::new(accounts, Rent::default(), 1, 4, 1); let message = new_sanitized_message(Message::new( &[ diff --git a/svm/src/rent_calculator.rs b/svm/src/rent_calculator.rs index 859ec6d..dafc2b3 100644 --- a/svm/src/rent_calculator.rs +++ b/svm/src/rent_calculator.rs @@ -6,7 +6,7 @@ use { solana_clock::Epoch, solana_pubkey::Pubkey, solana_rent::Rent, - solana_transaction_context::{IndexOfAccount, TransactionContext}, + solana_transaction_context::{transaction::TransactionContext, IndexOfAccount}, solana_transaction_error::{TransactionError, TransactionResult}, }; diff --git a/svm/src/transaction_account_state_info.rs b/svm/src/transaction_account_state_info.rs index 9c8e35f..5ff3b46 100644 --- a/svm/src/transaction_account_state_info.rs +++ b/svm/src/transaction_account_state_info.rs @@ -3,7 +3,7 @@ use { solana_account::ReadableAccount, solana_rent::Rent, solana_svm_transaction::svm_message::SVMMessage, - solana_transaction_context::{IndexOfAccount, TransactionContext}, + solana_transaction_context::{transaction::TransactionContext, IndexOfAccount}, solana_transaction_error::TransactionResult as Result, }; @@ -118,7 +118,7 @@ mod test { (key3.pubkey(), AccountSharedData::default()), ]; - let context = TransactionContext::new(transaction_accounts, rent.clone(), 20, 20); + let context = TransactionContext::new(transaction_accounts, rent.clone(), 20, 20, 1); let result = TransactionAccountStateInfo::new(&context, &sanitized_message, &rent); assert_eq!( result, @@ -170,7 +170,7 @@ mod test { (key3.pubkey(), AccountSharedData::default()), ]; - let context = TransactionContext::new(transaction_accounts, rent.clone(), 20, 20); + let context = TransactionContext::new(transaction_accounts, rent.clone(), 20, 20, 1); let _result = TransactionAccountStateInfo::new(&context, &sanitized_message, &rent); } @@ -195,7 +195,7 @@ mod test { (key2.pubkey(), AccountSharedData::default()), ]; - let context = TransactionContext::new(transaction_accounts, Rent::default(), 20, 20); + let context = TransactionContext::new(transaction_accounts, Rent::default(), 20, 20, 1); let result = TransactionAccountStateInfo::verify_changes( &pre_rent_state, @@ -219,7 +219,7 @@ mod test { (key2.pubkey(), AccountSharedData::default()), ]; - let context = TransactionContext::new(transaction_accounts, Rent::default(), 20, 20); + let context = TransactionContext::new(transaction_accounts, Rent::default(), 20, 20, 1); let result = TransactionAccountStateInfo::verify_changes( &pre_rent_state, &post_rent_state, diff --git a/svm/src/transaction_commit_result.rs b/svm/src/transaction_commit_result.rs index 9116f4b..7fdc51a 100644 --- a/svm/src/transaction_commit_result.rs +++ b/svm/src/transaction_commit_result.rs @@ -1,7 +1,8 @@ use { crate::transaction_execution_result::TransactionLoadedAccountsStats, solana_fee_structure::FeeDetails, solana_message::inner_instruction::InnerInstructionsList, - solana_transaction_context::TransactionReturnData, solana_transaction_error::TransactionResult, + solana_transaction_context::transaction::TransactionReturnData, + solana_transaction_error::TransactionResult, }; pub type TransactionCommitResult = TransactionResult; diff --git a/svm/src/transaction_execution_result.rs b/svm/src/transaction_execution_result.rs index 6a066b4..c625cac 100644 --- a/svm/src/transaction_execution_result.rs +++ b/svm/src/transaction_execution_result.rs @@ -3,7 +3,7 @@ use { solana_message::inner_instruction::InnerInstructionsList, solana_program_runtime::loaded_programs::ProgramCacheEntry, solana_pubkey::Pubkey, - solana_transaction_context::TransactionReturnData, + solana_transaction_context::transaction::TransactionReturnData, solana_transaction_error::TransactionResult, std::{collections::HashMap, sync::Arc}, }; diff --git a/svm/src/transaction_processor.rs b/svm/src/transaction_processor.rs index 20f7384..9114b6e 100644 --- a/svm/src/transaction_processor.rs +++ b/svm/src/transaction_processor.rs @@ -53,7 +53,7 @@ use { solana_svm_timings::{ExecuteTimingType, ExecuteTimings}, solana_svm_transaction::{svm_message::SVMMessage, svm_transaction::SVMTransaction}, solana_svm_type_overrides::sync::{atomic::Ordering, Arc, RwLock, RwLockReadGuard}, - solana_transaction_context::{ExecutionRecord, TransactionContext}, + solana_transaction_context::transaction::{ExecutionRecord, TransactionContext}, solana_transaction_error::{TransactionError, TransactionResult}, std::{ collections::HashSet, @@ -787,20 +787,25 @@ impl TransactionBatchProcessor { limit_to_load_programs: bool, increment_usage_counter: bool, ) { - let mut missing_programs: Vec<(Pubkey, ProgramCacheMatchCriteria)> = program_accounts_set - .iter() - .map(|pubkey| { - let match_criteria = if check_program_modification_slot { - get_program_modification_slot(account_loader, pubkey) - .map_or(ProgramCacheMatchCriteria::Tombstone, |slot| { + let mut missing_programs: Vec<(Pubkey, ProgramCacheMatchCriteria, u64)> = + program_accounts_set + .iter() + .map(|pubkey| { + let modification_slot = if check_program_modification_slot { + get_program_modification_slot(account_loader, pubkey).ok() + } else { + None + }; + let match_criteria = if check_program_modification_slot { + modification_slot.map_or(ProgramCacheMatchCriteria::Tombstone, |slot| { ProgramCacheMatchCriteria::DeployedOnOrAfterSlot(slot) }) - } else { - ProgramCacheMatchCriteria::NoCriteria - }; - (*pubkey, match_criteria) - }) - .collect(); + } else { + ProgramCacheMatchCriteria::NoCriteria + }; + (*pubkey, match_criteria, modification_slot.unwrap_or(0)) + }) + .collect(); let mut count_hits_and_misses = true; loop { @@ -828,7 +833,9 @@ impl TransactionBatchProcessor { false, ) .expect("called load_program_with_pubkey() with nonexistent account"); - (key, program) + let last_modification_slot = + get_program_modification_slot(account_loader, &key).unwrap_or(self.slot); + (key, last_modification_slot, program) }); let task_waiter = Arc::clone(&global_program_cache.loading_task_waiter); @@ -836,7 +843,7 @@ impl TransactionBatchProcessor { // Unlock the global cache again. }; - if let Some((key, program)) = program_to_store { + if let Some((key, last_modification_slot, program)) = program_to_store { program_cache_for_tx_batch.loaded_missing = true; let mut global_program_cache = self.global_program_cache.write().unwrap(); // Submit our last completed loading task. @@ -844,6 +851,7 @@ impl TransactionBatchProcessor { program_runtime_environments_for_execution, self.slot, key, + last_modification_slot, program, ) && limit_to_load_programs { @@ -904,6 +912,7 @@ impl TransactionBatchProcessor { environment.rent.clone(), compute_budget.max_instruction_stack_depth, compute_budget.max_instruction_trace_length, + tx.num_instructions(), ); let pre_account_state_info = @@ -1047,23 +1056,34 @@ impl TransactionBatchProcessor { == TRANSACTION_LEVEL_STACK_HEIGHT) .unwrap_or(true)); - let ix_trace = transaction_context.take_instruction_trace(); + let (ix_trace, instruction_accounts, instruction_data) = + transaction_context.take_instruction_trace(); let mut outer_instructions = Vec::new(); - for ix_in_trace in ix_trace.into_iter() { + for (index_in_trace, ix_in_trace) in ix_trace.into_iter().enumerate() { let stack_height = ix_in_trace.nesting_level.saturating_add(1); - if stack_height == TRANSACTION_LEVEL_STACK_HEIGHT { + if usize::from(stack_height) == TRANSACTION_LEVEL_STACK_HEIGHT { outer_instructions.push(Vec::new()); } else if let Some(inner_instructions) = outer_instructions.last_mut() { let stack_height = u8::try_from(stack_height).unwrap_or(u8::MAX); + let instruction_data = instruction_data + .get(index_in_trace) + .cloned() + .unwrap_or_default() + .into_owned(); + let instruction_accounts = instruction_accounts + .get(index_in_trace) + .map(|accounts| { + accounts + .iter() + .map(|acc| acc.index_in_transaction as u8) + .collect() + }) + .unwrap_or_default(); inner_instructions.push(InnerInstruction { instruction: CompiledInstruction::new_from_raw_parts( ix_in_trace.program_account_index_in_tx as u8, - ix_in_trace.instruction_data.into_owned(), - ix_in_trace - .instruction_accounts - .iter() - .map(|acc| acc.index_in_transaction as u8) - .collect(), + instruction_data, + instruction_accounts, ), stack_height, }); @@ -1109,6 +1129,7 @@ impl TransactionBatchProcessor { self.global_program_cache.write().unwrap().assign_program( &self.environments, program_id, + self.slot, Arc::new(builtin), ); } @@ -1308,6 +1329,7 @@ mod tests { Rent::default(), 3, instruction_trace.len(), + 1, ); for (index_in_trace, stack_height) in instruction_trace.into_iter().enumerate() { while stack_height <= transaction_context.get_instruction_stack_height() { diff --git a/transaction-context/Cargo.toml b/transaction-context/Cargo.toml index 953485d..6e8dc0c 100644 --- a/transaction-context/Cargo.toml +++ b/transaction-context/Cargo.toml @@ -2,7 +2,7 @@ name = "solana-transaction-context" description = "Solana data shared between program runtime and built-in programs as well as SBF programs." documentation = "https://docs.rs/solana-transaction-context" -version = { workspace = true } +version = "4.0.0" authors = { workspace = true } repository = { workspace = true } homepage = { workspace = true } diff --git a/transaction-context/src/lib.rs b/transaction-context/src/lib.rs index 777c632..a4a0b0f 100644 --- a/transaction-context/src/lib.rs +++ b/transaction-context/src/lib.rs @@ -26,6 +26,25 @@ use {solana_account::WritableAccount, solana_rent::Rent}; pub mod transaction_accounts; pub mod vm_slice; +pub mod instruction { + pub use crate::{InstructionContext, InstructionFrame}; +} + +pub mod instruction_accounts { + pub use crate::{BorrowedInstructionAccount, InstructionAccount}; +} + +pub mod transaction { + use std::borrow::Cow; + + pub use crate::{ExecutionRecord, TransactionContext, TransactionReturnData}; + pub type InstructionTrace<'ix_data> = ( + Vec>, + Vec>, + Vec>, + ); +} + pub const MAX_ACCOUNTS_PER_TRANSACTION: usize = 256; // This is one less than MAX_ACCOUNTS_PER_TRANSACTION because // one index is used as NON_DUP_MARKER in ABI v0 and v1. @@ -135,6 +154,7 @@ impl<'ix_data> TransactionContext<'ix_data> { rent: Rent, instruction_stack_capacity: usize, instruction_trace_capacity: usize, + _number_of_top_level_instructions: usize, ) -> Self { Self { accounts: Rc::new(TransactionAccounts::new(transaction_accounts)), @@ -264,6 +284,17 @@ impl<'ix_data> TransactionContext<'ix_data> { self.get_instruction_context_at_nesting_level(level) } + pub fn get_current_instruction_index(&self) -> Result { + let level = self + .get_instruction_stack_height() + .checked_sub(1) + .ok_or(InstructionError::CallDepth)?; + self.instruction_stack + .get(level) + .copied() + .ok_or(InstructionError::CallDepth) + } + /// Returns a view on the next instruction. This function assumes it has already been /// configured with the correct values in `prepare_next_instruction` or /// `prepare_next_top_level_instruction` @@ -300,6 +331,27 @@ impl<'ix_data> TransactionContext<'ix_data> { Ok(()) } + pub fn configure_instruction_at_index( + &mut self, + instruction_index: usize, + program_index: IndexOfAccount, + instruction_accounts: Vec, + deduplication_map: Vec, + instruction_data: Cow<'ix_data, [u8]>, + _caller_index: Option, + ) -> Result<(), InstructionError> { + debug_assert_eq!(deduplication_map.len(), MAX_ACCOUNTS_PER_TRANSACTION); + let instruction = self + .instruction_trace + .get_mut(instruction_index) + .ok_or(InstructionError::MaxInstructionTraceLengthExceeded)?; + instruction.program_account_index_in_tx = program_index; + instruction.instruction_accounts = instruction_accounts; + instruction.instruction_data = instruction_data; + instruction.dedup_map = deduplication_map; + Ok(()) + } + /// A version of `configure_next_instruction` to help creating the deduplication map in tests pub fn configure_next_instruction_for_tests( &mut self, @@ -325,6 +377,32 @@ impl<'ix_data> TransactionContext<'ix_data> { ) } + pub fn configure_top_level_instruction_for_tests( + &mut self, + program_index: IndexOfAccount, + instruction_accounts: Vec, + instruction_data: Vec, + ) -> Result<(), InstructionError> { + debug_assert!(instruction_accounts.len() <= u16::MAX as usize); + let mut dedup_map = vec![u16::MAX; MAX_ACCOUNTS_PER_TRANSACTION]; + for (idx, account) in instruction_accounts.iter().enumerate() { + let index_in_instruction = dedup_map + .get_mut(account.index_in_transaction as usize) + .unwrap(); + if *index_in_instruction == u16::MAX { + *index_in_instruction = idx as u16; + } + } + self.configure_instruction_at_index( + self.get_instruction_trace_length(), + program_index, + instruction_accounts, + dedup_map, + Cow::Owned(instruction_data), + None, + ) + } + /// Pushes the next instruction #[cfg(not(target_os = "solana"))] pub fn push(&mut self) -> Result<(), InstructionError> { @@ -485,11 +563,25 @@ impl<'ix_data> TransactionContext<'ix_data> { } /// Take ownership of the instruction trace - pub fn take_instruction_trace(&mut self) -> Vec> { + pub fn take_instruction_trace(&mut self) -> transaction::InstructionTrace<'_> { // The last frame is a placeholder for the next instruction to be executed, so it // is empty. self.instruction_trace.pop(); - std::mem::take(&mut self.instruction_trace) + let instruction_accounts = self + .instruction_trace + .iter() + .map(|frame| frame.instruction_accounts.clone().into_boxed_slice()) + .collect(); + let instruction_data = self + .instruction_trace + .iter() + .map(|frame| frame.instruction_data.clone()) + .collect(); + ( + std::mem::take(&mut self.instruction_trace), + instruction_accounts, + instruction_data, + ) } } @@ -1114,6 +1206,7 @@ mod tests { Rent::default(), /* max_instruction_stack_depth */ 2, /* max_instruction_trace_length */ 2, + /* number_of_top_level_instructions */ 1, ) }; @@ -1155,6 +1248,7 @@ mod tests { Rent::default(), 20, 20, + 1, ); transaction_context From f4d9b865c98ca92434f1a57fa4201367354bacda Mon Sep 17 00:00:00 2001 From: Gabriele Picco Date: Thu, 18 Jun 2026 12:34:55 +0200 Subject: [PATCH 2/4] Fix SVM tests for updated runtime APIs --- svm/src/account_loader.rs | 1 + svm/src/transaction_processor.rs | 2 +- svm/tests/integration_test.rs | 16 ++++++++++++---- svm/tests/mock_bank.rs | 1 + 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/svm/src/account_loader.rs b/svm/src/account_loader.rs index 72b0f14..1b0c0f9 100644 --- a/svm/src/account_loader.rs +++ b/svm/src/account_loader.rs @@ -857,6 +857,7 @@ mod tests { solana_signature::Signature, solana_signer::Signer, solana_svm_callback::{InvokeContextCallback, TransactionProcessingCallback}, + solana_svm_transaction::svm_message::SVMStaticMessage, solana_system_transaction::transfer, solana_transaction::{sanitized::SanitizedTransaction, Transaction}, solana_transaction_context::{ diff --git a/svm/src/transaction_processor.rs b/svm/src/transaction_processor.rs index 9114b6e..64701a9 100644 --- a/svm/src/transaction_processor.rs +++ b/svm/src/transaction_processor.rs @@ -1955,7 +1955,7 @@ mod tests { .write() .unwrap() .extract( - &mut vec![(key, ProgramCacheMatchCriteria::NoCriteria)], + &mut vec![(key, ProgramCacheMatchCriteria::NoCriteria, 0)], &mut loaded_programs_for_tx_batch, &program_runtime_environments, true, diff --git a/svm/tests/integration_test.rs b/svm/tests/integration_test.rs index 11404b4..b0ddd9b 100644 --- a/svm/tests/integration_test.rs +++ b/svm/tests/integration_test.rs @@ -44,7 +44,10 @@ use { }, }, solana_svm_feature_set::SVMFeatureSet, - solana_svm_transaction::{instruction::SVMInstruction, svm_message::SVMMessage}, + solana_svm_transaction::{ + instruction::SVMInstruction, + svm_message::{SVMMessage, SVMStaticMessage}, + }, solana_svm_type_overrides::sync::{Arc, RwLock}, solana_system_interface::{instruction as system_instruction, program as system_program}, solana_system_transaction as system_transaction, @@ -358,7 +361,11 @@ impl SvmTestEnvironment<'_> { .global_program_cache .write() .unwrap() - .merge(&self.batch_processor.environments, programs_modified_by_tx); + .merge( + &self.batch_processor.environments, + EXECUTION_SLOT, + programs_modified_by_tx, + ); } } } @@ -557,7 +564,7 @@ impl SvmTestEntry { let message = SanitizedTransaction::from_transaction_for_tests(item.transaction); let check_result = item.check_result.map(|tx_details| { let compute_budget_limits = process_test_compute_budget_instructions( - SVMMessage::program_instructions_iter(&message), + message.program_instructions_iter(), ); let signature_count = message .num_transaction_signatures() @@ -596,7 +603,8 @@ impl SvmTestEntry { } } - if SVMMessage::program_instructions_iter(tx) + if tx + .program_instructions_iter() .any(|(program_id, _)| bpf_loader_upgradeable::check_id(program_id)) { access.privileged_payers.insert(*tx.fee_payer()); diff --git a/svm/tests/mock_bank.rs b/svm/tests/mock_bank.rs index 5a9aa0e..a1202dd 100644 --- a/svm/tests/mock_bank.rs +++ b/svm/tests/mock_bank.rs @@ -369,6 +369,7 @@ pub fn create_custom_loader<'a>() -> BuiltinProgram> { sanitize_user_provided_values: true, enabled_sbpf_versions: SBPFVersion::V0..=SBPFVersion::V3, optimize_rodata: false, + allow_memory_region_zero: false, aligned_memory_mapping: false, }; From 7912594f63db106db83c8460f2fb6e13803b5b8a Mon Sep 17 00:00:00 2001 From: Gabriele Picco Date: Thu, 18 Jun 2026 12:41:11 +0200 Subject: [PATCH 3/4] Limit default workspace tests to active crates --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index bd425d5..9f270a2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,6 @@ [workspace] members = ["program-runtime", "solana-account", "svm", "transaction-context"] +default-members = ["solana-account", "svm", "transaction-context"] resolver = "2" [workspace.package] From c96e22987863f42bc78060d8c261e10b6e80c558 Mon Sep 17 00:00:00 2001 From: Gabriele Picco Date: Thu, 18 Jun 2026 12:54:58 +0200 Subject: [PATCH 4/4] Use default workspace members in cargo test workflow --- .github/workflows/cargo-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cargo-test.yml b/.github/workflows/cargo-test.yml index 74fc83a..0a6b585 100644 --- a/.github/workflows/cargo-test.yml +++ b/.github/workflows/cargo-test.yml @@ -35,4 +35,4 @@ jobs: protoc --version - name: Run tests - run: cargo test --all --locked + run: cargo test --locked