diff --git a/.github/workflows/ci-test-integration.yml b/.github/workflows/ci-test-integration.yml index 2d7641ec4..2fd3fdbe8 100644 --- a/.github/workflows/ci-test-integration.yml +++ b/.github/workflows/ci-test-integration.yml @@ -356,6 +356,7 @@ jobs: runs-on: ${{ matrix.runner || 'blacksmith-8vcpu-ubuntu-2404' }} env: SOLANA_VERSION: v3.1.5 + NEEDS_COMPRESSION_TOOLS: ${{ contains(fromJSON('["schedulecommit","chainlink","table_mania"]'), matrix.batch_tests) || startsWith(matrix.batch_tests, 'committor') }} strategy: matrix: include: @@ -504,6 +505,25 @@ jobs: chmod +x magicblock-validator/_integration_test_bins/* shell: bash + - name: Install Photon indexer + if: env.NEEDS_COMPRESSION_TOOLS == 'true' + shell: bash + env: + RUSTFLAGS: "-A dead-code" + run: cargo install --git https://github.com/lightprotocol/photon.git --rev 3f82b926be6717a07bd41aedb84b4d9e6b0ab0d3 --locked --force + + - name: Setup Node.js + if: env.NEEDS_COMPRESSION_TOOLS == 'true' + uses: actions/setup-node@v4 + with: + node-version: "20" + + - name: Install zk-compression CLI + if: env.NEEDS_COMPRESSION_TOOLS == 'true' + run: | + npm i -g @lightprotocol/zk-compression-cli@0.28.4 + shell: bash + - name: Run integration tests - ${{ matrix.batch_tests }} run: | sudo prlimit --pid $$ --nofile=1048576:1048576 diff --git a/Cargo.lock b/Cargo.lock index 8f7cdc2ac..2df5956de 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -60,6 +60,20 @@ dependencies = [ "zeroize", ] +[[package]] +name = "agave-feature-set" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a2c365c0245cbb8959de725fc2b44c754b673fdf34c9a7f9d4a25c35a7bf1" +dependencies = [ + "ahash 0.8.12", + "solana-epoch-schedule 2.2.1", + "solana-hash 2.3.0", + "solana-pubkey 2.4.0", + "solana-sha256-hasher 2.3.0", + "solana-svm-feature-set 2.3.13", +] + [[package]] name = "agave-feature-set" version = "3.1.12" @@ -71,7 +85,7 @@ dependencies = [ "solana-hash 3.1.0", "solana-pubkey 3.0.0", "solana-sha256-hasher 3.1.0", - "solana-svm-feature-set", + "solana-svm-feature-set 3.1.12", ] [[package]] @@ -81,10 +95,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d93caf9e6dd35ba4193fe778c1e52ee69433ba53b9eaeebc00c7bcd4d699081" dependencies = [ "log", - "solana-clock 3.0.1", + "solana-clock 3.1.0", "solana-hash 3.1.0", "solana-signature 3.4.0", - "solana-transaction", + "solana-transaction 3.1.0", "solana-transaction-status", "thiserror 2.0.18", ] @@ -95,7 +109,7 @@ version = "3.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c0fa80ea1037091eff64931fc53b6a89f153f5a88c33035cedfa79265b985cb" dependencies = [ - "agave-feature-set", + "agave-feature-set 3.1.12", "bincode", "digest 0.10.7", "ed25519-dalek 1.0.1", @@ -117,7 +131,7 @@ version = "3.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c3998a6ec388df954d8f78eeaf73ff487b50a8bdaebd48c8573af22c7b6db72" dependencies = [ - "agave-feature-set", + "agave-feature-set 3.1.12", "solana-pubkey 3.0.0", "solana-sdk-ids 3.1.0", ] @@ -135,10 +149,10 @@ dependencies = [ "solana-account-info 3.1.1", "solana-big-mod-exp 3.0.0", "solana-blake3-hasher 3.1.0", - "solana-bn254", - "solana-clock 3.0.1", + "solana-bn254 3.2.1", + "solana-clock 3.1.0", "solana-cpi 3.1.0", - "solana-curve25519", + "solana-curve25519 3.1.12", "solana-hash 3.1.0", "solana-instruction 3.4.0", "solana-keccak-hasher 3.1.0", @@ -154,14 +168,14 @@ dependencies = [ "solana-stable-layout 3.0.1", "solana-stake-interface 2.0.2", "solana-svm-callback", - "solana-svm-feature-set", + "solana-svm-feature-set 3.1.12", "solana-svm-log-collector", "solana-svm-measure", "solana-svm-timings", "solana-svm-type-overrides", "solana-sysvar 3.1.1", "solana-sysvar-id 3.1.0", - "solana-transaction-context", + "solana-transaction-context 3.1.12", "thiserror 2.0.18", ] @@ -198,6 +212,17 @@ dependencies = [ "memchr", ] +[[package]] +name = "aligned-sized" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48a526ec4434d531d488af59fe866f36b310fe8906691c75dffa664450a3800a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "alloc-no-stdlib" version = "2.0.4" @@ -264,7 +289,7 @@ version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -275,7 +300,7 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -532,6 +557,7 @@ checksum = "246a225cc6131e9ee4f24619af0f19d67761fff15d7ccc22e42b80846e69449a" dependencies = [ "num-traits", "rand 0.8.6", + "rayon", ] [[package]] @@ -657,9 +683,9 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "autotools" @@ -670,6 +696,28 @@ dependencies = [ "cc", ] +[[package]] +name = "aws-lc-rs" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ec2f1fc3ec205783a5da9a7e6c1509cc69dedf09a1949e412c1e18469326d00" +dependencies = [ + "aws-lc-sys", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a2f9779ce85b93ab6170dd940ad0169b5766ff848247aff13bb788b832fe3f4" +dependencies = [ + "cc", + "cmake", + "dunce", + "fs_extra", +] + [[package]] name = "axum" version = "0.7.9" @@ -772,6 +820,12 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + [[package]] name = "base64" version = "0.21.7" @@ -873,7 +927,7 @@ dependencies = [ "cfg-if", "constant_time_eq", "cpufeatures 0.3.0", - "digest 0.11.2", + "digest 0.11.3", ] [[package]] @@ -903,17 +957,40 @@ dependencies = [ "hybrid-array", ] +[[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.13.2", +] + [[package]] name = "borsh" version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfd1e3f8955a5d7de9fab72fc8373fade9fb8a703968cb200ae3dc6cf08e185a" dependencies = [ - "borsh-derive", + "borsh-derive 1.6.1", "bytes", "cfg_aliases", ] +[[package]] +name = "borsh-derive" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831213f80d9423998dd696e2c5345aba6be7a0bd8cd19e31c5243e13df1cef89" +dependencies = [ + "borsh-derive-internal", + "borsh-schema-derive-internal", + "proc-macro-crate 0.1.5", + "proc-macro2", + "syn 1.0.109", +] + [[package]] name = "borsh-derive" version = "1.6.1" @@ -921,12 +998,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfcfdc083699101d5a7965e49925975f2f55060f94f9a05e7187be95d530ca59" dependencies = [ "once_cell", - "proc-macro-crate", + "proc-macro-crate 3.5.0", "proc-macro2", "quote", "syn 2.0.117", ] +[[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.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "276691d96f063427be83e6692b86148e488ebba9f48f77788724ca027ba3b6d4" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "brotli" version = "8.0.2" @@ -1057,9 +1156,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.61" +version = "1.2.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d" +checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98" dependencies = [ "find-msvc-tools", "jobserver", @@ -1174,6 +1273,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" +[[package]] +name = "cmake" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" +dependencies = [ + "cc", +] + [[package]] name = "cmov" version = "0.5.3" @@ -1199,6 +1307,16 @@ dependencies = [ "unreachable", ] +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + [[package]] name = "compact_str" version = "0.8.1" @@ -1213,6 +1331,38 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "compressed-delegation-api" +version = "0.11.1" +dependencies = [ + "borsh 1.6.1", + "light-compressed-account", + "light-hasher", + "light-sdk", + "solana-pubkey 3.0.0", +] + +[[package]] +name = "compressed-delegation-client" +version = "0.11.1" +dependencies = [ + "borsh 1.6.1", + "compressed-delegation-api", + "light-hasher", + "light-sdk", + "light-sdk-types", + "num-derive", + "num-traits", + "serde", + "serde_with", + "solana-account-info 3.1.1", + "solana-cpi 3.1.0", + "solana-instruction 3.4.0", + "solana-program-error 3.0.1", + "solana-pubkey 3.0.0", + "thiserror 2.0.18", +] + [[package]] name = "compression-codecs" version = "0.4.38" @@ -1231,6 +1381,19 @@ version = "0.4.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc14f565cf027a105f7a44ccf9e5b424348421a1d8952a8fc9d499d313107789" +[[package]] +name = "console" +version = "0.15.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" +dependencies = [ + "encode_unicode", + "libc", + "once_cell", + "unicode-width 0.2.0", + "windows-sys 0.59.0", +] + [[package]] name = "console" version = "0.16.3" @@ -1252,7 +1415,7 @@ dependencies = [ "futures-core", "prost 0.14.3", "prost-types 0.14.3", - "tonic 0.14.5", + "tonic 0.14.6", "tonic-prost", "tracing-core", ] @@ -1277,7 +1440,7 @@ dependencies = [ "thread_local", "tokio", "tokio-stream", - "tonic 0.14.5", + "tonic 0.14.6", "tracing", "tracing-core", "tracing-subscriber", @@ -1396,6 +1559,25 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.21" @@ -1458,9 +1640,9 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" dependencies = [ "hybrid-array", ] @@ -1722,12 +1904,12 @@ dependencies = [ [[package]] name = "digest" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4850db49bf08e663084f7fb5c87d202ef91a3907271aff24a94eb97ff039153c" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" dependencies = [ "block-buffer 0.12.0", - "crypto-common 0.2.1", + "crypto-common 0.2.2", "ctutils", ] @@ -1757,6 +1939,12 @@ version = "0.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f678cf4a922c215c63e0de95eb1ff08a958a81d47e485cf9da1e27bf6305cfa5" +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + [[package]] name = "dyn-clone" version = "1.0.20" @@ -1858,9 +2046,9 @@ dependencies = [ [[package]] name = "either" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" [[package]] name = "elliptic-curve" @@ -1949,7 +2137,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -2044,20 +2232,19 @@ dependencies = [ "atomic", "pear", "serde", - "toml", + "toml 0.8.23", "uncased", "version_check", ] [[package]] name = "filetime" -version = "0.2.27" +version = "0.2.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db" +checksum = "5c287a33c7f0a620c38e641e7f60827713987b3c0f26e8ddc9462cc69cf75759" dependencies = [ "cfg-if", "libc", - "libredox", ] [[package]] @@ -2072,7 +2259,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75b8549488b4715defcb0d8a8a1c1c76a80661b5fa106b4ca0e7fce59d7d875" dependencies = [ - "five8_core", + "five8_core 0.1.2", ] [[package]] @@ -2081,7 +2268,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23f76610e969fa1784327ded240f1e28a3fd9520c9cec93b636fcf62dd37f772" dependencies = [ - "five8_core", + "five8_core 1.0.0", ] [[package]] @@ -2090,7 +2277,7 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26dec3da8bc3ef08f2c04f61eab298c3ab334523e55f076354d6d6f613799a7b" dependencies = [ - "five8_core", + "five8_core 0.1.2", ] [[package]] @@ -2099,7 +2286,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a0f1728185f277989ca573a402716ae0beaaea3f76a8ff87ef9dd8fb19436c5" dependencies = [ - "five8_core", + "five8_core 1.0.0", ] [[package]] @@ -2108,6 +2295,12 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2551bf44bc5f776c15044b9b94153a00198be06743e262afaaa61f11ac7523a5" +[[package]] +name = "five8_core" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "059c31d7d36c43fe39d89e55711858b4da8be7eb6dabac23c7289b1a19489406" + [[package]] name = "fixedbitset" version = "0.4.2" @@ -2312,9 +2505,9 @@ dependencies = [ "base64 0.21.7", "clap", "magicblock-accounts-db", - "solana-commitment-config", + "solana-commitment-config 3.1.1", "solana-pubkey 3.0.0", - "solana-rpc-client", + "solana-rpc-client 3.1.12", "sonic-rs", "tempfile", ] @@ -2406,6 +2599,21 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" +[[package]] +name = "groth16-solana" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a6d1ffb18dbf5cfc60b11bd7da88474c672870247c1e5b498619bcb6ba3d8f5" +dependencies = [ + "ark-bn254 0.5.0", + "ark-ec 0.5.0", + "ark-ff 0.5.0", + "ark-serialize 0.5.0", + "num-bigint 0.4.6", + "solana-bn254 2.2.2", + "thiserror 1.0.69", +] + [[package]] name = "group" version = "0.13.0" @@ -2448,9 +2656,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" +checksum = "171fefbc92fe4a4de27e0698d6a5b392d6a0e333506bc49133760b3bcf948733" dependencies = [ "atomic-waker", "bytes", @@ -2516,9 +2724,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.17.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" [[package]] name = "hashlink" @@ -2706,9 +2914,9 @@ dependencies = [ [[package]] name = "hybrid-array" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d46837a0ed51fe95bd3b05de33cd64a1ee88fc797477ca48446872504507c5" +checksum = "9155a582abd142abc056962c29e3ce5ff2ad5469f4246b537ed42c5deba857da" dependencies = [ "typenum", ] @@ -2747,7 +2955,7 @@ dependencies = [ "bytes", "futures-channel", "futures-core", - "h2 0.4.13", + "h2 0.4.14", "http 1.4.0", "http-body 1.0.1", "httparse", @@ -3013,18 +3221,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.17.0", + "hashbrown 0.17.1", "serde", "serde_core", ] +[[package]] +name = "indicatif" +version = "0.17.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "183b3088984b400f4cfac3620d5e076c84da5364016b4f49473de574b2586235" +dependencies = [ + "console 0.15.11", + "number_prefix", + "portable-atomic", + "unicode-width 0.2.0", + "web-time", +] + [[package]] name = "indicatif" version = "0.18.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25470f23803092da7d239834776d653104d551bc4d7eacaf31e6837854b8e9eb" dependencies = [ - "console", + "console 0.16.3", "portable-atomic", "unicode-width 0.2.0", "unit-prefix", @@ -3094,16 +3315,6 @@ version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" -[[package]] -name = "iri-string" -version = "0.7.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25e659a4bb38e810ebc252e53b5814ff908a8c58c2a9ce2fae1bbec24cbf4e20" -dependencies = [ - "memchr", - "serde", -] - [[package]] name = "is_terminal_polyfill" version = "1.70.2" @@ -3147,12 +3358,70 @@ 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 = "itoa" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +[[package]] +name = "jni" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" +dependencies = [ + "cfg-if", + "combine 4.6.7", + "jni-macros", + "jni-sys", + "log", + "simd_cesu8", + "thiserror 2.0.18", + "walkdir", + "windows-link", +] + +[[package]] +name = "jni-macros" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "simd_cesu8", + "syn 2.0.117", +] + +[[package]] +name = "jni-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" +dependencies = [ + "jni-sys-macros", +] + +[[package]] +name = "jni-sys-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" +dependencies = [ + "quote", + "syn 2.0.117", +] + [[package]] name = "jobserver" version = "0.1.34" @@ -3165,9 +3434,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.97" +version = "0.3.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1840c94c045fbcf8ba2812c95db44499f7c64910a912551aaaa541decebcacf" +checksum = "67df7112613f8bfd9150013a0314e196f4800d3201ae742489d999db2f979f08" dependencies = [ "cfg-if", "futures-util", @@ -3239,11 +3508,11 @@ dependencies = [ [[package]] name = "kqueue-sys" -version = "1.0.4" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b" +checksum = "07293a4e297ac234359b510362495713f75ea345d5307140414f20c69ffeb087" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.11.1", "libc", ] @@ -3257,7 +3526,7 @@ dependencies = [ "futures", "laserstream-core-proto", "thiserror 1.0.69", - "tonic 0.14.5", + "tonic 0.14.6", "tonic-health", ] @@ -3274,17 +3543,17 @@ dependencies = [ "protobuf-src", "solana-account 3.4.0", "solana-account-decoder", - "solana-clock 3.0.1", + "solana-clock 3.1.0", "solana-hash 3.1.0", "solana-message 3.1.0", "solana-pubkey 3.0.0", "solana-signature 3.4.0", - "solana-transaction", - "solana-transaction-context", + "solana-transaction 3.1.0", + "solana-transaction-context 3.1.12", "solana-transaction-error 3.2.0", "solana-transaction-status", - "tonic 0.14.5", - "tonic-build 0.14.5", + "tonic 0.14.6", + "tonic-build 0.14.6", "tonic-prost", "tonic-prost-build", ] @@ -3318,7 +3587,7 @@ dependencies = [ "num-format", "pretty-hex", "solana-account 3.4.0", - "solana-clock 3.0.1", + "solana-clock 3.1.0", "solana-message 3.1.0", "solana-pubkey 3.0.0", "solana-signature 3.4.0", @@ -3365,18 +3634,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "libredox" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" -dependencies = [ - "bitflags 2.11.1", - "libc", - "plain", - "redox_syscall 0.7.4", -] - [[package]] name = "librocksdb-sys" version = "0.17.1+9.9.3" @@ -3494,29 +3751,609 @@ dependencies = [ ] [[package]] -name = "light-poseidon" -version = "0.2.0" +name = "light-account" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c9a85a9752c549ceb7578064b4ed891179d20acd85f27318573b64d2d7ee7ee" +checksum = "ec4f3acf8345ca221e4c7a7d277924ca52daea0dea5d5cf8c8f0951a3cad60dc" dependencies = [ - "ark-bn254 0.4.0", - "ark-ff 0.4.2", - "num-bigint 0.4.6", - "thiserror 1.0.69", + "light-account-checks", + "light-compressed-account", + "light-compressible", + "light-hasher", + "light-macros", + "light-sdk-macros", + "light-sdk-types", + "solana-account-info 2.3.0", + "solana-instruction 2.3.3", + "solana-pubkey 2.4.0", ] [[package]] -name = "light-poseidon" -version = "0.4.0" +name = "light-account-checks" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47a1ccadd0bb5a32c196da536fd72c59183de24a055f6bf0513bf845fefab862" +checksum = "34d74dd13535c6014abb4cac694e14083b206a7f6cf1bbbc9611aa5c2e11cdd1" dependencies = [ - "ark-bn254 0.5.0", - "ark-ff 0.5.0", + "solana-account-info 2.3.0", + "solana-cpi 2.2.1", + "solana-instruction 2.3.3", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "solana-system-interface 1.0.0", + "solana-sysvar 2.3.0", + "thiserror 2.0.18", +] + +[[package]] +name = "light-array-map" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bdd13b18028ac9d80d0a987551c0dad7fe81be8140e87cc9d568b80f3728203" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "light-batched-merkle-tree" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3702b96798a1cc93c9d4b0d9eb6ee980481beb147ab663cfd260c71ec258c5f0" +dependencies = [ + "aligned-sized", + "borsh 0.10.4", + "light-account-checks", + "light-bloom-filter", + "light-compressed-account", + "light-hasher", + "light-macros", + "light-merkle-tree-metadata", + "light-verifier", + "light-zero-copy", + "solana-account-info 2.3.0", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "solana-sysvar 2.3.0", + "thiserror 2.0.18", + "zerocopy", +] + +[[package]] +name = "light-bloom-filter" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380b8cf734ccf5fbc1f5fed8e5308b57ebde6774d9304c167bcb0de2854412d8" +dependencies = [ + "bitvec", + "num-bigint 0.4.6", + "solana-nostd-keccak", + "solana-program-error 2.2.2", + "thiserror 2.0.18", +] + +[[package]] +name = "light-bounded-vec" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58cfa375d028164719e3ffef93d2e5c27855cc8a5bb5bf257b868d17c12a3e66" +dependencies = [ + "bytemuck", + "memoffset", + "solana-program-error 2.2.2", + "thiserror 1.0.69", +] + +[[package]] +name = "light-client" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4830579bed474120d4c8b79be18ecd7443ed62bf2d692fdfc591ef7cdee3f3de" +dependencies = [ + "async-trait", + "base64 0.13.1", + "borsh 0.10.4", + "bs58", + "futures", + "lazy_static", + "light-account", + "light-compressed-account", + "light-compressed-token-sdk", + "light-compressible", + "light-concurrent-merkle-tree", + "light-event", + "light-hasher", + "light-indexed-merkle-tree", + "light-merkle-tree-metadata", + "light-prover-client", + "light-sdk", + "light-sdk-types", + "light-token", + "light-token-interface", + "num-bigint 0.4.6", + "photon-api", + "rand 0.8.6", + "reqwest 0.12.28", + "serde_json", + "smallvec", + "solana-account 2.2.1", + "solana-account-decoder-client-types 2.3.13", + "solana-address-lookup-table-interface 2.2.2", + "solana-clock 2.2.3", + "solana-commitment-config 2.2.1", + "solana-compute-budget-interface 2.2.2", + "solana-hash 2.3.0", + "solana-instruction 2.3.3", + "solana-keypair 2.2.3", + "solana-message 2.4.0", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "solana-rpc-client 2.3.13", + "solana-rpc-client-api 2.3.13", + "solana-signature 2.3.0", + "solana-transaction 2.2.3", + "solana-transaction-error 2.2.1", + "solana-transaction-status-client-types 2.3.13", + "spl-pod 0.5.1", + "spl-token-2022-interface 1.0.0", + "thiserror 2.0.18", + "tokio", + "tracing", +] + +[[package]] +name = "light-compressed-account" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2ce168f42dab1a4c01ad83993d68b17cd2dc1bb31ced8ab4edecaf5b666a8ad" +dependencies = [ + "borsh 0.10.4", + "bytemuck", + "light-hasher", + "light-macros", + "light-poseidon 0.3.0", + "light-program-profiler", + "light-zero-copy", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "thiserror 2.0.18", + "tinyvec", + "zerocopy", +] + +[[package]] +name = "light-compressed-token-sdk" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af361443099082c3f7b0e8afe18a770512c494b25219aad951c80daba76beb86" +dependencies = [ + "arrayvec", + "borsh 0.10.4", + "light-account", + "light-account-checks", + "light-compressed-account", + "light-program-profiler", + "light-sdk", + "light-sdk-types", + "light-token-interface", + "light-token-types", + "light-zero-copy", + "solana-account-info 2.3.0", + "solana-cpi 2.2.1", + "solana-instruction 2.3.3", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "thiserror 2.0.18", +] + +[[package]] +name = "light-compressible" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54745d82dab271a4178b48c48d5768ff54af0a6e01aae62425003c25ed394fc5" +dependencies = [ + "aligned-sized", + "borsh 0.10.4", + "bytemuck", + "light-account-checks", + "light-compressed-account", + "light-hasher", + "light-macros", + "light-program-profiler", + "light-zero-copy", + "pinocchio-pubkey", + "solana-pubkey 2.4.0", + "solana-rent 2.2.1", + "thiserror 2.0.18", + "zerocopy", +] + +[[package]] +name = "light-concurrent-merkle-tree" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db96f47253a0907aaa46dac15cecb27b5510130e48da0b36690dcd2e99a6d558" +dependencies = [ + "borsh 0.10.4", + "light-bounded-vec", + "light-hasher", + "memoffset", + "solana-program-error 2.2.2", + "thiserror 2.0.18", +] + +[[package]] +name = "light-event" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd0c2e68b31f5fc890eb0e0c43bc7d5007cd2e02f4b46f3d601f3a91b4c7262c" +dependencies = [ + "borsh 0.10.4", + "light-compressed-account", + "light-hasher", + "light-token-interface", + "light-zero-copy", + "thiserror 2.0.18", +] + +[[package]] +name = "light-hasher" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c822662e6e109bac0e132a43fd52a4ef684811245a794e048cf9cda001e934c8" +dependencies = [ + "ark-bn254 0.5.0", + "ark-ff 0.5.0", + "borsh 0.10.4", + "light-poseidon 0.3.0", + "num-bigint 0.4.6", + "sha2 0.10.9", + "sha3", + "solana-program-error 2.2.2", + "thiserror 2.0.18", + "tinyvec", +] + +[[package]] +name = "light-indexed-array" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f14f984030d86b6f07bd8f5ae04e2c40fcd0c3bdfcc7a291fff1ed59c9e6554" +dependencies = [ + "light-hasher", + "num-bigint 0.4.6", + "num-traits", + "thiserror 2.0.18", +] + +[[package]] +name = "light-indexed-merkle-tree" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0824755289075f28de2820fc7d4ec4e6b9e99d404e033c07338b91cce8c71fb8" +dependencies = [ + "light-bounded-vec", + "light-concurrent-merkle-tree", + "light-hasher", + "light-merkle-tree-reference", + "num-bigint 0.4.6", + "num-traits", + "solana-program-error 2.2.2", + "thiserror 2.0.18", +] + +[[package]] +name = "light-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "179ac51cadc1d0ca047b4d6265a7cc245ca3affc16a20a2749585aa6464d39c2" +dependencies = [ + "bs58", + "proc-macro2", + "quote", + "solana-pubkey 2.4.0", + "syn 2.0.117", +] + +[[package]] +name = "light-merkle-tree-metadata" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee2ef127f8b968a22203515fca1822cb54bb8f0bd84de392fcb9fb0b77855393" +dependencies = [ + "borsh 0.10.4", + "bytemuck", + "light-compressed-account", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-sysvar 2.3.0", + "thiserror 2.0.18", + "zerocopy", +] + +[[package]] +name = "light-merkle-tree-reference" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8d480f62ca32b38a6231bbc5310d693f91d6b5bdcc18bb13c2d9aab7a1c90e8" +dependencies = [ + "light-hasher", + "light-indexed-array", + "num-bigint 0.4.6", + "num-traits", + "thiserror 2.0.18", +] + +[[package]] +name = "light-poseidon" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c9a85a9752c549ceb7578064b4ed891179d20acd85f27318573b64d2d7ee7ee" +dependencies = [ + "ark-bn254 0.4.0", + "ark-ff 0.4.2", "num-bigint 0.4.6", "thiserror 1.0.69", ] +[[package]] +name = "light-poseidon" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3d87542063daaccbfecd78b60f988079b6ec4e089249658b9455075c78d42" +dependencies = [ + "ark-bn254 0.5.0", + "ark-ff 0.5.0", + "num-bigint 0.4.6", + "thiserror 1.0.69", +] + +[[package]] +name = "light-poseidon" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47a1ccadd0bb5a32c196da536fd72c59183de24a055f6bf0513bf845fefab862" +dependencies = [ + "ark-bn254 0.5.0", + "ark-ff 0.5.0", + "num-bigint 0.4.6", + "thiserror 1.0.69", +] + +[[package]] +name = "light-profiler-macro" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a8be18fe4de58a6f754caa74a3fbc6d8a758a26f1f3c24d5b0f5b55df5f5408" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "light-program-profiler" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1d345871581aebd8825868a3f08410290aa1cdddcb189ca7f7e588f61d79fcf" +dependencies = [ + "light-profiler-macro", +] + +[[package]] +name = "light-prover-client" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a9b434c4819c575c53b439a04cef23e14a7359728d9438a10e6de3641a6d3ba" +dependencies = [ + "ark-bn254 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", + "light-compressed-account", + "light-hasher", + "light-indexed-array", + "light-sparse-merkle-tree", + "num-bigint 0.4.6", + "num-traits", + "reqwest 0.11.27", + "serde", + "serde_json", + "solana-bn254 2.2.2", + "thiserror 2.0.18", + "tokio", + "tracing", +] + +[[package]] +name = "light-sdk" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f982db1ecc2998f3f9af539f282a355582f094036024918627e468e9e29ab418" +dependencies = [ + "bincode", + "borsh 0.10.4", + "bytemuck", + "light-account-checks", + "light-compressed-account", + "light-hasher", + "light-macros", + "light-program-profiler", + "light-sdk-macros", + "light-sdk-types", + "light-token-interface", + "light-zero-copy", + "num-bigint 0.4.6", + "solana-account-info 2.3.0", + "solana-clock 2.2.3", + "solana-cpi 2.2.1", + "solana-instruction 2.3.3", + "solana-loader-v3-interface 5.0.0", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "solana-system-interface 1.0.0", + "solana-sysvar 2.3.0", + "thiserror 2.0.18", +] + +[[package]] +name = "light-sdk-macros" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2160586e2b381827d1ca921b5b9e3383e65c013e2c32e8c14a09d913ca7e1312" +dependencies = [ + "darling 0.21.3", + "light-hasher", + "light-sdk-types", + "proc-macro2", + "quote", + "solana-pubkey 2.4.0", + "syn 2.0.117", +] + +[[package]] +name = "light-sdk-types" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efbd944a80033d928d0abf6152595d2e69aa1af07a3dd0e5b86f0b7e4fc9f484" +dependencies = [ + "borsh 0.10.4", + "bytemuck", + "light-account-checks", + "light-compressed-account", + "light-compressible", + "light-hasher", + "light-macros", + "light-token-interface", + "solana-msg 2.2.1", + "thiserror 2.0.18", +] + +[[package]] +name = "light-sparse-merkle-tree" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4251e79b6c63f4946572dcfd7623680ad0f9e0efe1a761a944733333c5645063" +dependencies = [ + "light-hasher", + "light-indexed-array", + "num-bigint 0.4.6", + "num-traits", + "thiserror 2.0.18", +] + +[[package]] +name = "light-token" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "962fc0c26808f218cd4fb782a15adc24a2163e2e64cacd74c9ca86540cf9afb3" +dependencies = [ + "arrayvec", + "borsh 0.10.4", + "light-account", + "light-account-checks", + "light-batched-merkle-tree", + "light-compressed-account", + "light-compressed-token-sdk", + "light-compressible", + "light-macros", + "light-program-profiler", + "light-sdk", + "light-sdk-types", + "light-token-interface", + "light-token-types", + "light-zero-copy", + "solana-account-info 2.3.0", + "solana-cpi 2.2.1", + "solana-instruction 2.3.3", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "spl-pod 0.5.1", + "thiserror 2.0.18", +] + +[[package]] +name = "light-token-interface" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b14661b6592711d90b1cac2402fa10310d90e0517e035c6b1f47c30a14883461" +dependencies = [ + "aligned-sized", + "borsh 0.10.4", + "bytemuck", + "light-array-map", + "light-compressed-account", + "light-compressible", + "light-hasher", + "light-macros", + "light-program-profiler", + "light-zero-copy", + "pinocchio 0.9.3", + "pinocchio-pubkey", + "solana-account-info 2.3.0", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "solana-sysvar 2.3.0", + "spl-pod 0.5.1", + "spl-token-2022", + "thiserror 2.0.18", + "tinyvec", + "zerocopy", +] + +[[package]] +name = "light-token-types" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e5a8ab668ed571a98a01b4eb4df1e671386e89dc0075e614ede972e34c22742" +dependencies = [ + "borsh 0.10.4", + "light-account-checks", + "light-compressed-account", + "light-macros", + "light-sdk-types", + "solana-msg 2.2.1", + "thiserror 2.0.18", +] + +[[package]] +name = "light-verifier" +version = "10.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d829f997b17c7c65198bb93f0d645a4b2818aed2bd14bf2716e36171d4a9f3f" +dependencies = [ + "groth16-solana", + "light-compressed-account", + "thiserror 2.0.18", +] + +[[package]] +name = "light-zero-copy" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5621fb515e14af46148699c0b65334aabe230a1d2cbd06736ccc7a408c8a4af" +dependencies = [ + "light-zero-copy-derive", + "solana-program-error 2.2.2", + "zerocopy", +] + +[[package]] +name = "light-zero-copy-derive" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41c46425e5c7ab5203ff5c86ae2615b169cca55f9283f5f60f5dd74143be6934" +dependencies = [ + "lazy_static", + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "linux-raw-sys" version = "0.4.15" @@ -3612,7 +4449,7 @@ name = "magic-domain-program" version = "0.3.0" source = "git+https://github.com/magicblock-labs/magic-domain-program.git?rev=335a22#335a22ba5aa7b8c4bc84d5053444c74c3b05cdac" dependencies = [ - "borsh", + "borsh 1.6.1", "bytemuck_derive", "solana-program 3.0.0", "solana-system-interface 3.2.0", @@ -3643,9 +4480,9 @@ dependencies = [ "solana-pubkey 3.0.0", "solana-sdk-ids 3.1.0", "solana-signature 3.4.0", - "solana-signer", + "solana-signer 3.0.0", "solana-sysvar 3.1.1", - "solana-transaction", + "solana-transaction 3.1.0", "thiserror 2.0.18", "tokio", "tracing", @@ -3665,7 +4502,7 @@ dependencies = [ "magicblock-program", "solana-hash 3.1.0", "solana-pubkey 3.0.0", - "solana-transaction", + "solana-transaction 3.1.0", "solana-transaction-error 3.2.0", "thiserror 2.0.18", "tokio", @@ -3716,7 +4553,7 @@ dependencies = [ name = "magicblock-aperture" version = "0.11.1" dependencies = [ - "agave-feature-set", + "agave-feature-set 3.1.12", "agave-geyser-plugin-interface", "arc-swap", "base64 0.21.7", @@ -3744,15 +4581,15 @@ dependencies = [ "solana-account 3.4.0", "solana-account-decoder", "solana-fee-structure", - "solana-keypair", + "solana-keypair 3.1.0", "solana-message 3.1.0", "solana-pubkey 3.0.0", "solana-pubsub-client", - "solana-rpc-client", - "solana-rpc-client-api", + "solana-rpc-client 3.1.12", + "solana-rpc-client-api 3.1.12", "solana-signature 3.4.0", "solana-system-transaction", - "solana-transaction", + "solana-transaction 3.1.0", "solana-transaction-error 3.2.0", "solana-transaction-status", "sonic-rs", @@ -3767,10 +4604,11 @@ dependencies = [ name = "magicblock-api" version = "0.11.1" dependencies = [ - "agave-feature-set", + "agave-feature-set 3.1.12", "anyhow", - "borsh", + "borsh 1.6.1", "fd-lock", + "light-client", "magic-domain-program", "magicblock-account-cloner", "magicblock-accounts", @@ -3793,15 +4631,15 @@ dependencies = [ "num_cpus", "paste", "solana-account 3.4.0", - "solana-clock 3.0.1", + "solana-clock 3.1.0", "solana-cluster-type 3.1.0", - "solana-commitment-config", + "solana-commitment-config 3.1.1", "solana-feature-gate-interface 3.1.0", "solana-fee-calculator 3.2.0", "solana-genesis-config", "solana-hash 3.1.0", "solana-instruction 3.4.0", - "solana-keypair", + "solana-keypair 3.1.0", "solana-message 3.1.0", "solana-native-token 3.0.0", "solana-program 3.0.0", @@ -3809,14 +4647,14 @@ dependencies = [ "solana-program-pack 3.1.0", "solana-pubkey 3.0.0", "solana-rent 3.1.0", - "solana-rpc-client", + "solana-rpc-client 3.1.12", "solana-sdk-ids 3.1.0", "solana-sha256-hasher 3.1.0", "solana-signature 3.4.0", - "solana-signer", + "solana-signer 3.0.0", "solana-system-program", "solana-sysvar 3.1.1", - "solana-transaction", + "solana-transaction 3.1.0", "solana-transaction-error 3.2.0", "spl-token-interface", "thiserror 2.0.18", @@ -3829,14 +4667,16 @@ dependencies = [ name = "magicblock-chainlink" version = "0.11.1" dependencies = [ - "agave-feature-set", + "agave-feature-set 3.1.12", "arc-swap", "assert_matches", "async-trait", "bincode", - "borsh", + "borsh 1.6.1", + "compressed-delegation-client", "futures-util", "helius-laserstream", + "light-client", "lru 0.16.4", "magicblock-accounts-db", "magicblock-aml", @@ -3847,16 +4687,17 @@ dependencies = [ "magicblock-magic-program-api", "magicblock-metrics", "parking_lot", + "rustls 0.23.40", "scc", "solana-account 3.4.0", "solana-account-decoder", - "solana-account-decoder-client-types", + "solana-account-decoder-client-types 3.1.12", "solana-address-lookup-table-interface 3.1.0", - "solana-clock 3.0.1", - "solana-commitment-config", + "solana-clock 3.1.0", + "solana-commitment-config 3.1.1", "solana-hash 3.1.0", "solana-instruction 3.4.0", - "solana-keypair", + "solana-keypair 3.1.0", "solana-loader-v3-interface 6.1.1", "solana-loader-v4-interface 3.1.0", "solana-message 3.1.0", @@ -3864,21 +4705,21 @@ dependencies = [ "solana-pubkey 3.0.0", "solana-pubsub-client", "solana-rent 3.1.0", - "solana-rpc-client", - "solana-rpc-client-api", + "solana-rpc-client 3.1.12", + "solana-rpc-client-api 3.1.12", "solana-sdk-ids 3.1.0", "solana-signature 3.4.0", - "solana-signer", + "solana-signer 3.0.0", "solana-system-interface 3.2.0", - "solana-transaction", + "solana-transaction 3.1.0", "solana-transaction-error 3.2.0", - "spl-token-2022-interface", + "spl-token-2022-interface 2.1.0", "spl-token-interface", "thiserror 2.0.18", "tokio", "tokio-stream", "tokio-util", - "tonic 0.14.5", + "tonic 0.14.6", "tracing", "url", ] @@ -3887,7 +4728,7 @@ dependencies = [ name = "magicblock-committor-program" version = "0.11.1" dependencies = [ - "borsh", + "borsh 1.6.1", "paste", "solana-account 3.4.0", "solana-account-info 3.1.1", @@ -3905,9 +4746,13 @@ dependencies = [ "async-trait", "base64 0.21.7", "bincode", - "borsh", + "borsh 1.6.1", + "compressed-delegation-api", + "compressed-delegation-client", "futures-util", "lazy_static", + "light-client", + "light-sdk", "lru 0.16.4", "magicblock-committor-program", "magicblock-core", @@ -3922,22 +4767,22 @@ dependencies = [ "solana-account 3.4.0", "solana-account-decoder", "solana-address-lookup-table-interface 3.1.0", - "solana-commitment-config", - "solana-compute-budget-interface", + "solana-commitment-config 3.1.1", + "solana-compute-budget-interface 3.0.0", "solana-hash 3.1.0", "solana-instruction 3.4.0", - "solana-keypair", + "solana-keypair 3.1.0", "solana-message 3.1.0", "solana-program 3.0.0", "solana-pubkey 3.0.0", - "solana-rpc-client", - "solana-rpc-client-api", + "solana-rpc-client 3.1.12", + "solana-rpc-client-api 3.1.12", "solana-signature 3.4.0", - "solana-signer", + "solana-signer 3.0.0", "solana-system-program", - "solana-transaction", + "solana-transaction 3.1.0", "solana-transaction-error 3.2.0", - "solana-transaction-status-client-types", + "solana-transaction-status-client-types 3.1.12", "static_assertions", "tempfile", "test-kit", @@ -3961,11 +4806,11 @@ dependencies = [ "serde", "serde_with", "serial_test", - "solana-keypair", + "solana-keypair 3.1.0", "solana-pubkey 3.0.0", - "solana-signer", + "solana-signer 3.0.0", "tempfile", - "toml", + "toml 0.8.23", "url", ] @@ -3975,23 +4820,26 @@ version = "0.11.1" dependencies = [ "bincode", "bytes", + "compressed-delegation-client", "console-subscriber", "flume", + "light-client", + "light-sdk", "magicblock-magic-program-api", "serde", "solana-account 3.4.0", "solana-account-decoder", - "solana-clock 3.0.1", + "solana-clock 3.1.0", "solana-hash 3.1.0", "solana-message 3.1.0", "solana-program 3.0.0", "solana-pubkey 3.0.0", "solana-signature 3.4.0", - "solana-transaction", - "solana-transaction-context", + "solana-transaction 3.1.0", + "solana-transaction-context 3.1.12", "solana-transaction-error 3.2.0", - "solana-transaction-status-client-types", - "spl-token-2022-interface", + "solana-transaction-status-client-types 3.1.12", + "spl-token-2022-interface 2.1.0", "spl-token-interface", "tokio", "tracing", @@ -4005,7 +4853,7 @@ version = "0.3.0" source = "git+https://github.com/magicblock-labs/delegation-program.git?rev=25386a7c1d406d06b8d07a4d5b0fd37d5e74213b#25386a7c1d406d06b8d07a4d5b0fd37d5e74213b" dependencies = [ "bincode", - "borsh", + "borsh 1.6.1", "bytemuck", "const-crypto", "libsodium-rs", @@ -4047,20 +4895,20 @@ dependencies = [ "rocksdb", "serde", "solana-account-decoder", - "solana-clock 3.0.1", + "solana-clock 3.1.0", "solana-hash 3.1.0", "solana-instruction 3.4.0", - "solana-keypair", + "solana-keypair 3.1.0", "solana-message 3.1.0", "solana-metrics", "solana-pubkey 3.0.0", "solana-signature 3.4.0", - "solana-signer", + "solana-signer 3.0.0", "solana-storage-proto", "solana-svm-measure", "solana-system-transaction", - "solana-transaction", - "solana-transaction-context", + "solana-transaction 3.1.0", + "solana-transaction-context 3.1.12", "solana-transaction-error 3.2.0", "solana-transaction-status", "tempfile", @@ -4103,7 +4951,7 @@ dependencies = [ name = "magicblock-processor" version = "0.11.1" dependencies = [ - "agave-feature-set", + "agave-feature-set 3.1.12", "agave-precompiles", "agave-syscalls", "bincode", @@ -4125,7 +4973,7 @@ dependencies = [ "solana-feature-gate-interface 3.1.0", "solana-fee-structure", "solana-instruction 3.4.0", - "solana-keypair", + "solana-keypair 3.1.0", "solana-loader-v3-interface 6.1.1", "solana-loader-v4-program", "solana-precompile-error", @@ -4134,13 +4982,13 @@ dependencies = [ "solana-pubkey 3.0.0", "solana-sdk-ids 3.1.0", "solana-signature 3.4.0", - "solana-signer", + "solana-signer 3.0.0", "solana-svm", "solana-svm-callback", "solana-svm-transaction", "solana-system-program", - "solana-transaction", - "solana-transaction-context", + "solana-transaction 3.1.0", + "solana-transaction-context 3.1.12", "solana-transaction-error 3.2.0", "solana-transaction-status", "solana-zk-elgamal-proof-program", @@ -4168,23 +5016,23 @@ dependencies = [ "serial_test", "solana-account 3.4.0", "solana-account-info 3.1.1", - "solana-clock 3.0.1", + "solana-clock 3.1.0", "solana-fee-calculator 3.2.0", "solana-hash 3.1.0", "solana-instruction 3.4.0", - "solana-keypair", + "solana-keypair 3.1.0", "solana-loader-v3-interface 6.1.1", "solana-loader-v4-interface 3.1.0", "solana-program-runtime", "solana-pubkey 3.0.0", "solana-sdk-ids 3.1.0", - "solana-seed-derivable", + "solana-seed-derivable 3.0.0", "solana-signature 3.4.0", - "solana-signer", + "solana-signer 3.0.0", "solana-svm-log-collector", "solana-sysvar 3.1.1", - "solana-transaction", - "solana-transaction-context", + "solana-transaction 3.1.0", + "solana-transaction-context 3.1.12", "test-kit", "thiserror 2.0.18", ] @@ -4205,7 +5053,7 @@ dependencies = [ "serde", "solana-hash 3.1.0", "solana-pubkey 3.0.0", - "solana-transaction", + "solana-transaction 3.1.0", "solana-transaction-error 3.2.0", "tempfile", "thiserror 2.0.18", @@ -4221,18 +5069,18 @@ version = "0.11.1" dependencies = [ "futures-util", "solana-account 3.4.0", - "solana-account-decoder-client-types", + "solana-account-decoder-client-types 3.1.12", "solana-address-lookup-table-interface 3.1.0", - "solana-clock 3.0.1", - "solana-commitment-config", + "solana-clock 3.1.0", + "solana-commitment-config 3.1.1", "solana-hash 3.1.0", "solana-instruction 3.4.0", "solana-pubkey 3.0.0", - "solana-rpc-client", - "solana-rpc-client-api", + "solana-rpc-client 3.1.12", + "solana-rpc-client-api 3.1.12", "solana-signature 3.4.0", "solana-transaction-error 3.2.0", - "solana-transaction-status-client-types", + "solana-transaction-status-client-types 3.1.12", "thiserror 2.0.18", "tokio", "tracing", @@ -4247,13 +5095,13 @@ dependencies = [ "magicblock-core", "magicblock-magic-program-api", "solana-instruction 3.4.0", - "solana-keypair", + "solana-keypair 3.1.0", "solana-message 3.1.0", "solana-pubkey 3.0.0", - "solana-rpc-client", + "solana-rpc-client 3.1.12", "solana-signature 3.4.0", - "solana-signer", - "solana-transaction", + "solana-signer 3.0.0", + "solana-transaction 3.1.0", "thiserror 2.0.18", "tokio", "tracing", @@ -4269,17 +5117,17 @@ dependencies = [ "rand 0.9.4", "sha3", "solana-address-lookup-table-interface 3.1.0", - "solana-clock 3.0.1", - "solana-commitment-config", - "solana-compute-budget-interface", + "solana-clock 3.1.0", + "solana-commitment-config 3.1.1", + "solana-compute-budget-interface 3.0.0", "solana-instruction 3.4.0", - "solana-keypair", + "solana-keypair 3.1.0", "solana-message 3.1.0", "solana-pubkey 3.0.0", "solana-signature 3.4.0", - "solana-signer", - "solana-slot-hashes 3.0.1", - "solana-transaction", + "solana-signer 3.0.0", + "solana-slot-hashes 3.0.2", + "solana-transaction 3.1.0", "thiserror 2.0.18", "tokio", "tracing", @@ -4300,10 +5148,10 @@ dependencies = [ "solana-instruction 3.4.0", "solana-message 3.1.0", "solana-pubkey 3.0.0", - "solana-rpc-client", - "solana-rpc-client-api", + "solana-rpc-client 3.1.12", + "solana-rpc-client-api 3.1.12", "solana-signature 3.4.0", - "solana-transaction", + "solana-transaction 3.1.0", "solana-transaction-error 3.2.0", "thiserror 2.0.18", "tokio", @@ -4325,7 +5173,7 @@ dependencies = [ "serde", "serde_json", "solana-pubsub-client", - "solana-rpc-client-api", + "solana-rpc-client-api 3.1.12", "tokio", "tokio-util", "tracing", @@ -4344,7 +5192,7 @@ dependencies = [ "magicblock-tui-client", "magicblock-version", "num_cpus", - "solana-signer", + "solana-signer 3.0.0", "tokio", "tracing", ] @@ -4356,11 +5204,11 @@ dependencies = [ "magicblock-delegation-program-api", "magicblock-program", "magicblock-rpc-client", - "solana-commitment-config", - "solana-rpc-client", + "solana-commitment-config 3.1.1", + "solana-rpc-client 3.1.12", "solana-signature 3.4.0", - "solana-signer", - "solana-transaction", + "solana-signer 3.0.0", + "solana-transaction 3.1.0", "tokio", "tokio-util", "tracing", @@ -4370,13 +5218,13 @@ dependencies = [ name = "magicblock-version" version = "0.11.1" dependencies = [ - "agave-feature-set", + "agave-feature-set 3.1.12", "git-version", "rustc_version", "semver", "serde", "solana-frozen-abi-macro", - "solana-rpc-client-api", + "solana-rpc-client-api 3.1.12", "solana-sanitize 3.0.1", ] @@ -4555,9 +5403,9 @@ dependencies = [ [[package]] name = "no_std_io2" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b51ed7824b6e07d354605f4abb3d9d300350701299da96642ee084f5ce631550" +checksum = "418abd1b6d34fbf6cae440dc874771b0525a604428704c76e48b29a5e67b8003" dependencies = [ "memchr", ] @@ -4605,7 +5453,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -4650,6 +5498,7 @@ checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ "num-integer", "num-traits", + "serde", ] [[package]] @@ -4664,9 +5513,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" [[package]] name = "num-derive" @@ -4756,12 +5605,18 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 3.5.0", "proc-macro2", "quote", "syn 2.0.117", ] +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + [[package]] name = "once_cell" version = "1.21.4" @@ -4782,15 +5637,14 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.78" +version = "0.10.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38c4372413cdaaf3cc79dd92d29d7d9f5ab09b51b10dded508fb90bb70b9222" +checksum = "a45fa2aa886c42762255da344f0a0d313e254066c46aad76f300c3d3da62d967" dependencies = [ "bitflags 2.11.1", "cfg-if", "foreign-types", "libc", - "once_cell", "openssl-macros", "openssl-sys", ] @@ -4829,9 +5683,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.114" +version = "0.9.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13ce1245cd07fcc4cfdb438f7507b0c7e4f3849a69fd84d52374c66d83741bb6" +checksum = "f28a22dc7140cda5f096e5e7724a6962ca81a7f8bfd2979f9b18c11af56318c4" dependencies = [ "cc", "libc", @@ -4858,7 +5712,7 @@ checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.18", + "redox_syscall", "smallvec", "windows-link", ] @@ -4871,9 +5725,9 @@ checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "pastey" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5a797f0e07bdf071d15742978fc3128ec6c22891c31a3a931513263904c982a" +checksum = "2ee67f1008b1ba2321834326597b8e186293b049a023cdef258527550b9935b4" [[package]] name = "pbkdf2" @@ -4952,20 +5806,32 @@ dependencies = [ "indexmap 2.14.0", ] +[[package]] +name = "photon-api" +version = "0.56.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95609d4f08f2cf86d6e41f5b483cfbbfd914099eb0f7c6ea15e98b358f4614f8" +dependencies = [ + "progenitor-client", + "reqwest 0.13.3", + "serde", + "serde_json", +] + [[package]] name = "pin-project" -version = "1.1.11" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517" +checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.11" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6" +checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" dependencies = [ "proc-macro2", "quote", @@ -5054,12 +5920,6 @@ version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" -[[package]] -name = "plain" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" - [[package]] name = "polyval" version = "0.6.2" @@ -5118,6 +5978,15 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml 0.5.11", +] + [[package]] name = "proc-macro-crate" version = "3.5.0" @@ -5149,6 +6018,21 @@ dependencies = [ "yansi", ] +[[package]] +name = "progenitor-client" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffab7b358944dba033a7b324e7558e66e6bcb1fb4705cf57f26fd5092bcae630" +dependencies = [ + "bytes", + "futures-core", + "percent-encoding", + "reqwest 0.13.3", + "serde", + "serde_json", + "serde_urlencoded", +] + [[package]] name = "prometheus" version = "0.13.4" @@ -5221,7 +6105,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "343d3bd7056eda839b03204e68deff7d1b13aba7af2b2fd16890697274262ee7" dependencies = [ "heck", - "itertools 0.13.0", + "itertools 0.14.0", "log", "multimap", "petgraph 0.8.3", @@ -5255,7 +6139,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b" dependencies = [ "anyhow", - "itertools 0.13.0", + "itertools 0.14.0", "proc-macro2", "quote", "syn 2.0.117", @@ -5336,9 +6220,9 @@ dependencies = [ [[package]] name = "pulldown-cmark" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c3a14896dfa883796f1cb410461aef38810ea05f2b2c33c5aded3649095fdad" +checksum = "e9f068eba8e7071c5f9511831b44f32c740d5adf574e990f946ddb53db2f314e" dependencies = [ "bitflags 2.11.1", "memchr", @@ -5400,6 +6284,7 @@ version = "0.11.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" dependencies = [ + "aws-lc-rs", "bytes", "getrandom 0.3.4", "lru-slab", @@ -5587,19 +6472,30 @@ dependencies = [ ] [[package]] -name = "redox_syscall" -version = "0.5.18" +name = "rayon" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d" dependencies = [ - "bitflags 2.11.1", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", ] [[package]] name = "redox_syscall" -version = "0.7.4" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f450ad9c3b1da563fb6948a8e0fb0fb9269711c9c73d9ea1de5058c79c8d643a" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ "bitflags 2.11.1", ] @@ -5738,7 +6634,7 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2 0.4.13", + "h2 0.4.14", "http 1.4.0", "http-body 1.0.1", "http-body-util", @@ -5769,7 +6665,48 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots 1.0.7", + "webpki-roots 1.0.7", +] + +[[package]] +name = "reqwest" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62e0021ea2c22aed41653bc7e1419abb2c97e038ff2c33d0e1309e49a97deec0" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-core", + "futures-util", + "http 1.4.0", + "http-body 1.0.1", + "http-body-util", + "hyper 1.9.0", + "hyper-rustls 0.27.9", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls 0.23.40", + "rustls-pki-types", + "rustls-platform-verifier", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper 1.0.2", + "tokio", + "tokio-rustls 0.26.4", + "tokio-util", + "tower 0.5.3", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", ] [[package]] @@ -5836,7 +6773,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73389e0c99e664f919275ab5b5b0471391fe9a8de61e1dff9b1eaf56a90f16e3" dependencies = [ "bytes", - "hashbrown 0.17.0", + "hashbrown 0.17.1", "indexmap 2.14.0", "munge", "ptr_meta 0.3.1", @@ -5948,7 +6885,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.12.1", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -5969,6 +6906,7 @@ version = "0.23.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" dependencies = [ + "aws-lc-rs", "log", "once_cell", "ring", @@ -6031,6 +6969,33 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls-platform-verifier" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0" +dependencies = [ + "core-foundation 0.10.1", + "core-foundation-sys", + "jni", + "log", + "once_cell", + "rustls 0.23.40", + "rustls-native-certs 0.8.3", + "rustls-platform-verifier-android", + "rustls-webpki 0.103.13", + "security-framework 3.7.0", + "security-framework-sys", + "webpki-root-certs", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls-platform-verifier-android" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" + [[package]] name = "rustls-webpki" version = "0.101.7" @@ -6057,6 +7022,7 @@ version = "0.103.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" dependencies = [ + "aws-lc-rs", "ring", "rustls-pki-types", "untrusted", @@ -6260,9 +7226,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.149" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" dependencies = [ "itoa", "memchr", @@ -6314,11 +7280,12 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.18.0" +version = "3.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd5414fad8e6907dbdd5bc441a50ae8d6e26151a03b1de04d89a5576de61d01f" +checksum = "e72c1c2cb7b223fafb600a619537a871c2818583d619401b785e7c0b746ccde2" dependencies = [ "base64 0.22.1", + "bs58", "chrono", "hex", "indexmap 1.9.3", @@ -6333,9 +7300,9 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.18.0" +version = "3.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3db8978e608f1fe7357e211969fd9abdcae80bac1ba7a3369bb7eb6b404eb65" +checksum = "b90c488738ecb4fb0262f41f43bc40efc5868d9fb744319ddf5f5317f417bfac" dependencies = [ "darling 0.23.0", "proc-macro2", @@ -6500,6 +7467,16 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" +[[package]] +name = "simd_cesu8" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94f90157bb87cddf702797c5dadfa0be7d266cdf49e22da2fcaa32eff75b2c33" +dependencies = [ + "rustc_version", + "simdutf8", +] + [[package]] name = "simdutf8" version = "0.1.5" @@ -6541,7 +7518,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -6550,11 +7527,16 @@ version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f949fe4edaeaea78c844023bfc1c898e0b1f5a100f8a8d2d0f85d0a7b090258" dependencies = [ + "bincode", + "serde", + "serde_bytes", + "serde_derive", "solana-account-info 2.3.0", "solana-clock 2.2.3", "solana-instruction 2.3.3", "solana-pubkey 2.4.0", "solana-sdk-ids 2.2.1", + "solana-sysvar 2.3.0", ] [[package]] @@ -6567,7 +7549,7 @@ dependencies = [ "serde", "serde_bytes", "solana-account-info 3.1.1", - "solana-clock 3.0.1", + "solana-clock 3.1.0", "solana-instruction 3.4.0", "solana-pubkey 3.0.0", "solana-sdk-ids 3.1.0", @@ -6588,9 +7570,9 @@ dependencies = [ "serde", "serde_json", "solana-account 3.4.0", - "solana-account-decoder-client-types", + "solana-account-decoder-client-types 3.1.12", "solana-address-lookup-table-interface 3.1.0", - "solana-clock 3.0.1", + "solana-clock 3.1.0", "solana-config-interface", "solana-epoch-schedule 3.1.0", "solana-fee-calculator 3.2.0", @@ -6602,20 +7584,36 @@ dependencies = [ "solana-pubkey 3.0.0", "solana-rent 3.1.0", "solana-sdk-ids 3.1.0", - "solana-slot-hashes 3.0.1", - "solana-slot-history 3.0.0", + "solana-slot-hashes 3.0.2", + "solana-slot-history 3.0.1", "solana-stake-interface 2.0.2", "solana-sysvar 3.1.1", "solana-vote-interface 4.0.4", - "spl-generic-token", - "spl-token-2022-interface", - "spl-token-group-interface", + "spl-generic-token 2.0.1", + "spl-token-2022-interface 2.1.0", + "spl-token-group-interface 0.7.2", "spl-token-interface", - "spl-token-metadata-interface", + "spl-token-metadata-interface 0.8.0", "thiserror 2.0.18", "zstd", ] +[[package]] +name = "solana-account-decoder-client-types" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5519e8343325b707f17fbed54fcefb325131b692506d0af9e08a539d15e4f8cf" +dependencies = [ + "base64 0.22.1", + "bs58", + "serde", + "serde_derive", + "serde_json", + "solana-account 2.2.1", + "solana-pubkey 2.4.0", + "zstd", +] + [[package]] name = "solana-account-decoder-client-types" version = "3.1.12" @@ -6682,7 +7680,7 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1384b52c435a750cc9c538760fc7bb472fd78e65a9900a2d07312c5bb335b72" dependencies = [ - "borsh", + "borsh 1.6.1", "bytemuck", "bytemuck_derive", "curve25519-dalek 4.1.3", @@ -6728,12 +7726,12 @@ dependencies = [ "bytemuck", "serde", "serde_derive", - "solana-clock 3.0.1", + "solana-clock 3.1.0", "solana-instruction 3.4.0", "solana-instruction-error", "solana-pubkey 4.2.0", "solana-sdk-ids 3.1.0", - "solana-slot-hashes 3.0.1", + "solana-slot-hashes 3.0.2", ] [[package]] @@ -6821,6 +7819,21 @@ dependencies = [ "solana-hash 4.3.0", ] +[[package]] +name = "solana-bn254" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4420f125118732833f36facf96a27e7b78314b2d642ba07fa9ffdacd8d79e243" +dependencies = [ + "ark-bn254 0.4.0", + "ark-ec 0.4.2", + "ark-ff 0.4.2", + "ark-serialize 0.4.2", + "bytemuck", + "solana-define-syscall 2.3.0", + "thiserror 2.0.18", +] + [[package]] name = "solana-bn254" version = "3.2.1" @@ -6836,13 +7849,23 @@ dependencies = [ "thiserror 2.0.18", ] +[[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.6.1", +] + [[package]] name = "solana-borsh" version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c04abbae16f57178a163125805637b8a076175bb5c0002fb04f4792bea901cf7" dependencies = [ - "borsh", + "borsh 1.6.1", ] [[package]] @@ -6856,7 +7879,7 @@ dependencies = [ "qualifier_attr", "solana-account 3.4.0", "solana-bincode 3.1.0", - "solana-clock 3.0.1", + "solana-clock 3.1.0", "solana-instruction 3.4.0", "solana-loader-v3-interface 6.1.1", "solana-loader-v4-interface 3.1.0", @@ -6866,12 +7889,12 @@ dependencies = [ "solana-pubkey 3.0.0", "solana-sbpf", "solana-sdk-ids 3.1.0", - "solana-svm-feature-set", + "solana-svm-feature-set 3.1.12", "solana-svm-log-collector", "solana-svm-measure", "solana-svm-type-overrides", "solana-system-interface 2.0.0", - "solana-transaction-context", + "solana-transaction-context 3.1.12", ] [[package]] @@ -6889,9 +7912,9 @@ dependencies = [ [[package]] name = "solana-clock" -version = "3.0.1" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95cf11109c3b6115cc510f1e31f06fdd52f504271bc24ef5f1249fbbcae5f9f3" +checksum = "5ea35d8f69b67daddb921a9da7f78ca591b533cf5e98833cd9ae62fdc2e4652c" dependencies = [ "serde", "serde_derive", @@ -6918,6 +7941,16 @@ dependencies = [ "solana-hash 4.3.0", ] +[[package]] +name = "solana-commitment-config" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac49c4dde3edfa832de1697e9bcdb7c3b3f7cb7a1981b7c62526c8bb6700fb73" +dependencies = [ + "serde", + "serde_derive", +] + [[package]] name = "solana-commitment-config" version = "3.1.1" @@ -6938,6 +7971,16 @@ dependencies = [ "solana-program-runtime", ] +[[package]] +name = "solana-compute-budget-interface" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8432d2c4c22d0499aa06d62e4f7e333f81777b3d7c96050ae9e5cb71a8c3aee4" +dependencies = [ + "solana-instruction 2.3.3", + "solana-sdk-ids 2.2.1", +] + [[package]] name = "solana-compute-budget-interface" version = "3.0.0" @@ -7002,6 +8045,20 @@ dependencies = [ "solana-stable-layout 3.0.1", ] +[[package]] +name = "solana-curve25519" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae4261b9a8613d10e77ac831a8fa60b6fa52b9b103df46d641deff9f9812a23" +dependencies = [ + "bytemuck", + "bytemuck_derive", + "curve25519-dalek 4.1.3", + "solana-define-syscall 2.3.0", + "subtle", + "thiserror 2.0.18", +] + [[package]] name = "solana-curve25519" version = "3.1.12" @@ -7049,6 +8106,17 @@ version = "5.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21e14a4f604117f379840956a8fc8695e4c84f5b0ebed192f31f60d9b85d581d" +[[package]] +name = "solana-derivation-path" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "939756d798b25c5ec3cca10e06212bdca3b1443cb9bb740a38124f58b258737b" +dependencies = [ + "derivation-path", + "qstring", + "uriparse", +] + [[package]] name = "solana-derivation-path" version = "3.0.0" @@ -7072,6 +8140,16 @@ dependencies = [ "solana-sdk-ids 3.1.0", ] +[[package]] +name = "solana-epoch-info" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ef6f0b449290b0b9f32973eefd95af35b01c5c0c34c569f936c34c5b20d77b" +dependencies = [ + "serde", + "serde_derive", +] + [[package]] name = "solana-epoch-info" version = "3.1.0" @@ -7098,9 +8176,9 @@ dependencies = [ [[package]] name = "solana-epoch-rewards" -version = "3.0.1" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5e7b0ba210593ba8ddd39d6d234d81795d1671cebf3026baa10d5dc23ac42f0" +checksum = "1cddf2388b28291210d9aa60690740733cab527531f06ed153c4d388951e407c" dependencies = [ "serde", "serde_derive", @@ -7187,7 +8265,7 @@ dependencies = [ "serde", "serde_derive", "solana-address-lookup-table-interface 3.1.0", - "solana-clock 3.0.1", + "solana-clock 3.1.0", "solana-hash 3.1.0", "solana-instruction 3.4.0", "solana-keccak-hasher 3.1.0", @@ -7271,9 +8349,9 @@ dependencies = [ [[package]] name = "solana-frozen-abi-macro" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b04663357817fddb4755c6359005038c12e110ab04d1ac5048482551f95b160" +checksum = "4efd54c3f198403955addf2160af0ccc30294a04cf34e155c775d69960e1f0f6" dependencies = [ "proc-macro2", "quote", @@ -7290,20 +8368,20 @@ dependencies = [ "chrono", "memmap2 0.5.10", "solana-account 3.4.0", - "solana-clock 3.0.1", + "solana-clock 3.1.0", "solana-cluster-type 3.1.0", "solana-epoch-schedule 3.1.0", "solana-fee-calculator 3.2.0", "solana-hash 3.1.0", - "solana-inflation", - "solana-keypair", + "solana-inflation 3.1.0", + "solana-keypair 3.1.0", "solana-poh-config", "solana-pubkey 3.0.0", "solana-rent 3.1.0", "solana-sdk-ids 3.1.0", "solana-sha256-hasher 3.1.0", "solana-shred-version", - "solana-signer", + "solana-signer 3.0.0", "solana-time-utils 3.0.0", ] @@ -7319,6 +8397,7 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5b96e9f0300fa287b545613f007dfe20043d7812bee255f418c1eb649c93b63" dependencies = [ + "borsh 1.6.1", "bytemuck", "bytemuck_derive", "five8 0.2.1", @@ -7345,7 +8424,7 @@ version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1b113239362cee7093bfb250467138f079a2a03673181dc15bff6ccd677912d" dependencies = [ - "borsh", + "borsh 1.6.1", "bytemuck", "bytemuck_derive", "five8 1.0.0", @@ -7356,6 +8435,12 @@ dependencies = [ "wincode", ] +[[package]] +name = "solana-inflation" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23eef6a09eb8e568ce6839573e4966850e85e9ce71e6ae1a6c930c1c43947de3" + [[package]] name = "solana-inflation" version = "3.1.0" @@ -7373,6 +8458,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bab5682934bd1f65f8d2c16f21cb532526fcc1a09f796e2cacdb091eee5774ad" dependencies = [ "bincode", + "borsh 1.6.1", "getrandom 0.2.17", "js-sys", "num-traits", @@ -7391,7 +8477,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37ebb0ffd19263051bc3f683fcc086134b8ff23af894dcb63f7563c7137b42f1" dependencies = [ "bincode", - "borsh", + "borsh 1.6.1", "serde", "serde_derive", "solana-define-syscall 5.1.0", @@ -7442,19 +8528,18 @@ dependencies = [ [[package]] name = "solana-instructions-sysvar" -version = "3.0.0" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ddf67876c541aa1e21ee1acae35c95c6fbc61119814bfef70579317a5e26955" +checksum = "9e0732294560e88ecdb2bbc656e67383e9f88c78ec09469cef172f0d28cd1bcd" dependencies = [ "bitflags 2.11.1", "solana-account-info 3.1.1", "solana-instruction 3.4.0", "solana-instruction-error", "solana-program-error 3.0.1", - "solana-pubkey 3.0.0", "solana-sanitize 3.0.1", "solana-sdk-ids 3.1.0", - "solana-serialize-utils 3.1.1", + "solana-serialize-utils 3.1.2", "solana-sysvar-id 3.1.0", ] @@ -7481,6 +8566,22 @@ dependencies = [ "solana-hash 4.3.0", ] +[[package]] +name = "solana-keypair" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd3f04aa1a05c535e93e121a95f66e7dcccf57e007282e8255535d24bf1e98bb" +dependencies = [ + "ed25519-dalek 1.0.1", + "five8 0.2.1", + "rand 0.7.3", + "solana-pubkey 2.4.0", + "solana-seed-phrase 2.2.1", + "solana-signature 2.3.0", + "solana-signer 2.2.1", + "wasm-bindgen", +] + [[package]] name = "solana-keypair" version = "3.1.0" @@ -7492,11 +8593,11 @@ dependencies = [ "five8 1.0.0", "rand 0.8.6", "solana-address 2.6.0", - "solana-derivation-path", - "solana-seed-derivable", - "solana-seed-phrase", + "solana-derivation-path 3.0.0", + "solana-seed-derivable 3.0.0", + "solana-seed-phrase 3.0.0", "solana-signature 3.4.0", - "solana-signer", + "solana-signer 3.0.0", ] [[package]] @@ -7514,9 +8615,9 @@ dependencies = [ [[package]] name = "solana-last-restart-slot" -version = "3.0.0" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcda154ec827f5fc1e4da0af3417951b7e9b8157540f81f936c4a8b1156134d0" +checksum = "426711c6564b790026e45cabec3c64b971864c48b6b2d83c0ebf52a118bb4cda" dependencies = [ "serde", "serde_derive", @@ -7634,7 +8735,7 @@ dependencies = [ "solana-svm-log-collector", "solana-svm-measure", "solana-svm-type-overrides", - "solana-transaction-context", + "solana-transaction-context 3.1.12", ] [[package]] @@ -7766,11 +8867,20 @@ dependencies = [ "solana-sdk-ids 3.1.0", ] +[[package]] +name = "solana-nostd-keccak" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8ced70920435b1baa58f76e6f84bbc1110ddd1d6161ec76b6d731ae8431e9c4" +dependencies = [ + "sha3", +] + [[package]] name = "solana-nullable" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da028344c595c7416769ff648d206de7962571291a4cea24c38a60b6f40d53bb" +checksum = "a0f95d3028ef0f682bb174b77379c19d5dae2904a649f4a103fe29be7a139980" dependencies = [ "bytemuck", ] @@ -7788,7 +8898,7 @@ dependencies = [ "solana-sanitize 3.0.1", "solana-sha256-hasher 3.1.0", "solana-signature 3.4.0", - "solana-signer", + "solana-signer 3.0.0", ] [[package]] @@ -7837,7 +8947,7 @@ checksum = "0f704eaf825be3180832445b9e4983b875340696e8e7239bf2d535b0f86c14a2" dependencies = [ "solana-pubkey 3.0.0", "solana-signature 3.4.0", - "solana-signer", + "solana-signer 3.0.0", ] [[package]] @@ -7848,6 +8958,8 @@ checksum = "98eca145bd3545e2fbb07166e895370576e47a00a7d824e325390d33bf467210" dependencies = [ "bincode", "blake3", + "borsh 0.10.4", + "borsh 1.6.1", "bs58", "bytemuck", "console_error_panic_hook", @@ -7869,6 +8981,7 @@ dependencies = [ "solana-big-mod-exp 2.2.1", "solana-bincode 2.2.1", "solana-blake3-hasher 2.2.1", + "solana-borsh 2.2.1", "solana-clock 2.2.3", "solana-cpi 2.2.1", "solana-decode-error", @@ -7927,11 +9040,11 @@ dependencies = [ "solana-account-info 3.1.1", "solana-big-mod-exp 3.0.0", "solana-blake3-hasher 3.1.0", - "solana-borsh", - "solana-clock 3.0.1", + "solana-borsh 3.0.2", + "solana-clock 3.1.0", "solana-cpi 3.1.0", "solana-define-syscall 3.0.0", - "solana-epoch-rewards 3.0.1", + "solana-epoch-rewards 3.0.2", "solana-epoch-schedule 3.1.0", "solana-epoch-stake", "solana-example-mocks 3.0.0", @@ -7939,9 +9052,9 @@ dependencies = [ "solana-hash 3.1.0", "solana-instruction 3.4.0", "solana-instruction-error", - "solana-instructions-sysvar 3.0.0", + "solana-instructions-sysvar 3.0.1", "solana-keccak-hasher 3.1.0", - "solana-last-restart-slot 3.0.0", + "solana-last-restart-slot 3.0.1", "solana-msg 3.1.0", "solana-native-token 3.0.0", "solana-program-entrypoint 3.1.1", @@ -7954,11 +9067,11 @@ dependencies = [ "solana-sdk-ids 3.1.0", "solana-secp256k1-recover 3.1.1", "solana-serde-varint 3.0.1", - "solana-serialize-utils 3.1.1", + "solana-serialize-utils 3.1.2", "solana-sha256-hasher 3.1.0", "solana-short-vec 3.2.1", - "solana-slot-hashes 3.0.1", - "solana-slot-history 3.0.0", + "solana-slot-hashes 3.0.2", + "solana-slot-history 3.0.1", "solana-stable-layout 3.0.1", "solana-sysvar 3.1.1", "solana-sysvar-id 3.1.0", @@ -7994,6 +9107,7 @@ version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ee2e0217d642e2ea4bee237f37bd61bb02aec60da3647c48ff88f6556ade775" dependencies = [ + "borsh 1.6.1", "num-traits", "serde", "serde_derive", @@ -8009,7 +9123,7 @@ version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f04fa578707b3612b095f0c8e19b66a1233f7c42ca8082fcb3b745afcc0add6" dependencies = [ - "borsh", + "borsh 1.6.1", "serde", "serde_derive", ] @@ -8076,24 +9190,24 @@ dependencies = [ "serde", "solana-account 3.4.0", "solana-account-info 3.1.1", - "solana-clock 3.0.1", - "solana-epoch-rewards 3.0.1", + "solana-clock 3.1.0", + "solana-epoch-rewards 3.0.2", "solana-epoch-schedule 3.1.0", "solana-fee-structure", "solana-hash 3.1.0", "solana-instruction 3.4.0", - "solana-last-restart-slot 3.0.0", + "solana-last-restart-slot 3.0.1", "solana-loader-v3-interface 6.1.1", "solana-program-entrypoint 3.1.1", "solana-pubkey 3.0.0", "solana-rent 3.1.0", "solana-sbpf", "solana-sdk-ids 3.1.0", - "solana-slot-hashes 3.0.1", + "solana-slot-hashes 3.0.2", "solana-stable-layout 3.0.1", "solana-stake-interface 2.0.2", "solana-svm-callback", - "solana-svm-feature-set", + "solana-svm-feature-set 3.1.12", "solana-svm-log-collector", "solana-svm-measure", "solana-svm-timings", @@ -8102,7 +9216,7 @@ dependencies = [ "solana-system-interface 2.0.0", "solana-sysvar 3.1.1", "solana-sysvar-id 3.1.0", - "solana-transaction-context", + "solana-transaction-context 3.1.12", "thiserror 2.0.18", ] @@ -8112,6 +9226,8 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b62adb9c3261a052ca1f999398c388f1daf558a1b492f60a6d9e64857db4ff1" dependencies = [ + "borsh 0.10.4", + "borsh 1.6.1", "bytemuck", "bytemuck_derive", "curve25519-dalek 4.1.3", @@ -8162,10 +9278,10 @@ dependencies = [ "semver", "serde", "serde_json", - "solana-account-decoder-client-types", - "solana-clock 3.0.1", + "solana-account-decoder-client-types 3.1.12", + "solana-clock 3.1.0", "solana-pubkey 3.0.0", - "solana-rpc-client-types", + "solana-rpc-client-types 3.1.12", "solana-signature 3.4.0", "thiserror 2.0.18", "tokio", @@ -8210,6 +9326,16 @@ dependencies = [ "solana-sdk-macro 3.0.1", ] +[[package]] +name = "solana-reward-info" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18205b69139b1ae0ab8f6e11cdcb627328c0814422ad2482000fa2ca54ae4a2f" +dependencies = [ + "serde", + "serde_derive", +] + [[package]] name = "solana-reward-info" version = "3.0.0" @@ -8220,6 +9346,46 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "solana-rpc-client" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8d3161ac0918178e674c1f7f1bfac40de3e7ed0383bd65747d63113c156eaeb" +dependencies = [ + "async-trait", + "base64 0.22.1", + "bincode", + "bs58", + "futures", + "indicatif 0.17.11", + "log", + "reqwest 0.12.28", + "reqwest-middleware", + "semver", + "serde", + "serde_derive", + "serde_json", + "solana-account 2.2.1", + "solana-account-decoder-client-types 2.3.13", + "solana-clock 2.2.3", + "solana-commitment-config 2.2.1", + "solana-epoch-info 2.2.1", + "solana-epoch-schedule 2.2.1", + "solana-feature-gate-interface 2.2.2", + "solana-hash 2.3.0", + "solana-instruction 2.3.3", + "solana-message 2.4.0", + "solana-pubkey 2.4.0", + "solana-rpc-client-api 2.3.13", + "solana-signature 2.3.0", + "solana-transaction 2.2.3", + "solana-transaction-error 2.2.1", + "solana-transaction-status-client-types 2.3.13", + "solana-version 2.3.13", + "solana-vote-interface 2.2.6", + "tokio", +] + [[package]] name = "solana-rpc-client" version = "3.1.12" @@ -8231,7 +9397,7 @@ dependencies = [ "bincode", "bs58", "futures", - "indicatif", + "indicatif 0.18.4", "log", "reqwest 0.12.28", "reqwest-middleware", @@ -8240,26 +9406,48 @@ dependencies = [ "serde_json", "solana-account 3.4.0", "solana-account-decoder", - "solana-account-decoder-client-types", - "solana-clock 3.0.1", - "solana-commitment-config", - "solana-epoch-info", + "solana-account-decoder-client-types 3.1.12", + "solana-clock 3.1.0", + "solana-commitment-config 3.1.1", + "solana-epoch-info 3.1.0", "solana-epoch-schedule 3.1.0", "solana-feature-gate-interface 3.1.0", "solana-hash 3.1.0", "solana-instruction 3.4.0", "solana-message 3.1.0", "solana-pubkey 3.0.0", - "solana-rpc-client-api", + "solana-rpc-client-api 3.1.12", "solana-signature 3.4.0", - "solana-transaction", + "solana-transaction 3.1.0", "solana-transaction-error 3.2.0", - "solana-transaction-status-client-types", - "solana-version", + "solana-transaction-status-client-types 3.1.12", + "solana-version 3.1.12", "solana-vote-interface 4.0.4", "tokio", ] +[[package]] +name = "solana-rpc-client-api" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dbc138685c79d88a766a8fd825057a74ea7a21e1dd7f8de275ada899540fff7" +dependencies = [ + "anyhow", + "jsonrpc-core", + "reqwest 0.12.28", + "reqwest-middleware", + "serde", + "serde_derive", + "serde_json", + "solana-account-decoder-client-types 2.3.13", + "solana-clock 2.2.3", + "solana-rpc-client-types 2.3.13", + "solana-signer 2.2.1", + "solana-transaction-error 2.2.1", + "solana-transaction-status-client-types 2.3.13", + "thiserror 2.0.18", +] + [[package]] name = "solana-rpc-client-api" version = "3.1.12" @@ -8272,12 +9460,38 @@ dependencies = [ "reqwest-middleware", "serde", "serde_json", - "solana-account-decoder-client-types", - "solana-clock 3.0.1", - "solana-rpc-client-types", - "solana-signer", + "solana-account-decoder-client-types 3.1.12", + "solana-clock 3.1.0", + "solana-rpc-client-types 3.1.12", + "solana-signer 3.0.0", "solana-transaction-error 3.2.0", - "solana-transaction-status-client-types", + "solana-transaction-status-client-types 3.1.12", + "thiserror 2.0.18", +] + +[[package]] +name = "solana-rpc-client-types" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea428a81729255d895ea47fba9b30fd4dacbfe571a080448121bd0592751676" +dependencies = [ + "base64 0.22.1", + "bs58", + "semver", + "serde", + "serde_derive", + "serde_json", + "solana-account 2.2.1", + "solana-account-decoder-client-types 2.3.13", + "solana-clock 2.2.3", + "solana-commitment-config 2.2.1", + "solana-fee-calculator 2.2.1", + "solana-inflation 2.2.1", + "solana-pubkey 2.4.0", + "solana-transaction-error 2.2.1", + "solana-transaction-status-client-types 2.3.13", + "solana-version 2.3.13", + "spl-generic-token 1.0.1", "thiserror 2.0.18", ] @@ -8293,18 +9507,18 @@ dependencies = [ "serde", "serde_json", "solana-account 3.4.0", - "solana-account-decoder-client-types", + "solana-account-decoder-client-types 3.1.12", "solana-address 1.1.0", - "solana-clock 3.0.1", - "solana-commitment-config", + "solana-clock 3.1.0", + "solana-commitment-config 3.1.1", "solana-fee-calculator 3.2.0", - "solana-inflation", - "solana-reward-info", - "solana-transaction", + "solana-inflation 3.1.0", + "solana-reward-info 3.0.0", + "solana-transaction 3.1.0", "solana-transaction-error 3.2.0", - "solana-transaction-status-client-types", - "solana-version", - "spl-generic-token", + "solana-transaction-status-client-types 3.1.12", + "solana-version 3.1.12", + "spl-generic-token 2.0.1", "thiserror 2.0.18", ] @@ -8327,7 +9541,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15b079e08471a9dbfe1e48b2c7439c85aa2a055cbd54eddd8bd257b0a7dbb29" dependencies = [ "byteorder", - "combine", + "combine 3.8.1", "hash32", "libc", "log", @@ -8347,11 +9561,11 @@ dependencies = [ "bs58", "serde", "solana-account 3.4.0", - "solana-epoch-info", + "solana-epoch-info 3.1.0", "solana-epoch-rewards-hasher", "solana-fee-structure", - "solana-inflation", - "solana-keypair", + "solana-inflation 3.1.0", + "solana-keypair 3.1.0", "solana-message 3.1.0", "solana-offchain-message", "solana-presigner", @@ -8361,16 +9575,16 @@ dependencies = [ "solana-sanitize 3.0.1", "solana-sdk-ids 3.1.0", "solana-sdk-macro 3.0.1", - "solana-seed-derivable", - "solana-seed-phrase", + "solana-seed-derivable 3.0.0", + "solana-seed-phrase 3.0.0", "solana-serde", "solana-serde-varint 3.0.1", "solana-short-vec 3.2.1", "solana-shred-version", "solana-signature 3.4.0", - "solana-signer", + "solana-signer 3.0.0", "solana-time-utils 3.0.0", - "solana-transaction", + "solana-transaction 3.1.0", "solana-transaction-error 3.2.0", "thiserror 2.0.18", ] @@ -8465,13 +9679,39 @@ dependencies = [ "solana-sdk-ids 3.1.0", ] +[[package]] +name = "solana-security-txt" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c94a02d486b28f219a4f8f5d7dd93cbfbb93c9f466cb7871c22e50cd5ae9a7a2" + +[[package]] +name = "solana-seed-derivable" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3beb82b5adb266c6ea90e5cf3967235644848eac476c5a1f2f9283a143b7c97f" +dependencies = [ + "solana-derivation-path 2.2.1", +] + [[package]] name = "solana-seed-derivable" version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff7bdb72758e3bec33ed0e2658a920f1f35dfb9ed576b951d20d63cb61ecd95c" +checksum = "ff7bdb72758e3bec33ed0e2658a920f1f35dfb9ed576b951d20d63cb61ecd95c" +dependencies = [ + "solana-derivation-path 3.0.0", +] + +[[package]] +name = "solana-seed-phrase" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36187af2324f079f65a675ec22b31c24919cb4ac22c79472e85d819db9bbbc15" dependencies = [ - "solana-derivation-path", + "hmac 0.12.1", + "pbkdf2", + "sha2 0.10.9", ] [[package]] @@ -8525,9 +9765,9 @@ dependencies = [ [[package]] name = "solana-serialize-utils" -version = "3.1.1" +version = "3.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d7cc401931d178472358e6b78dc72d031dc08f752d7410f0e8bd259dd6f02fa" +checksum = "761357b0853c9623bf12c1d2314b3d6160a85b087b84c45224fb85766d22616b" dependencies = [ "solana-instruction-error", "solana-pubkey 4.2.0", @@ -8591,6 +9831,7 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64c8ec8e657aecfc187522fc67495142c12f35e55ddeca8698edbb738b8dbd8c" dependencies = [ + "ed25519-dalek 1.0.1", "five8 0.2.1", "serde", "serde-big-array", @@ -8614,6 +9855,17 @@ dependencies = [ "wincode", ] +[[package]] +name = "solana-signer" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c41991508a4b02f021c1342ba00bcfa098630b213726ceadc7cb032e051975b" +dependencies = [ + "solana-pubkey 2.4.0", + "solana-signature 2.3.0", + "solana-transaction-error 2.2.1", +] + [[package]] name = "solana-signer" version = "3.0.0" @@ -8640,9 +9892,9 @@ dependencies = [ [[package]] name = "solana-slot-hashes" -version = "3.0.1" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2585f70191623887329dfb5078da3a00e15e3980ea67f42c2e10b07028419f43" +checksum = "0a57c158c35629f9e302ab385f16b15813f4927a31c27dda72f3df828bb08d93" dependencies = [ "serde", "serde_derive", @@ -8666,9 +9918,9 @@ dependencies = [ [[package]] name = "solana-slot-history" -version = "3.0.0" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f914f6b108f5bba14a280b458d023e3621c9973f27f015a4d755b50e88d89e97" +checksum = "0622d03a823770f7763afd866e012b296d5a3cbbbe51e110b5bd9ab3441efdca" dependencies = [ "bv", "serde", @@ -8703,6 +9955,8 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5269e89fde216b4d7e1d1739cf5303f8398a1ff372a81232abbee80e554a838c" dependencies = [ + "borsh 0.10.4", + "borsh 1.6.1", "num-traits", "serde", "serde_derive", @@ -8725,7 +9979,7 @@ dependencies = [ "num-traits", "serde", "serde_derive", - "solana-clock 3.0.1", + "solana-clock 3.1.0", "solana-cpi 3.1.0", "solana-instruction 3.4.0", "solana-program-error 3.0.1", @@ -8751,7 +10005,7 @@ dependencies = [ "solana-message 3.1.0", "solana-pubkey 3.0.0", "solana-signature 3.4.0", - "solana-transaction", + "solana-transaction 3.1.0", "solana-transaction-error 3.2.0", "solana-transaction-status", "tonic-prost-build", @@ -8768,11 +10022,11 @@ dependencies = [ "qualifier_attr", "serde", "solana-account 3.4.0", - "solana-clock 3.0.1", + "solana-clock 3.1.0", "solana-fee-structure", "solana-hash 3.1.0", "solana-instruction 3.4.0", - "solana-instructions-sysvar 3.0.0", + "solana-instructions-sysvar 3.0.1", "solana-loader-v3-interface 6.1.1", "solana-loader-v4-interface 3.1.0", "solana-loader-v4-program", @@ -8786,7 +10040,7 @@ dependencies = [ "solana-rent 3.1.0", "solana-sdk-ids 3.1.0", "solana-svm-callback", - "solana-svm-feature-set", + "solana-svm-feature-set 3.1.12", "solana-svm-log-collector", "solana-svm-measure", "solana-svm-timings", @@ -8794,9 +10048,9 @@ dependencies = [ "solana-svm-type-overrides", "solana-system-interface 2.0.0", "solana-sysvar-id 3.1.0", - "solana-transaction-context", + "solana-transaction-context 3.1.12", "solana-transaction-error 3.2.0", - "spl-generic-token", + "spl-generic-token 2.0.1", "thiserror 2.0.18", ] @@ -8807,11 +10061,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb521c7f62db21661267a933f0d311a76b2b744a766b46f5a9a9395ce70f687c" dependencies = [ "solana-account 3.4.0", - "solana-clock 3.0.1", + "solana-clock 3.1.0", "solana-precompile-error", "solana-pubkey 3.0.0", ] +[[package]] +name = "solana-svm-feature-set" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f24b836eb4d74ec255217bdbe0f24f64a07adeac31aca61f334f91cd4a3b1d5" + [[package]] name = "solana-svm-feature-set" version = "3.1.12" @@ -8855,7 +10115,7 @@ dependencies = [ "solana-pubkey 3.0.0", "solana-sdk-ids 3.1.0", "solana-signature 3.4.0", - "solana-transaction", + "solana-transaction 3.1.0", ] [[package]] @@ -8936,7 +10196,7 @@ dependencies = [ "solana-svm-type-overrides", "solana-system-interface 2.0.0", "solana-sysvar 3.1.1", - "solana-transaction-context", + "solana-transaction-context 3.1.12", ] [[package]] @@ -8946,12 +10206,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a31b5699ec533621515e714f1533ee6b3b0e71c463301d919eb59b8c1e249d30" dependencies = [ "solana-hash 3.1.0", - "solana-keypair", + "solana-keypair 3.1.0", "solana-message 3.1.0", "solana-pubkey 3.0.0", - "solana-signer", + "solana-signer 3.0.0", "solana-system-interface 2.0.0", - "solana-transaction", + "solana-transaction 3.1.0", ] [[package]] @@ -9005,14 +10265,14 @@ dependencies = [ "serde", "serde_derive", "solana-account-info 3.1.1", - "solana-clock 3.0.1", + "solana-clock 3.1.0", "solana-define-syscall 4.0.1", - "solana-epoch-rewards 3.0.1", + "solana-epoch-rewards 3.0.2", "solana-epoch-schedule 3.1.0", "solana-fee-calculator 3.2.0", "solana-hash 4.3.0", "solana-instruction 3.4.0", - "solana-last-restart-slot 3.0.0", + "solana-last-restart-slot 3.0.1", "solana-program-entrypoint 3.1.1", "solana-program-error 3.0.1", "solana-program-memory 3.1.0", @@ -9020,8 +10280,8 @@ dependencies = [ "solana-rent 3.1.0", "solana-sdk-ids 3.1.0", "solana-sdk-macro 3.0.1", - "solana-slot-hashes 3.0.1", - "solana-slot-history 3.0.0", + "solana-slot-hashes 3.0.2", + "solana-slot-history 3.0.1", "solana-sysvar-id 3.1.0", ] @@ -9057,6 +10317,31 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ced92c60aa76ec4780a9d93f3bd64dfa916e1b998eacc6f1c110f3f444f02c9" +[[package]] +name = "solana-transaction" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80657d6088f721148f5d889c828ca60c7daeedac9a8679f9ec215e0c42bcbf41" +dependencies = [ + "bincode", + "serde", + "serde_derive", + "solana-bincode 2.2.1", + "solana-hash 2.3.0", + "solana-instruction 2.3.3", + "solana-keypair 2.2.3", + "solana-message 2.4.0", + "solana-pubkey 2.4.0", + "solana-sanitize 2.2.1", + "solana-sdk-ids 2.2.1", + "solana-short-vec 2.2.1", + "solana-signature 2.3.0", + "solana-signer 2.2.1", + "solana-system-interface 1.0.0", + "solana-transaction-error 2.2.1", + "wasm-bindgen", +] + [[package]] name = "solana-transaction" version = "3.1.0" @@ -9075,10 +10360,27 @@ dependencies = [ "solana-sdk-ids 3.1.0", "solana-short-vec 3.2.1", "solana-signature 3.4.0", - "solana-signer", + "solana-signer 3.0.0", "solana-transaction-error 3.2.0", ] +[[package]] +name = "solana-transaction-context" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54a312304361987a85b2ef2293920558e6612876a639dd1309daf6d0d59ef2fe" +dependencies = [ + "bincode", + "serde", + "serde_derive", + "solana-account 2.2.1", + "solana-instruction 2.3.3", + "solana-instructions-sysvar 2.2.2", + "solana-pubkey 2.4.0", + "solana-rent 2.2.1", + "solana-sdk-ids 2.2.1", +] + [[package]] name = "solana-transaction-context" version = "3.1.12" @@ -9089,7 +10391,7 @@ dependencies = [ "serde", "solana-account 3.4.0", "solana-instruction 3.4.0", - "solana-instructions-sysvar 3.0.0", + "solana-instructions-sysvar 3.0.1", "solana-pubkey 3.0.0", "solana-rent 3.1.0", "solana-sbpf", @@ -9102,6 +10404,8 @@ version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "222a9dc8fdb61c6088baab34fc3a8b8473a03a7a5fd404ed8dd502fa79b67cb1" dependencies = [ + "serde", + "serde_derive", "solana-instruction 2.3.3", "solana-sanitize 2.2.1", ] @@ -9128,14 +10432,14 @@ dependencies = [ "agave-reserved-account-keys", "base64 0.22.1", "bincode", - "borsh", + "borsh 1.6.1", "bs58", "log", "serde", "serde_json", "solana-account-decoder", "solana-address-lookup-table-interface 3.1.0", - "solana-clock 3.0.1", + "solana-clock 3.1.0", "solana-hash 3.1.0", "solana-instruction 3.4.0", "solana-loader-v2-interface 3.0.0", @@ -9143,21 +10447,44 @@ dependencies = [ "solana-message 3.1.0", "solana-program-option 3.1.0", "solana-pubkey 3.0.0", - "solana-reward-info", + "solana-reward-info 3.0.0", "solana-sdk-ids 3.1.0", "solana-signature 3.4.0", "solana-stake-interface 2.0.2", "solana-system-interface 2.0.0", - "solana-transaction", + "solana-transaction 3.1.0", "solana-transaction-error 3.2.0", - "solana-transaction-status-client-types", + "solana-transaction-status-client-types 3.1.12", "solana-vote-interface 4.0.4", "spl-associated-token-account-interface", "spl-memo-interface", - "spl-token-2022-interface", - "spl-token-group-interface", + "spl-token-2022-interface 2.1.0", + "spl-token-group-interface 0.7.2", "spl-token-interface", - "spl-token-metadata-interface", + "spl-token-metadata-interface 0.8.0", + "thiserror 2.0.18", +] + +[[package]] +name = "solana-transaction-status-client-types" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51f1d7c2387c35850848212244d2b225847666cb52d3bd59a5c409d2c300303d" +dependencies = [ + "base64 0.22.1", + "bincode", + "bs58", + "serde", + "serde_derive", + "serde_json", + "solana-account-decoder-client-types 2.3.13", + "solana-commitment-config 2.2.1", + "solana-message 2.4.0", + "solana-reward-info 2.2.1", + "solana-signature 2.3.0", + "solana-transaction 2.2.3", + "solana-transaction-context 2.3.13", + "solana-transaction-error 2.2.1", "thiserror 2.0.18", ] @@ -9172,26 +10499,41 @@ dependencies = [ "bs58", "serde", "serde_json", - "solana-account-decoder-client-types", - "solana-commitment-config", + "solana-account-decoder-client-types 3.1.12", + "solana-commitment-config 3.1.1", "solana-instruction 3.4.0", "solana-message 3.1.0", "solana-pubkey 3.0.0", - "solana-reward-info", + "solana-reward-info 3.0.0", "solana-signature 3.4.0", - "solana-transaction", - "solana-transaction-context", + "solana-transaction 3.1.0", + "solana-transaction-context 3.1.12", "solana-transaction-error 3.2.0", "thiserror 2.0.18", ] +[[package]] +name = "solana-version" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3324d46c7f7b7f5d34bf7dc71a2883bdc072c7b28ca81d0b2167ecec4cf8da9f" +dependencies = [ + "agave-feature-set 2.3.13", + "rand 0.8.6", + "semver", + "serde", + "serde_derive", + "solana-sanitize 2.2.1", + "solana-serde-varint 2.2.2", +] + [[package]] name = "solana-version" version = "3.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f697aacc5aa4ac5534abdde8a91afdcf18c24d28bd52768e8001445dbda078db" dependencies = [ - "agave-feature-set", + "agave-feature-set 3.1.12", "rand 0.8.6", "semver", "serde", @@ -9236,7 +10578,7 @@ dependencies = [ "serde", "serde_derive", "serde_with", - "solana-clock 3.0.1", + "solana-clock 3.1.0", "solana-hash 3.1.0", "solana-instruction 3.4.0", "solana-instruction-error", @@ -9244,18 +10586,18 @@ dependencies = [ "solana-rent 3.1.0", "solana-sdk-ids 3.1.0", "solana-serde-varint 3.0.1", - "solana-serialize-utils 3.1.1", + "solana-serialize-utils 3.1.2", "solana-short-vec 3.2.1", "solana-system-interface 2.0.0", ] [[package]] name = "solana-zero-copy" -version = "1.0.1" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5a91404c7de468dd80658cdb5d894ec803d1092ea6e2bfdf84eee6f07559c0d" +checksum = "8ea15126ebdc7e270c50d43884369af9f51d2308156d46a18e351522a164844d" dependencies = [ - "borsh", + "borsh 1.6.1", "bytemuck", "bytemuck_derive", ] @@ -9266,7 +10608,7 @@ version = "3.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cee65de587e6fe912668903e62f3f40c02a834f21967a18cc6c71f550c51a639" dependencies = [ - "agave-feature-set", + "agave-feature-set 3.1.12", "bytemuck", "num-derive", "num-traits", @@ -9274,7 +10616,43 @@ dependencies = [ "solana-program-runtime", "solana-sdk-ids 3.1.0", "solana-svm-log-collector", - "solana-zk-sdk", + "solana-zk-sdk 4.0.0", +] + +[[package]] +name = "solana-zk-sdk" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b9fc6ec37d16d0dccff708ed1dd6ea9ba61796700c3bb7c3b401973f10f63b" +dependencies = [ + "aes-gcm-siv", + "base64 0.22.1", + "bincode", + "bytemuck", + "bytemuck_derive", + "curve25519-dalek 4.1.3", + "itertools 0.12.1", + "js-sys", + "merlin", + "num-derive", + "num-traits", + "rand 0.8.6", + "serde", + "serde_derive", + "serde_json", + "sha3", + "solana-derivation-path 2.2.1", + "solana-instruction 2.3.3", + "solana-pubkey 2.4.0", + "solana-sdk-ids 2.2.1", + "solana-seed-derivable 2.2.1", + "solana-seed-phrase 2.2.1", + "solana-signature 2.3.0", + "solana-signer 2.2.1", + "subtle", + "thiserror 2.0.18", + "wasm-bindgen", + "zeroize", ] [[package]] @@ -9300,14 +10678,14 @@ dependencies = [ "serde_derive", "serde_json", "sha3", - "solana-derivation-path", + "solana-derivation-path 3.0.0", "solana-instruction 3.4.0", "solana-pubkey 3.0.0", "solana-sdk-ids 3.1.0", - "solana-seed-derivable", - "solana-seed-phrase", + "solana-seed-derivable 3.0.0", + "solana-seed-phrase 3.0.0", "solana-signature 3.4.0", - "solana-signer", + "solana-signer 3.0.0", "subtle", "thiserror 2.0.18", "wasm-bindgen", @@ -9378,11 +10756,23 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6433917b60441d68d99a17e121d9db0ea15a9a69c0e5afa34649cf5ba12612f" dependencies = [ - "borsh", + "borsh 1.6.1", "solana-instruction 3.4.0", "solana-pubkey 3.0.0", ] +[[package]] +name = "spl-discriminator" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7398da23554a31660f17718164e31d31900956054f54f52d5ec1be51cb4f4b3" +dependencies = [ + "bytemuck", + "solana-program-error 2.2.2", + "solana-sha256-hasher 2.3.0", + "spl-discriminator-derive", +] + [[package]] name = "spl-discriminator" version = "0.5.2" @@ -9410,52 +10800,229 @@ dependencies = [ name = "spl-discriminator-syn" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d1dbc82ab91422345b6df40a79e2b78c7bce1ebb366da323572dd60b7076b67" +checksum = "5d1dbc82ab91422345b6df40a79e2b78c7bce1ebb366da323572dd60b7076b67" +dependencies = [ + "proc-macro2", + "quote", + "sha2 0.10.9", + "syn 2.0.117", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-elgamal-registry" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce0f668975d2b0536e8a8fd60e56a05c467f06021dae037f1d0cfed0de2e231d" +dependencies = [ + "bytemuck", + "solana-program 2.3.0", + "solana-zk-sdk 2.3.13", + "spl-pod 0.5.1", + "spl-token-confidential-transfer-proof-extraction 0.2.1", +] + +[[package]] +name = "spl-generic-token" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "741a62a566d97c58d33f9ed32337ceedd4e35109a686e31b1866c5dfa56abddc" +dependencies = [ + "bytemuck", + "solana-pubkey 2.4.0", +] + +[[package]] +name = "spl-generic-token" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233df81b75ab99b42f002b5cdd6e65a7505ffa930624f7096a7580a56765e9cf" +dependencies = [ + "bytemuck", + "solana-pubkey 3.0.0", +] + +[[package]] +name = "spl-memo" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f09647c0974e33366efeb83b8e2daebb329f0420149e74d3a4bd2c08cf9f7cb" +dependencies = [ + "solana-account-info 2.3.0", + "solana-instruction 2.3.3", + "solana-msg 2.2.1", + "solana-program-entrypoint 2.3.0", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", +] + +[[package]] +name = "spl-memo-interface" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3745d384b0afee980d43d62b66c27bdcbbd03507732b8d3626d3413cb72084f2" +dependencies = [ + "solana-instruction 3.4.0", + "solana-pubkey 4.2.0", +] + +[[package]] +name = "spl-pod" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d994afaf86b779104b4a95ba9ca75b8ced3fdb17ee934e38cb69e72afbe17799" +dependencies = [ + "borsh 1.6.1", + "bytemuck", + "bytemuck_derive", + "num-derive", + "num-traits", + "solana-decode-error", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-program-option 2.2.1", + "solana-pubkey 2.4.0", + "solana-zk-sdk 2.3.13", + "thiserror 2.0.18", +] + +[[package]] +name = "spl-pod" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f9c6e142cdf1e7e77f480053ec9f0ce989890768ddf91f619b50f39d1b456f5" +dependencies = [ + "borsh 1.6.1", + "bytemuck", + "bytemuck_derive", + "num-derive", + "num-traits", + "num_enum", + "solana-program-error 3.0.1", + "solana-program-option 3.1.0", + "solana-pubkey 3.0.0", + "solana-zero-copy", + "solana-zk-sdk 4.0.0", + "thiserror 2.0.18", +] + +[[package]] +name = "spl-program-error" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d39b5186f42b2b50168029d81e58e800b690877ef0b30580d107659250da1d1" +dependencies = [ + "num-derive", + "num-traits", + "solana-program 2.3.0", + "spl-program-error-derive", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-program-error-derive" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d375dd76c517836353e093c2dbb490938ff72821ab568b545fd30ab3256b3e" +dependencies = [ + "proc-macro2", + "quote", + "sha2 0.10.9", + "syn 2.0.117", +] + +[[package]] +name = "spl-tlv-account-resolution" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd99ff1e9ed2ab86e3fd582850d47a739fec1be9f4661cba1782d3a0f26805f3" dependencies = [ - "proc-macro2", - "quote", - "sha2 0.10.9", - "syn 2.0.117", + "bytemuck", + "num-derive", + "num-traits", + "solana-account-info 2.3.0", + "solana-decode-error", + "solana-instruction 2.3.3", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "spl-discriminator 0.4.1", + "spl-pod 0.5.1", + "spl-program-error", + "spl-type-length-value 0.7.0", "thiserror 1.0.69", ] [[package]] -name = "spl-generic-token" -version = "2.0.1" +name = "spl-token" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233df81b75ab99b42f002b5cdd6e65a7505ffa930624f7096a7580a56765e9cf" +checksum = "ed320a6c934128d4f7e54fe00e16b8aeaecf215799d060ae14f93378da6dc834" dependencies = [ + "arrayref", "bytemuck", - "solana-pubkey 3.0.0", + "num-derive", + "num-traits", + "num_enum", + "solana-program 2.3.0", + "thiserror 1.0.69", ] [[package]] -name = "spl-memo-interface" -version = "2.0.0" +name = "spl-token-2022" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d4e2aedd58f858337fa609af5ad7100d4a243fdaf6a40d6eb4c28c5f19505d3" +checksum = "9048b26b0df0290f929ff91317c83db28b3ef99af2b3493dd35baa146774924c" dependencies = [ - "solana-instruction 3.4.0", - "solana-pubkey 3.0.0", + "arrayref", + "bytemuck", + "num-derive", + "num-traits", + "num_enum", + "solana-program 2.3.0", + "solana-security-txt", + "solana-zk-sdk 2.3.13", + "spl-elgamal-registry", + "spl-memo", + "spl-pod 0.5.1", + "spl-token", + "spl-token-confidential-transfer-ciphertext-arithmetic", + "spl-token-confidential-transfer-proof-extraction 0.2.1", + "spl-token-confidential-transfer-proof-generation 0.3.0", + "spl-token-group-interface 0.5.0", + "spl-token-metadata-interface 0.6.0", + "spl-transfer-hook-interface", + "spl-type-length-value 0.7.0", + "thiserror 2.0.18", ] [[package]] -name = "spl-pod" -version = "0.7.3" +name = "spl-token-2022-interface" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f9c6e142cdf1e7e77f480053ec9f0ce989890768ddf91f619b50f39d1b456f5" +checksum = "62d7ae2ee6b856f8ddcbdc3b3a9f4d2141582bbe150f93e5298ee97e0251fa04" dependencies = [ - "borsh", + "arrayref", "bytemuck", - "bytemuck_derive", "num-derive", "num-traits", "num_enum", - "solana-program-error 3.0.1", - "solana-program-option 3.1.0", - "solana-pubkey 3.0.0", - "solana-zero-copy", - "solana-zk-sdk", + "solana-account-info 2.3.0", + "solana-decode-error", + "solana-instruction 2.3.3", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-program-option 2.2.1", + "solana-program-pack 2.2.1", + "solana-pubkey 2.4.0", + "solana-sdk-ids 2.2.1", + "solana-zk-sdk 2.3.13", + "spl-pod 0.5.1", + "spl-token-confidential-transfer-proof-extraction 0.4.1", + "spl-token-confidential-transfer-proof-generation 0.4.1", + "spl-token-group-interface 0.6.0", + "spl-token-metadata-interface 0.7.0", + "spl-type-length-value 0.8.0", "thiserror 2.0.18", ] @@ -9477,13 +11044,59 @@ dependencies = [ "solana-program-pack 3.1.0", "solana-pubkey 3.0.0", "solana-sdk-ids 3.1.0", - "solana-zk-sdk", - "spl-pod", - "spl-token-confidential-transfer-proof-extraction", - "spl-token-confidential-transfer-proof-generation", - "spl-token-group-interface", - "spl-token-metadata-interface", - "spl-type-length-value", + "solana-zk-sdk 4.0.0", + "spl-pod 0.7.3", + "spl-token-confidential-transfer-proof-extraction 0.5.1", + "spl-token-confidential-transfer-proof-generation 0.5.1", + "spl-token-group-interface 0.7.2", + "spl-token-metadata-interface 0.8.0", + "spl-type-length-value 0.9.1", + "thiserror 2.0.18", +] + +[[package]] +name = "spl-token-confidential-transfer-ciphertext-arithmetic" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "170378693c5516090f6d37ae9bad2b9b6125069be68d9acd4865bbe9fc8499fd" +dependencies = [ + "base64 0.22.1", + "bytemuck", + "solana-curve25519 2.3.13", + "solana-zk-sdk 2.3.13", +] + +[[package]] +name = "spl-token-confidential-transfer-proof-extraction" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eff2d6a445a147c9d6dd77b8301b1e116c8299601794b558eafa409b342faf96" +dependencies = [ + "bytemuck", + "solana-curve25519 2.3.13", + "solana-program 2.3.0", + "solana-zk-sdk 2.3.13", + "spl-pod 0.5.1", + "thiserror 2.0.18", +] + +[[package]] +name = "spl-token-confidential-transfer-proof-extraction" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512c85bdbbb4cbcc2038849a9e164c958b16541f252b53ea1a3933191c0a4a1a" +dependencies = [ + "bytemuck", + "solana-account-info 2.3.0", + "solana-curve25519 2.3.13", + "solana-instruction 2.3.3", + "solana-instructions-sysvar 2.2.2", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "solana-sdk-ids 2.2.1", + "solana-zk-sdk 2.3.13", + "spl-pod 0.5.1", "thiserror 2.0.18", ] @@ -9495,15 +11108,37 @@ checksum = "879a9ebad0d77383d3ea71e7de50503554961ff0f4ef6cbca39ad126e6f6da3a" dependencies = [ "bytemuck", "solana-account-info 3.1.1", - "solana-curve25519", + "solana-curve25519 3.1.12", "solana-instruction 3.4.0", - "solana-instructions-sysvar 3.0.0", + "solana-instructions-sysvar 3.0.1", "solana-msg 3.1.0", "solana-program-error 3.0.1", "solana-pubkey 3.0.0", "solana-sdk-ids 3.1.0", - "solana-zk-sdk", - "spl-pod", + "solana-zk-sdk 4.0.0", + "spl-pod 0.7.3", + "thiserror 2.0.18", +] + +[[package]] +name = "spl-token-confidential-transfer-proof-generation" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e3597628b0d2fe94e7900fd17cdb4cfbb31ee35c66f82809d27d86e44b2848b" +dependencies = [ + "curve25519-dalek 4.1.3", + "solana-zk-sdk 2.3.13", + "thiserror 2.0.18", +] + +[[package]] +name = "spl-token-confidential-transfer-proof-generation" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa27b9174bea869a7ebf31e0be6890bce90b1a4288bc2bbf24bd413f80ae3fde" +dependencies = [ + "curve25519-dalek 4.1.3", + "solana-zk-sdk 2.3.13", "thiserror 2.0.18", ] @@ -9514,7 +11149,45 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0cd59fce3dc00f563c6fa364d67c3f200d278eae681f4dc250240afcfe044b1" dependencies = [ "curve25519-dalek 4.1.3", - "solana-zk-sdk", + "solana-zk-sdk 4.0.0", + "thiserror 2.0.18", +] + +[[package]] +name = "spl-token-group-interface" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d595667ed72dbfed8c251708f406d7c2814a3fa6879893b323d56a10bedfc799" +dependencies = [ + "bytemuck", + "num-derive", + "num-traits", + "solana-decode-error", + "solana-instruction 2.3.3", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "spl-discriminator 0.4.1", + "spl-pod 0.5.1", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-token-group-interface" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5597b4cd76f85ce7cd206045b7dc22da8c25516573d42d267c8d1fd128db5129" +dependencies = [ + "bytemuck", + "num-derive", + "num-traits", + "solana-decode-error", + "solana-instruction 2.3.3", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "spl-discriminator 0.4.1", + "spl-pod 0.5.1", "thiserror 2.0.18", ] @@ -9533,7 +11206,7 @@ dependencies = [ "solana-nullable", "solana-program-error 3.0.1", "solana-zero-copy", - "spl-discriminator", + "spl-discriminator 0.5.2", "thiserror 2.0.18", ] @@ -9557,22 +11230,125 @@ dependencies = [ "thiserror 2.0.18", ] +[[package]] +name = "spl-token-metadata-interface" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfb9c89dbc877abd735f05547dcf9e6e12c00c11d6d74d8817506cab4c99fdbb" +dependencies = [ + "borsh 1.6.1", + "num-derive", + "num-traits", + "solana-borsh 2.2.1", + "solana-decode-error", + "solana-instruction 2.3.3", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "spl-discriminator 0.4.1", + "spl-pod 0.5.1", + "spl-type-length-value 0.7.0", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-token-metadata-interface" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "304d6e06f0de0c13a621464b1fd5d4b1bebf60d15ca71a44d3839958e0da16ee" +dependencies = [ + "borsh 1.6.1", + "num-derive", + "num-traits", + "solana-borsh 2.2.1", + "solana-decode-error", + "solana-instruction 2.3.3", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "spl-discriminator 0.4.1", + "spl-pod 0.5.1", + "spl-type-length-value 0.8.0", + "thiserror 2.0.18", +] + [[package]] name = "spl-token-metadata-interface" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c467c7c3bd056f8fe60119e7ec34ddd6f23052c2fa8f1f51999098063b72676" dependencies = [ - "borsh", + "borsh 1.6.1", "num-derive", "num-traits", - "solana-borsh", + "solana-borsh 3.0.2", "solana-instruction 3.4.0", "solana-program-error 3.0.1", "solana-pubkey 3.0.0", - "spl-discriminator", - "spl-pod", - "spl-type-length-value", + "spl-discriminator 0.5.2", + "spl-pod 0.7.3", + "spl-type-length-value 0.9.1", + "thiserror 2.0.18", +] + +[[package]] +name = "spl-transfer-hook-interface" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4aa7503d52107c33c88e845e1351565050362c2314036ddf19a36cd25137c043" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive", + "num-traits", + "solana-account-info 2.3.0", + "solana-cpi 2.2.1", + "solana-decode-error", + "solana-instruction 2.3.3", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "spl-discriminator 0.4.1", + "spl-pod 0.5.1", + "spl-program-error", + "spl-tlv-account-resolution", + "spl-type-length-value 0.7.0", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-type-length-value" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba70ef09b13af616a4c987797870122863cba03acc4284f226a4473b043923f9" +dependencies = [ + "bytemuck", + "num-derive", + "num-traits", + "solana-account-info 2.3.0", + "solana-decode-error", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "spl-discriminator 0.4.1", + "spl-pod 0.5.1", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-type-length-value" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d417eb548214fa822d93f84444024b4e57c13ed6719d4dcc68eec24fb481e9f5" +dependencies = [ + "bytemuck", + "num-derive", + "num-traits", + "solana-account-info 2.3.0", + "solana-decode-error", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "spl-discriminator 0.4.1", + "spl-pod 0.5.1", "thiserror 2.0.18", ] @@ -9589,7 +11365,7 @@ dependencies = [ "solana-account-info 3.1.1", "solana-program-error 3.0.1", "solana-zero-copy", - "spl-discriminator", + "spl-discriminator 0.5.2", "thiserror 2.0.18", ] @@ -9758,9 +11534,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tar" -version = "0.4.45" +version = "0.4.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22692a6476a21fa75fdfc11d452fda482af402c008cdbaf3476414e122040973" +checksum = "3f6221d9a6003c78398e3b239969f352578258df48c8eb051caadae0015bc840" dependencies = [ "filetime", "libc", @@ -9777,7 +11553,7 @@ dependencies = [ "getrandom 0.4.2", "once_cell", "rustix 1.1.4", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -9791,14 +11567,15 @@ dependencies = [ "magicblock-processor", "solana-account 3.4.0", "solana-instruction 3.4.0", - "solana-keypair", + "solana-keypair 3.1.0", "solana-program 3.0.0", - "solana-rpc-client", + "solana-pubkey 3.0.0", + "solana-rpc-client 3.1.12", "solana-signature 3.4.0", - "solana-signer", - "solana-transaction", + "solana-signer 3.0.0", + "solana-transaction 3.1.0", "solana-transaction-error 3.2.0", - "solana-transaction-status-client-types", + "solana-transaction-status-client-types 3.1.12", "tempfile", "tokio", "tokio-util", @@ -9914,9 +11691,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.52.1" +version = "1.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67dee974fe86fd92cc45b7a95fdd2f99a36a6d7b0d431a231178d3d670bbcc6" +checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" dependencies = [ "bytes", "libc", @@ -10037,6 +11814,15 @@ dependencies = [ "webpki-roots 0.26.11", ] +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + [[package]] name = "toml" version = "0.8.23" @@ -10090,7 +11876,7 @@ dependencies = [ "indexmap 2.14.0", "toml_datetime 1.1.1+spec-1.1.0", "toml_parser", - "winnow 1.0.2", + "winnow 1.0.3", ] [[package]] @@ -10099,7 +11885,7 @@ version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" dependencies = [ - "winnow 1.0.2", + "winnow 1.0.3", ] [[package]] @@ -10120,7 +11906,7 @@ dependencies = [ "base64 0.22.1", "bytes", "flate2", - "h2 0.4.13", + "h2 0.4.14", "http 1.4.0", "http-body 1.0.1", "http-body-util", @@ -10144,16 +11930,16 @@ dependencies = [ [[package]] name = "tonic" -version = "0.14.5" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fec7c61a0695dc1887c1b53952990f3ad2e3a31453e1f49f10e75424943a93ec" +checksum = "ac2a5518c70fa84342385732db33fb3f44bc4cc748936eb5833d2df34d6445ef" dependencies = [ "async-trait", "axum 0.8.9", "base64 0.22.1", "bytes", "flate2", - "h2 0.4.13", + "h2 0.4.14", "http 1.4.0", "http-body 1.0.1", "http-body-util", @@ -10190,9 +11976,9 @@ dependencies = [ [[package]] name = "tonic-build" -version = "0.14.5" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1882ac3bf5ef12877d7ed57aad87e75154c11931c2ba7e6cde5e22d63522c734" +checksum = "c68f61875ac5293cf72e6c8cf0158086428c82c37229e98c840878f1706b0322" dependencies = [ "prettyplease", "proc-macro2", @@ -10202,33 +11988,33 @@ dependencies = [ [[package]] name = "tonic-health" -version = "0.14.5" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4ff0636fef47afb3ec02818f5bceb4377b8abb9d6a386aeade18bd6212f8eb7" +checksum = "fcfab99db777fba2802f0dfa861d1628d1ae916fb199d29819941f139ae85082" dependencies = [ "prost 0.14.3", "tokio", "tokio-stream", - "tonic 0.14.5", + "tonic 0.14.6", "tonic-prost", ] [[package]] name = "tonic-prost" -version = "0.14.5" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a55376a0bbaa4975a3f10d009ad763d8f4108f067c7c2e74f3001fb49778d309" +checksum = "50849f68853be452acf590cde0b146665b8d507b3b8af17261df47e02c209ea0" dependencies = [ "bytes", "prost 0.14.3", - "tonic 0.14.5", + "tonic 0.14.6", ] [[package]] name = "tonic-prost-build" -version = "0.14.5" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3144df636917574672e93d0f56d7edec49f90305749c668df5101751bb8f95a" +checksum = "654e5643eff75d7f8c99197ce1440ed19a3474eada74c12bbac488b2cafdae27" dependencies = [ "prettyplease", "proc-macro2", @@ -10237,7 +12023,7 @@ dependencies = [ "quote", "syn 2.0.117", "tempfile", - "tonic-build 0.14.5", + "tonic-build 0.14.6", ] [[package]] @@ -10281,9 +12067,9 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.8" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" dependencies = [ "async-compression", "bitflags 2.11.1", @@ -10293,13 +12079,13 @@ dependencies = [ "http 1.4.0", "http-body 1.0.1", "http-body-util", - "iri-string", "pin-project-lite", "tokio", "tokio-util", "tower 0.5.3", "tower-layer", "tower-service", + "url", ] [[package]] @@ -10675,9 +12461,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.120" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df52b6d9b87e0c74c9edfa1eb2d9bf85e5d63515474513aa50fa181b3c4f5db1" +checksum = "49ace1d07c165b0864824eee619580c4689389afa9dc9ed3a4c75040d82e6790" dependencies = [ "cfg-if", "once_cell", @@ -10688,9 +12474,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.70" +version = "0.4.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af934872acec734c2d80e6617bbb5ff4f12b052dd8e6332b0817bce889516084" +checksum = "96492d0d3ffba25305a7dc88720d250b1401d7edca02cc3bcd50633b424673b8" dependencies = [ "js-sys", "wasm-bindgen", @@ -10698,9 +12484,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.120" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b1041f495fb322e64aca85f5756b2172e35cd459376e67f2a6c9dffcedb103" +checksum = "8e68e6f4afd367a562002c05637acb8578ff2dea1943df76afb9e83d177c8578" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -10708,9 +12494,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.120" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dcd0ff20416988a18ac686d4d4d0f6aae9ebf08a389ff5d29012b05af2a1b41" +checksum = "d95a9ec35c64b2a7cb35d3fead40c4238d0940c86d107136999567a4703259f2" dependencies = [ "bumpalo", "proc-macro2", @@ -10721,9 +12507,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.120" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49757b3c82ebf16c57d69365a142940b384176c24df52a087fb748e2085359ea" +checksum = "c4e0100b01e9f0d03189a92b96772a1fb998639d981193d7dbab487302513441" dependencies = [ "unicode-ident", ] @@ -10750,6 +12536,19 @@ dependencies = [ "wasmparser", ] +[[package]] +name = "wasm-streams" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1ec4f6517c9e11ae630e200b2b65d193279042e28edd4a2cda233e46670bbb" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "wasmparser" version = "0.244.0" @@ -10764,9 +12563,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.97" +version = "0.3.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eadbac71025cd7b0834f20d1fe8472e8495821b4e9801eb0a60bd1f19827602" +checksum = "4b572dff8bcf38bad0fa19729c89bb5748b2b9b1d8be70cf90df697e3a8f32aa" dependencies = [ "js-sys", "wasm-bindgen", @@ -10782,6 +12581,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki-root-certs" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31141ce3fc3e300ae89b78c0dd67f9708061d1d2eda54b8209346fd6be9a92c" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "webpki-roots" version = "0.25.4" @@ -10828,7 +12636,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.61.2", ] [[package]] @@ -10839,9 +12647,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "wincode" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4c754f1fc41250f2f742a27ba0fcc9f73df1dec23f6878490770855d43c322d" +checksum = "37095eb18dd6254c66217edc61a29d83d51f8818de8a2ffe88e4584ad73fb5f9" dependencies = [ "pastey", "proc-macro2", @@ -10852,9 +12660,9 @@ dependencies = [ [[package]] name = "wincode-derive" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e070787599c7c067b89598cd3eda440cca1b69eda9e0ff7c725fc8679ce9eb4" +checksum = "e262d55d1261f31e2cfe49cc6385a421d14d99faa0526bbe3cc1bda0d3005c62" dependencies = [ "darling 0.21.3", "proc-macro2", @@ -11225,9 +13033,9 @@ dependencies = [ [[package]] name = "winnow" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ee1708bef14716a11bae175f579062d4554d95be2c6829f518df847b7b3fdd0" +checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" dependencies = [ "memchr", ] @@ -11412,9 +13220,9 @@ dependencies = [ [[package]] name = "zerofrom" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" dependencies = [ "zerofrom-derive", ] diff --git a/Cargo.toml b/Cargo.toml index 1490d7600..fb3b06c2d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,8 @@ split-debuginfo = "packed" [workspace] members = [ + "compressed-delegation-api", + "compressed-delegation-client", "magicblock-account-cloner", "magicblock-accounts", "magicblock-accounts-db", @@ -34,7 +36,7 @@ members = [ "tools/genx", "tools/keypair-base58", "tools/ledger-stats", - "tools/magicblock-tui-client" + "tools/magicblock-tui-client", ] # This prevents a Travis CI error when building for Windows. @@ -62,11 +64,14 @@ base64 = "0.21.7" bincode = "1.3.3" blake3 = "1.8" borsh = { version = "1.5.1", features = ["derive", "unstable__schema"] } +borsh10 = { package = "borsh", version = "0.10.4" } bs58 = "0.5.1" byteorder = "1.5.0" bytes = { version = "1.0", features = ["serde"] } chrono = "0.4" clap = "4.5.40" +compressed-delegation-api = { path = "./compressed-delegation-api" } +compressed-delegation-client = { path = "./compressed-delegation-client" } console-subscriber = "0.5.0" derive_more = "2.0" ed25519-dalek = "1.0.1" @@ -91,6 +96,11 @@ json = { package = "sonic-rs", version = "0.5.3" } lazy_static = "1.4.0" libc = "0.2.153" libloading = "0.8" +light-client = "0.23" +light-compressed-account = "0.11" +light-hasher = "5" +light-sdk = "0.23" +light-sdk-types = "0.23" # Only used in magicblock-ledger for solana_metrics::datapoint_info! log = { version = "0.4.20" } lru = "0.16.0" @@ -101,9 +111,11 @@ magicblock-accounts-db = { path = "./magicblock-accounts-db" } magicblock-aml = { path = "./magicblock-aml" } magicblock-aperture = { path = "./magicblock-aperture" } magicblock-api = { path = "./magicblock-api" } -magicblock-chainlink = { path = "./magicblock-chainlink", features = ["dev-context"] } +magicblock-chainlink = { path = "./magicblock-chainlink", features = [ + "dev-context", +] } magicblock-committor-program = { path = "./magicblock-committor-program", features = [ - "no-entrypoint" + "no-entrypoint", ] } magicblock-committor-service = { path = "./magicblock-committor-service" } magicblock-config = { path = "./magicblock-config" } @@ -139,6 +151,10 @@ reqwest = "0.12" rusqlite = { version = "0.37.0", features = ["bundled"] } rustc-hash = "2.1" rustc_version = "0.4" +rustls = { version = "0.23", default-features = false, features = [ + "aws_lc_rs", + "std", +] } scc = "2.4" semver = "1.0.22" serde = "1.0.217" @@ -158,6 +174,7 @@ solana-commitment-config = { version = "3.1" } solana-compute-budget = { version = "=3.1.12" } solana-compute-budget-interface = { version = "3.0" } solana-compute-budget-program = { version = "=3.1.12" } +solana-cpi = { version = "3.1" } solana-feature-gate-interface = { version = "3.1" } solana-feature-set = { package = "agave-feature-set", version = "=3.1.12" } solana-fee-calculator = { version = "3.1" } @@ -177,6 +194,7 @@ solana-metrics = { version = "2.3.13" } solana-native-token = { version = "3.0" } solana-precompile-error = "3.0" solana-program = "3.0" +solana-program-error = { version = "3.0" } solana-program-option = { version = "3.0" } solana-program-pack = { version = "3.0" } solana-program-runtime = { git = "https://github.com/magicblock-labs/magicblock-svm.git", rev = "5bd1d56" } @@ -221,7 +239,10 @@ tonic-prost-build = "0.14" tracing = "0.1" tracing-log = { version = "0.2", features = ["log-tracer"] } tracing-subscriber = { version = "0.3", features = ["env-filter", "fmt"] } -twox-hash = { version = "2.1", default-features = false, features = ["alloc", "xxhash3_64"] } +twox-hash = { version = "2.1", default-features = false, features = [ + "alloc", + "xxhash3_64", +] } url = "2.5.0" # SPL Token crates used across the workspace diff --git a/compressed-delegation-api/Cargo.toml b/compressed-delegation-api/Cargo.toml new file mode 100644 index 000000000..a9117fe01 --- /dev/null +++ b/compressed-delegation-api/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "compressed-delegation-api" +version.workspace = true +authors.workspace = true +repository.workspace = true +homepage.workspace = true +license.workspace = true +edition.workspace = true + +[dependencies] +borsh = { workspace = true, features = ["derive"] } +light-compressed-account = { workspace = true } +light-hasher = { workspace = true, features = ["solana"] } +light-sdk = { workspace = true, features = ["v2"] } +solana-pubkey = { workspace = true, features = ["borsh"] } diff --git a/compressed-delegation-api/src/instruction.rs b/compressed-delegation-api/src/instruction.rs new file mode 100644 index 000000000..9e95a8fbf --- /dev/null +++ b/compressed-delegation-api/src/instruction.rs @@ -0,0 +1,336 @@ +use std::io::{Read, Write}; + +use borsh::{BorshDeserialize, BorshSerialize}; +use light_sdk::instruction::{ + account_meta::CompressedAccountMeta, CompressedProof, + PackedAddressTreeInfo, PackedStateTreeInfo, ValidityProof, +}; +use solana_pubkey::Pubkey; + +use crate::state::CompressedDelegationRecord; + +/// Instruction discriminators for the compressed delegation program (`u64`). +#[repr(u64)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum CompressedDelegationInstructionDiscriminator { + InitDelegationRecord = 0, + Delegate = 1, + CommitAndFinalize = 2, + Undelegate = 3, +} + +impl TryFrom for CompressedDelegationInstructionDiscriminator { + type Error = std::io::Error; + fn try_from(value: u64) -> Result { + match value { + 0 => Ok(Self::InitDelegationRecord), + 1 => Ok(Self::Delegate), + 2 => Ok(Self::CommitAndFinalize), + 3 => Ok(Self::Undelegate), + _ => Err(std::io::Error::new( + std::io::ErrorKind::InvalidData, + "Invalid CompressedDelegationInstructionDiscriminator value", + )), + } + } +} + +#[derive(Clone, Debug)] +pub enum CompressedDelegationProgramInstruction { + /// Initialize a new delegation record. + InitDelegationRecord { args: InitDelegationRecordArgs }, + + /// Delegate the compressed account to a validator. + Delegate { args: DelegateArgs }, + + /// Commit the compressed account. + CommitAndFinalize { args: CommitAndFinalizeArgs }, + + /// Undelegate the compressed account. + Undelegate { args: UndelegateArgs }, +} + +impl CompressedDelegationProgramInstruction { + /// Discriminator for this instruction (first `u64` in serialized form). + pub fn discriminator( + &self, + ) -> CompressedDelegationInstructionDiscriminator { + match self { + Self::InitDelegationRecord { .. } => { + CompressedDelegationInstructionDiscriminator::InitDelegationRecord + } + Self::Delegate { .. } => CompressedDelegationInstructionDiscriminator::Delegate, + Self::CommitAndFinalize { .. } => CompressedDelegationInstructionDiscriminator::CommitAndFinalize, + Self::Undelegate { .. } => CompressedDelegationInstructionDiscriminator::Undelegate, + } + } +} + +impl BorshSerialize for CompressedDelegationProgramInstruction { + fn serialize(&self, writer: &mut W) -> std::io::Result<()> { + (self.discriminator() as u64).serialize(writer)?; + match self { + Self::InitDelegationRecord { args } => args.serialize(writer), + Self::Delegate { args } => args.serialize(writer), + Self::CommitAndFinalize { args } => args.serialize(writer), + Self::Undelegate { args } => args.serialize(writer), + } + } +} + +impl BorshDeserialize for CompressedDelegationProgramInstruction { + fn deserialize_reader(reader: &mut R) -> std::io::Result { + let raw = u64::deserialize_reader(reader)?; + let disc = CompressedDelegationInstructionDiscriminator::try_from(raw)?; + Ok(match disc { + CompressedDelegationInstructionDiscriminator::InitDelegationRecord => { + Self::InitDelegationRecord { + args: InitDelegationRecordArgs::deserialize_reader(reader)?, + } + } + CompressedDelegationInstructionDiscriminator::Delegate => Self::Delegate { + args: DelegateArgs::deserialize_reader(reader)?, + }, + CompressedDelegationInstructionDiscriminator::CommitAndFinalize => Self::CommitAndFinalize { + args: CommitAndFinalizeArgs::deserialize_reader(reader)?, + }, + CompressedDelegationInstructionDiscriminator::Undelegate => Self::Undelegate { + args: UndelegateArgs::deserialize_reader(reader)?, + }, + }) + } +} + +#[repr(C)] +#[derive( + BorshSerialize, BorshDeserialize, Clone, Default, Debug, PartialEq, +)] +pub struct InitDelegationRecordArgs { + /// The proof of the account data + pub validity_proof: CdpValidityProof, + /// Address tree info + pub address_tree_info: CdpPackedAddressTreeInfo, + /// Output state tree index + pub output_state_tree_index: u8, + /// Owner program id + pub owner_program_id: Pubkey, + /// PDA seeds + pub pda_seeds: Vec>, + /// Bump + pub bump: u8, +} + +#[repr(C)] +#[derive( + BorshSerialize, BorshDeserialize, Clone, Default, Debug, PartialEq, +)] +pub struct DelegateArgs { + /// The proof of the account data + pub validity_proof: CdpValidityProof, + /// Account meta + pub account_meta: CdpCompressedAccountMeta, + /// Owner program id + pub owner_program_id: Pubkey, + /// Validator + pub validator: Pubkey, + /// Bump + pub bump: u8, + /// Account data before delegation + pub account_data: Vec, + /// PDA seeds + pub pda_seeds: Vec>, +} + +#[repr(C)] +#[derive( + BorshSerialize, BorshDeserialize, Clone, Default, Debug, PartialEq, +)] +pub struct CommitAndFinalizeArgs { + /// The current data of the compressed delegated account + pub current_compressed_delegated_account_data: Vec, + /// The new state of the compressed delegated account data + pub new_data: Vec, + /// Compressed account meta + pub account_meta: CdpCompressedAccountMeta, + /// Validity proof + pub validity_proof: CdpValidityProof, + /// Update nonce + pub update_nonce: u64, + /// Allow undelegation + pub allow_undelegation: bool, +} + +#[derive( + BorshSerialize, BorshDeserialize, Clone, Default, Debug, PartialEq, +)] +pub struct UndelegateArgs { + /// The proof of the account data + pub validity_proof: CdpValidityProof, + /// Delegation record account meta + pub delegation_record_account_meta: CdpCompressedAccountMeta, + /// Compressed delegated record + pub compressed_delegated_record: CompressedDelegationRecord, +} + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, PartialEq)] +pub struct ExternalUndelegateArgs { + /// The delegation record + pub delegation_record: CompressedDelegationRecord, +} + +// ------------------------------------------------------------------------------------------------ +// Reimplementations of the types from light-sdk for borsh compatibility +// ------------------------------------------------------------------------------------------------ + +/// Reimplements [ValidityProof] compatible with borsh 1. +/// It is a wrapper around a [CompressedProof] [Option] that is compatible with borsh 1. +#[derive( + BorshSerialize, BorshDeserialize, Clone, Copy, Debug, Default, PartialEq, +)] +pub struct CdpValidityProof(pub Option); + +#[derive(BorshSerialize, BorshDeserialize, Clone, Copy, Debug, PartialEq)] +pub struct CdpCompressedProof { + pub a: [u8; 32], + pub b: [u8; 64], + pub c: [u8; 32], +} + +impl From for CompressedProof { + fn from(cp: CdpCompressedProof) -> Self { + Self { + a: cp.a, + b: cp.b, + c: cp.c, + } + } +} + +impl From for CdpCompressedProof { + fn from(cp: CompressedProof) -> Self { + Self { + a: cp.a, + b: cp.b, + c: cp.c, + } + } +} + +impl TryFrom for ValidityProof { + type Error = light_compressed_account::CompressedAccountError; + fn try_from( + cdp_validity_proof: CdpValidityProof, + ) -> Result { + let Some(proof) = cdp_validity_proof.0 else { + return Ok(Self(None)); + }; + let proof = CompressedProof::from(proof); + Ok(Self(Some(proof))) + } +} + +impl From for CdpValidityProof { + fn from(vp: ValidityProof) -> Self { + Self(vp.0.map(CdpCompressedProof::from)) + } +} + +/// Reimplements [CompressedAccountMeta] compatible with borsh 1. +/// It is a wrapper around a [CompressedAccountMeta] that is compatible with borsh 1. +#[derive( + BorshSerialize, BorshDeserialize, Clone, Copy, Debug, PartialEq, Default, +)] +pub struct CdpCompressedAccountMeta { + pub tree_info: CdpPackedStateTreeInfo, + pub address: [u8; 32], + pub output_state_tree_index: u8, +} + +impl From for CdpCompressedAccountMeta { + fn from(cam: CompressedAccountMeta) -> Self { + Self { + tree_info: cam.tree_info.into(), + address: cam.address, + output_state_tree_index: cam.output_state_tree_index, + } + } +} + +impl From for CompressedAccountMeta { + fn from(cam: CdpCompressedAccountMeta) -> Self { + Self { + tree_info: cam.tree_info.into(), + address: cam.address, + output_state_tree_index: cam.output_state_tree_index, + } + } +} + +#[derive( + BorshSerialize, BorshDeserialize, Clone, Copy, Debug, PartialEq, Default, +)] +pub struct CdpPackedStateTreeInfo { + pub root_index: u16, + pub prove_by_index: bool, + pub merkle_tree_pubkey_index: u8, + pub queue_pubkey_index: u8, + pub leaf_index: u32, +} + +impl From for CdpPackedStateTreeInfo { + fn from(psti: PackedStateTreeInfo) -> Self { + Self { + root_index: psti.root_index, + prove_by_index: psti.prove_by_index, + merkle_tree_pubkey_index: psti.merkle_tree_pubkey_index, + queue_pubkey_index: psti.queue_pubkey_index, + leaf_index: psti.leaf_index, + } + } +} + +impl From for PackedStateTreeInfo { + fn from(psti: CdpPackedStateTreeInfo) -> Self { + Self { + root_index: psti.root_index, + prove_by_index: psti.prove_by_index, + merkle_tree_pubkey_index: psti.merkle_tree_pubkey_index, + queue_pubkey_index: psti.queue_pubkey_index, + leaf_index: psti.leaf_index, + } + } +} + +/// Reimplements [PackedAddressTreeInfo] compatible with borsh 1. +/// It is a wrapper around a [PackedAddressTreeInfo] that is compatible with borsh 1. +#[derive( + BorshSerialize, BorshDeserialize, Clone, Copy, Debug, Default, PartialEq, +)] +pub struct CdpPackedAddressTreeInfo { + pub address_merkle_tree_pubkey_index: u8, + pub address_queue_pubkey_index: u8, + pub root_index: u16, +} + +impl From for CdpPackedAddressTreeInfo { + fn from(pati: PackedAddressTreeInfo) -> Self { + Self { + address_merkle_tree_pubkey_index: pati + .address_merkle_tree_pubkey_index, + address_queue_pubkey_index: pati.address_queue_pubkey_index, + root_index: pati.root_index, + } + } +} + +impl From for PackedAddressTreeInfo { + fn from(cdp_packed_address_tree_info: CdpPackedAddressTreeInfo) -> Self { + Self { + address_merkle_tree_pubkey_index: cdp_packed_address_tree_info + .address_merkle_tree_pubkey_index, + address_queue_pubkey_index: cdp_packed_address_tree_info + .address_queue_pubkey_index, + root_index: cdp_packed_address_tree_info.root_index, + } + } +} diff --git a/compressed-delegation-api/src/lib.rs b/compressed-delegation-api/src/lib.rs new file mode 100644 index 000000000..eb128b81c --- /dev/null +++ b/compressed-delegation-api/src/lib.rs @@ -0,0 +1,22 @@ +//! Shared instruction layouts, discriminators, and account types for the +//! compressed delegation program. Used by the on-chain program and off-chain clients. + +pub mod instruction; +pub mod state; + +pub use instruction::{ + CommitAndFinalizeArgs, CompressedDelegationInstructionDiscriminator, + CompressedDelegationProgramInstruction, DelegateArgs, + ExternalUndelegateArgs, InitDelegationRecordArgs, UndelegateArgs, +}; +use solana_pubkey::declare_id; +pub use state::{CompressedDelegationRecord, DCP_DISCRIMINATOR}; + +/// Discriminator for CPI into owner programs for external undelegate. +pub const EXTERNAL_UNDELEGATE_DISCRIMINATOR_COMPRESSED: [u8; 8] = + [0xD, 0x23, 0xB0, 0x7C, 0x70, 0x68, 0xFE, 0x73]; + +pub const EXTERNAL_UNDELEGATE_DISCRIMINATOR_U64_COMPRESSED: u64 = + u64::from_le_bytes(EXTERNAL_UNDELEGATE_DISCRIMINATOR_COMPRESSED); + +declare_id!("DEL2rPzhFaS5qzo8XY9ZNxSzuunWueySq3p2dxJfwPbT"); diff --git a/compressed-delegation-api/src/state.rs b/compressed-delegation-api/src/state.rs new file mode 100644 index 000000000..292d8dd15 --- /dev/null +++ b/compressed-delegation-api/src/state.rs @@ -0,0 +1,51 @@ +use borsh::{BorshDeserialize, BorshSerialize}; +use light_hasher::{DataHasher, Hasher, HasherError, Sha256}; +use light_sdk::LightDiscriminator; +use solana_pubkey::Pubkey; + +pub const DCP_DISCRIMINATOR: [u8; 8] = + [0x4d, 0x41, 0x47, 0x49, 0x43, 0x42, 0x4c, 0x4b]; + +/// The Delegated Metadata includes Account Seeds, max delegation time, seeds +/// and other meta information about the delegated account. +/// * Everything necessary at cloning time is instead stored in the delegation record. +#[repr(C)] +#[derive( + BorshSerialize, BorshDeserialize, Clone, Debug, Default, PartialEq, +)] +pub struct CompressedDelegationRecord { + /// The PDA of the delegated account + pub pda: Pubkey, + /// The validator the account is delegated to + pub authority: Pubkey, + /// Last update nonce + pub last_update_nonce: u64, + /// Whether the account can be undelegated + pub is_undelegatable: bool, + /// The program that owns the delegated account + pub owner: Pubkey, + /// The slot at which the delegation was created + pub delegation_slot: u64, + /// Original lamports of the account + pub lamports: u64, + /// The original data of the delegated account + pub data: Vec, +} + +impl DataHasher for CompressedDelegationRecord { + fn hash(&self) -> Result<[u8; 32], HasherError> { + let bytes = borsh::to_vec(self).map_err(|_| HasherError::BorshError)?; + let mut hash = Sha256::hash(&bytes)?; + hash[0] = 0; + Ok(hash) + } +} + +impl LightDiscriminator for CompressedDelegationRecord { + const LIGHT_DISCRIMINATOR: [u8; 8] = DCP_DISCRIMINATOR; + const LIGHT_DISCRIMINATOR_SLICE: &'static [u8] = &Self::LIGHT_DISCRIMINATOR; + + fn discriminator() -> [u8; 8] { + Self::LIGHT_DISCRIMINATOR + } +} diff --git a/compressed-delegation-client/Cargo.toml b/compressed-delegation-client/Cargo.toml new file mode 100644 index 000000000..1b674c20f --- /dev/null +++ b/compressed-delegation-client/Cargo.toml @@ -0,0 +1,35 @@ +[package] +name = "compressed-delegation-client" +version.workspace = true +authors.workspace = true +repository.workspace = true +homepage.workspace = true +license.workspace = true +edition.workspace = true + +[lib] +crate-type = ["lib"] + +[features] +test-sbf = [] +serde = ["dep:serde", "dep:serde_with"] +anchor = [] +anchor-idl-build = [] +fetch = [] + +[dependencies] +compressed-delegation-api = { workspace = true } +borsh = { workspace = true } +light-hasher = { workspace = true } +light-sdk = { workspace = true, features = ["v2"] } +light-sdk-types = { workspace = true } +num-derive = { workspace = true } +num-traits = { workspace = true } +serde = { workspace = true, features = ["derive"], optional = true } +serde_with = { workspace = true, optional = true } +solana-account-info = { workspace = true } +solana-cpi = { workspace = true } +solana-program-error = { workspace = true } +solana-pubkey = { workspace = true } +solana-instruction = { workspace = true } +thiserror = { workspace = true } diff --git a/compressed-delegation-client/src/builders/commit_finalize.rs b/compressed-delegation-client/src/builders/commit_finalize.rs new file mode 100644 index 000000000..f18a2e2d2 --- /dev/null +++ b/compressed-delegation-client/src/builders/commit_finalize.rs @@ -0,0 +1,43 @@ +use solana_instruction::{AccountMeta, Instruction}; +use solana_program_error::ProgramError; +use solana_pubkey::Pubkey; + +use crate::{CommitAndFinalizeArgs, DelegationProgramDiscriminator}; + +/// Instruction builder for `CommitAndFinalize`. +/// +/// ### Accounts: +/// +/// 0. `[writable, signer]` validator +/// 1. `[]` delegated_account +#[derive(Clone, Debug, Default)] +pub struct CommitAndFinalizeBuilder { + pub validator: Pubkey, + pub delegated_account: Pubkey, + pub remaining_accounts: Vec, + pub args: CommitAndFinalizeArgs, +} + +impl CommitAndFinalizeBuilder { + pub fn instruction(&self) -> Result { + Ok(Instruction { + program_id: crate::COMPRESSED_DELEGATION_ID, + accounts: [ + &[ + AccountMeta::new(self.validator, true), + AccountMeta::new_readonly(self.delegated_account, false), + ], + self.remaining_accounts.as_slice(), + ] + .concat(), + data: [ + &(DelegationProgramDiscriminator::CommitAndFinalize as u64) + .to_le_bytes(), + borsh::to_vec(&self.args) + .map_err(|_| ProgramError::BorshIoError)? + .as_slice(), + ] + .concat(), + }) + } +} diff --git a/compressed-delegation-client/src/builders/delegate.rs b/compressed-delegation-client/src/builders/delegate.rs new file mode 100644 index 000000000..04bc954b0 --- /dev/null +++ b/compressed-delegation-client/src/builders/delegate.rs @@ -0,0 +1,43 @@ +use solana_instruction::{AccountMeta, Instruction}; +use solana_program_error::ProgramError; +use solana_pubkey::Pubkey; + +use crate::{DelegateArgs, DelegationProgramDiscriminator}; + +/// Instruction builder for `Delegate`. +/// +/// ### Accounts: +/// +/// 0. `[writable, signer]` payer +/// 1. `[signer]` delegated_account +#[derive(Clone, Debug, Default)] +pub struct DelegateBuilder { + pub payer: Pubkey, + pub delegated_account: Pubkey, + pub remaining_accounts: Vec, + pub args: DelegateArgs, +} + +impl DelegateBuilder { + pub fn instruction(&self) -> Result { + Ok(Instruction { + program_id: crate::COMPRESSED_DELEGATION_ID, + accounts: [ + &[ + AccountMeta::new(self.payer, true), + AccountMeta::new_readonly(self.delegated_account, true), + ], + self.remaining_accounts.as_slice(), + ] + .concat(), + data: [ + &(DelegationProgramDiscriminator::Delegate as u64) + .to_le_bytes(), + borsh::to_vec(&self.args) + .map_err(|_| ProgramError::BorshIoError)? + .as_slice(), + ] + .concat(), + }) + } +} diff --git a/compressed-delegation-client/src/builders/init_delegation_record.rs b/compressed-delegation-client/src/builders/init_delegation_record.rs new file mode 100644 index 000000000..8c9fb34bc --- /dev/null +++ b/compressed-delegation-client/src/builders/init_delegation_record.rs @@ -0,0 +1,43 @@ +use solana_instruction::{AccountMeta, Instruction}; +use solana_program_error::ProgramError; +use solana_pubkey::Pubkey; + +use crate::{DelegationProgramDiscriminator, InitDelegationRecordArgs}; + +/// Instruction builder for `InitDelegationRecord`. +/// +/// ### Accounts: +/// +/// 0. `[writable, signer]` payer +/// 1. `[signer]` delegated_account +#[derive(Clone, Debug)] +pub struct InitDelegationRecordBuilder { + pub payer: Pubkey, + pub delegated_account: Pubkey, + pub remaining_accounts: Vec, + pub args: InitDelegationRecordArgs, +} + +impl InitDelegationRecordBuilder { + pub fn instruction(&self) -> Result { + Ok(Instruction { + program_id: crate::COMPRESSED_DELEGATION_ID, + accounts: [ + &[ + AccountMeta::new(self.payer, true), + AccountMeta::new_readonly(self.delegated_account, true), + ], + self.remaining_accounts.as_slice(), + ] + .concat(), + data: [ + &(DelegationProgramDiscriminator::InitDelegationRecord as u64) + .to_le_bytes(), + borsh::to_vec(&self.args) + .map_err(|_| ProgramError::BorshIoError)? + .as_slice(), + ] + .concat(), + }) + } +} diff --git a/compressed-delegation-client/src/builders/mod.rs b/compressed-delegation-client/src/builders/mod.rs new file mode 100644 index 000000000..89accb2d0 --- /dev/null +++ b/compressed-delegation-client/src/builders/mod.rs @@ -0,0 +1,8 @@ +pub(crate) mod commit_finalize; +pub(crate) mod delegate; +pub(crate) mod init_delegation_record; +pub(crate) mod undelegate; + +pub use self::{ + commit_finalize::*, delegate::*, init_delegation_record::*, undelegate::*, +}; diff --git a/compressed-delegation-client/src/builders/undelegate.rs b/compressed-delegation-client/src/builders/undelegate.rs new file mode 100644 index 000000000..5d0734c37 --- /dev/null +++ b/compressed-delegation-client/src/builders/undelegate.rs @@ -0,0 +1,49 @@ +use solana_instruction::{AccountMeta, Instruction}; +use solana_program_error::ProgramError; +use solana_pubkey::Pubkey; + +use crate::{DelegationProgramDiscriminator, UndelegateArgs}; + +/// Instruction builder for `Undelegate`. +/// +/// ### Accounts: +/// +/// 0. `[writable, signer]` payer +/// 1. `[writable]` delegated_account +/// 2. `[]` owner_program +/// 3. `[]` system_program +#[derive(Clone, Debug, Default)] +pub struct UndelegateBuilder { + pub payer: Pubkey, + pub delegated_account: Pubkey, + pub owner_program: Pubkey, + pub system_program: Pubkey, + pub remaining_accounts: Vec, + pub args: UndelegateArgs, +} + +impl UndelegateBuilder { + pub fn instruction(&self) -> Result { + Ok(Instruction { + program_id: crate::COMPRESSED_DELEGATION_ID, + accounts: [ + &[ + AccountMeta::new(self.payer, true), + AccountMeta::new(self.delegated_account, false), + AccountMeta::new_readonly(self.owner_program, false), + AccountMeta::new_readonly(self.system_program, false), + ], + self.remaining_accounts.as_slice(), + ] + .concat(), + data: [ + &(DelegationProgramDiscriminator::Undelegate as u64) + .to_le_bytes(), + borsh::to_vec(&self.args) + .map_err(|_| ProgramError::BorshIoError)? + .as_slice(), + ] + .concat(), + }) + } +} diff --git a/compressed-delegation-client/src/cpi/commit_finalize.rs b/compressed-delegation-client/src/cpi/commit_finalize.rs new file mode 100644 index 000000000..51ebcfde7 --- /dev/null +++ b/compressed-delegation-client/src/cpi/commit_finalize.rs @@ -0,0 +1,43 @@ +use solana_account_info::AccountInfo; +use solana_cpi::invoke_signed; +use solana_program_error::ProgramResult; + +use crate::{ + cpi::helpers::{collect_account_infos, remaining_to_metas}, + CommitAndFinalizeArgs, +}; + +/// CPI helper for `CommitAndFinalize` (on-chain callers). +/// +/// ### Accounts: +/// +/// 0. `[writable, signer]` validator +/// 1. `[]` delegated_account +#[derive(Clone, Debug)] +pub struct CommitAndFinalizeCpi<'a> { + pub validator: AccountInfo<'a>, + pub delegated_account: AccountInfo<'a>, + pub remaining_accounts: Vec<(AccountInfo<'a>, bool, bool)>, + pub args: CommitAndFinalizeArgs, +} + +impl<'a> CommitAndFinalizeCpi<'a> { + pub fn invoke(&self) -> ProgramResult { + self.invoke_signed(&[]) + } + + pub fn invoke_signed(&self, signers: &[&[&[u8]]]) -> ProgramResult { + let ix = crate::builders::CommitAndFinalizeBuilder { + validator: *self.validator.key, + delegated_account: *self.delegated_account.key, + remaining_accounts: remaining_to_metas(&self.remaining_accounts), + args: self.args.clone(), + } + .instruction()?; + let infos = collect_account_infos( + &[self.validator.clone(), self.delegated_account.clone()], + &self.remaining_accounts, + ); + invoke_signed(&ix, &infos, signers) + } +} diff --git a/compressed-delegation-client/src/cpi/delegate.rs b/compressed-delegation-client/src/cpi/delegate.rs new file mode 100644 index 000000000..35dd91fb3 --- /dev/null +++ b/compressed-delegation-client/src/cpi/delegate.rs @@ -0,0 +1,43 @@ +use solana_account_info::AccountInfo; +use solana_cpi::invoke_signed; +use solana_program_error::ProgramResult; + +use crate::{ + cpi::helpers::{collect_account_infos, remaining_to_metas}, + DelegateArgs, +}; + +/// CPI helper for `Delegate` (on-chain callers). +/// +/// ### Accounts: +/// +/// 0. `[writable, signer]` payer +/// 1. `[signer]` delegated_account +#[derive(Clone, Debug)] +pub struct DelegateCpi<'a> { + pub payer: AccountInfo<'a>, + pub delegated_account: AccountInfo<'a>, + pub remaining_accounts: Vec<(AccountInfo<'a>, bool, bool)>, + pub args: DelegateArgs, +} + +impl<'a> DelegateCpi<'a> { + pub fn invoke(&self) -> ProgramResult { + self.invoke_signed(&[]) + } + + pub fn invoke_signed(&self, signers: &[&[&[u8]]]) -> ProgramResult { + let ix = crate::builders::DelegateBuilder { + payer: *self.payer.key, + delegated_account: *self.delegated_account.key, + remaining_accounts: remaining_to_metas(&self.remaining_accounts), + args: self.args.clone(), + } + .instruction()?; + let infos = collect_account_infos( + &[self.payer.clone(), self.delegated_account.clone()], + &self.remaining_accounts, + ); + invoke_signed(&ix, &infos, signers) + } +} diff --git a/compressed-delegation-client/src/cpi/helpers.rs b/compressed-delegation-client/src/cpi/helpers.rs new file mode 100644 index 000000000..88545e74b --- /dev/null +++ b/compressed-delegation-client/src/cpi/helpers.rs @@ -0,0 +1,24 @@ +use solana_account_info::AccountInfo; +use solana_instruction::AccountMeta; + +pub(crate) fn remaining_to_metas<'a>( + remaining: &[(AccountInfo<'a>, bool, bool)], +) -> Vec { + remaining + .iter() + .map(|(ai, is_signer, is_writable)| AccountMeta { + pubkey: *ai.key, + is_signer: *is_signer, + is_writable: *is_writable, + }) + .collect() +} + +pub(crate) fn collect_account_infos<'a>( + prefix: &[AccountInfo<'a>], + remaining: &[(AccountInfo<'a>, bool, bool)], +) -> Vec> { + let mut out = prefix.to_vec(); + out.extend(remaining.iter().map(|(ai, _, _)| ai.clone())); + out +} diff --git a/compressed-delegation-client/src/cpi/init_delegation_record.rs b/compressed-delegation-client/src/cpi/init_delegation_record.rs new file mode 100644 index 000000000..bdc5f27ba --- /dev/null +++ b/compressed-delegation-client/src/cpi/init_delegation_record.rs @@ -0,0 +1,43 @@ +use solana_account_info::AccountInfo; +use solana_cpi::invoke_signed; +use solana_program_error::ProgramResult; + +use crate::{ + cpi::helpers::{collect_account_infos, remaining_to_metas}, + InitDelegationRecordArgs, +}; + +/// CPI helper for `InitDelegationRecord` (on-chain callers). +/// +/// ### Accounts: +/// +/// 0. `[writable, signer]` payer +/// 1. `[signer]` delegated_account +#[derive(Clone, Debug)] +pub struct InitDelegationRecordCpi<'a> { + pub payer: AccountInfo<'a>, + pub delegated_account: AccountInfo<'a>, + pub remaining_accounts: Vec<(AccountInfo<'a>, bool, bool)>, + pub args: InitDelegationRecordArgs, +} + +impl<'a> InitDelegationRecordCpi<'a> { + pub fn invoke(&self) -> ProgramResult { + self.invoke_signed(&[]) + } + + pub fn invoke_signed(&self, signers: &[&[&[u8]]]) -> ProgramResult { + let ix = crate::builders::InitDelegationRecordBuilder { + payer: *self.payer.key, + delegated_account: *self.delegated_account.key, + remaining_accounts: remaining_to_metas(&self.remaining_accounts), + args: self.args.clone(), + } + .instruction()?; + let infos = collect_account_infos( + &[self.payer.clone(), self.delegated_account.clone()], + &self.remaining_accounts, + ); + invoke_signed(&ix, &infos, signers) + } +} diff --git a/compressed-delegation-client/src/cpi/mod.rs b/compressed-delegation-client/src/cpi/mod.rs new file mode 100644 index 000000000..d3b89833b --- /dev/null +++ b/compressed-delegation-client/src/cpi/mod.rs @@ -0,0 +1,10 @@ +mod helpers; + +pub(crate) mod commit_finalize; +pub(crate) mod delegate; +pub(crate) mod init_delegation_record; +pub(crate) mod undelegate; + +pub use self::{ + commit_finalize::*, delegate::*, init_delegation_record::*, undelegate::*, +}; diff --git a/compressed-delegation-client/src/cpi/undelegate.rs b/compressed-delegation-client/src/cpi/undelegate.rs new file mode 100644 index 000000000..2fc5a332f --- /dev/null +++ b/compressed-delegation-client/src/cpi/undelegate.rs @@ -0,0 +1,54 @@ +use solana_account_info::AccountInfo; +use solana_cpi::invoke_signed; +use solana_program_error::ProgramResult; + +use crate::{ + cpi::helpers::{collect_account_infos, remaining_to_metas}, + UndelegateArgs, +}; + +/// CPI helper for `Undelegate` (on-chain callers). +/// +/// ### Accounts: +/// +/// 0. `[writable, signer]` payer +/// 1. `[writable]` delegated_account +/// 2. `[]` owner_program +/// 3. `[]` system_program +#[derive(Clone, Debug)] +pub struct UndelegateCpi<'a> { + pub payer: AccountInfo<'a>, + pub delegated_account: AccountInfo<'a>, + pub owner_program: AccountInfo<'a>, + pub system_program: AccountInfo<'a>, + pub remaining_accounts: Vec<(AccountInfo<'a>, bool, bool)>, + pub args: UndelegateArgs, +} + +impl<'a> UndelegateCpi<'a> { + pub fn invoke(&self) -> ProgramResult { + self.invoke_signed(&[]) + } + + pub fn invoke_signed(&self, signers: &[&[&[u8]]]) -> ProgramResult { + let ix = crate::builders::UndelegateBuilder { + payer: *self.payer.key, + delegated_account: *self.delegated_account.key, + owner_program: *self.owner_program.key, + system_program: *self.system_program.key, + remaining_accounts: remaining_to_metas(&self.remaining_accounts), + args: self.args.clone(), + } + .instruction()?; + let infos = collect_account_infos( + &[ + self.payer.clone(), + self.delegated_account.clone(), + self.owner_program.clone(), + self.system_program.clone(), + ], + &self.remaining_accounts, + ); + invoke_signed(&ix, &infos, signers) + } +} diff --git a/compressed-delegation-client/src/lib.rs b/compressed-delegation-client/src/lib.rs new file mode 100644 index 000000000..091b37362 --- /dev/null +++ b/compressed-delegation-client/src/lib.rs @@ -0,0 +1,27 @@ +pub mod builders; +pub mod cpi; +mod programs; + +pub use compressed_delegation_api::{ + CommitAndFinalizeArgs, CompressedDelegationInstructionDiscriminator, + CompressedDelegationProgramInstruction, CompressedDelegationRecord, + DelegateArgs, ExternalUndelegateArgs, InitDelegationRecordArgs, + UndelegateArgs, DCP_DISCRIMINATOR, + EXTERNAL_UNDELEGATE_DISCRIMINATOR_COMPRESSED, + EXTERNAL_UNDELEGATE_DISCRIMINATOR_U64_COMPRESSED, +}; +use light_sdk::derive_light_cpi_signer; +use light_sdk_types::CpiSigner; +pub use programs::{COMPRESSED_DELEGATION_ID, COMPRESSED_DELEGATION_ID as ID}; +use solana_pubkey::Pubkey; + +/// Backwards-compatible name for [`CompressedDelegationInstructionDiscriminator`]. +pub type DelegationProgramDiscriminator = + CompressedDelegationInstructionDiscriminator; + +pub const COMPRESSED_DELEGATION_CPI_SIGNER: CpiSigner = + derive_light_cpi_signer!("DEL2rPzhFaS5qzo8XY9ZNxSzuunWueySq3p2dxJfwPbT"); + +pub const fn id() -> Pubkey { + ID +} diff --git a/compressed-delegation-client/src/programs.rs b/compressed-delegation-client/src/programs.rs new file mode 100644 index 000000000..f68e7d375 --- /dev/null +++ b/compressed-delegation-client/src/programs.rs @@ -0,0 +1,7 @@ +//! Program IDs for on-chain programs in this workspace. + +use solana_pubkey::{pubkey, Pubkey}; + +/// `compressed_delegation` program ID. +pub const COMPRESSED_DELEGATION_ID: Pubkey = + pubkey!("DEL2rPzhFaS5qzo8XY9ZNxSzuunWueySq3p2dxJfwPbT"); diff --git a/config.example.toml b/config.example.toml index 01d711499..d7873bc9c 100644 --- a/config.example.toml +++ b/config.example.toml @@ -340,6 +340,15 @@ failed-task-retention = "14d" # Env: MBV_TASK_SCHEDULER__FAILED_TASK_CLEANUP_INTERVAL failed-task-cleanup-interval = "1h" +# ============================================================================== +# Compression +# ============================================================================== +[compression] +# The URL of the Photon indexer. +# Default: http://localhost:8784 +# Env: MBV_COMPRESSION__PHOTON_URL +photon-url = "http://localhost:8784" + # ============================================================================== # Pre-loaded Programs # ============================================================================== diff --git a/magicblock-account-cloner/src/lib.rs b/magicblock-account-cloner/src/lib.rs index 1adb4b4aa..e7b12eb03 100644 --- a/magicblock-account-cloner/src/lib.rs +++ b/magicblock-account-cloner/src/lib.rs @@ -222,6 +222,7 @@ impl ChainlinkCloner { executable: request.account.executable(), delegated: request.account.delegated(), confined: request.account.confined(), + compressed: request.account.compressed(), remote_slot: request.account.remote_slot(), } } diff --git a/magicblock-accounts/src/scheduled_commits_processor.rs b/magicblock-accounts/src/scheduled_commits_processor.rs index 820bf1fab..f09a0260f 100644 --- a/magicblock-accounts/src/scheduled_commits_processor.rs +++ b/magicblock-accounts/src/scheduled_commits_processor.rs @@ -10,6 +10,7 @@ use magicblock_chainlink::{ remote_account_provider::{ chain_rpc_client::ChainRpcClientImpl, chain_updates_client::ChainUpdatesClient, + photon_client::PhotonClientImpl, }, submux::SubMuxClient, Chainlink, @@ -48,6 +49,7 @@ pub type ChainlinkImpl = Chainlink< SubMuxClient, AccountsDb, ChainlinkCloner, + PhotonClientImpl, >; pub struct ScheduledCommitsProcessorImpl { diff --git a/magicblock-aperture/src/state/mod.rs b/magicblock-aperture/src/state/mod.rs index e74e76ba9..3239e787d 100644 --- a/magicblock-aperture/src/state/mod.rs +++ b/magicblock-aperture/src/state/mod.rs @@ -8,6 +8,7 @@ use magicblock_chainlink::{ remote_account_provider::{ chain_rpc_client::ChainRpcClientImpl, chain_updates_client::ChainUpdatesClient, + photon_client::PhotonClientImpl, }, submux::SubMuxClient, Chainlink, @@ -23,6 +24,7 @@ pub type ChainlinkImpl = Chainlink< SubMuxClient, AccountsDb, ChainlinkCloner, + PhotonClientImpl, >; /// A container for the shared, global state of the RPC service. diff --git a/magicblock-api/Cargo.toml b/magicblock-api/Cargo.toml index cdef84a27..43a7f7817 100644 --- a/magicblock-api/Cargo.toml +++ b/magicblock-api/Cargo.toml @@ -33,6 +33,7 @@ magicblock-replicator = { workspace = true } magicblock-task-scheduler = { workspace = true } magicblock-validator-admin = { workspace = true } +light-client = { workspace = true, features = ["v2"] } num_cpus = { workspace = true } paste = { workspace = true } solana-account = { workspace = true } diff --git a/magicblock-api/src/magic_sys_adapter.rs b/magicblock-api/src/magic_sys_adapter.rs index 1e13b44a7..493cfe27b 100644 --- a/magicblock-api/src/magic_sys_adapter.rs +++ b/magicblock-api/src/magic_sys_adapter.rs @@ -10,6 +10,7 @@ use tracing::error; #[derive(Clone)] pub struct MagicSysAdapter { committor_service: Option>, + is_compression_enabled: bool, } impl MagicSysAdapter { @@ -24,8 +25,14 @@ impl MagicSysAdapter { const FETCH_TIMEOUT: Duration = Duration::from_secs(30); - pub fn new(committor_service: Option>) -> Self { - Self { committor_service } + pub fn new( + committor_service: Option>, + is_compression_enabled: bool, + ) -> Self { + Self { + committor_service, + is_compression_enabled, + } } } @@ -33,6 +40,7 @@ impl MagicSys for MagicSysAdapter { fn fetch_current_commit_nonces( &self, commits: &[CommittedAccount], + compressed: bool, ) -> Result, InstructionError> { if commits.is_empty() { return Ok(HashMap::new()); @@ -53,8 +61,11 @@ impl MagicSys for MagicSysAdapter { commits.iter().map(|account| account.pubkey).collect(); let _timer = metrics::start_fetch_commit_nonces_wait_timer(); - let receiver = committor_service - .fetch_current_commit_nonces_sync(&pubkeys, min_context_slot); + let receiver = committor_service.fetch_current_commit_nonces_sync( + &pubkeys, + compressed, + min_context_slot, + ); receiver .recv_timeout(Self::FETCH_TIMEOUT) .map_err(|err| match err { @@ -72,4 +83,8 @@ impl MagicSys for MagicSysAdapter { }) .map_err(|_| InstructionError::Custom(Self::FETCH_ERR)) } + + fn is_compression_enabled(&self) -> bool { + self.is_compression_enabled + } } diff --git a/magicblock-api/src/magic_validator.rs b/magicblock-api/src/magic_validator.rs index 0fc23e8fe..a99b65b68 100644 --- a/magicblock-api/src/magic_validator.rs +++ b/magicblock-api/src/magic_validator.rs @@ -22,7 +22,8 @@ use magicblock_chainlink::{ config::ChainlinkConfig, remote_account_provider::{ chain_rpc_client::ChainRpcClientImpl, - chain_updates_client::ChainUpdatesClient, Endpoints, + chain_updates_client::ChainUpdatesClient, + photon_client::PhotonClientImpl, Endpoint, Endpoints, }, submux::SubMuxClient, Chainlink, @@ -105,6 +106,7 @@ type ChainlinkImpl = Chainlink< SubMuxClient, AccountsDb, ChainlinkCloner, + PhotonClientImpl, >; // ----------------- @@ -224,9 +226,14 @@ impl MagicValidator { let committor_service = Self::init_committor_service(&config, ledger.latest_block()) .await?; + let is_compression_enabled = config + .compression + .as_ref() + .is_some_and(|compression| compression.photon_url.is_some()); log_timing("startup", "committor_service_init", step_start); init_magic_sys(Arc::new(MagicSysAdapter::new( committor_service.clone(), + is_compression_enabled, ))); let step_start = Instant::now(); @@ -466,6 +473,10 @@ impl MagicValidator { committor_persist_path, ChainConfig { rpc_uri: config.rpc_url().to_owned(), + photon_uri: config + .compression + .as_ref() + .and_then(|compression| compression.photon_url.clone()), commitment: CommitmentConfig::confirmed(), compute_budget_config: ComputeBudgetConfig::new( config.commit.compute_unit_price, @@ -486,13 +497,24 @@ impl MagicValidator { latest_block: &LatestBlock, accountsdb: &Arc, ) -> ApiResult { - let endpoints = Endpoints::try_from(config.remotes.as_slice()) + let mut endpoints = Endpoints::try_from(config.remotes.as_slice()) .map_err(|e| { ApiError::from( magicblock_chainlink::errors::ChainlinkError::from(e), ) })?; + if let Some(photon_url) = config + .compression + .as_ref() + .and_then(|compression| compression.photon_url.clone()) + { + endpoints.push(Endpoint::Compression { + label: "photon".to_string(), + url: photon_url, + }); + } + let cloner = ChainlinkCloner::new( transaction_scheduler.clone(), latest_block.clone(), diff --git a/magicblock-chainlink/Cargo.toml b/magicblock-chainlink/Cargo.toml index 29f664fcf..6abb7b9ff 100644 --- a/magicblock-chainlink/Cargo.toml +++ b/magicblock-chainlink/Cargo.toml @@ -8,9 +8,11 @@ arc-swap = "1.7" async-trait = { workspace = true } bincode = { workspace = true } borsh = { workspace = true } +compressed-delegation-client = { workspace = true } futures-util = { workspace = true } helius-laserstream = { workspace = true } lru = { workspace = true } +light-client = { workspace = true } magicblock-accounts-db = { workspace = true } magicblock-aml = { workspace = true } magicblock-config = { workspace = true } @@ -19,6 +21,7 @@ magicblock-delegation-program-api = { workspace = true } magicblock-magic-program-api = { workspace = true } magicblock-metrics = { workspace = true } parking_lot = { workspace = true } +rustls = { workspace = true } scc = { workspace = true } solana-account = { workspace = true } solana-account-decoder = { workspace = true } diff --git a/magicblock-chainlink/src/chainlink/account_still_undelegating_on_chain.rs b/magicblock-chainlink/src/chainlink/account_still_undelegating_on_chain.rs index 1f4d135ec..cd3b99c12 100644 --- a/magicblock-chainlink/src/chainlink/account_still_undelegating_on_chain.rs +++ b/magicblock-chainlink/src/chainlink/account_still_undelegating_on_chain.rs @@ -18,6 +18,8 @@ use tracing::*; /// of the account in our bank /// - `delegation_record`: the delegation record associated with the account in our bank, if found /// - `validator_auth`: the validator authority pubkey +/// - `compressed_delegation_slot`: for compressed (no DLP) accounts, the slot from the +/// borsh record; `None` when the classic DLP is used /// - returns `true` if the account is still undelegating, `false` otherwise. pub(crate) fn account_still_undelegating_on_chain( pubkey: &Pubkey, @@ -25,6 +27,7 @@ pub(crate) fn account_still_undelegating_on_chain( remote_slot_in_bank: u64, deleg_record: Option, validator_auth: &Pubkey, + compressed_delegation_slot: Option, ) -> bool { // In the case of a subscription update for an account that was undelegating // we know that the undelegation or associated commit or possibly a previous @@ -54,6 +57,7 @@ pub(crate) fn account_still_undelegating_on_chain( let delegation_slot = deleg_record .as_ref() .map(|d| d.delegation_slot) + .or(compressed_delegation_slot) .unwrap_or_default(); if delegation_slot <= remote_slot_in_bank { // The last update of the account was after the last delegation @@ -117,6 +121,7 @@ mod tests { remote_slot, deleg_record, &Pubkey::default(), + None, )); } @@ -144,6 +149,7 @@ mod tests { remote_slot, deleg_record, &Pubkey::default(), + None, )); */ @@ -156,6 +162,7 @@ mod tests { remote_slot, deleg_record, &Pubkey::default(), + None, )); } @@ -180,6 +187,7 @@ mod tests { remote_slot, deleg_record, &Pubkey::default(), + None, )); } @@ -203,6 +211,33 @@ mod tests { remote_slot, deleg_record, &Pubkey::default(), + None, + )); + } + + #[test] + fn test_compressed_redelegation_slot_when_no_dlp() { + let pubkey = Pubkey::default(); + let is_delegated = true; + let remote_slot = 100; + // No classic delegation record: without `compressed_delegation_slot`, `delegation_slot` + // defaults to 0 and is treated as case D (commit still behind bank). + assert!(account_still_undelegating_on_chain( + &pubkey, + is_delegated, + remote_slot, + None, + &Pubkey::default(), + None, + )); + // Borsh `delegation_slot` for compressed accounts disambiguates redelegation to us. + assert!(!account_still_undelegating_on_chain( + &pubkey, + is_delegated, + remote_slot, + None, + &Pubkey::default(), + Some(101), )); } } diff --git a/magicblock-chainlink/src/chainlink/errors.rs b/magicblock-chainlink/src/chainlink/errors.rs index 5d6b68a93..bdb2fe9e9 100644 --- a/magicblock-chainlink/src/chainlink/errors.rs +++ b/magicblock-chainlink/src/chainlink/errors.rs @@ -49,6 +49,12 @@ pub enum ChainlinkError { #[error("Missing accounts required by delegation actions: {0:?}")] MissingDelegationActionAccounts(Vec), + #[error("Photon client error: {0}")] + PhotonClientError( + #[from] + crate::remote_account_provider::photon_client::PhotonClientError, + ), + #[error("timeout waiting for pending request for {0}")] PendingRequestTimeout(Pubkey), diff --git a/magicblock-chainlink/src/chainlink/fetch_cloner/ata_projection.rs b/magicblock-chainlink/src/chainlink/fetch_cloner/ata_projection.rs index bec28bef5..487119103 100644 --- a/magicblock-chainlink/src/chainlink/fetch_cloner/ata_projection.rs +++ b/magicblock-chainlink/src/chainlink/fetch_cloner/ata_projection.rs @@ -22,8 +22,8 @@ use super::{ use crate::{ cloner::{AccountCloneRequest, Cloner, DelegationActions}, remote_account_provider::{ - ChainPubsubClient, ChainRpcClient, ResolvedAccountSharedData, - SubscriptionReason, + photon_client::PhotonClient, ChainPubsubClient, ChainRpcClient, + ResolvedAccountSharedData, SubscriptionReason, }, }; @@ -75,8 +75,8 @@ fn ata_info_from_layout( /// and, if the ATA is delegated to us and the eATA exists, we clone the eATA data /// into the ATA in the bank. #[instrument(skip(this, atas))] -pub(crate) async fn resolve_ata_with_eata_projection( - this: &FetchCloner, +pub(crate) async fn resolve_ata_with_eata_projection( + this: &FetchCloner, atas: Vec<( Pubkey, AccountSharedData, @@ -91,6 +91,7 @@ where U: ChainPubsubClient, V: AccountsBank, C: Cloner, + P: PhotonClient, { if atas.is_empty() { return vec![]; diff --git a/magicblock-chainlink/src/chainlink/fetch_cloner/compression.rs b/magicblock-chainlink/src/chainlink/fetch_cloner/compression.rs new file mode 100644 index 000000000..5bcbb58c7 --- /dev/null +++ b/magicblock-chainlink/src/chainlink/fetch_cloner/compression.rs @@ -0,0 +1,114 @@ +use borsh::BorshDeserialize; +use compressed_delegation_client::CompressedDelegationRecord; +use magicblock_accounts_db::traits::AccountsBank; +use solana_account::{AccountSharedData, ReadableAccount}; +use solana_pubkey::Pubkey; +use tracing::*; + +use super::FetchCloner; +use crate::{ + cloner::{AccountCloneRequest, Cloner, DelegationActions}, + remote_account_provider::{ + photon_client::PhotonClient, ChainPubsubClient, ChainRpcClient, + }, +}; + +/// Expand a [`CompressedDelegationRecord`] from `data` into the logical owner, payload, and +/// delegation flags. +/// +/// Returns `None` when `data` is not a valid borsh record (including when the account is already +/// expanded and `data` holds only the program payload). +pub(crate) fn try_decompress_compressed_delegation( + this: &FetchCloner, + account: &AccountSharedData, + min_context_slot: u64, +) -> Option<(AccountSharedData, u64)> +where + T: ChainRpcClient, + U: ChainPubsubClient, + V: AccountsBank, + C: Cloner, + P: PhotonClient, +{ + let Ok(compressed_delegation_record) = + CompressedDelegationRecord::try_from_slice(account.data()) + else { + return None; + }; + let effective_slot = min_context_slot.max(account.remote_slot()); + let delegation_slot = compressed_delegation_record.delegation_slot; + let mut out = AccountSharedData::new( + compressed_delegation_record.lamports, + compressed_delegation_record.data.len(), + &compressed_delegation_record.owner, + ); + out.set_data(compressed_delegation_record.data); + out.set_compressed(true); + out.set_remote_slot(effective_slot); + out.set_delegated( + compressed_delegation_record.authority == this.validator_pubkey, + ); + Some((out, delegation_slot)) +} + +#[instrument(skip(this, compressed_accounts))] +pub(crate) fn resolve_compressed_accounts( + this: &FetchCloner, + compressed_accounts: Vec<(Pubkey, AccountSharedData, u64)>, + min_context_slot: Option, +) -> Vec +where + T: ChainRpcClient, + U: ChainPubsubClient, + V: AccountsBank, + C: Cloner, + P: PhotonClient, +{ + if compressed_accounts.is_empty() { + return vec![]; + } + + let mut accounts_to_clone = Vec::with_capacity(compressed_accounts.len()); + + for (pubkey, account_shared_data, slot) in compressed_accounts { + let effective_slot = if let Some(min_slot) = min_context_slot { + min_slot.max(slot) + } else { + slot + }; + + let Ok(compressed_delegation_record) = + CompressedDelegationRecord::try_from_slice( + account_shared_data.data(), + ) + else { + warn!( + pubkey = %pubkey, + "Failed to deserialize compressed delegation record" + ); + continue; + }; + + let mut account = AccountSharedData::new( + compressed_delegation_record.lamports, + compressed_delegation_record.data.len(), + &compressed_delegation_record.owner, + ); + account.set_data(compressed_delegation_record.data); + account.set_compressed(true); + account.set_remote_slot(effective_slot); + account.set_delegated( + compressed_delegation_record.authority == this.validator_pubkey, + ); + + accounts_to_clone.push(AccountCloneRequest { + pubkey, + account, + commit_frequency_ms: None, + delegation_actions: DelegationActions::default(), + delegated_to_other: None, + }); + } + + accounts_to_clone +} diff --git a/magicblock-chainlink/src/chainlink/fetch_cloner/delegation.rs b/magicblock-chainlink/src/chainlink/fetch_cloner/delegation.rs index a167f80f7..a98b85b22 100644 --- a/magicblock-chainlink/src/chainlink/fetch_cloner/delegation.rs +++ b/magicblock-chainlink/src/chainlink/fetch_cloner/delegation.rs @@ -20,8 +20,8 @@ use crate::{ chainlink::errors::{ChainlinkError, ChainlinkResult}, cloner::{Cloner, DelegationActions}, remote_account_provider::{ - ChainPubsubClient, ChainRpcClient, MatchSlotsConfig, - ResolvedAccountSharedData, SubscriptionReason, + photon_client::PhotonClient, ChainPubsubClient, ChainRpcClient, + MatchSlotsConfig, ResolvedAccountSharedData, SubscriptionReason, }, }; @@ -92,8 +92,8 @@ fn parse_post_delegation_actions( Ok(instructions.into()) } -pub(crate) fn apply_delegation_record_to_account( - this: &FetchCloner, +pub(crate) fn apply_delegation_record_to_account( + this: &FetchCloner, account_pubkey: Pubkey, account: &mut ResolvedAccountSharedData, delegation_record: &DelegationRecord, @@ -103,6 +103,7 @@ where U: ChainPubsubClient, V: AccountsBank, C: Cloner, + P: PhotonClient, { let is_confined = delegation_record.authority.eq(&Pubkey::default()); let is_delegated_to_us = @@ -146,8 +147,8 @@ pub(crate) fn parse_raw_eata_pda( .then_some((wallet_owner, mint)) } -pub(crate) fn get_delegated_to_other( - this: &FetchCloner, +pub(crate) fn get_delegated_to_other( + this: &FetchCloner, delegation_record: &DelegationRecord, ) -> Option where @@ -155,6 +156,7 @@ where U: ChainPubsubClient, V: AccountsBank, C: Cloner, + P: PhotonClient, { let is_delegated_to_us = delegation_record.authority.eq(&this.validator_pubkey) @@ -164,8 +166,8 @@ where } #[instrument(skip(this))] -pub(crate) async fn fetch_and_parse_delegation_record( - this: &FetchCloner, +pub(crate) async fn fetch_and_parse_delegation_record( + this: &FetchCloner, account_pubkey: Pubkey, min_context_slot: u64, fetch_origin: metrics::AccountFetchOrigin, @@ -175,6 +177,7 @@ where U: ChainPubsubClient, V: AccountsBank, C: Cloner, + P: PhotonClient, { let delegation_record_pubkey = delegation_record_pda_from_delegated_account(&account_pubkey); diff --git a/magicblock-chainlink/src/chainlink/fetch_cloner/mod.rs b/magicblock-chainlink/src/chainlink/fetch_cloner/mod.rs index 157929eff..8fd8af58d 100644 --- a/magicblock-chainlink/src/chainlink/fetch_cloner/mod.rs +++ b/magicblock-chainlink/src/chainlink/fetch_cloner/mod.rs @@ -39,6 +39,7 @@ pub(crate) const FETCH_CLONE_OPERATION_TIMEOUT: Duration = Duration::from_secs(60); mod ata_projection; +mod compression; mod delegation; mod pending_clone_guard; mod pending_operation; @@ -78,6 +79,7 @@ use crate::{ AccountCloneRequest, Cloner, DelegationActions, }, remote_account_provider::{ + photon_client::PhotonClient, program_account::get_loaderv3_get_program_data_address, CapacityEvictionProtection, ChainPubsubClient, ChainRpcClient, ForwardedSubscriptionUpdate, MatchSlotsConfig, RemoteAccount, @@ -85,15 +87,16 @@ use crate::{ }, }; -pub struct FetchCloner +pub struct FetchCloner where T: ChainRpcClient, U: ChainPubsubClient, V: AccountsBank, C: Cloner, + P: PhotonClient, { /// The RemoteAccountProvider to fetch accounts from - remote_account_provider: Arc>, + remote_account_provider: Arc>, /// Tracks pending account fetch requests to avoid duplicate fetches in parallel /// Once an account is fetched and cloned into the bank, it's removed from here pending_requests: Arc>, @@ -134,6 +137,12 @@ where >, >, + /// Pubkeys for which the committor called `undelegation_requested`. Until the + /// bank reflects delegated+compressed (or a newer merged view), we must not short-circuit + /// in [`FetchCloner::fetch_and_clone_accounts_with_dedup`]: RPC may be up to date while + /// Photon has the compressed redelegation. + post_undelegation_photon_merge_pending: Arc>>, + pending_operation_timeout_ms: Arc, /// Risk checker for post-delegation action addresses. @@ -150,12 +159,13 @@ const KNOWN_EMPTY_EATAS_CAPACITY: NonZeroUsize = /// Manual Clone impl: `#[derive(Clone)]` would add `V: Clone, C: Clone` /// bounds that are not satisfied (`AccountsBank` and `Cloner` don't /// require `Clone`). All fields are behind `Arc` so Clone is not needed. -impl Clone for FetchCloner +impl Clone for FetchCloner where T: ChainRpcClient, U: ChainPubsubClient, V: AccountsBank, C: Cloner, + P: PhotonClient, { fn clone(&self) -> Self { Self { @@ -173,6 +183,9 @@ where programs_not_to_subscribe: self.programs_not_to_subscribe.clone(), known_empty_eatas: self.known_empty_eatas.clone(), pending_clones: self.pending_clones.clone(), + post_undelegation_photon_merge_pending: self + .post_undelegation_photon_merge_pending + .clone(), pending_operation_timeout_ms: self .pending_operation_timeout_ms .clone(), @@ -181,17 +194,41 @@ where } } -impl FetchCloner +/// `mark_empty_if_not_found` can materialize a 0-lamport, no-data account. That entry must not +/// short-circuit [`FetchCloner::fetch_and_clone_accounts_with_dedup`], or a later run might skip +/// [`RemoteAccountProvider`]'s merged RPC+Photon path and never observe compressed state. +fn bank_entry_is_tentative_empty_for_refetch( + account: &AccountSharedData, +) -> bool { + if account.lamports() != 0 + || !account.data().is_empty() + || account.executable() + || account.delegated() + || account.undelegating() + { + return false; + } + if account.compressed() { + // Placeholder that already came from the compressed fetch path; both sides may agree on + // not found — nothing further to resolve here. + return false; + } + let owner = account.owner(); + owner == &Pubkey::default() || owner == &system_program::id() +} + +impl FetchCloner where T: ChainRpcClient, U: ChainPubsubClient, V: AccountsBank, C: Cloner, + P: PhotonClient, { /// Create FetchCloner with subscription updates properly connected #[allow(clippy::too_many_arguments)] pub fn new( - remote_account_provider: &Arc>, + remote_account_provider: &Arc>, accounts_bank: &Arc, cloner: &Arc, validator_keypair: Keypair, @@ -221,6 +258,9 @@ where KNOWN_EMPTY_EATAS_CAPACITY, ))), pending_clones: Arc::new(Mutex::new(hash_map::HashMap::new())), + post_undelegation_photon_merge_pending: Arc::new(Mutex::new( + HashSet::new(), + )), pending_operation_timeout_ms: Arc::new(AtomicU64::new( FETCH_CLONE_OPERATION_TIMEOUT.as_millis() as u64, )), @@ -254,6 +294,22 @@ where self.fetch_count.load(Ordering::Relaxed) } + /// Mark an account as needing a merged RPC+Photon refetch after the committor has run + /// `undelegation_requested` for this pubkey. + pub fn mark_post_undelegation_photon_merge_pending(&self, pubkey: Pubkey) { + self.post_undelegation_photon_merge_pending + .lock() + .expect("post_undelegation_photon_merge_pending lock poisoned") + .insert(pubkey); + } + + fn clear_post_undelegation_photon_merge_pending(&self, pubkey: Pubkey) { + self.post_undelegation_photon_merge_pending + .lock() + .expect("post_undelegation_photon_merge_pending lock poisoned") + .remove(&pubkey); + } + pub fn cloner(&self) -> &Arc { &self.cloner } @@ -568,7 +624,12 @@ where return; } - let (resolved_account, deleg_record, delegation_actions) = self + let ( + resolved_account, + deleg_record, + delegation_actions, + compressed_delegation_slot, + ) = self .resolve_account_to_clone_from_forwarded_sub_with_unsubscribe( update, ) @@ -673,6 +734,7 @@ where in_bank.remote_slot(), deleg_record, &self.validator_pubkey, + compressed_delegation_slot, ) { return; } @@ -1045,6 +1107,38 @@ where .await; } + async fn unsubscribe_from_delegated_account(&self, pubkey: Pubkey) { + self.clear_post_undelegation_photon_merge_pending(pubkey); + if let Err(err) = self + .remote_account_provider + .release_single_subscription( + &pubkey, + SubscriptionReason::UndelegationTracking, + ) + .await + { + warn!( + pubkey = %pubkey, + error = %err, + "Failed to clean up undelegation tracking subscription for delegated account" + ); + } + if let Err(err) = self + .remote_account_provider + .release_single_subscription( + &pubkey, + SubscriptionReason::DirectAccount, + ) + .await + { + warn!( + pubkey = %pubkey, + error = %err, + "Failed to clean up direct subscription for delegated account" + ); + } + } + async fn cleanup_direct_subscription_for_delegated_account( &self, pubkey: Pubkey, @@ -1102,6 +1196,65 @@ where } } + /// If `data` holds a borsh [`CompressedDelegationRecord`], expand to logical owner and + /// payload like `resolve_compressed_accounts`. Fetched Photon accounts may already list the + /// logical owner; we only require valid record bytes in `data`. + /// If the notification has no `data` (e.g. truncated), refetch merged RPC+Photon and retry. + /// Second return: [`CompressedDelegationRecord::delegation_slot`] when expanded (see + /// [`account_still_undelegating_on_chain`]). + async fn decompress_or_refetch_compressed_account( + &self, + pubkey: Pubkey, + account: AccountSharedData, + ) -> Option<(AccountSharedData, Option)> { + let min_slot = account.remote_slot(); + if let Some((out, delegation_slot)) = + compression::try_decompress_compressed_delegation( + self, &account, min_slot, + ) + { + return Some((out, Some(delegation_slot))); + } + if !account.data().is_empty() { + return Some((account, None)); + } + let skip_on_failed_refetch = account.compressed(); + if let Ok(fetched) = self + .remote_account_provider + .try_get_multi( + &[pubkey], + None, + AccountFetchOrigin::GetAccount, + None, + Some(min_slot), + ) + .await + { + if let Some(ra) = fetched.into_iter().next() { + if let Some(fresh) = ra.fresh_account() { + if let Some((out, delegation_slot)) = + compression::try_decompress_compressed_delegation( + self, + &fresh, + min_slot.max(fresh.remote_slot()), + ) + { + return Some((out, Some(delegation_slot))); + } + } + } + } else { + warn!(pubkey = %pubkey, "Refetch for compressed subscription account failed"); + } + if skip_on_failed_refetch { + None + } else { + Some((account, None)) + } + } + + // Fourth return value: `CompressedDelegationRecord::delegation_slot` for compressed (no DLP) + // accounts, used in `account_still_undelegating_on_chain`. async fn resolve_account_to_clone_from_forwarded_sub_with_unsubscribe( &self, update: ForwardedSubscriptionUpdate, @@ -1109,6 +1262,7 @@ where Option, Option, DelegationActions, + Option, ) { let ForwardedSubscriptionUpdate { pubkey, account } = update; let owned_by_delegation_program = @@ -1239,12 +1393,13 @@ where Some(account.into_account_shared_data()), Some(delegation_record), delegation_actions.unwrap_or_default(), + None, ) } else { // If the delegation record is invalid we cannot clone the account // since something is corrupt and we wouldn't know what owner to // use, etc. - (None, None, DelegationActions::default()) + (None, None, DelegationActions::default(), None) } } else { // If no delegation record exists we must assume the account itself is @@ -1253,6 +1408,7 @@ where Some(account.into_account_shared_data()), None, DelegationActions::default(), + None, ) }; @@ -1283,7 +1439,7 @@ where ) .await; } - (None, None, DelegationActions::default()) + (None, None, DelegationActions::default(), None) } Err(err) => { warn!( @@ -1302,10 +1458,16 @@ where ) .await; } - (None, None, DelegationActions::default()) + (None, None, DelegationActions::default(), None) } } } else { + let Some((account, compressed_delegation_slot)) = self + .decompress_or_refetch_compressed_account(pubkey, account) + .await + else { + return (None, None, DelegationActions::default(), None); + }; let (account, deleg_record) = self .maybe_project_ata_from_subscription_update(pubkey, account) .await; @@ -1314,16 +1476,22 @@ where Some(account), Some(deleg_record), actions.unwrap_or_default(), + compressed_delegation_slot, ) } else { - (Some(account), None, DelegationActions::default()) + ( + Some(account), + None, + DelegationActions::default(), + compressed_delegation_slot, + ) } } } else { // This should not happen since we call this method with sub updates which always hold // a fresh remote account error!(pubkey = %pubkey, account = ?account, "BUG: Received subscription update without fresh account"); - (None, None, DelegationActions::default()) + (None, None, DelegationActions::default(), None) } } @@ -1627,6 +1795,7 @@ where not_found, plain, owned_by_deleg, + compressed, programs, atas, } = pipeline::classify_remote_accounts(accs, pubkeys); @@ -1644,6 +1813,10 @@ where .iter() .map(|(pubkey, _, slot)| (pubkey.to_string(), *slot)) .collect::>(); + let compressed = compressed + .iter() + .map(|(pubkey, _, slot)| (pubkey.to_string(), *slot)) + .collect::>(); let programs = programs .iter() .map(|(p, _, _)| p.to_string()) @@ -1653,7 +1826,7 @@ where .map(|(a, _, _, _)| a.to_string()) .collect::>(); trace!( - "Fetched accounts: \nnot_found: {not_found:?} \nplain: {plain:?} \nowned_by_deleg: {owned_by_deleg:?}\nprograms: {programs:?} \natas: {atas:?}", + "Fetched accounts: \nnot_found: {not_found:?} \nplain: {plain:?} \nowned_by_deleg: {owned_by_deleg:?}\ncompressed: {compressed:?}\nprograms: {programs:?} \natas: {atas:?}", ); } @@ -1775,6 +1948,13 @@ where .await; accounts_to_clone.extend(ata_accounts); + let compressed_accounts = compression::resolve_compressed_accounts( + self, + compressed, + min_context_slot, + ); + accounts_to_clone.extend(compressed_accounts); + // Ensure all accounts referenced by delegation actions exist and are // cloned before we execute those actions as part of account cloning. let action_dependencies = @@ -1823,6 +2003,7 @@ where not_found, plain, owned_by_deleg, + compressed, programs, atas, } = pipeline::classify_remote_accounts( @@ -1932,8 +2113,16 @@ where ) .await; + let action_dep_compressed_accounts = + compression::resolve_compressed_accounts( + self, + compressed, + min_context_slot, + ); + accounts_to_clone.extend(action_dep_accounts_to_clone); accounts_to_clone.extend(action_dep_ata_accounts); + accounts_to_clone.extend(action_dep_compressed_accounts); loaded_programs.extend(action_dep_loaded_programs); } @@ -1944,6 +2133,11 @@ where record_subs, program_data_subs, ); + let delegated_cloned_pubkeys = accounts_to_clone + .iter() + .filter(|request| request.account.delegated()) + .map(|request| request.pubkey) + .collect::>(); pipeline::clone_accounts_and_programs( self, @@ -1953,6 +2147,26 @@ where .await?; release_subs(&self.remote_account_provider, releases).await; + for pubkey in delegated_cloned_pubkeys { + self.unsubscribe_from_delegated_account(pubkey).await; + } + + { + let mut pending = self + .post_undelegation_photon_merge_pending + .lock() + .expect("post_undelegation_photon_merge_pending lock poisoned"); + for pubkey in pubkeys { + if !pending.contains(pubkey) { + continue; + } + if self.accounts_bank.get_account(pubkey).is_some_and( + |in_bank| !in_bank.delegated() && !in_bank.compressed(), + ) { + pending.remove(pubkey); + } + } + } Ok(FetchAndCloneResult { not_found_on_chain: not_found, @@ -1980,6 +2194,12 @@ where "Fetching undelegating account" ); + if in_bank.compressed() { + // We must refetch so RPC+Photon see the latest compressed record. + debug!(pubkey = %pubkey, "Undelegating compressed account: refresh from chain"); + return RefreshDecision::Yes; + } + if let Some(eata_pubkey) = ata_projection::derive_eata_pubkey_from_ata_layout( pubkey, in_bank, @@ -2032,6 +2252,7 @@ where in_bank.remote_slot(), deleg_record, &self.validator_pubkey, + None, ) { debug!( "Account {pubkey} marked as undelegating will be overridden since undelegation completed" @@ -2090,25 +2311,85 @@ where { if account_in_bank.undelegating() { undelegating_checks.push((**pubkey, account_in_bank)); + } else if bank_entry_is_tentative_empty_for_refetch( + &account_in_bank, + ) { + // `mark_empty_if_not_found` (RPC/Photon) stores a 0-lamport empty account. If + // the first attempt only had the RPC side, the bank can hold that placeholder + // even when Photon later has the real compressed state — and we would skip + // `try_get_multi` and never merge. Refetch to let consolidation run again. + debug!( + pubkey = %pubkey, + "Tentative empty account in bank; not treating as fetch-complete" + ); } else { - if account_in_bank.owner().eq(&dlp_api::id()) { + { + let mut pending = self + .post_undelegation_photon_merge_pending + .lock() + .expect("post_undelegation_photon_merge_pending lock poisoned"); + if account_in_bank.delegated() + || account_in_bank.compressed() + { + pending.remove(*pubkey); + } + } + // Subscription updates resolve delegated accounts by fetching the account + // with its delegation record. While that provider fetch is in flight, the + // bank can still hold the older undelegated view; do not short-circuit. + let delegation_record_pubkey = + delegation_record_pda_from_delegated_account(pubkey); + let pending_delegation_update = self.is_watching(pubkey) + && !account_in_bank.delegated() + && !account_in_bank.compressed() + && (self.remote_account_provider.is_pending(pubkey) + || self + .remote_account_provider + .is_pending(&delegation_record_pubkey)); + + // After undelegation the bank can hold a plain (non-compressed) undelegated + // view while a newer compressed redelegation exists only in Photon. If we + // short-circuited here, we would never run RPC+Photon merge and would miss + // redelegation. `undelegation_requested` marks the pubkey; we refetch until + // the bank shows merged delegated/compressed state. + let may_have_newer_photon = { + self.post_undelegation_photon_merge_pending + .lock() + .expect("post_undelegation_photon_merge_pending lock poisoned") + .contains(*pubkey) + } && self.is_watching(pubkey) + && !account_in_bank.delegated() + && !account_in_bank.compressed(); + if pending_delegation_update { debug!( pubkey = %pubkey, - "Account owned by deleg program not marked as undelegating" + "Account has pending delegation update; not treating bank entry as fetch-complete" ); - } - if tracing::enabled!(tracing::Level::TRACE) { - let delegated = account_in_bank.delegated(); - let owner = account_in_bank.owner(); - trace!( + } else if may_have_newer_photon { + debug!( pubkey = %pubkey, - undelegating = false, - delegated, - owner = %owner, - "Account found in bank in valid state, no fetch needed" + "Post-undelegation, non-delegated, non-compressed in bank; refetching to merge possible Photon state" ); + } else { + if account_in_bank.owner().eq(&dlp_api::id()) { + debug!( + pubkey = %pubkey, + "Account owned by deleg program not marked as undelegating" + ); + } + if tracing::enabled!(tracing::Level::TRACE) { + let delegated = account_in_bank.delegated(); + let owner = account_in_bank.owner(); + trace!( + pubkey = %pubkey, + undelegating = false, + delegated, + owner = %owner, + "Account found in bank in valid state, no fetch needed" + ); + } + in_bank.insert(**pubkey); } - in_bank.insert(**pubkey); } } } @@ -2447,6 +2728,7 @@ where reason = ?SubscriptionReason::UndelegationTracking, "Subscribing to account" ); + self.mark_post_undelegation_photon_merge_pending(*pubkey); // Acquire undelegation tracking ownership before/with local // undelegating visibility; any LRU entry created for this reason is // protected from capacity eviction by the provider's bank-state diff --git a/magicblock-chainlink/src/chainlink/fetch_cloner/pipeline.rs b/magicblock-chainlink/src/chainlink/fetch_cloner/pipeline.rs index c4ae23908..b2898369b 100644 --- a/magicblock-chainlink/src/chainlink/fetch_cloner/pipeline.rs +++ b/magicblock-chainlink/src/chainlink/fetch_cloner/pipeline.rs @@ -23,12 +23,13 @@ use crate::{ errors::ClonerResult, AccountCloneRequest, Cloner, DelegationActions, }, remote_account_provider::{ + photon_client::PhotonClient, program_account::{ get_loaderv3_get_program_data_address, ProgramAccountResolver, LOADER_V3, }, ChainPubsubClient, ChainRpcClient, MatchSlotsConfig, RemoteAccount, - ResolvedAccount, SubscriptionReason, + RemoteAccountUpdateSource, ResolvedAccount, SubscriptionReason, }, }; @@ -55,6 +56,7 @@ pub(crate) fn classify_remote_accounts( let mut not_found = Vec::new(); let mut plain = Vec::new(); let mut owned_by_deleg = Vec::new(); + let mut compressed = Vec::new(); let mut programs = Vec::new(); let mut atas = Vec::new(); @@ -65,6 +67,7 @@ pub(crate) fn classify_remote_accounts( &mut not_found, &mut plain, &mut owned_by_deleg, + &mut compressed, &mut programs, &mut atas, ); @@ -74,6 +77,7 @@ pub(crate) fn classify_remote_accounts( not_found, plain, owned_by_deleg, + compressed, programs, atas, } @@ -81,12 +85,14 @@ pub(crate) fn classify_remote_accounts( /// Helper function to classify a single remote account #[inline] +#[allow(clippy::too_many_arguments)] fn classify_single_account( acc: RemoteAccount, pubkey: Pubkey, not_found: &mut Vec<(Pubkey, u64)>, plain: &mut Vec, owned_by_deleg: &mut Vec<(Pubkey, AccountSharedData, u64)>, + compressed: &mut Vec<(Pubkey, AccountSharedData, u64)>, programs: &mut Vec<(Pubkey, AccountSharedData, u64)>, atas: &mut Vec<( Pubkey, @@ -125,6 +131,11 @@ fn classify_single_account( { // Associated Token Account atas.push((pubkey, account_shared_data, ata, slot)); + } else if remote_account_state.source + == RemoteAccountUpdateSource::Compressed + { + // Compressed account + compressed.push((pubkey, account_shared_data, slot)); } else { // Plain account plain.push(AccountCloneRequest { @@ -190,8 +201,8 @@ pub(crate) fn partition_not_found( /// Resolves delegated accounts by fetching their delegation records #[instrument(skip(this, owned_by_deleg, plain), fields(pubkey_count = owned_by_deleg.len()))] -pub(crate) async fn resolve_delegated_accounts( - this: &FetchCloner, +pub(crate) async fn resolve_delegated_accounts( + this: &FetchCloner, owned_by_deleg: Vec<(Pubkey, AccountSharedData, u64)>, plain: Vec, min_context_slot: Option, @@ -202,6 +213,7 @@ where U: ChainPubsubClient, V: AccountsBank, C: Cloner, + P: PhotonClient, { let record_subs = owned_by_deleg .iter() @@ -435,8 +447,8 @@ where /// Resolves program accounts, fetching program data accounts for LoaderV3 programs #[instrument(skip(this, programs), fields(pubkey_count = programs.len()))] -pub(crate) async fn resolve_programs_with_program_data( - this: &FetchCloner, +pub(crate) async fn resolve_programs_with_program_data( + this: &FetchCloner, programs: Vec<(Pubkey, AccountSharedData, u64)>, min_context_slot: Option, fetch_origin: AccountFetchOrigin, @@ -446,6 +458,7 @@ where U: ChainPubsubClient, V: AccountsBank, C: Cloner, + P: PhotonClient, { // For LoaderV3 accounts we fetch the program data account let (loaderv3_programs, single_account_programs): (Vec<_>, Vec<_>) = @@ -535,7 +548,7 @@ where let account_program = account_pair[0].clone(); let account_data = account_pair[1].clone(); - let result = FetchCloner::::resolve_account_with_companion( + let result = FetchCloner::::resolve_account_with_companion( &this.accounts_bank, pubkey, program_data_pubkey, @@ -678,10 +691,41 @@ pub(crate) fn compute_subscription_releases( releases } +/// While the bank still marks a compressed account as `undelegating`, a refetch can return the +/// prior on-chain/Photon state (still delegated to us at the same or older slot). Cloning that +/// would clear `undelegating` early. Skip only for that stale same-slot (or older) view; a fetch +/// with a **newer** `remote_slot` is fresh (e.g. redelegation after undelegation) and must be +/// applied. +fn skip_clone_while_compressed_undelegation_not_on_chain_yet( + in_bank: Option, + request: &AccountCloneRequest, +) -> bool { + let Some(in_bank) = in_bank else { + return false; + }; + if !in_bank.undelegating() || !in_bank.compressed() { + return false; + } + if !request.account.compressed() { + return false; + } + if !request.account.delegated() { + return false; + } + if request.account.remote_slot() > in_bank.remote_slot() { + return false; + } + trace!( + pubkey = %request.pubkey, + "Skipping clone: merged fetch still shows delegation to us at a stale slot while bank is undelegating" + ); + true +} + /// Clones accounts and programs into the bank #[instrument(skip(this, accounts_to_clone, loaded_programs))] -pub(crate) async fn clone_accounts_and_programs( - this: &FetchCloner, +pub(crate) async fn clone_accounts_and_programs( + this: &FetchCloner, accounts_to_clone: Vec, loaded_programs: Vec< crate::remote_account_provider::program_account::LoadedProgram, @@ -692,7 +736,18 @@ where U: ChainPubsubClient, V: AccountsBank, C: Cloner, + P: PhotonClient, { + let accounts_to_clone = accounts_to_clone + .into_iter() + .filter(|request| { + !skip_clone_while_compressed_undelegation_not_on_chain_yet( + this.accounts_bank.get_account(&request.pubkey), + request, + ) + }) + .collect::>(); + // 1) Clone programs first so post-delegation action instructions can load // their program accounts when action txs are sent during account cloning. let mut program_join_set = JoinSet::new(); diff --git a/magicblock-chainlink/src/chainlink/fetch_cloner/program_loader.rs b/magicblock-chainlink/src/chainlink/fetch_cloner/program_loader.rs index efef02b3c..e829cc233 100644 --- a/magicblock-chainlink/src/chainlink/fetch_cloner/program_loader.rs +++ b/magicblock-chainlink/src/chainlink/fetch_cloner/program_loader.rs @@ -8,6 +8,7 @@ use super::{subscription::release_program_data_subs, FetchCloner}; use crate::{ cloner::Cloner, remote_account_provider::{ + photon_client::PhotonClient, program_account::{ get_loaderv3_get_program_data_address, ProgramAccountResolver, LOADER_V1, LOADER_V3, @@ -16,8 +17,8 @@ use crate::{ }, }; -pub(crate) async fn handle_executable_sub_update( - this: &FetchCloner, +pub(crate) async fn handle_executable_sub_update( + this: &FetchCloner, pubkey: Pubkey, account: AccountSharedData, ) where @@ -25,6 +26,7 @@ pub(crate) async fn handle_executable_sub_update( U: ChainPubsubClient, V: AccountsBank, C: Cloner, + P: PhotonClient, { if !this.is_program_allowed(&pubkey) { debug!(pubkey = %pubkey, "Skipping clone of program, not in allowed_programs"); diff --git a/magicblock-chainlink/src/chainlink/fetch_cloner/subscription.rs b/magicblock-chainlink/src/chainlink/fetch_cloner/subscription.rs index e66ffd8b3..3020b703b 100644 --- a/magicblock-chainlink/src/chainlink/fetch_cloner/subscription.rs +++ b/magicblock-chainlink/src/chainlink/fetch_cloner/subscription.rs @@ -6,8 +6,8 @@ use tracing::*; use crate::{ chainlink::errors::{ChainlinkError, ChainlinkResult}, remote_account_provider::{ - ChainPubsubClient, ChainRpcClient, RemoteAccountProvider, - SubscriptionReason, + photon_client::PhotonClient, ChainPubsubClient, ChainRpcClient, + RemoteAccountProvider, SubscriptionReason, }, }; @@ -18,8 +18,12 @@ pub(crate) enum SubscriptionRelease { }, } -pub(crate) async fn acquire_subs( - provider: &Arc>, +pub(crate) async fn acquire_subs< + T: ChainRpcClient, + U: ChainPubsubClient, + P: PhotonClient, +>( + provider: &Arc>, pubkeys: impl IntoIterator, reason: SubscriptionReason, ) -> ChainlinkResult<()> { @@ -45,8 +49,12 @@ pub(crate) async fn acquire_subs( } #[instrument(skip(provider, releases))] -pub(crate) async fn release_subs( - provider: &Arc>, +pub(crate) async fn release_subs< + T: ChainRpcClient, + U: ChainPubsubClient, + P: PhotonClient, +>( + provider: &Arc>, releases: impl IntoIterator, ) { for release in releases { @@ -62,8 +70,9 @@ pub(crate) async fn release_subs( pub(crate) async fn release_program_data_subs< T: ChainRpcClient, U: ChainPubsubClient, + P: PhotonClient, >( - provider: &Arc>, + provider: &Arc>, program_data_pubkey: Pubkey, ) { release_subs( diff --git a/magicblock-chainlink/src/chainlink/fetch_cloner/tests.rs b/magicblock-chainlink/src/chainlink/fetch_cloner/tests.rs index 95a1462a5..7ca491ed0 100644 --- a/magicblock-chainlink/src/chainlink/fetch_cloner/tests.rs +++ b/magicblock-chainlink/src/chainlink/fetch_cloner/tests.rs @@ -32,6 +32,7 @@ use crate::{ EATA_PROGRAM_ID, }, init_logger, + photon_client_mock::PhotonClientMock, rpc_client_mock::{ChainRpcClientMock, ChainRpcClientMockBuilder}, utils::{create_test_lru_cache, random_pubkey}, }, @@ -47,6 +48,7 @@ type TestFetchClonerResult = ( ChainPubsubClientMock, AccountsBankStub, ClonerStub, + PhotonClientMock, >, >, mpsc::Sender, @@ -100,8 +102,13 @@ macro_rules! assert_cloned_undelegated_account { } struct FetcherTestCtx { - remote_account_provider: - Arc>, + remote_account_provider: Arc< + RemoteAccountProvider< + ChainRpcClientMock, + ChainPubsubClientMock, + PhotonClientMock, + >, + >, accounts_bank: Arc, rpc_client: crate::testing::rpc_client_mock::ChainRpcClientMock, #[allow(unused)] @@ -112,6 +119,7 @@ struct FetcherTestCtx { ChainPubsubClientMock, AccountsBankStub, ClonerStub, + PhotonClientMock, >, >, #[allow(unused)] @@ -152,6 +160,7 @@ where let (updates_sender, updates_receiver) = mpsc::channel(1_000); let pubsub_client = ChainPubsubClientMock::new(updates_sender, updates_receiver); + let photon_client = PhotonClientMock::default(); let accounts_bank = Arc::new(AccountsBankStub::default()); let rpc_client_clone = rpc_client.clone(); @@ -163,6 +172,7 @@ where RemoteAccountProvider::new( rpc_client, pubsub_client, + Some(photon_client), forward_tx, &config, subscribed_accounts, @@ -248,7 +258,11 @@ fn add_delegation_record_with_slot_for( /// Returns (FetchCloner, subscription_sender) for simulating subscription updates in tests fn init_fetch_cloner( remote_account_provider: Arc< - RemoteAccountProvider, + RemoteAccountProvider< + ChainRpcClientMock, + ChainPubsubClientMock, + PhotonClientMock, + >, >, bank: &Arc, validator_keypair: Keypair, @@ -274,6 +288,7 @@ async fn wait_for_pending_request( ChainPubsubClientMock, AccountsBankStub, ClonerStub, + PhotonClientMock, >, >, pubkey: Pubkey, @@ -298,6 +313,7 @@ async fn wait_for_pending_waiter_count( ChainPubsubClientMock, AccountsBankStub, ClonerStub, + PhotonClientMock, >, >, pubkey: Pubkey, @@ -549,7 +565,12 @@ async fn test_get_account_releases_delegation_record_direct_ref_when_already_wat .await .unwrap(); - let (resolved_account, delegation_record, _actions) = fetch_cloner + let ( + resolved_account, + delegation_record, + _actions, + _compressed_delegation_slot, + ) = fetch_cloner .resolve_account_to_clone_from_forwarded_sub_with_unsubscribe( ForwardedSubscriptionUpdate { pubkey: account_pubkey, @@ -1152,7 +1173,7 @@ async fn test_delegation_record_unsub_race_condition_prevention() { // Use a shared FetchCloner to test deduplication // Helper function to spawn a fetch_and_clone task with shared FetchCloner - let spawn_fetch_task = |fetch_cloner: &Arc>| { + let spawn_fetch_task = |fetch_cloner: &Arc>| { let fetch_cloner = fetch_cloner.clone(); tokio::spawn(async move { fetch_cloner @@ -1335,6 +1356,142 @@ async fn test_undelegation_requested_subscription_behavior() { assert_subscribed!(remote_account_provider, &[&account_pubkey]); } +#[tokio::test] +async fn test_post_undelegation_plain_refresh_clears_photon_merge_marker() { + init_logger(); + let validator_keypair = Keypair::new(); + let account_owner = random_pubkey(); + const CURRENT_SLOT: u64 = 100; + + let account_pubkey = random_pubkey(); + let account = Account { + lamports: 1_000_000, + data: vec![1, 2, 3, 4], + owner: account_owner, + executable: false, + rent_epoch: 0, + }; + + let FetcherTestCtx { + remote_account_provider, + accounts_bank, + fetch_cloner, + .. + } = setup( + [(account_pubkey, account.clone())], + CURRENT_SLOT, + validator_keypair.insecure_clone(), + ) + .await; + + accounts_bank + .insert(account_pubkey, AccountSharedData::from(account.clone())); + fetch_cloner + .subscribe_to_account_to_track_undelegation(&account_pubkey) + .await + .expect("failed to subscribe to account"); + assert_subscribed!(remote_account_provider, &[&account_pubkey]); + + fetch_cloner.mark_post_undelegation_photon_merge_pending(account_pubkey); + + let result = fetch_cloner + .fetch_and_clone_accounts_with_dedup( + &[account_pubkey], + None, + None, + AccountFetchOrigin::GetAccount, + None, + ) + .await; + assert!(result.is_ok()); + + let marker_still_pending = fetch_cloner + .post_undelegation_photon_merge_pending + .lock() + .expect("post_undelegation_photon_merge_pending lock poisoned") + .contains(&account_pubkey); + assert!( + !marker_still_pending, + "plain refresh should clear post-undelegation Photon merge marker" + ); + + let fetch_count_after_plain_refresh = fetch_cloner.fetch_count(); + let result = fetch_cloner + .fetch_and_clone_accounts_with_dedup( + &[account_pubkey], + None, + None, + AccountFetchOrigin::GetAccount, + None, + ) + .await; + assert!(result.is_ok()); + assert_eq!(fetch_cloner.fetch_count(), fetch_count_after_plain_refresh); +} + +#[tokio::test] +async fn test_empty_compressed_subscription_update_skips_when_refetch_cannot_decompress( +) { + init_logger(); + let validator_keypair = Keypair::new(); + let account_owner = random_pubkey(); + const CURRENT_SLOT: u64 = 100; + + let account_pubkey = random_pubkey(); + let bank_account = Account { + lamports: 1_000_000, + data: vec![1, 2, 3, 4], + owner: account_owner, + executable: false, + rent_epoch: 0, + }; + + let FetcherTestCtx { + accounts_bank, + fetch_cloner, + .. + } = setup( + [(account_pubkey, bank_account.clone())], + CURRENT_SLOT + 1, + validator_keypair.insecure_clone(), + ) + .await; + + let mut expected_bank_account = AccountSharedData::from(bank_account); + expected_bank_account.set_remote_slot(CURRENT_SLOT); + accounts_bank.insert(account_pubkey, expected_bank_account.clone()); + + use crate::remote_account_provider::{ + RemoteAccount, RemoteAccountUpdateSource, + }; + let empty_compressed_shell = Account { + lamports: 0, + data: vec![], + owner: compressed_delegation_client::ID, + executable: false, + rent_epoch: 0, + }; + fetch_cloner + .process_subscription_update( + account_pubkey, + ForwardedSubscriptionUpdate { + pubkey: account_pubkey, + account: RemoteAccount::from_fresh_account( + empty_compressed_shell, + CURRENT_SLOT + 1, + RemoteAccountUpdateSource::Compressed, + ), + }, + ) + .await; + + assert_eq!( + accounts_bank.get_account(&account_pubkey), + Some(expected_bank_account), + "empty compressed shell should be skipped when refetch cannot decompress" + ); +} + #[tokio::test] async fn test_delegated_discovered_after_direct_subscribe_releases_direct_without_bank_removal( ) { @@ -2653,7 +2810,11 @@ async fn test_no_program_subscription_for_undelegated_account() { #[allow(clippy::too_many_arguments)] async fn send_subscription_update_and_get_subscribed_programs( remote_account_provider: &Arc< - RemoteAccountProvider, + RemoteAccountProvider< + ChainRpcClientMock, + ChainPubsubClientMock, + PhotonClientMock, + >, >, accounts_bank: &Arc, subscription_tx: &mpsc::Sender, diff --git a/magicblock-chainlink/src/chainlink/fetch_cloner/types.rs b/magicblock-chainlink/src/chainlink/fetch_cloner/types.rs index 2eece34d5..00cae5229 100644 --- a/magicblock-chainlink/src/chainlink/fetch_cloner/types.rs +++ b/magicblock-chainlink/src/chainlink/fetch_cloner/types.rs @@ -27,6 +27,7 @@ pub(crate) struct ClassifiedAccounts { pub(crate) not_found: Vec<(Pubkey, u64)>, pub(crate) plain: Vec, pub(crate) owned_by_deleg: Vec<(Pubkey, AccountSharedData, u64)>, + pub(crate) compressed: Vec<(Pubkey, AccountSharedData, u64)>, pub(crate) programs: Vec<(Pubkey, AccountSharedData, u64)>, pub(crate) atas: Vec<( Pubkey, diff --git a/magicblock-chainlink/src/chainlink/mod.rs b/magicblock-chainlink/src/chainlink/mod.rs index 4ea59a345..8a1f6429f 100644 --- a/magicblock-chainlink/src/chainlink/mod.rs +++ b/magicblock-chainlink/src/chainlink/mod.rs @@ -24,11 +24,16 @@ use crate::{ filters::is_noop_system_transfer, remote_account_provider::{ chain_pubsub_client::mock::ChainPubsubClientMock, - chain_updates_client::ChainUpdatesClient, ChainPubsubClient, - ChainRpcClient, ChainRpcClientImpl, Endpoints, RemoteAccountProvider, + chain_updates_client::ChainUpdatesClient, + photon_client::{PhotonClient, PhotonClientImpl}, + ChainPubsubClient, ChainRpcClient, ChainRpcClientImpl, Endpoints, + RemoteAccountProvider, }, submux::SubMuxClient, - testing::{cloner_stub::ClonerStub, rpc_client_mock::ChainRpcClientMock}, + testing::{ + cloner_stub::ClonerStub, photon_client_mock::PhotonClientMock, + rpc_client_mock::ChainRpcClientMock, + }, }; mod account_still_undelegating_on_chain; @@ -40,8 +45,18 @@ pub mod fetch_cloner; pub use blacklisted_accounts::*; /// A type alias for chainlink with only accountsdb being real impl -pub type StubbedChainlink = - Chainlink; +pub type StubbedChainlink = Chainlink< + ChainRpcClientMock, + ChainPubsubClientMock, + V, + ClonerStub, + PhotonClientMock, +>; + +type OptionalFetchCloner = + Option>>; +type OptionalFetchClonerRef<'a, T, U, V, C, P> = + Option<&'a Arc>>; // ----------------- // Chainlink @@ -51,9 +66,10 @@ pub struct Chainlink< U: ChainPubsubClient, V: AccountsBank, C: Cloner, + P: PhotonClient, > { accounts_bank: Arc, - fetch_cloner: Option>>, + fetch_cloner: OptionalFetchCloner, /// The subscription to events for each account that is removed from /// the accounts tracked by the provider. /// In that case we also remove it from the bank since it is no longer @@ -67,12 +83,17 @@ pub struct Chainlink< remove_confined_accounts: bool, } -impl - Chainlink +impl< + T: ChainRpcClient, + U: ChainPubsubClient, + V: AccountsBank, + C: Cloner, + P: PhotonClient, + > Chainlink { pub fn try_new( accounts_bank: &Arc, - fetch_cloner: Option>>, + fetch_cloner: OptionalFetchCloner, validator_pubkey: Pubkey, config: &ChainLinkConfig, ) -> ChainlinkResult { @@ -115,7 +136,13 @@ impl chainlink_config: &ChainLinkConfig, ledger_path: &Path, ) -> ChainlinkResult< - Chainlink, V, C>, + Chainlink< + ChainRpcClientImpl, + SubMuxClient, + V, + C, + PhotonClientImpl, + >, > { let validator_pubkey = validator_keypair.pubkey(); // Extract accounts provider and create fetch cloner while connecting @@ -281,7 +308,7 @@ impl /// does nothing as only existing accounts are affected. /// See [lru::LruCache::promote] fn promote_accounts( - fetch_cloner: &FetchCloner, + fetch_cloner: &FetchCloner, pubkeys: &[&Pubkey], ) { fetch_cloner.promote_accounts(pubkeys); @@ -420,7 +447,7 @@ impl ))] async fn fetch_accounts_common( &self, - fetch_cloner: &FetchCloner, + fetch_cloner: &FetchCloner, pubkeys: &[Pubkey], mark_empty_if_not_found: Option<&[Pubkey]>, fetch_origin: AccountFetchOrigin, @@ -478,7 +505,9 @@ impl Ok(()) } - pub fn fetch_cloner(&self) -> Option<&Arc>> { + pub fn fetch_cloner<'a>( + &'a self, + ) -> OptionalFetchClonerRef<'a, T, U, V, C, P> { self.fetch_cloner.as_ref() } @@ -555,6 +584,7 @@ mod tests { ChainPubsubClientMock, AccountsBankStub, ClonerStub, + PhotonClientMock, >::subscribe_account_removals( &accounts_bank, &cloner, removed_rx ); diff --git a/magicblock-chainlink/src/remote_account_provider/chain_updates_client.rs b/magicblock-chainlink/src/remote_account_provider/chain_updates_client.rs index 125a9407f..c974aa031 100644 --- a/magicblock-chainlink/src/remote_account_provider/chain_updates_client.rs +++ b/magicblock-chainlink/src/remote_account_provider/chain_updates_client.rs @@ -90,6 +90,11 @@ impl ChainUpdatesClient { "{endpoint:?}" ))) } + Compression { .. } => { + Err(RemoteAccountProviderError::InvalidPubsubEndpoint(format!( + "{endpoint:?}" + ))) + } } } } diff --git a/magicblock-chainlink/src/remote_account_provider/endpoint.rs b/magicblock-chainlink/src/remote_account_provider/endpoint.rs index d30d7b50b..fd27346b5 100644 --- a/magicblock-chainlink/src/remote_account_provider/endpoint.rs +++ b/magicblock-chainlink/src/remote_account_provider/endpoint.rs @@ -1,4 +1,4 @@ -use std::ops::Deref; +use std::ops::{Deref, DerefMut}; use magicblock_config::types::network::Remote; use url::Url; @@ -20,6 +20,10 @@ pub enum Endpoint { label: String, api_key: String, }, + Compression { + label: String, + url: String, + }, } impl Endpoint { @@ -27,7 +31,8 @@ impl Endpoint { match self { Endpoint::Rpc { label, .. } | Endpoint::WebSocket { label, .. } - | Endpoint::Grpc { label, .. } => label, + | Endpoint::Grpc { label, .. } + | Endpoint::Compression { label, .. } => label, } } } @@ -52,6 +57,16 @@ impl Endpoints { }) .collect() } + + pub fn photon_url(&self) -> Option { + self.iter().find_map(|ep| { + if let Endpoint::Compression { url, .. } = ep { + Some(url.clone()) + } else { + None + } + }) + } } impl TryFrom<&[Remote]> for Endpoints { @@ -121,6 +136,12 @@ impl Deref for Endpoints { } } +impl DerefMut for Endpoints { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + impl<'a> IntoIterator for &'a Endpoints { type Item = &'a Endpoint; type IntoIter = std::slice::Iter<'a, Endpoint>; diff --git a/magicblock-chainlink/src/remote_account_provider/errors.rs b/magicblock-chainlink/src/remote_account_provider/errors.rs index 2273ac3db..f029d5694 100644 --- a/magicblock-chainlink/src/remote_account_provider/errors.rs +++ b/magicblock-chainlink/src/remote_account_provider/errors.rs @@ -122,6 +122,9 @@ pub enum RemoteAccountProviderError { "Failed to update gRPC subscription to {0} after {1} retries: {2}" )] GrpcSubscriptionUpdateFailed(String, usize, String), + + #[error("Photon indexer error: {0}")] + PhotonIndexerError(#[from] light_client::indexer::IndexerError), } impl From for RemoteAccountProviderError diff --git a/magicblock-chainlink/src/remote_account_provider/mod.rs b/magicblock-chainlink/src/remote_account_provider/mod.rs index 0dbdf9559..0395ec1a5 100644 --- a/magicblock-chainlink/src/remote_account_provider/mod.rs +++ b/magicblock-chainlink/src/remote_account_provider/mod.rs @@ -54,6 +54,7 @@ pub mod config; pub mod endpoint; pub mod errors; mod lru_cache; +pub mod photon_client; pub mod program_account; pub mod pubsub_common; pub mod pubsub_connection; @@ -65,14 +66,17 @@ mod subscription_reconciler; mod tests; pub use endpoint::{Endpoint, Endpoints}; -use magicblock_metrics::{ - metrics, - metrics::{ - inc_account_fetches_failed, inc_account_fetches_found, - inc_account_fetches_not_found, inc_account_fetches_success, - inc_per_program_account_fetch_stats, set_monitored_accounts_count, - AccountFetchOrigin, ProgramFetchResult, - }, +use magicblock_metrics::metrics::{ + self, inc_account_fetches_found, inc_account_fetches_not_found, + inc_account_fetches_success, inc_compressed_account_fetches_found, + inc_compressed_account_fetches_not_found, + inc_compressed_account_fetches_success, + inc_per_program_account_fetch_stats, set_monitored_accounts_count, + AccountFetchOrigin, ProgramFetchResult, +}; +use remote_account::{ + is_synthetic_mark_empty_fresh, + should_prefer_rpc_over_photon_compressed_shell, }; pub use remote_account::{ResolvedAccount, ResolvedAccountSharedData}; @@ -80,7 +84,9 @@ use crate::{ errors::ChainlinkResult, remote_account_provider::{ chain_updates_client::ChainUpdatesClient, + photon_client::{PhotonClient, PhotonClientImpl}, pubsub_common::SubscriptionUpdate, + remote_account::FetchedRemoteAccounts, }, submux::SubMuxClient, }; @@ -88,6 +94,10 @@ use crate::{ const ACTIVE_SUBSCRIPTIONS_UPDATE_INTERVAL_MS: u64 = 60_000; pub(crate) const DEFAULT_SUBSCRIPTION_RETRIES: usize = 5; +fn install_default_rustls_crypto_provider() { + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); +} + type ChainUpdatesPubsub = (Arc, mpsc::Receiver<()>); async fn connect_pubsub_client( @@ -370,13 +380,19 @@ const RPC_FETCH_MAX_RETRIES: u64 = 3; const RPC_FETCH_RETRY_DELAY: Duration = Duration::from_millis(400); const RPC_FETCH_TIMEOUT: Duration = Duration::from_secs(5); const MATCH_SLOTS_MAX_TOTAL_TIME: Duration = Duration::from_secs(10); -pub struct RemoteAccountProvider { +pub struct RemoteAccountProvider< + T: ChainRpcClient, + U: ChainPubsubClient, + P: PhotonClient, +> { /// The RPC client to fetch accounts from chain the first time we receive /// a request for them rpc_client: T, /// The pubsub client to listen for updates on chain and keep the account /// states up to date pubsub_client: U, + /// The photon client to fetch compressed accounts from + photon_client: Option

, /// Minimal tracking of accounts currently being fetched to handle race conditions /// between fetch and subscription updates. Only used during active fetch operations. fetching_accounts: Arc, @@ -487,7 +503,11 @@ fn match_slots_retry_delay(config: &MatchSlotsConfig) -> Duration { } impl - RemoteAccountProvider> + RemoteAccountProvider< + ChainRpcClientImpl, + SubMuxClient, + PhotonClientImpl, + > { pub async fn try_from_urls_and_config( endpoints: &Endpoints, @@ -499,6 +519,7 @@ impl RemoteAccountProvider< ChainRpcClientImpl, SubMuxClient, + PhotonClientImpl, >, >, > { @@ -508,6 +529,7 @@ impl let provider = RemoteAccountProvider::< ChainRpcClientImpl, SubMuxClient, + PhotonClientImpl, >::try_new_from_endpoints( endpoints, commitment, @@ -522,7 +544,9 @@ impl } } -impl RemoteAccountProvider { +impl + RemoteAccountProvider +{ fn next_fetching_account_generation(&self) -> FetchingAccountGeneration { self.next_fetching_account_generation .fetch_add(1, Ordering::Relaxed) @@ -532,17 +556,19 @@ impl RemoteAccountProvider { pub async fn try_from_clients_and_mode( rpc_client: T, pubsub_client: U, + photon_client: Option

, subscription_forwarder: mpsc::Sender, config: &RemoteAccountProviderConfig, lrucache_subscribed_accounts: Arc, chain_slot: Arc, - ) -> ChainlinkResult>> { + ) -> ChainlinkResult>> { let chain_slot = ChainSlot::new(chain_slot); if config.lifecycle_mode().needs_remote_account_provider() { Ok(Some( Self::new( rpc_client, pubsub_client, + photon_client, subscription_forwarder, config, lrucache_subscribed_accounts, @@ -590,11 +616,14 @@ impl RemoteAccountProvider { pub(crate) async fn new( rpc_client: T, pubsub_client: U, + photon_client: Option

, subscription_forwarder: mpsc::Sender, config: &RemoteAccountProviderConfig, lrucache_subscribed_accounts: Arc, chain_slot: ChainSlot, ) -> RemoteAccountProviderResult { + install_default_rustls_crypto_provider(); + let (removed_account_tx, removed_account_rx) = tokio::sync::mpsc::channel(100); @@ -617,6 +646,7 @@ impl RemoteAccountProvider { subscription_key_locks: Arc::new(AsyncMutex::new(HashMap::new())), rpc_client, pubsub_client, + photon_client, chain_slot, last_update_slot: Arc::::default(), received_updates_count: Arc::::default(), @@ -655,8 +685,11 @@ impl RemoteAccountProvider { RemoteAccountProvider< ChainRpcClientImpl, SubMuxClient, + PhotonClientImpl, >, > { + install_default_rustls_crypto_provider(); + if endpoints.is_empty() { return Err( RemoteAccountProviderError::AccountSubscriptionsTaskFailed( @@ -674,6 +707,9 @@ impl RemoteAccountProvider { let rpc_client = ChainRpcClientImpl::new_from_url(rpc_url.as_str(), commitment); + let photon_client = + endpoints.photon_url().map(PhotonClientImpl::new_from_url); + // Create chain_slot to be shared with all pubsub clients let chain_slot = Arc::::default(); @@ -697,6 +733,7 @@ impl RemoteAccountProvider { deferred_pubsubs, commitment, rpc_client.clone(), + photon_client.clone(), chain_slot.clone(), subscription_forwarder.clone(), config, @@ -732,6 +769,7 @@ impl RemoteAccountProvider { Vec::new(), commitment, rpc_client, + photon_client, chain_slot, subscription_forwarder, config, @@ -742,11 +780,13 @@ impl RemoteAccountProvider { } } + #[allow(clippy::too_many_arguments)] async fn try_new_from_pubsubs( startup_pubsubs: Vec, mut deferred_pubsubs: Vec, commitment: CommitmentConfig, rpc_client: ChainRpcClientImpl, + photon_client: Option, chain_slot: Arc, subscription_forwarder: mpsc::Sender, config: &RemoteAccountProviderConfig, @@ -754,6 +794,7 @@ impl RemoteAccountProvider { RemoteAccountProvider< ChainRpcClientImpl, SubMuxClient, + PhotonClientImpl, >, Vec, )> { @@ -818,9 +859,11 @@ impl RemoteAccountProvider { let provider = RemoteAccountProvider::< ChainRpcClientImpl, SubMuxClient, + PhotonClientImpl, >::new( rpc_client, submux, + photon_client, subscription_forwarder, config, subscribed_accounts, @@ -1881,13 +1924,6 @@ impl RemoteAccountProvider { Ok(()) } - /// Tries to fetch the given accounts from RPC. - /// NOTE: if we get an RPC error we just log it and give up since there is no - /// obvious way how to handle this even if we were to bubble the error up. - /// Any action that depends on those accounts to be there will fail. - /// NOTE: this is not used during subscription updates since we receive the data - /// as part of that update, thus we won't have stale data issues. - #[allow(clippy::too_many_arguments)] fn fetch( &self, pubkeys: Vec, @@ -1898,39 +1934,81 @@ impl RemoteAccountProvider { program_ids: Option<&[Pubkey]>, ) { let rpc_client = self.rpc_client.clone(); + let photon_client = self.photon_client.clone(); let fetching_accounts = self.fetching_accounts.clone(); - let commitment = self.rpc_client.commitment(); let mark_empty_if_not_found = mark_empty_if_not_found.unwrap_or(&[]).to_vec(); let program_ids = program_ids.map(|ids| ids.to_vec()); tokio::spawn(async move { - use RemoteAccount::*; - - let fetch_started_at = std::time::Instant::now(); - // Helper to notify all pending requests of fetch failure - let notify_error = |error_msg: &str| { - let mut fetching = fetching_accounts.lock().unwrap(); - warn!( - pubkey_count = pubkeys.len(), - pubkeys = %pubkeys_str(&pubkeys), - min_context_slot = min_context_slot, - commitment = ?commitment, - fetch_origin = %fetch_origin, - elapsed_ms = fetch_started_at.elapsed().as_millis() as u64, - error = %error_msg, - "{error_msg}" + let results = if let Some(photon_client) = photon_client { + let (rpc_accounts, photon_accounts) = tokio::join!( + Self::fetch_from_rpc( + rpc_client, + pubkeys.clone(), + &mark_empty_if_not_found, + min_context_slot, + fetch_origin, + ), + Self::fetch_from_photon( + photon_client, + pubkeys.clone(), + &mark_empty_if_not_found, + min_context_slot, + ) ); - inc_account_fetches_failed(pubkeys.len() as u64); - if let Some(program_ids) = &program_ids { - for program_id in program_ids { - inc_per_program_account_fetch_stats( - &program_id.to_string(), - ProgramFetchResult::Failed, - pubkeys.len() as u64, - ); + trace!(rpc_accounts = ?rpc_accounts, photon_accounts = ?photon_accounts, "Fetched accounts from RPC and Photon"); + vec![rpc_accounts, photon_accounts] + } else { + let rpc_accounts = Self::fetch_from_rpc( + rpc_client, + pubkeys.clone(), + &mark_empty_if_not_found, + min_context_slot, + fetch_origin, + ) + .await; + trace!(rpc_accounts = ?rpc_accounts, "Fetched accounts from RPC"); + vec![rpc_accounts] + }; + + let mut remote_accounts_results = Vec::with_capacity(2); + let mut rpc_fetch_success = false; + let mut found_cnt = 0; + let mut not_found_cnt = 0; + let mut compressed_found_count = 0; + let mut compressed_not_found_count = 0; + let mut fetch_errors = vec![]; + + for result in results { + match result { + Ok((FetchedRemoteAccounts::Rpc(accs), fc, nfc)) => { + rpc_fetch_success = true; + remote_accounts_results + .push(FetchedRemoteAccounts::Rpc(accs)); + found_cnt += fc; + not_found_cnt += nfc; + } + Ok((FetchedRemoteAccounts::Compressed(accs), fc, nfc)) => { + remote_accounts_results + .push(FetchedRemoteAccounts::Compressed(accs)); + compressed_found_count += fc; + compressed_not_found_count += nfc; + } + Err(err) => { + error!("Failed to fetch accounts: {err:?}"); + fetch_errors.push(err.to_string()); } } + } + if !fetch_errors.is_empty() { + let msg = format!( + "failed to fetch accounts: {}", + fetch_errors.join(", ") + ); + let mut fetching = fetching_accounts + .lock() + .unwrap_or_else(|poisoned| poisoned.into_inner()); for pubkey in &pubkeys { // Update metrics // Remove pending requests and send error @@ -1944,72 +2022,220 @@ impl RemoteAccountProvider { { for sender in state.waiters { let error = RemoteAccountProviderError::AccountResolutionsFailed( - format!("{}: {}", pubkey, error_msg) + format!("{}: {}", pubkey, msg) ); let _ = sender.send(Err(error)); } } } } - }; + return Err( + RemoteAccountProviderError::AccountResolutionsFailed(msg), + ); + } + + let remote_accounts = Self::consolidate_fetched_remote_accounts( + &pubkeys, + remote_accounts_results, + ); + + if remote_accounts.len() != pubkeys.len() { + let msg = format!( + "resolved {} of {} accounts after fetch", + remote_accounts.len(), + pubkeys.len() + ); + let mut fetching = fetching_accounts + .lock() + .unwrap_or_else(|poisoned| poisoned.into_inner()); + for pubkey in &pubkeys { + if let Some(generation) = generations.get(pubkey).copied() { + if let Some(state) = + remove_fetching_account_if_generation_matches( + &mut fetching, + pubkey, + generation, + ) + { + for request in state.waiters { + let _ = request.send(Err( + RemoteAccountProviderError::AccountResolutionsFailed(msg.clone()) + )); + } + } + } + } + return Err( + RemoteAccountProviderError::AccountResolutionsFailed(msg), + ); + } + + // Update metrics for successful RPC fetch + if rpc_fetch_success { + inc_account_fetches_success(pubkeys.len() as u64); + inc_account_fetches_found(fetch_origin, found_cnt); + inc_account_fetches_not_found(fetch_origin, not_found_cnt); + } + + let compressed_total = + compressed_found_count + compressed_not_found_count; + if compressed_total > 0 { + // Update metrics for successful compressed fetch + inc_compressed_account_fetches_success(pubkeys.len() as u64); + inc_compressed_account_fetches_found( + fetch_origin, + compressed_found_count, + ); + inc_compressed_account_fetches_not_found( + fetch_origin, + compressed_not_found_count, + ); + } - let mut remaining_retries: u64 = RPC_FETCH_MAX_RETRIES; + // Record per-program metrics if programs were provided + if let Some(program_ids) = &program_ids { + for program_id in program_ids { + if found_cnt > 0 { + inc_per_program_account_fetch_stats( + &program_id.to_string(), + ProgramFetchResult::Found, + found_cnt, + ); + } + if not_found_cnt > 0 { + inc_per_program_account_fetch_stats( + &program_id.to_string(), + ProgramFetchResult::NotFound, + not_found_cnt, + ); + } + } + } if tracing::enabled!(tracing::Level::TRACE) { - trace!(pubkeys = pubkeys_str(&pubkeys), "Fetching accounts"); + trace!( + pubkeys = pubkeys_str(&pubkeys), + remote_accounts = %format!("{:?}", remote_accounts), + "Fetched accounts, notifying pending requests", + ); + } + + // Notify all pending requests with fetch results (unless subscription override occurred) + for (pubkey, remote_account) in + pubkeys.iter().zip(remote_accounts.iter()) + { + let waiters = { + let mut fetching = fetching_accounts.lock().unwrap(); + // Remove from fetching and get pending requests + // Note: the account might have been resolved by a + // subscription update already or replaced by a newer owner. + let Some(generation) = generations.get(pubkey).copied() + else { + continue; + }; + if let Some(state) = + remove_fetching_account_if_generation_matches( + &mut fetching, + pubkey, + generation, + ) + { + state.waiters + } else { + // Account was already resolved or replaced, skip. + if tracing::enabled!(tracing::Level::TRACE) { + trace!( + pubkey = %pubkey, + generation = generation, + "Account was already resolved or replaced" + ); + } + continue; + } + }; + + // Send the fetch result to all waiting requests + for request in waiters { + let _ = request.send(Ok(remote_account.clone())); + } } + Ok::<(), RemoteAccountProviderError>(()) + }); + } + + /// Tries to fetch the given accounts from RPC. + /// NOTE: if we get an RPC error we just log it and give up since there is no + /// obvious way how to handle this even if we were to bubble the error up. + /// Any action that depends on those accounts to be there will fail. + /// NOTE: this is not used during subscription updates since we receive the data + /// as part of that update, thus we won't have stale data issues. + async fn fetch_from_rpc( + rpc_client: T, + pubkeys: Vec, + mark_empty_if_not_found: &[Pubkey], + min_context_slot: u64, + fetch_origin: AccountFetchOrigin, + ) -> ChainlinkResult<(FetchedRemoteAccounts, u64, u64)> { + let fetch_started_at = std::time::Instant::now(); + let commitment = rpc_client.commitment(); + let mut remaining_retries: u64 = RPC_FETCH_MAX_RETRIES; - macro_rules! retry { + if tracing::enabled!(tracing::Level::TRACE) { + trace!(pubkeys = pubkeys_str(&pubkeys), "Fetching accounts"); + } + + macro_rules! retry { ($msg:expr) => {{ trace!($msg); remaining_retries -= 1; if remaining_retries <= 0 { let err_msg = format!("Max retries {RPC_FETCH_MAX_RETRIES} reached, giving up on fetching accounts: {pubkeys:?}"); - notify_error(&err_msg); - return; + return Err(RemoteAccountProviderError::AccountResolutionsFailed( + err_msg + ).into()); } tokio::time::sleep(RPC_FETCH_RETRY_DELAY).await; continue; }}; } - let response = loop { - // We provide the min_context slot in order to _force_ the RPC to update - // its account cache. Otherwise we could just keep fetching the accounts - // until the context slot is high enough. - metrics::inc_remote_account_provider_a_count(); - match tokio::time::timeout(RPC_FETCH_TIMEOUT, async { - let config = RpcAccountInfoConfig { - commitment: Some(commitment), - min_context_slot: Some(min_context_slot), - encoding: Some(UiAccountEncoding::Base64Zstd), - data_slice: None, - }; + let response = loop { + // We provide the min_context slot in order to _force_ the RPC to update + // its account cache. Otherwise we could just keep fetching the accounts + // until the context slot is high enough. + metrics::inc_remote_account_provider_a_count(); + match tokio::time::timeout(RPC_FETCH_TIMEOUT, async { + let config = RpcAccountInfoConfig { + commitment: Some(commitment), + min_context_slot: Some(min_context_slot), + encoding: Some(UiAccountEncoding::Base64Zstd), + data_slice: None, + }; - if pubkeys.len() == 1 { - rpc_client - .get_account_with_config(&pubkeys[0], config) - .await - .map(|res| (res.context.slot, vec![res.value])) + if pubkeys.len() == 1 { + rpc_client + .get_account_with_config(&pubkeys[0], config) + .await + .map(|res| (res.context.slot, vec![res.value])) + } else { + rpc_client + .get_multiple_accounts_with_config(&pubkeys, config) + .await + .map(|res| (res.context.slot, res.value)) + } + }) + .await + { + Ok(Ok(res)) => { + let (slot, value) = res; + if slot < min_context_slot { + retry!("Response slot {slot} < {min_context_slot}. Retrying..."); } else { - rpc_client - .get_multiple_accounts_with_config(&pubkeys, config) - .await - .map(|res| (res.context.slot, res.value)) - } - }) - .await - { - Ok(Ok(res)) => { - let (slot, value) = res; - if slot < min_context_slot { - retry!("Response slot {slot} < {min_context_slot}. Retrying..."); - } else { - break (slot, value); - } + break (slot, value); } - Ok(Err(err)) => match *err.kind { - ErrorKind::RpcError(rpc_err) => { - match rpc_err { + } + Ok(Err(err)) => match *err.kind { + ErrorKind::RpcError(rpc_err) => { + match rpc_err { RpcError::ForUser(ref rpc_user_err) => { // When an account is not present for the desired // min-context slot then we normally get the below @@ -2027,7 +2253,7 @@ impl RemoteAccountProvider { // ) // ``` retry!("Fetching accounts failed: {rpc_user_err:?}"); - } + } RpcError::RpcResponseError { code, message, @@ -2044,179 +2270,297 @@ impl RemoteAccountProvider { let err_msg = format!( "RpcError fetching accounts {}: {err:?}", pubkeys_str(&pubkeys) ); - notify_error(&err_msg); - return; + return Err(RemoteAccountProviderError::AccountResolutionsFailed( + err_msg + ).into()); } } err => { let err_msg = format!( "RpcError fetching accounts {}: {err:?}", pubkeys_str(&pubkeys) ); - notify_error(&err_msg); - return; + return Err(RemoteAccountProviderError::AccountResolutionsFailed( + err_msg + ).into()); } } - } - ErrorKind::Custom(message) - if message - .to_ascii_lowercase() - .contains("minimum context slot") => - { - retry!( + } + ErrorKind::Custom(message) + if message + .to_ascii_lowercase() + .contains("minimum context slot") => + { + retry!( "Minimum context slot {min_context_slot} not reached for {commitment:?}: {message}" ); - } - _ => { - let err_msg = format!( - "RpcError fetching accounts {}: {err:?}", - pubkeys_str(&pubkeys) - ); - notify_error(&err_msg); - return; - } - }, - Err(_) => { - let attempt = - RPC_FETCH_MAX_RETRIES - remaining_retries + 1; - warn!( - pubkey_count = pubkeys.len(), - pubkeys = %pubkeys_str(&pubkeys), - attempt = attempt, - max_retries = RPC_FETCH_MAX_RETRIES, - remaining_retries = remaining_retries.saturating_sub(1), - timeout_ms = RPC_FETCH_TIMEOUT.as_millis() as u64, - elapsed_ms = fetch_started_at.elapsed().as_millis() as u64, - min_context_slot = min_context_slot, - commitment = ?commitment, - fetch_origin = %fetch_origin, - "RPC call timeout. Retrying..." + } + _ => { + let err_msg = format!( + "RpcError fetching accounts {}: {err:?}", + pubkeys_str(&pubkeys) ); - remaining_retries -= 1; - if remaining_retries == 0 { - let err_msg = format!("Max retries {RPC_FETCH_MAX_RETRIES} reached, giving up on fetching accounts: {pubkeys:?}"); - notify_error(&err_msg); - return; - } - tokio::time::sleep(RPC_FETCH_RETRY_DELAY).await; - continue; + return Err(RemoteAccountProviderError::AccountResolutionsFailed( + err_msg + ).into()); } - }; + }, + Err(_) => { + let attempt = RPC_FETCH_MAX_RETRIES - remaining_retries + 1; + warn!( + pubkey_count = pubkeys.len(), + pubkeys = %pubkeys_str(&pubkeys), + attempt = attempt, + max_retries = RPC_FETCH_MAX_RETRIES, + remaining_retries = remaining_retries.saturating_sub(1), + timeout_ms = RPC_FETCH_TIMEOUT.as_millis() as u64, + elapsed_ms = fetch_started_at.elapsed().as_millis() as u64, + min_context_slot = min_context_slot, + commitment = ?commitment, + fetch_origin = %fetch_origin, + "RPC call timeout. Retrying..." + ); + remaining_retries -= 1; + if remaining_retries == 0 { + let err_msg = format!("Max retries {RPC_FETCH_MAX_RETRIES} reached, giving up on fetching accounts: {pubkeys:?}"); + return Err(RemoteAccountProviderError::AccountResolutionsFailed( + err_msg + ).into()); + } + tokio::time::sleep(RPC_FETCH_RETRY_DELAY).await; + continue; + } }; + }; - // TODO: should we retry if not or respond with an error? - let (response_slot, response_value) = response; - assert!(response_slot >= min_context_slot); + // TODO: should we retry if not or respond with an error? + let (response_slot, response_value) = response; + assert!(response_slot >= min_context_slot); - let mut found_count = 0u64; - let mut not_found_count = 0u64; + let mut found_count = 0u64; + let mut not_found_count = 0u64; - let remote_accounts: Vec = pubkeys - .iter() - .zip(response_value) - .map(|(pubkey, acc)| match acc { - Some(value) => { - found_count += 1; - RemoteAccount::from_fresh_account( - value, - response_slot, - RemoteAccountUpdateSource::Fetch, - ) - } - None if mark_empty_if_not_found.contains(pubkey) => { - not_found_count += 1; - RemoteAccount::from_fresh_account( - Account { - lamports: 0, - data: vec![], - owner: Pubkey::default(), - executable: false, - rent_epoch: 0, - }, - response_slot, - RemoteAccountUpdateSource::Fetch, - ) - } - None => { - not_found_count += 1; - NotFound(response_slot) - } - }) - .collect(); + let remote_accounts: Vec = pubkeys + .iter() + .zip(response_value) + .map(|(pubkey, acc)| match acc { + Some(value) => { + found_count += 1; + RemoteAccount::from_fresh_account( + value, + response_slot, + RemoteAccountUpdateSource::Fetch, + ) + } + None if mark_empty_if_not_found.contains(pubkey) => { + not_found_count += 1; + RemoteAccount::from_fresh_account( + Account { + lamports: 0, + data: vec![], + owner: Pubkey::default(), + executable: false, + rent_epoch: 0, + }, + response_slot, + RemoteAccountUpdateSource::Fetch, + ) + } + None => { + not_found_count += 1; + RemoteAccount::NotFound(response_slot) + } + }) + .collect(); - // Update metrics for successful RPC fetch - inc_account_fetches_success(pubkeys.len() as u64); - inc_account_fetches_found(fetch_origin, found_count); - inc_account_fetches_not_found(fetch_origin, not_found_count); + Ok(( + FetchedRemoteAccounts::Rpc(remote_accounts), + found_count, + not_found_count, + )) + } - // Record per-program metrics if programs were provided - if let Some(program_ids) = &program_ids { - for program_id in program_ids { - if found_count > 0 { - inc_per_program_account_fetch_stats( - &program_id.to_string(), - ProgramFetchResult::Found, - found_count, - ); + async fn fetch_from_photon( + photon_client: P, + pubkeys: Vec, + mark_empty_if_not_found: &[Pubkey], + min_context_slot: u64, + ) -> ChainlinkResult<(FetchedRemoteAccounts, u64, u64)> { + if tracing::enabled!(tracing::Level::TRACE) { + trace!( + pubkeys = pubkeys_str(&pubkeys), + "Fetching accounts from photon" + ); + } + + // The photon client already handles the retry logic + let response = if pubkeys.len() == 1 { + match photon_client + .get_account(&pubkeys[0], Some(min_context_slot)) + .await? + { + Some((acc, slot)) => (slot, vec![Some(acc)]), + None => (min_context_slot, vec![None]), + } + } else { + photon_client + .get_multiple_accounts(&pubkeys, Some(min_context_slot)) + .await + .map(|(accs, slot)| (slot, accs))? + }; + + // TODO: should we retry if not or respond with an error? + let (response_slot, response_value) = response; + assert!(response_slot >= min_context_slot); + + let mut found_count = 0u64; + let mut not_found_count = 0u64; + + let remote_accounts: Vec = pubkeys + .iter() + .zip(response_value) + .map(|(pubkey, acc)| match acc { + Some(value) => { + found_count += 1; + RemoteAccount::from_fresh_account( + value, + response_slot, + RemoteAccountUpdateSource::Compressed, + ) + } + None if mark_empty_if_not_found.contains(pubkey) => { + not_found_count += 1; + RemoteAccount::from_fresh_account( + Account { + lamports: 0, + data: vec![], + owner: Pubkey::default(), + executable: false, + rent_epoch: 0, + }, + response_slot, + RemoteAccountUpdateSource::Compressed, + ) + } + None => { + not_found_count += 1; + RemoteAccount::NotFound(response_slot) + } + }) + .collect(); + + Ok(( + FetchedRemoteAccounts::Compressed(remote_accounts), + found_count, + not_found_count, + )) + } + + fn consolidate_fetched_remote_accounts( + pubkeys: &[Pubkey], + remote_accounts_results: Vec, + ) -> Vec { + const STALE_SLOT_THRESHOLD: u64 = 100; + let (rpc_accounts, compressed_accounts) = { + if remote_accounts_results.is_empty() { + return vec![]; + } + if remote_accounts_results.len() == 1 { + match &remote_accounts_results[0] { + FetchedRemoteAccounts::Rpc(rpc_accounts) => { + return rpc_accounts.clone(); } - if not_found_count > 0 { - inc_per_program_account_fetch_stats( - &program_id.to_string(), - ProgramFetchResult::NotFound, - not_found_count, - ); + FetchedRemoteAccounts::Compressed(compressed_accounts) => { + return compressed_accounts.clone(); } } } - - if tracing::enabled!(tracing::Level::TRACE) { - let pubkeys = pubkeys - .iter() - .map(|pk| pk.to_string()) - .collect::>() - .join(", "); - trace!( - pubkeys = %pubkeys, remote_accounts = ?remote_accounts, "Fetched, notifying pending requests" - ); - } - - // Notify all pending requests with fetch results (unless subscription override occurred) - for (pubkey, remote_account) in - pubkeys.iter().zip(remote_accounts.iter()) - { - let waiters = { - let mut fetching = fetching_accounts.lock().unwrap(); - // Remove from fetching and get pending requests - // Note: the account might have been resolved by a - // subscription update already or replaced by a newer owner. - let Some(generation) = generations.get(pubkey).copied() - else { - continue; - }; - if let Some(state) = - remove_fetching_account_if_generation_matches( - &mut fetching, - pubkey, - generation, - ) - { - state.waiters - } else { - // Account was already resolved or replaced, skip. - if tracing::enabled!(tracing::Level::TRACE) { - trace!( - "Account {pubkey} generation {generation} was already resolved or replaced" - ); + if remote_accounts_results.len() == 2 { + let mut rpc_accounts = None; + let mut compressed_accounts = None; + for res in remote_accounts_results { + match res { + FetchedRemoteAccounts::Rpc(rpc_accs) => { + rpc_accounts.replace(rpc_accs); + } + FetchedRemoteAccounts::Compressed(comp_accs) => { + compressed_accounts.replace(comp_accs); } - continue; } - }; - - // Send the fetch result to all waiting requests - for request in waiters { - let _ = request.send(Ok(remote_account.clone())); } + (rpc_accounts.unwrap_or_default(), compressed_accounts) + } else { + error!("BUG: More than 2 fetch results found"); + return vec![]; + } + }; + + debug_assert_eq!(rpc_accounts.len(), pubkeys.len()); + debug_assert!(compressed_accounts + .as_ref() + .is_none_or(|comp_accs| comp_accs.len() == pubkeys.len())); + + let all_lens_match = pubkeys.len() == rpc_accounts.len() + && pubkeys.len() + == compressed_accounts + .as_ref() + .map_or(rpc_accounts.len(), |comp_accs| comp_accs.len()); + if !all_lens_match { + error!("BUG: Fetched accounts length mismatch: pubkeys {}, rpc {}, compressed {:?}", + pubkeys.len(), rpc_accounts.len(), + compressed_accounts.as_ref().map(|c| c.len())); + return rpc_accounts; + } + + use RemoteAccount::*; + match compressed_accounts { + Some(compressed_accounts) => + pubkeys.iter().zip( + rpc_accounts + .into_iter() + .zip(compressed_accounts)) + .map(|(pubkey, (rpc_acc, comp_acc))| match (rpc_acc, comp_acc) { + (Found(rpc_state), Found(comp_state)) => { + if is_synthetic_mark_empty_fresh(&rpc_state.account) + && is_synthetic_mark_empty_fresh( + &comp_state.account, + ) + { + // Both sides materialized the same not-found + + // `mark_empty_if_not_found` placeholder. Prefer + // the RPC `Fresh` (not marked compressed) so + // classification and cloning do not run empty + // data through the compressed delegation path. + Found(rpc_state) + } else if should_prefer_rpc_over_photon_compressed_shell( + &rpc_state, + &comp_state, + ) { + trace!( + pubkey = %pubkey, + "Photon compressed account has no payload; using RPC ledger account" + ); + Found(rpc_state) + } else { + debug!("Both RPC and Compressed account found for pubkey {}. Using Compressed account.", pubkey); + if rpc_state.account.slot() > comp_state.account.slot() + STALE_SLOT_THRESHOLD { + warn!("Compressed account is stale. rpc_slot={}, comp_slot={}", rpc_state.account.slot(), comp_state.account.slot()); + } + Found(comp_state) + } + } + (Found(rpc_state), NotFound(_)) => Found(rpc_state), + (NotFound(_), Found(comp_state)) => Found(comp_state), + (NotFound(rpc_slot), NotFound(comp_slot)) => { + if rpc_slot >= comp_slot { + NotFound(rpc_slot) + } else { + NotFound(comp_slot) + } + } + }) + .collect(), + None => rpc_accounts, } - }); } } @@ -2233,7 +2577,13 @@ fn remove_fetching_account_if_generation_matches( } } -impl RemoteAccountProvider { +impl + RemoteAccountProvider< + ChainRpcClientImpl, + ChainPubsubClientImpl, + PhotonClientImpl, + > +{ #[cfg(any(test, feature = "dev-context"))] pub fn rpc_client(&self) -> &RpcClient { &self.rpc_client.rpc_client @@ -2244,6 +2594,7 @@ impl RemoteAccountProvider< ChainRpcClientImpl, SubMuxClient, + PhotonClientImpl, > { #[cfg(any(test, feature = "dev-context"))] @@ -2253,7 +2604,11 @@ impl } impl - RemoteAccountProvider> + RemoteAccountProvider< + ChainRpcClientImpl, + SubMuxClient, + PhotonClientImpl, + > { #[cfg(any(test, feature = "dev-context"))] pub fn rpc_client(&self) -> &RpcClient { diff --git a/magicblock-chainlink/src/remote_account_provider/photon_client.rs b/magicblock-chainlink/src/remote_account_provider/photon_client.rs new file mode 100644 index 000000000..a91093d16 --- /dev/null +++ b/magicblock-chainlink/src/remote_account_provider/photon_client.rs @@ -0,0 +1,137 @@ +use std::{ops::Deref, sync::Arc}; + +use async_trait::async_trait; +use light_client::indexer::{ + photon_indexer::PhotonIndexer, CompressedAccount, Context, Indexer, + IndexerRpcConfig, Response, +}; +use magicblock_core::compression::derive_cda_from_pda; +use solana_account::Account; +use solana_clock::Slot; +use solana_pubkey::Pubkey; +use thiserror::Error; +use tracing::*; + +#[derive(Debug, Clone, Error)] +pub enum PhotonClientError { + #[error("Indexer error: {0}")] + IndexerError(#[from] light_client::indexer::IndexerError), +} + +pub type PhotonClientResult = Result; + +#[async_trait] +pub trait PhotonClient: Send + Sync + Clone + 'static { + async fn get_account( + &self, + pubkey: &Pubkey, + min_context_slot: Option, + ) -> PhotonClientResult>; + + async fn get_multiple_accounts( + &self, + pubkeys: &[Pubkey], + min_context_slot: Option, + ) -> PhotonClientResult<(Vec>, Slot)>; +} + +#[derive(Clone)] +pub struct PhotonClientImpl(Arc); + +impl Deref for PhotonClientImpl { + type Target = Arc; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl PhotonClientImpl { + pub fn new(photon_indexer: Arc) -> Self { + Self(photon_indexer) + } + pub fn new_from_url(url: String) -> Self { + Self::new(Arc::new(PhotonIndexer::new(url))) + } +} + +#[async_trait] +impl PhotonClient for PhotonClientImpl { + async fn get_account( + &self, + pubkey: &Pubkey, + min_context_slot: Option, + ) -> PhotonClientResult> { + let config = min_context_slot.map(|slot| IndexerRpcConfig { + slot, + ..Default::default() + }); + let cda = derive_cda_from_pda(pubkey); + let Response { + value: compressed_acc, + context: Context { slot, .. }, + } = self.get_compressed_account(cda.to_bytes(), config).await?; + let account = account_from_compressed_account(compressed_acc); + Ok(account.map(|acc| (acc, slot))) + } + + async fn get_multiple_accounts( + &self, + pubkeys: &[Pubkey], + min_context_slot: Option, + ) -> PhotonClientResult<(Vec>, Slot)> { + let config = min_context_slot.map(|slot| IndexerRpcConfig { + slot, + ..Default::default() + }); + let cdas: Vec<_> = pubkeys + .iter() + .map(|pk| derive_cda_from_pda(pk).to_bytes()) + .collect(); + + if tracing::enabled!(tracing::Level::DEBUG) { + let pks_cdas = pubkeys + .iter() + .zip(cdas.iter()) + .map(|(pk, cda)| { + format!("({}: {})", pk, Pubkey::new_from_array(*cda)) + }) + .collect::>() + .join(", "); + debug!(cdas = %pks_cdas, "Fetching multiple accounts"); + } + + let Response { + value: compressed_accs, + context: Context { slot, .. }, + } = self + .get_multiple_compressed_accounts(Some(cdas), None, config) + .await?; + + let accounts = compressed_accs + .items + .into_iter() + .map(account_from_compressed_account) + .collect(); + Ok((accounts, slot)) + } +} + +// ----------------- +// Helpers +// ----------------- + +fn account_from_compressed_account( + compressed_acc: Option, +) -> Option { + let compressed_acc = compressed_acc?; + let data = compressed_acc.data?.data; + // NOTE: delegated compressed accounts are set to zero lamports when cloned + // Actual lamports have to be paid back when undelegating + Some(Account { + lamports: 0, + data, + owner: compressed_acc.owner.to_bytes().into(), + executable: false, + rent_epoch: 0, + }) +} diff --git a/magicblock-chainlink/src/remote_account_provider/remote_account.rs b/magicblock-chainlink/src/remote_account_provider/remote_account.rs index fd79aea26..d194bf500 100644 --- a/magicblock-chainlink/src/remote_account_provider/remote_account.rs +++ b/magicblock-chainlink/src/remote_account_provider/remote_account.rs @@ -9,6 +9,7 @@ use solana_pubkey::Pubkey; pub enum RemoteAccountUpdateSource { Fetch, Subscription, + Compressed, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -27,6 +28,25 @@ pub enum ResolvedAccount { Bank((Pubkey, Slot)), } +/// The placeholder produced when a pubkey is not on chain but the caller set +/// `mark_empty_if_not_found` (see [`super::RemoteAccountProvider::fetch_from_rpc`]). The same +/// structure is used for both RPC and Photon; if both are present, the merged result must not +/// always be treated as a compressed account or empty bytes may be run through +/// decompression. +pub(crate) fn is_synthetic_mark_empty_fresh( + resolved: &ResolvedAccount, +) -> bool { + match resolved { + ResolvedAccount::Fresh(acc) => { + acc.lamports() == 0 + && acc.data().is_empty() + && !acc.executable() + && *acc.owner() == Pubkey::default() + } + ResolvedAccount::Bank(_) => false, + } +} + impl ResolvedAccount { pub fn resolved_account_shared_data( &self, @@ -41,6 +61,13 @@ impl ResolvedAccount { .map(ResolvedAccountSharedData::Bank), } } + + pub fn slot(&self) -> u64 { + match self { + ResolvedAccount::Fresh(account) => account.remote_slot(), + ResolvedAccount::Bank((_, slot)) => *slot, + } + } } /// Same as [ResolvedAccount], but with the account data fetched from the bank. @@ -166,6 +193,10 @@ impl ResolvedAccountSharedData { Bank(account) => account.remote_slot(), } } + + pub fn compressed(&self) -> bool { + self.account_shared_data().compressed() + } } #[derive(Debug, Clone, PartialEq, Eq)] @@ -174,6 +205,28 @@ pub struct RemoteAccountState { pub source: RemoteAccountUpdateSource, } +/// Prefer RPC when Photon returns a compressed-account shell with no payload while RPC has +/// real ledger state. Empty account data cannot deserialize as a compressed delegation record; +/// without this, merge would pick Photon and the fetch cloner would drop the account. +pub(crate) fn should_prefer_rpc_over_photon_compressed_shell( + rpc: &RemoteAccountState, + photon: &RemoteAccountState, +) -> bool { + if photon.source != RemoteAccountUpdateSource::Compressed { + return false; + } + let ResolvedAccount::Fresh(photon_acc) = &photon.account else { + return false; + }; + if !photon_acc.data().is_empty() { + return false; + } + let ResolvedAccount::Fresh(rpc_acc) = &rpc.account else { + return false; + }; + rpc_acc.lamports() > 0 || !rpc_acc.data().is_empty() +} + #[derive(Debug, Clone, PartialEq, Eq)] pub enum RemoteAccount { NotFound(Slot), @@ -188,6 +241,8 @@ impl RemoteAccount { ) -> Self { let mut account_shared_data = AccountSharedData::from(account); account_shared_data.set_remote_slot(slot); + account_shared_data + .set_compressed(source == RemoteAccountUpdateSource::Compressed); RemoteAccount::Found(RemoteAccountState { account: ResolvedAccount::Fresh(account_shared_data), source, @@ -265,3 +320,9 @@ impl RemoteAccount { self.owner().is_some_and(|owner| owner.eq(&dlp_api::id())) } } + +#[derive(Clone, Debug)] +pub enum FetchedRemoteAccounts { + Rpc(Vec), + Compressed(Vec), +} diff --git a/magicblock-chainlink/src/remote_account_provider/tests.rs b/magicblock-chainlink/src/remote_account_provider/tests.rs index 7d240afaa..52dd47212 100644 --- a/magicblock-chainlink/src/remote_account_provider/tests.rs +++ b/magicblock-chainlink/src/remote_account_provider/tests.rs @@ -15,6 +15,7 @@ use crate::{ }, testing::{ init_logger, + photon_client_mock::PhotonClientMock, rpc_client_mock::{ AccountAtSlot, ChainRpcClientMock, ChainRpcClientMockBuilder, }, @@ -23,8 +24,13 @@ use crate::{ }; struct ProviderTestCtx { - provider: - Arc>, + provider: Arc< + RemoteAccountProvider< + ChainRpcClientMock, + ChainPubsubClientMock, + PhotonClientMock, + >, + >, rpc_client: ChainRpcClientMock, _pubsub_client: ChainPubsubClientMock, _forward_rx: mpsc::Receiver, @@ -60,6 +66,7 @@ async fn setup_provider_with_lru_capacity( RemoteAccountProvider::new( rpc_client.clone(), pubsub_client.clone(), + None, forward_tx, &config, subscribed_accounts, @@ -88,7 +95,11 @@ async fn setup_matching_slots( pubkey1: Pubkey, pubkey2: Pubkey, ) -> ( - RemoteAccountProvider, + RemoteAccountProvider< + ChainRpcClientMock, + ChainPubsubClientMock, + PhotonClientMock, + >, mpsc::Receiver, ) { init_logger(); @@ -129,6 +140,7 @@ async fn setup_matching_slots( RemoteAccountProvider::new( rpc_client, pubsub_client, + None, forward_tx, &config, subscribed_accounts, @@ -860,6 +872,7 @@ async fn test_get_non_existing_account() { RemoteAccountProvider::new( rpc_client, pubsub_client, + None::, fwd_tx, &config, subscribed_accounts, @@ -911,6 +924,7 @@ async fn test_get_existing_account_for_valid_slot() { RemoteAccountProvider::new( rpc_client.clone(), pubsub_client, + None::, fwd_tx, &config, subscribed_accounts, @@ -1014,6 +1028,7 @@ async fn test_get_accounts_until_slots_match_refetches_mixed_sources_as_rpc_batc RemoteAccountProvider::new( rpc_client.clone(), pubsub_client.clone(), + None::, forward_tx, &config, subscribed_accounts, @@ -1227,7 +1242,11 @@ async fn setup_with_accounts( pubkeys: &[Pubkey], accounts_capacity: usize, ) -> ( - RemoteAccountProvider, + RemoteAccountProvider< + ChainRpcClientMock, + ChainPubsubClientMock, + PhotonClientMock, + >, mpsc::Receiver, mpsc::Receiver, ) { @@ -1259,6 +1278,7 @@ async fn setup_with_accounts( let provider = RemoteAccountProvider::new( rpc_client, pubsub_client, + None, forward_tx, &config, subscribed_accounts, diff --git a/magicblock-chainlink/src/testing/accounts.rs b/magicblock-chainlink/src/testing/accounts.rs index 88b19c991..3338c11f1 100644 --- a/magicblock-chainlink/src/testing/accounts.rs +++ b/magicblock-chainlink/src/testing/accounts.rs @@ -1,3 +1,4 @@ +use compressed_delegation_client::CompressedDelegationRecord; use solana_account::{Account, AccountSharedData, WritableAccount}; use solana_pubkey::Pubkey; @@ -34,3 +35,31 @@ pub fn delegated_account_shared_with_owner_and_slot( acc.set_remote_slot(remote_slot); acc } + +pub fn compressed_account_shared_with_owner_and_slot( + pda: Pubkey, + authority: Pubkey, + delegation_slot: u64, + account: Account, +) -> AccountSharedData { + let delegation_record_bytes = borsh::to_vec(&CompressedDelegationRecord { + pda, + authority, + last_update_nonce: 0, + is_undelegatable: false, + owner: account.owner, + delegation_slot, + lamports: account.lamports, + data: account.data, + }) + .unwrap(); + let mut acc = Account::new( + 0, + delegation_record_bytes.len(), + &compressed_delegation_client::ID, + ); + acc.data = delegation_record_bytes; + let mut acc = AccountSharedData::from(acc); + acc.set_remote_slot(delegation_slot); + acc +} diff --git a/magicblock-chainlink/src/testing/mod.rs b/magicblock-chainlink/src/testing/mod.rs index 4d5696938..e061ff190 100644 --- a/magicblock-chainlink/src/testing/mod.rs +++ b/magicblock-chainlink/src/testing/mod.rs @@ -9,6 +9,8 @@ pub mod deleg; #[cfg(any(test, feature = "dev-context"))] pub mod eatas; #[cfg(any(test, feature = "dev-context"))] +pub mod photon_client_mock; +#[cfg(any(test, feature = "dev-context"))] pub mod rpc_client_mock; #[cfg(any(test, feature = "dev-context"))] pub mod utils; diff --git a/magicblock-chainlink/src/testing/photon_client_mock.rs b/magicblock-chainlink/src/testing/photon_client_mock.rs new file mode 100644 index 000000000..0d7ba75f5 --- /dev/null +++ b/magicblock-chainlink/src/testing/photon_client_mock.rs @@ -0,0 +1,69 @@ +use std::{collections::HashMap, sync::Arc}; + +use magicblock_core::{compression::derive_cda_from_pda, Slot}; +use parking_lot::Mutex; +use solana_account::Account; +use solana_pubkey::Pubkey; +use tonic::async_trait; + +use crate::remote_account_provider::photon_client::{ + PhotonClient, PhotonClientResult, +}; + +#[derive(Clone, Default)] +pub struct PhotonClientMock { + accounts: Arc>>, +} + +impl PhotonClientMock { + pub fn add_account(&self, pubkey: Pubkey, account: Account, slot: Slot) { + let cda = derive_cda_from_pda(&pubkey); + self.accounts.lock().insert(cda, (account, slot)); + } + + pub fn remove_account(&self, pubkey: &Pubkey) { + let cda = derive_cda_from_pda(pubkey); + self.accounts.lock().remove(&cda); + } +} + +#[async_trait] +impl PhotonClient for PhotonClientMock { + async fn get_account( + &self, + pubkey: &Pubkey, + min_context_slot: Option, + ) -> PhotonClientResult> { + let cda = derive_cda_from_pda(pubkey); + if let Some((account, slot)) = self.accounts.lock().get(&cda) { + if let Some(min_slot) = min_context_slot { + if *slot < min_slot { + return Ok(None); + } + } + return Ok(Some((account.clone(), *slot))); + } + Ok(None) + } + + async fn get_multiple_accounts( + &self, + pubkeys: &[Pubkey], + min_context_slot: Option, + ) -> PhotonClientResult<(Vec>, Slot)> { + let mut accs = Vec::with_capacity(pubkeys.len()); + // Seed with min_context_slot if present to better approximate the + // "context slot" semantics of the real Photon client. + let mut slot = min_context_slot.unwrap_or(0); + for pubkey in pubkeys { + let account = self.get_account(pubkey, min_context_slot).await?; + if let Some((ref _acc, acc_slot)) = account { + if acc_slot > slot { + slot = acc_slot; + } + } + accs.push(account.map(|(acc, _)| acc)); + } + Ok((accs, slot)) + } +} diff --git a/magicblock-chainlink/src/testing/utils.rs b/magicblock-chainlink/src/testing/utils.rs index 4f1bc4503..a276829c6 100644 --- a/magicblock-chainlink/src/testing/utils.rs +++ b/magicblock-chainlink/src/testing/utils.rs @@ -18,6 +18,7 @@ use crate::{ pub const PUBSUB_URL: &str = "ws://localhost:7800"; pub const RPC_URL: &str = "http://localhost:7799"; +pub const COMPRESSION_URL: &str = "http://localhost:8784"; pub fn random_pubkey() -> Pubkey { Keypair::new().pubkey() diff --git a/magicblock-chainlink/tests/01_ensure-accounts.rs b/magicblock-chainlink/tests/01_ensure-accounts.rs index ada3afe24..754e583c7 100644 --- a/magicblock-chainlink/tests/01_ensure-accounts.rs +++ b/magicblock-chainlink/tests/01_ensure-accounts.rs @@ -1,11 +1,16 @@ use assert_matches::assert_matches; +use compressed_delegation_client::CompressedDelegationRecord; use dlp_api::pda::delegation_record_pda_from_delegated_account; use magicblock_chainlink::{ assert_cloned_as_delegated, assert_cloned_as_undelegated, assert_not_cloned, assert_not_found, assert_not_subscribed, assert_not_undelegating, assert_remain_undelegating, assert_subscribed_without_delegation_record, - testing::deleg::add_delegation_record_for, AccountFetchOrigin, + testing::{ + accounts::compressed_account_shared_with_owner_and_slot, + deleg::add_delegation_record_for, + }, + AccountFetchOrigin, }; use solana_account::{Account, AccountSharedData}; use solana_program::clock::Slot; @@ -357,3 +362,132 @@ async fn test_write_existing_account_invalid_delegation_record() { assert_not_subscribed!(chainlink, &[&deleg_record_pubkey, &pubkey]); } + +// ----------------- +// Compressed delegation record is initialized and delegated to us +// ----------------- +#[tokio::test] +async fn test_compressed_delegation_record_delegated() { + let TestContext { + chainlink, + photon_client, + cloner, + validator_pubkey, + .. + } = setup(CURRENT_SLOT).await; + + let pubkey = Pubkey::new_unique(); + let owner = Pubkey::new_unique(); + let account = Account::new(0, 0, &owner); + let compressed_account = compressed_account_shared_with_owner_and_slot( + pubkey, + validator_pubkey, + CURRENT_SLOT, + account, + ); + photon_client.add_account( + pubkey, + compressed_account.clone().into(), + CURRENT_SLOT, + ); + + let pubkeys = [pubkey]; + let res = chainlink + .ensure_accounts( + &pubkeys, + None, + AccountFetchOrigin::GetMultipleAccounts, + None, + ) + .await + .unwrap(); + debug!("res: {res:?}"); + + assert_cloned_as_delegated!(cloner, &pubkeys, CURRENT_SLOT, owner); + assert_not_subscribed!(chainlink, &[&pubkey]); +} + +// ----------------- +// Compressed delegation record is initialized and delegated to another authority +// ----------------- +#[tokio::test] +async fn test_compressed_delegation_record_delegated_to_other() { + let TestContext { + chainlink, + photon_client, + cloner, + .. + } = setup(CURRENT_SLOT).await; + + let pubkey = Pubkey::new_unique(); + let authority = Pubkey::new_unique(); + let owner = Pubkey::new_unique(); + let account = Account::new(0, 0, &owner); + let compressed_account = compressed_account_shared_with_owner_and_slot( + pubkey, + authority, + CURRENT_SLOT, + account, + ); + photon_client.add_account( + pubkey, + compressed_account.clone().into(), + CURRENT_SLOT, + ); + + let pubkeys = [pubkey]; + let res = chainlink + .ensure_accounts( + &pubkeys, + None, + AccountFetchOrigin::GetMultipleAccounts, + None, + ) + .await + .unwrap(); + debug!("res: {res:?}"); + + assert_cloned_as_undelegated!(cloner, &pubkeys, CURRENT_SLOT, owner); + assert_subscribed_without_delegation_record!(chainlink, &[&pubkey]); +} + +// ----------------- +// Compressed delegation record is initialized and empty (undelegated) +// ----------------- +#[tokio::test] +async fn test_compressed_account_undelegated() { + let TestContext { + chainlink, + photon_client, + rpc_client, + cloner, + .. + } = setup(CURRENT_SLOT).await; + + let pubkey = Pubkey::new_unique(); + rpc_client.add_account(pubkey, Account::default()); + photon_client.add_account( + pubkey, + Account { + data: borsh::to_vec(&CompressedDelegationRecord::default()) + .unwrap(), + ..Account::default() + }, + CURRENT_SLOT, + ); + + let pubkeys = [pubkey]; + let res = chainlink + .ensure_accounts( + &pubkeys, + None, + AccountFetchOrigin::GetMultipleAccounts, + None, + ) + .await + .unwrap(); + debug!("res: {res:?}"); + + assert_cloned_as_undelegated!(cloner, &pubkeys, CURRENT_SLOT); + assert_subscribed_without_delegation_record!(chainlink, &[&pubkey]); +} diff --git a/magicblock-chainlink/tests/03_deleg_after_sub.rs b/magicblock-chainlink/tests/03_deleg_after_sub.rs index 81baba293..7f58a2825 100644 --- a/magicblock-chainlink/tests/03_deleg_after_sub.rs +++ b/magicblock-chainlink/tests/03_deleg_after_sub.rs @@ -2,7 +2,10 @@ use magicblock_chainlink::{ assert_cloned_as_delegated, assert_cloned_as_undelegated, assert_not_cloned, assert_not_subscribed, assert_subscribed_without_delegation_record, - testing::{deleg::add_delegation_record_for, init_logger}, + testing::{ + accounts::compressed_account_shared_with_owner_and_slot, + deleg::add_delegation_record_for, init_logger, + }, AccountFetchOrigin, }; use solana_account::Account; @@ -119,3 +122,122 @@ async fn test_deleg_after_subscribe_case2() { assert_not_subscribed!(&chainlink, &[&pubkey, &delegation_record]); } } + +// NOTE: Flow "Account created then fetched, then delegated" +#[tokio::test] +async fn test_deleg_after_subscribe_case2_compressed() { + let mut slot: u64 = 11; + + let ctx = setup(slot).await; + let TestContext { + chainlink, + cloner, + rpc_client, + photon_client, + validator_pubkey, + .. + } = ctx.clone(); + + let pubkey = Pubkey::new_unique(); + let program_pubkey = Pubkey::new_unique(); + let acc = Account { + lamports: 1_000, + owner: program_pubkey, + ..Default::default() + }; + + // 1. Initially the account does not exist + // - readable: OK (non existing account) + // - writable: NO + { + info!("1. Initially the account does not exist"); + assert_not_cloned!(cloner, &[pubkey]); + + chainlink + .ensure_accounts( + &[pubkey], + None, + AccountFetchOrigin::GetMultipleAccounts, + None, + ) + .await + .unwrap(); + assert_not_cloned!(cloner, &[pubkey]); + } + + // 2. Account created with original owner + // + // Now we can ensure it as readonly and it will be cloned + // - readable: OK + // - writable: NO + { + info!("2. Create account owned by program {program_pubkey}"); + + slot = rpc_client.set_slot(slot + 11); + let acc = + account_shared_with_owner_and_slot(&acc, program_pubkey, slot); + + // When the account is created we do not receive any update since we do not sub to a non-existing account + let updated = ctx + .send_and_receive_account_update(pubkey, acc.clone(), Some(400)) + .await; + assert!(!updated); + + chainlink + .ensure_accounts( + &[pubkey], + None, + AccountFetchOrigin::GetMultipleAccounts, + None, + ) + .await + .unwrap(); + assert_cloned_as_undelegated!(cloner, &[pubkey], slot, program_pubkey); + assert_subscribed_without_delegation_record!(&chainlink, &[&pubkey]); + } + + // 3. Account delegated to us + // + // Delegate account to us and the sub update should be received + // even before the ensure_writable request + { + info!("3. Delegate account {pubkey} to us"); + + slot = rpc_client.set_slot(slot + 11); + let compressed_account = compressed_account_shared_with_owner_and_slot( + pubkey, + validator_pubkey, + slot, + acc, + ); + photon_client.add_account( + pubkey, + compressed_account.clone().into(), + slot, + ); + // Compressed accounts don't need the PDA to exist + rpc_client.remove_account(&pubkey); + let updated = ctx + .send_and_receive_account_update( + pubkey, + Account::default(), + Some(400), + ) + .await; + + // Needs to ensure accounts for compressed accounts + chainlink + .ensure_accounts( + &[pubkey], + None, + AccountFetchOrigin::GetMultipleAccounts, + None, + ) + .await + .unwrap(); + + assert!(updated); + assert_cloned_as_delegated!(cloner, &[pubkey], slot, program_pubkey); + assert_not_subscribed!(&chainlink, &[&pubkey]); + } +} diff --git a/magicblock-chainlink/tests/04_redeleg_other_separate_slots.rs b/magicblock-chainlink/tests/04_redeleg_other_separate_slots.rs index 835726338..27a8155c9 100644 --- a/magicblock-chainlink/tests/04_redeleg_other_separate_slots.rs +++ b/magicblock-chainlink/tests/04_redeleg_other_separate_slots.rs @@ -7,7 +7,10 @@ use magicblock_chainlink::{ assert_cloned_as_delegated, assert_cloned_as_undelegated, assert_not_subscribed, assert_remain_undelegating, assert_subscribed_without_delegation_record, - testing::{deleg::add_delegation_record_for, init_logger}, + testing::{ + accounts::compressed_account_shared_with_owner_and_slot, + deleg::add_delegation_record_for, init_logger, + }, }; use solana_account::Account; use solana_program::clock::Slot; @@ -127,3 +130,120 @@ async fn test_undelegate_redelegate_to_other_in_separate_slot() { assert_subscribed_without_delegation_record!(&chainlink, &[&pubkey]); } } + +#[tokio::test] +async fn test_undelegate_redelegate_to_other_in_separate_slot_compressed() { + let mut slot: u64 = 11; + + let ctx = setup(slot).await; + let TestContext { + chainlink, + cloner, + rpc_client, + photon_client, + validator_pubkey, + .. + } = ctx.clone(); + + let pubkey = Pubkey::new_unique(); + let program_pubkey = Pubkey::new_unique(); + let other_authority = Pubkey::new_unique(); + let acc = Account::new(0, 0, &program_pubkey); + + // 1. Account delegated to us + // Initial state: Account is delegated to us and we can read/write to it + { + info!("1. Account delegated to us"); + + slot = rpc_client.set_slot(slot + 11); + let mut compressed_account = + compressed_account_shared_with_owner_and_slot( + pubkey, + validator_pubkey, + slot, + acc.clone(), + ); + compressed_account.set_remote_slot(slot); + photon_client.add_account(pubkey, compressed_account.into(), slot); + + // Transaction to read + // Fetch account - see it's owned by DP, fetch compressed account, clone account as delegated + ctx.ensure_account(&pubkey).await.unwrap(); + assert_cloned_as_delegated!(cloner, &[pubkey], slot, program_pubkey); + assert_not_subscribed!(&chainlink, &[&pubkey]); + }; + + // 2. Account is undelegated + // Undelegation requested, setup subscription, writes refused + { + info!("2.1. Account is undelegated - Undelegation requested (account owner set to DP in Ephem)"); + + ctx.force_undelegation(&pubkey); + + info!("2.2. Would refuse write (account still owned by DP in Ephem)"); + ctx.ensure_account(&pubkey).await.unwrap(); + assert_remain_undelegating!(cloner, &[pubkey], slot); + + slot = rpc_client.set_slot(slot + 11); + + info!("2.3. Account is undelegated on chain"); + // For compressed accounts, undelegation means the compressed account is emptied. + let undelegated_acc = ctx + .commit_and_undelegate_compressed(&pubkey, &program_pubkey) + .await + .unwrap(); + + // Account should be empty onchain + assert_eq!(cloner.get_account(&pubkey).unwrap(), undelegated_acc); + + info!("2.4. Would refuse write (undelegated on chain)"); + ctx.ensure_account(&pubkey).await.unwrap(); + assert_cloned_as_undelegated!(cloner, &[pubkey], slot, program_pubkey); + assert_subscribed_without_delegation_record!(&chainlink, &[&pubkey]); + } + + // 4. Account redelegated to another authority + // Delegate to other, subscription update, writes refused + { + info!("4.1. Account redelegated to another authority - Delegate account to other"); + slot = rpc_client.set_slot(slot + 2); + + // Create compressed delegation record + let compressed_account = compressed_account_shared_with_owner_and_slot( + pubkey, + other_authority, + slot, + acc, + ); + photon_client.add_account( + pubkey, + compressed_account.clone().into(), + slot, + ); + + // Compressed accounts don't send notifications when they are undelegated. + let acc = rpc_client.get_account_at_slot(&pubkey).unwrap(); + let updated = ctx + .send_and_receive_account_update( + pubkey, + acc.account.clone(), + Some(400), + ) + .await; + assert!(updated, "Failed to receive delegation update"); + + // Logical state matches; `compressed` stays set (expanded from `CompressedDelegationRecord`). + let mut acc_redeleg_expected = account_shared_with_owner_and_slot( + &acc.account, + program_pubkey, + slot, + ); + acc_redeleg_expected.set_compressed(true); + assert_eq!(cloner.get_account(&pubkey).unwrap(), acc_redeleg_expected); + + info!("4.2. Would refuse write (delegated to other)"); + ctx.ensure_account(&pubkey).await.unwrap(); + assert_cloned_as_undelegated!(cloner, &[pubkey], slot, program_pubkey); + assert_subscribed_without_delegation_record!(&chainlink, &[&pubkey]); + } +} diff --git a/magicblock-chainlink/tests/05_redeleg_other_same_slot.rs b/magicblock-chainlink/tests/05_redeleg_other_same_slot.rs index 664c9e940..b6c6ca214 100644 --- a/magicblock-chainlink/tests/05_redeleg_other_same_slot.rs +++ b/magicblock-chainlink/tests/05_redeleg_other_same_slot.rs @@ -7,7 +7,11 @@ use magicblock_chainlink::{ assert_cloned_as_delegated, assert_cloned_as_undelegated, assert_not_subscribed, assert_remain_undelegating, assert_subscribed_without_delegation_record, - testing::{deleg::add_delegation_record_for, init_logger}, + testing::{ + accounts::compressed_account_shared_with_owner_and_slot, + deleg::add_delegation_record_for, init_logger, + }, + AccountFetchOrigin, }; use solana_account::Account; use solana_program::clock::Slot; @@ -99,3 +103,92 @@ async fn test_undelegate_redelegate_to_other_in_same_slot() { assert_subscribed_without_delegation_record!(&chainlink, &[&pubkey]); } } + +#[tokio::test] +async fn test_undelegate_redelegate_to_other_in_same_slot_compressed() { + let mut slot: u64 = 11; + + let ctx = setup(slot).await; + let TestContext { + chainlink, + cloner, + rpc_client, + photon_client, + .. + } = ctx.clone(); + + let pubkey = Pubkey::new_unique(); + let program_pubkey = Pubkey::new_unique(); + let other_authority = Pubkey::new_unique(); + let acc = Account::new(0, 0, &program_pubkey); + + // 1. Account delegated to us + // Initial state: Account is delegated to us and we can read/write to it + { + info!("1. Account delegated to us"); + + slot = rpc_client.set_slot(slot + 11); + let compressed_account = compressed_account_shared_with_owner_and_slot( + pubkey, + ctx.validator_pubkey, + slot, + acc.clone(), + ); + photon_client.add_account( + pubkey, + compressed_account.clone().into(), + slot, + ); + + // Transaction to read/write would be ok + // Fetch account - see it's owned by DP, fetch delegation record, clone account as delegated + ctx.ensure_account(&pubkey).await.unwrap(); + assert_cloned_as_delegated!(cloner, &[pubkey], slot, program_pubkey); + assert_not_subscribed!(&chainlink, &[&pubkey]); + }; + + // 2. Account is undelegated and redelegated to another authority (same slot) + // Undelegation requested, setup subscription, writes refused + { + info!("2.1. Account is undelegated - Undelegation requested (account owner set to DP in Ephem)"); + + ctx.force_undelegation(&pubkey); + + info!("2.2. Would refuse write (account still owned by DP in Ephem)"); + assert_remain_undelegating!(cloner, &[pubkey], slot); + + slot = rpc_client.set_slot(slot + 1); + + info!("2.3. Account is undelegated and redelegated to other authority in same slot"); + + // Compressed accounts don't send notifications when they are undelegated. + + // Then immediately delegate to other authority (simulating same slot operation) + let compressed_account = compressed_account_shared_with_owner_and_slot( + pubkey, + other_authority, + slot, + acc.clone(), + ); + photon_client.add_account( + pubkey, + compressed_account.clone().into(), + slot, + ); + + ctx.chainlink + .ensure_accounts( + &[pubkey], + None, + AccountFetchOrigin::GetMultipleAccounts, + None, + ) + .await + .unwrap(); + + // Account should be cloned as delegated to other (flagged as undelegated) + info!("2.4. Would refuse write (delegated to other)"); + assert_cloned_as_undelegated!(cloner, &[pubkey], slot, program_pubkey); + assert_subscribed_without_delegation_record!(&chainlink, &[&pubkey]); + } +} diff --git a/magicblock-chainlink/tests/06_redeleg_us_separate_slots.rs b/magicblock-chainlink/tests/06_redeleg_us_separate_slots.rs index e26956f1b..0f38c51ab 100644 --- a/magicblock-chainlink/tests/06_redeleg_us_separate_slots.rs +++ b/magicblock-chainlink/tests/06_redeleg_us_separate_slots.rs @@ -7,7 +7,11 @@ use magicblock_chainlink::{ assert_cloned_as_delegated, assert_cloned_as_undelegated, assert_not_subscribed, assert_remain_undelegating, assert_subscribed_without_delegation_record, - testing::{deleg::add_delegation_record_for, init_logger}, + testing::{ + accounts::compressed_account_shared_with_owner_and_slot, + deleg::add_delegation_record_for, init_logger, + }, + AccountFetchOrigin, }; use solana_account::Account; use solana_program::clock::Slot; @@ -113,3 +117,109 @@ async fn test_undelegate_redelegate_to_us_in_separate_slots() { assert_not_subscribed!(chainlink, &[&pubkey, &deleg_record_pubkey]); } } + +#[tokio::test] +async fn test_undelegate_redelegate_to_us_in_separate_slots_compressed() { + let mut slot: u64 = 11; + + let ctx = setup(slot).await; + let TestContext { + chainlink, + cloner, + rpc_client, + photon_client, + .. + } = ctx.clone(); + + let pubkey = Pubkey::new_unique(); + let program_pubkey = Pubkey::new_unique(); + + // 1. Account delegated to us + // Initial state: Account is delegated to us and we can read/write to it + { + info!("1. Account delegated to us"); + + slot = rpc_client.set_slot(slot + 11); + let compressed_account = compressed_account_shared_with_owner_and_slot( + pubkey, + ctx.validator_pubkey, + slot, + Account::new(0, 0, &program_pubkey), + ); + photon_client.add_account( + pubkey, + compressed_account.clone().into(), + slot, + ); + + // Fetch account - see it's owned by DP, fetch delegation record, clone account as delegated + ctx.ensure_account(&pubkey).await.unwrap(); + assert_cloned_as_delegated!(cloner, &[pubkey], slot, program_pubkey); + assert_not_subscribed!(&chainlink, &[&pubkey]); + }; + + // 2. Account is undelegated + // Undelegation requested, setup subscription, writes would be refused + { + info!("2.1. Account is undelegated - Undelegation requested (account owner set to DP in Ephem)"); + + ctx.force_undelegation(&pubkey); + + info!("2.2. Would refuse write (account still owned by DP in Ephem)"); + assert_remain_undelegating!(cloner, &[pubkey], slot); + + slot = rpc_client.set_slot(slot + 11); + + info!("2.3. Account is undelegated on chain"); + // Committor service calls this to trigger subscription + chainlink.undelegation_requested(pubkey).await.unwrap(); + + // Committor service then requests undelegation on chain + let undelegated_acc = ctx + .commit_and_undelegate_compressed(&pubkey, &program_pubkey) + .await + .unwrap(); + assert_eq!(cloner.get_account(&pubkey).unwrap(), undelegated_acc); + + // Account should be cloned as undelegated + info!("2.4. Write would be refused (undelegated on chain)"); + assert_cloned_as_undelegated!(cloner, &[pubkey], slot, program_pubkey); + assert_subscribed_without_delegation_record!(&chainlink, &[&pubkey]); + } + + // 3. Account redelegated to us (separate slot) + // Delegate back to us, subscription update, writes allowed + { + info!("3.1. Account redelegated to us - Delegate account back to us"); + slot = rpc_client.set_slot(slot + 11); + + let compressed_account = compressed_account_shared_with_owner_and_slot( + pubkey, + ctx.validator_pubkey, + slot, + Account::new(0, 0, &program_pubkey), + ); + photon_client.add_account( + pubkey, + compressed_account.clone().into(), + slot, + ); + + chainlink + .ensure_accounts( + &[pubkey], + None, + AccountFetchOrigin::GetMultipleAccounts, + None, + ) + .await + .unwrap(); + + // Account should be cloned as delegated back to us + info!("3.2. Would allow write (delegated to us again)"); + assert_cloned_as_delegated!(cloner, &[pubkey], slot, program_pubkey); + + // Account is delegated to us, so we don't subscribe to it nor its delegation record + assert_not_subscribed!(chainlink, &[&pubkey]); + } +} diff --git a/magicblock-chainlink/tests/07_redeleg_us_same_slot.rs b/magicblock-chainlink/tests/07_redeleg_us_same_slot.rs index 911dd3004..49f2a688e 100644 --- a/magicblock-chainlink/tests/07_redeleg_us_same_slot.rs +++ b/magicblock-chainlink/tests/07_redeleg_us_same_slot.rs @@ -6,7 +6,11 @@ use magicblock_chainlink::{ assert_cloned_as_delegated, assert_not_subscribed, assert_remain_undelegating, - testing::{deleg::add_delegation_record_for, init_logger}, + testing::{ + accounts::compressed_account_shared_with_owner_and_slot, + deleg::add_delegation_record_for, init_logger, + }, + AccountFetchOrigin, }; use solana_account::Account; use solana_program::clock::Slot; @@ -108,3 +112,95 @@ async fn test_undelegate_redelegate_to_us_in_same_slot() { assert_not_subscribed!(chainlink, &[&pubkey, &deleg_record_pubkey]); } } + +#[tokio::test] +async fn test_undelegate_redelegate_to_us_in_same_slot_compressed() { + let mut slot: u64 = 11; + + let ctx = setup(slot).await; + let TestContext { + chainlink, + cloner, + rpc_client, + photon_client, + .. + } = ctx.clone(); + + let pubkey = Pubkey::new_unique(); + let program_pubkey = Pubkey::new_unique(); + + // 1. Account delegated to us + // Initial state: Account is delegated to us and we can read/write to it + { + info!("1. Account delegated to us"); + + slot = rpc_client.set_slot(slot + 11); + + let compressed_account = compressed_account_shared_with_owner_and_slot( + pubkey, + ctx.validator_pubkey, + slot, + Account::new(0, 0, &program_pubkey), + ); + photon_client.add_account( + pubkey, + compressed_account.clone().into(), + slot, + ); + + // Transaction to read + // Fetch account - see it's owned by DP, fetch delegation record, clone account as delegated + ctx.ensure_account(&pubkey).await.unwrap(); + assert_cloned_as_delegated!(cloner, &[pubkey], slot, program_pubkey); + assert_not_subscribed!(&chainlink, &[&pubkey]); + } + + // 2. Account is undelegated and redelegated to us (same slot) + // Undelegation requested, setup subscription, writes refused until redelegation + { + info!("2.1. Account is undelegated - Undelegation requested (account owner set to DP in Ephem)"); + + ctx.force_undelegation(&pubkey); + + info!("2.2. Would refuse write (account still owned by DP in Ephem)"); + assert_remain_undelegating!(cloner, &[pubkey], slot); + + slot = rpc_client.set_slot(slot + 1); + + info!("2.3. Account is undelegated and redelegated to us in same slot"); + + // First trigger undelegation subscription + ctx.chainlink.undelegation_requested(pubkey).await.unwrap(); + + // Update account to be delegated on chain and send a sub update + let compressed_account = compressed_account_shared_with_owner_and_slot( + pubkey, + ctx.validator_pubkey, + slot, + Account::new(0, 0, &program_pubkey), + ); + photon_client.add_account( + pubkey, + compressed_account.clone().into(), + slot, + ); + + // Then immediately delegate back to us (simulating same slot operation) + chainlink + .ensure_accounts( + &[pubkey], + None, + AccountFetchOrigin::GetMultipleAccounts, + None, + ) + .await + .unwrap(); + + // Account should be cloned as delegated back to us + info!("2.4. Would allow write (delegated to us again)"); + assert_cloned_as_delegated!(cloner, &[pubkey], slot, program_pubkey); + + // Account is delegated to us, so we don't subscribe to it nor its delegation record + assert_not_subscribed!(chainlink, &[&pubkey]); + } +} diff --git a/magicblock-chainlink/tests/utils/test_context.rs b/magicblock-chainlink/tests/utils/test_context.rs index 10389704c..bdb166a35 100644 --- a/magicblock-chainlink/tests/utils/test_context.rs +++ b/magicblock-chainlink/tests/utils/test_context.rs @@ -12,12 +12,14 @@ use magicblock_chainlink::{ remote_account_provider::{ chain_pubsub_client::{mock::ChainPubsubClientMock, ChainPubsubClient}, config::RemoteAccountProviderConfig, + photon_client::PhotonClient, RemoteAccountProvider, }, testing::{ accounts::account_shared_with_owner, cloner_stub::ClonerStub, deleg::add_delegation_record_for, + photon_client_mock::PhotonClientMock, rpc_client_mock::{ChainRpcClientMock, ChainRpcClientMockBuilder}, utils::{create_test_lru_cache, create_test_lru_cache_with_config}, }, @@ -38,16 +40,24 @@ pub type TestChainlink = Chainlink< ChainPubsubClientMock, AccountsBankStub, ClonerStub, + PhotonClientMock, >; #[derive(Clone)] pub struct TestContext { pub rpc_client: ChainRpcClientMock, pub pubsub_client: ChainPubsubClientMock, + pub photon_client: PhotonClientMock, pub chainlink: Arc, pub bank: Arc, pub remote_account_provider: Option< - Arc>, + Arc< + RemoteAccountProvider< + ChainRpcClientMock, + ChainPubsubClientMock, + PhotonClientMock, + >, + >, >, pub cloner: Arc, pub validator_pubkey: Pubkey, @@ -55,13 +65,14 @@ pub struct TestContext { impl TestContext { pub async fn init(slot: Slot) -> Self { - let (rpc_client, pubsub_client) = { + let (rpc_client, pubsub_client, photon_client) = { let rpc_client = ChainRpcClientMockBuilder::new().slot(slot).build(); let (updates_sndr, updates_rcvr) = mpsc::channel(100); let pubsub_client = ChainPubsubClientMock::new(updates_sndr, updates_rcvr); - (rpc_client, pubsub_client) + let photon_client = PhotonClientMock::default(); + (rpc_client, pubsub_client, photon_client) }; let lifecycle_mode = LifecycleMode::Ephemeral; @@ -83,6 +94,7 @@ impl TestContext { RemoteAccountProvider::try_from_clients_and_mode( rpc_client.clone(), pubsub_client.clone(), + Some(photon_client.clone()), tx, &config, subscribed_accounts, @@ -123,6 +135,7 @@ impl TestContext { Self { rpc_client, pubsub_client, + photon_client, chainlink: Arc::new(chainlink), bank, cloner, @@ -262,6 +275,39 @@ impl TestContext { Ok(undelegated_acc) } + /// Assumes that account was already marked as undelegate in the bank + /// see [`force_undelegation`](Self::force_undelegation) + #[allow(dead_code)] + pub async fn commit_and_undelegate_compressed( + &self, + pubkey: &Pubkey, + owner: &Pubkey, + ) -> ChainlinkResult { + // For compressed accounts, undelegation means the compressed account is emptied. + let acc = self.bank.get(pubkey).unwrap(); + self.rpc_client.add_account(*pubkey, acc.clone().into()); + self.photon_client.remove_account(pubkey); + // Committor service calls this to trigger subscription + self.chainlink.undelegation_requested(*pubkey).await?; + + // Committor service then requests undelegation on chain + let undelegated_acc = account_shared_with_owner_and_slot( + &acc.into(), + *owner, + self.rpc_client.get_slot(), + ); + let updated = self + .send_and_receive_account_update( + *pubkey, + undelegated_acc.clone(), + Some(400), + ) + .await; + assert!(updated, "Failed to receive undelegation update"); + + Ok(undelegated_acc) + } + #[allow(dead_code)] pub async fn delegate_existing_account_to( &self, diff --git a/magicblock-committor-service/Cargo.toml b/magicblock-committor-service/Cargo.toml index 11eec877e..d61d2e9ba 100644 --- a/magicblock-committor-service/Cargo.toml +++ b/magicblock-committor-service/Cargo.toml @@ -15,8 +15,12 @@ async-trait = { workspace = true } base64 = { workspace = true } bincode = { workspace = true } borsh = { workspace = true } +compressed-delegation-api = { workspace = true } +compressed-delegation-client = { workspace = true } futures-util = { workspace = true } tracing = { workspace = true } +light-client = { workspace = true } +light-sdk = { workspace = true, features = ["v2"] } lru = { workspace = true } magicblock-committor-program = { workspace = true, features = [ "no-entrypoint", diff --git a/magicblock-committor-service/src/committor_processor.rs b/magicblock-committor-service/src/committor_processor.rs index 5439037d8..e83a060ec 100644 --- a/magicblock-committor-service/src/committor_processor.rs +++ b/magicblock-committor-service/src/committor_processor.rs @@ -4,8 +4,12 @@ use std::{ sync::Arc, }; +use light_client::indexer::photon_indexer::PhotonIndexer; use magicblock_core::traits::ActionsCallbackScheduler; -use magicblock_program::magic_scheduled_base_intent::ScheduledIntentBundle; +use magicblock_program::{ + magic_scheduled_base_intent::ScheduledIntentBundle, + magic_sys::is_compression_enabled, +}; use magicblock_rpc_client::MagicblockRpcClient; use magicblock_table_mania::{GarbageCollectorConfig, TableMania}; use solana_keypair::Keypair; @@ -17,7 +21,7 @@ use tracing::{error, instrument}; use crate::{ config::ChainConfig, - error::CommittorServiceResult, + error::{CommittorServiceError, CommittorServiceResult}, intent_execution_manager::{ db::DummyDB, BroadcastedIntentExecutionResult, IntentExecutionManager, }, @@ -60,6 +64,10 @@ impl CommittorProcessor { ); let rpc_client = Arc::new(rpc_client); let magic_block_rpc_client = MagicblockRpcClient::new(rpc_client); + let photon_client = chain_config + .photon_uri + .as_ref() + .map(|uri| Arc::new(PhotonIndexer::new(uri.to_string()))); // Create TableMania let gc_config = GarbageCollectorConfig::default(); @@ -73,9 +81,11 @@ impl CommittorProcessor { let persister = IntentPersisterImpl::try_new(persist_file)?; // Create commit scheduler - let task_info_fetcher = Arc::new(CacheTaskInfoFetcher::new( - RpcTaskInfoFetcher::new(magic_block_rpc_client.clone()), - )); + let task_info_fetcher = + Arc::new(CacheTaskInfoFetcher::new(RpcTaskInfoFetcher::new( + magic_block_rpc_client.clone(), + photon_client, + ))); let commits_scheduler = IntentExecutionManager::new( magic_block_rpc_client.clone(), DummyDB::new(), @@ -152,7 +162,22 @@ impl CommittorProcessor { &self, intent_bundles: Vec, ) -> CommittorServiceResult<()> { - if let Err(err) = self.persister.start_base_intents(&intent_bundles) { + let is_compression_enabled = is_compression_enabled() + .map_err(|_| CommittorServiceError::CompressionNotConfigured)?; + let (invalid_bundles, valid_bundles): (Vec<_>, Vec<_>) = + intent_bundles.into_iter().partition(|bundle| { + !is_compression_enabled && bundle.has_compressed_intent() + }); + if !invalid_bundles.is_empty() { + for bundle in invalid_bundles { + error!( + bundle_id = bundle.id, + "Intent bundle contains compressed intent but compression is not enabled" + ); + } + } + + if let Err(err) = self.persister.start_base_intents(&valid_bundles) { // We will still try to perform the commits, but the fact that we cannot // persist the intent is very serious and we should probably restart the // valiator @@ -160,7 +185,7 @@ impl CommittorProcessor { }; self.commits_scheduler - .schedule(intent_bundles) + .schedule(valid_bundles) .await .inspect_err(|err| { error!(error = ?err, "Failed to schedule intent"); @@ -180,10 +205,81 @@ impl CommittorProcessor { pub async fn fetch_current_commit_nonces( &self, pubkeys: &[Pubkey], + compressed: bool, min_context_slot: u64, ) -> TaskInfoFetcherResult> { self.task_info_fetcher - .fetch_current_commit_nonces(pubkeys, min_context_slot) + .fetch_current_commit_nonces(pubkeys, compressed, min_context_slot) .await } } + +#[cfg(test)] +mod tests { + use magicblock_core::{ + intent::BaseActionCallback, + traits::{ + ActionResult, ActionsCallbackScheduler, CallbackScheduleError, + }, + }; + use solana_hash::Hash; + use solana_signature::Signature; + use solana_transaction::Transaction; + use tempfile::NamedTempFile; + + use super::*; + use crate::{ + compute_budget::ComputeBudgetConfig, + config::{ChainConfig, DEFAULT_ACTIONS_TIMEOUT}, + error::CommittorServiceError, + intent_execution_manager::intent_scheduler::create_test_compressed_intent, + }; + + #[derive(Clone, Default)] + struct NoopActionsCallbackScheduler; + + impl ActionsCallbackScheduler for NoopActionsCallbackScheduler { + fn schedule( + &self, + callbacks: Vec, + _signature: Option, + _result: ActionResult, + ) -> Vec> { + callbacks + .iter() + .map(|_| Ok(Signature::new_unique())) + .collect() + } + } + + #[tokio::test] + async fn compressed_intents_fail_without_photon_indexer() { + let persist_file = NamedTempFile::new().unwrap(); + let processor = CommittorProcessor::try_new( + Keypair::new(), + persist_file.path(), + ChainConfig { + rpc_uri: "http://localhost:7799".to_string(), + photon_uri: None, + commitment: + solana_commitment_config::CommitmentConfig::processed(), + compute_budget_config: ComputeBudgetConfig::new(1_000_000), + actions_timeout: DEFAULT_ACTIONS_TIMEOUT, + }, + NoopActionsCallbackScheduler, + ) + .unwrap(); + + let mut intent = + create_test_compressed_intent(1, &[Pubkey::new_unique()], false); + intent.blockhash = Hash::new_unique(); + intent.sent_transaction = Transaction::default(); + + let result = processor.schedule_intent_bundle(vec![intent]).await; + + assert!(matches!( + result, + Err(CommittorServiceError::CompressionNotConfigured) + )); + } +} diff --git a/magicblock-committor-service/src/config.rs b/magicblock-committor-service/src/config.rs index fc231b07f..833760bcd 100644 --- a/magicblock-committor-service/src/config.rs +++ b/magicblock-committor-service/src/config.rs @@ -9,42 +9,20 @@ pub const DEFAULT_ACTIONS_TIMEOUT: Duration = Duration::from_secs(60); #[derive(Debug, Clone)] pub struct ChainConfig { pub rpc_uri: String, + pub photon_uri: Option, pub commitment: CommitmentConfig, pub compute_budget_config: ComputeBudgetConfig, pub actions_timeout: Duration, } impl ChainConfig { - pub fn devnet(compute_budget_config: ComputeBudgetConfig) -> Self { - Self { - rpc_uri: "https://api.devnet.solana.com".to_string(), - commitment: CommitmentConfig::confirmed(), - compute_budget_config, - actions_timeout: DEFAULT_ACTIONS_TIMEOUT, - } - } - - pub fn mainnet(compute_budget_config: ComputeBudgetConfig) -> Self { - Self { - rpc_uri: "https://api.mainnet-beta.solana.com".to_string(), - commitment: CommitmentConfig::confirmed(), - compute_budget_config, - actions_timeout: DEFAULT_ACTIONS_TIMEOUT, - } - } - pub fn local(compute_budget_config: ComputeBudgetConfig) -> Self { Self { rpc_uri: "http://localhost:7799".to_string(), + photon_uri: Some("http://localhost:8784".to_string()), commitment: CommitmentConfig::processed(), compute_budget_config, actions_timeout: DEFAULT_ACTIONS_TIMEOUT, } } } - -impl Default for ChainConfig { - fn default() -> Self { - Self::local(ComputeBudgetConfig::new(1_000_000)) - } -} diff --git a/magicblock-committor-service/src/error.rs b/magicblock-committor-service/src/error.rs index fa13e49b8..492ba2701 100644 --- a/magicblock-committor-service/src/error.rs +++ b/magicblock-committor-service/src/error.rs @@ -64,6 +64,11 @@ pub enum CommittorServiceError { #[error("Could not find commit strategy for bundle {0}")] CouldNotFindCommitStrategyForBundle(u64), + #[error( + "Compression is not configured; cannot schedule compressed commits" + )] + CompressionNotConfigured, + #[error("Failed to fetch metadata account for {0}")] FailedToFetchDelegationMetadata(Pubkey), diff --git a/magicblock-committor-service/src/intent_execution_manager/intent_scheduler.rs b/magicblock-committor-service/src/intent_execution_manager/intent_scheduler.rs index 580acebf6..888e4e365 100644 --- a/magicblock-committor-service/src/intent_execution_manager/intent_scheduler.rs +++ b/magicblock-committor-service/src/intent_execution_manager/intent_scheduler.rs @@ -1,5 +1,6 @@ use std::collections::{hash_map::Entry, HashMap, VecDeque}; +use magicblock_core::compression::OUTPUT_QUEUE; use magicblock_program::magic_scheduled_base_intent::ScheduledIntentBundle; use solana_pubkey::Pubkey; use thiserror::Error; @@ -14,6 +15,23 @@ struct IntentMeta { intent: ScheduledIntentBundle, } +fn scheduling_pubkeys(intent_bundle: &ScheduledIntentBundle) -> Vec { + let mut pubkeys = intent_bundle.get_all_committed_pubkeys(); + if intent_bundle + .get_commit_finalize_compressed_intent_accounts() + .is_some() + || intent_bundle + .get_commit_finalize_compressed_and_undelegate_intent_accounts() + .is_some() + { + // Compressed finalize updates flow through Light's shared output queue. + // Without this lock, disjoint account intents can race inside the + // compression program even though their committed account keys differ. + pubkeys.push(OUTPUT_QUEUE); + } + pubkeys +} + /// A scheduler that ensures mutually exclusive access to pubkeys across intents /// /// # Data Structures @@ -111,7 +129,7 @@ impl IntentScheduler { return None; } - let pubkeys = intent_bundle.get_all_committed_pubkeys(); + let pubkeys = scheduling_pubkeys(&intent_bundle); if pubkeys.is_empty() { return Some(intent_bundle); }; @@ -152,7 +170,7 @@ impl IntentScheduler { ) -> IntentSchedulerResult<()> { // Release data for completed intent let intent_id = intent_bundle.id; - let pubkeys = intent_bundle.get_all_committed_pubkeys(); + let pubkeys = scheduling_pubkeys(intent_bundle); if pubkeys.is_empty() { // This means BaseAction, it doesn't have to be scheduled return Ok(()); @@ -341,6 +359,54 @@ mod simple_test { assert_eq!(scheduler.intents_blocked(), 0); } + #[test] + fn test_compressed_finalize_intents_share_queue_lock() { + setup(); + let mut scheduler = IntentScheduler::new(); + let msg1 = create_test_compressed_intent( + 1, + &[pubkey!("1111111111111111111111111111111111111111111")], + false, + ); + let msg2 = create_test_compressed_intent( + 2, + &[pubkey!("22222222222222222222222222222222222222222222")], + false, + ); + + assert!(scheduler.schedule(msg1.clone()).is_some()); + assert!(scheduler.schedule(msg2.clone()).is_none()); + assert_eq!(scheduler.intents_blocked(), 1); + + assert!(scheduler.complete(&msg1).is_ok()); + assert_eq!(scheduler.pop_next_scheduled_intent(), Some(msg2)); + assert_eq!(scheduler.intents_blocked(), 0); + } + + #[test] + fn test_compressed_undelegate_finalize_intents_share_queue_lock() { + setup(); + let mut scheduler = IntentScheduler::new(); + let msg1 = create_test_compressed_intent( + 1, + &[pubkey!("1111111111111111111111111111111111111111111")], + true, + ); + let msg2 = create_test_compressed_intent( + 2, + &[pubkey!("22222222222222222222222222222222222222222222")], + true, + ); + + assert!(scheduler.schedule(msg1.clone()).is_some()); + assert!(scheduler.schedule(msg2.clone()).is_none()); + assert_eq!(scheduler.intents_blocked(), 1); + + assert!(scheduler.complete(&msg1).is_ok()); + assert_eq!(scheduler.pop_next_scheduled_intent(), Some(msg2)); + assert_eq!(scheduler.intents_blocked(), 0); + } + /// Ensure intents conflicting intents get blocked #[test] fn test_conflicting_intents() { @@ -898,6 +964,56 @@ pub(crate) fn create_test_intent( intent } +#[cfg(test)] +pub(crate) fn create_test_compressed_intent( + id: u64, + pubkeys: &[Pubkey], + is_undelegate: bool, +) -> ScheduledIntentBundle { + use magicblock_core::intent::CommittedAccount; + use magicblock_program::magic_scheduled_base_intent::{ + CommitAndUndelegate, CommitType, MagicIntentBundle, + ScheduledIntentBundle, UndelegateType, + }; + use solana_account::Account; + use solana_hash::Hash; + use solana_transaction::Transaction; + + let committed_accounts = pubkeys + .iter() + .copied() + .map(|pubkey| CommittedAccount { + pubkey, + account: Account::default(), + remote_slot: Default::default(), + }) + .collect(); + + let commit_type = CommitType::Standalone(committed_accounts); + let mut intent = ScheduledIntentBundle { + id, + slot: 0, + blockhash: Hash::default(), + sent_transaction: Transaction::default(), + payer: Pubkey::default(), + intent_bundle: MagicIntentBundle::default(), + }; + + if is_undelegate { + intent + .intent_bundle + .commit_finalize_compressed_and_undelegate = + Some(CommitAndUndelegate { + commit_action: commit_type, + undelegate_action: UndelegateType::Standalone, + }); + } else { + intent.intent_bundle.commit_finalize_compressed = Some(commit_type); + } + + intent +} + #[cfg(test)] pub(crate) fn create_test_intent_bundle( id: u64, diff --git a/magicblock-committor-service/src/intent_executor/task_info_fetcher.rs b/magicblock-committor-service/src/intent_executor/task_info_fetcher.rs index 25c93d79f..3644847cf 100644 --- a/magicblock-committor-service/src/intent_executor/task_info_fetcher.rs +++ b/magicblock-committor-service/src/intent_executor/task_info_fetcher.rs @@ -7,14 +7,29 @@ use std::{ }; use async_trait::async_trait; +use borsh::BorshDeserialize; +use compressed_delegation_api::{ + instruction::{CdpCompressedAccountMeta, CdpValidityProof}, + CompressedDelegationRecord, +}; use dlp_api::{ delegation_metadata_seeds_from_delegated_account, state::DelegationMetadata, }; +use futures_util::{future::try_join_all, TryFutureExt}; +use light_client::indexer::{ + photon_indexer::PhotonIndexer, Indexer, IndexerRpcConfig, RetryConfig, +}; +use light_sdk::instruction::{ + account_meta::CompressedAccountMeta, PackedAccounts, + SystemAccountMetaConfig, +}; use lru::LruCache; +use magicblock_core::compression::derive_cda_from_pda; use magicblock_metrics::metrics; use magicblock_rpc_client::{MagicBlockRpcClientError, MagicblockRpcClient}; use solana_account::Account; use solana_account_decoder::UiAccountEncoding; +use solana_instruction::AccountMeta; use solana_pubkey::Pubkey; use solana_rpc_client_api::{ client_error::ErrorKind, config::RpcAccountInfoConfig, @@ -28,6 +43,15 @@ use tracing::{error, info, warn}; const NUM_FETCH_RETRIES: NonZeroUsize = NonZeroUsize::new(5).unwrap(); const MUTEX_POISONED_MSG: &str = "CacheTaskInfoFetcher mutex poisoned!"; +#[derive(Clone, Debug, Default, PartialEq)] +pub struct CompressedData { + pub hash: [u8; 32], + pub compressed_delegation_record_bytes: Vec, + pub remaining_accounts: Vec, + pub account_meta: CdpCompressedAccountMeta, + pub proof: CdpValidityProof, +} + #[async_trait] pub trait TaskInfoFetcher: Send + Sync + 'static { /// Fetches correct commit nonces for pubkeys @@ -35,6 +59,7 @@ pub trait TaskInfoFetcher: Send + Sync + 'static { async fn fetch_next_commit_nonces( &self, pubkeys: &[Pubkey], + compressed: bool, min_context_slot: u64, ) -> TaskInfoFetcherResult>; @@ -43,6 +68,7 @@ pub trait TaskInfoFetcher: Send + Sync + 'static { async fn fetch_current_commit_nonces( &self, pubkeys: &[Pubkey], + compressed: bool, min_context_slot: u64, ) -> TaskInfoFetcherResult>; @@ -58,6 +84,23 @@ pub trait TaskInfoFetcher: Send + Sync + 'static { pubkeys: &[Pubkey], min_context_slot: u64, ) -> TaskInfoFetcherResult>; + + async fn get_compressed_data( + &self, + pubkey: &Pubkey, + min_context_slot: Option, + ) -> TaskInfoFetcherResult; + + async fn get_compressed_data_for_accounts( + &self, + pubkeys: &[Pubkey], + min_context_slot: Option, + ) -> TaskInfoFetcherResult>> { + try_join_all(pubkeys.iter().map(|pubkey| async move { + Ok(self.get_compressed_data(pubkey, min_context_slot).await) + })) + .await + } } // --------------------------------------------------------------------------- @@ -67,11 +110,24 @@ pub trait TaskInfoFetcher: Send + Sync + 'static { /// Pure RPC implementation of [`TaskInfoFetcher`] — no caching. pub struct RpcTaskInfoFetcher { rpc_client: MagicblockRpcClient, + photon_client: Option>, } impl RpcTaskInfoFetcher { - pub fn new(rpc_client: MagicblockRpcClient) -> Self { - Self { rpc_client } + pub fn new( + rpc_client: MagicblockRpcClient, + photon_client: Option>, + ) -> Self { + Self { + rpc_client, + photon_client, + } + } + + fn photon_client(&self) -> TaskInfoFetcherResult<&PhotonIndexer> { + self.photon_client + .as_deref() + .ok_or(PhotonFetcherError::CompressionNotConfigured.into()) } /// Fetches [`DelegationMetadata`]s with some num of retries @@ -162,6 +218,9 @@ impl RpcTaskInfoFetcher { TaskInfoFetcherError::MagicBlockRpcClientError(ref err) => { warn!(error = ?err, attempt = i, "Fetch account error"); } + TaskInfoFetcherError::PhotonFetcherError(_) => { + break Err(err); + } } if i >= max_retries.get() { @@ -228,41 +287,129 @@ impl TaskInfoFetcher for RpcTaskInfoFetcher { async fn fetch_next_commit_nonces( &self, pubkeys: &[Pubkey], + compressed: bool, min_context_slot: u64, ) -> TaskInfoFetcherResult> { if pubkeys.is_empty() { return Ok(HashMap::new()); } - let nonces = Self::fetch_metadata_with_retries( - &self.rpc_client, - pubkeys, - min_context_slot, - NUM_FETCH_RETRIES, - ) - .await? - .into_iter() - .map(|m| m.last_update_nonce + 1); - Ok(pubkeys.iter().copied().zip(nonces).collect()) + if !compressed { + let nonces = Self::fetch_metadata_with_retries( + &self.rpc_client, + pubkeys, + min_context_slot, + NUM_FETCH_RETRIES, + ) + .await? + .into_iter() + .map(|m| m.last_update_nonce + 1); + Ok(pubkeys.iter().copied().zip(nonces).collect()) + } else { + let cdas = pubkeys + .iter() + .map(|pubkey| derive_cda_from_pda(pubkey).to_bytes()) + .collect::>(); + + let items = self + .photon_client()? + .get_multiple_compressed_accounts( + Some(cdas), + None, + Some(IndexerRpcConfig::new(min_context_slot)), + ) + .map_err(PhotonFetcherError::from) + .await? + .value + .items; + + if items.len() != pubkeys.len() { + return Err(PhotonFetcherError::PhotonItemsMismatch( + items.len(), + pubkeys.len(), + ) + .into()); + } + + let mut result = HashMap::with_capacity(pubkeys.len()); + for (pubkey, compressed_account) in pubkeys.iter().zip(items) { + let nonce = compressed_account + .and_then(|acc| acc.data) + .and_then(|data| { + CompressedDelegationRecord::try_from_slice(&data.data) + .ok() + }) + .map(|record| record.last_update_nonce + 1) + .ok_or(PhotonFetcherError::CompressedAccountNotFound( + *pubkey, + ))?; + result.insert(*pubkey, nonce); + } + Ok(result) + } } async fn fetch_current_commit_nonces( &self, pubkeys: &[Pubkey], + compressed: bool, min_context_slot: u64, ) -> TaskInfoFetcherResult> { if pubkeys.is_empty() { return Ok(HashMap::new()); } - let nonces = Self::fetch_metadata_with_retries( - &self.rpc_client, - pubkeys, - min_context_slot, - NUM_FETCH_RETRIES, - ) - .await? - .into_iter() - .map(|m| m.last_update_nonce); - Ok(pubkeys.iter().copied().zip(nonces).collect()) + if !compressed { + let nonces = Self::fetch_metadata_with_retries( + &self.rpc_client, + pubkeys, + min_context_slot, + NUM_FETCH_RETRIES, + ) + .await? + .into_iter() + .map(|m| m.last_update_nonce); + Ok(pubkeys.iter().copied().zip(nonces).collect()) + } else { + let cdas = pubkeys + .iter() + .map(|pubkey| derive_cda_from_pda(pubkey).to_bytes()) + .collect::>(); + + let items = self + .photon_client()? + .get_multiple_compressed_accounts( + Some(cdas), + None, + Some(IndexerRpcConfig::new(min_context_slot)), + ) + .map_err(PhotonFetcherError::from) + .await? + .value + .items; + + if items.len() != pubkeys.len() { + return Err(PhotonFetcherError::PhotonItemsMismatch( + items.len(), + pubkeys.len(), + ) + .into()); + } + + let mut result = HashMap::with_capacity(pubkeys.len()); + for (pubkey, compressed_account) in pubkeys.iter().zip(items) { + let nonce = compressed_account + .and_then(|acc| acc.data) + .and_then(|data| { + CompressedDelegationRecord::try_from_slice(&data.data) + .ok() + }) + .map(|record| record.last_update_nonce) + .ok_or(PhotonFetcherError::CompressedAccountNotFound( + *pubkey, + ))?; + result.insert(*pubkey, nonce); + } + Ok(result) + } } async fn fetch_rent_reimbursements( @@ -296,6 +443,93 @@ impl TaskInfoFetcher for RpcTaskInfoFetcher { .await?; Ok(pubkeys.iter().copied().zip(accounts).collect()) } + + async fn get_compressed_data( + &self, + pubkey: &Pubkey, + min_context_slot: Option, + ) -> TaskInfoFetcherResult { + let cda = derive_cda_from_pda(pubkey); + let compressed_delegation_record = self + .photon_client()? + .get_compressed_account( + cda.to_bytes(), + min_context_slot.map(|slot| IndexerRpcConfig { + slot, + retry_config: RetryConfig::default(), + }), + ) + .map_err(PhotonFetcherError::from) + .await? + .value + .ok_or(PhotonFetcherError::EmptyCompressedAccount)?; + let proof_result = self + .photon_client()? + .get_validity_proof( + vec![compressed_delegation_record.hash], + vec![], + min_context_slot.map(|slot| IndexerRpcConfig { + slot, + retry_config: RetryConfig::default(), + }), + ) + .map_err(PhotonFetcherError::from) + .await? + .value; + + let system_account_meta_config = SystemAccountMetaConfig::new( + compressed_delegation_client::ID.to_bytes().into(), + ); + let mut remaining_accounts = PackedAccounts::default(); + remaining_accounts + .add_system_accounts_v2(system_account_meta_config) + .map_err(|err| PhotonFetcherError::LightSdkError(Box::new(err)))?; + let packed_tree_accounts = proof_result + .pack_tree_infos(&mut remaining_accounts) + .state_trees + .ok_or(PhotonFetcherError::MissingStateTrees)?; + + let tree_info = packed_tree_accounts + .packed_tree_infos + .first() + .copied() + .ok_or(PhotonFetcherError::MissingStateTrees)?; + + let account_meta = CompressedAccountMeta { + tree_info, + address: compressed_delegation_record + .address + .ok_or(PhotonFetcherError::MissingAddress)?, + output_state_tree_index: packed_tree_accounts.output_tree_index, + } + .into(); + + let compressed_delegation_record_bytes = compressed_delegation_record + .data + .ok_or(PhotonFetcherError::MissingCompressedData)? + .data; + CompressedDelegationRecord::try_from_slice( + &compressed_delegation_record_bytes, + ) + .map_err(|_| TaskInfoFetcherError::InvalidAccountDataError(*pubkey))?; + + Ok(CompressedData { + hash: compressed_delegation_record.hash, + compressed_delegation_record_bytes, + remaining_accounts: remaining_accounts + .to_account_metas() + .0 + .iter() + .map(|meta| AccountMeta { + pubkey: meta.pubkey.to_bytes().into(), + is_signer: meta.is_signer, + is_writable: meta.is_writable, + }) + .collect(), + account_meta, + proof: proof_result.proof.into(), + }) + } } /// Per-account async mutex protecting the cached nonce value. @@ -500,6 +734,7 @@ impl TaskInfoFetcher for CacheTaskInfoFetcher { async fn fetch_next_commit_nonces( &self, pubkeys: &[Pubkey], + compressed: bool, min_context_slot: u64, ) -> TaskInfoFetcherResult> { if pubkeys.is_empty() { @@ -537,7 +772,11 @@ impl TaskInfoFetcher for CacheTaskInfoFetcher { let missing_pubkeys: Vec<_> = missing.iter().map(|(pubkey, _)| **pubkey).collect(); self.inner - .fetch_current_commit_nonces(&missing_pubkeys, min_context_slot) + .fetch_current_commit_nonces( + &missing_pubkeys, + compressed, + min_context_slot, + ) .await? }; @@ -563,6 +802,7 @@ impl TaskInfoFetcher for CacheTaskInfoFetcher { async fn fetch_current_commit_nonces( &self, pubkeys: &[Pubkey], + compressed: bool, min_context_slot: u64, ) -> TaskInfoFetcherResult> { if pubkeys.is_empty() { @@ -593,7 +833,11 @@ impl TaskInfoFetcher for CacheTaskInfoFetcher { let missing_pubkeys: Vec<_> = missing.iter().map(|(pubkey, _)| **pubkey).collect(); self.inner - .fetch_current_commit_nonces(&missing_pubkeys, min_context_slot) + .fetch_current_commit_nonces( + &missing_pubkeys, + compressed, + min_context_slot, + ) .await? }; @@ -632,6 +876,16 @@ impl TaskInfoFetcher for CacheTaskInfoFetcher { .get_base_accounts(pubkeys, min_context_slot) .await } + + async fn get_compressed_data( + &self, + pubkey: &Pubkey, + min_context_slot: Option, + ) -> TaskInfoFetcherResult { + self.inner + .get_compressed_data(pubkey, min_context_slot) + .await + } } pub enum ResetType<'a> { @@ -649,6 +903,30 @@ pub enum TaskInfoFetcherError { MinContextSlotNotReachedError(u64, Box), #[error("MagicBlockRpcClientError: {0}")] MagicBlockRpcClientError(Box), + #[error("Photon fetcher error: {0}")] + PhotonFetcherError(#[from] PhotonFetcherError), +} + +#[derive(thiserror::Error, Debug)] +pub enum PhotonFetcherError { + #[error("Indexer error: {0}")] + IndexerError(#[from] light_client::indexer::IndexerError), + #[error("Compression is not configured")] + CompressionNotConfigured, + #[error("Compressed account not found for: {0}")] + CompressedAccountNotFound(Pubkey), + #[error("Empty compressed account")] + EmptyCompressedAccount, + #[error("Missing state trees")] + MissingStateTrees, + #[error("Missing address")] + MissingAddress, + #[error("Missing compressed data")] + MissingCompressedData, + #[error("LightSdkError: {0}")] + LightSdkError(Box), + #[error("Photon returned {0} items for {1} pubkeys")] + PhotonItemsMismatch(usize, usize), } impl TaskInfoFetcherError { @@ -699,6 +977,7 @@ impl TaskInfoFetcherError { Self::InvalidAccountDataError(_) => None, Self::MinContextSlotNotReachedError(_, err) => err.signature(), Self::MagicBlockRpcClientError(err) => err.signature(), + Self::PhotonFetcherError(_) => None, } } } @@ -720,11 +999,17 @@ mod tests { let pk = Pubkey::new_unique(); let fetcher = FetcherBuilder::new(vec![10]).build(); - let r1 = fetcher.fetch_next_commit_nonces(&[pk], 0).await.unwrap(); + let r1 = fetcher + .fetch_next_commit_nonces(&[pk], false, 0) + .await + .unwrap(); assert_eq!(r1[&pk], 11); // Cache hit: no RPC (only 1 response queued), increments - let r2 = fetcher.fetch_next_commit_nonces(&[pk], 0).await.unwrap(); + let r2 = fetcher + .fetch_next_commit_nonces(&[pk], false, 0) + .await + .unwrap(); assert_eq!(r2[&pk], 12); } @@ -735,9 +1020,12 @@ mod tests { // prime pk1 (nonce 5), then mixed call fetches only cold pk2 (nonce 20) let fetcher = FetcherBuilder::new(vec![5, 20]).build(); - fetcher.fetch_next_commit_nonces(&[pk1], 0).await.unwrap(); // pk1 = 6 + fetcher + .fetch_next_commit_nonces(&[pk1], false, 0) + .await + .unwrap(); // pk1 = 6 let r = fetcher - .fetch_next_commit_nonces(&[pk1, pk2], 0) + .fetch_next_commit_nonces(&[pk1, pk2], false, 0) .await .unwrap(); assert_eq!(r[&pk1], 7); // cached, incremented @@ -751,12 +1039,21 @@ mod tests { // pk1 initial, pk2 evicts pk1, pk1 re-fetch after eviction let fetcher = FetcherBuilder::new(vec![1, 2, 10]).capacity(1).build(); - fetcher.fetch_next_commit_nonces(&[pk1], 0).await.unwrap(); // pk1 cached = 2 - fetcher.fetch_next_commit_nonces(&[pk2], 0).await.unwrap(); // pk2 cached = 3, pk1 evicted + fetcher + .fetch_next_commit_nonces(&[pk1], false, 0) + .await + .unwrap(); // pk1 cached = 2 + fetcher + .fetch_next_commit_nonces(&[pk2], false, 0) + .await + .unwrap(); // pk2 cached = 3, pk1 evicted assert!(fetcher.peek_commit_nonce(&pk1).await.is_none()); // evicted - let r = fetcher.fetch_next_commit_nonces(&[pk1], 0).await.unwrap(); + let r = fetcher + .fetch_next_commit_nonces(&[pk1], false, 0) + .await + .unwrap(); assert_eq!(r[&pk1], 11); // re-fetched (10 + 1) // Sequential eviction: pk1's guard was dropped before pk2 evicted it, @@ -776,17 +1073,26 @@ mod tests { iters: usize, ) { for pk in &phase1_keys { - fetcher.fetch_next_commit_nonces(&[*pk], 0).await.unwrap(); + fetcher + .fetch_next_commit_nonces(&[*pk], false, 0) + .await + .unwrap(); } barrier.wait().await; // signal phase 1 done barrier.wait().await; // wait for outer verification for _ in 0..iters { for pk in &phase2_keys { - fetcher.fetch_next_commit_nonces(&[*pk], 0).await.unwrap(); + fetcher + .fetch_next_commit_nonces(&[*pk], false, 0) + .await + .unwrap(); } } for chunk in shared_b.chunks(2) { - fetcher.fetch_next_commit_nonces(chunk, 0).await.unwrap(); + fetcher + .fetch_next_commit_nonces(chunk, false, 0) + .await + .unwrap(); } } @@ -885,11 +1191,17 @@ mod tests { let pk = Pubkey::new_unique(); let fetcher = FetcherBuilder::new(vec![10]).build(); - let r1 = fetcher.fetch_current_commit_nonces(&[pk], 0).await.unwrap(); + let r1 = fetcher + .fetch_current_commit_nonces(&[pk], false, 0) + .await + .unwrap(); assert_eq!(r1[&pk], 10); // stored as-is // Cache hit: still 10, fetch_current never increments - let r2 = fetcher.fetch_current_commit_nonces(&[pk], 0).await.unwrap(); + let r2 = fetcher + .fetch_current_commit_nonces(&[pk], false, 0) + .await + .unwrap(); assert_eq!(r2[&pk], 10); } @@ -900,14 +1212,23 @@ mod tests { // pk1 initial, pk2 initial, pk1 after reset let fetcher = FetcherBuilder::new(vec![1, 2, 50]).build(); - fetcher.fetch_next_commit_nonces(&[pk1], 0).await.unwrap(); // pk1 cached = 2 - fetcher.fetch_next_commit_nonces(&[pk2], 0).await.unwrap(); // pk2 cached = 3 + fetcher + .fetch_next_commit_nonces(&[pk1], false, 0) + .await + .unwrap(); // pk1 cached = 2 + fetcher + .fetch_next_commit_nonces(&[pk2], false, 0) + .await + .unwrap(); // pk2 cached = 3 fetcher.reset(ResetType::Specific(&[pk1])); assert!(fetcher.peek_commit_nonce(&pk1).await.is_none()); // cleared assert_eq!(fetcher.peek_commit_nonce(&pk2).await, Some(3)); // still cached - let r1 = fetcher.fetch_next_commit_nonces(&[pk1], 0).await.unwrap(); + let r1 = fetcher + .fetch_next_commit_nonces(&[pk1], false, 0) + .await + .unwrap(); assert_eq!(r1[&pk1], 51); // re-fetched (50 + 1) } @@ -927,7 +1248,10 @@ mod tests { // Spawn Task A: slow fetch for pk1 acquires its nonce lock and sleeps. let fetcher2 = fetcher.clone(); let task_a = tokio::spawn(async move { - fetcher2.fetch_next_commit_nonces(&[pk1], 0).await.unwrap(); + fetcher2 + .fetch_next_commit_nonces(&[pk1], false, 0) + .await + .unwrap(); }); // Let Task A acquire pk1's nonce lock and start the slow fetch. @@ -937,7 +1261,10 @@ mod tests { // because Task A's guard still holds a clone of pk1's Arc. let fetcher3 = fetcher.clone(); let task_b = tokio::spawn(async move { - fetcher3.fetch_next_commit_nonces(&[pk2], 0).await.unwrap(); + fetcher3 + .fetch_next_commit_nonces(&[pk2], false, 0) + .await + .unwrap(); }); // Let Task B run through acquire_nonce_locks (eviction happens here). @@ -982,15 +1309,21 @@ mod tests { async fn fetch_next_commit_nonces( &self, pubkeys: &[Pubkey], + compressed: bool, min_context_slot: u64, ) -> TaskInfoFetcherResult> { - self.fetch_current_commit_nonces(pubkeys, min_context_slot) - .await + self.fetch_current_commit_nonces( + pubkeys, + compressed, + min_context_slot, + ) + .await } async fn fetch_current_commit_nonces( &self, pubkeys: &[Pubkey], + _: bool, _: u64, ) -> TaskInfoFetcherResult> { if let Some(delay) = self.delay { @@ -1022,6 +1355,14 @@ mod tests { ) -> TaskInfoFetcherResult> { unimplemented!() } + + async fn get_compressed_data( + &self, + _: &Pubkey, + _: Option, + ) -> TaskInfoFetcherResult { + unimplemented!() + } } struct FetcherBuilder { diff --git a/magicblock-committor-service/src/intent_executor/utils.rs b/magicblock-committor-service/src/intent_executor/utils.rs index b40cab63f..8c56c0725 100644 --- a/magicblock-committor-service/src/intent_executor/utils.rs +++ b/magicblock-committor-service/src/intent_executor/utils.rs @@ -1,4 +1,4 @@ -use std::time::Duration; +use std::{collections::HashMap, time::Duration}; use async_trait::async_trait; use magicblock_core::traits::{ @@ -80,18 +80,61 @@ pub(in crate::intent_executor) async fn handle_commit_id_error< BaseTaskImpl::CommitFinalize(task) => { Some(task.committed_account.remote_slot) } + BaseTaskImpl::CommitFinalizeCompressed(task) => { + Some(task.committed_account.remote_slot) + } _ => None, }) .max() .unwrap_or_default(); + let regular_pubkeys = strategy + .optimized_tasks + .iter() + .filter_map(|task| match task { + BaseTaskImpl::Commit(task) => Some(task.committed_account.pubkey), + BaseTaskImpl::CommitFinalize(task) => { + Some(task.committed_account.pubkey) + } + _ => None, + }) + .collect::>(); + let compressed_pubkeys = strategy + .optimized_tasks + .iter() + .filter_map(|task| match task { + BaseTaskImpl::CommitFinalizeCompressed(task) => { + Some(task.committed_account.pubkey) + } + _ => None, + }) + .collect::>(); // We reset TaskInfoFetcher for all committed accounts // We re-fetch them to fix out of sync tasks task_info_fetcher.reset(ResetType::Specific(committed_pubkeys)); - let commit_ids = task_info_fetcher - .fetch_next_commit_nonces(committed_pubkeys, min_context_slot) - .await - .map_err(TaskBuilderError::CommitTasksBuildError)?; + let commit_ids = { + let (regular_nonces, compressed_nonces) = tokio::join!( + task_info_fetcher.fetch_next_commit_nonces( + ®ular_pubkeys, + false, + min_context_slot + ), + task_info_fetcher.fetch_next_commit_nonces( + &compressed_pubkeys, + true, + min_context_slot, + ) + ); + regular_nonces + .map_err(TaskBuilderError::CommitTasksBuildError)? + .into_iter() + .chain( + compressed_nonces + .map_err(TaskBuilderError::CommitFinalizeCompressedTasksBuildError)? + .into_iter(), + ) + .collect::>() + }; // Here we find the broken tasks and reset them // Broken tasks are prepared incorrectly so they have to be cleaned up @@ -126,7 +169,24 @@ pub(in crate::intent_executor) async fn handle_commit_id_error< to_cleanup.push(BaseTaskImpl::CommitFinalize(task.clone())); task.reset_commit_id(*commit_id); } - _ => {} + BaseTaskImpl::CommitFinalizeCompressed(task) => { + let Some(commit_id) = + commit_ids.get(&task.committed_account.pubkey) + else { + continue; + }; + if commit_id == &task.commit_id { + continue; + } + + // Handle invalid tasks + to_cleanup + .push(BaseTaskImpl::CommitFinalizeCompressed(task.clone())); + task.reset_commit_id(*commit_id); + } + BaseTaskImpl::BaseAction(_) + | BaseTaskImpl::Finalize(_) + | BaseTaskImpl::Undelegate(_) => {} } } @@ -153,7 +213,9 @@ pub(in crate::intent_executor) fn handle_cpi_limit_error( let last_commit_ind = strategy.optimized_tasks.iter().rposition(|el| { matches!( el, - BaseTaskImpl::Commit(_) | BaseTaskImpl::CommitFinalize(_) + BaseTaskImpl::Commit(_) + | BaseTaskImpl::CommitFinalize(_) + | BaseTaskImpl::CommitFinalizeCompressed(_) ) }); let (mut commit_stage_tasks, mut finalize_stage_tasks) = (vec![], vec![]); diff --git a/magicblock-committor-service/src/persist/commit_persister.rs b/magicblock-committor-service/src/persist/commit_persister.rs index 2fc1598c1..bbe5c9a67 100644 --- a/magicblock-committor-service/src/persist/commit_persister.rs +++ b/magicblock-committor-service/src/persist/commit_persister.rs @@ -141,6 +141,15 @@ impl IntentPersisterImpl { intent_bundle .get_commit_finalize_and_undelegate_intent_accounts(), ), + ( + false, + intent_bundle.get_commit_finalize_compressed_intent_accounts(), + ), + ( + true, + intent_bundle + .get_commit_finalize_compressed_and_undelegate_intent_accounts(), + ), ] .into_iter() .filter_map(|(undelegate, accounts)| { @@ -501,6 +510,8 @@ mod tests { commit_and_undelegate: None, commit_finalize: None, commit_finalize_and_undelegate: None, + commit_finalize_compressed: None, + commit_finalize_compressed_and_undelegate: None, standalone_actions: vec![], } } @@ -514,6 +525,8 @@ mod tests { }), commit_finalize: None, commit_finalize_and_undelegate: None, + commit_finalize_compressed: None, + commit_finalize_compressed_and_undelegate: None, standalone_actions: vec![], } } @@ -527,6 +540,8 @@ mod tests { }), commit_finalize: None, commit_finalize_and_undelegate: None, + commit_finalize_compressed: None, + commit_finalize_compressed_and_undelegate: None, standalone_actions: vec![], } } @@ -537,6 +552,8 @@ mod tests { commit_and_undelegate: None, commit_finalize: None, commit_finalize_and_undelegate: None, + commit_finalize_compressed: None, + commit_finalize_compressed_and_undelegate: None, standalone_actions: vec![], } } diff --git a/magicblock-committor-service/src/service.rs b/magicblock-committor-service/src/service.rs index bbec9d805..34dad6d52 100644 --- a/magicblock-committor-service/src/service.rs +++ b/magicblock-committor-service/src/service.rs @@ -88,6 +88,7 @@ pub enum CommittorMessage { respond_to: oneshot::Sender>>, pubkeys: Vec, + compressed: bool, min_context_slot: u64, }, FetchCurrentCommitNoncesSync { @@ -95,6 +96,7 @@ pub enum CommittorMessage { CommittorServiceResult>, >, pubkeys: Vec, + compressed: bool, min_context_slot: u64, }, } @@ -248,12 +250,17 @@ impl CommittorActor { FetchCurrentCommitNonces { respond_to, pubkeys, + compressed, min_context_slot, } => { let processor = self.processor.clone(); tokio::spawn(async move { let result = processor - .fetch_current_commit_nonces(&pubkeys, min_context_slot) + .fetch_current_commit_nonces( + &pubkeys, + compressed, + min_context_slot, + ) .await; if let Err(err) = respond_to .send(result.map_err(CommittorServiceError::from)) @@ -265,12 +272,17 @@ impl CommittorActor { FetchCurrentCommitNoncesSync { respond_to, pubkeys, + compressed, min_context_slot, } => { let processor = self.processor.clone(); tokio::spawn(async move { let result = processor - .fetch_current_commit_nonces(&pubkeys, min_context_slot) + .fetch_current_commit_nonces( + &pubkeys, + compressed, + min_context_slot, + ) .await; if let Err(err) = respond_to .send(result.map_err(CommittorServiceError::from)) @@ -386,6 +398,7 @@ impl CommittorService { pub fn fetch_current_commit_nonces_sync( &self, pubkeys: &[Pubkey], + compressed: bool, min_context_slot: u64, ) -> std::sync::mpsc::Receiver>> { @@ -393,6 +406,7 @@ impl CommittorService { self.try_send(CommittorMessage::FetchCurrentCommitNoncesSync { respond_to: tx, pubkeys: pubkeys.to_vec(), + compressed, min_context_slot, }); rx @@ -496,12 +510,14 @@ impl BaseIntentCommittor for CommittorService { fn fetch_current_commit_nonces( &self, pubkeys: &[Pubkey], + compressed: bool, min_context_slot: u64, ) -> oneshot::Receiver>> { let (tx, rx) = oneshot::channel(); self.try_send(CommittorMessage::FetchCurrentCommitNonces { respond_to: tx, pubkeys: pubkeys.to_vec(), + compressed, min_context_slot, }); @@ -559,6 +575,7 @@ pub trait BaseIntentCommittor: Send + Sync + 'static { fn fetch_current_commit_nonces( &self, pubkeys: &[Pubkey], + compressed: bool, min_context_slot: u64, ) -> oneshot::Receiver>>; diff --git a/magicblock-committor-service/src/service_ext.rs b/magicblock-committor-service/src/service_ext.rs index 024d0423e..b40f19a92 100644 --- a/magicblock-committor-service/src/service_ext.rs +++ b/magicblock-committor-service/src/service_ext.rs @@ -210,10 +210,14 @@ impl BaseIntentCommittor for CommittorServiceExt { fn fetch_current_commit_nonces( &self, pubkeys: &[Pubkey], + compressed: bool, min_context_slot: u64, ) -> oneshot::Receiver>> { - self.inner - .fetch_current_commit_nonces(pubkeys, min_context_slot) + self.inner.fetch_current_commit_nonces( + pubkeys, + compressed, + min_context_slot, + ) } fn stop(&self) { diff --git a/magicblock-committor-service/src/stubs/changeset_committor_stub.rs b/magicblock-committor-service/src/stubs/changeset_committor_stub.rs index 0b417db47..ac9f79d4c 100644 --- a/magicblock-committor-service/src/stubs/changeset_committor_stub.rs +++ b/magicblock-committor-service/src/stubs/changeset_committor_stub.rs @@ -195,6 +195,7 @@ impl BaseIntentCommittor for ChangesetCommittorStub { fn fetch_current_commit_nonces( &self, pubkeys: &[Pubkey], + _compressed: bool, _min_context_slot: u64, ) -> oneshot::Receiver>> { let (tx, rx) = oneshot::channel(); diff --git a/magicblock-committor-service/src/tasks/commit_finalize_compressed_task.rs b/magicblock-committor-service/src/tasks/commit_finalize_compressed_task.rs new file mode 100644 index 000000000..53ed1978a --- /dev/null +++ b/magicblock-committor-service/src/tasks/commit_finalize_compressed_task.rs @@ -0,0 +1,57 @@ +use compressed_delegation_api::CommitAndFinalizeArgs; +use magicblock_core::intent::CommittedAccount; +use solana_instruction::Instruction; +use solana_pubkey::Pubkey; + +use crate::{ + intent_executor::task_info_fetcher::CompressedData, tasks::BaseTaskImpl, +}; + +/// A task that commits a delegated account's state to the base layer and finalizes it in the same +/// instruction, using compressed data. +/// +/// The delivery strategy ([`CommitDelivery`]) determines how the data reaches +/// the chain (inline args vs buffer, full state vs diff). +#[derive(Clone, Debug)] +pub struct CommitFinalizeCompressedTask { + pub commit_id: u64, + pub allow_undelegation: bool, + pub committed_account: CommittedAccount, + pub compressed_data: CompressedData, +} + +impl CommitFinalizeCompressedTask { + #[inline(always)] + pub fn instruction(&self, validator: &Pubkey) -> Instruction { + let args = CommitAndFinalizeArgs { + current_compressed_delegated_account_data: self + .compressed_data + .compressed_delegation_record_bytes + .clone(), + new_data: self.committed_account.account.data.clone(), + account_meta: self.compressed_data.account_meta, + validity_proof: self.compressed_data.proof, + update_nonce: self.commit_id, + allow_undelegation: self.allow_undelegation, + }; + + compressed_delegation_client::builders::CommitAndFinalizeBuilder { + validator: *validator, + delegated_account: self.committed_account.pubkey, + remaining_accounts: self.compressed_data.remaining_accounts.clone(), + args, + } + .instruction() + .expect("The serializing the args should not fail") + } + + pub fn reset_commit_id(&mut self, commit_id: u64) { + self.commit_id = commit_id; + } +} + +impl From for BaseTaskImpl { + fn from(value: CommitFinalizeCompressedTask) -> Self { + Self::CommitFinalizeCompressed(value) + } +} diff --git a/magicblock-committor-service/src/tasks/mod.rs b/magicblock-committor-service/src/tasks/mod.rs index 033877bdd..e1d154b9a 100644 --- a/magicblock-committor-service/src/tasks/mod.rs +++ b/magicblock-committor-service/src/tasks/mod.rs @@ -10,12 +10,13 @@ use magicblock_committor_program::{ }, pdas, ChangesetChunks, Chunks, }; -use magicblock_core::intent::BaseActionCallback; +use magicblock_core::intent::{BaseActionCallback, CommittedAccount}; use magicblock_metrics::metrics::LabelValue; use magicblock_program::magic_scheduled_base_intent::BaseAction; use solana_instruction::{AccountMeta, Instruction}; use solana_pubkey::Pubkey; +pub mod commit_finalize_compressed_task; pub mod commit_finalize_task; pub mod commit_task; pub mod task_builder; @@ -25,18 +26,10 @@ pub mod utils; pub use task_builder::TaskBuilderImpl; use crate::tasks::{ + commit_finalize_compressed_task::CommitFinalizeCompressedTask, commit_finalize_task::CommitFinalizeTask, commit_task::CommitTask, }; -#[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub enum TaskType { - Commit, - CommitFinalize, - Finalize, - Undelegate, - Action, -} - #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub enum TaskStrategy { Args, @@ -50,6 +43,7 @@ pub enum BaseTaskImpl { Finalize(FinalizeTask), Undelegate(UndelegateTask), BaseAction(BaseActionTask), + CommitFinalizeCompressed(CommitFinalizeCompressedTask), } impl BaseTask for BaseTaskImpl { @@ -64,6 +58,9 @@ impl BaseTask for BaseTaskImpl { Self::Finalize(value) => value.instruction(validator), Self::Undelegate(value) => value.instruction(validator), Self::BaseAction(value) => value.instruction(validator), + Self::CommitFinalizeCompressed(value) => { + value.instruction(validator) + } } } @@ -82,6 +79,7 @@ impl BaseTask for BaseTaskImpl { Self::BaseAction(value) => value.compute_units(), Self::Finalize(_) => 70_000, Self::Undelegate(_) => 70_000, + Self::CommitFinalizeCompressed(_) => 250_000, } } @@ -89,6 +87,11 @@ impl BaseTask for BaseTaskImpl { match self { Self::Commit(value) => value.accounts_size_budget(), Self::CommitFinalize(value) => value.accounts_size_budget(), + Self::CommitFinalizeCompressed(_) => { + dlp_api::instruction_builder::finalize_size_budget( + AccountSizeClass::Huge, + ) + } Self::BaseAction(value) => value.accounts_size_budget(), Self::Finalize(_) => { dlp_api::instruction_builder::finalize_size_budget( @@ -111,7 +114,43 @@ impl BaseTaskImpl { Self::CommitFinalize(task) if task.is_buffer() => { TaskStrategy::Buffer } - _ => TaskStrategy::Args, + Self::Commit(_) + | Self::CommitFinalize(_) + | Self::Finalize(_) + | Self::Undelegate(_) + | Self::BaseAction(_) + | Self::CommitFinalizeCompressed(_) => TaskStrategy::Args, + } + } + + pub fn commit_id(&self) -> Option { + match self { + Self::Commit(task) => Some(task.commit_id), + Self::CommitFinalize(task) => Some(task.commit_id), + Self::CommitFinalizeCompressed(task) => Some(task.commit_id), + _ => None, + } + } + + pub fn reset_commit_id(&mut self, commit_id: u64) { + match self { + Self::Commit(task) => task.reset_commit_id(commit_id), + Self::CommitFinalize(task) => task.reset_commit_id(commit_id), + Self::CommitFinalizeCompressed(task) => { + task.reset_commit_id(commit_id) + } + _ => {} + } + } + + pub fn committed_account(&self) -> Option<&CommittedAccount> { + match self { + Self::Commit(task) => Some(&task.committed_account), + Self::CommitFinalize(task) => Some(&task.committed_account), + Self::CommitFinalizeCompressed(task) => { + Some(&task.committed_account) + } + _ => None, } } } @@ -137,6 +176,9 @@ impl LabelValue for BaseTaskImpl { Self::Undelegate(_) => "args_undelegate", Self::BaseAction(BaseActionTask::V1(_)) => "args_action", Self::BaseAction(BaseActionTask::V2(_)) => "args_action_v2", + Self::CommitFinalizeCompressed(_) => { + "args_commit_finalize_compressed" + } } } } diff --git a/magicblock-committor-service/src/tasks/task_builder.rs b/magicblock-committor-service/src/tasks/task_builder.rs index 515e925f5..f65064cf2 100644 --- a/magicblock-committor-service/src/tasks/task_builder.rs +++ b/magicblock-committor-service/src/tasks/task_builder.rs @@ -14,10 +14,12 @@ use tracing::error; use crate::{ intent_executor::task_info_fetcher::{ - TaskInfoFetcher, TaskInfoFetcherError, TaskInfoFetcherResult, + CompressedData, PhotonFetcherError, TaskInfoFetcher, + TaskInfoFetcherError, TaskInfoFetcherResult, }, persist::IntentPersister, tasks::{ + commit_finalize_compressed_task::CommitFinalizeCompressedTask, commit_task::{CommitDelivery, CommitTask}, BaseActionTask, BaseActionTaskV1, BaseActionTaskV2, BaseTaskImpl, CommitFinalizeTask, FinalizeTask, UndelegateTask, @@ -46,6 +48,9 @@ pub struct CommitStageTaskInfo { commit_nonces: HashMap, /// Base account state for diff calculation base_accounts: HashMap, + /// Data used for compressed accounts + compressed_data: + HashMap>, } /// Task builder @@ -106,30 +111,50 @@ impl TaskBuilderImpl { async fn fetch_commit_nonces( task_info_fetcher: &Arc, - accounts: &[CommittedAccount], + accounts: &[(CommittedAccount, bool)], min_context_slot: u64, ) -> TaskInfoFetcherResult> { - let committed_pubkeys = accounts - .iter() - .map(|account| account.pubkey) + let (regular_accounts, compressed_accounts): (Vec<_>, Vec<_>) = + accounts.iter().partition(|(_, compressed)| !compressed); + let regular_pubkeys = regular_accounts + .into_iter() + .map(|(account, _)| account.pubkey) + .collect::>(); + let compressed_pubkeys = compressed_accounts + .into_iter() + .map(|(account, _)| account.pubkey) .collect::>(); - task_info_fetcher - .fetch_next_commit_nonces(&committed_pubkeys, min_context_slot) - .await + let (regular_nonces, compressed_nonces) = tokio::join!( + task_info_fetcher.fetch_next_commit_nonces( + ®ular_pubkeys, + false, + min_context_slot + ), + task_info_fetcher.fetch_next_commit_nonces( + &compressed_pubkeys, + true, + min_context_slot, + ) + ); + Ok(regular_nonces? + .into_iter() + .chain(compressed_nonces?.into_iter()) + .collect::>()) } async fn fetch_diffable_accounts( task_info_fetcher: &Arc, - accounts: &[CommittedAccount], + accounts: &[(CommittedAccount, bool)], min_context_slot: u64, ) -> TaskInfoFetcherResult> { let diffable_pubkeys = accounts .iter() - .filter(|account| { + .filter(|(account, compressed)| { account.account.data.len() > COMMIT_STATE_SIZE_THRESHOLD + && !compressed }) - .map(|account| account.pubkey) + .map(|(account, _)| account.pubkey) .collect::>(); task_info_fetcher @@ -137,6 +162,32 @@ impl TaskBuilderImpl { .await } + async fn fetch_compressed_data( + task_info_fetcher: &Arc, + accounts: &[(CommittedAccount, bool)], + min_context_slot: u64, + ) -> TaskInfoFetcherResult< + HashMap>, + > { + let pubkeys = accounts + .iter() + .filter(|(_, compressed)| *compressed) + .map(|(account, _)| account.pubkey) + .collect::>(); + Ok(pubkeys + .iter() + .zip( + task_info_fetcher + .get_compressed_data_for_accounts( + &pubkeys, + Some(min_context_slot), + ) + .await?, + ) + .map(|(pk, data)| (*pk, data)) + .collect()) + } + async fn fetch_commit_stage_info( intent_bundle: &ScheduledIntentBundle, task_info_fetcher: &Arc, @@ -144,21 +195,39 @@ impl TaskBuilderImpl { ) -> TaskBuilderResult { // Fetch necessary data for BaseTasks creation let all_committed_accounts = intent_bundle.get_all_committed_accounts(); + let all_regular_committed_accounts = + intent_bundle.get_all_regular_committed_accounts(); + let all_compressed_committed_accounts = + intent_bundle.get_all_compressed_committed_accounts(); + let flagged_accounts = all_regular_committed_accounts + .into_iter() + .map(|acc| (acc, false)) + .chain( + all_compressed_committed_accounts + .into_iter() + .map(|acc| (acc, true)), + ) + .collect::>(); // Get commit nonces and base accounts let min_context_slot = all_committed_accounts .iter() .map(|account| account.remote_slot) .max() .unwrap_or(0); - let (commit_ids, base_accounts) = tokio::join!( + let (commit_ids, base_accounts, compressed_data) = tokio::join!( Self::fetch_commit_nonces( task_info_fetcher, - &all_committed_accounts, + &flagged_accounts, min_context_slot ), Self::fetch_diffable_accounts( task_info_fetcher, - &all_committed_accounts, + &flagged_accounts, + min_context_slot + ), + Self::fetch_compressed_data( + task_info_fetcher, + &flagged_accounts, min_context_slot ) ); @@ -168,6 +237,9 @@ impl TaskBuilderImpl { tracing::warn!(intent_id = intent_bundle.id, error = ?err, "Failed to fetch base accounts, falling back to CommitState"); Default::default() }); + let compressed_data = compressed_data.map_err( + TaskBuilderError::CommitFinalizeCompressedTasksBuildError, + )?; // Persist commit ids for commitees commit_nonces @@ -181,6 +253,7 @@ impl TaskBuilderImpl { Ok(CommitStageTaskInfo { commit_nonces, base_accounts, + compressed_data, }) } @@ -210,6 +283,20 @@ impl TaskBuilderImpl { delivery: delivery_details, } } + + pub fn create_commit_finalize_compressed_task( + commit_id: u64, + allow_undelegation: bool, + account: CommittedAccount, + compressed_data: CompressedData, + ) -> CommitFinalizeCompressedTask { + CommitFinalizeCompressedTask { + commit_id, + allow_undelegation, + committed_account: account, + compressed_data, + } + } } #[async_trait] @@ -230,6 +317,7 @@ impl TasksBuilder for TaskBuilderImpl { let CommitStageTaskInfo { mut commit_nonces, mut base_accounts, + mut compressed_data, } = Self::fetch_commit_stage_info( intent_bundle, task_info_fetcher, @@ -278,6 +366,31 @@ impl TasksBuilder for TaskBuilderImpl { .build(&value.commit_action), ); } + if let Some(ref value) = + intent_bundle.intent_bundle.commit_finalize_compressed + { + tasks.extend( + CommitFinalizeCompressedBuilder { + commit_nonces: &mut commit_nonces, + base_accounts: &mut base_accounts, + compressed_data: &mut compressed_data, + } + .build(value)?, + ); + } + if let Some(ref value) = intent_bundle + .intent_bundle + .commit_finalize_compressed_and_undelegate + { + tasks.extend( + CommitFinalizeAndUndelegateCompressedBuilder { + commit_nonces: &mut commit_nonces, + base_accounts: &mut base_accounts, + compressed_data: &mut compressed_data, + } + .build(value)?, + ); + } Ok(tasks) } @@ -510,6 +623,105 @@ impl<'a> CommitFinalizeAndUndelegateBuilder<'a> { } } +struct CommitFinalizeCompressedBuilder<'a> { + commit_nonces: &'a mut HashMap, + base_accounts: &'a mut HashMap, + compressed_data: + &'a mut HashMap>, +} + +impl<'a> CommitFinalizeCompressedBuilder<'a> { + fn build( + &mut self, + commit_type: &CommitType, + ) -> TaskBuilderResult> { + let mut tasks: Vec = commit_type + .get_committed_accounts() + .iter() + .map(|account| -> TaskBuilderResult { + let nonce = + take_commit_nonce(self.commit_nonces, account.pubkey); + let _base = self.base_accounts.remove(&account.pubkey); + let compressed_data = self + .compressed_data + .remove(&account.pubkey) + .ok_or( + TaskBuilderError::CommitFinalizeCompressedTasksBuildError( + PhotonFetcherError::MissingCompressedData.into(), + ), + )? + .map_err(TaskBuilderError::CommitFinalizeCompressedTasksBuildError)?; + Ok( + TaskBuilderImpl::create_commit_finalize_compressed_task( + nonce, + false, + account.clone(), + compressed_data, + ) + .into(), + ) + }) + .collect::, _>>()?; + if let CommitType::WithBaseActions { + ref base_actions, .. + } = commit_type + { + tasks.extend(TaskBuilderImpl::create_action_tasks(base_actions)); + } + Ok(tasks) + } +} + +struct CommitFinalizeAndUndelegateCompressedBuilder<'a> { + commit_nonces: &'a mut HashMap, + base_accounts: &'a mut HashMap, + compressed_data: + &'a mut HashMap>, +} + +impl<'a> CommitFinalizeAndUndelegateCompressedBuilder<'a> { + fn build( + &mut self, + commit_and_undelegate: &CommitAndUndelegate, + ) -> TaskBuilderResult> { + let commit_type = &commit_and_undelegate.commit_action; + let mut tasks: Vec = commit_type + .get_committed_accounts() + .iter() + .map(|account| -> TaskBuilderResult { + let nonce = + take_commit_nonce(self.commit_nonces, account.pubkey); + let _base = self.base_accounts.remove(&account.pubkey); + let compressed_data = self + .compressed_data + .remove(&account.pubkey) + .ok_or( + TaskBuilderError::CommitFinalizeCompressedTasksBuildError( + PhotonFetcherError::MissingCompressedData.into(), + ), + )? + .map_err(TaskBuilderError::CommitFinalizeCompressedTasksBuildError)?; + Ok( + TaskBuilderImpl::create_commit_finalize_compressed_task( + nonce, + true, + account.clone(), + compressed_data, + ) + .into(), + ) + }) + .collect::, _>>()?; + if let CommitType::WithBaseActions { + ref base_actions, .. + } = commit_type + { + tasks.extend(TaskBuilderImpl::create_action_tasks(base_actions)); + } + Ok(tasks) + } +} + fn take_commit_nonce( commit_nonces: &mut HashMap, pubkey: Pubkey, @@ -529,6 +741,8 @@ pub enum TaskBuilderError { CommitTasksBuildError(#[source] TaskInfoFetcherError), #[error("FinalizedTasksBuildError: {0}")] FinalizedTasksBuildError(#[source] TaskInfoFetcherError), + #[error("CommitFinalizeCompressedTasksBuildError: {0}")] + CommitFinalizeCompressedTasksBuildError(#[source] TaskInfoFetcherError), } impl TaskBuilderError { @@ -536,6 +750,7 @@ impl TaskBuilderError { match self { Self::CommitTasksBuildError(err) => err.signature(), Self::FinalizedTasksBuildError(err) => err.signature(), + Self::CommitFinalizeCompressedTasksBuildError(_) => None, } } } diff --git a/magicblock-committor-service/src/tasks/task_strategist.rs b/magicblock-committor-service/src/tasks/task_strategist.rs index eeba22ac5..4705ec296 100644 --- a/magicblock-committor-service/src/tasks/task_strategist.rs +++ b/magicblock-committor-service/src/tasks/task_strategist.rs @@ -364,7 +364,14 @@ impl TaskStrategist { &commit_finalize_task.delivery, ), ), - _ => continue, + BaseTaskImpl::CommitFinalizeCompressed(task) => ( + task.commit_id, + task.committed_account.pubkey, + CommitStrategy::StateArgs, + ), + BaseTaskImpl::Undelegate(_) + | BaseTaskImpl::Finalize(_) + | BaseTaskImpl::BaseAction(_) => continue, }; if let Err(err) = persistor.set_commit_strategy( commit_id, @@ -479,7 +486,7 @@ mod tests { use crate::{ intent_execution_manager::intent_scheduler::create_test_intent, intent_executor::task_info_fetcher::{ - TaskInfoFetcher, TaskInfoFetcherResult, + CompressedData, TaskInfoFetcher, TaskInfoFetcherResult, }, persist::IntentPersisterImpl, tasks::{ @@ -500,6 +507,7 @@ mod tests { async fn fetch_next_commit_nonces( &self, pubkeys: &[Pubkey], + _: bool, _: u64, ) -> TaskInfoFetcherResult> { Ok(pubkeys.iter().map(|pubkey| (*pubkey, 0)).collect()) @@ -508,6 +516,7 @@ mod tests { async fn fetch_current_commit_nonces( &self, pubkeys: &[Pubkey], + _: bool, _: u64, ) -> TaskInfoFetcherResult> { Ok(pubkeys.iter().map(|pubkey| (*pubkey, 0)).collect()) @@ -528,6 +537,14 @@ mod tests { ) -> TaskInfoFetcherResult> { Ok(Default::default()) } + + async fn get_compressed_data( + &self, + _: &Pubkey, + _: Option, + ) -> TaskInfoFetcherResult { + Ok(Default::default()) + } } // Helper to create a simple commit task diff --git a/magicblock-config/README.md b/magicblock-config/README.md index 79b88c99d..b1504d703 100644 --- a/magicblock-config/README.md +++ b/magicblock-config/README.md @@ -53,10 +53,10 @@ Environment variables are mapped using the `figment` provider. ### Examples -| Struct Field | Config Section | Environment Variable | -| :--- | :--- | :--- | -| `validator.basefee` | `[validator]` | `MBV_VALIDATOR__BASEFEE` | -| `ledger.block_time` | `[ledger]` | `MBV_LEDGER__BLOCK_TIME` | +| Struct Field | Config Section | Environment Variable | +| :----------------------------- | :------------------ | :---------------------------------- | +| `validator.basefee` | `[validator]` | `MBV_VALIDATOR__BASEFEE` | +| `ledger.block_time` | `[ledger]` | `MBV_LEDGER__BLOCK_TIME` | | `chain_operation.country_code` | `[chain-operation]` | `MBV_CHAIN_OPERATION__COUNTRY_CODE` | ## Configuration File @@ -93,6 +93,7 @@ The configuration is split into domain-specific structs available in `src/config * **`ChainLinkConfig`**: Account cloning settings. * **`CommitStrategy`**: Compute unit pricing for base chain commits. * **`TaskSchedulerConfig`**: Task scheduling settings. + * **`CompressionConfig`**: Compression settings. ## Testing diff --git a/magicblock-config/src/config/compression.rs b/magicblock-config/src/config/compression.rs new file mode 100644 index 000000000..a872b56aa --- /dev/null +++ b/magicblock-config/src/config/compression.rs @@ -0,0 +1,9 @@ +use serde::{Deserialize, Serialize}; + +/// Configuration for the compression service. +#[derive(Deserialize, Serialize, Debug, Clone, Default)] +#[serde(rename_all = "kebab-case", deny_unknown_fields, default)] +pub struct CompressionConfig { + /// The URL of the Photon indexer. + pub photon_url: Option, +} diff --git a/magicblock-config/src/config/mod.rs b/magicblock-config/src/config/mod.rs index 5d9377d10..19390a2dc 100644 --- a/magicblock-config/src/config/mod.rs +++ b/magicblock-config/src/config/mod.rs @@ -2,6 +2,7 @@ pub mod accounts; pub mod aperture; pub mod chain; pub mod cli; +pub mod compression; pub mod grpc; pub mod ledger; pub mod lifecycle; @@ -17,6 +18,7 @@ pub use chain::{ AllowedProgram, ChainLinkConfig, ChainOperationConfig, CommittorConfig, RiskConfig, }; +pub use compression::CompressionConfig; pub use grpc::GrpcConfig; pub use ledger::LedgerConfig; pub use lifecycle::LifecycleMode; diff --git a/magicblock-config/src/lib.rs b/magicblock-config/src/lib.rs index 2f19e7511..07f6df853 100644 --- a/magicblock-config/src/lib.rs +++ b/magicblock-config/src/lib.rs @@ -22,8 +22,8 @@ pub mod types; use crate::{ config::{ AccountsDbConfig, ChainLinkConfig, ChainOperationConfig, - CommittorConfig, LedgerConfig, LoadableProgram, TaskSchedulerConfig, - ValidatorConfig, + CommittorConfig, CompressionConfig, LedgerConfig, LoadableProgram, + TaskSchedulerConfig, ValidatorConfig, }, types::Remote, }; @@ -64,6 +64,7 @@ pub struct ValidatorParams { pub chainlink: ChainLinkConfig, pub chain_operation: Option, pub task_scheduler: TaskSchedulerConfig, + pub compression: Option, pub programs: Vec, } diff --git a/magicblock-config/src/tests.rs b/magicblock-config/src/tests.rs index 50632ad6e..0aaa36278 100644 --- a/magicblock-config/src/tests.rs +++ b/magicblock-config/src/tests.rs @@ -301,6 +301,33 @@ fn test_chainlink_config() { assert_eq!(config.chainlink.risk.risk_score_threshold, 8); } +#[test] +#[parallel] +fn test_compression_config() { + // Verify compression config is loaded correctly + let (_dir, config_path) = create_temp_config( + r#" + [compression] + photon-url = "http://localhost:8784" + "#, + ); + + let config = run_cli(vec![config_path.to_str().unwrap()]); + + assert_eq!( + config.compression.as_ref().unwrap().photon_url, + Some("http://localhost:8784".to_string()) + ); +} + +#[test] +#[parallel] +fn test_compression_config_is_optional() { + let config = run_cli(vec![]); + + assert!(config.compression.is_none()); +} + // ============================================================================ // 6. Type Parsing & Validation // ============================================================================ @@ -492,6 +519,12 @@ fn test_example_config_full_coverage() { Duration::from_secs(60 * 60) ); + // Compression config is present + assert_eq!( + config.compression.as_ref().unwrap().photon_url, + Some("http://localhost:8784".to_string()) + ); + // The example file has the programs section with 2 entries assert_eq!( config.programs.len(), diff --git a/magicblock-core/Cargo.toml b/magicblock-core/Cargo.toml index fe621634b..a5decb6b9 100644 --- a/magicblock-core/Cargo.toml +++ b/magicblock-core/Cargo.toml @@ -8,7 +8,9 @@ license.workspace = true edition.workspace = true [dependencies] - +light-client = { workspace = true } +light-sdk = { workspace = true, features = ["v2"] } +compressed-delegation-client = { workspace = true } console-subscriber = { workspace = true, optional = true } tokio = { workspace = true, features = ["sync"] } flume = { workspace = true } diff --git a/magicblock-core/src/compression.rs b/magicblock-core/src/compression.rs new file mode 100644 index 000000000..52cbee6eb --- /dev/null +++ b/magicblock-core/src/compression.rs @@ -0,0 +1,39 @@ +use light_sdk::address::v2::derive_address; +use solana_pubkey::Pubkey; + +// Light protocol V2 accounts: +// https://www.zkcompression.com/resources/addresses-and-urls#v2-2 +pub const ADDRESS_TREE: Pubkey = + Pubkey::from_str_const("amt2kaJA14v3urZbZvnc5v2np8jqvc4Z8zDep5wbtzx"); +pub const OUTPUT_QUEUE: Pubkey = + Pubkey::from_str_const("oq1na8gojfdUhsfCpyjNt6h4JaDWtHf1yQj4koBWfto"); + +/// Derives a CDA (Compressed derived Address) from a PDA (Program derived Address) +/// of a compressed account we want to use in our validator in uncompressed form. +pub fn derive_cda_from_pda(pda: &Pubkey) -> Pubkey { + // Since the PDA is already unique we use the delegation program's id + // as a program id. + let (address, _seed) = derive_address( + &[pda.as_array()], + &ADDRESS_TREE.to_bytes().into(), + &compressed_delegation_client::ID.to_bytes().into(), + ); + Pubkey::new_from_array(address) +} + +#[cfg(test)] +mod tests { + use solana_pubkey::pubkey; + + use super::*; + + #[test] + fn test_derive_cda_from_pda() { + let pda = pubkey!("6pyGAQnqveUcHJ4iT1B6N72iJSBWcb6KRht315Fo7mLX"); + let cda = derive_cda_from_pda(&pda); + assert_eq!( + cda, + pubkey!("13CJjg6sMzZ8Lsn1oyQggzcyq5nFHYt97i7bhMu7BNu9") + ); + } +} diff --git a/magicblock-core/src/lib.rs b/magicblock-core/src/lib.rs index 3bb588051..3a4d4e865 100644 --- a/magicblock-core/src/lib.rs +++ b/magicblock-core/src/lib.rs @@ -15,6 +15,7 @@ macro_rules! debug_panic { ) } +pub mod compression; pub mod coordination_mode; pub mod intent; pub mod link; diff --git a/magicblock-core/src/traits.rs b/magicblock-core/src/traits.rs index 7ccc27bae..c07aaa130 100644 --- a/magicblock-core/src/traits.rs +++ b/magicblock-core/src/traits.rs @@ -18,7 +18,10 @@ pub trait MagicSys: Sync + Send + 'static { fn fetch_current_commit_nonces( &self, commits: &[CommittedAccount], + compressed: bool, ) -> Result, InstructionError>; + + fn is_compression_enabled(&self) -> bool; } /// Provides read access to the latest confirmed block's metadata. diff --git a/magicblock-magic-program-api/src/args.rs b/magicblock-magic-program-api/src/args.rs index 00b9a250d..e8787f196 100644 --- a/magicblock-magic-program-api/src/args.rs +++ b/magicblock-magic-program-api/src/args.rs @@ -86,6 +86,8 @@ pub enum MagicBaseIntentArgs { CommitAndUndelegate(CommitAndUndelegateArgs), CommitFinalize(CommitTypeArgs), CommitFinalizeAndUndelegate(CommitAndUndelegateArgs), + CommitFinalizeCompressed(CommitTypeArgs), + CommitFinalizeAndUndelegateCompressed(CommitAndUndelegateArgs), } #[derive(Clone, Default, Serialize, Deserialize, Debug, PartialEq, Eq)] @@ -94,6 +96,9 @@ pub struct MagicIntentBundleArgs { pub commit_and_undelegate: Option, pub commit_finalize: Option, pub commit_finalize_and_undelegate: Option, + pub commit_finalize_compressed: Option, + pub commit_finalize_compressed_and_undelegate: + Option, pub standalone_actions: Vec, } @@ -114,6 +119,12 @@ impl From for MagicIntentBundleArgs { MagicBaseIntentArgs::CommitFinalizeAndUndelegate(value) => { this.commit_finalize_and_undelegate = Some(value) } + MagicBaseIntentArgs::CommitFinalizeCompressed(value) => { + this.commit_finalize_compressed = Some(value) + } + MagicBaseIntentArgs::CommitFinalizeAndUndelegateCompressed( + value, + ) => this.commit_finalize_compressed_and_undelegate = Some(value), } this diff --git a/magicblock-magic-program-api/src/instruction.rs b/magicblock-magic-program-api/src/instruction.rs index 6b3655ff5..7ca1daa83 100644 --- a/magicblock-magic-program-api/src/instruction.rs +++ b/magicblock-magic-program-api/src/instruction.rs @@ -11,6 +11,7 @@ use crate::{ Pubkey, }; +#[allow(clippy::large_enum_variant)] #[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)] pub enum MagicBlockInstruction { /// Modify one or more accounts @@ -323,6 +324,7 @@ pub struct AccountModification { pub pubkey: Pubkey, pub owner: Option, pub delegated: Option, + pub compressed: Option, pub confined: Option, } @@ -330,6 +332,7 @@ pub struct AccountModification { pub struct AccountModificationForInstruction { pub owner: Option, pub delegated: Option, + pub compressed: Option, pub confined: Option, } @@ -343,6 +346,7 @@ pub struct AccountCloneFields { pub executable: bool, pub delegated: bool, pub confined: bool, + pub compressed: bool, pub remote_slot: u64, } diff --git a/magicblock-metrics/src/metrics/mod.rs b/magicblock-metrics/src/metrics/mod.rs index 296dd3f6c..edbfce9a7 100644 --- a/magicblock-metrics/src/metrics/mod.rs +++ b/magicblock-metrics/src/metrics/mod.rs @@ -286,6 +286,41 @@ lazy_static::lazy_static! { ) .unwrap(); + // Account fetch results from network (Photon) + pub static ref COMPRESSED_ACCOUNT_FETCHES_SUCCESS_COUNT: IntCounter = + IntCounter::new( + "compressed_account_fetches_success_count", + "Total number of successful network \ + account fetches", + ) + .unwrap(); + + pub static ref COMPRESSED_ACCOUNT_FETCHES_FAILED_COUNT: IntCounter = + IntCounter::new( + "compressed_account_fetches_failed_count", + "Total number of failed network account fetches \ + (RPC errors)", + ) + .unwrap(); + + pub static ref COMPRESSED_ACCOUNT_FETCHES_FOUND_COUNT: IntCounterVec = IntCounterVec::new( + Opts::new( + "compressed_account_fetches_found_count", + "Total number of network account fetches that found an account", + ), + &["origin"], + ) + .unwrap(); + + pub static ref COMPRESSED_ACCOUNT_FETCHES_NOT_FOUND_COUNT: IntCounterVec = IntCounterVec::new( + Opts::new( + "compressed_account_fetches_not_found_count", + "Total number of network account fetches where account was not found", + ), + &["origin"], + ) + .unwrap(); + pub static ref PER_PROGRAM_ACCOUNT_FETCH_STATS: IntCounterVec = IntCounterVec::new( Opts::new( "per_program_account_fetch_stats", @@ -817,6 +852,32 @@ pub fn inc_account_fetches_found(fetch_origin: AccountFetchOrigin, count: u64) { .inc_by(count); } +pub fn inc_compressed_account_fetches_success(count: u64) { + COMPRESSED_ACCOUNT_FETCHES_SUCCESS_COUNT.inc_by(count); +} + +pub fn inc_compressed_account_fetches_found( + fetch_origin: AccountFetchOrigin, + count: u64, +) { + COMPRESSED_ACCOUNT_FETCHES_FOUND_COUNT + .with_label_values(&[fetch_origin.value()]) + .inc_by(count); +} + +pub fn inc_compressed_account_fetches_not_found( + fetch_origin: AccountFetchOrigin, + count: u64, +) { + COMPRESSED_ACCOUNT_FETCHES_NOT_FOUND_COUNT + .with_label_values(&[fetch_origin.value()]) + .inc_by(count); +} + +pub fn inc_compressed_account_fetches_failed(count: u64) { + COMPRESSED_ACCOUNT_FETCHES_FAILED_COUNT.inc_by(count); +} + pub fn inc_account_fetches_not_found( fetch_origin: AccountFetchOrigin, count: u64, diff --git a/programs/magicblock/src/clone_account/common.rs b/programs/magicblock/src/clone_account/common.rs index 26153e636..d32111c1c 100644 --- a/programs/magicblock/src/clone_account/common.rs +++ b/programs/magicblock/src/clone_account/common.rs @@ -212,24 +212,26 @@ pub fn set_account_from_fields( ) -> Result<(), InstructionError> { ic_msg!( invoke_context, - "src account state: lamports={}, owner={}, executable={}, delegated={}, confined={}, remote_slot={}, data_len={}", + "src account state: lamports={}, owner={}, executable={}, delegated={}, confined={}, compressed={}, remote_slot={}, data_len={}", fields.lamports, fields.owner, fields.executable, fields.delegated, fields.confined, + fields.compressed, fields.remote_slot, data.len() ); ic_msg!( invoke_context, - "dest account state: lamports={}, owner={}, executable={}, delegated={}, undelegating={} confined={}, remote_slot={}, data_len={}", + "dest account state: lamports={}, owner={}, executable={}, delegated={}, undelegating={}, confined={}, compressed={}, remote_slot={}, data_len={}", acc.lamports(), acc.owner(), acc.executable(), acc.delegated(), acc.undelegating(), acc.confined(), + acc.compressed(), acc.remote_slot(), acc.data().len() ); @@ -261,6 +263,7 @@ pub fn set_account_from_fields( acc.set_executable(fields.executable); acc.set_delegated(fields.delegated); acc.set_confined(fields.confined); + acc.set_compressed(fields.compressed); acc.set_remote_slot(fields.remote_slot); acc.set_undelegating(false); diff --git a/programs/magicblock/src/clone_account/tests.rs b/programs/magicblock/src/clone_account/tests.rs index 086040f9b..22a2a988b 100644 --- a/programs/magicblock/src/clone_account/tests.rs +++ b/programs/magicblock/src/clone_account/tests.rs @@ -103,6 +103,7 @@ fn test_clone_account_basic() { executable: true, delegated: true, confined: true, + compressed: true, remote_slot: 42, }; let ix = InstructionUtils::clone_account_instruction( @@ -126,6 +127,7 @@ fn test_clone_account_basic() { assert!(account.executable()); assert!(account.delegated()); assert!(account.confined()); + assert!(account.compressed()); assert_eq!(account.remote_slot(), 42); assert_eq!(account.data(), &[1, 2, 3]); } diff --git a/programs/magicblock/src/magic_scheduled_base_intent.rs b/programs/magicblock/src/magic_scheduled_base_intent.rs index e399c52a3..bec70aaea 100644 --- a/programs/magicblock/src/magic_scheduled_base_intent.rs +++ b/programs/magicblock/src/magic_scheduled_base_intent.rs @@ -36,6 +36,9 @@ pub const ACTUAL_COMMIT_LIMIT: u64 = 25; /// Fixed fee per commit. /// https://github.com/magicblock-labs/delegation-program/blob/main/src/consts.rs#L11 pub const COMMIT_FEE_LAMPORTS: u64 = 100_000; +/// Fixed fee per compressed commit. +/// Cost = 2 * (tx cost(5k) + light protocol fee(5k)) = 20k +pub const COMPRESSED_COMMIT_FEE_LAMPORTS: u64 = 20_000; /// Price per compute unit for a BaseAction executed on Solana base chain, /// denominated in micro-lamports per CU (mirrors Solana's priority fee model). pub const COMPUTE_UNIT_PRICE_MICRO_LAMPORTS: u64 = 50_000; @@ -127,6 +130,20 @@ impl ScheduledIntentBundle { self.intent_bundle.get_all_committed_accounts() } + /// Returns all regular accounts that will be committed on Base layer, + /// including the one scheduled for undelegation + pub fn get_all_regular_committed_accounts(&self) -> Vec { + self.intent_bundle.get_all_regular_committed_accounts() + } + + /// Returns all compressed accounts that will be committed on Base layer, + /// including the one scheduled for undelegation + pub fn get_all_compressed_committed_accounts( + &self, + ) -> Vec { + self.intent_bundle.get_all_compressed_committed_accounts() + } + /// Returns pubkeys of all accounts that will be committed on Base layer, /// including the one scheduled for undelegation pub fn get_all_committed_pubkeys(&self) -> Vec { @@ -165,6 +182,21 @@ impl ScheduledIntentBundle { self.intent_bundle.get_commit_finalize_intent_accounts() } + /// Returns `CommitFinalizeCompressed` intent's accounts + pub fn get_commit_finalize_compressed_intent_accounts( + &self, + ) -> Option<&Vec> { + self.intent_bundle + .get_commit_finalize_compressed_intent_accounts() + } + + pub fn get_commit_finalize_compressed_and_undelegate_intent_accounts( + &self, + ) -> Option<&Vec> { + self.intent_bundle + .get_commit_finalize_compressed_and_undelegate_intent_accounts() + } + /// Returns `Commit` intent's accounts pub fn get_commit_intent_accounts_mut( &mut self, @@ -188,6 +220,10 @@ impl ScheduledIntentBundle { self.intent_bundle.has_callbacks() } + pub fn has_compressed_intent(&self) -> bool { + self.intent_bundle.has_compressed_intent() + } + pub fn is_empty(&self) -> bool { self.intent_bundle.is_empty() } @@ -206,6 +242,8 @@ pub enum MagicBaseIntent { CommitAndUndelegate(CommitAndUndelegate), CommitFinalize(CommitType), CommitFinalizeAndUndelegate(CommitAndUndelegate), + CommitFinalizeCompressed(CommitType), + CommitFinalizeAndUndelegateCompressed(CommitAndUndelegate), } // Bundle of BaseIntents @@ -215,6 +253,8 @@ pub struct MagicIntentBundle { pub commit_and_undelegate: Option, pub commit_finalize: Option, pub commit_finalize_and_undelegate: Option, + pub commit_finalize_compressed: Option, + pub commit_finalize_compressed_and_undelegate: Option, pub standalone_actions: Vec, } @@ -235,6 +275,12 @@ impl From for MagicIntentBundle { MagicBaseIntent::CommitFinalizeAndUndelegate(value) => { this.commit_finalize_and_undelegate = Some(value) } + MagicBaseIntent::CommitFinalizeCompressed(value) => { + this.commit_finalize_compressed = Some(value) + } + MagicBaseIntent::CommitFinalizeAndUndelegateCompressed(value) => { + this.commit_finalize_compressed_and_undelegate = Some(value) + } } this @@ -268,6 +314,16 @@ impl MagicIntentBundle { .map(|value| CommitAndUndelegate::try_from_args(value, context)) .transpose()?; + let commit_finalize_compressed = args + .commit_finalize_compressed + .map(|value| CommitType::try_from_args(value, context)) + .transpose()?; + + let commit_finalize_compressed_and_undelegate = args + .commit_finalize_compressed_and_undelegate + .map(|value| CommitAndUndelegate::try_from_args(value, context)) + .transpose()?; + let actions = args .standalone_actions .into_iter() @@ -279,6 +335,8 @@ impl MagicIntentBundle { commit_and_undelegate, commit_finalize, commit_finalize_and_undelegate, + commit_finalize_compressed, + commit_finalize_compressed_and_undelegate, standalone_actions: actions, }; this.post_validation(context)?; @@ -367,6 +425,19 @@ impl MagicIntentBundle { { check(commit_finalize_and_undelegate.get_committed_accounts())?; } + if let Some(commit_finalize_compressed) = + &self.commit_finalize_compressed + { + check(commit_finalize_compressed.get_committed_accounts())?; + } + if let Some(commit_finalize_compressed_and_undelegate) = + &self.commit_finalize_compressed_and_undelegate + { + check( + commit_finalize_compressed_and_undelegate + .get_committed_accounts(), + )?; + } Ok(()) } @@ -377,10 +448,16 @@ impl MagicIntentBundle { ) -> Result { let mut fee = 0; if let Some(ref commit) = self.commit { - fee += commit.calculate_fee(commit_nonces)?; + fee += commit.calculate_fee(commit_nonces, false)?; } if let Some(ref cau) = self.commit_and_undelegate { - fee += cau.calculate_fee(commit_nonces)?; + fee += cau.calculate_fee(commit_nonces, false)?; + } + if let Some(ref commit) = self.commit_finalize_compressed { + fee += commit.calculate_fee(commit_nonces, true)?; + } + if let Some(ref cau) = self.commit_finalize_compressed_and_undelegate { + fee += cau.calculate_fee(commit_nonces, true)?; } fee += calculate_actions_fee(&self.standalone_actions); Ok(fee) @@ -389,6 +466,7 @@ impl MagicIntentBundle { pub fn has_undelegate_intent(&self) -> bool { self.commit_and_undelegate.is_some() || self.commit_finalize_and_undelegate.is_some() + || self.commit_finalize_compressed_and_undelegate.is_some() } pub fn has_committed_accounts(&self) -> bool { @@ -408,11 +486,22 @@ impl MagicIntentBundle { .get_commit_finalize_and_undelegate_intent_accounts() .map(|el| !el.is_empty()) .unwrap_or(false); + let has_commit_finalize_compressed_intent_accounts = self + .get_commit_finalize_compressed_intent_accounts() + .map(|el| !el.is_empty()) + .unwrap_or(false); + let has_commit_finalize_compressed_and_undelegate_intent_accounts = + self.get_commit_finalize_compressed_and_undelegate_intent_accounts( + ) + .map(|el| !el.is_empty()) + .unwrap_or(false); has_commit_intent_accounts || has_undelegate_intent_accounts || has_commit_finalize_intent_accounts || has_commit_finalize_and_undelegate_intent_accounts + || has_commit_finalize_compressed_intent_accounts + || has_commit_finalize_compressed_and_undelegate_intent_accounts } /// Returns `[CommitAndUndelegate]` intent's accounts @@ -442,6 +531,27 @@ impl MagicIntentBundle { ) } + /// Returns `[CommitType]` intent's accounts + pub fn get_commit_finalize_compressed_intent_accounts( + &self, + ) -> Option<&Vec> { + Some( + self.commit_finalize_compressed + .as_ref()? + .get_committed_accounts(), + ) + } + + pub fn get_commit_finalize_compressed_and_undelegate_intent_accounts( + &self, + ) -> Option<&Vec> { + Some( + self.commit_finalize_compressed_and_undelegate + .as_ref()? + .get_committed_accounts(), + ) + } + /// Returns `Commit` intent's accounts pub fn get_commit_finalize_intent_accounts( &self, @@ -459,6 +569,34 @@ impl MagicIntentBundle { /// Returns all the accounts that will be committed, /// including the ones that will be undelegated as well pub fn get_all_committed_accounts(&self) -> Vec { + let committed = self.get_commit_intent_accounts(); + let undelegated = self.get_undelegate_intent_accounts(); + let commit_finalize = self.get_commit_finalize_intent_accounts(); + let commit_finalize_and_undelegate = + self.get_commit_finalize_and_undelegate_intent_accounts(); + let commit_finalize_compressed = + self.get_commit_finalize_compressed_intent_accounts(); + let commit_finalize_compressed_and_unde = self + .get_commit_finalize_compressed_and_undelegate_intent_accounts(); + + [ + committed, + undelegated, + commit_finalize, + commit_finalize_and_undelegate, + commit_finalize_compressed, + commit_finalize_compressed_and_unde, + ] + .into_iter() + .flatten() + .flatten() + .cloned() + .collect() + } + + /// Returns all the compressed accounts that will be committed, + /// including the ones that will be undelegated as well + pub fn get_all_regular_committed_accounts(&self) -> Vec { let committed = self.get_commit_intent_accounts(); let undelegated = self.get_undelegate_intent_accounts(); let commit_finalize = self.get_commit_finalize_intent_accounts(); @@ -478,12 +616,35 @@ impl MagicIntentBundle { .collect() } + /// Returns all the compressed accounts that will be committed, + /// including the ones that will be undelegated as well + pub fn get_all_compressed_committed_accounts( + &self, + ) -> Vec { + let commit_finalize_compressed = + self.get_commit_finalize_compressed_intent_accounts(); + let commit_finalize_compressed_and_unde = self + .get_commit_finalize_compressed_and_undelegate_intent_accounts(); + + [ + commit_finalize_compressed, + commit_finalize_compressed_and_unde, + ] + .into_iter() + .flatten() + .flatten() + .cloned() + .collect() + } + pub fn get_all_committed_pubkeys(&self) -> Vec { [ self.get_commit_intent_pubkeys(), self.get_undelegate_intent_pubkeys(), self.get_commit_finalize_intent_pubkeys(), self.get_commit_finalize_and_undelegate_intent_pubkeys(), + self.get_commit_finalize_compressed_intent_pubkeys(), + self.get_commit_finalize_compressed_and_undelegate_intent_pubkeys(), ] .into_iter() .flatten() @@ -517,6 +678,22 @@ impl MagicIntentBundle { .map(|value| value.get_committed_pubkeys()) } + pub fn get_commit_finalize_compressed_intent_pubkeys( + &self, + ) -> Option> { + self.commit_finalize_compressed + .as_ref() + .map(|value| value.get_committed_pubkeys()) + } + + pub fn get_commit_finalize_compressed_and_undelegate_intent_pubkeys( + &self, + ) -> Option> { + self.commit_finalize_compressed_and_undelegate + .as_ref() + .map(|value| value.get_committed_pubkeys()) + } + pub fn is_empty(&self) -> bool { let no_committed = self.commit.as_ref().map(|el| el.is_empty()).unwrap_or(true); @@ -538,6 +715,17 @@ impl MagicIntentBundle { .as_ref() .map(|el| el.is_empty()) .unwrap_or(true); + let no_commit_finalize_compressed = self + .commit_finalize_compressed + .as_ref() + .map(|el| el.is_empty()) + .unwrap_or(true); + + let no_commit_finalize_compressed_and_undelegate = self + .commit_finalize_compressed_and_undelegate + .as_ref() + .map(|el| el.is_empty()) + .unwrap_or(true); let no_actions = self.standalone_actions.is_empty(); @@ -545,6 +733,8 @@ impl MagicIntentBundle { && no_committed_and_undelegated && no_commit_finalize && no_commit_finalize_and_undelegate + && no_commit_finalize_compressed + && no_commit_finalize_compressed_and_undelegate && no_actions } @@ -567,6 +757,11 @@ impl MagicIntentBundle { x || y || z } + pub fn has_compressed_intent(&self) -> bool { + self.commit_finalize_compressed.is_some() + || self.commit_finalize_compressed_and_undelegate.is_some() + } + pub fn get_action_mut(&mut self, index: usize) -> Option<&mut BaseAction> { let mut offset = 0usize; @@ -623,6 +818,19 @@ impl MagicBaseIntent { commit_and_undelegate, )) } + MagicBaseIntentArgs::CommitFinalizeCompressed(type_) => { + let commit = CommitType::try_from_args(type_, context)?; + Ok(MagicBaseIntent::CommitFinalizeCompressed(commit)) + } + MagicBaseIntentArgs::CommitFinalizeAndUndelegateCompressed( + type_, + ) => { + let commit_and_undelegate = + CommitAndUndelegate::try_from_args(type_, context)?; + Ok(MagicBaseIntent::CommitFinalizeAndUndelegateCompressed( + commit_and_undelegate, + )) + } } } @@ -633,6 +841,8 @@ impl MagicBaseIntent { MagicBaseIntent::CommitAndUndelegate(_) => true, MagicBaseIntent::CommitFinalize(_) => false, MagicBaseIntent::CommitFinalizeAndUndelegate(_) => true, + MagicBaseIntent::CommitFinalizeCompressed(_) => false, + MagicBaseIntent::CommitFinalizeAndUndelegateCompressed(_) => true, } } @@ -643,6 +853,8 @@ impl MagicBaseIntent { MagicBaseIntent::CommitAndUndelegate(_) => false, MagicBaseIntent::CommitFinalize(_) => true, MagicBaseIntent::CommitFinalizeAndUndelegate(_) => true, + MagicBaseIntent::CommitFinalizeCompressed(_) => true, + MagicBaseIntent::CommitFinalizeAndUndelegateCompressed(_) => true, } } @@ -659,6 +871,12 @@ impl MagicBaseIntent { MagicBaseIntent::CommitFinalizeAndUndelegate(t) => { Some(t.get_committed_accounts()) } + MagicBaseIntent::CommitFinalizeCompressed(t) => { + Some(t.get_committed_accounts()) + } + MagicBaseIntent::CommitFinalizeAndUndelegateCompressed(t) => { + Some(t.get_committed_accounts()) + } } } @@ -677,6 +895,12 @@ impl MagicBaseIntent { MagicBaseIntent::CommitFinalizeAndUndelegate(t) => { Some(t.get_committed_accounts_mut()) } + MagicBaseIntent::CommitFinalizeCompressed(t) => { + Some(t.get_committed_accounts_mut()) + } + MagicBaseIntent::CommitFinalizeAndUndelegateCompressed(t) => { + Some(t.get_committed_accounts_mut()) + } } } @@ -693,6 +917,10 @@ impl MagicBaseIntent { MagicBaseIntent::CommitAndUndelegate(t) => t.is_empty(), MagicBaseIntent::CommitFinalize(t) => t.is_empty(), MagicBaseIntent::CommitFinalizeAndUndelegate(t) => t.is_empty(), + MagicBaseIntent::CommitFinalizeCompressed(t) => t.is_empty(), + MagicBaseIntent::CommitFinalizeAndUndelegateCompressed(t) => { + t.is_empty() + } } } } @@ -753,9 +981,12 @@ impl CommitAndUndelegate { pub fn calculate_fee( &self, commit_nonces: &HashMap, + compressed: bool, ) -> Result { let mut fee = 0; - fee += self.commit_action.calculate_fee(commit_nonces)?; + fee += self + .commit_action + .calculate_fee(commit_nonces, compressed)?; fee += self.undelegate_action.calculate_fee(commit_nonces)?; Ok(fee) } @@ -1039,17 +1270,26 @@ impl CommitType { pub fn calculate_fee( &self, commit_nonces: &HashMap, + compressed: bool, ) -> Result { let mut fee = 0; match self { CommitType::Standalone(ref committed_accounts) => { - fee += calculate_commit_fee(committed_accounts, commit_nonces)?; + fee += calculate_commit_fee( + committed_accounts, + commit_nonces, + compressed, + )?; } CommitType::WithBaseActions { committed_accounts, base_actions, } => { - fee += calculate_commit_fee(committed_accounts, commit_nonces)?; + fee += calculate_commit_fee( + committed_accounts, + commit_nonces, + compressed, + )?; fee += calculate_actions_fee(base_actions); } } @@ -1226,10 +1466,13 @@ pub(crate) fn validate_commit_schedule_permissions( pub(crate) fn calculate_commit_fee( accounts: &[CommittedAccount], commit_nonces: &HashMap, + compressed: bool, ) -> Result { accounts.iter().try_fold(0u64, |fee, account| { if let Some(nonce) = commit_nonces.get(&account.pubkey) { - if nonce >= &ACTUAL_COMMIT_LIMIT { + if compressed { + Ok(fee + COMPRESSED_COMMIT_FEE_LAMPORTS) + } else if nonce >= &ACTUAL_COMMIT_LIMIT { Ok(fee + COMMIT_FEE_LAMPORTS) } else { Ok(fee) @@ -1293,8 +1536,9 @@ mod tests { // nonce is commits done so far; nonce+1 is the next commit number. // ACTUAL_COMMIT_LIMIT - 1 means the next commit is exactly at the limit → free. let nonces = HashMap::from([(pk, ACTUAL_COMMIT_LIMIT - 1)]); - let fee = calculate_commit_fee(&[make_committed_account(pk)], &nonces) - .unwrap(); + let fee = + calculate_commit_fee(&[make_committed_account(pk)], &nonces, false) + .unwrap(); assert_eq!(fee, 0); } @@ -1309,6 +1553,7 @@ mod tests { let fee = calculate_commit_fee( &[make_committed_account(pk1), make_committed_account(pk2)], &nonces, + false, ) .unwrap(); assert_eq!(fee, COMMIT_FEE_LAMPORTS * 2); @@ -1328,6 +1573,7 @@ mod tests { make_committed_account(pk_above), ], &nonces, + false, ) .unwrap(); assert_eq!(fee, COMMIT_FEE_LAMPORTS); @@ -1339,6 +1585,7 @@ mod tests { let err = calculate_commit_fee( &[make_committed_account(pk)], &HashMap::new(), + false, ) .unwrap_err(); assert_eq!(err, InstructionError::Custom(MISSING_COMMIT_NONCE_ERR)); @@ -1393,6 +1640,8 @@ mod tests { }), commit_finalize: None, commit_finalize_and_undelegate: None, + commit_finalize_compressed: None, + commit_finalize_compressed_and_undelegate: None, standalone_actions: vec![make_base_action(50_000)], }, }; diff --git a/programs/magicblock/src/magic_sys.rs b/programs/magicblock/src/magic_sys.rs index 0fda01653..b76a8298e 100644 --- a/programs/magicblock/src/magic_sys.rs +++ b/programs/magicblock/src/magic_sys.rs @@ -31,11 +31,21 @@ pub fn init_magic_sys(magic_sys: Arc) { pub(crate) fn fetch_current_commit_nonces( commits: &[CommittedAccount], + compressed: bool, ) -> Result, InstructionError> { MAGIC_SYS .read() .expect(MAGIC_SYS_POISONED_MSG) .as_ref() .ok_or(InstructionError::UninitializedAccount)? - .fetch_current_commit_nonces(commits) + .fetch_current_commit_nonces(commits, compressed) +} + +pub fn is_compression_enabled() -> Result { + Ok(MAGIC_SYS + .read() + .expect(MAGIC_SYS_POISONED_MSG) + .as_ref() + .ok_or(InstructionError::UninitializedAccount)? + .is_compression_enabled()) } diff --git a/programs/magicblock/src/magicblock_processor.rs b/programs/magicblock/src/magicblock_processor.rs index 9f5737d17..6e1a2ac1f 100644 --- a/programs/magicblock/src/magicblock_processor.rs +++ b/programs/magicblock/src/magicblock_processor.rs @@ -285,9 +285,31 @@ mod test { use magicblock_magic_program_api::args::ScheduleTaskArgs; use solana_instruction::AccountMeta; use solana_program_runtime::invoke_context::mock_process_instruction; + use solana_pubkey::Pubkey; use super::*; + #[test] + fn crank_entrypoint_decodes_execute_crank_before_account_validation() { + let data = bincode::serialize(&MagicBlockInstruction::ExecuteCrank { + authority: Pubkey::new_unique(), + instructions: vec![], + }) + .unwrap(); + + mock_process_instruction( + &crate::CRANK_PROGRAM_ID, + None, + &data, + Vec::new(), + vec![AccountMeta::new_readonly(crate::CRANK_PROGRAM_ID, false)], + Err(InstructionError::MissingAccount), + CrankEntrypoint::vm, + |_invoke_context| {}, + |_invoke_context| {}, + ); + } + #[test] fn crank_entrypoint_rejects_non_execute_crank_instructions() { let data = bincode::serialize(&MagicBlockInstruction::ScheduleTask( diff --git a/programs/magicblock/src/mutate_accounts/process_mutate_accounts.rs b/programs/magicblock/src/mutate_accounts/process_mutate_accounts.rs index df066f35a..bb411cc54 100644 --- a/programs/magicblock/src/mutate_accounts/process_mutate_accounts.rs +++ b/programs/magicblock/src/mutate_accounts/process_mutate_accounts.rs @@ -161,6 +161,14 @@ pub(crate) fn process_mutate_accounts( ); account.set_delegated(delegated); } + if let Some(compressed) = modification.compressed { + ic_msg!( + invoke_context, + "MutateAccounts: setting compressed to {}", + compressed + ); + account.set_compressed(compressed); + } if let Some(confined) = modification.confined { ic_msg!( invoke_context, @@ -213,6 +221,7 @@ mod tests { owner: Some(owner_key), delegated: Some(true), confined: Some(true), + compressed: Some(true), }], None, ); @@ -238,6 +247,7 @@ mod tests { let account_authority: AccountSharedData = accounts.drain(0..1).next().unwrap(); assert!(!account_authority.delegated()); + assert!(!account_authority.compressed()); assert!(!account_authority.confined()); assert_matches!( account_authority.into(), @@ -256,6 +266,7 @@ mod tests { let modified_account: AccountSharedData = accounts.drain(0..1).next().unwrap(); assert!(modified_account.delegated()); + assert!(modified_account.compressed()); assert!(modified_account.confined()); assert_matches!( modified_account.into(), diff --git a/programs/magicblock/src/schedule_transactions/mod.rs b/programs/magicblock/src/schedule_transactions/mod.rs index 574446361..cb2d52a60 100644 --- a/programs/magicblock/src/schedule_transactions/mod.rs +++ b/programs/magicblock/src/schedule_transactions/mod.rs @@ -126,9 +126,10 @@ pub fn check_magic_context_id( pub(crate) fn check_commit_limits( commits: &[CommittedAccount], + compressed: bool, invoke_context: &InvokeContext, ) -> Result<(), InstructionError> { - let mut nonces = fetch_current_commit_nonces(commits)?; + let mut nonces = fetch_current_commit_nonces(commits, compressed)?; let mut limit_exceeded = false; for account in commits { let nonce = nonces diff --git a/programs/magicblock/src/schedule_transactions/process_schedule_commit.rs b/programs/magicblock/src/schedule_transactions/process_schedule_commit.rs index a4a0f641e..45202aa98 100644 --- a/programs/magicblock/src/schedule_transactions/process_schedule_commit.rs +++ b/programs/magicblock/src/schedule_transactions/process_schedule_commit.rs @@ -251,13 +251,13 @@ pub(crate) fn process_schedule_commit( } if let Some(fee_vault) = magic_fee_vault { - let nonces = fetch_current_commit_nonces(&committed_accounts)?; - let fee = calculate_commit_fee(&committed_accounts, &nonces)?; + let nonces = fetch_current_commit_nonces(&committed_accounts, false)?; + let fee = calculate_commit_fee(&committed_accounts, &nonces, false)?; charge_delegated_payer(&payer_account, &fee_vault, fee)?; } else if !opts.request_undelegation { // We validate commit nonces only for plain commits. // If accounts are undelegated we don't want to fail. - check_commit_limits(&committed_accounts, invoke_context)?; + check_commit_limits(&committed_accounts, false, invoke_context)?; } // NOTE: this is only protected by all the above checks however if the diff --git a/programs/magicblock/src/schedule_transactions/process_schedule_commit_tests.rs b/programs/magicblock/src/schedule_transactions/process_schedule_commit_tests.rs index 3aa357ea1..26a7b0763 100644 --- a/programs/magicblock/src/schedule_transactions/process_schedule_commit_tests.rs +++ b/programs/magicblock/src/schedule_transactions/process_schedule_commit_tests.rs @@ -426,6 +426,8 @@ mod tests { commit_and_undelegate: None, commit_finalize: None, commit_finalize_and_undelegate: None, + commit_finalize_compressed: None, + commit_finalize_compressed_and_undelegate: None, standalone_actions: vec![BaseActionArgs { args: ActionArgs::new(vec![1, 2, 3]).with_escrow_index(0), compute_units: 100_000, diff --git a/programs/magicblock/src/schedule_transactions/process_schedule_intent_bundle.rs b/programs/magicblock/src/schedule_transactions/process_schedule_intent_bundle.rs index 5210e36f6..647162cf0 100644 --- a/programs/magicblock/src/schedule_transactions/process_schedule_intent_bundle.rs +++ b/programs/magicblock/src/schedule_transactions/process_schedule_intent_bundle.rs @@ -11,7 +11,9 @@ use crate::{ magic_scheduled_base_intent::{ CommitType, ConstructionContext, ScheduledIntentBundle, }, - magic_sys::fetch_current_commit_nonces, + magic_sys::{ + fetch_current_commit_nonces, is_compression_enabled, COMMIT_LIMIT_ERR, + }, schedule_transactions::{ check_commit_limits, check_magic_context_id, get_clock, get_parent_program_id, try_get_fee_vault, MAGIC_CONTEXT_IDX, PAYER_IDX, @@ -33,6 +35,56 @@ pub(crate) fn process_schedule_intent_bundle( args: MagicIntentBundleArgs, secure: bool, ) -> Result<(), InstructionError> { + let contains_compressed_commits = args.commit_finalize_compressed.is_some() + || args.commit_finalize_compressed_and_undelegate.is_some(); + if !is_compression_enabled()? && contains_compressed_commits { + ic_msg!( + invoke_context, + "ScheduleIntentBundle: compression is not enabled" + ); + return Err(InstructionError::InvalidInstructionData); + } + + if contains_compressed_commits { + let mut compressed_account_indices = Vec::::new(); + if let Some(ref args_cau) = + args.commit_finalize_compressed_and_undelegate + { + compressed_account_indices + .extend(args_cau.committed_accounts_indices()); + } + if let Some(ref args_cc) = args.commit_finalize_compressed { + compressed_account_indices + .extend(args_cc.committed_accounts_indices()); + } + if !compressed_account_indices.is_empty() { + for idx in compressed_account_indices { + let account = get_instruction_account_with_idx( + invoke_context.transaction_context, + idx as u16, + )?; + let account = account.borrow()?; + if !account.compressed() { + ic_msg!( + invoke_context, + "ScheduleIntentBundle: compressed commits are only for compressed accounts ({})", + get_instruction_pubkey_with_idx(invoke_context.transaction_context, idx as u16)? + ); + return Err(InstructionError::InvalidInstructionData); + } + + if account.lamports() != 0 { + ic_msg!( + invoke_context, + "ScheduleIntentBundle: compressed commits are only for accounts with zero lamports ({})", + get_instruction_pubkey_with_idx(invoke_context.transaction_context, idx as u16)? + ); + return Err(InstructionError::InvalidInstructionData); + } + } + } + } + check_magic_context_id(invoke_context, MAGIC_CONTEXT_IDX)?; let parent_program_id = get_parent_program_id(invoke_context)?; @@ -94,6 +146,7 @@ pub(crate) fn process_schedule_intent_bundle( let undelegated_accounts_ref = [ args.commit_and_undelegate.as_ref(), args.commit_finalize_and_undelegate.as_ref(), + args.commit_finalize_compressed_and_undelegate.as_ref(), ] .into_iter() .flatten() @@ -143,14 +196,33 @@ pub(crate) fn process_schedule_intent_bundle( MAGIC_CONTEXT_IDX + 1, )?; if let Some(magic_fee_vault) = magic_fee_vault { - let chargable_accounts = scheduled_intent.get_all_committed_accounts(); - let nonces = fetch_current_commit_nonces(&chargable_accounts)?; - let fee = scheduled_intent.calculate_fee(&nonces)?; + let regular_chargable_accounts = + scheduled_intent.get_all_regular_committed_accounts(); + let regular_nonces = + fetch_current_commit_nonces(®ular_chargable_accounts, false)?; + let compressed_chargable_accounts = + scheduled_intent.get_all_compressed_committed_accounts(); + let compressed_nonces = + fetch_current_commit_nonces(&compressed_chargable_accounts, true)?; + let mut commit_nonces = regular_nonces; + commit_nonces.extend(compressed_nonces); + let fee = scheduled_intent.calculate_fee(&commit_nonces)?; charge_delegated_payer(&payer_account, &magic_fee_vault, fee)?; } else if let Some(commit_accounts) = scheduled_intent.get_commit_intent_accounts() { - check_commit_limits(commit_accounts, invoke_context)?; + check_commit_limits(commit_accounts, false, invoke_context)?; + } else if scheduled_intent + .get_commit_finalize_compressed_intent_accounts() + .is_some() + { + // Compressed accounts are free to delegate and don't have rents. + // Committing them must be paid for. + ic_msg!( + invoke_context, + "ScheduleCommit ERR: compressed accounts need to be paid for", + ); + return Err(InstructionError::Custom(COMMIT_LIMIT_ERR)); } let action_sent_signature = scheduled_intent.sent_transaction.signatures[0]; diff --git a/programs/magicblock/src/test_utils/mod.rs b/programs/magicblock/src/test_utils/mod.rs index 7a7eda903..adbfd47b9 100644 --- a/programs/magicblock/src/test_utils/mod.rs +++ b/programs/magicblock/src/test_utils/mod.rs @@ -143,6 +143,7 @@ impl MagicSys for MagicSysStub { fn fetch_current_commit_nonces( &self, commits: &[CommittedAccount], + _compressed: bool, ) -> Result, InstructionError> { match &self.nonces { StubNonces::Global(nonce) => { @@ -160,4 +161,8 @@ impl MagicSys for MagicSysStub { .collect(), } } + + fn is_compression_enabled(&self) -> bool { + true + } } diff --git a/programs/magicblock/src/utils/instruction_utils.rs b/programs/magicblock/src/utils/instruction_utils.rs index 56dfcad2b..ed9f06dfb 100644 --- a/programs/magicblock/src/utils/instruction_utils.rs +++ b/programs/magicblock/src/utils/instruction_utils.rs @@ -188,6 +188,7 @@ impl InstructionUtils { AccountModificationForInstruction { owner: account_modification.owner, delegated: account_modification.delegated, + compressed: account_modification.compressed, confined: account_modification.confined, }; account_mods.insert( diff --git a/test-integration/Cargo.lock b/test-integration/Cargo.lock index 0ebfe7d2c..bcff604c5 100644 --- a/test-integration/Cargo.lock +++ b/test-integration/Cargo.lock @@ -39,7 +39,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" dependencies = [ - "crypto-common", + "crypto-common 0.1.7", "generic-array", ] @@ -51,7 +51,7 @@ checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", "cipher", - "cpufeatures", + "cpufeatures 0.2.17", ] [[package]] @@ -69,6 +69,20 @@ dependencies = [ "zeroize", ] +[[package]] +name = "agave-feature-set" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a2c365c0245cbb8959de725fc2b44c754b673fdf34c9a7f9d4a25c35a7bf1" +dependencies = [ + "ahash 0.8.12", + "solana-epoch-schedule 2.2.1", + "solana-hash 2.3.0", + "solana-pubkey 2.4.0", + "solana-sha256-hasher 2.3.0", + "solana-svm-feature-set 2.3.13", +] + [[package]] name = "agave-feature-set" version = "3.1.12" @@ -76,11 +90,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6200f3b8cfbe5992fde00d443f60e62a79d2d8f6a658af1ffb7c4f0baa3c7028" dependencies = [ "ahash 0.8.12", - "solana-epoch-schedule", + "solana-epoch-schedule 3.1.0", "solana-hash 3.1.0", "solana-pubkey 3.0.0", "solana-sha256-hasher 3.1.0", - "solana-svm-feature-set", + "solana-svm-feature-set 3.1.12", ] [[package]] @@ -104,10 +118,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d93caf9e6dd35ba4193fe778c1e52ee69433ba53b9eaeebc00c7bcd4d699081" dependencies = [ "log", - "solana-clock", + "solana-clock 3.1.0", "solana-hash 3.1.0", - "solana-signature", - "solana-transaction", + "solana-signature 3.4.0", + "solana-transaction 3.1.0", "solana-transaction-status", "thiserror 2.0.18", ] @@ -143,7 +157,7 @@ version = "3.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c0fa80ea1037091eff64931fc53b6a89f153f5a88c33035cedfa79265b985cb" dependencies = [ - "agave-feature-set", + "agave-feature-set 3.1.12", "bincode", "digest 0.10.7", "ed25519-dalek 1.0.1", @@ -151,10 +165,10 @@ dependencies = [ "openssl", "sha3", "solana-ed25519-program", - "solana-message", + "solana-message 3.1.0", "solana-precompile-error", "solana-pubkey 3.0.0", - "solana-sdk-ids", + "solana-sdk-ids 3.1.0", "solana-secp256k1-program", "solana-secp256r1-program", ] @@ -165,9 +179,9 @@ version = "3.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c3998a6ec388df954d8f78eeaf73ff487b50a8bdaebd48c8573af22c7b6db72" dependencies = [ - "agave-feature-set", + "agave-feature-set 3.1.12", "solana-pubkey 3.0.0", - "solana-sdk-ids", + "solana-sdk-ids 3.1.0", ] [[package]] @@ -182,11 +196,11 @@ dependencies = [ "crossbeam-channel", "log", "lz4", - "rand 0.8.5", + "rand 0.8.6", "regex", "semver", "solana-accounts-db", - "solana-clock", + "solana-clock 3.1.0", "solana-genesis-config", "solana-hash 3.1.0", "solana-lattice-hash", @@ -209,37 +223,37 @@ dependencies = [ "bincode", "libsecp256k1", "num-traits", - "solana-account", - "solana-account-info", - "solana-big-mod-exp", - "solana-blake3-hasher", - "solana-bn254", - "solana-clock", - "solana-cpi", - "solana-curve25519", + "solana-account 3.4.0", + "solana-account-info 3.1.1", + "solana-big-mod-exp 3.0.0", + "solana-blake3-hasher 3.1.0", + "solana-bn254 3.2.1", + "solana-clock 3.1.0", + "solana-cpi 3.1.0", + "solana-curve25519 3.1.12", "solana-hash 3.1.0", - "solana-instruction", - "solana-keccak-hasher", - "solana-loader-v3-interface", + "solana-instruction 3.4.0", + "solana-keccak-hasher 3.1.0", + "solana-loader-v3-interface 6.1.1", "solana-poseidon", - "solana-program-entrypoint", + "solana-program-entrypoint 3.1.1", "solana-program-runtime", "solana-pubkey 3.0.0", "solana-sbpf", - "solana-sdk-ids", - "solana-secp256k1-recover", + "solana-sdk-ids 3.1.0", + "solana-secp256k1-recover 3.1.1", "solana-sha256-hasher 3.1.0", - "solana-stable-layout", - "solana-stake-interface", + "solana-stable-layout 3.0.1", + "solana-stake-interface 2.0.2", "solana-svm-callback", - "solana-svm-feature-set", + "solana-svm-feature-set 3.1.12", "solana-svm-log-collector", "solana-svm-measure", "solana-svm-timings", "solana-svm-type-overrides", - "solana-sysvar", - "solana-sysvar-id", - "solana-transaction-context", + "solana-sysvar 3.1.1", + "solana-sysvar-id 3.1.0", + "solana-transaction-context 3.1.12", "thiserror 2.0.18", ] @@ -250,14 +264,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9b36ce7792c4e48140ee2f9ef4eaa289fab1c383a0670588a6c7c755947608c" dependencies = [ "solana-hash 3.1.0", - "solana-message", + "solana-message 3.1.0", "solana-packet", "solana-pubkey 3.0.0", - "solana-sdk-ids", - "solana-short-vec", - "solana-signature", + "solana-sdk-ids 3.1.0", + "solana-short-vec 3.2.1", + "solana-signature 3.4.0", "solana-svm-transaction", - "solana-transaction-context", + "solana-transaction-context 3.1.12", ] [[package]] @@ -269,7 +283,7 @@ dependencies = [ "agave-logger", "serde", "solana-bls-signatures", - "solana-clock", + "solana-clock 3.1.0", "solana-hash 3.1.0", ] @@ -279,7 +293,7 @@ version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", "once_cell", "version_check", ] @@ -306,6 +320,17 @@ dependencies = [ "memchr", ] +[[package]] +name = "aligned-sized" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48a526ec4434d531d488af59fe866f36b310fe8906691c75dffa664450a3800a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "alloc-no-stdlib" version = "2.0.4" @@ -336,21 +361,6 @@ dependencies = [ "libc", ] -[[package]] -name = "anstream" -version = "0.6.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" -dependencies = [ - "anstyle", - "anstyle-parse 0.2.7", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is_terminal_polyfill", - "utf8parse", -] - [[package]] name = "anstream" version = "1.0.0" @@ -358,7 +368,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" dependencies = [ "anstyle", - "anstyle-parse 1.0.0", + "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", @@ -368,18 +378,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" - -[[package]] -name = "anstyle-parse" -version = "0.2.7" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" -dependencies = [ - "utf8parse", -] +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" [[package]] name = "anstyle-parse" @@ -396,7 +397,7 @@ version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -407,14 +408,14 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] name = "anyhow" -version = "1.0.100" +version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" [[package]] name = "anza-quinn" @@ -427,9 +428,9 @@ dependencies = [ "cfg_aliases", "pin-project-lite", "quinn-udp", - "rustc-hash 2.1.1", - "rustls 0.23.35", - "socket2 0.6.1", + "rustc-hash 2.1.2", + "rustls 0.23.40", + "socket2 0.6.3", "thiserror 2.0.18", "tokio", "tracing", @@ -446,12 +447,12 @@ dependencies = [ "fastbloom", "getrandom 0.3.4", "lru-slab", - "rand 0.9.2", + "rand 0.9.4", "ring", - "rustc-hash 2.1.1", - "rustls 0.23.35", + "rustc-hash 2.1.2", + "rustls 0.23.40", "rustls-pki-types", - "rustls-platform-verifier", + "rustls-platform-verifier 0.6.2", "slab", "thiserror 2.0.18", "tinyvec", @@ -475,9 +476,12 @@ dependencies = [ [[package]] name = "arc-swap" -version = "1.7.1" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" +checksum = "6a3a1fd6f75306b68087b831f025c712524bcb19aad54e557b1129cfa0a2b207" +dependencies = [ + "rustversion", +] [[package]] name = "ark-bn254" @@ -531,7 +535,7 @@ dependencies = [ "ark-std 0.5.0", "educe 0.6.0", "fnv", - "hashbrown 0.15.2", + "hashbrown 0.15.5", "itertools 0.13.0", "num-bigint 0.4.6", "num-integer", @@ -650,7 +654,7 @@ dependencies = [ "ark-std 0.5.0", "educe 0.6.0", "fnv", - "hashbrown 0.15.2", + "hashbrown 0.15.5", ] [[package]] @@ -707,7 +711,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" dependencies = [ "num-traits", - "rand 0.8.5", + "rand 0.8.6", ] [[package]] @@ -717,7 +721,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "246a225cc6131e9ee4f24619af0f19d67761fff15d7ccc22e42b80846e69449a" dependencies = [ "num-traits", - "rand 0.8.5", + "rand 0.8.6", + "rayon", ] [[package]] @@ -785,22 +790,21 @@ checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" [[package]] name = "async-compression" -version = "0.4.36" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98ec5f6c2f8bc326c994cb9e241cc257ddaba9afa8555a43cffbb5dd86efaa37" +checksum = "e79b3f8a79cccc2898f31920fc69f304859b3bd567490f75ebf51ae1c792a9ac" dependencies = [ "compression-codecs", "compression-core", - "futures-core", "pin-project-lite", "tokio", ] [[package]] name = "async-lock" -version = "3.4.1" +version = "3.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd03604047cee9b6ce9de9f70c6cd540a0520c813cbd49bae61f33ab80ed1dc" +checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311" dependencies = [ "event-listener", "event-listener-strategy", @@ -822,7 +826,7 @@ dependencies = [ "once_cell", "pin-project", "portable-atomic", - "rand 0.8.5", + "rand 0.8.6", "regex", "ring", "rustls-native-certs 0.7.3", @@ -837,7 +841,7 @@ dependencies = [ "tokio", "tokio-rustls 0.26.4", "tokio-stream", - "tokio-util 0.7.17", + "tokio-util 0.7.18", "tokio-websockets", "tracing", "tryhard", @@ -894,9 +898,9 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "autotools" @@ -907,6 +911,28 @@ dependencies = [ "cc", ] +[[package]] +name = "aws-lc-rs" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ec2f1fc3ec205783a5da9a7e6c1509cc69dedf09a1949e412c1e18469326d00" +dependencies = [ + "aws-lc-sys", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a2f9779ce85b93ab6170dd940ad0169b5766ff848247aff13bb788b832fe3f4" +dependencies = [ + "cc", + "cmake", + "dunce", + "fs_extra", +] + [[package]] name = "axum" version = "0.7.9" @@ -929,16 +955,16 @@ dependencies = [ "rustversion", "serde", "sync_wrapper 1.0.2", - "tower 0.5.2", + "tower 0.5.3", "tower-layer", "tower-service", ] [[package]] name = "axum" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8" +checksum = "31b698c5f9a010f6573133b09e0de5408834d0c82f8d7475a89fc1867a71cd90" dependencies = [ "axum-core 0.5.6", "bytes", @@ -954,7 +980,7 @@ dependencies = [ "pin-project-lite", "serde_core", "sync_wrapper 1.0.2", - "tower 0.5.2", + "tower 0.5.3", "tower-layer", "tower-service", ] @@ -1063,7 +1089,7 @@ version = "0.69.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.1", "cexpr", "clang-sys", "itertools 0.12.1", @@ -1083,14 +1109,14 @@ version = "0.72.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.1", "cexpr", "clang-sys", "itertools 0.13.0", "proc-macro2", "quote", "regex", - "rustc-hash 2.1.1", + "rustc-hash 2.1.2", "shlex", "syn 2.0.117", ] @@ -1103,9 +1129,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.10.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" +checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" dependencies = [ "serde_core", ] @@ -1133,16 +1159,17 @@ dependencies = [ [[package]] name = "blake3" -version = "1.8.2" +version = "1.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0" +checksum = "0aa83c34e62843d924f905e0f5c866eb1dd6545fc4d719e803d9ba6030371fce" dependencies = [ "arrayref", "arrayvec", "cc", "cfg-if", "constant_time_eq", - "digest 0.10.7", + "cpufeatures 0.3.0", + "digest 0.11.3", ] [[package]] @@ -1163,6 +1190,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-buffer" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be" +dependencies = [ + "hybrid-array", +] + [[package]] name = "block2" version = "0.6.2" @@ -1202,27 +1238,73 @@ dependencies = [ [[package]] name = "borsh" -version = "1.6.0" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115e54d64eb62cdebad391c19efc9dce4981c690c85a33a12199d99bb9546fee" +dependencies = [ + "borsh-derive 0.10.4", + "hashbrown 0.13.2", +] + +[[package]] +name = "borsh" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1da5ab77c1437701eeff7c88d968729e7766172279eab0676857b3d63af7a6f" +checksum = "cfd1e3f8955a5d7de9fab72fc8373fade9fb8a703968cb200ae3dc6cf08e185a" dependencies = [ - "borsh-derive", + "borsh-derive 1.6.1", + "bytes", "cfg_aliases", ] [[package]] name = "borsh-derive" -version = "1.6.0" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831213f80d9423998dd696e2c5345aba6be7a0bd8cd19e31c5243e13df1cef89" +dependencies = [ + "borsh-derive-internal", + "borsh-schema-derive-internal", + "proc-macro-crate 0.1.5", + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "borsh-derive" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0686c856aa6aac0c4498f936d7d6a02df690f614c03e4d906d1018062b5c5e2c" +checksum = "bfcfdc083699101d5a7965e49925975f2f55060f94f9a05e7187be95d530ca59" dependencies = [ "once_cell", - "proc-macro-crate", + "proc-macro-crate 3.5.0", "proc-macro2", "quote", "syn 2.0.117", ] +[[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.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "276691d96f063427be83e6692b86148e488ebba9f48f77788724ca027ba3b6d4" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "brotli" version = "8.0.2" @@ -1255,9 +1337,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.19.1" +version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] name = "bv" @@ -1325,9 +1407,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" dependencies = [ "serde", ] @@ -1363,9 +1445,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.56" +version = "1.2.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2" +checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98" dependencies = [ "find-msvc-tools", "jobserver", @@ -1413,9 +1495,9 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.42" +version = "0.4.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" +checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" dependencies = [ "iana-time-zone", "js-sys", @@ -1440,7 +1522,7 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ - "crypto-common", + "crypto-common 0.1.7", "inout", ] @@ -1457,9 +1539,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.53" +version = "4.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" +checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51" dependencies = [ "clap_builder", "clap_derive", @@ -1467,11 +1549,11 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.53" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" +checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" dependencies = [ - "anstream 0.6.21", + "anstream", "anstyle", "clap_lex", "strsim", @@ -1479,9 +1561,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.49" +version = "4.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" +checksum = "f2ce8604710f6733aa641a2b3731eaa1e8b3d9973d5e3565da11800813f997a9" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -1491,9 +1573,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.6" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" [[package]] name = "cleanass" @@ -1501,6 +1583,21 @@ version = "0.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "009067b02b9284528f9f01e3b35ebcd6b545666d15fb74fd9fa30222de89da8e" +[[package]] +name = "cmake" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" +dependencies = [ + "cc", +] + +[[package]] +name = "cmov" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f88a43d011fc4a6876cb7344703e297c71dda42494fee094d5f7c76bf13f746" + [[package]] name = "color-backtrace" version = "0.7.2" @@ -1513,9 +1610,9 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" +checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" [[package]] name = "combine" @@ -1540,11 +1637,41 @@ dependencies = [ "memchr", ] +[[package]] +name = "compressed-delegation-api" +version = "0.11.1" +dependencies = [ + "borsh 1.6.1", + "light-compressed-account", + "light-hasher", + "light-sdk", + "solana-pubkey 3.0.0", +] + +[[package]] +name = "compressed-delegation-client" +version = "0.11.1" +dependencies = [ + "borsh 1.6.1", + "compressed-delegation-api", + "light-hasher", + "light-sdk", + "light-sdk-types", + "num-derive", + "num-traits", + "solana-account-info 3.1.1", + "solana-cpi 3.1.0", + "solana-instruction 3.4.0", + "solana-program-error 3.0.1", + "solana-pubkey 3.0.0", + "thiserror 2.0.18", +] + [[package]] name = "compression-codecs" -version = "0.4.35" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0f7ac3e5b97fdce45e8922fb05cae2c37f7bbd63d30dd94821dacfd8f3f2bf2" +checksum = "ce2548391e9c1929c21bf6aa2680af86fe4c1b33e6cea9ac1cfeec0bd11218cf" dependencies = [ "brotli", "compression-core", @@ -1554,9 +1681,9 @@ dependencies = [ [[package]] name = "compression-core" -version = "0.4.31" +version = "0.4.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75984efb6ed102a0d42db99afb6c1948f0380d1d91808d5529916e6c08b49d8d" +checksum = "cc14f565cf027a105f7a44ccf9e5b424348421a1d8952a8fc9d499d313107789" [[package]] name = "concurrent-queue" @@ -1567,6 +1694,19 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "console" +version = "0.15.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" +dependencies = [ + "encode_unicode", + "libc", + "once_cell", + "unicode-width", + "windows-sys 0.59.0", +] + [[package]] name = "console" version = "0.16.3" @@ -1579,6 +1719,26 @@ dependencies = [ "windows-sys 0.61.2", ] +[[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 = "const-crypto" version = "0.3.0" @@ -1597,9 +1757,9 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "constant_time_eq" -version = "0.3.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" +checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" [[package]] name = "convert_case" @@ -1637,19 +1797,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] -name = "core2" -version = "0.4.0" +name = "cpufeatures" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" dependencies = [ - "memchr", + "libc", ] [[package]] name = "cpufeatures" -version = "0.2.17" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" dependencies = [ "libc", ] @@ -1726,6 +1886,15 @@ dependencies = [ "typenum", ] +[[package]] +name = "crypto-common" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" +dependencies = [ + "hybrid-array", +] + [[package]] name = "crypto-mac" version = "0.8.0" @@ -1769,15 +1938,24 @@ dependencies = [ [[package]] name = "ctrlc" -version = "3.5.1" +version = "3.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73736a89c4aff73035ba2ed2e565061954da00d4970fc9ac25dcc85a2a20d790" +checksum = "e0b1fab2ae45819af2d0731d60f2afe17227ebb1a1538a236da84c93e9a60162" dependencies = [ "dispatch2", - "nix", + "nix 0.31.3", "windows-sys 0.61.2", ] +[[package]] +name = "ctutils" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e" +dependencies = [ + "cmov", +] + [[package]] name = "curve25519-dalek" version = "3.2.0" @@ -1798,7 +1976,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "curve25519-dalek-derive", "digest 0.10.7", "fiat-crypto", @@ -1826,8 +2004,18 @@ version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" dependencies = [ - "darling_core", - "darling_macro", + "darling_core 0.21.3", + "darling_macro 0.21.3", +] + +[[package]] +name = "darling" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" +dependencies = [ + "darling_core 0.23.0", + "darling_macro 0.23.0", ] [[package]] @@ -1844,22 +2032,46 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "darling_core" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" +dependencies = [ + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.117", +] + [[package]] name = "darling_macro" version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" dependencies = [ - "darling_core", + "darling_core 0.21.3", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "darling_macro" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" +dependencies = [ + "darling_core 0.23.0", "quote", "syn 2.0.117", ] [[package]] name = "dary_heap" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06d2e3287df1c007e74221c49ca10a95d557349e54b3a75dc2fb14712c751f04" +checksum = "8b1e3a325bc115f096c8b77bbf027a7c2592230e70be2d985be950d3d5e60ebe" [[package]] name = "dashmap" @@ -1878,9 +2090,9 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.9.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" +checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8" [[package]] name = "der" @@ -1909,9 +2121,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.5.5" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" dependencies = [ "powerfmt", "serde_core", @@ -1936,18 +2148,18 @@ dependencies = [ [[package]] name = "derive_more" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10b768e943bed7bf2cab53df09f4bc34bfd217cdb57d971e769874c9a6710618" +checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" dependencies = [ "derive_more-impl", ] [[package]] name = "derive_more-impl" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d286bfdaf75e988b4a78e013ecd79c581e06399ab53fbacd2d916c2f904f30b" +checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" dependencies = [ "convert_case", "proc-macro2", @@ -1980,10 +2192,21 @@ checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.4", "const-oid", - "crypto-common", + "crypto-common 0.1.7", "subtle", ] +[[package]] +name = "digest" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" +dependencies = [ + "block-buffer 0.12.0", + "crypto-common 0.2.2", + "ctutils", +] + [[package]] name = "dir-diff" version = "0.3.3" @@ -1995,11 +2218,11 @@ dependencies = [ [[package]] name = "dispatch2" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" +checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.1", "block2", "libc", "objc2", @@ -2060,6 +2283,12 @@ version = "0.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f678cf4a922c215c63e0de95eb1ff08a958a81d47e485cf9da1e27bf6305cfa5" +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + [[package]] name = "dyn-clone" version = "1.0.20" @@ -2173,9 +2402,9 @@ dependencies = [ [[package]] name = "either" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" [[package]] name = "elliptic-curve" @@ -2266,9 +2495,9 @@ dependencies = [ [[package]] name = "env_filter" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a1c3cc8e57274ec99de65301228b537f1e4eedc1b8e0f9411c6caac8ae7308f" +checksum = "32e90c2accc4b07a8456ea0debdc2e7587bdd890680d71173a15d4ae604f6eef" dependencies = [ "log", "regex", @@ -2280,7 +2509,7 @@ version = "0.11.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0621c04f2196ac3f488dd583365b9c09be011a4ab8b9f37248ffcc8f6198b56a" dependencies = [ - "anstream 1.0.0", + "anstream", "anstyle", "env_filter", "jiff", @@ -2289,35 +2518,41 @@ dependencies = [ [[package]] name = "ephemeral-rollups-sdk" -version = "0.11.0" -source = "git+https://github.com/magicblock-labs/ephemeral-rollups-sdk.git?rev=ccfc9f924dc40#ccfc9f924dc403e6ec93780e575fa655af1bebb5" +version = "0.14.3" +source = "git+https://github.com/magicblock-labs/ephemeral-rollups-sdk.git?rev=01abca6e74631a10376c014bcc843ab168a8ba95#01abca6e74631a10376c014bcc843ab168a8ba95" dependencies = [ "base64ct", "bincode", - "borsh", + "bytemuck", "ephemeral-rollups-sdk-attribute-action", "ephemeral-rollups-sdk-attribute-commit", "ephemeral-rollups-sdk-attribute-delegate", "ephemeral-rollups-sdk-attribute-ephemeral", "ephemeral-rollups-sdk-attribute-ephemeral-accounts", - "getrandom 0.2.16", - "magicblock-delegation-program-api 0.3.0 (git+https://github.com/magicblock-labs/delegation-program.git?branch=snawaz%2Fupgrade)", + "five8 0.2.1", + "getrandom 0.2.17", + "magicblock-delegation-program-api 3.0.0", "magicblock-magic-program-api 0.9.0", - "solana-account", - "solana-account-info", - "solana-cpi", - "solana-instruction", - "solana-program-error", - "solana-program-memory", + "solana-account 3.4.0", + "solana-account-info 2.3.0", + "solana-account-info 3.1.1", + "solana-address 2.6.0", + "solana-cpi 3.1.0", + "solana-instruction 3.4.0", + "solana-program 2.3.0", + "solana-program 3.0.0", + "solana-program-error 2.2.2", + "solana-program-error 3.0.1", + "solana-program-memory 3.1.0", "solana-pubkey 3.0.0", - "solana-system-interface 3.2.0", - "solana-sysvar", + "solana-system-interface 2.0.0", + "solana-sysvar 3.1.1", ] [[package]] name = "ephemeral-rollups-sdk-attribute-action" -version = "0.11.0" -source = "git+https://github.com/magicblock-labs/ephemeral-rollups-sdk.git?rev=ccfc9f924dc40#ccfc9f924dc403e6ec93780e575fa655af1bebb5" +version = "0.14.3" +source = "git+https://github.com/magicblock-labs/ephemeral-rollups-sdk.git?rev=01abca6e74631a10376c014bcc843ab168a8ba95#01abca6e74631a10376c014bcc843ab168a8ba95" dependencies = [ "quote", "syn 1.0.109", @@ -2325,17 +2560,18 @@ dependencies = [ [[package]] name = "ephemeral-rollups-sdk-attribute-commit" -version = "0.11.0" -source = "git+https://github.com/magicblock-labs/ephemeral-rollups-sdk.git?rev=ccfc9f924dc40#ccfc9f924dc403e6ec93780e575fa655af1bebb5" +version = "0.14.3" +source = "git+https://github.com/magicblock-labs/ephemeral-rollups-sdk.git?rev=01abca6e74631a10376c014bcc843ab168a8ba95#01abca6e74631a10376c014bcc843ab168a8ba95" dependencies = [ + "proc-macro2", "quote", "syn 1.0.109", ] [[package]] name = "ephemeral-rollups-sdk-attribute-delegate" -version = "0.11.0" -source = "git+https://github.com/magicblock-labs/ephemeral-rollups-sdk.git?rev=ccfc9f924dc40#ccfc9f924dc403e6ec93780e575fa655af1bebb5" +version = "0.14.3" +source = "git+https://github.com/magicblock-labs/ephemeral-rollups-sdk.git?rev=01abca6e74631a10376c014bcc843ab168a8ba95#01abca6e74631a10376c014bcc843ab168a8ba95" dependencies = [ "proc-macro2", "quote", @@ -2344,8 +2580,8 @@ dependencies = [ [[package]] name = "ephemeral-rollups-sdk-attribute-ephemeral" -version = "0.11.0" -source = "git+https://github.com/magicblock-labs/ephemeral-rollups-sdk.git?rev=ccfc9f924dc40#ccfc9f924dc403e6ec93780e575fa655af1bebb5" +version = "0.14.3" +source = "git+https://github.com/magicblock-labs/ephemeral-rollups-sdk.git?rev=01abca6e74631a10376c014bcc843ab168a8ba95#01abca6e74631a10376c014bcc843ab168a8ba95" dependencies = [ "proc-macro2", "quote", @@ -2354,8 +2590,8 @@ dependencies = [ [[package]] name = "ephemeral-rollups-sdk-attribute-ephemeral-accounts" -version = "0.11.0" -source = "git+https://github.com/magicblock-labs/ephemeral-rollups-sdk.git?rev=ccfc9f924dc40#ccfc9f924dc403e6ec93780e575fa655af1bebb5" +version = "0.14.3" +source = "git+https://github.com/magicblock-labs/ephemeral-rollups-sdk.git?rev=01abca6e74631a10376c014bcc843ab168a8ba95#01abca6e74631a10376c014bcc843ab168a8ba95" dependencies = [ "proc-macro2", "quote", @@ -2375,7 +2611,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -2413,30 +2649,30 @@ checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" [[package]] name = "fastbloom" -version = "0.14.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18c1ddb9231d8554c2d6bdf4cfaabf0c59251658c68b6c95cd52dd0c513a912a" +checksum = "4e7f34442dbe69c60fe8eaf58a8cafff81a1f278816d8ab4db255b3bef4ac3c4" dependencies = [ "getrandom 0.3.4", "libm", - "rand 0.9.2", - "siphasher 1.0.1", + "rand 0.9.4", + "siphasher 1.0.3", ] [[package]] name = "fastrand" -version = "2.3.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" [[package]] name = "faststr" -version = "0.2.32" +version = "0.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baec6a0289d7f1fe5665586ef7340af82e3037207bef60f5785e57569776f0c8" +checksum = "1ca7d44d22004409a61c393afb3369c8f7bb74abcae49fe249ee01dcc3002113" dependencies = [ "bytes", - "rkyv 0.8.12", + "rkyv 0.8.16", "serde", "simdutf8", ] @@ -2450,10 +2686,10 @@ dependencies = [ "base64 0.21.7", "bytes", "http-body-util", - "hyper 1.8.1", + "hyper 1.9.0", "hyper-util", "pin-project", - "rand 0.8.5", + "rand 0.8.6", "sha1", "simdutf8", "thiserror 1.0.69", @@ -2504,21 +2740,19 @@ dependencies = [ "atomic", "pear", "serde", - "toml", + "toml 0.8.23", "uncased", "version_check", ] [[package]] name = "filetime" -version = "0.2.26" +version = "0.2.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc0505cd1b6fa6580283f6bdf70a73fcf4aba1184038c90902b92b3dd0df63ed" +checksum = "5c287a33c7f0a620c38e641e7f60827713987b3c0f26e8ddc9462cc69cf75759" dependencies = [ "cfg-if", "libc", - "libredox", - "windows-sys 0.60.2", ] [[package]] @@ -2533,7 +2767,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75b8549488b4715defcb0d8a8a1c1c76a80661b5fa106b4ca0e7fce59d7d875" dependencies = [ - "five8_core", + "five8_core 0.1.2", ] [[package]] @@ -2542,7 +2776,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23f76610e969fa1784327ded240f1e28a3fd9520c9cec93b636fcf62dd37f772" dependencies = [ - "five8_core", + "five8_core 1.0.0", ] [[package]] @@ -2551,7 +2785,7 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26dec3da8bc3ef08f2c04f61eab298c3ab334523e55f076354d6d6f613799a7b" dependencies = [ - "five8_core", + "five8_core 0.1.2", ] [[package]] @@ -2560,7 +2794,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a0f1728185f277989ca573a402716ae0beaaea3f76a8ff87ef9dd8fb19436c5" dependencies = [ - "five8_core", + "five8_core 1.0.0", ] [[package]] @@ -2569,6 +2803,12 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2551bf44bc5f776c15044b9b94153a00198be06743e262afaaa61f11ac7523a5" +[[package]] +name = "five8_core" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "059c31d7d36c43fe39d89e55711858b4da8be7eb6dabac23c7289b1a19489406" + [[package]] name = "fixedbitset" version = "0.4.2" @@ -2583,13 +2823,13 @@ checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" [[package]] name = "flate2" -version = "1.1.5" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" dependencies = [ "crc32fast", - "libz-rs-sys", "miniz_oxide", + "zlib-rs", ] [[package]] @@ -2657,9 +2897,12 @@ dependencies = [ [[package]] name = "fragile" -version = "2.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dd6caf6059519a65843af8fe2a3ae298b14b80179855aeb4adc2c1934ee619" +checksum = "8878864ba14bb86e818a412bfd6f18f9eabd4ec0f008a28e8f7eb61db532fcf9" +dependencies = [ + "futures-core", +] [[package]] name = "fs_extra" @@ -2694,9 +2937,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" dependencies = [ "futures-channel", "futures-core", @@ -2709,9 +2952,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" dependencies = [ "futures-core", "futures-sink", @@ -2719,15 +2962,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" [[package]] name = "futures-executor" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" dependencies = [ "futures-core", "futures-task", @@ -2736,15 +2979,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" [[package]] name = "futures-macro" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" dependencies = [ "proc-macro2", "quote", @@ -2753,27 +2996,27 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" [[package]] name = "futures-task" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" [[package]] name = "futures-timer" -version = "3.0.3" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" +checksum = "af43fadb8a98512d547e37b4e92e0ced13e205c061b87b4623eff01d918d6968" [[package]] name = "futures-util" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" dependencies = [ "futures-channel", "futures-core", @@ -2783,7 +3026,6 @@ dependencies = [ "futures-task", "memchr", "pin-project-lite", - "pin-utils", "slab", ] @@ -2821,9 +3063,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", "js-sys", @@ -2841,11 +3083,24 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "r-efi", + "r-efi 5.3.0", "wasip2", "wasm-bindgen", ] +[[package]] +name = "getrandom" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +dependencies = [ + "cfg-if", + "libc", + "r-efi 6.0.0", + "wasip2", + "wasip3", +] + [[package]] name = "gimli" version = "0.32.3" @@ -2893,11 +3148,26 @@ dependencies = [ "parking_lot", "portable-atomic", "quanta", - "rand 0.8.5", + "rand 0.8.6", "smallvec", "spinning_top", ] +[[package]] +name = "groth16-solana" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a6d1ffb18dbf5cfc60b11bd7da88474c672870247c1e5b498619bcb6ba3d8f5" +dependencies = [ + "ark-bn254 0.5.0", + "ark-ec 0.5.0", + "ark-ff 0.5.0", + "ark-serialize 0.5.0", + "num-bigint 0.4.6", + "solana-bn254 2.2.2", + "thiserror 1.0.69", +] + [[package]] name = "group" version = "0.13.0" @@ -2905,7 +3175,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", - "rand 0.8.5", + "rand 0.8.6", "rand_core 0.6.4", "rand_xorshift", "subtle", @@ -2918,7 +3188,7 @@ dependencies = [ "bincode", "magicblock-magic-program-api 0.11.1", "serde", - "solana-program", + "solana-program 3.0.0", ] [[package]] @@ -2933,18 +3203,18 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.12.1", + "indexmap 2.14.0", "slab", "tokio", - "tokio-util 0.7.17", + "tokio-util 0.7.18", "tracing", ] [[package]] name = "h2" -version = "0.4.12" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" +checksum = "171fefbc92fe4a4de27e0698d6a5b392d6a0e333506bc49133760b3bcf948733" dependencies = [ "atomic-waker", "bytes", @@ -2952,10 +3222,10 @@ dependencies = [ "futures-core", "futures-sink", "http 1.4.0", - "indexmap 2.12.1", + "indexmap 2.14.0", "slab", "tokio", - "tokio-util 0.7.17", + "tokio-util 0.7.18", "tracing", ] @@ -2994,9 +3264,9 @@ checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "hashbrown" -version = "0.15.2" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ "allocator-api2", "foldhash 0.1.5", @@ -3013,13 +3283,19 @@ dependencies = [ "foldhash 0.2.0", ] +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + [[package]] name = "hashlink" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" dependencies = [ - "hashbrown 0.15.2", + "hashbrown 0.15.5", ] [[package]] @@ -3049,7 +3325,7 @@ dependencies = [ "laserstream-core-proto", "prost 0.12.6", "prost-types 0.12.6", - "rand 0.8.5", + "rand 0.8.6", "reqwest 0.11.27", "serde", "serde_json", @@ -3196,6 +3472,15 @@ dependencies = [ "serde", ] +[[package]] +name = "hybrid-array" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9155a582abd142abc056962c29e3ce5ff2ad5469f4246b537ed42c5deba857da" +dependencies = [ + "typenum", +] + [[package]] name = "hyper" version = "0.14.32" @@ -3222,22 +3507,21 @@ dependencies = [ [[package]] name = "hyper" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" +checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" dependencies = [ "atomic-waker", "bytes", "futures-channel", "futures-core", - "h2 0.4.12", + "h2 0.4.14", "http 1.4.0", "http-body 1.0.1", "httparse", "httpdate", "itoa", "pin-project-lite", - "pin-utils", "smallvec", "tokio", "want", @@ -3259,18 +3543,18 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.8" +version = "0.27.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2b52f86d1d4bc0d6b4e6826d960b1b333217e07d36b882dca570a5e1c48895b" +checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" dependencies = [ "http 1.4.0", - "hyper 1.8.1", + "hyper 1.9.0", "hyper-util", - "rustls 0.23.35", + "rustls 0.23.40", "tokio", "tokio-rustls 0.26.4", "tower-service", - "webpki-roots 1.0.4", + "webpki-roots 1.0.7", ] [[package]] @@ -3279,7 +3563,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" dependencies = [ - "hyper 1.8.1", + "hyper 1.9.0", "hyper-util", "pin-project-lite", "tokio", @@ -3307,7 +3591,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", "http-body-util", - "hyper 1.8.1", + "hyper 1.9.0", "hyper-util", "native-tls", "tokio", @@ -3317,24 +3601,23 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" dependencies = [ "base64 0.22.1", "bytes", "futures-channel", - "futures-core", "futures-util", "http 1.4.0", "http-body 1.0.1", - "hyper 1.8.1", + "hyper 1.9.0", "ipnet", "libc", "percent-encoding", "pin-project-lite", - "socket2 0.6.1", - "system-configuration", + "socket2 0.6.3", + "system-configuration 0.7.0", "tokio", "tower-service", "tracing", @@ -3343,9 +3626,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.64" +version = "0.1.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -3367,12 +3650,13 @@ dependencies = [ [[package]] name = "icu_collections" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" dependencies = [ "displaydoc", "potential_utf", + "utf8_iter", "yoke", "zerofrom", "zerovec", @@ -3380,9 +3664,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" dependencies = [ "displaydoc", "litemap", @@ -3393,9 +3677,9 @@ dependencies = [ [[package]] name = "icu_normalizer" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" dependencies = [ "icu_collections", "icu_normalizer_data", @@ -3407,15 +3691,15 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" +checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" [[package]] name = "icu_properties" -version = "2.1.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" dependencies = [ "icu_collections", "icu_locale_core", @@ -3427,15 +3711,15 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.1.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" +checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" [[package]] name = "icu_provider" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" dependencies = [ "displaydoc", "icu_locale_core", @@ -3446,6 +3730,12 @@ dependencies = [ "zerovec", ] +[[package]] +name = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + [[package]] name = "ident_case" version = "1.0.1" @@ -3465,9 +3755,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" dependencies = [ "icu_normalizer", "icu_properties", @@ -3521,23 +3811,36 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.12.1" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.16.1", + "hashbrown 0.17.1", "serde", "serde_core", ] +[[package]] +name = "indicatif" +version = "0.17.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "183b3088984b400f4cfac3620d5e076c84da5364016b4f49473de574b2586235" +dependencies = [ + "console 0.15.11", + "number_prefix", + "portable-atomic", + "unicode-width", + "web-time", +] + [[package]] name = "indicatif" version = "0.18.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25470f23803092da7d239834776d653104d551bc4d7eacaf31e6837854b8e9eb" dependencies = [ - "console", + "console 0.16.3", "portable-atomic", "unicode-width", "unit-prefix", @@ -3556,7 +3859,7 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd5b3eaf1a28b758ac0faa5a4254e8ab2705605496f1b1f3fbbc3988ad73d199" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.1", "inotify-sys", "libc", ] @@ -3584,22 +3887,24 @@ name = "integration-test-tools" version = "0.0.0" dependencies = [ "anyhow", - "borsh", + "borsh 1.6.1", "color-backtrace", + "light-client", "magicblock-config", - "magicblock-delegation-program-api 0.3.0 (git+https://github.com/magicblock-labs/delegation-program.git?rev=25386a7c1d406d06b8d07a4d5b0fd37d5e74213b)", - "rand 0.8.5", + "magicblock-delegation-program-api 0.3.0", + "rand 0.8.6", "rayon", "serde", - "solana-commitment-config", + "shlex", + "solana-commitment-config 3.1.1", "solana-pubkey 3.0.0", - "solana-rpc-client", - "solana-rpc-client-api", + "solana-rpc-client 3.1.12", + "solana-rpc-client-api 3.1.12", "solana-sdk", "solana-system-interface 3.2.0", "solana-transaction-status", "tempfile", - "toml", + "toml 0.8.23", "tracing", "ureq 2.12.1", "url", @@ -3607,30 +3912,20 @@ dependencies = [ [[package]] name = "io-uring" -version = "0.7.11" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdd7bddefd0a8833b88a4b68f90dae22c7450d11b354198baee3874fd811b344" +checksum = "4d09b98f7eace8982db770e4408e7470b028ce513ac28fecdc6bf4c30fe92b62" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.1", "cfg-if", "libc", ] [[package]] name = "ipnet" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" - -[[package]] -name = "iri-string" -version = "0.7.12" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25e659a4bb38e810ebc252e53b5814ff908a8c58c2a9ce2fae1bbec24cbf4e20" -dependencies = [ - "memchr", - "serde", -] +checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" [[package]] name = "is_terminal_polyfill" @@ -3675,17 +3970,26 @@ 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 = "itoa" -version = "1.0.15" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jiff" -version = "0.2.23" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a3546dc96b6d42c5f24902af9e2538e82e39ad350b0c766eb3fbf2d8f3d8359" +checksum = "f00b5dbd620d61dfdcb6007c9c1f6054ebd75319f163d886a9055cec1155073d" dependencies = [ "jiff-static", "log", @@ -3696,9 +4000,9 @@ dependencies = [ [[package]] name = "jiff-static" -version = "0.2.23" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a8c8b344124222efd714b73bb41f8b5120b27a7cc1c75593a6ff768d9d05aa4" +checksum = "e000de030ff8022ea1da3f466fbb0f3a809f5e51ed31f6dd931c35181ad8e6d7" dependencies = [ "proc-macro2", "quote", @@ -3714,18 +4018,70 @@ dependencies = [ "cesu8", "cfg-if", "combine 4.6.7", - "jni-sys", + "jni-sys 0.3.1", "log", "thiserror 1.0.69", "walkdir", "windows-sys 0.45.0", ] +[[package]] +name = "jni" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" +dependencies = [ + "cfg-if", + "combine 4.6.7", + "jni-macros", + "jni-sys 0.4.1", + "log", + "simd_cesu8", + "thiserror 2.0.18", + "walkdir", + "windows-link", +] + +[[package]] +name = "jni-macros" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "simd_cesu8", + "syn 2.0.117", +] + [[package]] name = "jni-sys" -version = "0.3.0" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258" +dependencies = [ + "jni-sys 0.4.1", +] + +[[package]] +name = "jni-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" +dependencies = [ + "jni-sys-macros", +] + +[[package]] +name = "jni-sys-macros" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" +checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" +dependencies = [ + "quote", + "syn 2.0.117", +] [[package]] name = "jobserver" @@ -3739,10 +4095,12 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.83" +version = "0.3.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" +checksum = "67df7112613f8bfd9150013a0314e196f4800d3201ae742489d999db2f979f08" dependencies = [ + "cfg-if", + "futures-util", "once_cell", "wasm-bindgen", ] @@ -3778,11 +4136,11 @@ dependencies = [ [[package]] name = "keccak" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" dependencies = [ - "cpufeatures", + "cpufeatures 0.2.17", ] [[package]] @@ -3803,11 +4161,11 @@ dependencies = [ [[package]] name = "kqueue-sys" -version = "1.0.4" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b" +checksum = "07293a4e297ac234359b510362495713f75ea345d5307140414f20c69ffeb087" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.11.1", "libc", ] @@ -3821,7 +4179,7 @@ dependencies = [ "futures", "laserstream-core-proto", "thiserror 1.0.69", - "tonic 0.14.5", + "tonic 0.14.6", "tonic-health", ] @@ -3836,19 +4194,19 @@ dependencies = [ "prost 0.14.3", "prost-types 0.14.3", "protobuf-src", - "solana-account", + "solana-account 3.4.0", "solana-account-decoder", - "solana-clock", + "solana-clock 3.1.0", "solana-hash 3.1.0", - "solana-message", + "solana-message 3.1.0", "solana-pubkey 3.0.0", - "solana-signature", - "solana-transaction", - "solana-transaction-context", - "solana-transaction-error", + "solana-signature 3.4.0", + "solana-transaction 3.1.0", + "solana-transaction-context 3.1.12", + "solana-transaction-error 3.2.0", "solana-transaction-status", - "tonic 0.14.5", - "tonic-build 0.14.5", + "tonic 0.14.6", + "tonic-build 0.14.6", "tonic-prost", "tonic-prost-build", ] @@ -3865,33 +4223,39 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + [[package]] name = "libc" -version = "0.2.178" +version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "libflate" -version = "2.2.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3248b8d211bd23a104a42d81b4fa8bb8ac4a3b75e7a43d85d2c9ccb6179cd74" +checksum = "cd96e993e5f3368b0cb8497dae6c860c22af8ff18388c61c6c0b86c58d86b5df" dependencies = [ "adler32", - "core2", "crc32fast", "dary_heap", "libflate_lz77", + "no_std_io2", ] [[package]] name = "libflate_lz77" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a599cb10a9cd92b1300debcef28da8f70b935ec937f44fcd1b70a7c986a11c5c" +checksum = "ff7a10e427698aef6eef269482776debfef63384d30f13aad39a1a95e0e098fd" dependencies = [ - "core2", "hashbrown 0.16.1", + "no_std_io2", "rle-decode-fast", ] @@ -3907,20 +4271,9 @@ dependencies = [ [[package]] name = "libm" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" - -[[package]] -name = "libredox" -version = "0.1.11" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df15f6eac291ed1cf25865b1ee60399f57e7c227e7f51bdbd4c5270396a9ed50" -dependencies = [ - "bitflags 2.10.0", - "libc", - "redox_syscall 0.6.0", -] +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "librocksdb-sys" @@ -4001,9 +4354,9 @@ dependencies = [ [[package]] name = "libsodium-sys-stable" -version = "1.23.2" +version = "1.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e5d23f4a051a13cf1085b2c5a050d4d890d80c754534cc4247eff525fa5283d" +checksum = "72b04bf6da2c98b727af37ab62cb505f4d751b975b034a9b9ad491d333b0564e" dependencies = [ "cc", "libc", @@ -4011,7 +4364,7 @@ dependencies = [ "minisign-verify", "pkg-config", "tar", - "ureq 3.2.0", + "ureq 3.3.0", "vcpkg", "zip", ] @@ -4027,20 +4380,11 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "libz-rs-sys" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c10501e7805cee23da17c7790e59df2870c0d4043ec6d03f67d31e2b53e77415" -dependencies = [ - "zlib-rs", -] - [[package]] name = "libz-sys" -version = "1.1.23" +version = "1.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15d118bbf3771060e7311cc7bb0545b01d08a8b4a7de949198dec1fa0ca1c0f7" +checksum = "fc3a226e576f50782b3305c5ccf458698f92798987f551c6a02efe8276721e22" dependencies = [ "cc", "pkg-config", @@ -4048,73 +4392,653 @@ dependencies = [ ] [[package]] -name = "light-poseidon" -version = "0.2.0" +name = "light-account" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c9a85a9752c549ceb7578064b4ed891179d20acd85f27318573b64d2d7ee7ee" +checksum = "ec4f3acf8345ca221e4c7a7d277924ca52daea0dea5d5cf8c8f0951a3cad60dc" dependencies = [ - "ark-bn254 0.4.0", - "ark-ff 0.4.2", - "num-bigint 0.4.6", - "thiserror 1.0.69", + "light-account-checks", + "light-compressed-account", + "light-compressible", + "light-hasher", + "light-macros", + "light-sdk-macros", + "light-sdk-types", + "solana-account-info 2.3.0", + "solana-instruction 2.3.3", + "solana-pubkey 2.4.0", ] [[package]] -name = "light-poseidon" -version = "0.4.0" +name = "light-account-checks" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47a1ccadd0bb5a32c196da536fd72c59183de24a055f6bf0513bf845fefab862" +checksum = "34d74dd13535c6014abb4cac694e14083b206a7f6cf1bbbc9611aa5c2e11cdd1" dependencies = [ - "ark-bn254 0.5.0", - "ark-ff 0.5.0", - "num-bigint 0.4.6", - "thiserror 1.0.69", + "solana-account-info 2.3.0", + "solana-cpi 2.2.1", + "solana-instruction 2.3.3", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "solana-system-interface 1.0.0", + "solana-sysvar 2.3.0", + "thiserror 2.0.18", ] [[package]] -name = "linux-raw-sys" -version = "0.11.0" +name = "light-array-map" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" +checksum = "9bdd13b18028ac9d80d0a987551c0dad7fe81be8140e87cc9d568b80f3728203" +dependencies = [ + "tinyvec", +] [[package]] -name = "litemap" -version = "0.8.1" +name = "light-batched-merkle-tree" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" +checksum = "3702b96798a1cc93c9d4b0d9eb6ee980481beb147ab663cfd260c71ec258c5f0" +dependencies = [ + "aligned-sized", + "borsh 0.10.4", + "light-account-checks", + "light-bloom-filter", + "light-compressed-account", + "light-hasher", + "light-macros", + "light-merkle-tree-metadata", + "light-verifier", + "light-zero-copy", + "solana-account-info 2.3.0", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "solana-sysvar 2.3.0", + "thiserror 2.0.18", + "zerocopy", +] [[package]] -name = "lmdb-rkv" -version = "0.14.0" +name = "light-bloom-filter" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "447a296f7aca299cfbb50f4e4f3d49451549af655fb7215d7f8c0c3d64bad42b" +checksum = "380b8cf734ccf5fbc1f5fed8e5308b57ebde6774d9304c167bcb0de2854412d8" dependencies = [ - "bitflags 1.3.2", - "byteorder", - "libc", - "lmdb-rkv-sys", + "bitvec", + "num-bigint 0.4.6", + "solana-nostd-keccak", + "solana-program-error 2.2.2", + "thiserror 2.0.18", ] [[package]] -name = "lmdb-rkv-sys" -version = "0.11.2" +name = "light-bounded-vec" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61b9ce6b3be08acefa3003c57b7565377432a89ec24476bbe72e11d101f852fe" +checksum = "58cfa375d028164719e3ffef93d2e5c27855cc8a5bb5bf257b868d17c12a3e66" dependencies = [ - "cc", - "libc", - "pkg-config", + "bytemuck", + "memoffset", + "solana-program-error 2.2.2", + "thiserror 1.0.69", ] [[package]] -name = "lock_api" -version = "0.4.14" +name = "light-client" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +checksum = "4830579bed474120d4c8b79be18ecd7443ed62bf2d692fdfc591ef7cdee3f3de" dependencies = [ - "scopeguard", -] - + "async-trait", + "base64 0.13.1", + "borsh 0.10.4", + "bs58", + "futures", + "lazy_static", + "light-account", + "light-compressed-account", + "light-compressed-token-sdk", + "light-compressible", + "light-concurrent-merkle-tree", + "light-event", + "light-hasher", + "light-indexed-merkle-tree", + "light-merkle-tree-metadata", + "light-prover-client", + "light-sdk", + "light-sdk-types", + "light-token", + "light-token-interface", + "num-bigint 0.4.6", + "photon-api", + "rand 0.8.6", + "reqwest 0.12.28", + "serde_json", + "smallvec", + "solana-account 2.2.1", + "solana-account-decoder-client-types 2.3.13", + "solana-address-lookup-table-interface 2.2.2", + "solana-clock 2.2.3", + "solana-commitment-config 2.2.1", + "solana-compute-budget-interface 2.2.2", + "solana-hash 2.3.0", + "solana-instruction 2.3.3", + "solana-keypair 2.2.3", + "solana-message 2.4.0", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "solana-rpc-client 2.3.13", + "solana-rpc-client-api 2.3.13", + "solana-signature 2.3.0", + "solana-transaction 2.2.3", + "solana-transaction-error 2.2.1", + "solana-transaction-status-client-types 2.3.13", + "spl-pod 0.5.1", + "spl-token-2022-interface 1.0.0", + "thiserror 2.0.18", + "tokio", + "tracing", +] + +[[package]] +name = "light-compressed-account" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2ce168f42dab1a4c01ad83993d68b17cd2dc1bb31ced8ab4edecaf5b666a8ad" +dependencies = [ + "borsh 0.10.4", + "bytemuck", + "light-hasher", + "light-macros", + "light-poseidon 0.3.0", + "light-program-profiler", + "light-zero-copy", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "thiserror 2.0.18", + "tinyvec", + "zerocopy", +] + +[[package]] +name = "light-compressed-token-sdk" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af361443099082c3f7b0e8afe18a770512c494b25219aad951c80daba76beb86" +dependencies = [ + "arrayvec", + "borsh 0.10.4", + "light-account", + "light-account-checks", + "light-compressed-account", + "light-program-profiler", + "light-sdk", + "light-sdk-types", + "light-token-interface", + "light-token-types", + "light-zero-copy", + "solana-account-info 2.3.0", + "solana-cpi 2.2.1", + "solana-instruction 2.3.3", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "thiserror 2.0.18", +] + +[[package]] +name = "light-compressible" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54745d82dab271a4178b48c48d5768ff54af0a6e01aae62425003c25ed394fc5" +dependencies = [ + "aligned-sized", + "borsh 0.10.4", + "bytemuck", + "light-account-checks", + "light-compressed-account", + "light-hasher", + "light-macros", + "light-program-profiler", + "light-zero-copy", + "pinocchio-pubkey", + "solana-pubkey 2.4.0", + "solana-rent 2.2.1", + "thiserror 2.0.18", + "zerocopy", +] + +[[package]] +name = "light-concurrent-merkle-tree" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db96f47253a0907aaa46dac15cecb27b5510130e48da0b36690dcd2e99a6d558" +dependencies = [ + "borsh 0.10.4", + "light-bounded-vec", + "light-hasher", + "memoffset", + "solana-program-error 2.2.2", + "thiserror 2.0.18", +] + +[[package]] +name = "light-event" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd0c2e68b31f5fc890eb0e0c43bc7d5007cd2e02f4b46f3d601f3a91b4c7262c" +dependencies = [ + "borsh 0.10.4", + "light-compressed-account", + "light-hasher", + "light-token-interface", + "light-zero-copy", + "thiserror 2.0.18", +] + +[[package]] +name = "light-hasher" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c822662e6e109bac0e132a43fd52a4ef684811245a794e048cf9cda001e934c8" +dependencies = [ + "ark-bn254 0.5.0", + "ark-ff 0.5.0", + "borsh 0.10.4", + "light-poseidon 0.3.0", + "num-bigint 0.4.6", + "sha2 0.10.9", + "sha3", + "solana-program-error 2.2.2", + "thiserror 2.0.18", + "tinyvec", +] + +[[package]] +name = "light-indexed-array" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f14f984030d86b6f07bd8f5ae04e2c40fcd0c3bdfcc7a291fff1ed59c9e6554" +dependencies = [ + "light-hasher", + "num-bigint 0.4.6", + "num-traits", + "thiserror 2.0.18", +] + +[[package]] +name = "light-indexed-merkle-tree" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0824755289075f28de2820fc7d4ec4e6b9e99d404e033c07338b91cce8c71fb8" +dependencies = [ + "light-bounded-vec", + "light-concurrent-merkle-tree", + "light-hasher", + "light-merkle-tree-reference", + "num-bigint 0.4.6", + "num-traits", + "solana-program-error 2.2.2", + "thiserror 2.0.18", +] + +[[package]] +name = "light-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "179ac51cadc1d0ca047b4d6265a7cc245ca3affc16a20a2749585aa6464d39c2" +dependencies = [ + "bs58", + "proc-macro2", + "quote", + "solana-pubkey 2.4.0", + "syn 2.0.117", +] + +[[package]] +name = "light-merkle-tree-metadata" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee2ef127f8b968a22203515fca1822cb54bb8f0bd84de392fcb9fb0b77855393" +dependencies = [ + "borsh 0.10.4", + "bytemuck", + "light-compressed-account", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-sysvar 2.3.0", + "thiserror 2.0.18", + "zerocopy", +] + +[[package]] +name = "light-merkle-tree-reference" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8d480f62ca32b38a6231bbc5310d693f91d6b5bdcc18bb13c2d9aab7a1c90e8" +dependencies = [ + "light-hasher", + "light-indexed-array", + "num-bigint 0.4.6", + "num-traits", + "thiserror 2.0.18", +] + +[[package]] +name = "light-poseidon" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c9a85a9752c549ceb7578064b4ed891179d20acd85f27318573b64d2d7ee7ee" +dependencies = [ + "ark-bn254 0.4.0", + "ark-ff 0.4.2", + "num-bigint 0.4.6", + "thiserror 1.0.69", +] + +[[package]] +name = "light-poseidon" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3d87542063daaccbfecd78b60f988079b6ec4e089249658b9455075c78d42" +dependencies = [ + "ark-bn254 0.5.0", + "ark-ff 0.5.0", + "num-bigint 0.4.6", + "thiserror 1.0.69", +] + +[[package]] +name = "light-poseidon" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47a1ccadd0bb5a32c196da536fd72c59183de24a055f6bf0513bf845fefab862" +dependencies = [ + "ark-bn254 0.5.0", + "ark-ff 0.5.0", + "num-bigint 0.4.6", + "thiserror 1.0.69", +] + +[[package]] +name = "light-profiler-macro" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a8be18fe4de58a6f754caa74a3fbc6d8a758a26f1f3c24d5b0f5b55df5f5408" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "light-program-profiler" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1d345871581aebd8825868a3f08410290aa1cdddcb189ca7f7e588f61d79fcf" +dependencies = [ + "light-profiler-macro", +] + +[[package]] +name = "light-prover-client" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a9b434c4819c575c53b439a04cef23e14a7359728d9438a10e6de3641a6d3ba" +dependencies = [ + "ark-bn254 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", + "light-compressed-account", + "light-hasher", + "light-indexed-array", + "light-sparse-merkle-tree", + "num-bigint 0.4.6", + "num-traits", + "reqwest 0.11.27", + "serde", + "serde_json", + "solana-bn254 2.2.2", + "thiserror 2.0.18", + "tokio", + "tracing", +] + +[[package]] +name = "light-sdk" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f982db1ecc2998f3f9af539f282a355582f094036024918627e468e9e29ab418" +dependencies = [ + "bincode", + "borsh 0.10.4", + "bytemuck", + "light-account-checks", + "light-compressed-account", + "light-hasher", + "light-macros", + "light-program-profiler", + "light-sdk-macros", + "light-sdk-types", + "light-token-interface", + "light-zero-copy", + "num-bigint 0.4.6", + "solana-account-info 2.3.0", + "solana-clock 2.2.3", + "solana-cpi 2.2.1", + "solana-instruction 2.3.3", + "solana-loader-v3-interface 5.0.0", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "solana-system-interface 1.0.0", + "solana-sysvar 2.3.0", + "thiserror 2.0.18", +] + +[[package]] +name = "light-sdk-macros" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2160586e2b381827d1ca921b5b9e3383e65c013e2c32e8c14a09d913ca7e1312" +dependencies = [ + "darling 0.21.3", + "light-hasher", + "light-sdk-types", + "proc-macro2", + "quote", + "solana-pubkey 2.4.0", + "syn 2.0.117", +] + +[[package]] +name = "light-sdk-types" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efbd944a80033d928d0abf6152595d2e69aa1af07a3dd0e5b86f0b7e4fc9f484" +dependencies = [ + "borsh 0.10.4", + "bytemuck", + "light-account-checks", + "light-compressed-account", + "light-compressible", + "light-hasher", + "light-macros", + "light-token-interface", + "solana-msg 2.2.1", + "thiserror 2.0.18", +] + +[[package]] +name = "light-sparse-merkle-tree" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4251e79b6c63f4946572dcfd7623680ad0f9e0efe1a761a944733333c5645063" +dependencies = [ + "light-hasher", + "light-indexed-array", + "num-bigint 0.4.6", + "num-traits", + "thiserror 2.0.18", +] + +[[package]] +name = "light-token" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "962fc0c26808f218cd4fb782a15adc24a2163e2e64cacd74c9ca86540cf9afb3" +dependencies = [ + "arrayvec", + "borsh 0.10.4", + "light-account", + "light-account-checks", + "light-batched-merkle-tree", + "light-compressed-account", + "light-compressed-token-sdk", + "light-compressible", + "light-macros", + "light-program-profiler", + "light-sdk", + "light-sdk-types", + "light-token-interface", + "light-token-types", + "light-zero-copy", + "solana-account-info 2.3.0", + "solana-cpi 2.2.1", + "solana-instruction 2.3.3", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "spl-pod 0.5.1", + "thiserror 2.0.18", +] + +[[package]] +name = "light-token-interface" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b14661b6592711d90b1cac2402fa10310d90e0517e035c6b1f47c30a14883461" +dependencies = [ + "aligned-sized", + "borsh 0.10.4", + "bytemuck", + "light-array-map", + "light-compressed-account", + "light-compressible", + "light-hasher", + "light-macros", + "light-program-profiler", + "light-zero-copy", + "pinocchio 0.9.3", + "pinocchio-pubkey", + "solana-account-info 2.3.0", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "solana-sysvar 2.3.0", + "spl-pod 0.5.1", + "spl-token-2022", + "thiserror 2.0.18", + "tinyvec", + "zerocopy", +] + +[[package]] +name = "light-token-types" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e5a8ab668ed571a98a01b4eb4df1e671386e89dc0075e614ede972e34c22742" +dependencies = [ + "borsh 0.10.4", + "light-account-checks", + "light-compressed-account", + "light-macros", + "light-sdk-types", + "solana-msg 2.2.1", + "thiserror 2.0.18", +] + +[[package]] +name = "light-verifier" +version = "10.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d829f997b17c7c65198bb93f0d645a4b2818aed2bd14bf2716e36171d4a9f3f" +dependencies = [ + "groth16-solana", + "light-compressed-account", + "thiserror 2.0.18", +] + +[[package]] +name = "light-zero-copy" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5621fb515e14af46148699c0b65334aabe230a1d2cbd06736ccc7a408c8a4af" +dependencies = [ + "light-zero-copy-derive", + "solana-program-error 2.2.2", + "zerocopy", +] + +[[package]] +name = "light-zero-copy-derive" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41c46425e5c7ab5203ff5c86ae2615b169cca55f9283f5f60f5dd74143be6934" +dependencies = [ + "lazy_static", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "linux-raw-sys" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" + +[[package]] +name = "litemap" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" + +[[package]] +name = "lmdb-rkv" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "447a296f7aca299cfbb50f4e4f3d49451549af655fb7215d7f8c0c3d64bad42b" +dependencies = [ + "bitflags 1.3.2", + "byteorder", + "libc", + "lmdb-rkv-sys", +] + +[[package]] +name = "lmdb-rkv-sys" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61b9ce6b3be08acefa3003c57b7565377432a89ec24476bbe72e11d101f852fe" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + [[package]] name = "log" version = "0.4.29" @@ -4132,9 +5056,9 @@ dependencies = [ [[package]] name = "lru" -version = "0.16.2" +version = "0.16.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96051b46fc183dc9cd4a223960ef37b9af631b55191852a8274bfef064cda20f" +checksum = "7f66e8d5d03f609abc3a39e6f08e4164ebf1447a732906d39eb9b99b7919ef39" dependencies = [ "hashbrown 0.16.1", ] @@ -4169,9 +5093,9 @@ name = "magic-domain-program" version = "0.3.0" source = "git+https://github.com/magicblock-labs/magic-domain-program.git?rev=335a22#335a22ba5aa7b8c4bc84d5053444c74c3b05cdac" dependencies = [ - "borsh", + "borsh 1.6.1", "bytemuck_derive", - "solana-program", + "solana-program 3.0.0", "solana-system-interface 3.2.0", ] @@ -4181,7 +5105,7 @@ version = "0.11.1" dependencies = [ "async-trait", "bincode", - "lru 0.16.2", + "lru 0.16.4", "magicblock-accounts-db", "magicblock-chainlink", "magicblock-committor-service", @@ -4191,18 +5115,18 @@ dependencies = [ "magicblock-magic-program-api 0.11.1", "magicblock-program", "magicblock-rpc-client", - "rand 0.9.2", - "solana-account", + "rand 0.9.4", + "solana-account 3.4.0", "solana-hash 3.1.0", - "solana-instruction", - "solana-loader-v3-interface", - "solana-loader-v4-interface", + "solana-instruction 3.4.0", + "solana-loader-v3-interface 6.1.1", + "solana-loader-v4-interface 3.1.0", "solana-pubkey 3.0.0", - "solana-sdk-ids", - "solana-signature", - "solana-signer", - "solana-sysvar", - "solana-transaction", + "solana-sdk-ids 3.1.0", + "solana-signature 3.4.0", + "solana-signer 3.0.0", + "solana-sysvar 3.1.1", + "solana-transaction 3.1.0", "thiserror 2.0.18", "tokio", "tracing", @@ -4222,11 +5146,11 @@ dependencies = [ "magicblock-program", "solana-hash 3.1.0", "solana-pubkey 3.0.0", - "solana-transaction", - "solana-transaction-error", + "solana-transaction 3.1.0", + "solana-transaction-error 3.2.0", "thiserror 2.0.18", "tokio", - "tokio-util 0.7.17", + "tokio-util 0.7.18", "tracing", "url", ] @@ -4238,10 +5162,10 @@ dependencies = [ "flate2", "lmdb-rkv", "magicblock-config", - "memmap2 0.9.9", + "memmap2 0.9.10", "parking_lot", "reflink-copy", - "solana-account", + "solana-account 3.4.0", "solana-pubkey 3.0.0", "tar", "thiserror 2.0.18", @@ -4269,7 +5193,7 @@ dependencies = [ name = "magicblock-aperture" version = "0.11.1" dependencies = [ - "agave-feature-set", + "agave-feature-set 3.1.12", "agave-geyser-plugin-interface", "arc-swap", "base64 0.21.7", @@ -4278,7 +5202,7 @@ dependencies = [ "fastwebsockets", "futures", "http-body-util", - "hyper 1.8.1", + "hyper 1.9.0", "hyper-util", "libloading", "magicblock-account-cloner", @@ -4292,22 +5216,22 @@ dependencies = [ "parking_lot", "scc", "serde", - "solana-account", + "solana-account 3.4.0", "solana-account-decoder", "solana-fee-structure", - "solana-keypair", - "solana-message", + "solana-keypair 3.1.0", + "solana-message 3.1.0", "solana-pubkey 3.0.0", - "solana-rpc-client-api", - "solana-signature", + "solana-rpc-client-api 3.1.12", + "solana-signature 3.4.0", "solana-system-transaction", - "solana-transaction", - "solana-transaction-error", + "solana-transaction 3.1.0", + "solana-transaction-error 3.2.0", "solana-transaction-status", "sonic-rs", "thiserror 2.0.18", "tokio", - "tokio-util 0.7.17", + "tokio-util 0.7.18", "tracing", ] @@ -4315,10 +5239,11 @@ dependencies = [ name = "magicblock-api" version = "0.11.1" dependencies = [ - "agave-feature-set", + "agave-feature-set 3.1.12", "anyhow", - "borsh", + "borsh 1.6.1", "fd-lock", + "light-client", "magic-domain-program", "magicblock-account-cloner", "magicblock-accounts", @@ -4328,7 +5253,7 @@ dependencies = [ "magicblock-committor-service", "magicblock-config", "magicblock-core", - "magicblock-delegation-program-api 0.3.0 (git+https://github.com/magicblock-labs/delegation-program.git?rev=25386a7c1d406d06b8d07a4d5b0fd37d5e74213b)", + "magicblock-delegation-program-api 0.3.0", "magicblock-ledger", "magicblock-magic-program-api 0.11.1", "magicblock-metrics", @@ -4340,36 +5265,36 @@ dependencies = [ "magicblock-validator-admin", "num_cpus", "paste", - "solana-account", - "solana-clock", + "solana-account 3.4.0", + "solana-clock 3.1.0", "solana-cluster-type 3.1.0", - "solana-commitment-config", - "solana-feature-gate-interface", - "solana-fee-calculator", + "solana-commitment-config 3.1.1", + "solana-feature-gate-interface 3.1.0", + "solana-fee-calculator 3.2.0", "solana-genesis-config", "solana-hash 3.1.0", - "solana-instruction", - "solana-keypair", - "solana-message", - "solana-native-token", - "solana-program", - "solana-program-option", - "solana-program-pack", + "solana-instruction 3.4.0", + "solana-keypair 3.1.0", + "solana-message 3.1.0", + "solana-native-token 3.0.0", + "solana-program 3.0.0", + "solana-program-option 3.1.0", + "solana-program-pack 3.1.0", "solana-pubkey 3.0.0", "solana-rent 3.1.0", - "solana-rpc-client", - "solana-sdk-ids", + "solana-rpc-client 3.1.12", + "solana-sdk-ids 3.1.0", "solana-sha256-hasher 3.1.0", - "solana-signature", - "solana-signer", + "solana-signature 3.4.0", + "solana-signer 3.0.0", "solana-system-program", - "solana-sysvar", - "solana-transaction", - "solana-transaction-error", + "solana-sysvar 3.1.1", + "solana-transaction 3.1.0", + "solana-transaction-error 3.2.0", "spl-token-interface", "thiserror 2.0.18", "tokio", - "tokio-util 0.7.17", + "tokio-util 0.7.18", "tracing", ] @@ -4377,54 +5302,57 @@ dependencies = [ name = "magicblock-chainlink" version = "0.11.1" dependencies = [ - "agave-feature-set", + "agave-feature-set 3.1.12", "arc-swap", "async-trait", "bincode", - "borsh", + "borsh 1.6.1", + "compressed-delegation-client", "futures-util", "helius-laserstream", - "lru 0.16.2", + "light-client", + "lru 0.16.4", "magicblock-accounts-db", "magicblock-aml", "magicblock-config", "magicblock-core", - "magicblock-delegation-program-api 0.3.0 (git+https://github.com/magicblock-labs/delegation-program.git?rev=25386a7c1d406d06b8d07a4d5b0fd37d5e74213b)", + "magicblock-delegation-program-api 0.3.0", "magicblock-magic-program-api 0.11.1", "magicblock-metrics", "parking_lot", + "rustls 0.23.40", "scc", - "solana-account", + "solana-account 3.4.0", "solana-account-decoder", - "solana-account-decoder-client-types", - "solana-address-lookup-table-interface", - "solana-clock", - "solana-commitment-config", + "solana-account-decoder-client-types 3.1.12", + "solana-address-lookup-table-interface 3.1.0", + "solana-clock 3.1.0", + "solana-commitment-config 3.1.1", "solana-hash 3.1.0", - "solana-instruction", - "solana-keypair", - "solana-loader-v3-interface", - "solana-loader-v4-interface", - "solana-message", - "solana-program", + "solana-instruction 3.4.0", + "solana-keypair 3.1.0", + "solana-loader-v3-interface 6.1.1", + "solana-loader-v4-interface 3.1.0", + "solana-message 3.1.0", + "solana-program 3.0.0", "solana-pubkey 3.0.0", "solana-pubsub-client", "solana-rent 3.1.0", - "solana-rpc-client", - "solana-rpc-client-api", - "solana-sdk-ids", - "solana-signature", - "solana-signer", + "solana-rpc-client 3.1.12", + "solana-rpc-client-api 3.1.12", + "solana-sdk-ids 3.1.0", + "solana-signature 3.4.0", + "solana-signer 3.0.0", "solana-system-interface 3.2.0", - "solana-transaction", - "solana-transaction-error", - "spl-token-2022-interface", + "solana-transaction 3.1.0", + "solana-transaction-error 3.2.0", + "spl-token-2022-interface 2.1.0", "spl-token-interface", "thiserror 2.0.18", "tokio", "tokio-stream", - "tokio-util 0.7.17", - "tonic 0.14.5", + "tokio-util 0.7.18", + "tonic 0.14.6", "tracing", "url", ] @@ -4433,13 +5361,13 @@ dependencies = [ name = "magicblock-committor-program" version = "0.11.1" dependencies = [ - "borsh", + "borsh 1.6.1", "paste", - "solana-account", - "solana-account-info", - "solana-program", + "solana-account 3.4.0", + "solana-account-info 3.1.1", + "solana-program 3.0.0", "solana-pubkey 3.0.0", - "solana-sdk-ids", + "solana-sdk-ids 3.1.0", "solana-system-interface 3.2.0", "thiserror 2.0.18", ] @@ -4451,40 +5379,44 @@ dependencies = [ "async-trait", "base64 0.21.7", "bincode", - "borsh", + "borsh 1.6.1", + "compressed-delegation-api", + "compressed-delegation-client", "futures-util", - "lru 0.16.2", + "light-client", + "light-sdk", + "lru 0.16.4", "magicblock-committor-program", "magicblock-core", - "magicblock-delegation-program-api 0.3.0 (git+https://github.com/magicblock-labs/delegation-program.git?rev=25386a7c1d406d06b8d07a4d5b0fd37d5e74213b)", + "magicblock-delegation-program-api 0.3.0", "magicblock-metrics", "magicblock-program", "magicblock-rpc-client", "magicblock-table-mania", "rusqlite", - "solana-account", + "solana-account 3.4.0", "solana-account-decoder", - "solana-address-lookup-table-interface", - "solana-commitment-config", - "solana-compute-budget-interface", + "solana-address-lookup-table-interface 3.1.0", + "solana-commitment-config 3.1.1", + "solana-compute-budget-interface 3.0.0", "solana-hash 3.1.0", - "solana-instruction", - "solana-keypair", - "solana-message", - "solana-program", + "solana-instruction 3.4.0", + "solana-keypair 3.1.0", + "solana-message 3.1.0", + "solana-program 3.0.0", "solana-pubkey 3.0.0", - "solana-rpc-client", - "solana-rpc-client-api", - "solana-signature", - "solana-signer", + "solana-rpc-client 3.1.12", + "solana-rpc-client-api 3.1.12", + "solana-signature 3.4.0", + "solana-signer 3.0.0", "solana-system-program", - "solana-transaction", - "solana-transaction-error", - "solana-transaction-status-client-types", + "solana-transaction 3.1.0", + "solana-transaction-error 3.2.0", + "solana-transaction-status-client-types 3.1.12", "static_assertions", "thiserror 2.0.18", "tokio", - "tokio-util 0.7.17", + "tokio-util 0.7.18", "tracing", ] @@ -4499,10 +5431,10 @@ dependencies = [ "isocountry", "serde", "serde_with", - "solana-keypair", + "solana-keypair 3.1.0", "solana-pubkey 3.0.0", - "solana-signer", - "toml", + "solana-signer 3.0.0", + "toml 0.8.23", "url", ] @@ -4512,22 +5444,25 @@ version = "0.11.1" dependencies = [ "bincode", "bytes", + "compressed-delegation-client", "flume", + "light-client", + "light-sdk", "magicblock-magic-program-api 0.11.1", "serde", - "solana-account", + "solana-account 3.4.0", "solana-account-decoder", - "solana-clock", + "solana-clock 3.1.0", "solana-hash 3.1.0", - "solana-message", - "solana-program", + "solana-message 3.1.0", + "solana-program 3.0.0", "solana-pubkey 3.0.0", - "solana-signature", - "solana-transaction", - "solana-transaction-context", - "solana-transaction-error", - "solana-transaction-status-client-types", - "spl-token-2022-interface", + "solana-signature 3.4.0", + "solana-transaction 3.1.0", + "solana-transaction-context 3.1.12", + "solana-transaction-error 3.2.0", + "solana-transaction-status-client-types 3.1.12", + "spl-token-2022-interface 2.1.0", "spl-token-interface", "tokio", "tracing", @@ -4538,58 +5473,61 @@ dependencies = [ [[package]] name = "magicblock-delegation-program-api" version = "0.3.0" -source = "git+https://github.com/magicblock-labs/delegation-program.git?branch=snawaz%2Fupgrade#25386a7c1d406d06b8d07a4d5b0fd37d5e74213b" +source = "git+https://github.com/magicblock-labs/delegation-program.git?rev=25386a7c1d406d06b8d07a4d5b0fd37d5e74213b#25386a7c1d406d06b8d07a4d5b0fd37d5e74213b" dependencies = [ "bincode", - "borsh", + "borsh 1.6.1", "bytemuck", "const-crypto", + "libsodium-rs", "num_enum", "pinocchio 0.10.2", "pinocchio-log", "pinocchio-pubkey", "pinocchio-system", - "rkyv 0.7.45", + "rkyv 0.7.46", "serde", "solana-address 2.6.0", - "solana-instruction", - "solana-loader-v3-interface", - "solana-program", - "solana-sdk-ids", + "solana-instruction 3.4.0", + "solana-loader-v3-interface 6.1.1", + "solana-program 3.0.0", + "solana-sdk", + "solana-sdk-ids 3.1.0", "solana-sha256-hasher 3.1.0", "solana-system-interface 2.0.0", "static_assertions", - "strum 0.27.2", + "strum 0.28.0", "thiserror 2.0.18", ] [[package]] name = "magicblock-delegation-program-api" -version = "0.3.0" -source = "git+https://github.com/magicblock-labs/delegation-program.git?rev=25386a7c1d406d06b8d07a4d5b0fd37d5e74213b#25386a7c1d406d06b8d07a4d5b0fd37d5e74213b" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "288904a9950bd20f27f0ef934f320ab1410bd35a6d5c9cf138eca276442b6b2e" dependencies = [ "bincode", - "borsh", + "borsh 0.10.4", + "borsh 1.6.1", "bytemuck", "const-crypto", - "libsodium-rs", "num_enum", "pinocchio 0.10.2", "pinocchio-log", "pinocchio-pubkey", "pinocchio-system", - "rkyv 0.7.45", + "rkyv 0.7.46", "serde", "solana-address 2.6.0", - "solana-instruction", - "solana-loader-v3-interface", - "solana-program", - "solana-sdk", - "solana-sdk-ids", + "solana-instruction 3.4.0", + "solana-loader-v3-interface 6.1.1", + "solana-program 3.0.0", + "solana-pubkey 2.4.0", + "solana-sdk-ids 3.1.0", "solana-sha256-hasher 3.1.0", "solana-system-interface 2.0.0", "static_assertions", - "strum 0.27.2", + "strum 0.28.0", "thiserror 2.0.18", ] @@ -4611,35 +5549,36 @@ dependencies = [ "rocksdb", "serde", "solana-account-decoder", - "solana-clock", + "solana-clock 3.1.0", "solana-hash 3.1.0", - "solana-instruction", - "solana-message", + "solana-instruction 3.4.0", + "solana-message 3.1.0", "solana-metrics 2.3.13", "solana-pubkey 3.0.0", - "solana-signature", - "solana-signer", + "solana-signature 3.4.0", + "solana-signer 3.0.0", "solana-storage-proto", "solana-svm-measure", - "solana-transaction", - "solana-transaction-context", - "solana-transaction-error", + "solana-transaction 3.1.0", + "solana-transaction-context 3.1.12", + "solana-transaction-error 3.2.0", "solana-transaction-status", "thiserror 2.0.18", "tokio", - "tokio-util 0.7.17", + "tokio-util 0.7.18", "tracing", ] [[package]] name = "magicblock-magic-program-api" version = "0.9.0" -source = "git+https://github.com/magicblock-labs/magicblock-validator.git?branch=bmuddha%2Fepic%2Fmigration-solana-v3#ef8ebb18879f0a3c41c11159eb5a5358dd3c89c0" +source = "git+https://github.com/magicblock-labs/magicblock-validator.git?branch=dode%2Fcompression-3x#febfda46883e7c171f42af2ffb0925a7a60cfe29" dependencies = [ "bincode", + "const-crypto", "serde", - "solana-program", - "solana-signature", + "solana-program 3.0.0", + "solana-signature 3.4.0", ] [[package]] @@ -4649,8 +5588,8 @@ dependencies = [ "bincode", "const-crypto", "serde", - "solana-program", - "solana-signature", + "solana-program 3.0.0", + "solana-signature 3.4.0", ] [[package]] @@ -4658,13 +5597,13 @@ name = "magicblock-metrics" version = "0.11.1" dependencies = [ "http-body-util", - "hyper 1.8.1", + "hyper 1.9.0", "hyper-util", "lazy_static", "prometheus", - "solana-signature", + "solana-signature 3.4.0", "tokio", - "tokio-util 0.7.17", + "tokio-util 0.7.18", "tracing", ] @@ -4672,7 +5611,7 @@ dependencies = [ name = "magicblock-processor" version = "0.11.1" dependencies = [ - "agave-feature-set", + "agave-feature-set 3.1.12", "agave-precompiles", "agave-syscalls", "bincode", @@ -4683,33 +5622,33 @@ dependencies = [ "magicblock-metrics", "magicblock-program", "parking_lot", - "rustc-hash 2.1.1", + "rustc-hash 2.1.2", "serde", - "solana-account", + "solana-account 3.4.0", "solana-bpf-loader-program", "solana-compute-budget", "solana-compute-budget-program", - "solana-feature-gate-interface", + "solana-feature-gate-interface 3.1.0", "solana-fee-structure", - "solana-instruction", - "solana-loader-v3-interface", + "solana-instruction 3.4.0", + "solana-loader-v3-interface 6.1.1", "solana-loader-v4-program", "solana-precompile-error", - "solana-program", + "solana-program 3.0.0", "solana-program-runtime", "solana-pubkey 3.0.0", - "solana-sdk-ids", + "solana-sdk-ids 3.1.0", "solana-svm", "solana-svm-callback", "solana-svm-transaction", "solana-system-program", - "solana-transaction", - "solana-transaction-context", - "solana-transaction-error", + "solana-transaction 3.1.0", + "solana-transaction-context 3.1.12", + "solana-transaction-error 3.2.0", "solana-transaction-status", "solana-zk-elgamal-proof-program", "tokio", - "tokio-util 0.7.17", + "tokio-util 0.7.18", "tracing", ] @@ -4725,25 +5664,25 @@ dependencies = [ "num-traits", "parking_lot", "serde", - "solana-account", - "solana-account-info", - "solana-clock", - "solana-fee-calculator", + "solana-account 3.4.0", + "solana-account-info 3.1.1", + "solana-clock 3.1.0", + "solana-fee-calculator 3.2.0", "solana-hash 3.1.0", - "solana-instruction", - "solana-keypair", - "solana-loader-v3-interface", - "solana-loader-v4-interface", + "solana-instruction 3.4.0", + "solana-keypair 3.1.0", + "solana-loader-v3-interface 6.1.1", + "solana-loader-v4-interface 3.1.0", "solana-program-runtime", "solana-pubkey 3.0.0", - "solana-sdk-ids", - "solana-seed-derivable", - "solana-signature", - "solana-signer", + "solana-sdk-ids 3.1.0", + "solana-seed-derivable 3.0.0", + "solana-signature 3.4.0", + "solana-signer 3.0.0", "solana-svm-log-collector", - "solana-sysvar", - "solana-transaction", - "solana-transaction-context", + "solana-sysvar 3.1.1", + "solana-transaction 3.1.0", + "solana-transaction-context 3.1.12", "thiserror 2.0.18", ] @@ -4763,11 +5702,11 @@ dependencies = [ "serde", "solana-hash 3.1.0", "solana-pubkey 3.0.0", - "solana-transaction", - "solana-transaction-error", + "solana-transaction 3.1.0", + "solana-transaction-error 3.2.0", "thiserror 2.0.18", "tokio", - "tokio-util 0.7.17", + "tokio-util 0.7.18", "tracing", "url", ] @@ -4777,19 +5716,19 @@ name = "magicblock-rpc-client" version = "0.11.1" dependencies = [ "futures-util", - "solana-account", - "solana-account-decoder-client-types", - "solana-address-lookup-table-interface", - "solana-clock", - "solana-commitment-config", + "solana-account 3.4.0", + "solana-account-decoder-client-types 3.1.12", + "solana-address-lookup-table-interface 3.1.0", + "solana-clock 3.1.0", + "solana-commitment-config 3.1.1", "solana-hash 3.1.0", - "solana-instruction", + "solana-instruction 3.4.0", "solana-pubkey 3.0.0", - "solana-rpc-client", - "solana-rpc-client-api", - "solana-signature", - "solana-transaction-error", - "solana-transaction-status-client-types", + "solana-rpc-client 3.1.12", + "solana-rpc-client-api 3.1.12", + "solana-signature 3.4.0", + "solana-transaction-error 3.2.0", + "solana-transaction-status-client-types 3.1.12", "thiserror 2.0.18", "tokio", "tracing", @@ -4803,14 +5742,14 @@ dependencies = [ "futures-util", "magicblock-core", "magicblock-magic-program-api 0.11.1", - "solana-instruction", - "solana-keypair", - "solana-message", + "solana-instruction 3.4.0", + "solana-keypair 3.1.0", + "solana-message 3.1.0", "solana-pubkey 3.0.0", - "solana-rpc-client", - "solana-signature", - "solana-signer", - "solana-transaction", + "solana-rpc-client 3.1.12", + "solana-signature 3.4.0", + "solana-signer 3.0.0", + "solana-transaction 3.1.0", "thiserror 2.0.18", "tokio", "tracing", @@ -4823,20 +5762,20 @@ dependencies = [ "ed25519-dalek 1.0.1", "magicblock-metrics", "magicblock-rpc-client", - "rand 0.9.2", + "rand 0.9.4", "sha3", - "solana-address-lookup-table-interface", - "solana-clock", - "solana-commitment-config", - "solana-compute-budget-interface", - "solana-instruction", - "solana-keypair", - "solana-message", + "solana-address-lookup-table-interface 3.1.0", + "solana-clock 3.1.0", + "solana-commitment-config 3.1.1", + "solana-compute-budget-interface 3.0.0", + "solana-instruction 3.4.0", + "solana-keypair 3.1.0", + "solana-message 3.1.0", "solana-pubkey 3.0.0", - "solana-signature", - "solana-signer", - "solana-slot-hashes", - "solana-transaction", + "solana-signature 3.4.0", + "solana-signer 3.0.0", + "solana-slot-hashes 3.0.2", + "solana-transaction 3.1.0", "thiserror 2.0.18", "tokio", "tracing", @@ -4854,17 +5793,17 @@ dependencies = [ "magicblock-ledger", "magicblock-program", "rusqlite", - "solana-instruction", - "solana-message", + "solana-instruction 3.4.0", + "solana-message 3.1.0", "solana-pubkey 3.0.0", - "solana-rpc-client", - "solana-rpc-client-api", - "solana-signature", - "solana-transaction", - "solana-transaction-error", + "solana-rpc-client 3.1.12", + "solana-rpc-client-api 3.1.12", + "solana-signature 3.4.0", + "solana-transaction 3.1.0", + "solana-transaction-error 3.2.0", "thiserror 2.0.18", "tokio", - "tokio-util 0.7.17", + "tokio-util 0.7.18", "tracing", ] @@ -4872,16 +5811,16 @@ dependencies = [ name = "magicblock-validator-admin" version = "0.11.1" dependencies = [ - "magicblock-delegation-program-api 0.3.0 (git+https://github.com/magicblock-labs/delegation-program.git?rev=25386a7c1d406d06b8d07a4d5b0fd37d5e74213b)", + "magicblock-delegation-program-api 0.3.0", "magicblock-program", "magicblock-rpc-client", - "solana-commitment-config", - "solana-rpc-client", - "solana-signature", - "solana-signer", - "solana-transaction", + "solana-commitment-config 3.1.1", + "solana-rpc-client 3.1.12", + "solana-signature 3.4.0", + "solana-signer 3.0.0", + "solana-transaction 3.1.0", "tokio", - "tokio-util 0.7.17", + "tokio-util 0.7.18", "tracing", ] @@ -4889,13 +5828,13 @@ dependencies = [ name = "magicblock-version" version = "0.11.1" dependencies = [ - "agave-feature-set", + "agave-feature-set 3.1.12", "git-version", "rustc_version", "semver", "serde", "solana-frozen-abi-macro", - "solana-rpc-client-api", + "solana-rpc-client-api 3.1.12", "solana-sanitize 3.0.1", ] @@ -4922,9 +5861,9 @@ checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" [[package]] name = "memchr" -version = "2.7.6" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] name = "memmap2" @@ -4937,9 +5876,9 @@ dependencies = [ [[package]] name = "memmap2" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "744133e4a0e0a658e1374cf3bf8e415c4052a15a111acd372764c55b4177d490" +checksum = "714098028fe011992e1c3962653c96b2d578c4b4bce9036e15ff220319b1e0e3" dependencies = [ "libc", ] @@ -4979,9 +5918,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "minisign-verify" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e856fdd13623a2f5f2f54676a4ee49502a96a80ef4a62bcedd23d52427c44d43" +checksum = "22f9645cb765ea72b8111f36c522475d2daa0d22c957a9826437e97534bc4e9e" [[package]] name = "miniz_oxide" @@ -4995,9 +5934,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" +checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" dependencies = [ "libc", "log", @@ -5055,9 +5994,9 @@ dependencies = [ [[package]] name = "multimap" -version = "0.8.3" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" +checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084" [[package]] name = "munge" @@ -5085,22 +6024,22 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", ] [[package]] name = "native-tls" -version = "0.2.14" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +checksum = "465500e14ea162429d264d44189adc38b199b62b1c21eea9f69e4b73cb03bbf2" dependencies = [ "libc", "log", "openssl", - "openssl-probe", + "openssl-probe 0.2.1", "openssl-sys", "schannel", - "security-framework 2.11.1", + "security-framework 3.7.0", "security-framework-sys", "tempfile", ] @@ -5111,13 +6050,25 @@ version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.1", "cfg-if", "cfg_aliases", "libc", "memoffset", ] +[[package]] +name = "nix" +version = "0.31.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d" +dependencies = [ + "bitflags 2.11.1", + "cfg-if", + "cfg_aliases", + "libc", +] + [[package]] name = "nkeys" version = "0.4.5" @@ -5127,9 +6078,9 @@ dependencies = [ "data-encoding", "ed25519 2.2.3", "ed25519-dalek 2.2.0", - "getrandom 0.2.16", + "getrandom 0.2.17", "log", - "rand 0.8.5", + "rand 0.8.6", "signatory", ] @@ -5139,6 +6090,15 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c" +[[package]] +name = "no_std_io2" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418abd1b6d34fbf6cae440dc874771b0525a604428704c76e48b29a5e67b8003" +dependencies = [ + "memchr", +] + [[package]] name = "nom" version = "7.1.3" @@ -5167,7 +6127,7 @@ version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d3d07927151ff8575b7087f245456e549fea62edf0ec4e565a5ee50c8402bc3" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.1", "fsevent-sys", "inotify", "kqueue", @@ -5185,7 +6145,7 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42b8cfee0e339a0337359f3c88165702ac6e600dc01c0cc9579a92d62b08477a" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.1", ] [[package]] @@ -5194,7 +6154,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -5203,7 +6163,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc895af95856f929163a0aa20c26a78d26bfdc839f51b9d5aa7a5b79e52b7e83" dependencies = [ - "rand 0.8.5", + "rand 0.8.6", ] [[package]] @@ -5239,6 +6199,7 @@ checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ "num-integer", "num-traits", + "serde", ] [[package]] @@ -5253,9 +6214,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.1.0" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" [[package]] name = "num-derive" @@ -5331,9 +6292,9 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c" +checksum = "5d0bca838442ec211fa11de3a8b0e0e8f3a4522575b5c4c06ed722e005036f26" dependencies = [ "num_enum_derive", "rustversion", @@ -5341,21 +6302,27 @@ dependencies = [ [[package]] name = "num_enum_derive" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" +checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 3.5.0", "proc-macro2", "quote", "syn 2.0.117", ] +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + [[package]] name = "objc2" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c2599ce0ec54857b29ce62166b0ed9b4f6f1a70ccc9a71165b6154caca8c05" +checksum = "3a12a8ed07aefc768292f076dc3ac8c48f3781c8f2d5851dd3d98950e8c5a89f" dependencies = [ "objc2-encode", ] @@ -5386,9 +6353,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.21.3" +version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "once_cell_polyfill" @@ -5404,15 +6371,14 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.75" +version = "0.10.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328" +checksum = "a45fa2aa886c42762255da344f0a0d313e254066c46aad76f300c3d3da62d967" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.1", "cfg-if", "foreign-types", "libc", - "once_cell", "openssl-macros", "openssl-sys", ] @@ -5434,6 +6400,12 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" +[[package]] +name = "openssl-probe" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" + [[package]] name = "openssl-src" version = "300.6.0+3.6.2" @@ -5445,9 +6417,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.111" +version = "0.9.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" +checksum = "f28a22dc7140cda5f096e5e7724a6962ca81a7f8bfd2979f9b18c11af56318c4" dependencies = [ "cc", "libc", @@ -5471,7 +6443,7 @@ dependencies = [ "lazy_static", "percent-encoding", "pin-project", - "rand 0.8.5", + "rand 0.8.6", "thiserror 1.0.69", ] @@ -5508,7 +6480,7 @@ checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.18", + "redox_syscall", "smallvec", "windows-link", ] @@ -5521,9 +6493,9 @@ checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "pastey" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b867cad97c0791bbd3aaa6472142568c6c9e8f71937e98379f584cfb0cf35bec" +checksum = "2ee67f1008b1ba2321834326597b8e186293b049a023cdef258527550b9935b4" [[package]] name = "pbkdf2" @@ -5597,7 +6569,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset 0.4.2", - "indexmap 2.12.1", + "indexmap 2.14.0", ] [[package]] @@ -5607,24 +6579,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455" dependencies = [ "fixedbitset 0.5.7", - "hashbrown 0.15.2", - "indexmap 2.12.1", + "hashbrown 0.15.5", + "indexmap 2.14.0", +] + +[[package]] +name = "photon-api" +version = "0.56.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95609d4f08f2cf86d6e41f5b483cfbbfd914099eb0f7c6ea15e98b358f4614f8" +dependencies = [ + "progenitor-client", + "reqwest 0.13.3", + "serde", + "serde_json", ] [[package]] name = "pin-project" -version = "1.1.10" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" +checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.10" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" +checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" dependencies = [ "proc-macro2", "quote", @@ -5633,21 +6617,15 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" - -[[package]] -name = "pin-utils" -version = "0.1.0" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] name = "pinocchio" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b971851087bc3699b001954ad02389d50c41405ece3548cbcafc88b3e20017a" +checksum = "b8afe4f39c0e25cc471b35b89963312791a5162d45a86578cbeaad9e5e7d1b3b" [[package]] name = "pinocchio" @@ -5659,7 +6637,7 @@ dependencies = [ "solana-address 2.6.0", "solana-define-syscall 4.0.1", "solana-instruction-view", - "solana-program-error", + "solana-program-error 3.0.1", ] [[package]] @@ -5689,7 +6667,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0225638cadcbebae8932cb7f49cb5da7c15c21beb19f048f05a5ca7d93f065" dependencies = [ "five8_const 0.1.4", - "pinocchio 0.9.2", + "pinocchio 0.9.3", "sha2-const-stable", ] @@ -5715,9 +6693,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" [[package]] name = "polyval" @@ -5726,7 +6704,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "opaque-debug", "universal-hash", ] @@ -5739,18 +6717,18 @@ checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" [[package]] name = "portable-atomic-util" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "091397be61a01d4be58e7841595bd4bfedb15f1cd54977d79b8271e94ed799a3" +checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618" dependencies = [ "portable-atomic", ] [[package]] name = "potential_utf" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" dependencies = [ "zerovec", ] @@ -5786,15 +6764,15 @@ dependencies = [ [[package]] name = "predicates-core" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "727e462b119fe9c93fd0eb1429a5f7647394014cf3c04ab2c0350eeb09095ffa" +checksum = "cad38746f3166b4031b1a0d39ad9f954dd291e7854fcc0eed52ee41a0b50d144" [[package]] name = "predicates-tree" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72dd2d6d381dfb73a193c7fca536518d7caee39fc8503f74e7dc0be0531b425c" +checksum = "d0de1b847b39c8131db0467e9df1ff60e6d0562ab8e9a16e568ad0fdb372e2f2" dependencies = [ "predicates-core", "termtree", @@ -5802,9 +6780,9 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.36" +version = "0.2.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff24dfcda44452b9816fff4cd4227e1bb73ff5a2f1bc1105aa92fb8565ce44d2" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", "syn 2.0.117", @@ -5812,11 +6790,20 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.4.0" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" dependencies = [ - "toml_edit 0.23.9", + "toml 0.5.11", +] + +[[package]] +name = "proc-macro-crate" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" +dependencies = [ + "toml_edit 0.25.11+spec-1.1.0", ] [[package]] @@ -5862,16 +6849,36 @@ dependencies = [ "yansi", ] +[[package]] +name = "progenitor-client" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffab7b358944dba033a7b324e7558e66e6bcb1fb4705cf57f26fd5092bcae630" +dependencies = [ + "bytes", + "futures-core", + "percent-encoding", + "reqwest 0.13.3", + "serde", + "serde_json", + "serde_urlencoded", +] + [[package]] name = "program-flexi-counter" version = "0.0.0" dependencies = [ "bincode", - "borsh", + "borsh 1.6.1", + "compressed-delegation-api", + "compressed-delegation-client", "ephemeral-rollups-sdk", + "light-hasher", + "light-sdk", + "light-sdk-types", "magicblock-magic-program-api 0.11.1", "serde", - "solana-program", + "solana-program 3.0.0", "solana-system-interface 3.2.0", ] @@ -5879,10 +6886,10 @@ dependencies = [ name = "program-mini" version = "0.0.0" dependencies = [ - "solana-program", + "solana-program 3.0.0", "solana-program-test", "solana-sdk", - "solana-sdk-ids", + "solana-sdk-ids 3.1.0", "solana-system-interface 3.2.0", "tokio", ] @@ -5891,12 +6898,12 @@ dependencies = [ name = "program-schedulecommit" version = "0.0.0" dependencies = [ - "borsh", + "borsh 1.6.1", "ephemeral-rollups-sdk", - "magicblock-delegation-program-api 0.3.0 (git+https://github.com/magicblock-labs/delegation-program.git?rev=25386a7c1d406d06b8d07a4d5b0fd37d5e74213b)", + "magicblock-delegation-program-api 0.3.0", "magicblock-magic-program-api 0.11.1", - "rkyv 0.7.45", - "solana-program", + "rkyv 0.7.46", + "solana-program 3.0.0", "solana-system-interface 3.2.0", "static_assertions", ] @@ -5905,10 +6912,10 @@ dependencies = [ name = "program-schedulecommit-security" version = "0.0.0" dependencies = [ - "borsh", + "borsh 1.6.1", "ephemeral-rollups-sdk", "program-schedulecommit", - "solana-program", + "solana-program 3.0.0", ] [[package]] @@ -5983,7 +6990,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "343d3bd7056eda839b03204e68deff7d1b13aba7af2b2fd16890697274262ee7" dependencies = [ "heck 0.5.0", - "itertools 0.13.0", + "itertools 0.14.0", "log", "multimap", "petgraph 0.8.3", @@ -6017,7 +7024,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b" dependencies = [ "anyhow", - "itertools 0.13.0", + "itertools 0.14.0", "proc-macro2", "quote", "syn 2.0.117", @@ -6098,11 +7105,11 @@ dependencies = [ [[package]] name = "pulldown-cmark" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c3a14896dfa883796f1cb410461aef38810ea05f2b2c33c5aded3649095fdad" +checksum = "e9f068eba8e7071c5f9511831b44f32c740d5adf574e990f946ddb53db2f314e" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.1", "memchr", "unicase", ] @@ -6162,9 +7169,9 @@ dependencies = [ "pin-project-lite", "quinn-proto", "quinn-udp", - "rustc-hash 2.1.1", - "rustls 0.23.35", - "socket2 0.6.1", + "rustc-hash 2.1.2", + "rustls 0.23.40", + "socket2 0.6.3", "thiserror 2.0.18", "tokio", "tracing", @@ -6173,17 +7180,18 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.13" +version = "0.11.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" +checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" dependencies = [ + "aws-lc-rs", "bytes", "getrandom 0.3.4", "lru-slab", - "rand 0.9.2", + "rand 0.9.4", "ring", - "rustc-hash 2.1.1", - "rustls 0.23.35", + "rustc-hash 2.1.2", + "rustls 0.23.40", "rustls-pki-types", "slab", "thiserror 2.0.18", @@ -6201,7 +7209,7 @@ dependencies = [ "cfg_aliases", "libc", "once_cell", - "socket2 0.6.1", + "socket2 0.6.3", "tracing", "windows-sys 0.60.2", ] @@ -6221,6 +7229,12 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + [[package]] name = "radium" version = "0.7.0" @@ -6251,9 +7265,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" dependencies = [ "libc", "rand_chacha 0.3.1", @@ -6262,12 +7276,12 @@ dependencies = [ [[package]] name = "rand" -version = "0.9.2" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" dependencies = [ "rand_chacha 0.9.0", - "rand_core 0.9.3", + "rand_core 0.9.5", ] [[package]] @@ -6297,7 +7311,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", - "rand_core 0.9.3", + "rand_core 0.9.5", ] [[package]] @@ -6315,14 +7329,14 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", ] [[package]] name = "rand_core" -version = "0.9.3" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" dependencies = [ "getrandom 0.3.4", ] @@ -6360,14 +7374,14 @@ version = "11.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.1", ] [[package]] name = "rayon" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" +checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d" dependencies = [ "either", "rayon-core", @@ -6389,16 +7403,7 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.10.0", -] - -[[package]] -name = "redox_syscall" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec96166dafa0886eb81fe1c0a388bece180fbef2135f97c1e2cf8302e74b43b5" -dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.1", ] [[package]] @@ -6423,9 +7428,9 @@ dependencies = [ [[package]] name = "reflink-copy" -version = "0.1.28" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23bbed272e39c47a095a5242218a67412a220006842558b03fe2935e8f3d7b92" +checksum = "13362233b147e57674c37b802d216b7c5e3dcccbed8967c84f0d8d223868ae27" dependencies = [ "cfg-if", "libc", @@ -6435,9 +7440,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.12.2" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" dependencies = [ "aho-corasick", "memchr", @@ -6447,9 +7452,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" dependencies = [ "aho-corasick", "memchr", @@ -6458,9 +7463,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.8" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" +checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" [[package]] name = "rend" @@ -6509,11 +7514,11 @@ dependencies = [ "serde_json", "serde_urlencoded", "sync_wrapper 0.1.2", - "system-configuration", + "system-configuration 0.5.1", "tokio", "tokio-native-tls", "tokio-rustls 0.24.1", - "tokio-util 0.7.17", + "tokio-util 0.7.18", "tower-service", "url", "wasm-bindgen", @@ -6535,12 +7540,12 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2 0.4.12", + "h2 0.4.14", "http 1.4.0", "http-body 1.0.1", "http-body-util", - "hyper 1.8.1", - "hyper-rustls 0.27.8", + "hyper 1.9.0", + "hyper-rustls 0.27.9", "hyper-tls 0.6.0", "hyper-util", "js-sys", @@ -6550,7 +7555,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "quinn", - "rustls 0.23.35", + "rustls 0.23.40", "rustls-pki-types", "serde", "serde_json", @@ -6559,14 +7564,55 @@ dependencies = [ "tokio", "tokio-native-tls", "tokio-rustls 0.26.4", - "tower 0.5.2", + "tower 0.5.3", "tower-http", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots 1.0.4", + "webpki-roots 1.0.7", +] + +[[package]] +name = "reqwest" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62e0021ea2c22aed41653bc7e1419abb2c97e038ff2c33d0e1309e49a97deec0" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-core", + "futures-util", + "http 1.4.0", + "http-body 1.0.1", + "http-body-util", + "hyper 1.9.0", + "hyper-rustls 0.27.9", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls 0.23.40", + "rustls-pki-types", + "rustls-platform-verifier 0.7.0", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper 1.0.2", + "tokio", + "tokio-rustls 0.26.4", + "tokio-util 0.7.18", + "tower 0.5.3", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", ] [[package]] @@ -6602,7 +7648,7 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.16", + "getrandom 0.2.17", "libc", "untrusted", "windows-sys 0.52.0", @@ -6610,9 +7656,9 @@ dependencies = [ [[package]] name = "rkyv" -version = "0.7.45" +version = "0.7.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9008cd6385b9e161d8229e1f6549dd23c3d022f132a2ea37ac3a10ac4935779b" +checksum = "2297bf9c81a3f0dc96bc9521370b88f054168c29826a75e89c55ff196e7ed6a1" dependencies = [ "bitvec", "bytecheck", @@ -6620,7 +7666,7 @@ dependencies = [ "hashbrown 0.12.3", "ptr_meta 0.1.4", "rend 0.4.2", - "rkyv_derive 0.7.45", + "rkyv_derive 0.7.46", "seahash", "tinyvec", "uuid", @@ -6628,27 +7674,27 @@ dependencies = [ [[package]] name = "rkyv" -version = "0.8.12" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35a640b26f007713818e9a9b65d34da1cf58538207b052916a83d80e43f3ffa4" +checksum = "73389e0c99e664f919275ab5b5b0471391fe9a8de61e1dff9b1eaf56a90f16e3" dependencies = [ "bytes", - "hashbrown 0.15.2", - "indexmap 2.12.1", + "hashbrown 0.17.1", + "indexmap 2.14.0", "munge", "ptr_meta 0.3.1", "rancor", "rend 0.5.3", - "rkyv_derive 0.8.12", + "rkyv_derive 0.8.16", "tinyvec", "uuid", ] [[package]] name = "rkyv_derive" -version = "0.7.45" +version = "0.7.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "503d1d27590a2b0a3a4ca4c94755aa2875657196ecbf401a42eff41d7de532c0" +checksum = "84d7b42d4b8d06048d3ac8db0eb31bcb942cbeb709f0b5f2b2ebde398d3038f5" dependencies = [ "proc-macro2", "quote", @@ -6657,9 +7703,9 @@ dependencies = [ [[package]] name = "rkyv_derive" -version = "0.8.12" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd83f5f173ff41e00337d97f6572e416d022ef8a19f371817259ae960324c482" +checksum = "5d2ed0b54125315fb36bd021e82d314d1c126548f871634b483f46b31d13cac6" dependencies = [ "proc-macro2", "quote", @@ -6687,7 +7733,7 @@ version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "165ca6e57b20e1351573e3729b958bc62f0e48025386970b6e4d29e7a7e71f3f" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.1", "fallible-iterator", "fallible-streaming-iterator", "hashlink", @@ -6697,9 +7743,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" +checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d" [[package]] name = "rustc-hash" @@ -6709,9 +7755,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustc-hash" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" +checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" [[package]] name = "rustc_version" @@ -6733,15 +7779,15 @@ dependencies = [ [[package]] name = "rustix" -version = "1.1.2" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.1", "errno", "libc", "linux-raw-sys", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -6758,15 +7804,16 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.35" +version = "0.23.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "533f54bc6a7d4f647e46ad909549eda97bf5afc1585190ef692b4286b198bd8f" +checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" dependencies = [ + "aws-lc-rs", "log", "once_cell", "ring", "rustls-pki-types", - "rustls-webpki 0.103.8", + "rustls-webpki 0.103.13", "subtle", "zeroize", ] @@ -6777,7 +7824,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5" dependencies = [ - "openssl-probe", + "openssl-probe 0.1.6", "rustls-pemfile 2.2.0", "rustls-pki-types", "schannel", @@ -6786,14 +7833,14 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9980d917ebb0c0536119ba501e90834767bffc3d60641457fd84a1f3fd337923" +checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" dependencies = [ - "openssl-probe", + "openssl-probe 0.2.1", "rustls-pki-types", "schannel", - "security-framework 3.5.1", + "security-framework 3.7.0", ] [[package]] @@ -6816,9 +7863,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.13.2" +version = "1.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e6f2ab2928ca4291b86736a8bd920a277a399bba1589409d72154ff87c1282" +checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9" dependencies = [ "web-time", "zeroize", @@ -6828,21 +7875,42 @@ dependencies = [ name = "rustls-platform-verifier" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784" +checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784" +dependencies = [ + "core-foundation 0.10.1", + "core-foundation-sys", + "jni 0.21.1", + "log", + "once_cell", + "rustls 0.23.40", + "rustls-native-certs 0.8.3", + "rustls-platform-verifier-android", + "rustls-webpki 0.103.13", + "security-framework 3.7.0", + "security-framework-sys", + "webpki-root-certs", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls-platform-verifier" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0" dependencies = [ "core-foundation 0.10.1", "core-foundation-sys", - "jni", + "jni 0.22.4", "log", "once_cell", - "rustls 0.23.35", - "rustls-native-certs 0.8.2", + "rustls 0.23.40", + "rustls-native-certs 0.8.3", "rustls-platform-verifier-android", - "rustls-webpki 0.103.8", - "security-framework 3.5.1", + "rustls-webpki 0.103.13", + "security-framework 3.7.0", "security-framework-sys", "webpki-root-certs", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -6873,10 +7941,11 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.8" +version = "0.103.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52" +checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" dependencies = [ + "aws-lc-rs", "ring", "rustls-pki-types", "untrusted", @@ -6890,9 +7959,9 @@ checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "ryu" -version = "1.0.20" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" [[package]] name = "same-file" @@ -6914,9 +7983,9 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.28" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" +checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" dependencies = [ "windows-sys 0.61.2", ] @@ -6926,15 +7995,15 @@ name = "schedulecommit-client" version = "0.0.0" dependencies = [ "anyhow", - "borsh", + "borsh 1.6.1", "integration-test-tools", - "magicblock-delegation-program-api 0.3.0 (git+https://github.com/magicblock-labs/delegation-program.git?rev=25386a7c1d406d06b8d07a4d5b0fd37d5e74213b)", + "magicblock-delegation-program-api 0.3.0", "program-schedulecommit", - "solana-commitment-config", - "solana-compute-budget-interface", - "solana-program", - "solana-rpc-client", - "solana-rpc-client-api", + "solana-commitment-config 3.1.1", + "solana-compute-budget-interface 3.0.0", + "solana-program 3.0.0", + "solana-rpc-client 3.1.12", + "solana-rpc-client-api 3.1.12", "solana-sdk", "solana-system-interface 3.2.0", "tracing", @@ -6945,25 +8014,30 @@ name = "schedulecommit-committor-service" version = "0.0.0" dependencies = [ "async-trait", - "borsh", + "borsh 1.6.1", + "compressed-delegation-client", "futures", + "light-client", + "light-sdk", + "light-sdk-types", "magicblock-committor-program", "magicblock-committor-service", "magicblock-core", - "magicblock-delegation-program-api 0.3.0 (git+https://github.com/magicblock-labs/delegation-program.git?rev=25386a7c1d406d06b8d07a4d5b0fd37d5e74213b)", + "magicblock-delegation-program-api 0.3.0", "magicblock-program", "magicblock-rpc-client", "magicblock-table-mania", "program-flexi-counter", "program-schedulecommit", - "rand 0.8.5", - "solana-account", - "solana-commitment-config", + "rand 0.8.6", + "solana-account 3.4.0", + "solana-commitment-config 3.1.1", + "solana-compute-budget-interface 3.0.0", "solana-pubkey 3.0.0", - "solana-rpc-client", - "solana-rpc-client-api", + "solana-rpc-client 3.1.12", + "solana-rpc-client-api 3.1.12", "solana-sdk", - "solana-sdk-ids", + "solana-sdk-ids 3.1.0", "solana-system-interface 3.2.0", "test-kit", "tokio", @@ -6974,23 +8048,29 @@ dependencies = [ name = "schedulecommit-test-scenarios" version = "0.0.0" dependencies = [ - "borsh", + "borsh 1.6.1", + "compressed-delegation-client", "ephemeral-rollups-sdk", "integration-test-tools", + "light-client", + "light-sdk", "magicblock-core", - "magicblock-delegation-program-api 0.3.0 (git+https://github.com/magicblock-labs/delegation-program.git?rev=25386a7c1d406d06b8d07a4d5b0fd37d5e74213b)", + "magicblock-delegation-program-api 0.3.0", "magicblock-magic-program-api 0.11.1", "magicblock-program", + "program-flexi-counter", "program-schedulecommit", - "rand 0.8.5", + "rand 0.8.6", "schedulecommit-client", "serial_test", - "solana-commitment-config", - "solana-program", - "solana-rpc-client", - "solana-rpc-client-api", + "solana-commitment-config 3.1.1", + "solana-compute-budget-interface 3.0.0", + "solana-program 3.0.0", + "solana-rpc-client 3.1.12", + "solana-rpc-client-api 3.1.12", "solana-sdk", "test-kit", + "tokio", "tracing", ] @@ -6999,12 +8079,12 @@ name = "schedulecommit-test-security" version = "0.0.0" dependencies = [ "integration-test-tools", - "magicblock-delegation-program-api 0.3.0 (git+https://github.com/magicblock-labs/delegation-program.git?rev=25386a7c1d406d06b8d07a4d5b0fd37d5e74213b)", + "magicblock-delegation-program-api 0.3.0", "magicblock-magic-program-api 0.11.1", "program-schedulecommit", "program-schedulecommit-security", "schedulecommit-client", - "solana-rpc-client-api", + "solana-rpc-client-api 3.1.12", "solana-sdk", "solana-system-interface 3.2.0", ] @@ -7023,9 +8103,9 @@ dependencies = [ [[package]] name = "schemars" -version = "1.1.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9558e172d4e8533736ba97870c4b2cd63f84b382a3d6eb063da41b91cce17289" +checksum = "a2b42f36aa1cd011945615b92222f6bf73c599a102a300334cd7f8dbeec726cc" dependencies = [ "dyn-clone", "ref-cast", @@ -7081,7 +8161,7 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.1", "core-foundation 0.9.4", "core-foundation-sys", "libc", @@ -7090,11 +8170,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "3.5.1" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" +checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.1", "core-foundation 0.10.1", "core-foundation-sys", "libc", @@ -7103,9 +8183,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.15.0" +version = "2.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" +checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" dependencies = [ "core-foundation-sys", "libc", @@ -7113,9 +8193,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" [[package]] name = "seqlock" @@ -7177,15 +8257,15 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.145" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" dependencies = [ "itoa", "memchr", - "ryu", "serde", "serde_core", + "zmij", ] [[package]] @@ -7231,17 +8311,18 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.16.1" +version = "3.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fa237f2807440d238e0364a218270b98f767a00d3dada77b1c53ae88940e2e7" +checksum = "e72c1c2cb7b223fafb600a619537a871c2818583d619401b785e7c0b746ccde2" dependencies = [ "base64 0.22.1", + "bs58", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.12.1", + "indexmap 2.14.0", "schemars 0.9.0", - "schemars 1.1.0", + "schemars 1.2.1", "serde_core", "serde_json", "serde_with_macros", @@ -7250,11 +8331,11 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.16.1" +version = "3.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52a8e3ca0ca629121f70ab50f95249e5a6f925cc0f6ffe8256c45b728875706c" +checksum = "b90c488738ecb4fb0262f41f43bc40efc5868d9fb744319ddf5f5317f417bfac" dependencies = [ - "darling", + "darling 0.23.0", "proc-macro2", "quote", "syn 2.0.117", @@ -7262,12 +8343,13 @@ dependencies = [ [[package]] name = "serial_test" -version = "3.2.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b258109f244e1d6891bf1053a55d63a5cd4f8f4c30cf9a1280989f80e7a1fa9" +checksum = "911bd979bf1070a3f3aa7b691a3b3e9968f339ceeec89e08c280a8a22207a32f" dependencies = [ "fslock", - "futures", + "futures-executor", + "futures-util", "log", "once_cell", "parking_lot", @@ -7277,9 +8359,9 @@ dependencies = [ [[package]] name = "serial_test_derive" -version = "3.2.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d69265a08751de7844521fd15003ae0a888e035773ba05695c5c759a6f89eef" +checksum = "0a7d91949b85b0d2fb687445e448b40d322b6b3e4af6b44a29b21d9a5f33e6d9" dependencies = [ "proc-macro2", "quote", @@ -7293,7 +8375,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "digest 0.10.7", ] @@ -7305,7 +8387,7 @@ checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" dependencies = [ "block-buffer 0.9.0", "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "digest 0.9.0", "opaque-debug", ] @@ -7317,7 +8399,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "digest 0.10.7", ] @@ -7329,9 +8411,9 @@ checksum = "5f179d4e11094a893b82fff208f74d448a7512f99f5a0acbd5c679b705f83ed9" [[package]] name = "sha3" -version = "0.10.8" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +checksum = "77fd7028345d415a4034cf8777cd4f8ab1851274233b45f84e3d955502d93874" dependencies = [ "digest 0.10.7", "keccak", @@ -7364,10 +8446,11 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.7" +version = "1.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7664a098b8e616bdfcc2dc0e9ac44eb231eedf41db4e9fe95d8d32ec728dedad" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" dependencies = [ + "errno", "libc", ] @@ -7401,9 +8484,19 @@ dependencies = [ [[package]] name = "simd-adler32" -version = "0.3.8" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" + +[[package]] +name = "simd_cesu8" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" +checksum = "94f90157bb87cddf702797c5dadfa0be7d266cdf49e22da2fcaa32eff75b2c33" +dependencies = [ + "rustc_version", + "simdutf8", +] [[package]] name = "simdutf8" @@ -7419,9 +8512,9 @@ checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" [[package]] name = "siphasher" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" +checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" [[package]] name = "sized-chunks" @@ -7435,9 +8528,9 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "smallvec" @@ -7457,12 +8550,30 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.1" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", +] + +[[package]] +name = "solana-account" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f949fe4edaeaea78c844023bfc1c898e0b1f5a100f8a8d2d0f85d0a7b090258" +dependencies = [ + "bincode", + "serde", + "serde_bytes", + "serde_derive", + "solana-account-info 2.3.0", + "solana-clock 2.2.3", + "solana-instruction 2.3.3", + "solana-pubkey 2.4.0", + "solana-sdk-ids 2.2.1", + "solana-sysvar 2.3.0", ] [[package]] @@ -7474,12 +8585,12 @@ dependencies = [ "qualifier_attr", "serde", "serde_bytes", - "solana-account-info", - "solana-clock", - "solana-instruction", + "solana-account-info 3.1.1", + "solana-clock 3.1.0", + "solana-instruction 3.4.0", "solana-pubkey 3.0.0", - "solana-sdk-ids", - "solana-sysvar", + "solana-sdk-ids 3.1.0", + "solana-sysvar 3.1.1", ] [[package]] @@ -7495,35 +8606,51 @@ dependencies = [ "bv", "serde", "serde_json", - "solana-account", - "solana-account-decoder-client-types", - "solana-address-lookup-table-interface", - "solana-clock", + "solana-account 3.4.0", + "solana-account-decoder-client-types 3.1.12", + "solana-address-lookup-table-interface 3.1.0", + "solana-clock 3.1.0", "solana-config-interface", - "solana-epoch-schedule", - "solana-fee-calculator", - "solana-instruction", - "solana-loader-v3-interface", - "solana-nonce", - "solana-program-option", - "solana-program-pack", + "solana-epoch-schedule 3.1.0", + "solana-fee-calculator 3.2.0", + "solana-instruction 3.4.0", + "solana-loader-v3-interface 6.1.1", + "solana-nonce 3.2.0", + "solana-program-option 3.1.0", + "solana-program-pack 3.1.0", "solana-pubkey 3.0.0", "solana-rent 3.1.0", - "solana-sdk-ids", - "solana-slot-hashes", - "solana-slot-history", - "solana-stake-interface", - "solana-sysvar", - "solana-vote-interface", - "spl-generic-token", - "spl-token-2022-interface", - "spl-token-group-interface", + "solana-sdk-ids 3.1.0", + "solana-slot-hashes 3.0.2", + "solana-slot-history 3.0.1", + "solana-stake-interface 2.0.2", + "solana-sysvar 3.1.1", + "solana-vote-interface 4.0.4", + "spl-generic-token 2.0.1", + "spl-token-2022-interface 2.1.0", + "spl-token-group-interface 0.7.2", "spl-token-interface", - "spl-token-metadata-interface", + "spl-token-metadata-interface 0.8.0", "thiserror 2.0.18", "zstd", ] +[[package]] +name = "solana-account-decoder-client-types" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5519e8343325b707f17fbed54fcefb325131b692506d0af9e08a539d15e4f8cf" +dependencies = [ + "base64 0.22.1", + "bs58", + "serde", + "serde_derive", + "serde_json", + "solana-account 2.2.1", + "solana-pubkey 2.4.0", + "zstd", +] + [[package]] name = "solana-account-decoder-client-types" version = "3.1.12" @@ -7534,11 +8661,24 @@ dependencies = [ "bs58", "serde", "serde_json", - "solana-account", + "solana-account 3.4.0", "solana-pubkey 3.0.0", "zstd", ] +[[package]] +name = "solana-account-info" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8f5152a288ef1912300fc6efa6c2d1f9bb55d9398eb6c72326360b8063987da" +dependencies = [ + "bincode", + "serde", + "solana-program-error 2.2.2", + "solana-program-memory 2.3.1", + "solana-pubkey 2.4.0", +] + [[package]] name = "solana-account-info" version = "3.1.1" @@ -7548,8 +8688,8 @@ dependencies = [ "bincode", "serde_core", "solana-address 2.6.0", - "solana-program-error", - "solana-program-memory", + "solana-program-error 3.0.1", + "solana-program-memory 3.1.0", ] [[package]] @@ -7559,7 +8699,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f37ca34c37f92ee341b73d5ce7c8ef5bb38e9a87955b4bd343c63fa18b149215" dependencies = [ "solana-address 2.6.0", - "solana-program-error", + "solana-program-error 3.0.1", ] [[package]] @@ -7577,45 +8717,45 @@ dependencies = [ "bytemuck_derive", "crossbeam-channel", "dashmap", - "indexmap 2.12.1", + "indexmap 2.14.0", "itertools 0.12.1", "log", "lz4", - "memmap2 0.9.9", + "memmap2 0.9.10", "modular-bitfield", "num_cpus", "num_enum", - "rand 0.8.5", + "rand 0.8.6", "rayon", "seqlock", "serde", "smallvec", - "solana-account", - "solana-address-lookup-table-interface", + "solana-account 3.4.0", + "solana-address-lookup-table-interface 3.1.0", "solana-bucket-map", - "solana-clock", - "solana-epoch-schedule", - "solana-fee-calculator", + "solana-clock 3.1.0", + "solana-epoch-schedule 3.1.0", + "solana-fee-calculator 3.2.0", "solana-genesis-config", "solana-hash 3.1.0", "solana-lattice-hash", "solana-measure", - "solana-message", + "solana-message 3.1.0", "solana-metrics 3.1.12", "solana-nohash-hasher", "solana-pubkey 3.0.0", "solana-rayon-threadlimit", - "solana-reward-info", + "solana-reward-info 3.0.0", "solana-sha256-hasher 3.1.0", - "solana-slot-hashes", + "solana-slot-hashes 3.0.2", "solana-svm-transaction", "solana-system-interface 2.0.0", - "solana-sysvar", + "solana-sysvar 3.1.1", "solana-time-utils 3.0.0", - "solana-transaction", - "solana-transaction-context", - "solana-transaction-error", - "spl-generic-token", + "solana-transaction 3.1.0", + "solana-transaction-context 3.1.12", + "solana-transaction-error 3.2.0", + "spl-generic-token 2.0.1", "static_assertions", "tempfile", "thiserror 2.0.18", @@ -7636,23 +8776,40 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1384b52c435a750cc9c538760fc7bb472fd78e65a9900a2d07312c5bb335b72" dependencies = [ - "borsh", + "borsh 1.6.1", "bytemuck", "bytemuck_derive", "curve25519-dalek 4.1.3", "five8 1.0.0", "five8_const 1.0.0", - "rand 0.9.2", + "rand 0.9.4", "serde", "serde_derive", "sha2-const-stable", "solana-atomic-u64 3.0.1", - "solana-define-syscall 5.0.0", + "solana-define-syscall 5.1.0", "solana-nullable", - "solana-program-error", + "solana-program-error 3.0.1", "solana-sanitize 3.0.1", "solana-sha256-hasher 3.1.0", - "wincode 0.5.1", + "wincode", +] + +[[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 2.2.3", + "solana-instruction 2.3.3", + "solana-pubkey 2.4.0", + "solana-sdk-ids 2.2.1", + "solana-slot-hashes 2.2.1", ] [[package]] @@ -7665,12 +8822,12 @@ dependencies = [ "bytemuck", "serde", "serde_derive", - "solana-clock", - "solana-instruction", + "solana-clock 3.1.0", + "solana-instruction 3.4.0", "solana-instruction-error", "solana-pubkey 4.2.0", - "solana-sdk-ids", - "solana-slot-hashes", + "solana-sdk-ids 3.1.0", + "solana-slot-hashes 3.0.2", ] [[package]] @@ -7697,22 +8854,22 @@ version = "3.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16034da9477c2ceb6bf03a04389d68f463fb9e09a7641b4517af4177976c5f59" dependencies = [ - "borsh", + "borsh 1.6.1", "futures", - "solana-account", + "solana-account 3.4.0", "solana-banks-interface", - "solana-clock", - "solana-commitment-config", + "solana-clock 3.1.0", + "solana-commitment-config 3.1.1", "solana-hash 3.1.0", - "solana-message", - "solana-program-pack", + "solana-message 3.1.0", + "solana-program-pack 3.1.0", "solana-pubkey 3.0.0", "solana-rent 3.1.0", - "solana-signature", - "solana-sysvar", - "solana-transaction", - "solana-transaction-context", - "solana-transaction-error", + "solana-signature 3.4.0", + "solana-sysvar 3.1.1", + "solana-transaction 3.1.0", + "solana-transaction-context 3.1.12", + "solana-transaction-error 3.2.0", "tarpc", "thiserror 2.0.18", "tokio", @@ -7726,16 +8883,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aeed8b00c1b30e10cada0de485c4c7aa2805bc54587d7fbfd4c89b9a6a2b7bb5" dependencies = [ "serde", - "solana-account", - "solana-clock", - "solana-commitment-config", + "solana-account 3.4.0", + "solana-clock 3.1.0", + "solana-commitment-config 3.1.1", "solana-hash 3.1.0", - "solana-message", + "solana-message 3.1.0", "solana-pubkey 3.0.0", - "solana-signature", - "solana-transaction", - "solana-transaction-context", - "solana-transaction-error", + "solana-signature 3.4.0", + "solana-transaction 3.1.0", + "solana-transaction-context 3.1.12", + "solana-transaction-error 3.2.0", "tarpc", ] @@ -7745,30 +8902,41 @@ version = "3.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d24b007191bac5046513d8b642ff554a9413a270fbf78ab416e5ecc1b9eea11" dependencies = [ - "agave-feature-set", + "agave-feature-set 3.1.12", "bincode", "crossbeam-channel", "futures", - "solana-account", + "solana-account 3.4.0", "solana-banks-interface", "solana-client", - "solana-clock", - "solana-commitment-config", + "solana-clock 3.1.0", + "solana-commitment-config 3.1.1", "solana-hash 3.1.0", - "solana-message", + "solana-message 3.1.0", "solana-pubkey 3.0.0", "solana-runtime", "solana-runtime-transaction", "solana-send-transaction-service", - "solana-signature", + "solana-signature 3.4.0", "solana-svm", - "solana-transaction", - "solana-transaction-error", + "solana-transaction 3.1.0", + "solana-transaction-error 3.2.0", "tarpc", "tokio", "tokio-serde", ] +[[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 0.4.6", + "num-traits", + "solana-define-syscall 2.3.0", +] + [[package]] name = "solana-big-mod-exp" version = "3.0.0" @@ -7780,6 +8948,17 @@ dependencies = [ "solana-define-syscall 3.0.0", ] +[[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 2.3.3", +] + [[package]] name = "solana-bincode" version = "3.1.0" @@ -7791,6 +8970,18 @@ dependencies = [ "solana-instruction-error", ] +[[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 2.3.0", + "solana-hash 2.3.0", + "solana-sanitize 2.2.1", +] + [[package]] name = "solana-blake3-hasher" version = "3.1.0" @@ -7799,7 +8990,7 @@ checksum = "7116e1d942a2432ca3f514625104757ab8a56233787e95144c93950029e31176" dependencies = [ "blake3", "solana-define-syscall 4.0.1", - "solana-hash 4.2.0", + "solana-hash 4.3.0", ] [[package]] @@ -7816,16 +9007,31 @@ dependencies = [ "ff", "group", "pairing", - "rand 0.8.5", + "rand 0.8.6", "serde", "serde_json", "serde_with", - "solana-signature", - "solana-signer", + "solana-signature 3.4.0", + "solana-signer 3.0.0", "subtle", "thiserror 2.0.18", ] +[[package]] +name = "solana-bn254" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4420f125118732833f36facf96a27e7b78314b2d642ba07fa9ffdacd8d79e243" +dependencies = [ + "ark-bn254 0.4.0", + "ark-ec 0.4.2", + "ark-ff 0.4.2", + "ark-serialize 0.4.2", + "bytemuck", + "solana-define-syscall 2.3.0", + "thiserror 2.0.18", +] + [[package]] name = "solana-bn254" version = "3.2.1" @@ -7837,17 +9043,27 @@ dependencies = [ "ark-ff 0.5.0", "ark-serialize 0.5.0", "bytemuck", - "solana-define-syscall 5.0.0", + "solana-define-syscall 5.1.0", "thiserror 2.0.18", ] +[[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.6.1", +] + [[package]] name = "solana-borsh" version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c04abbae16f57178a163125805637b8a076175bb5c0002fb04f4792bea901cf7" dependencies = [ - "borsh", + "borsh 1.6.1", ] [[package]] @@ -7859,24 +9075,24 @@ dependencies = [ "agave-syscalls", "bincode", "qualifier_attr", - "solana-account", - "solana-bincode", - "solana-clock", - "solana-instruction", - "solana-loader-v3-interface", - "solana-loader-v4-interface", + "solana-account 3.4.0", + "solana-bincode 3.1.0", + "solana-clock 3.1.0", + "solana-instruction 3.4.0", + "solana-loader-v3-interface 6.1.1", + "solana-loader-v4-interface 3.1.0", "solana-packet", - "solana-program-entrypoint", + "solana-program-entrypoint 3.1.1", "solana-program-runtime", "solana-pubkey 3.0.0", "solana-sbpf", - "solana-sdk-ids", - "solana-svm-feature-set", + "solana-sdk-ids 3.1.0", + "solana-svm-feature-set 3.1.12", "solana-svm-log-collector", "solana-svm-measure", "solana-svm-type-overrides", "solana-system-interface 2.0.0", - "solana-transaction-context", + "solana-transaction-context 3.1.12", ] [[package]] @@ -7888,11 +9104,11 @@ dependencies = [ "bv", "bytemuck", "bytemuck_derive", - "memmap2 0.9.9", + "memmap2 0.9.10", "modular-bitfield", "num_enum", - "rand 0.8.5", - "solana-clock", + "rand 0.8.6", + "solana-clock 3.1.0", "solana-measure", "solana-pubkey 3.0.0", "tempfile", @@ -7904,14 +9120,14 @@ version = "3.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eaf44075aa3dbe16ce0112314d0dfd2435a18ddfd96f53e5269879f4006eb60d" dependencies = [ - "agave-feature-set", + "agave-feature-set 3.1.12", "solana-bpf-loader-program", "solana-compute-budget-program", "solana-hash 3.1.0", "solana-loader-v4-program", "solana-program-runtime", "solana-pubkey 3.0.0", - "solana-sdk-ids", + "solana-sdk-ids 3.1.0", "solana-system-program", "solana-vote-program", "solana-zk-elgamal-proof-program", @@ -7924,14 +9140,14 @@ version = "3.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c6cd4d41f391f427e64e03fb00fb0c93443f18464dafd71e06f996ac03a3982" dependencies = [ - "agave-feature-set", + "agave-feature-set 3.1.12", "ahash 0.8.12", "log", "solana-bpf-loader-program", "solana-compute-budget-program", "solana-loader-v4-program", "solana-pubkey 3.0.0", - "solana-sdk-ids", + "solana-sdk-ids 3.1.0", "solana-system-program", "solana-vote-program", ] @@ -7948,40 +9164,40 @@ dependencies = [ "dashmap", "futures", "futures-util", - "indexmap 2.12.1", - "indicatif", + "indexmap 2.14.0", + "indicatif 0.18.4", "log", "rayon", - "solana-account", + "solana-account 3.4.0", "solana-client-traits", - "solana-commitment-config", + "solana-commitment-config 3.1.1", "solana-connection-cache", - "solana-epoch-info", + "solana-epoch-info 3.1.0", "solana-hash 3.1.0", - "solana-instruction", - "solana-keypair", + "solana-instruction 3.4.0", + "solana-keypair 3.1.0", "solana-measure", - "solana-message", + "solana-message 3.1.0", "solana-net-utils", "solana-pubkey 3.0.0", "solana-pubsub-client", "solana-quic-client", "solana-quic-definitions", - "solana-rpc-client", - "solana-rpc-client-api", + "solana-rpc-client 3.1.12", + "solana-rpc-client-api 3.1.12", "solana-rpc-client-nonce-utils", - "solana-signature", - "solana-signer", + "solana-signature 3.4.0", + "solana-signer 3.0.0", "solana-streamer", "solana-time-utils 3.0.0", "solana-tpu-client", - "solana-transaction", - "solana-transaction-error", - "solana-transaction-status-client-types", + "solana-transaction 3.1.0", + "solana-transaction-error 3.2.0", + "solana-transaction-status-client-types 3.1.12", "solana-udp-client", "thiserror 2.0.18", "tokio", - "tokio-util 0.7.17", + "tokio-util 0.7.18", ] [[package]] @@ -7990,32 +9206,45 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08618ed587e128105510c54ae3e456b9a06d674d8640db75afe66dad65cb4e02" dependencies = [ - "solana-account", - "solana-commitment-config", - "solana-epoch-info", + "solana-account 3.4.0", + "solana-commitment-config 3.1.1", + "solana-epoch-info 3.1.0", "solana-hash 3.1.0", - "solana-instruction", - "solana-keypair", - "solana-message", + "solana-instruction 3.4.0", + "solana-keypair 3.1.0", + "solana-message 3.1.0", "solana-pubkey 3.0.0", - "solana-signature", - "solana-signer", + "solana-signature 3.4.0", + "solana-signer 3.0.0", "solana-system-interface 2.0.0", - "solana-transaction", - "solana-transaction-error", + "solana-transaction 3.1.0", + "solana-transaction-error 3.2.0", ] [[package]] name = "solana-clock" -version = "3.0.1" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8584296123df8fe229b95e2ebfd37ae637fe9db9b7d4dd677ac5a78e80dbfce" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids 2.2.1", + "solana-sdk-macro 2.2.1", + "solana-sysvar-id 2.2.1", +] + +[[package]] +name = "solana-clock" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95cf11109c3b6115cc510f1e31f06fdd52f504271bc24ef5f1249fbbcae5f9f3" +checksum = "5ea35d8f69b67daddb921a9da7f78ca591b533cf5e98833cd9ae62fdc2e4652c" dependencies = [ "serde", "serde_derive", - "solana-sdk-ids", - "solana-sdk-macro", - "solana-sysvar-id", + "solana-sdk-ids 3.1.0", + "solana-sdk-macro 3.0.1", + "solana-sysvar-id 3.1.0", ] [[package]] @@ -8035,7 +9264,17 @@ checksum = "3a494cf8eda7d98d9f0144b288bb409c88308d2e86f15cc1045aa77b83304718" dependencies = [ "serde", "serde_derive", - "solana-hash 4.2.0", + "solana-hash 4.3.0", +] + +[[package]] +name = "solana-commitment-config" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac49c4dde3edfa832de1697e9bcdb7c3b3f7cb7a1981b7c62526c8bb6700fb73" +dependencies = [ + "serde", + "serde_derive", ] [[package]] @@ -8064,30 +9303,40 @@ version = "3.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6bf47dcc57b770cee0432899ac89cd7e85896f9e28e3d5e5542a0b8a8f5839f" dependencies = [ - "agave-feature-set", + "agave-feature-set 3.1.12", "log", - "solana-borsh", + "solana-borsh 3.0.2", "solana-builtins-default-costs", "solana-compute-budget", - "solana-compute-budget-interface", - "solana-instruction", + "solana-compute-budget-interface 3.0.0", + "solana-instruction 3.4.0", "solana-packet", "solana-pubkey 3.0.0", - "solana-sdk-ids", + "solana-sdk-ids 3.1.0", "solana-svm-transaction", - "solana-transaction-error", + "solana-transaction-error 3.2.0", "thiserror 2.0.18", ] +[[package]] +name = "solana-compute-budget-interface" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8432d2c4c22d0499aa06d62e4f7e333f81777b3d7c96050ae9e5cb71a8c3aee4" +dependencies = [ + "solana-instruction 2.3.3", + "solana-sdk-ids 2.2.1", +] + [[package]] name = "solana-compute-budget-interface" version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8292c436b269ad23cecc8b24f7da3ab07ca111661e25e00ce0e1d22771951ab9" dependencies = [ - "borsh", - "solana-instruction", - "solana-sdk-ids", + "borsh 1.6.1", + "solana-instruction 3.4.0", + "solana-sdk-ids 3.1.0", ] [[package]] @@ -8108,11 +9357,11 @@ dependencies = [ "bincode", "serde", "serde_derive", - "solana-account", - "solana-instruction", + "solana-account 3.4.0", + "solana-instruction 3.4.0", "solana-pubkey 3.0.0", - "solana-sdk-ids", - "solana-short-vec", + "solana-sdk-ids 3.1.0", + "solana-short-vec 3.2.1", "solana-system-interface 2.0.0", ] @@ -8126,15 +9375,15 @@ dependencies = [ "bincode", "crossbeam-channel", "futures-util", - "indexmap 2.12.1", + "indexmap 2.14.0", "log", - "rand 0.8.5", + "rand 0.8.6", "rayon", - "solana-keypair", + "solana-keypair 3.1.0", "solana-measure", "solana-metrics 3.1.12", "solana-time-utils 3.0.0", - "solana-transaction-error", + "solana-transaction-error 3.2.0", "thiserror 2.0.18", "tokio", ] @@ -8145,40 +9394,68 @@ version = "3.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "daa79df27ff7b933c4cb7612340d9af3b4f49b0219bec81ad6826e9352ad054f" dependencies = [ - "agave-feature-set", + "agave-feature-set 3.1.12", "ahash 0.8.12", "log", - "solana-bincode", - "solana-borsh", + "solana-bincode 3.1.0", + "solana-borsh 3.0.2", "solana-builtins-default-costs", - "solana-clock", + "solana-clock 3.1.0", "solana-compute-budget", "solana-compute-budget-instruction", - "solana-compute-budget-interface", + "solana-compute-budget-interface 3.0.0", "solana-fee-structure", "solana-metrics 3.1.12", "solana-packet", "solana-pubkey 3.0.0", "solana-runtime-transaction", - "solana-sdk-ids", + "solana-sdk-ids 3.1.0", "solana-svm-transaction", "solana-system-interface 2.0.0", - "solana-transaction-error", + "solana-transaction-error 3.2.0", "solana-vote-program", ] +[[package]] +name = "solana-cpi" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dc71126edddc2ba014622fc32d0f5e2e78ec6c5a1e0eb511b85618c09e9ea11" +dependencies = [ + "solana-account-info 2.3.0", + "solana-define-syscall 2.3.0", + "solana-instruction 2.3.3", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "solana-stable-layout 2.2.1", +] + [[package]] name = "solana-cpi" version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dea26709d867aada85d0d3617db0944215c8bb28d3745b912de7db13a23280c" dependencies = [ - "solana-account-info", + "solana-account-info 3.1.1", "solana-define-syscall 4.0.1", - "solana-instruction", - "solana-program-error", + "solana-instruction 3.4.0", + "solana-program-error 3.0.1", "solana-pubkey 4.2.0", - "solana-stable-layout", + "solana-stable-layout 3.0.1", +] + +[[package]] +name = "solana-curve25519" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae4261b9a8613d10e77ac831a8fa60b6fa52b9b103df46d641deff9f9812a23" +dependencies = [ + "bytemuck", + "bytemuck_derive", + "curve25519-dalek 4.1.3", + "solana-define-syscall 2.3.0", + "subtle", + "thiserror 2.0.18", ] [[package]] @@ -8195,6 +9472,15 @@ dependencies = [ "thiserror 2.0.18", ] +[[package]] +name = "solana-decode-error" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c781686a18db2f942e70913f7ca15dc120ec38dcab42ff7557db2c70c625a35" +dependencies = [ + "num-traits", +] + [[package]] name = "solana-define-syscall" version = "2.3.0" @@ -8215,9 +9501,20 @@ checksum = "57e5b1c0bc1d4a4d10c88a4100499d954c09d3fecfae4912c1a074dff68b1738" [[package]] name = "solana-define-syscall" -version = "5.0.0" +version = "5.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03aacdd7a61e2109887a7a7f046caebafce97ddf1150f33722eeac04f9039c73" +checksum = "21e14a4f604117f379840956a8fc8695e4c84f5b0ebed192f31f60d9b85d581d" + +[[package]] +name = "solana-derivation-path" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "939756d798b25c5ec3cca10e06212bdca3b1443cb9bb740a38124f58b258737b" +dependencies = [ + "derivation-path", + "qstring", + "uriparse", +] [[package]] name = "solana-derivation-path" @@ -8238,8 +9535,18 @@ checksum = "e1419197f1c06abf760043f6d64ba9d79a03ad5a43f18c7586471937122094da" dependencies = [ "bytemuck", "bytemuck_derive", - "solana-instruction", - "solana-sdk-ids", + "solana-instruction 3.4.0", + "solana-sdk-ids 3.1.0", +] + +[[package]] +name = "solana-epoch-info" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ef6f0b449290b0b9f32973eefd95af35b01c5c0c34c569f936c34c5b20d77b" +dependencies = [ + "serde", + "serde_derive", ] [[package]] @@ -8254,16 +9561,30 @@ dependencies = [ [[package]] name = "solana-epoch-rewards" -version = "3.0.1" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b575d3dd323b9ea10bb6fe89bf6bf93e249b215ba8ed7f68f1a3633f384db7" +dependencies = [ + "serde", + "serde_derive", + "solana-hash 2.3.0", + "solana-sdk-ids 2.2.1", + "solana-sdk-macro 2.2.1", + "solana-sysvar-id 2.2.1", +] + +[[package]] +name = "solana-epoch-rewards" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5e7b0ba210593ba8ddd39d6d234d81795d1671cebf3026baa10d5dc23ac42f0" +checksum = "1cddf2388b28291210d9aa60690740733cab527531f06ed153c4d388951e407c" dependencies = [ "serde", "serde_derive", - "solana-hash 4.2.0", - "solana-sdk-ids", - "solana-sdk-macro", - "solana-sysvar-id", + "solana-hash 4.3.0", + "solana-sdk-ids 3.1.0", + "solana-sdk-macro 3.0.1", + "solana-sysvar-id 3.1.0", ] [[package]] @@ -8274,7 +9595,20 @@ checksum = "1ee8beac9bff4db9225e57d532d169b0be5e447f1e6601a2f50f27a01bf5518f" dependencies = [ "siphasher 0.3.11", "solana-address 2.6.0", - "solana-hash 4.2.0", + "solana-hash 4.3.0", +] + +[[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 2.2.1", + "solana-sdk-macro 2.2.1", + "solana-sysvar-id 2.2.1", ] [[package]] @@ -8285,9 +9619,9 @@ checksum = "9ce264b7b42322325947c4136a09460bf5c73d9aa8262c9b0a2064be63ba8639" dependencies = [ "serde", "serde_derive", - "solana-sdk-ids", - "solana-sdk-macro", - "solana-sysvar-id", + "solana-sdk-ids 3.1.0", + "solana-sdk-macro 3.0.1", + "solana-sysvar-id 3.1.0", ] [[package]] @@ -8296,10 +9630,31 @@ version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "027e6d0b9e7daac5b2ac7c3f9ca1b727861121d9ef05084cf435ff736051e7c2" dependencies = [ - "solana-define-syscall 5.0.0", + "solana-define-syscall 5.1.0", "solana-pubkey 4.2.0", ] +[[package]] +name = "solana-example-mocks" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84461d56cbb8bb8d539347151e0525b53910102e4bced875d49d5139708e39d3" +dependencies = [ + "serde", + "serde_derive", + "solana-address-lookup-table-interface 2.2.2", + "solana-clock 2.2.3", + "solana-hash 2.3.0", + "solana-instruction 2.3.3", + "solana-keccak-hasher 2.2.1", + "solana-message 2.4.0", + "solana-nonce 2.2.1", + "solana-pubkey 2.4.0", + "solana-sdk-ids 2.2.1", + "solana-system-interface 1.0.0", + "thiserror 2.0.18", +] + [[package]] name = "solana-example-mocks" version = "3.0.0" @@ -8308,19 +9663,38 @@ checksum = "978855d164845c1b0235d4b4d101cadc55373fffaf0b5b6cfa2194d25b2ed658" dependencies = [ "serde", "serde_derive", - "solana-address-lookup-table-interface", - "solana-clock", + "solana-address-lookup-table-interface 3.1.0", + "solana-clock 3.1.0", "solana-hash 3.1.0", - "solana-instruction", - "solana-keccak-hasher", - "solana-message", - "solana-nonce", + "solana-instruction 3.4.0", + "solana-keccak-hasher 3.1.0", + "solana-message 3.1.0", + "solana-nonce 3.2.0", "solana-pubkey 3.0.0", - "solana-sdk-ids", + "solana-sdk-ids 3.1.0", "solana-system-interface 2.0.0", "thiserror 2.0.18", ] +[[package]] +name = "solana-feature-gate-interface" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43f5c5382b449e8e4e3016fb05e418c53d57782d8b5c30aa372fc265654b956d" +dependencies = [ + "bincode", + "serde", + "serde_derive", + "solana-account 2.2.1", + "solana-account-info 2.3.0", + "solana-instruction 2.3.3", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "solana-rent 2.2.1", + "solana-sdk-ids 2.2.1", + "solana-system-interface 1.0.0", +] + [[package]] name = "solana-feature-gate-interface" version = "3.1.0" @@ -8330,13 +9704,13 @@ dependencies = [ "bincode", "serde", "serde_derive", - "solana-account", - "solana-account-info", - "solana-instruction", - "solana-program-error", + "solana-account 3.4.0", + "solana-account-info 3.1.1", + "solana-instruction 3.4.0", + "solana-program-error 3.0.1", "solana-pubkey 4.2.0", "solana-rent 4.2.0", - "solana-sdk-ids", + "solana-sdk-ids 3.1.0", "solana-system-interface 3.2.0", ] @@ -8346,11 +9720,22 @@ version = "3.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0c7ab7f31d404a130c78c29a7a845cd599b2623fa335e5fcaef2bd7b3be83e6" dependencies = [ - "agave-feature-set", + "agave-feature-set 3.1.12", "solana-fee-structure", "solana-svm-transaction", ] +[[package]] +name = "solana-fee-calculator" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89bc408da0fb3812bc3008189d148b4d3e08252c79ad810b245482a3f70cd8d" +dependencies = [ + "log", + "serde", + "serde_derive", +] + [[package]] name = "solana-fee-calculator" version = "3.2.0" @@ -8374,9 +9759,9 @@ dependencies = [ [[package]] name = "solana-frozen-abi-macro" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b04663357817fddb4755c6359005038c12e110ab04d1ac5048482551f95b160" +checksum = "4efd54c3f198403955addf2160af0ccc30294a04cf34e155c775d69960e1f0f6" dependencies = [ "proc-macro2", "quote", @@ -8394,21 +9779,21 @@ dependencies = [ "memmap2 0.5.10", "serde", "serde_derive", - "solana-account", - "solana-clock", + "solana-account 3.4.0", + "solana-clock 3.1.0", "solana-cluster-type 3.1.0", - "solana-epoch-schedule", - "solana-fee-calculator", + "solana-epoch-schedule 3.1.0", + "solana-fee-calculator 3.2.0", "solana-hash 3.1.0", - "solana-inflation", - "solana-keypair", + "solana-inflation 3.1.0", + "solana-keypair 3.1.0", "solana-poh-config", "solana-pubkey 3.0.0", "solana-rent 3.1.0", - "solana-sdk-ids", + "solana-sdk-ids 3.1.0", "solana-sha256-hasher 3.1.0", "solana-shred-version", - "solana-signer", + "solana-signer 3.0.0", "solana-time-utils 3.0.0", ] @@ -8428,8 +9813,13 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5b96e9f0300fa287b545613f007dfe20043d7812bee255f418c1eb649c93b63" dependencies = [ + "borsh 1.6.1", + "bytemuck", + "bytemuck_derive", "five8 0.2.1", "js-sys", + "serde", + "serde_derive", "solana-atomic-u64 2.2.1", "solana-sanitize 2.2.1", "wasm-bindgen", @@ -8441,16 +9831,16 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "337c246447142f660f778cf6cb582beba8e28deb05b3b24bfb9ffd7c562e5f41" dependencies = [ - "solana-hash 4.2.0", + "solana-hash 4.3.0", ] [[package]] name = "solana-hash" -version = "4.2.0" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8064ea1d591ec791be95245058ca40f4f5345d390c200069d0f79bbf55bfae55" +checksum = "f1b113239362cee7093bfb250467138f079a2a03673181dc15bff6ccd677912d" dependencies = [ - "borsh", + "borsh 1.6.1", "bytemuck", "bytemuck_derive", "five8 1.0.0", @@ -8458,9 +9848,15 @@ dependencies = [ "serde_derive", "solana-atomic-u64 3.0.1", "solana-sanitize 3.0.1", - "wincode 0.4.4", + "wincode", ] +[[package]] +name = "solana-inflation" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23eef6a09eb8e568ce6839573e4966850e85e9ce71e6ae1a6c930c1c43947de3" + [[package]] name = "solana-inflation" version = "3.1.0" @@ -8471,6 +9867,25 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "solana-instruction" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab5682934bd1f65f8d2c16f21cb532526fcc1a09f796e2cacdb091eee5774ad" +dependencies = [ + "bincode", + "borsh 1.6.1", + "getrandom 0.2.17", + "js-sys", + "num-traits", + "serde", + "serde_derive", + "serde_json", + "solana-define-syscall 2.3.0", + "solana-pubkey 2.4.0", + "wasm-bindgen", +] + [[package]] name = "solana-instruction" version = "3.4.0" @@ -8478,10 +9893,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37ebb0ffd19263051bc3f683fcc086134b8ff23af894dcb63f7563c7137b42f1" dependencies = [ "bincode", - "borsh", + "borsh 1.6.1", "serde", "serde_derive", - "solana-define-syscall 5.0.0", + "solana-define-syscall 5.1.0", "solana-instruction-error", "solana-pubkey 4.2.0", ] @@ -8495,7 +9910,7 @@ dependencies = [ "num-traits", "serde", "serde_derive", - "solana-program-error", + "solana-program-error 3.0.1", ] [[package]] @@ -8507,25 +9922,53 @@ dependencies = [ "solana-account-view", "solana-address 2.6.0", "solana-define-syscall 4.0.1", - "solana-program-error", + "solana-program-error 3.0.1", ] [[package]] name = "solana-instructions-sysvar" -version = "3.0.0" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0e85a6fad5c2d0c4f5b91d34b8ca47118fc593af706e523cdbedf846a954f57" +dependencies = [ + "bitflags 2.11.1", + "solana-account-info 2.3.0", + "solana-instruction 2.3.3", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "solana-sanitize 2.2.1", + "solana-sdk-ids 2.2.1", + "solana-serialize-utils 2.2.1", + "solana-sysvar-id 2.2.1", +] + +[[package]] +name = "solana-instructions-sysvar" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ddf67876c541aa1e21ee1acae35c95c6fbc61119814bfef70579317a5e26955" +checksum = "9e0732294560e88ecdb2bbc656e67383e9f88c78ec09469cef172f0d28cd1bcd" dependencies = [ - "bitflags 2.10.0", - "solana-account-info", - "solana-instruction", + "bitflags 2.11.1", + "solana-account-info 3.1.1", + "solana-instruction 3.4.0", "solana-instruction-error", - "solana-program-error", - "solana-pubkey 3.0.0", + "solana-program-error 3.0.1", "solana-sanitize 3.0.1", - "solana-sdk-ids", - "solana-serialize-utils", - "solana-sysvar-id", + "solana-sdk-ids 3.1.0", + "solana-serialize-utils 3.1.2", + "solana-sysvar-id 3.1.0", +] + +[[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 2.3.0", + "solana-hash 2.3.0", + "solana-sanitize 2.2.1", ] [[package]] @@ -8536,7 +9979,23 @@ checksum = "ed1c0d16d6fdeba12291a1f068cdf0d479d9bff1141bf44afd7aa9d485f65ef8" dependencies = [ "sha3", "solana-define-syscall 4.0.1", - "solana-hash 4.2.0", + "solana-hash 4.3.0", +] + +[[package]] +name = "solana-keypair" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd3f04aa1a05c535e93e121a95f66e7dcccf57e007282e8255535d24bf1e98bb" +dependencies = [ + "ed25519-dalek 1.0.1", + "five8 0.2.1", + "rand 0.7.3", + "solana-pubkey 2.4.0", + "solana-seed-phrase 2.2.1", + "solana-signature 2.3.0", + "solana-signer 2.2.1", + "wasm-bindgen", ] [[package]] @@ -8548,26 +10007,39 @@ dependencies = [ "ed25519-dalek 2.2.0", "ed25519-dalek-bip32", "five8 1.0.0", - "rand 0.8.5", + "rand 0.8.6", "solana-address 2.6.0", - "solana-derivation-path", - "solana-seed-derivable", - "solana-seed-phrase", - "solana-signature", - "solana-signer", + "solana-derivation-path 3.0.0", + "solana-seed-derivable 3.0.0", + "solana-seed-phrase 3.0.0", + "solana-signature 3.4.0", + "solana-signer 3.0.0", ] [[package]] name = "solana-last-restart-slot" -version = "3.0.0" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a6360ac2fdc72e7463565cd256eedcf10d7ef0c28a1249d261ec168c1b55cdd" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids 2.2.1", + "solana-sdk-macro 2.2.1", + "solana-sysvar-id 2.2.1", +] + +[[package]] +name = "solana-last-restart-slot" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcda154ec827f5fc1e4da0af3417951b7e9b8157540f81f936c4a8b1156134d0" +checksum = "426711c6564b790026e45cabec3c64b971864c48b6b2d83c0ebf52a118bb4cda" dependencies = [ "serde", "serde_derive", - "solana-sdk-ids", - "solana-sdk-macro", - "solana-sysvar-id", + "solana-sdk-ids 3.1.0", + "solana-sdk-macro 3.0.1", + "solana-sysvar-id 3.1.0", ] [[package]] @@ -8582,6 +10054,20 @@ dependencies = [ "bytemuck", ] +[[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 2.3.3", + "solana-pubkey 2.4.0", + "solana-sdk-ids 2.2.1", +] + [[package]] name = "solana-loader-v2-interface" version = "3.0.0" @@ -8591,9 +10077,24 @@ dependencies = [ "serde", "serde_bytes", "serde_derive", - "solana-instruction", + "solana-instruction 3.4.0", "solana-pubkey 3.0.0", - "solana-sdk-ids", + "solana-sdk-ids 3.1.0", +] + +[[package]] +name = "solana-loader-v3-interface" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f7162a05b8b0773156b443bccd674ea78bb9aa406325b467ea78c06c99a63a2" +dependencies = [ + "serde", + "serde_bytes", + "serde_derive", + "solana-instruction 2.3.3", + "solana-pubkey 2.4.0", + "solana-sdk-ids 2.2.1", + "solana-system-interface 1.0.0", ] [[package]] @@ -8605,12 +10106,27 @@ dependencies = [ "serde", "serde_bytes", "serde_derive", - "solana-instruction", + "solana-instruction 3.4.0", "solana-pubkey 4.2.0", - "solana-sdk-ids", + "solana-sdk-ids 3.1.0", "solana-system-interface 3.2.0", ] +[[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 2.3.3", + "solana-pubkey 2.4.0", + "solana-sdk-ids 2.2.1", + "solana-system-interface 1.0.0", +] + [[package]] name = "solana-loader-v4-interface" version = "3.1.0" @@ -8620,9 +10136,9 @@ dependencies = [ "serde", "serde_bytes", "serde_derive", - "solana-instruction", + "solana-instruction 3.4.0", "solana-pubkey 3.0.0", - "solana-sdk-ids", + "solana-sdk-ids 3.1.0", "solana-system-interface 2.0.0", ] @@ -8633,21 +10149,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e88b98ba6b408fe6fcf180784fc378d07ae63100c7dd413ff97474b6de30c5d" dependencies = [ "log", - "solana-account", - "solana-bincode", + "solana-account 3.4.0", + "solana-bincode 3.1.0", "solana-bpf-loader-program", - "solana-instruction", - "solana-loader-v3-interface", - "solana-loader-v4-interface", + "solana-instruction 3.4.0", + "solana-loader-v3-interface 6.1.1", + "solana-loader-v4-interface 3.1.0", "solana-packet", "solana-program-runtime", "solana-pubkey 3.0.0", "solana-sbpf", - "solana-sdk-ids", + "solana-sdk-ids 3.1.0", "solana-svm-log-collector", "solana-svm-measure", "solana-svm-type-overrides", - "solana-transaction-context", + "solana-transaction-context 3.1.12", ] [[package]] @@ -8656,6 +10172,29 @@ version = "3.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de496c3f0e0cee33abd4ae958a8703e04ae1011f3c3e73b641bf319a18301c01" +[[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 2.2.1", + "solana-hash 2.3.0", + "solana-instruction 2.3.3", + "solana-pubkey 2.4.0", + "solana-sanitize 2.2.1", + "solana-sdk-ids 2.2.1", + "solana-short-vec 2.2.1", + "solana-system-interface 1.0.0", + "solana-transaction-error 2.2.1", + "wasm-bindgen", +] + [[package]] name = "solana-message" version = "3.1.0" @@ -8668,12 +10207,12 @@ dependencies = [ "serde", "serde_derive", "solana-address 2.6.0", - "solana-hash 4.2.0", - "solana-instruction", + "solana-hash 4.3.0", + "solana-instruction 3.4.0", "solana-sanitize 3.0.1", - "solana-sdk-ids", - "solana-short-vec", - "solana-transaction-error", + "solana-sdk-ids 3.1.0", + "solana-short-vec 3.2.1", + "solana-transaction-error 3.2.0", ] [[package]] @@ -8687,7 +10226,7 @@ dependencies = [ "log", "reqwest 0.12.28", "solana-cluster-type 2.2.1", - "solana-sha256-hasher 2.2.1", + "solana-sha256-hasher 2.3.0", "solana-time-utils 2.2.1", "thiserror 2.0.18", ] @@ -8708,15 +10247,30 @@ dependencies = [ "thiserror 2.0.18", ] +[[package]] +name = "solana-msg" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36a1a14399afaabc2781a1db09cb14ee4cc4ee5c7a5a3cfcc601811379a8092" +dependencies = [ + "solana-define-syscall 2.3.0", +] + [[package]] name = "solana-msg" version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "726b7cbbc6be6f1c6f29146ac824343b9415133eee8cce156452ad1db93f8008" dependencies = [ - "solana-define-syscall 5.0.0", + "solana-define-syscall 5.1.0", ] +[[package]] +name = "solana-native-token" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61515b880c36974053dd499c0510066783f0cc6ac17def0c7ef2a244874cf4a9" + [[package]] name = "solana-native-token" version = "3.0.0" @@ -8736,10 +10290,10 @@ dependencies = [ "dashmap", "itertools 0.12.1", "log", - "nix", - "rand 0.8.5", + "nix 0.30.1", + "rand 0.8.6", "serde", - "socket2 0.6.1", + "socket2 0.6.3", "solana-serde", "solana-svm-type-overrides", "tokio", @@ -8754,14 +10308,28 @@ checksum = "8b8a731ed60e89177c8a7ab05fe0f1511cedd3e70e773f288f9de33a9cfdc21e" [[package]] name = "solana-nonce" -version = "3.1.0" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703e22eb185537e06204a5bd9d509b948f0066f2d1d814a6f475dafb3ddf1325" +dependencies = [ + "serde", + "serde_derive", + "solana-fee-calculator 2.2.1", + "solana-hash 2.3.0", + "solana-pubkey 2.4.0", + "solana-sha256-hasher 2.3.0", +] + +[[package]] +name = "solana-nonce" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbc469152a63284ef959b80c59cda015262a021da55d3b8fe42171d89c4b64f8" +checksum = "d95dbc9f2e33b6c10e231df15cb2a3bff9ea7eab6347f9e316fe75c97fd67bbb" dependencies = [ "serde", "serde_derive", - "solana-fee-calculator", - "solana-hash 4.2.0", + "solana-fee-calculator 3.2.0", + "solana-hash 4.3.0", "solana-pubkey 4.2.0", "solana-sha256-hasher 3.1.0", ] @@ -8772,17 +10340,26 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "805fd25b29e5a1a0e6c3dd6320c9da80f275fbe4ff6e392617c303a2085c435e" dependencies = [ - "solana-account", + "solana-account 3.4.0", "solana-hash 3.1.0", - "solana-nonce", - "solana-sdk-ids", + "solana-nonce 3.2.0", + "solana-sdk-ids 3.1.0", +] + +[[package]] +name = "solana-nostd-keccak" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8ced70920435b1baa58f76e6f84bbc1110ddd1d6161ec76b6d731ae8431e9c4" +dependencies = [ + "sha3", ] [[package]] name = "solana-nullable" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da028344c595c7416769ff648d206de7962571291a4cea24c38a60b6f40d53bb" +checksum = "a0f95d3028ef0f682bb174b77379c19d5dae2904a649f4a103fe29be7a139980" dependencies = [ "bytemuck", ] @@ -8799,8 +10376,8 @@ dependencies = [ "solana-pubkey 3.0.0", "solana-sanitize 3.0.1", "solana-sha256-hasher 3.1.0", - "solana-signature", - "solana-signer", + "solana-signature 3.4.0", + "solana-signer 3.0.0", ] [[package]] @@ -8810,7 +10387,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6edf2f25743c95229ac0fdc32f8f5893ef738dbf332c669e9861d33ddb0f469d" dependencies = [ "bincode", - "bitflags 2.10.0", + "bitflags 2.11.1", "cfg_eval", "serde", "serde_derive", @@ -8833,21 +10410,21 @@ dependencies = [ "fnv", "libc", "log", - "nix", - "rand 0.8.5", + "nix 0.30.1", + "rand 0.8.6", "rayon", "serde", "solana-hash 3.1.0", - "solana-message", + "solana-message 3.1.0", "solana-metrics 3.1.12", "solana-packet", "solana-pubkey 3.0.0", "solana-rayon-threadlimit", - "solana-sdk-ids", - "solana-short-vec", - "solana-signature", + "solana-sdk-ids 3.1.0", + "solana-short-vec 3.2.1", + "solana-signature 3.4.0", "solana-time-utils 3.0.0", - "solana-transaction-context", + "solana-transaction-context 3.1.12", ] [[package]] @@ -8890,8 +10467,88 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f704eaf825be3180832445b9e4983b875340696e8e7239bf2d535b0f86c14a2" dependencies = [ "solana-pubkey 3.0.0", - "solana-signature", - "solana-signer", + "solana-signature 3.4.0", + "solana-signer 3.0.0", +] + +[[package]] +name = "solana-program" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98eca145bd3545e2fbb07166e895370576e47a00a7d824e325390d33bf467210" +dependencies = [ + "bincode", + "blake3", + "borsh 0.10.4", + "borsh 1.6.1", + "bs58", + "bytemuck", + "console_error_panic_hook", + "console_log", + "getrandom 0.2.17", + "lazy_static", + "log", + "memoffset", + "num-bigint 0.4.6", + "num-derive", + "num-traits", + "rand 0.8.6", + "serde", + "serde_bytes", + "serde_derive", + "solana-account-info 2.3.0", + "solana-address-lookup-table-interface 2.2.2", + "solana-atomic-u64 2.2.1", + "solana-big-mod-exp 2.2.1", + "solana-bincode 2.2.1", + "solana-blake3-hasher 2.2.1", + "solana-borsh 2.2.1", + "solana-clock 2.2.3", + "solana-cpi 2.2.1", + "solana-decode-error", + "solana-define-syscall 2.3.0", + "solana-epoch-rewards 2.2.1", + "solana-epoch-schedule 2.2.1", + "solana-example-mocks 2.2.1", + "solana-feature-gate-interface 2.2.2", + "solana-fee-calculator 2.2.1", + "solana-hash 2.3.0", + "solana-instruction 2.3.3", + "solana-instructions-sysvar 2.2.2", + "solana-keccak-hasher 2.2.1", + "solana-last-restart-slot 2.2.1", + "solana-loader-v2-interface 2.2.1", + "solana-loader-v3-interface 5.0.0", + "solana-loader-v4-interface 2.2.1", + "solana-message 2.4.0", + "solana-msg 2.2.1", + "solana-native-token 2.3.0", + "solana-nonce 2.2.1", + "solana-program-entrypoint 2.3.0", + "solana-program-error 2.2.2", + "solana-program-memory 2.3.1", + "solana-program-option 2.2.1", + "solana-program-pack 2.2.1", + "solana-pubkey 2.4.0", + "solana-rent 2.2.1", + "solana-sanitize 2.2.1", + "solana-sdk-ids 2.2.1", + "solana-sdk-macro 2.2.1", + "solana-secp256k1-recover 2.2.1", + "solana-serde-varint 2.2.2", + "solana-serialize-utils 2.2.1", + "solana-sha256-hasher 2.3.0", + "solana-short-vec 2.2.1", + "solana-slot-hashes 2.2.1", + "solana-slot-history 2.2.1", + "solana-stable-layout 2.2.1", + "solana-stake-interface 1.2.1", + "solana-system-interface 1.0.0", + "solana-sysvar 2.3.0", + "solana-sysvar-id 2.2.1", + "solana-vote-interface 2.2.6", + "thiserror 2.0.18", + "wasm-bindgen", ] [[package]] @@ -8901,44 +10558,44 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91b12305dd81045d705f427acd0435a2e46444b65367d7179d7bdcfc3bc5f5eb" dependencies = [ "memoffset", - "solana-account-info", - "solana-big-mod-exp", - "solana-blake3-hasher", - "solana-borsh", - "solana-clock", - "solana-cpi", + "solana-account-info 3.1.1", + "solana-big-mod-exp 3.0.0", + "solana-blake3-hasher 3.1.0", + "solana-borsh 3.0.2", + "solana-clock 3.1.0", + "solana-cpi 3.1.0", "solana-define-syscall 3.0.0", - "solana-epoch-rewards", - "solana-epoch-schedule", + "solana-epoch-rewards 3.0.2", + "solana-epoch-schedule 3.1.0", "solana-epoch-stake", - "solana-example-mocks", - "solana-fee-calculator", + "solana-example-mocks 3.0.0", + "solana-fee-calculator 3.2.0", "solana-hash 3.1.0", - "solana-instruction", + "solana-instruction 3.4.0", "solana-instruction-error", - "solana-instructions-sysvar", - "solana-keccak-hasher", - "solana-last-restart-slot", - "solana-msg", - "solana-native-token", - "solana-program-entrypoint", - "solana-program-error", - "solana-program-memory", - "solana-program-option", - "solana-program-pack", + "solana-instructions-sysvar 3.0.1", + "solana-keccak-hasher 3.1.0", + "solana-last-restart-slot 3.0.1", + "solana-msg 3.1.0", + "solana-native-token 3.0.0", + "solana-program-entrypoint 3.1.1", + "solana-program-error 3.0.1", + "solana-program-memory 3.1.0", + "solana-program-option 3.1.0", + "solana-program-pack 3.1.0", "solana-pubkey 3.0.0", "solana-rent 3.1.0", - "solana-sdk-ids", - "solana-secp256k1-recover", - "solana-serde-varint", - "solana-serialize-utils", + "solana-sdk-ids 3.1.0", + "solana-secp256k1-recover 3.1.1", + "solana-serde-varint 3.0.1", + "solana-serialize-utils 3.1.2", "solana-sha256-hasher 3.1.0", - "solana-short-vec", - "solana-slot-hashes", - "solana-slot-history", - "solana-stable-layout", - "solana-sysvar", - "solana-sysvar-id", + "solana-short-vec 3.2.1", + "solana-slot-hashes 3.0.2", + "solana-slot-history 3.0.1", + "solana-stable-layout 3.0.1", + "solana-sysvar 3.1.1", + "solana-sysvar-id 3.1.0", ] [[package]] @@ -8949,12 +10606,24 @@ checksum = "68d372660fc5c61b691279bcecb4bf92fa1a7cba3b357ef209404f425dafd394" dependencies = [ "bincode", "serde", - "solana-account", - "solana-loader-v3-interface", + "solana-account 3.4.0", + "solana-loader-v3-interface 6.1.1", "solana-pubkey 3.0.0", "solana-rent 3.1.0", - "solana-sdk-ids", - "spl-generic-token", + "solana-sdk-ids 3.1.0", + "spl-generic-token 2.0.1", +] + +[[package]] +name = "solana-program-entrypoint" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32ce041b1a0ed275290a5008ee1a4a6c48f5054c8a3d78d313c08958a06aedbd" +dependencies = [ + "solana-account-info 2.3.0", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", ] [[package]] @@ -8963,23 +10632,48 @@ version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84c9b0a1ff494e05f503a08b3d51150b73aa639544631e510279d6375f290997" dependencies = [ - "solana-account-info", + "solana-account-info 3.1.1", "solana-define-syscall 4.0.1", - "solana-program-error", + "solana-program-error 3.0.1", "solana-pubkey 4.2.0", ] [[package]] name = "solana-program-error" -version = "3.0.0" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ee2e0217d642e2ea4bee237f37bd61bb02aec60da3647c48ff88f6556ade775" +dependencies = [ + "borsh 1.6.1", + "num-traits", + "serde", + "serde_derive", + "solana-decode-error", + "solana-instruction 2.3.3", + "solana-msg 2.2.1", + "solana-pubkey 2.4.0", +] + +[[package]] +name = "solana-program-error" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1af32c995a7b692a915bb7414d5f8e838450cf7c70414e763d8abcae7b51f28" +checksum = "4f04fa578707b3612b095f0c8e19b66a1233f7c42ca8082fcb3b745afcc0add6" dependencies = [ - "borsh", + "borsh 1.6.1", "serde", "serde_derive", ] +[[package]] +name = "solana-program-memory" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a5426090c6f3fd6cfdc10685322fede9ca8e5af43cd6a59e98bfe4e91671712" +dependencies = [ + "solana-define-syscall 2.3.0", +] + [[package]] name = "solana-program-memory" version = "3.1.0" @@ -8989,19 +10683,34 @@ dependencies = [ "solana-define-syscall 4.0.1", ] +[[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-option" version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a88006a9b8594088cec9027ab77caaaa258a2aaa2083d3f086c44b42e50aeab" +[[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 2.2.2", +] + [[package]] name = "solana-program-pack" version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d7701cb15b90667ae1c89ef4ac35a59c61e66ce58ddee13d729472af7f41d59" dependencies = [ - "solana-program-error", + "solana-program-error 3.0.1", ] [[package]] @@ -9014,37 +10723,37 @@ dependencies = [ "itertools 0.12.1", "log", "percentage", - "rand 0.8.5", + "rand 0.8.6", "serde", - "solana-account", - "solana-account-info", - "solana-clock", - "solana-epoch-rewards", - "solana-epoch-schedule", + "solana-account 3.4.0", + "solana-account-info 3.1.1", + "solana-clock 3.1.0", + "solana-epoch-rewards 3.0.2", + "solana-epoch-schedule 3.1.0", "solana-fee-structure", "solana-hash 3.1.0", - "solana-instruction", - "solana-last-restart-slot", - "solana-loader-v3-interface", - "solana-program-entrypoint", + "solana-instruction 3.4.0", + "solana-last-restart-slot 3.0.1", + "solana-loader-v3-interface 6.1.1", + "solana-program-entrypoint 3.1.1", "solana-pubkey 3.0.0", "solana-rent 3.1.0", "solana-sbpf", - "solana-sdk-ids", - "solana-slot-hashes", - "solana-stable-layout", - "solana-stake-interface", + "solana-sdk-ids 3.1.0", + "solana-slot-hashes 3.0.2", + "solana-stable-layout 3.0.1", + "solana-stake-interface 2.0.2", "solana-svm-callback", - "solana-svm-feature-set", + "solana-svm-feature-set 3.1.12", "solana-svm-log-collector", "solana-svm-measure", "solana-svm-timings", "solana-svm-transaction", "solana-svm-type-overrides", "solana-system-interface 2.0.0", - "solana-sysvar", - "solana-sysvar-id", - "solana-transaction-context", + "solana-sysvar 3.1.1", + "solana-sysvar-id 3.1.0", + "solana-transaction-context 3.1.12", "thiserror 2.0.18", ] @@ -9054,7 +10763,7 @@ version = "3.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3848324dae946ff709b78cf5599fc5fa17fb1877cf5c98e8167e2e0fd9e1990f" dependencies = [ - "agave-feature-set", + "agave-feature-set 3.1.12", "agave-logger", "assert_matches", "async-trait", @@ -9064,62 +10773,88 @@ dependencies = [ "crossbeam-channel", "log", "serde", - "solana-account", - "solana-account-info", + "solana-account 3.4.0", + "solana-account-info 3.1.1", "solana-accounts-db", "solana-banks-client", "solana-banks-interface", "solana-banks-server", - "solana-clock", + "solana-clock 3.1.0", "solana-cluster-type 3.1.0", - "solana-commitment-config", + "solana-commitment-config 3.1.1", "solana-compute-budget", - "solana-epoch-rewards", - "solana-epoch-schedule", - "solana-fee-calculator", + "solana-epoch-rewards 3.0.2", + "solana-epoch-schedule 3.1.0", + "solana-fee-calculator 3.2.0", "solana-genesis-config", "solana-hash 3.1.0", - "solana-instruction", - "solana-keypair", - "solana-loader-v3-interface", - "solana-message", - "solana-msg", - "solana-native-token", + "solana-instruction 3.4.0", + "solana-keypair 3.1.0", + "solana-loader-v3-interface 6.1.1", + "solana-message 3.1.0", + "solana-msg 3.1.0", + "solana-native-token 3.0.0", "solana-poh-config", "solana-program-binaries", - "solana-program-entrypoint", - "solana-program-error", + "solana-program-entrypoint 3.1.1", + "solana-program-error 3.0.1", "solana-program-runtime", "solana-pubkey 3.0.0", "solana-rent 3.1.0", "solana-runtime", "solana-sbpf", - "solana-sdk-ids", - "solana-signer", - "solana-stable-layout", - "solana-stake-interface", + "solana-sdk-ids 3.1.0", + "solana-signer 3.0.0", + "solana-stable-layout 3.0.1", + "solana-stake-interface 2.0.2", "solana-svm", "solana-svm-log-collector", "solana-svm-timings", "solana-system-interface 2.0.0", - "solana-sysvar", - "solana-sysvar-id", - "solana-transaction", - "solana-transaction-context", - "solana-transaction-error", + "solana-sysvar 3.1.1", + "solana-sysvar-id 3.1.0", + "solana-transaction 3.1.0", + "solana-transaction-context 3.1.12", + "solana-transaction-error 3.2.0", "solana-vote-program", - "spl-generic-token", + "spl-generic-token 2.0.1", "thiserror 2.0.18", "tokio", ] +[[package]] +name = "solana-pubkey" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b62adb9c3261a052ca1f999398c388f1daf558a1b492f60a6d9e64857db4ff1" +dependencies = [ + "borsh 0.10.4", + "borsh 1.6.1", + "bytemuck", + "bytemuck_derive", + "curve25519-dalek 4.1.3", + "five8 0.2.1", + "five8_const 0.1.4", + "getrandom 0.2.17", + "js-sys", + "num-traits", + "serde", + "serde_derive", + "solana-atomic-u64 2.2.1", + "solana-decode-error", + "solana-define-syscall 2.3.0", + "solana-sanitize 2.2.1", + "solana-sha256-hasher 2.3.0", + "wasm-bindgen", +] + [[package]] name = "solana-pubkey" version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8909d399deb0851aa524420beeb5646b115fd253ef446e35fe4504c904da3941" dependencies = [ - "rand 0.8.5", + "rand 0.8.6", "solana-address 1.1.0", ] @@ -9145,11 +10880,11 @@ dependencies = [ "semver", "serde", "serde_json", - "solana-account-decoder-client-types", - "solana-clock", + "solana-account-decoder-client-types 3.1.12", + "solana-clock 3.1.0", "solana-pubkey 3.0.0", - "solana-rpc-client-types", - "solana-signature", + "solana-rpc-client-types 3.1.12", + "solana-signature 3.4.0", "thiserror 2.0.18", "tokio", "tokio-stream", @@ -9171,19 +10906,19 @@ dependencies = [ "futures", "itertools 0.12.1", "log", - "rustls 0.23.35", + "rustls 0.23.40", "solana-connection-cache", - "solana-keypair", + "solana-keypair 3.1.0", "solana-measure", "solana-metrics 3.1.12", "solana-net-utils", "solana-pubkey 3.0.0", "solana-quic-definitions", - "solana-rpc-client-api", - "solana-signer", + "solana-rpc-client-api 3.1.12", + "solana-signer 3.0.0", "solana-streamer", "solana-tls-utils", - "solana-transaction-error", + "solana-transaction-error 3.2.0", "thiserror 2.0.18", "tokio", ] @@ -9194,7 +10929,7 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "15319accf7d3afd845817aeffa6edd8cc185f135cefbc6b985df29cfd8c09609" dependencies = [ - "solana-keypair", + "solana-keypair 3.1.0", ] [[package]] @@ -9207,6 +10942,19 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "solana-rent" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1aea8fdea9de98ca6e8c2da5827707fb3842833521b528a713810ca685d2480" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-ids 2.2.1", + "solana-sdk-macro 2.2.1", + "solana-sysvar-id 2.2.1", +] + [[package]] name = "solana-rent" version = "3.1.0" @@ -9215,9 +10963,9 @@ checksum = "e860d5499a705369778647e97d760f7670adfb6fc8419dd3d568deccd46d5487" dependencies = [ "serde", "serde_derive", - "solana-sdk-ids", - "solana-sdk-macro", - "solana-sysvar-id", + "solana-sdk-ids 3.1.0", + "solana-sdk-macro 3.0.1", + "solana-sysvar-id 3.1.0", ] [[package]] @@ -9226,17 +10974,67 @@ version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9809b081e99bc142ce803bcd7ee18306759ce3b30a96a9da3f6f41c45e50ef0" dependencies = [ - "solana-sdk-macro", + "solana-sdk-macro 3.0.1", +] + +[[package]] +name = "solana-reward-info" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18205b69139b1ae0ab8f6e11cdcb627328c0814422ad2482000fa2ca54ae4a2f" +dependencies = [ + "serde", + "serde_derive", ] [[package]] name = "solana-reward-info" version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82be7946105c2ee6be9f9ee7bd18a068b558389221d29efa92b906476102bfcc" +checksum = "82be7946105c2ee6be9f9ee7bd18a068b558389221d29efa92b906476102bfcc" +dependencies = [ + "serde", + "serde_derive", +] + +[[package]] +name = "solana-rpc-client" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8d3161ac0918178e674c1f7f1bfac40de3e7ed0383bd65747d63113c156eaeb" dependencies = [ + "async-trait", + "base64 0.22.1", + "bincode", + "bs58", + "futures", + "indicatif 0.17.11", + "log", + "reqwest 0.12.28", + "reqwest-middleware", + "semver", "serde", "serde_derive", + "serde_json", + "solana-account 2.2.1", + "solana-account-decoder-client-types 2.3.13", + "solana-clock 2.2.3", + "solana-commitment-config 2.2.1", + "solana-epoch-info 2.2.1", + "solana-epoch-schedule 2.2.1", + "solana-feature-gate-interface 2.2.2", + "solana-hash 2.3.0", + "solana-instruction 2.3.3", + "solana-message 2.4.0", + "solana-pubkey 2.4.0", + "solana-rpc-client-api 2.3.13", + "solana-signature 2.3.0", + "solana-transaction 2.2.3", + "solana-transaction-error 2.2.1", + "solana-transaction-status-client-types 2.3.13", + "solana-version 2.3.13", + "solana-vote-interface 2.2.6", + "tokio", ] [[package]] @@ -9250,35 +11048,57 @@ dependencies = [ "bincode", "bs58", "futures", - "indicatif", + "indicatif 0.18.4", "log", "reqwest 0.12.28", "reqwest-middleware", "semver", "serde", "serde_json", - "solana-account", + "solana-account 3.4.0", "solana-account-decoder", - "solana-account-decoder-client-types", - "solana-clock", - "solana-commitment-config", - "solana-epoch-info", - "solana-epoch-schedule", - "solana-feature-gate-interface", + "solana-account-decoder-client-types 3.1.12", + "solana-clock 3.1.0", + "solana-commitment-config 3.1.1", + "solana-epoch-info 3.1.0", + "solana-epoch-schedule 3.1.0", + "solana-feature-gate-interface 3.1.0", "solana-hash 3.1.0", - "solana-instruction", - "solana-message", + "solana-instruction 3.4.0", + "solana-message 3.1.0", "solana-pubkey 3.0.0", - "solana-rpc-client-api", - "solana-signature", - "solana-transaction", - "solana-transaction-error", - "solana-transaction-status-client-types", - "solana-version", - "solana-vote-interface", + "solana-rpc-client-api 3.1.12", + "solana-signature 3.4.0", + "solana-transaction 3.1.0", + "solana-transaction-error 3.2.0", + "solana-transaction-status-client-types 3.1.12", + "solana-version 3.1.12", + "solana-vote-interface 4.0.4", "tokio", ] +[[package]] +name = "solana-rpc-client-api" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dbc138685c79d88a766a8fd825057a74ea7a21e1dd7f8de275ada899540fff7" +dependencies = [ + "anyhow", + "jsonrpc-core", + "reqwest 0.12.28", + "reqwest-middleware", + "serde", + "serde_derive", + "serde_json", + "solana-account-decoder-client-types 2.3.13", + "solana-clock 2.2.3", + "solana-rpc-client-types 2.3.13", + "solana-signer 2.2.1", + "solana-transaction-error 2.2.1", + "solana-transaction-status-client-types 2.3.13", + "thiserror 2.0.18", +] + [[package]] name = "solana-rpc-client-api" version = "3.1.12" @@ -9291,12 +11111,12 @@ dependencies = [ "reqwest-middleware", "serde", "serde_json", - "solana-account-decoder-client-types", - "solana-clock", - "solana-rpc-client-types", - "solana-signer", - "solana-transaction-error", - "solana-transaction-status-client-types", + "solana-account-decoder-client-types 3.1.12", + "solana-clock 3.1.0", + "solana-rpc-client-types 3.1.12", + "solana-signer 3.0.0", + "solana-transaction-error 3.2.0", + "solana-transaction-status-client-types 3.1.12", "thiserror 2.0.18", ] @@ -9306,14 +11126,40 @@ version = "3.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1fc7c6ad3eb7df35a1f97c820003439334ee0d5944b155e9cb78bf9e0ecce36" dependencies = [ - "solana-account", - "solana-commitment-config", + "solana-account 3.4.0", + "solana-commitment-config 3.1.1", "solana-hash 3.1.0", - "solana-message", - "solana-nonce", + "solana-message 3.1.0", + "solana-nonce 3.2.0", "solana-pubkey 3.0.0", - "solana-rpc-client", - "solana-sdk-ids", + "solana-rpc-client 3.1.12", + "solana-sdk-ids 3.1.0", + "thiserror 2.0.18", +] + +[[package]] +name = "solana-rpc-client-types" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea428a81729255d895ea47fba9b30fd4dacbfe571a080448121bd0592751676" +dependencies = [ + "base64 0.22.1", + "bs58", + "semver", + "serde", + "serde_derive", + "serde_json", + "solana-account 2.2.1", + "solana-account-decoder-client-types 2.3.13", + "solana-clock 2.2.3", + "solana-commitment-config 2.2.1", + "solana-fee-calculator 2.2.1", + "solana-inflation 2.2.1", + "solana-pubkey 2.4.0", + "solana-transaction-error 2.2.1", + "solana-transaction-status-client-types 2.3.13", + "solana-version 2.3.13", + "spl-generic-token 1.0.1", "thiserror 2.0.18", ] @@ -9328,19 +11174,19 @@ dependencies = [ "semver", "serde", "serde_json", - "solana-account", - "solana-account-decoder-client-types", + "solana-account 3.4.0", + "solana-account-decoder-client-types 3.1.12", "solana-address 1.1.0", - "solana-clock", - "solana-commitment-config", - "solana-fee-calculator", - "solana-inflation", - "solana-reward-info", - "solana-transaction", - "solana-transaction-error", - "solana-transaction-status-client-types", - "solana-version", - "spl-generic-token", + "solana-clock 3.1.0", + "solana-commitment-config 3.1.1", + "solana-fee-calculator 3.2.0", + "solana-inflation 3.1.0", + "solana-reward-info 3.0.0", + "solana-transaction 3.1.0", + "solana-transaction-error 3.2.0", + "solana-transaction-status-client-types 3.1.12", + "solana-version 3.1.12", + "spl-generic-token 2.0.1", "thiserror 2.0.18", ] @@ -9350,7 +11196,7 @@ version = "3.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eb482d0c82ee826621758e7fdba331cd78857a94107247a2674216abb4ff808" dependencies = [ - "agave-feature-set", + "agave-feature-set 3.1.12", "agave-fs", "agave-precompiles", "agave-reserved-account-keys", @@ -9376,7 +11222,7 @@ dependencies = [ "libc", "log", "lz4", - "memmap2 0.9.9", + "memmap2 0.9.10", "mockall", "modular-bitfield", "num-derive", @@ -9385,54 +11231,54 @@ dependencies = [ "num_enum", "percentage", "qualifier_attr", - "rand 0.8.5", + "rand 0.8.6", "rayon", "regex", "semver", "serde", "serde_json", "serde_with", - "solana-account", - "solana-account-info", + "solana-account 3.4.0", + "solana-account-info 3.1.1", "solana-accounts-db", - "solana-address-lookup-table-interface", + "solana-address-lookup-table-interface 3.1.0", "solana-bls-signatures", "solana-bpf-loader-program", "solana-bucket-map", "solana-builtins", "solana-client-traits", - "solana-clock", + "solana-clock 3.1.0", "solana-cluster-type 3.1.0", - "solana-commitment-config", + "solana-commitment-config 3.1.1", "solana-compute-budget", "solana-compute-budget-instruction", - "solana-compute-budget-interface", + "solana-compute-budget-interface 3.0.0", "solana-config-interface", "solana-cost-model", - "solana-cpi", + "solana-cpi 3.1.0", "solana-ed25519-program", - "solana-epoch-info", + "solana-epoch-info 3.1.0", "solana-epoch-rewards-hasher", - "solana-epoch-schedule", - "solana-feature-gate-interface", + "solana-epoch-schedule 3.1.0", + "solana-feature-gate-interface 3.1.0", "solana-fee", - "solana-fee-calculator", + "solana-fee-calculator 3.2.0", "solana-fee-structure", "solana-genesis-config", "solana-hard-forks", "solana-hash 3.1.0", - "solana-inflation", - "solana-instruction", - "solana-keypair", + "solana-inflation 3.1.0", + "solana-instruction 3.4.0", + "solana-keypair 3.1.0", "solana-lattice-hash", - "solana-loader-v3-interface", - "solana-loader-v4-interface", + "solana-loader-v3-interface 6.1.1", + "solana-loader-v4-interface 3.1.0", "solana-measure", - "solana-message", + "solana-message 3.1.0", "solana-metrics 3.1.12", - "solana-native-token", + "solana-native-token 3.0.0", "solana-nohash-hasher", - "solana-nonce", + "solana-nonce 3.2.0", "solana-nonce-account", "solana-packet", "solana-perf", @@ -9442,37 +11288,37 @@ dependencies = [ "solana-pubkey 3.0.0", "solana-rayon-threadlimit", "solana-rent 3.1.0", - "solana-reward-info", + "solana-reward-info 3.0.0", "solana-runtime-transaction", - "solana-sdk-ids", + "solana-sdk-ids 3.1.0", "solana-secp256k1-program", - "solana-seed-derivable", + "solana-seed-derivable 3.0.0", "solana-serde", "solana-sha256-hasher 3.1.0", - "solana-signature", - "solana-signer", - "solana-slot-hashes", - "solana-slot-history", - "solana-stake-interface", + "solana-signature 3.4.0", + "solana-signer 3.0.0", + "solana-slot-hashes 3.0.2", + "solana-slot-history 3.0.1", + "solana-stake-interface 2.0.2", "solana-svm", "solana-svm-callback", "solana-svm-timings", "solana-svm-transaction", "solana-system-interface 2.0.0", "solana-system-transaction", - "solana-sysvar", - "solana-sysvar-id", + "solana-sysvar 3.1.1", + "solana-sysvar-id 3.1.0", "solana-time-utils 3.0.0", - "solana-transaction", - "solana-transaction-context", - "solana-transaction-error", - "solana-transaction-status-client-types", + "solana-transaction 3.1.0", + "solana-transaction-context 3.1.12", + "solana-transaction-error 3.2.0", + "solana-transaction-status-client-types 3.1.12", "solana-unified-scheduler-logic", - "solana-version", + "solana-version 3.1.12", "solana-vote", - "solana-vote-interface", + "solana-vote-interface 4.0.4", "solana-vote-program", - "spl-generic-token", + "spl-generic-token 2.0.1", "static_assertions", "strum 0.24.1", "strum_macros 0.24.3", @@ -9492,14 +11338,14 @@ dependencies = [ "solana-compute-budget", "solana-compute-budget-instruction", "solana-hash 3.1.0", - "solana-message", + "solana-message 3.1.0", "solana-pubkey 3.0.0", - "solana-sdk-ids", - "solana-signature", + "solana-sdk-ids 3.1.0", + "solana-signature 3.4.0", "solana-svm-transaction", - "solana-transaction", - "solana-transaction-context", - "solana-transaction-error", + "solana-transaction 3.1.0", + "solana-transaction-context 3.1.12", + "solana-transaction-error 3.2.0", "thiserror 2.0.18", ] @@ -9526,7 +11372,7 @@ dependencies = [ "hash32", "libc", "log", - "rand 0.8.5", + "rand 0.8.6", "rustc-demangle", "thiserror 2.0.18", "winapi", @@ -9541,35 +11387,44 @@ dependencies = [ "bincode", "bs58", "serde", - "solana-account", - "solana-epoch-info", + "solana-account 3.4.0", + "solana-epoch-info 3.1.0", "solana-epoch-rewards-hasher", "solana-fee-structure", - "solana-inflation", - "solana-keypair", - "solana-message", + "solana-inflation 3.1.0", + "solana-keypair 3.1.0", + "solana-message 3.1.0", "solana-offchain-message", "solana-presigner", - "solana-program", - "solana-program-memory", + "solana-program 3.0.0", + "solana-program-memory 3.1.0", "solana-pubkey 3.0.0", "solana-sanitize 3.0.1", - "solana-sdk-ids", - "solana-sdk-macro", - "solana-seed-derivable", - "solana-seed-phrase", + "solana-sdk-ids 3.1.0", + "solana-sdk-macro 3.0.1", + "solana-seed-derivable 3.0.0", + "solana-seed-phrase 3.0.0", "solana-serde", - "solana-serde-varint", - "solana-short-vec", + "solana-serde-varint 3.0.1", + "solana-short-vec 3.2.1", "solana-shred-version", - "solana-signature", - "solana-signer", + "solana-signature 3.4.0", + "solana-signer 3.0.0", "solana-time-utils 3.0.0", - "solana-transaction", - "solana-transaction-error", + "solana-transaction 3.1.0", + "solana-transaction-error 3.2.0", "thiserror 2.0.18", ] +[[package]] +name = "solana-sdk-ids" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5d8b9cc68d5c88b062a33e23a6466722467dde0035152d8fb1afbcdf350a5f" +dependencies = [ + "solana-pubkey 2.4.0", +] + [[package]] name = "solana-sdk-ids" version = "3.1.0" @@ -9579,6 +11434,18 @@ dependencies = [ "solana-address 2.6.0", ] +[[package]] +name = "solana-sdk-macro" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86280da8b99d03560f6ab5aca9de2e38805681df34e0bb8f238e69b29433b9df" +dependencies = [ + "bs58", + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "solana-sdk-macro" version = "3.0.1" @@ -9602,7 +11469,18 @@ dependencies = [ "serde", "serde_derive", "sha3", - "solana-signature", + "solana-signature 3.4.0", +] + +[[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 2.3.0", + "thiserror 2.0.18", ] [[package]] @@ -9612,7 +11490,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7c5f18893d62e6c73117dcba48f8f5e3266d90e5ec3d0a0a90f9785adac36c1" dependencies = [ "k256", - "solana-define-syscall 5.0.0", + "solana-define-syscall 5.1.0", "thiserror 2.0.18", ] @@ -9624,8 +11502,23 @@ checksum = "445d8e12592631d76fc4dc57858bae66c9fd7cc838c306c62a472547fc9d0ce6" dependencies = [ "bytemuck", "openssl", - "solana-instruction", - "solana-sdk-ids", + "solana-instruction 3.4.0", + "solana-sdk-ids 3.1.0", +] + +[[package]] +name = "solana-security-txt" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c94a02d486b28f219a4f8f5d7dd93cbfbb93c9f466cb7871c22e50cd5ae9a7a2" + +[[package]] +name = "solana-seed-derivable" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3beb82b5adb266c6ea90e5cf3967235644848eac476c5a1f2f9283a143b7c97f" +dependencies = [ + "solana-derivation-path 2.2.1", ] [[package]] @@ -9634,7 +11527,18 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff7bdb72758e3bec33ed0e2658a920f1f35dfb9ed576b951d20d63cb61ecd95c" dependencies = [ - "solana-derivation-path", + "solana-derivation-path 3.0.0", +] + +[[package]] +name = "solana-seed-phrase" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36187af2324f079f65a675ec22b31c24919cb4ac22c79472e85d819db9bbbc15" +dependencies = [ + "hmac 0.12.1", + "pbkdf2", + "sha2 0.10.9", ] [[package]] @@ -9659,21 +11563,21 @@ dependencies = [ "itertools 0.12.1", "log", "solana-client", - "solana-clock", + "solana-clock 3.1.0", "solana-connection-cache", "solana-hash 3.1.0", - "solana-keypair", + "solana-keypair 3.1.0", "solana-measure", "solana-metrics 3.1.12", "solana-nonce-account", "solana-pubkey 3.0.0", "solana-quic-definitions", "solana-runtime", - "solana-signature", + "solana-signature 3.4.0", "solana-time-utils 3.0.0", "solana-tpu-client-next", "tokio", - "tokio-util 0.7.17", + "tokio-util 0.7.18", ] [[package]] @@ -9685,6 +11589,15 @@ dependencies = [ "serde", ] +[[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-serde-varint" version = "3.0.1" @@ -9696,9 +11609,20 @@ dependencies = [ [[package]] name = "solana-serialize-utils" -version = "3.1.1" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "817a284b63197d2b27afdba829c5ab34231da4a9b4e763466a003c40ca4f535e" +dependencies = [ + "solana-instruction 2.3.3", + "solana-pubkey 2.4.0", + "solana-sanitize 2.2.1", +] + +[[package]] +name = "solana-serialize-utils" +version = "3.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d7cc401931d178472358e6b78dc72d031dc08f752d7410f0e8bd259dd6f02fa" +checksum = "761357b0853c9623bf12c1d2314b3d6160a85b087b84c45224fb85766d22616b" dependencies = [ "solana-instruction-error", "solana-pubkey 4.2.0", @@ -9707,9 +11631,9 @@ dependencies = [ [[package]] name = "solana-sha256-hasher" -version = "2.2.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0037386961c0d633421f53560ad7c80675c0447cba4d1bb66d60974dd486c7ea" +checksum = "5aa3feb32c28765f6aa1ce8f3feac30936f16c5c3f7eb73d63a5b8f6f8ecdc44" dependencies = [ "sha2 0.10.9", "solana-define-syscall 2.3.0", @@ -9724,14 +11648,23 @@ checksum = "db7dc3011ea4c0334aaaa7e7128cb390ecf546b28d412e9bf2064680f57f588f" dependencies = [ "sha2 0.10.9", "solana-define-syscall 4.0.1", - "solana-hash 4.2.0", + "solana-hash 4.3.0", ] [[package]] name = "solana-short-vec" -version = "3.2.0" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c54c66f19b9766a56fa0057d060de8378676cb64987533fa088861858fc5a69" +dependencies = [ + "serde", +] + +[[package]] +name = "solana-short-vec" +version = "3.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3bd991c2cc415291c86bb0b6b4d53e93d13bb40344e4c5a2884e0e4f5fa93f" +checksum = "2bb8cc883fc7b8ce4a7814cb1441b48c06437049ec11847005cf63bcfa85c546" dependencies = [ "serde_core", ] @@ -9743,10 +11676,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6c79722e299d957958bf33695f7cd1ef6724ff55563c60fd9e3e24487cccde2" dependencies = [ "solana-hard-forks", - "solana-hash 4.2.0", + "solana-hash 4.3.0", "solana-sha256-hasher 3.1.0", ] +[[package]] +name = "solana-signature" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64c8ec8e657aecfc187522fc67495142c12f35e55ddeca8698edbb738b8dbd8c" +dependencies = [ + "ed25519-dalek 1.0.1", + "five8 0.2.1", + "serde", + "serde-big-array", + "serde_derive", + "solana-sanitize 2.2.1", +] + [[package]] name = "solana-signature" version = "3.4.0" @@ -9755,12 +11702,23 @@ checksum = "e7a73c6e97cc2108be0adf6a6ea326434f8398df9d7eed81da2a4548b69e971c" dependencies = [ "ed25519-dalek 2.2.0", "five8 1.0.0", - "rand 0.9.2", + "rand 0.9.4", "serde", "serde-big-array", "serde_derive", "solana-sanitize 3.0.1", - "wincode 0.5.1", + "wincode", +] + +[[package]] +name = "solana-signer" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c41991508a4b02f021c1342ba00bcfa098630b213726ceadc7cb032e051975b" +dependencies = [ + "solana-pubkey 2.4.0", + "solana-signature 2.3.0", + "solana-transaction-error 2.2.1", ] [[package]] @@ -9770,34 +11728,70 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5bfea97951fee8bae0d6038f39a5efcb6230ecdfe33425ac75196d1a1e3e3235" dependencies = [ "solana-pubkey 3.0.0", - "solana-signature", - "solana-transaction-error", + "solana-signature 3.4.0", + "solana-transaction-error 3.2.0", ] [[package]] name = "solana-slot-hashes" -version = "3.0.1" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c8691982114513763e88d04094c9caa0376b867a29577939011331134c301ce" +dependencies = [ + "serde", + "serde_derive", + "solana-hash 2.3.0", + "solana-sdk-ids 2.2.1", + "solana-sysvar-id 2.2.1", +] + +[[package]] +name = "solana-slot-hashes" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2585f70191623887329dfb5078da3a00e15e3980ea67f42c2e10b07028419f43" +checksum = "0a57c158c35629f9e302ab385f16b15813f4927a31c27dda72f3df828bb08d93" dependencies = [ "serde", "serde_derive", - "solana-hash 4.2.0", - "solana-sdk-ids", - "solana-sysvar-id", + "solana-hash 4.3.0", + "solana-sdk-ids 3.1.0", + "solana-sysvar-id 3.1.0", ] [[package]] name = "solana-slot-history" -version = "3.0.0" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97ccc1b2067ca22754d5283afb2b0126d61eae734fc616d23871b0943b0d935e" +dependencies = [ + "bv", + "serde", + "serde_derive", + "solana-sdk-ids 2.2.1", + "solana-sysvar-id 2.2.1", +] + +[[package]] +name = "solana-slot-history" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f914f6b108f5bba14a280b458d023e3621c9973f27f015a4d755b50e88d89e97" +checksum = "0622d03a823770f7763afd866e012b296d5a3cbbbe51e110b5bd9ab3441efdca" dependencies = [ "bv", "serde", "serde_derive", - "solana-sdk-ids", - "solana-sysvar-id", + "solana-sdk-ids 3.1.0", + "solana-sysvar-id 3.1.0", +] + +[[package]] +name = "solana-stable-layout" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f14f7d02af8f2bc1b5efeeae71bc1c2b7f0f65cd75bcc7d8180f2c762a57f54" +dependencies = [ + "solana-instruction 2.3.3", + "solana-pubkey 2.4.0", ] [[package]] @@ -9806,10 +11800,31 @@ version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9f6a291ba063a37780af29e7db14bdd3dc447584d8ba5b3fc4b88e2bbc982fa" dependencies = [ - "solana-instruction", + "solana-instruction 3.4.0", "solana-pubkey 4.2.0", ] +[[package]] +name = "solana-stake-interface" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5269e89fde216b4d7e1d1739cf5303f8398a1ff372a81232abbee80e554a838c" +dependencies = [ + "borsh 0.10.4", + "borsh 1.6.1", + "num-traits", + "serde", + "serde_derive", + "solana-clock 2.2.3", + "solana-cpi 2.2.1", + "solana-decode-error", + "solana-instruction 2.3.3", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "solana-system-interface 1.0.0", + "solana-sysvar-id 2.2.1", +] + [[package]] name = "solana-stake-interface" version = "2.0.2" @@ -9819,14 +11834,14 @@ dependencies = [ "num-traits", "serde", "serde_derive", - "solana-clock", - "solana-cpi", - "solana-instruction", - "solana-program-error", + "solana-clock 3.1.0", + "solana-cpi 3.1.0", + "solana-instruction 3.4.0", + "solana-program-error 3.0.1", "solana-pubkey 3.0.0", "solana-system-interface 2.0.0", - "solana-sysvar", - "solana-sysvar-id", + "solana-sysvar 3.1.1", + "solana-sysvar-id 3.1.0", ] [[package]] @@ -9840,12 +11855,12 @@ dependencies = [ "serde", "solana-account-decoder", "solana-hash 3.1.0", - "solana-instruction", - "solana-message", + "solana-instruction 3.4.0", + "solana-message 3.1.0", "solana-pubkey 3.0.0", - "solana-signature", - "solana-transaction", - "solana-transaction-error", + "solana-signature 3.4.0", + "solana-transaction 3.1.0", + "solana-transaction-error 3.2.0", "solana-transaction-status", "tonic-prost-build", ] @@ -9866,19 +11881,19 @@ dependencies = [ "futures-util", "governor", "histogram", - "indexmap 2.12.1", + "indexmap 2.14.0", "itertools 0.12.1", "libc", "log", - "nix", + "nix 0.30.1", "num_cpus", "pem", "percentage", - "rand 0.8.5", - "rustls 0.23.35", + "rand 0.8.6", + "rustls 0.23.40", "smallvec", - "socket2 0.6.1", - "solana-keypair", + "socket2 0.6.3", + "solana-keypair 3.1.0", "solana-measure", "solana-metrics 3.1.12", "solana-net-utils", @@ -9886,15 +11901,15 @@ dependencies = [ "solana-perf", "solana-pubkey 3.0.0", "solana-quic-definitions", - "solana-signature", - "solana-signer", + "solana-signature 3.4.0", + "solana-signer 3.0.0", "solana-time-utils 3.0.0", "solana-tls-utils", - "solana-transaction-error", + "solana-transaction-error 3.2.0", "solana-transaction-metrics-tracker", "thiserror 2.0.18", "tokio", - "tokio-util 0.7.17", + "tokio-util 0.7.18", "x509-parser", ] @@ -9908,36 +11923,36 @@ dependencies = [ "percentage", "qualifier_attr", "serde", - "solana-account", - "solana-clock", + "solana-account 3.4.0", + "solana-clock 3.1.0", "solana-fee-structure", "solana-hash 3.1.0", - "solana-instruction", - "solana-instructions-sysvar", - "solana-loader-v3-interface", - "solana-loader-v4-interface", + "solana-instruction 3.4.0", + "solana-instructions-sysvar 3.0.1", + "solana-loader-v3-interface 6.1.1", + "solana-loader-v4-interface 3.1.0", "solana-loader-v4-program", - "solana-message", - "solana-nonce", + "solana-message 3.1.0", + "solana-nonce 3.2.0", "solana-nonce-account", - "solana-program-entrypoint", - "solana-program-pack", + "solana-program-entrypoint 3.1.1", + "solana-program-pack 3.1.0", "solana-program-runtime", "solana-pubkey 3.0.0", "solana-rent 3.1.0", - "solana-sdk-ids", + "solana-sdk-ids 3.1.0", "solana-svm-callback", - "solana-svm-feature-set", + "solana-svm-feature-set 3.1.12", "solana-svm-log-collector", "solana-svm-measure", "solana-svm-timings", "solana-svm-transaction", "solana-svm-type-overrides", "solana-system-interface 2.0.0", - "solana-sysvar-id", - "solana-transaction-context", - "solana-transaction-error", - "spl-generic-token", + "solana-sysvar-id 3.1.0", + "solana-transaction-context 3.1.12", + "solana-transaction-error 3.2.0", + "spl-generic-token 2.0.1", "thiserror 2.0.18", ] @@ -9947,12 +11962,18 @@ version = "3.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb521c7f62db21661267a933f0d311a76b2b744a766b46f5a9a9395ce70f687c" dependencies = [ - "solana-account", - "solana-clock", + "solana-account 3.4.0", + "solana-clock 3.1.0", "solana-precompile-error", "solana-pubkey 3.0.0", ] +[[package]] +name = "solana-svm-feature-set" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f24b836eb4d74ec255217bdbe0f24f64a07adeac31aca61f334f91cd4a3b1d5" + [[package]] name = "solana-svm-feature-set" version = "3.1.12" @@ -9992,11 +12013,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ef6ff55ce4c24e26ad8b0e67bc604cbd54eabfc94540c4c2c93e51fa087ead5" dependencies = [ "solana-hash 3.1.0", - "solana-message", + "solana-message 3.1.0", "solana-pubkey 3.0.0", - "solana-sdk-ids", - "solana-signature", - "solana-transaction", + "solana-sdk-ids 3.1.0", + "solana-signature 3.4.0", + "solana-transaction 3.1.0", ] [[package]] @@ -10005,7 +12026,23 @@ version = "3.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa888be46794b88f130508f694e989fb8802c823b9048acd4d0240e9818502fe" dependencies = [ - "rand 0.8.5", + "rand 0.8.6", +] + +[[package]] +name = "solana-system-interface" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94d7c18cb1a91c6be5f5a8ac9276a1d7c737e39a21beba9ea710ab4b9c63bc90" +dependencies = [ + "js-sys", + "num-traits", + "serde", + "serde_derive", + "solana-decode-error", + "solana-instruction 2.3.3", + "solana-pubkey 2.4.0", + "wasm-bindgen", ] [[package]] @@ -10017,9 +12054,9 @@ dependencies = [ "num-traits", "serde", "serde_derive", - "solana-instruction", - "solana-msg", - "solana-program-error", + "solana-instruction 3.4.0", + "solana-msg 3.1.0", + "solana-program-error 3.0.1", "solana-pubkey 3.0.0", ] @@ -10033,9 +12070,9 @@ dependencies = [ "serde", "serde_derive", "solana-address 2.6.0", - "solana-instruction", - "solana-msg", - "solana-program-error", + "solana-instruction 3.4.0", + "solana-msg 3.1.0", + "solana-program-error 3.0.1", ] [[package]] @@ -10047,21 +12084,21 @@ dependencies = [ "bincode", "log", "serde", - "solana-account", - "solana-bincode", - "solana-fee-calculator", - "solana-instruction", - "solana-nonce", + "solana-account 3.4.0", + "solana-bincode 3.1.0", + "solana-fee-calculator 3.2.0", + "solana-instruction 3.4.0", + "solana-nonce 3.2.0", "solana-nonce-account", "solana-packet", "solana-program-runtime", "solana-pubkey 3.0.0", - "solana-sdk-ids", + "solana-sdk-ids 3.1.0", "solana-svm-log-collector", "solana-svm-type-overrides", "solana-system-interface 2.0.0", - "solana-sysvar", - "solana-transaction-context", + "solana-sysvar 3.1.1", + "solana-transaction-context 3.1.12", ] [[package]] @@ -10071,12 +12108,49 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a31b5699ec533621515e714f1533ee6b3b0e71c463301d919eb59b8c1e249d30" dependencies = [ "solana-hash 3.1.0", - "solana-keypair", - "solana-message", + "solana-keypair 3.1.0", + "solana-message 3.1.0", "solana-pubkey 3.0.0", - "solana-signer", + "solana-signer 3.0.0", "solana-system-interface 2.0.0", - "solana-transaction", + "solana-transaction 3.1.0", +] + +[[package]] +name = "solana-sysvar" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8c3595f95069f3d90f275bb9bd235a1973c4d059028b0a7f81baca2703815db" +dependencies = [ + "base64 0.22.1", + "bincode", + "bytemuck", + "bytemuck_derive", + "lazy_static", + "serde", + "serde_derive", + "solana-account-info 2.3.0", + "solana-clock 2.2.3", + "solana-define-syscall 2.3.0", + "solana-epoch-rewards 2.2.1", + "solana-epoch-schedule 2.2.1", + "solana-fee-calculator 2.2.1", + "solana-hash 2.3.0", + "solana-instruction 2.3.3", + "solana-instructions-sysvar 2.2.2", + "solana-last-restart-slot 2.2.1", + "solana-program-entrypoint 2.3.0", + "solana-program-error 2.2.2", + "solana-program-memory 2.3.1", + "solana-pubkey 2.4.0", + "solana-rent 2.2.1", + "solana-sanitize 2.2.1", + "solana-sdk-ids 2.2.1", + "solana-sdk-macro 2.2.1", + "solana-slot-hashes 2.2.1", + "solana-slot-history 2.2.1", + "solana-stake-interface 1.2.1", + "solana-sysvar-id 2.2.1", ] [[package]] @@ -10092,25 +12166,35 @@ dependencies = [ "lazy_static", "serde", "serde_derive", - "solana-account-info", - "solana-clock", + "solana-account-info 3.1.1", + "solana-clock 3.1.0", "solana-define-syscall 4.0.1", - "solana-epoch-rewards", - "solana-epoch-schedule", - "solana-fee-calculator", - "solana-hash 4.2.0", - "solana-instruction", - "solana-last-restart-slot", - "solana-program-entrypoint", - "solana-program-error", - "solana-program-memory", + "solana-epoch-rewards 3.0.2", + "solana-epoch-schedule 3.1.0", + "solana-fee-calculator 3.2.0", + "solana-hash 4.3.0", + "solana-instruction 3.4.0", + "solana-last-restart-slot 3.0.1", + "solana-program-entrypoint 3.1.1", + "solana-program-error 3.0.1", + "solana-program-memory 3.1.0", "solana-pubkey 4.2.0", "solana-rent 3.1.0", - "solana-sdk-ids", - "solana-sdk-macro", - "solana-slot-hashes", - "solana-slot-history", - "solana-sysvar-id", + "solana-sdk-ids 3.1.0", + "solana-sdk-macro 3.0.1", + "solana-slot-hashes 3.0.2", + "solana-slot-history 3.0.1", + "solana-sysvar-id 3.1.0", +] + +[[package]] +name = "solana-sysvar-id" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5762b273d3325b047cfda250787f8d796d781746860d5d0a746ee29f3e8812c1" +dependencies = [ + "solana-pubkey 2.4.0", + "solana-sdk-ids 2.2.1", ] [[package]] @@ -10120,7 +12204,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17358d1e9a13e5b9c2264d301102126cf11a47fd394cdf3dec174fe7bc96e1de" dependencies = [ "solana-address 2.6.0", - "solana-sdk-ids", + "solana-sdk-ids 3.1.0", ] [[package]] @@ -10141,10 +12225,10 @@ version = "3.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57a74352404ca3378d3bc6586a9a1e0d7362b687ce2218a0b646dccb767c7ba2" dependencies = [ - "rustls 0.23.35", - "solana-keypair", + "rustls 0.23.40", + "solana-keypair 3.1.0", "solana-pubkey 3.0.0", - "solana-signer", + "solana-signer 3.0.0", "x509-parser", ] @@ -10157,27 +12241,27 @@ dependencies = [ "async-trait", "bincode", "futures-util", - "indexmap 2.12.1", - "indicatif", + "indexmap 2.14.0", + "indicatif 0.18.4", "log", "rayon", "solana-client-traits", - "solana-clock", - "solana-commitment-config", + "solana-clock 3.1.0", + "solana-commitment-config 3.1.1", "solana-connection-cache", - "solana-epoch-schedule", + "solana-epoch-schedule 3.1.0", "solana-measure", - "solana-message", + "solana-message 3.1.0", "solana-net-utils", "solana-pubkey 3.0.0", "solana-pubsub-client", "solana-quic-definitions", - "solana-rpc-client", - "solana-rpc-client-api", - "solana-signature", - "solana-signer", - "solana-transaction", - "solana-transaction-error", + "solana-rpc-client 3.1.12", + "solana-rpc-client-api 3.1.12", + "solana-signature 3.4.0", + "solana-signer 3.0.0", + "solana-transaction 3.1.0", + "solana-transaction-error 3.2.0", "thiserror 2.0.18", "tokio", ] @@ -10192,21 +12276,46 @@ dependencies = [ "async-trait", "log", "lru 0.7.8", - "rustls 0.23.35", - "solana-clock", + "rustls 0.23.40", + "solana-clock 3.1.0", "solana-connection-cache", - "solana-keypair", + "solana-keypair 3.1.0", "solana-measure", "solana-metrics 3.1.12", "solana-quic-definitions", - "solana-rpc-client", + "solana-rpc-client 3.1.12", "solana-streamer", "solana-time-utils 3.0.0", "solana-tls-utils", "solana-tpu-client", "thiserror 2.0.18", "tokio", - "tokio-util 0.7.17", + "tokio-util 0.7.18", +] + +[[package]] +name = "solana-transaction" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80657d6088f721148f5d889c828ca60c7daeedac9a8679f9ec215e0c42bcbf41" +dependencies = [ + "bincode", + "serde", + "serde_derive", + "solana-bincode 2.2.1", + "solana-hash 2.3.0", + "solana-instruction 2.3.3", + "solana-keypair 2.2.3", + "solana-message 2.4.0", + "solana-pubkey 2.4.0", + "solana-sanitize 2.2.1", + "solana-sdk-ids 2.2.1", + "solana-short-vec 2.2.1", + "solana-signature 2.3.0", + "solana-signer 2.2.1", + "solana-system-interface 1.0.0", + "solana-transaction-error 2.2.1", + "wasm-bindgen", ] [[package]] @@ -10219,16 +12328,33 @@ dependencies = [ "serde", "serde_derive", "solana-address 2.6.0", - "solana-hash 4.2.0", - "solana-instruction", + "solana-hash 4.3.0", + "solana-instruction 3.4.0", "solana-instruction-error", - "solana-message", + "solana-message 3.1.0", "solana-sanitize 3.0.1", - "solana-sdk-ids", - "solana-short-vec", - "solana-signature", - "solana-signer", - "solana-transaction-error", + "solana-sdk-ids 3.1.0", + "solana-short-vec 3.2.1", + "solana-signature 3.4.0", + "solana-signer 3.0.0", + "solana-transaction-error 3.2.0", +] + +[[package]] +name = "solana-transaction-context" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54a312304361987a85b2ef2293920558e6612876a639dd1309daf6d0d59ef2fe" +dependencies = [ + "bincode", + "serde", + "serde_derive", + "solana-account 2.2.1", + "solana-instruction 2.3.3", + "solana-instructions-sysvar 2.2.2", + "solana-pubkey 2.4.0", + "solana-rent 2.2.1", + "solana-sdk-ids 2.2.1", ] [[package]] @@ -10236,23 +12362,35 @@ name = "solana-transaction-context" version = "3.1.12" source = "git+https://github.com/magicblock-labs/magicblock-svm.git?rev=5bd1d56#5bd1d567c53c43fb501d3cb6d28ea1e9dd42f948" dependencies = [ - "bincode", - "qualifier_attr", + "bincode", + "qualifier_attr", + "serde", + "solana-account 3.4.0", + "solana-instruction 3.4.0", + "solana-instructions-sysvar 3.0.1", + "solana-pubkey 3.0.0", + "solana-rent 3.1.0", + "solana-sbpf", + "solana-sdk-ids 3.1.0", +] + +[[package]] +name = "solana-transaction-error" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "222a9dc8fdb61c6088baab34fc3a8b8473a03a7a5fd404ed8dd502fa79b67cb1" +dependencies = [ "serde", - "solana-account", - "solana-instruction", - "solana-instructions-sysvar", - "solana-pubkey 3.0.0", - "solana-rent 3.1.0", - "solana-sbpf", - "solana-sdk-ids", + "serde_derive", + "solana-instruction 2.3.3", + "solana-sanitize 2.2.1", ] [[package]] name = "solana-transaction-error" -version = "3.1.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8396904805b0b385b9de115a652fe80fd01e5b98ce0513f4fcd8184ada9bb792" +checksum = "4a2165ad25b694c654d5395fc7a049452a192376e4c96a7fad05580f6ba5ba1c" dependencies = [ "serde", "serde_derive", @@ -10269,11 +12407,11 @@ dependencies = [ "base64 0.22.1", "bincode", "log", - "rand 0.8.5", + "rand 0.8.6", "solana-packet", "solana-perf", - "solana-short-vec", - "solana-signature", + "solana-short-vec 3.2.1", + "solana-signature 3.4.0", ] [[package]] @@ -10286,36 +12424,59 @@ dependencies = [ "agave-reserved-account-keys", "base64 0.22.1", "bincode", - "borsh", + "borsh 1.6.1", "bs58", "log", "serde", "serde_json", "solana-account-decoder", - "solana-address-lookup-table-interface", - "solana-clock", + "solana-address-lookup-table-interface 3.1.0", + "solana-clock 3.1.0", "solana-hash 3.1.0", - "solana-instruction", - "solana-loader-v2-interface", - "solana-loader-v3-interface", - "solana-message", - "solana-program-option", + "solana-instruction 3.4.0", + "solana-loader-v2-interface 3.0.0", + "solana-loader-v3-interface 6.1.1", + "solana-message 3.1.0", + "solana-program-option 3.1.0", "solana-pubkey 3.0.0", - "solana-reward-info", - "solana-sdk-ids", - "solana-signature", - "solana-stake-interface", + "solana-reward-info 3.0.0", + "solana-sdk-ids 3.1.0", + "solana-signature 3.4.0", + "solana-stake-interface 2.0.2", "solana-system-interface 2.0.0", - "solana-transaction", - "solana-transaction-error", - "solana-transaction-status-client-types", - "solana-vote-interface", + "solana-transaction 3.1.0", + "solana-transaction-error 3.2.0", + "solana-transaction-status-client-types 3.1.12", + "solana-vote-interface 4.0.4", "spl-associated-token-account-interface", "spl-memo-interface", - "spl-token-2022-interface", - "spl-token-group-interface", + "spl-token-2022-interface 2.1.0", + "spl-token-group-interface 0.7.2", "spl-token-interface", - "spl-token-metadata-interface", + "spl-token-metadata-interface 0.8.0", + "thiserror 2.0.18", +] + +[[package]] +name = "solana-transaction-status-client-types" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51f1d7c2387c35850848212244d2b225847666cb52d3bd59a5c409d2c300303d" +dependencies = [ + "base64 0.22.1", + "bincode", + "bs58", + "serde", + "serde_derive", + "serde_json", + "solana-account-decoder-client-types 2.3.13", + "solana-commitment-config 2.2.1", + "solana-message 2.4.0", + "solana-reward-info 2.2.1", + "solana-signature 2.3.0", + "solana-transaction 2.2.3", + "solana-transaction-context 2.3.13", + "solana-transaction-error 2.2.1", "thiserror 2.0.18", ] @@ -10330,16 +12491,16 @@ dependencies = [ "bs58", "serde", "serde_json", - "solana-account-decoder-client-types", - "solana-commitment-config", - "solana-instruction", - "solana-message", + "solana-account-decoder-client-types 3.1.12", + "solana-commitment-config 3.1.1", + "solana-instruction 3.4.0", + "solana-message 3.1.0", "solana-pubkey 3.0.0", - "solana-reward-info", - "solana-signature", - "solana-transaction", - "solana-transaction-context", - "solana-transaction-error", + "solana-reward-info 3.0.0", + "solana-signature 3.4.0", + "solana-transaction 3.1.0", + "solana-transaction-context 3.1.12", + "solana-transaction-error 3.2.0", "thiserror 2.0.18", ] @@ -10351,10 +12512,10 @@ checksum = "b32651092f28c7fa9fb622a055f21fcfb1a109e6851d964ce043336a0035a629" dependencies = [ "async-trait", "solana-connection-cache", - "solana-keypair", + "solana-keypair 3.1.0", "solana-net-utils", "solana-streamer", - "solana-transaction-error", + "solana-transaction-error 3.2.0", "thiserror 2.0.18", "tokio", ] @@ -10368,23 +12529,38 @@ dependencies = [ "assert_matches", "solana-pubkey 3.0.0", "solana-runtime-transaction", - "solana-transaction", + "solana-transaction 3.1.0", "static_assertions", "unwrap_none", ] +[[package]] +name = "solana-version" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3324d46c7f7b7f5d34bf7dc71a2883bdc072c7b28ca81d0b2167ecec4cf8da9f" +dependencies = [ + "agave-feature-set 2.3.13", + "rand 0.8.6", + "semver", + "serde", + "serde_derive", + "solana-sanitize 2.2.1", + "solana-serde-varint 2.2.2", +] + [[package]] name = "solana-version" version = "3.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f697aacc5aa4ac5534abdde8a91afdcf18c24d28bd52768e8001445dbda078db" dependencies = [ - "agave-feature-set", - "rand 0.8.5", + "agave-feature-set 3.1.12", + "rand 0.8.6", "semver", "serde", "solana-sanitize 3.0.1", - "solana-serde-varint", + "solana-serde-varint 3.0.1", ] [[package]] @@ -10396,24 +12572,48 @@ dependencies = [ "itertools 0.12.1", "log", "serde", - "solana-account", - "solana-bincode", - "solana-clock", + "solana-account 3.4.0", + "solana-bincode 3.1.0", + "solana-clock 3.1.0", "solana-hash 3.1.0", - "solana-instruction", - "solana-keypair", + "solana-instruction 3.4.0", + "solana-keypair 3.1.0", "solana-packet", "solana-pubkey 3.0.0", - "solana-sdk-ids", - "solana-serialize-utils", - "solana-signature", - "solana-signer", + "solana-sdk-ids 3.1.0", + "solana-serialize-utils 3.1.2", + "solana-signature 3.4.0", + "solana-signer 3.0.0", "solana-svm-transaction", - "solana-transaction", - "solana-vote-interface", + "solana-transaction 3.1.0", + "solana-vote-interface 4.0.4", "thiserror 2.0.18", ] +[[package]] +name = "solana-vote-interface" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b80d57478d6599d30acc31cc5ae7f93ec2361a06aefe8ea79bc81739a08af4c3" +dependencies = [ + "bincode", + "num-derive", + "num-traits", + "serde", + "serde_derive", + "solana-clock 2.2.3", + "solana-decode-error", + "solana-hash 2.3.0", + "solana-instruction 2.3.3", + "solana-pubkey 2.4.0", + "solana-rent 2.2.1", + "solana-sdk-ids 2.2.1", + "solana-serde-varint 2.2.2", + "solana-serialize-utils 2.2.1", + "solana-short-vec 2.2.1", + "solana-system-interface 1.0.0", +] + [[package]] name = "solana-vote-interface" version = "4.0.4" @@ -10427,16 +12627,16 @@ dependencies = [ "serde", "serde_derive", "serde_with", - "solana-clock", + "solana-clock 3.1.0", "solana-hash 3.1.0", - "solana-instruction", + "solana-instruction 3.4.0", "solana-instruction-error", "solana-pubkey 3.0.0", "solana-rent 3.1.0", - "solana-sdk-ids", - "solana-serde-varint", - "solana-serialize-utils", - "solana-short-vec", + "solana-sdk-ids 3.1.0", + "solana-serde-varint 3.0.1", + "solana-serialize-utils 3.1.2", + "solana-short-vec 3.2.1", "solana-system-interface 2.0.0", ] @@ -10446,39 +12646,39 @@ version = "3.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac7f37540da27c0ec132ee1b5380ad32d98663afba7ade3581f2d963fd2f63c2" dependencies = [ - "agave-feature-set", + "agave-feature-set 3.1.12", "bincode", "log", "num-derive", "num-traits", "serde", - "solana-account", - "solana-bincode", - "solana-clock", - "solana-epoch-schedule", + "solana-account 3.4.0", + "solana-bincode 3.1.0", + "solana-clock 3.1.0", + "solana-epoch-schedule 3.1.0", "solana-hash 3.1.0", - "solana-instruction", - "solana-keypair", + "solana-instruction 3.4.0", + "solana-keypair 3.1.0", "solana-packet", "solana-program-runtime", "solana-pubkey 3.0.0", "solana-rent 3.1.0", - "solana-sdk-ids", - "solana-signer", - "solana-slot-hashes", - "solana-transaction", - "solana-transaction-context", - "solana-vote-interface", + "solana-sdk-ids 3.1.0", + "solana-signer 3.0.0", + "solana-slot-hashes 3.0.2", + "solana-transaction 3.1.0", + "solana-transaction-context 3.1.12", + "solana-vote-interface 4.0.4", "thiserror 2.0.18", ] [[package]] name = "solana-zero-copy" -version = "1.0.1" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5a91404c7de468dd80658cdb5d894ec803d1092ea6e2bfdf84eee6f07559c0d" +checksum = "8ea15126ebdc7e270c50d43884369af9f51d2308156d46a18e351522a164844d" dependencies = [ - "borsh", + "borsh 1.6.1", "bytemuck", "bytemuck_derive", ] @@ -10489,15 +12689,51 @@ version = "3.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cee65de587e6fe912668903e62f3f40c02a834f21967a18cc6c71f550c51a639" dependencies = [ - "agave-feature-set", + "agave-feature-set 3.1.12", "bytemuck", "num-derive", "num-traits", - "solana-instruction", + "solana-instruction 3.4.0", "solana-program-runtime", - "solana-sdk-ids", + "solana-sdk-ids 3.1.0", "solana-svm-log-collector", - "solana-zk-sdk", + "solana-zk-sdk 4.0.0", +] + +[[package]] +name = "solana-zk-sdk" +version = "2.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b9fc6ec37d16d0dccff708ed1dd6ea9ba61796700c3bb7c3b401973f10f63b" +dependencies = [ + "aes-gcm-siv", + "base64 0.22.1", + "bincode", + "bytemuck", + "bytemuck_derive", + "curve25519-dalek 4.1.3", + "itertools 0.12.1", + "js-sys", + "merlin", + "num-derive", + "num-traits", + "rand 0.8.6", + "serde", + "serde_derive", + "serde_json", + "sha3", + "solana-derivation-path 2.2.1", + "solana-instruction 2.3.3", + "solana-pubkey 2.4.0", + "solana-sdk-ids 2.2.1", + "solana-seed-derivable 2.2.1", + "solana-seed-phrase 2.2.1", + "solana-signature 2.3.0", + "solana-signer 2.2.1", + "subtle", + "thiserror 2.0.18", + "wasm-bindgen", + "zeroize", ] [[package]] @@ -10512,25 +12748,25 @@ dependencies = [ "bytemuck", "bytemuck_derive", "curve25519-dalek 4.1.3", - "getrandom 0.2.16", + "getrandom 0.2.17", "itertools 0.12.1", "js-sys", "merlin", "num-derive", "num-traits", - "rand 0.8.5", + "rand 0.8.6", "serde", "serde_derive", "serde_json", "sha3", - "solana-derivation-path", - "solana-instruction", + "solana-derivation-path 3.0.0", + "solana-instruction 3.4.0", "solana-pubkey 3.0.0", - "solana-sdk-ids", - "solana-seed-derivable", - "solana-seed-phrase", - "solana-signature", - "solana-signer", + "solana-sdk-ids 3.1.0", + "solana-seed-derivable 3.0.0", + "solana-seed-phrase 3.0.0", + "solana-signature 3.4.0", + "solana-signer 3.0.0", "subtle", "thiserror 2.0.18", "wasm-bindgen", @@ -10543,13 +12779,13 @@ version = "3.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56ecb5f2989632b030709c8aebdbc586a8c0f867d0ec154d0cb7feafb86f72fb" dependencies = [ - "agave-feature-set", + "agave-feature-set 3.1.12", "bytemuck", "num-derive", "num-traits", - "solana-instruction", + "solana-instruction 3.4.0", "solana-program-runtime", - "solana-sdk-ids", + "solana-sdk-ids 3.1.0", "solana-svm-log-collector", "solana-zk-token-sdk", ] @@ -10570,19 +12806,19 @@ dependencies = [ "merlin", "num-derive", "num-traits", - "rand 0.8.5", + "rand 0.8.6", "serde", "serde_json", "sha3", - "solana-curve25519", - "solana-derivation-path", - "solana-instruction", + "solana-curve25519 3.1.12", + "solana-derivation-path 3.0.0", + "solana-instruction 3.4.0", "solana-pubkey 3.0.0", - "solana-sdk-ids", - "solana-seed-derivable", - "solana-seed-phrase", - "solana-signature", - "solana-signer", + "solana-sdk-ids 3.1.0", + "solana-seed-derivable 3.0.0", + "solana-seed-phrase 3.0.0", + "solana-signature 3.4.0", + "solana-signer 3.0.0", "subtle", "thiserror 2.0.18", "zeroize", @@ -10590,18 +12826,18 @@ dependencies = [ [[package]] name = "sonic-number" -version = "0.1.0" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8a74044c092f4f43ca7a6cfd62854cf9fb5ac8502b131347c990bf22bef1dfe" +checksum = "3775c3390edf958191f1ab1e8c5c188907feebd0f3ce1604cb621f72961dbf32" dependencies = [ "cfg-if", ] [[package]] name = "sonic-rs" -version = "0.5.6" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4425ea8d66ec950e0a8f2ef52c766cc3d68d661d9a0845c353c40833179fd866" +checksum = "d971cc77a245ccf1756dbd1a87c3e7f709c0191464096510d43eec056d0f2c4f" dependencies = [ "ahash 0.8.12", "bumpalo", @@ -10610,19 +12846,19 @@ dependencies = [ "faststr", "itoa", "ref-cast", - "ryu", "serde", "simdutf8", "sonic-number", "sonic-simd", "thiserror 2.0.18", + "zmij", ] [[package]] name = "sonic-simd" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5707edbfb34a40c9f2a55fa09a49101d9fec4e0cc171ce386086bd9616f34257" +checksum = "f99e664ecd2d85a68c87e3c7a3cfe691f647ea9e835de984aba4d54a41f817d4" dependencies = [ "cfg-if", ] @@ -10661,11 +12897,23 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6433917b60441d68d99a17e121d9db0ea15a9a69c0e5afa34649cf5ba12612f" dependencies = [ - "borsh", - "solana-instruction", + "borsh 1.6.1", + "solana-instruction 3.4.0", "solana-pubkey 3.0.0", ] +[[package]] +name = "spl-discriminator" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7398da23554a31660f17718164e31d31900956054f54f52d5ec1be51cb4f4b3" +dependencies = [ + "bytemuck", + "solana-program-error 2.2.2", + "solana-sha256-hasher 2.3.0", + "spl-discriminator-derive", +] + [[package]] name = "spl-discriminator" version = "0.5.2" @@ -10673,7 +12921,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e597c5ff9ed7c74a54dbc47bae2f06e4db8c98f4356ad280200dc11878266db1" dependencies = [ "bytemuck", - "solana-program-error", + "solana-program-error 3.0.1", "solana-sha256-hasher 3.1.0", "spl-discriminator-derive", ] @@ -10702,6 +12950,29 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "spl-elgamal-registry" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce0f668975d2b0536e8a8fd60e56a05c467f06021dae037f1d0cfed0de2e231d" +dependencies = [ + "bytemuck", + "solana-program 2.3.0", + "solana-zk-sdk 2.3.13", + "spl-pod 0.5.1", + "spl-token-confidential-transfer-proof-extraction 0.2.1", +] + +[[package]] +name = "spl-generic-token" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "741a62a566d97c58d33f9ed32337ceedd4e35109a686e31b1866c5dfa56abddc" +dependencies = [ + "bytemuck", + "solana-pubkey 2.4.0", +] + [[package]] name = "spl-generic-token" version = "2.0.1" @@ -10712,14 +12983,48 @@ dependencies = [ "solana-pubkey 3.0.0", ] +[[package]] +name = "spl-memo" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f09647c0974e33366efeb83b8e2daebb329f0420149e74d3a4bd2c08cf9f7cb" +dependencies = [ + "solana-account-info 2.3.0", + "solana-instruction 2.3.3", + "solana-msg 2.2.1", + "solana-program-entrypoint 2.3.0", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", +] + [[package]] name = "spl-memo-interface" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d4e2aedd58f858337fa609af5ad7100d4a243fdaf6a40d6eb4c28c5f19505d3" +checksum = "3745d384b0afee980d43d62b66c27bdcbbd03507732b8d3626d3413cb72084f2" dependencies = [ - "solana-instruction", - "solana-pubkey 3.0.0", + "solana-instruction 3.4.0", + "solana-pubkey 4.2.0", +] + +[[package]] +name = "spl-pod" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d994afaf86b779104b4a95ba9ca75b8ced3fdb17ee934e38cb69e72afbe17799" +dependencies = [ + "borsh 1.6.1", + "bytemuck", + "bytemuck_derive", + "num-derive", + "num-traits", + "solana-decode-error", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-program-option 2.2.1", + "solana-pubkey 2.4.0", + "solana-zk-sdk 2.3.13", + "thiserror 2.0.18", ] [[package]] @@ -10728,17 +13033,137 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f9c6e142cdf1e7e77f480053ec9f0ce989890768ddf91f619b50f39d1b456f5" dependencies = [ - "borsh", + "borsh 1.6.1", "bytemuck", "bytemuck_derive", "num-derive", "num-traits", "num_enum", - "solana-program-error", - "solana-program-option", + "solana-program-error 3.0.1", + "solana-program-option 3.1.0", "solana-pubkey 3.0.0", "solana-zero-copy", - "solana-zk-sdk", + "solana-zk-sdk 4.0.0", + "thiserror 2.0.18", +] + +[[package]] +name = "spl-program-error" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d39b5186f42b2b50168029d81e58e800b690877ef0b30580d107659250da1d1" +dependencies = [ + "num-derive", + "num-traits", + "solana-program 2.3.0", + "spl-program-error-derive", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-program-error-derive" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d375dd76c517836353e093c2dbb490938ff72821ab568b545fd30ab3256b3e" +dependencies = [ + "proc-macro2", + "quote", + "sha2 0.10.9", + "syn 2.0.117", +] + +[[package]] +name = "spl-tlv-account-resolution" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd99ff1e9ed2ab86e3fd582850d47a739fec1be9f4661cba1782d3a0f26805f3" +dependencies = [ + "bytemuck", + "num-derive", + "num-traits", + "solana-account-info 2.3.0", + "solana-decode-error", + "solana-instruction 2.3.3", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "spl-discriminator 0.4.1", + "spl-pod 0.5.1", + "spl-program-error", + "spl-type-length-value 0.7.0", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-token" +version = "7.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed320a6c934128d4f7e54fe00e16b8aeaecf215799d060ae14f93378da6dc834" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive", + "num-traits", + "num_enum", + "solana-program 2.3.0", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-token-2022" +version = "7.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9048b26b0df0290f929ff91317c83db28b3ef99af2b3493dd35baa146774924c" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive", + "num-traits", + "num_enum", + "solana-program 2.3.0", + "solana-security-txt", + "solana-zk-sdk 2.3.13", + "spl-elgamal-registry", + "spl-memo", + "spl-pod 0.5.1", + "spl-token", + "spl-token-confidential-transfer-ciphertext-arithmetic", + "spl-token-confidential-transfer-proof-extraction 0.2.1", + "spl-token-confidential-transfer-proof-generation 0.3.0", + "spl-token-group-interface 0.5.0", + "spl-token-metadata-interface 0.6.0", + "spl-transfer-hook-interface", + "spl-type-length-value 0.7.0", + "thiserror 2.0.18", +] + +[[package]] +name = "spl-token-2022-interface" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62d7ae2ee6b856f8ddcbdc3b3a9f4d2141582bbe150f93e5298ee97e0251fa04" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive", + "num-traits", + "num_enum", + "solana-account-info 2.3.0", + "solana-decode-error", + "solana-instruction 2.3.3", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-program-option 2.2.1", + "solana-program-pack 2.2.1", + "solana-pubkey 2.4.0", + "solana-sdk-ids 2.2.1", + "solana-zk-sdk 2.3.13", + "spl-pod 0.5.1", + "spl-token-confidential-transfer-proof-extraction 0.4.1", + "spl-token-confidential-transfer-proof-generation 0.4.1", + "spl-token-group-interface 0.6.0", + "spl-token-metadata-interface 0.7.0", + "spl-type-length-value 0.8.0", "thiserror 2.0.18", ] @@ -10753,20 +13178,66 @@ dependencies = [ "num-derive", "num-traits", "num_enum", - "solana-account-info", - "solana-instruction", - "solana-program-error", - "solana-program-option", - "solana-program-pack", + "solana-account-info 3.1.1", + "solana-instruction 3.4.0", + "solana-program-error 3.0.1", + "solana-program-option 3.1.0", + "solana-program-pack 3.1.0", "solana-pubkey 3.0.0", - "solana-sdk-ids", - "solana-zk-sdk", - "spl-pod", - "spl-token-confidential-transfer-proof-extraction", - "spl-token-confidential-transfer-proof-generation", - "spl-token-group-interface", - "spl-token-metadata-interface", - "spl-type-length-value", + "solana-sdk-ids 3.1.0", + "solana-zk-sdk 4.0.0", + "spl-pod 0.7.3", + "spl-token-confidential-transfer-proof-extraction 0.5.1", + "spl-token-confidential-transfer-proof-generation 0.5.1", + "spl-token-group-interface 0.7.2", + "spl-token-metadata-interface 0.8.0", + "spl-type-length-value 0.9.1", + "thiserror 2.0.18", +] + +[[package]] +name = "spl-token-confidential-transfer-ciphertext-arithmetic" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "170378693c5516090f6d37ae9bad2b9b6125069be68d9acd4865bbe9fc8499fd" +dependencies = [ + "base64 0.22.1", + "bytemuck", + "solana-curve25519 2.3.13", + "solana-zk-sdk 2.3.13", +] + +[[package]] +name = "spl-token-confidential-transfer-proof-extraction" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eff2d6a445a147c9d6dd77b8301b1e116c8299601794b558eafa409b342faf96" +dependencies = [ + "bytemuck", + "solana-curve25519 2.3.13", + "solana-program 2.3.0", + "solana-zk-sdk 2.3.13", + "spl-pod 0.5.1", + "thiserror 2.0.18", +] + +[[package]] +name = "spl-token-confidential-transfer-proof-extraction" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512c85bdbbb4cbcc2038849a9e164c958b16541f252b53ea1a3933191c0a4a1a" +dependencies = [ + "bytemuck", + "solana-account-info 2.3.0", + "solana-curve25519 2.3.13", + "solana-instruction 2.3.3", + "solana-instructions-sysvar 2.2.2", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "solana-sdk-ids 2.2.1", + "solana-zk-sdk 2.3.13", + "spl-pod 0.5.1", "thiserror 2.0.18", ] @@ -10777,16 +13248,38 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879a9ebad0d77383d3ea71e7de50503554961ff0f4ef6cbca39ad126e6f6da3a" dependencies = [ "bytemuck", - "solana-account-info", - "solana-curve25519", - "solana-instruction", - "solana-instructions-sysvar", - "solana-msg", - "solana-program-error", + "solana-account-info 3.1.1", + "solana-curve25519 3.1.12", + "solana-instruction 3.4.0", + "solana-instructions-sysvar 3.0.1", + "solana-msg 3.1.0", + "solana-program-error 3.0.1", "solana-pubkey 3.0.0", - "solana-sdk-ids", - "solana-zk-sdk", - "spl-pod", + "solana-sdk-ids 3.1.0", + "solana-zk-sdk 4.0.0", + "spl-pod 0.7.3", + "thiserror 2.0.18", +] + +[[package]] +name = "spl-token-confidential-transfer-proof-generation" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e3597628b0d2fe94e7900fd17cdb4cfbb31ee35c66f82809d27d86e44b2848b" +dependencies = [ + "curve25519-dalek 4.1.3", + "solana-zk-sdk 2.3.13", + "thiserror 2.0.18", +] + +[[package]] +name = "spl-token-confidential-transfer-proof-generation" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa27b9174bea869a7ebf31e0be6890bce90b1a4288bc2bbf24bd413f80ae3fde" +dependencies = [ + "curve25519-dalek 4.1.3", + "solana-zk-sdk 2.3.13", "thiserror 2.0.18", ] @@ -10797,7 +13290,45 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0cd59fce3dc00f563c6fa364d67c3f200d278eae681f4dc250240afcfe044b1" dependencies = [ "curve25519-dalek 4.1.3", - "solana-zk-sdk", + "solana-zk-sdk 4.0.0", + "thiserror 2.0.18", +] + +[[package]] +name = "spl-token-group-interface" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d595667ed72dbfed8c251708f406d7c2814a3fa6879893b323d56a10bedfc799" +dependencies = [ + "bytemuck", + "num-derive", + "num-traits", + "solana-decode-error", + "solana-instruction 2.3.3", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "spl-discriminator 0.4.1", + "spl-pod 0.5.1", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-token-group-interface" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5597b4cd76f85ce7cd206045b7dc22da8c25516573d42d267c8d1fd128db5129" +dependencies = [ + "bytemuck", + "num-derive", + "num-traits", + "solana-decode-error", + "solana-instruction 2.3.3", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "spl-discriminator 0.4.1", + "spl-pod 0.5.1", "thiserror 2.0.18", ] @@ -10812,11 +13343,11 @@ dependencies = [ "num-traits", "num_enum", "solana-address 2.6.0", - "solana-instruction", + "solana-instruction 3.4.0", "solana-nullable", - "solana-program-error", + "solana-program-error 3.0.1", "solana-zero-copy", - "spl-discriminator", + "spl-discriminator 0.5.2", "thiserror 2.0.18", ] @@ -10831,12 +13362,54 @@ dependencies = [ "num-derive", "num-traits", "num_enum", - "solana-instruction", - "solana-program-error", - "solana-program-option", - "solana-program-pack", + "solana-instruction 3.4.0", + "solana-program-error 3.0.1", + "solana-program-option 3.1.0", + "solana-program-pack 3.1.0", "solana-pubkey 3.0.0", - "solana-sdk-ids", + "solana-sdk-ids 3.1.0", + "thiserror 2.0.18", +] + +[[package]] +name = "spl-token-metadata-interface" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfb9c89dbc877abd735f05547dcf9e6e12c00c11d6d74d8817506cab4c99fdbb" +dependencies = [ + "borsh 1.6.1", + "num-derive", + "num-traits", + "solana-borsh 2.2.1", + "solana-decode-error", + "solana-instruction 2.3.3", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "spl-discriminator 0.4.1", + "spl-pod 0.5.1", + "spl-type-length-value 0.7.0", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-token-metadata-interface" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "304d6e06f0de0c13a621464b1fd5d4b1bebf60d15ca71a44d3839958e0da16ee" +dependencies = [ + "borsh 1.6.1", + "num-derive", + "num-traits", + "solana-borsh 2.2.1", + "solana-decode-error", + "solana-instruction 2.3.3", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "spl-discriminator 0.4.1", + "spl-pod 0.5.1", + "spl-type-length-value 0.8.0", "thiserror 2.0.18", ] @@ -10846,16 +13419,77 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c467c7c3bd056f8fe60119e7ec34ddd6f23052c2fa8f1f51999098063b72676" dependencies = [ - "borsh", + "borsh 1.6.1", "num-derive", "num-traits", - "solana-borsh", - "solana-instruction", - "solana-program-error", + "solana-borsh 3.0.2", + "solana-instruction 3.4.0", + "solana-program-error 3.0.1", "solana-pubkey 3.0.0", - "spl-discriminator", - "spl-pod", - "spl-type-length-value", + "spl-discriminator 0.5.2", + "spl-pod 0.7.3", + "spl-type-length-value 0.9.1", + "thiserror 2.0.18", +] + +[[package]] +name = "spl-transfer-hook-interface" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4aa7503d52107c33c88e845e1351565050362c2314036ddf19a36cd25137c043" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive", + "num-traits", + "solana-account-info 2.3.0", + "solana-cpi 2.2.1", + "solana-decode-error", + "solana-instruction 2.3.3", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "solana-pubkey 2.4.0", + "spl-discriminator 0.4.1", + "spl-pod 0.5.1", + "spl-program-error", + "spl-tlv-account-resolution", + "spl-type-length-value 0.7.0", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-type-length-value" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba70ef09b13af616a4c987797870122863cba03acc4284f226a4473b043923f9" +dependencies = [ + "bytemuck", + "num-derive", + "num-traits", + "solana-account-info 2.3.0", + "solana-decode-error", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "spl-discriminator 0.4.1", + "spl-pod 0.5.1", + "thiserror 1.0.69", +] + +[[package]] +name = "spl-type-length-value" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d417eb548214fa822d93f84444024b4e57c13ed6719d4dcc68eec24fb481e9f5" +dependencies = [ + "bytemuck", + "num-derive", + "num-traits", + "solana-account-info 2.3.0", + "solana-decode-error", + "solana-msg 2.2.1", + "solana-program-error 2.2.2", + "spl-discriminator 0.4.1", + "spl-pod 0.5.1", "thiserror 2.0.18", ] @@ -10869,10 +13503,10 @@ dependencies = [ "num-derive", "num-traits", "num_enum", - "solana-account-info", - "solana-program-error", + "solana-account-info 3.1.1", + "solana-program-error 3.0.1", "solana-zero-copy", - "spl-discriminator", + "spl-discriminator 0.5.2", "thiserror 2.0.18", ] @@ -10905,11 +13539,11 @@ dependencies = [ [[package]] name = "strum" -version = "0.27.2" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" +checksum = "9628de9b8791db39ceda2b119bbe13134770b56c138ec1d3af810d045c04f9bd" dependencies = [ - "strum_macros 0.27.2", + "strum_macros 0.28.0", ] [[package]] @@ -10927,9 +13561,9 @@ dependencies = [ [[package]] name = "strum_macros" -version = "0.27.2" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" +checksum = "ab85eea0270ee17587ed4156089e10b9e6880ee688791d45a905f5b1ca36f664" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -11017,7 +13651,18 @@ checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ "bitflags 1.3.2", "core-foundation 0.9.4", - "system-configuration-sys", + "system-configuration-sys 0.5.0", +] + +[[package]] +name = "system-configuration" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" +dependencies = [ + "bitflags 2.11.1", + "core-foundation 0.9.4", + "system-configuration-sys 0.6.0", ] [[package]] @@ -11030,11 +13675,21 @@ dependencies = [ "libc", ] +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "sysvars" version = "0.0.0" dependencies = [ - "solana-program", + "solana-program 3.0.0", ] [[package]] @@ -11045,9 +13700,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tar" -version = "0.4.45" +version = "0.4.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22692a6476a21fa75fdfc11d452fda482af402c008cdbaf3476414e122040973" +checksum = "3f6221d9a6003c78398e3b239969f352578258df48c8eb051caadae0015bc840" dependencies = [ "filetime", "libc", @@ -11066,7 +13721,7 @@ dependencies = [ "humantime", "opentelemetry", "pin-project", - "rand 0.8.5", + "rand 0.8.6", "serde", "static_assertions", "tarpc-plugins", @@ -11097,15 +13752,15 @@ checksum = "28768569381ae187ca3e46026f5c0786c4120e146fc74bda02ab930dc1b94bd3" [[package]] name = "tempfile" -version = "3.23.0" +version = "3.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.3.4", + "getrandom 0.4.2", "once_cell", "rustix", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -11128,23 +13783,30 @@ name = "test-chainlink" version = "0.0.0" dependencies = [ "bincode", + "borsh 1.6.1", + "compressed-delegation-client", "futures", "integration-test-tools", + "light-client", + "light-hasher", + "light-sdk", "magicblock-chainlink", "magicblock-config", - "magicblock-delegation-program-api 0.3.0 (git+https://github.com/magicblock-labs/delegation-program.git?rev=25386a7c1d406d06b8d07a4d5b0fd37d5e74213b)", + "magicblock-core", + "magicblock-delegation-program-api 0.3.0", "program-flexi-counter", "program-mini", - "solana-account", - "solana-commitment-config", - "solana-loader-v2-interface", - "solana-loader-v3-interface", - "solana-loader-v4-interface", + "solana-account 3.4.0", + "solana-commitment-config 3.1.1", + "solana-compute-budget-interface 3.0.0", + "solana-loader-v2-interface 3.0.0", + "solana-loader-v3-interface 6.1.1", + "solana-loader-v4-interface 3.1.0", "solana-pubkey 3.0.0", - "solana-rpc-client", - "solana-rpc-client-api", + "solana-rpc-client 3.1.12", + "solana-rpc-client-api 3.1.12", "solana-sdk", - "solana-sdk-ids", + "solana-sdk-ids 3.1.0", "solana-system-interface 3.2.0", "spl-token-interface", "tokio", @@ -11157,10 +13819,10 @@ version = "0.0.0" dependencies = [ "integration-test-tools", "magicblock-core", - "magicblock-delegation-program-api 0.3.0 (git+https://github.com/magicblock-labs/delegation-program.git?rev=25386a7c1d406d06b8d07a4d5b0fd37d5e74213b)", + "magicblock-delegation-program-api 0.3.0", "program-flexi-counter", "program-mini", - "solana-loader-v4-interface", + "solana-loader-v4-interface 3.1.0", "solana-sdk", "solana-system-interface 3.2.0", "spl-associated-token-account-interface", @@ -11182,9 +13844,9 @@ dependencies = [ "magicblock-config", "program-flexi-counter", "serial_test", - "solana-rpc-client", + "solana-rpc-client 3.1.12", "solana-sdk", - "solana-sdk-ids", + "solana-sdk-ids 3.1.0", "solana-system-interface 3.2.0", "tempfile", "test-kit", @@ -11200,19 +13862,20 @@ dependencies = [ "magicblock-core", "magicblock-ledger", "magicblock-processor", - "solana-account", - "solana-instruction", - "solana-keypair", - "solana-program", - "solana-rpc-client", - "solana-signature", - "solana-signer", - "solana-transaction", - "solana-transaction-error", - "solana-transaction-status-client-types", + "solana-account 3.4.0", + "solana-instruction 3.4.0", + "solana-keypair 3.1.0", + "solana-program 3.0.0", + "solana-pubkey 3.0.0", + "solana-rpc-client 3.1.12", + "solana-signature 3.4.0", + "solana-signer 3.0.0", + "solana-transaction 3.1.0", + "solana-transaction-error 3.2.0", + "solana-transaction-status-client-types 3.1.12", "tempfile", "tokio", - "tokio-util 0.7.17", + "tokio-util 0.7.18", "tracing", "tracing-log", "tracing-subscriber", @@ -11227,12 +13890,12 @@ dependencies = [ "integration-test-tools", "magicblock-accounts-db", "magicblock-config", - "magicblock-delegation-program-api 0.3.0 (git+https://github.com/magicblock-labs/delegation-program.git?rev=25386a7c1d406d06b8d07a4d5b0fd37d5e74213b)", + "magicblock-delegation-program-api 0.3.0", "program-flexi-counter", - "solana-commitment-config", - "solana-rpc-client", + "solana-commitment-config 3.1.1", + "solana-rpc-client 3.1.12", "solana-sdk", - "solana-sdk-ids", + "solana-sdk-ids 3.1.0", "solana-system-interface 3.2.0", "solana-transaction-status", "tempfile", @@ -11250,12 +13913,12 @@ dependencies = [ "magic-domain-program", "magicblock-api", "magicblock-config", - "magicblock-delegation-program-api 0.3.0 (git+https://github.com/magicblock-labs/delegation-program.git?rev=25386a7c1d406d06b8d07a4d5b0fd37d5e74213b)", + "magicblock-delegation-program-api 0.3.0", "magicblock-program", "magicblock-validator-admin", - "solana-commitment-config", - "solana-rpc-client", - "solana-rpc-client-api", + "solana-commitment-config 3.1.1", + "solana-rpc-client 3.1.12", + "solana-rpc-client-api 3.1.12", "solana-sdk", "solana-system-interface 3.2.0", "solana-transaction-status", @@ -11271,8 +13934,8 @@ dependencies = [ "futures", "integration-test-tools", "solana-pubsub-client", - "solana-rpc-client", - "solana-rpc-client-api", + "solana-rpc-client 3.1.12", + "solana-rpc-client-api 3.1.12", "solana-sdk", "solana-system-interface 3.2.0", "tokio", @@ -11295,10 +13958,10 @@ dependencies = [ "ephemeral-rollups-sdk", "integration-test-tools", "log", - "magicblock-delegation-program-api 0.3.0 (git+https://github.com/magicblock-labs/delegation-program.git?rev=25386a7c1d406d06b8d07a4d5b0fd37d5e74213b)", + "magicblock-delegation-program-api 0.3.0", "magicblock-magic-program-api 0.11.1", "program-flexi-counter", - "solana-rpc-client-api", + "solana-rpc-client-api 3.1.12", "solana-sdk", "test-kit", "tracing", @@ -11311,10 +13974,10 @@ dependencies = [ "magicblock-rpc-client", "magicblock-table-mania", "paste", - "solana-address-lookup-table-interface", - "solana-commitment-config", + "solana-address-lookup-table-interface 3.1.0", + "solana-commitment-config 3.1.1", "solana-pubkey 3.0.0", - "solana-rpc-client", + "solana-rpc-client 3.1.12", "solana-sdk", "test-kit", "tokio", @@ -11334,7 +13997,7 @@ dependencies = [ "magicblock-task-scheduler", "program-flexi-counter", "program-schedulecommit", - "solana-rpc-client", + "solana-rpc-client 3.1.12", "solana-sdk", "tempfile", "tokio", @@ -11401,30 +14064,30 @@ dependencies = [ [[package]] name = "time" -version = "0.3.44" +version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" +checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" dependencies = [ "deranged", "itoa", "num-conv", "powerfmt", - "serde", + "serde_core", "time-core", "time-macros", ] [[package]] name = "time-core" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" +checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" [[package]] name = "time-macros" -version = "0.2.24" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" +checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" dependencies = [ "num-conv", "time-core", @@ -11432,9 +14095,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" dependencies = [ "displaydoc", "zerovec", @@ -11442,9 +14105,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" dependencies = [ "tinyvec_macros", ] @@ -11457,9 +14120,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.48.0" +version = "1.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" +checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" dependencies = [ "bytes", "libc", @@ -11467,16 +14130,16 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.6.1", + "socket2 0.6.3", "tokio-macros", "windows-sys 0.61.2", ] [[package]] name = "tokio-macros" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" +checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" dependencies = [ "proc-macro2", "quote", @@ -11509,7 +14172,7 @@ version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ - "rustls 0.23.35", + "rustls 0.23.40", "tokio", ] @@ -11531,14 +14194,14 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" +checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" dependencies = [ "futures-core", "pin-project-lite", "tokio", - "tokio-util 0.7.17", + "tokio-util 0.7.18", ] [[package]] @@ -11549,7 +14212,7 @@ checksum = "d25a406cddcc431a75d3d9afc6a7c0f7428d4891dd973e4d54c56b46127bf857" dependencies = [ "futures-util", "log", - "rustls 0.23.35", + "rustls 0.23.40", "rustls-pki-types", "tokio", "tokio-rustls 0.26.4", @@ -11574,16 +14237,16 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.17" +version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594" +checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" dependencies = [ "bytes", "futures-core", "futures-io", "futures-sink", "futures-util", - "hashbrown 0.15.2", + "hashbrown 0.15.5", "pin-project-lite", "slab", "tokio", @@ -11601,15 +14264,24 @@ dependencies = [ "futures-sink", "http 1.4.0", "httparse", - "rand 0.8.5", + "rand 0.8.6", "ring", "rustls-pki-types", "tokio", "tokio-rustls 0.26.4", - "tokio-util 0.7.17", + "tokio-util 0.7.18", "webpki-roots 0.26.11", ] +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + [[package]] name = "toml" version = "0.8.23" @@ -11633,9 +14305,9 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.7.3" +version = "1.1.1+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" dependencies = [ "serde_core", ] @@ -11646,33 +14318,33 @@ version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ - "indexmap 2.12.1", + "indexmap 2.14.0", "serde", "serde_spanned", "toml_datetime 0.6.11", "toml_write", - "winnow", + "winnow 0.7.15", ] [[package]] name = "toml_edit" -version = "0.23.9" +version = "0.25.11+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d7cbc3b4b49633d57a0509303158ca50de80ae32c265093b24c414705807832" +checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b" dependencies = [ - "indexmap 2.12.1", - "toml_datetime 0.7.3", + "indexmap 2.14.0", + "toml_datetime 1.1.1+spec-1.1.0", "toml_parser", - "winnow", + "winnow 1.0.3", ] [[package]] name = "toml_parser" -version = "1.0.4" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" +checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" dependencies = [ - "winnow", + "winnow 1.0.3", ] [[package]] @@ -11693,11 +14365,11 @@ dependencies = [ "base64 0.22.1", "bytes", "flate2", - "h2 0.4.12", + "h2 0.4.14", "http 1.4.0", "http-body 1.0.1", "http-body-util", - "hyper 1.8.1", + "hyper 1.9.0", "hyper-timeout", "hyper-util", "percent-encoding", @@ -11717,31 +14389,31 @@ dependencies = [ [[package]] name = "tonic" -version = "0.14.5" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fec7c61a0695dc1887c1b53952990f3ad2e3a31453e1f49f10e75424943a93ec" +checksum = "ac2a5518c70fa84342385732db33fb3f44bc4cc748936eb5833d2df34d6445ef" dependencies = [ "async-trait", - "axum 0.8.8", + "axum 0.8.9", "base64 0.22.1", "bytes", "flate2", - "h2 0.4.12", + "h2 0.4.14", "http 1.4.0", "http-body 1.0.1", "http-body-util", - "hyper 1.8.1", + "hyper 1.9.0", "hyper-timeout", "hyper-util", "percent-encoding", "pin-project", - "rustls-native-certs 0.8.2", - "socket2 0.6.1", + "rustls-native-certs 0.8.3", + "socket2 0.6.3", "sync_wrapper 1.0.2", "tokio", "tokio-rustls 0.26.4", "tokio-stream", - "tower 0.5.2", + "tower 0.5.3", "tower-layer", "tower-service", "tracing", @@ -11763,9 +14435,9 @@ dependencies = [ [[package]] name = "tonic-build" -version = "0.14.5" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1882ac3bf5ef12877d7ed57aad87e75154c11931c2ba7e6cde5e22d63522c734" +checksum = "c68f61875ac5293cf72e6c8cf0158086428c82c37229e98c840878f1706b0322" dependencies = [ "prettyplease", "proc-macro2", @@ -11775,33 +14447,33 @@ dependencies = [ [[package]] name = "tonic-health" -version = "0.14.5" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4ff0636fef47afb3ec02818f5bceb4377b8abb9d6a386aeade18bd6212f8eb7" +checksum = "fcfab99db777fba2802f0dfa861d1628d1ae916fb199d29819941f139ae85082" dependencies = [ "prost 0.14.3", "tokio", "tokio-stream", - "tonic 0.14.5", + "tonic 0.14.6", "tonic-prost", ] [[package]] name = "tonic-prost" -version = "0.14.5" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a55376a0bbaa4975a3f10d009ad763d8f4108f067c7c2e74f3001fb49778d309" +checksum = "50849f68853be452acf590cde0b146665b8d507b3b8af17261df47e02c209ea0" dependencies = [ "bytes", "prost 0.14.3", - "tonic 0.14.5", + "tonic 0.14.6", ] [[package]] name = "tonic-prost-build" -version = "0.14.5" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3144df636917574672e93d0f56d7edec49f90305749c668df5101751bb8f95a" +checksum = "654e5643eff75d7f8c99197ce1440ed19a3474eada74c12bbac488b2cafdae27" dependencies = [ "prettyplease", "proc-macro2", @@ -11810,7 +14482,7 @@ dependencies = [ "quote", "syn 2.0.117", "tempfile", - "tonic-build 0.14.5", + "tonic-build 0.14.6", ] [[package]] @@ -11824,10 +14496,10 @@ dependencies = [ "indexmap 1.9.3", "pin-project", "pin-project-lite", - "rand 0.8.5", + "rand 0.8.6", "slab", "tokio", - "tokio-util 0.7.17", + "tokio-util 0.7.18", "tower-layer", "tower-service", "tracing", @@ -11835,18 +14507,18 @@ dependencies = [ [[package]] name = "tower" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" dependencies = [ "futures-core", "futures-util", - "indexmap 2.12.1", + "indexmap 2.14.0", "pin-project-lite", "slab", "sync_wrapper 1.0.2", "tokio", - "tokio-util 0.7.17", + "tokio-util 0.7.18", "tower-layer", "tower-service", "tracing", @@ -11854,25 +14526,25 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.8" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" dependencies = [ "async-compression", - "bitflags 2.10.0", + "bitflags 2.11.1", "bytes", "futures-core", "futures-util", "http 1.4.0", "http-body 1.0.1", "http-body-util", - "iri-string", "pin-project-lite", "tokio", - "tokio-util 0.7.17", - "tower 0.5.2", + "tokio-util 0.7.18", + "tower 0.5.3", "tower-layer", "tower-service", + "url", ] [[package]] @@ -11889,9 +14561,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.43" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d15d90a0b5c19378952d479dc858407149d7bb45a14de0142f6c534b16fc647" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ "log", "pin-project-lite", @@ -11912,9 +14584,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.35" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a04e24fab5c89c6a36eb8558c9656f30d81de51dfa4d3b45f26b21d61fa0a6c" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ "once_cell", "valuable", @@ -11946,9 +14618,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.22" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" +checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" dependencies = [ "matchers", "nu-ansi-term", @@ -11990,8 +14662,8 @@ dependencies = [ "http 1.4.0", "httparse", "log", - "rand 0.9.2", - "rustls 0.23.35", + "rand 0.9.4", + "rustls 0.23.40", "rustls-pki-types", "sha1", "thiserror 2.0.18", @@ -12013,9 +14685,9 @@ checksum = "8e28f89b80c87b8fb0cf04ab448d5dd0dd0ade2f8891bae878de66a75a28600e" [[package]] name = "typenum" -version = "1.19.0" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" +checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" [[package]] name = "uncased" @@ -12028,21 +14700,21 @@ dependencies = [ [[package]] name = "unicase" -version = "2.8.1" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" +checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" [[package]] name = "unicode-ident" -version = "1.0.22" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "unicode-segmentation" -version = "1.12.0" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" +checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" [[package]] name = "unicode-width" @@ -12068,7 +14740,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" dependencies = [ - "crypto-common", + "crypto-common 0.1.7", "subtle", ] @@ -12103,7 +14775,7 @@ dependencies = [ "flate2", "log", "once_cell", - "rustls 0.23.35", + "rustls 0.23.40", "rustls-pki-types", "url", "webpki-roots 0.26.11", @@ -12111,22 +14783,22 @@ dependencies = [ [[package]] name = "ureq" -version = "3.2.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc97a28575b85cfedf2a7e7d3cc64b3e11bd8ac766666318003abbacc7a21fc" +checksum = "dea7109cdcd5864d4eeb1b58a1648dc9bf520360d7af16ec26d0a9354bafcfc0" dependencies = [ "base64 0.22.1", "log", "percent-encoding", "ureq-proto", - "utf-8", + "utf8-zero", ] [[package]] name = "ureq-proto" -version = "0.5.3" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d81f9efa9df032be5934a46a068815a10a042b494b6a58cb0a1a97bb5467ed6f" +checksum = "e994ba84b0bd1b1b0cf92878b7ef898a5c1760108fe7b6010327e274917a808c" dependencies = [ "base64 0.22.1", "http 1.4.0", @@ -12146,14 +14818,15 @@ dependencies = [ [[package]] name = "url" -version = "2.5.7" +version = "2.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" dependencies = [ "form_urlencoded", "idna", "percent-encoding", "serde", + "serde_derive", ] [[package]] @@ -12162,6 +14835,12 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf8-zero" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8c0a043c9540bae7c578c88f91dda8bd82e59ae27c21baca69c8b191aaf5a6e" + [[package]] name = "utf8_iter" version = "1.0.4" @@ -12176,11 +14855,11 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.19.0" +version = "1.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" +checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76" dependencies = [ - "getrandom 0.3.4", + "getrandom 0.4.2", "js-sys", "wasm-bindgen", ] @@ -12242,18 +14921,27 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.1+wasi-0.2.4" +version = "1.0.3+wasi-0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" +dependencies = [ + "wit-bindgen 0.57.1", +] + +[[package]] +name = "wasip3" +version = "0.4.0+wasi-0.3.0-rc-2026-01-06" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" dependencies = [ - "wit-bindgen", + "wit-bindgen 0.51.0", ] [[package]] name = "wasm-bindgen" -version = "0.2.106" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" +checksum = "49ace1d07c165b0864824eee619580c4689389afa9dc9ed3a4c75040d82e6790" dependencies = [ "cfg-if", "once_cell", @@ -12264,22 +14952,19 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.56" +version = "0.4.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c" +checksum = "96492d0d3ffba25305a7dc88720d250b1401d7edca02cc3bcd50633b424673b8" dependencies = [ - "cfg-if", "js-sys", - "once_cell", "wasm-bindgen", - "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.106" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" +checksum = "8e68e6f4afd367a562002c05637acb8578ff2dea1943df76afb9e83d177c8578" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -12287,9 +14972,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.106" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" +checksum = "d95a9ec35c64b2a7cb35d3fead40c4238d0940c86d107136999567a4703259f2" dependencies = [ "bumpalo", "proc-macro2", @@ -12300,18 +14985,65 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.106" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" +checksum = "c4e0100b01e9f0d03189a92b96772a1fb998639d981193d7dbab487302513441" dependencies = [ "unicode-ident", ] +[[package]] +name = "wasm-encoder" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +dependencies = [ + "leb128fmt", + "wasmparser", +] + +[[package]] +name = "wasm-metadata" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +dependencies = [ + "anyhow", + "indexmap 2.14.0", + "wasm-encoder", + "wasmparser", +] + +[[package]] +name = "wasm-streams" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1ec4f6517c9e11ae630e200b2b65d193279042e28edd4a2cda233e46670bbb" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "wasmparser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +dependencies = [ + "bitflags 2.11.1", + "hashbrown 0.15.5", + "indexmap 2.14.0", + "semver", +] + [[package]] name = "web-sys" -version = "0.3.83" +version = "0.3.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac" +checksum = "4b572dff8bcf38bad0fa19729c89bb5748b2b9b1d8be70cf90df697e3a8f32aa" dependencies = [ "js-sys", "wasm-bindgen", @@ -12329,9 +15061,9 @@ dependencies = [ [[package]] name = "webpki-root-certs" -version = "1.0.4" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee3e3b5f5e80bc89f30ce8d0343bf4e5f12341c51f3e26cbeecbc7c85443e85b" +checksum = "f31141ce3fc3e300ae89b78c0dd67f9708061d1d2eda54b8209346fd6be9a92c" dependencies = [ "rustls-pki-types", ] @@ -12348,14 +15080,14 @@ version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" dependencies = [ - "webpki-roots 1.0.4", + "webpki-roots 1.0.7", ] [[package]] name = "webpki-roots" -version = "1.0.4" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2878ef029c47c6e8cf779119f20fcf52bde7ad42a731b2a304bc221df17571e" +checksum = "52f5ee44c96cf55f1b349600768e3ece3a8f26010c05265ab73f945bb1a2eb9d" dependencies = [ "rustls-pki-types", ] @@ -12382,7 +15114,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.61.2", ] [[package]] @@ -12393,22 +15125,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "wincode" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "466e67917609b2d40a838a5b972d1a6237c9749600cb8de8f65559b90d48485b" -dependencies = [ - "pastey", - "proc-macro2", - "quote", - "thiserror 2.0.18", - "wincode-derive", -] - -[[package]] -name = "wincode" -version = "0.5.1" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a61f8f0a55eb6cae5d7b7ad2eca536a944deb9722a948525181069064ecd1abc" +checksum = "37095eb18dd6254c66217edc61a29d83d51f8818de8a2ffe88e4584ad73fb5f9" dependencies = [ "pastey", "proc-macro2", @@ -12419,11 +15138,11 @@ dependencies = [ [[package]] name = "wincode-derive" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fca057fc9a13dd19cdb64ef558635d43c42667c0afa1ae7915ea1fa66993fd1a" +checksum = "e262d55d1261f31e2cfe49cc6385a421d14d99faa0526bbe3cc1bda0d3005c62" dependencies = [ - "darling", + "darling 0.21.3", "proc-macro2", "quote", "syn 2.0.117", @@ -12849,9 +15568,18 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winnow" -version = "0.7.14" +version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" +checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" +dependencies = [ + "memchr", +] + +[[package]] +name = "winnow" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" dependencies = [ "memchr", ] @@ -12868,15 +15596,103 @@ dependencies = [ [[package]] name = "wit-bindgen" -version = "0.46.0" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +dependencies = [ + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + +[[package]] +name = "wit-bindgen-core" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +dependencies = [ + "anyhow", + "heck 0.5.0", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +dependencies = [ + "anyhow", + "heck 0.5.0", + "indexmap 2.14.0", + "prettyplease", + "syn 2.0.117", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn 2.0.117", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +dependencies = [ + "anyhow", + "bitflags 2.11.1", + "indexmap 2.14.0", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" +checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +dependencies = [ + "anyhow", + "id-arena", + "indexmap 2.14.0", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser", +] [[package]] name = "writeable" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" +checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" [[package]] name = "wyz" @@ -12923,9 +15739,9 @@ checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" [[package]] name = "yoke" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" dependencies = [ "stable_deref_trait", "yoke-derive", @@ -12934,9 +15750,9 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", "quote", @@ -12946,18 +15762,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.31" +version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3" +checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.31" +version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a" +checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" dependencies = [ "proc-macro2", "quote", @@ -12966,18 +15782,18 @@ dependencies = [ [[package]] name = "zerofrom" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", "quote", @@ -12996,9 +15812,9 @@ dependencies = [ [[package]] name = "zeroize_derive" -version = "1.4.2" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" dependencies = [ "proc-macro2", "quote", @@ -13007,9 +15823,9 @@ dependencies = [ [[package]] name = "zerotrie" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" dependencies = [ "displaydoc", "yoke", @@ -13018,9 +15834,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.5" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" dependencies = [ "yoke", "zerofrom", @@ -13029,9 +15845,9 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" dependencies = [ "proc-macro2", "quote", @@ -13040,13 +15856,13 @@ dependencies = [ [[package]] name = "zip" -version = "7.2.0" +version = "8.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42e33efc22a0650c311c2ef19115ce232583abbe80850bc8b66509ebef02de0" +checksum = "2d04a6b5381502aa6087c94c669499eb1602eb9c5e8198e534de571f7154809b" dependencies = [ "crc32fast", "flate2", - "indexmap 2.12.1", + "indexmap 2.14.0", "memchr", "typed-path", "zopfli", @@ -13054,9 +15870,15 @@ dependencies = [ [[package]] name = "zlib-rs" -version = "0.5.5" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be3d40e40a133f9c916ee3f9f4fa2d9d63435b5fbe1bfc6d9dae0aa0ada1513" + +[[package]] +name = "zmij" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40990edd51aae2c2b6907af74ffb635029d5788228222c4bb811e9351c0caad3" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" [[package]] name = "zopfli" diff --git a/test-integration/Cargo.toml b/test-integration/Cargo.toml index 6178a48cf..fe93f2b42 100644 --- a/test-integration/Cargo.toml +++ b/test-integration/Cargo.toml @@ -19,7 +19,7 @@ members = [ "test-schedule-intent", "test-table-mania", "test-task-scheduler", - "test-tools" + "test-tools", ] resolver = "2" @@ -35,21 +35,30 @@ borsh = { version = "1.2.1", features = ["derive", "unstable__schema"] } chrono = "0.4" cleanass = "0.0.1" color-backtrace = { version = "0.7" } +compressed-delegation-api = { path = "../compressed-delegation-api" } +compressed-delegation-client = { path = "../compressed-delegation-client" } ctrlc = "3.4.7" -ephemeral-rollups-sdk = { git = "https://github.com/magicblock-labs/ephemeral-rollups-sdk.git", rev = "ccfc9f924dc40", default-features = false, features = [ - "disable-realloc", - "modular-sdk" +ephemeral-rollups-sdk = { git = "https://github.com/magicblock-labs/ephemeral-rollups-sdk.git", rev = "01abca6e74631a10376c014bcc843ab168a8ba95", features = [ + "modular-sdk", ] } futures = "0.3.31" integration-test-tools = { path = "test-tools" } isocountry = "0.3.2" lazy_static = "1.4.0" +light-client = "0.23" +light-hasher = "5" +light-sdk = "0.23" +light-sdk-types = "0.23" magic-domain-program = { git = "https://github.com/magicblock-labs/magic-domain-program.git", rev = "335a22", default-features = false } -magicblock-accounts-db = { path = "../magicblock-accounts-db", features = ["dev-tools"] } +magicblock-accounts-db = { path = "../magicblock-accounts-db", features = [ + "dev-tools", +] } magicblock-api = { path = "../magicblock-api" } -magicblock-chainlink = { path = "../magicblock-chainlink", features = ["dev-context"] } +magicblock-chainlink = { path = "../magicblock-chainlink", features = [ + "dev-context", +] } magicblock-committor-program = { path = "../magicblock-committor-program", features = [ - "no-entrypoint" + "no-entrypoint", ] } magicblock-committor-service = { path = "../magicblock-committor-service" } magicblock-config = { path = "../magicblock-config" } @@ -70,6 +79,7 @@ rkyv = "0.7.45" schedulecommit-client = { path = "schedulecommit/client" } serde = "1.0.217" serial_test = "3.2.0" +shlex = "1.3.0" solana-account = { git = "https://github.com/magicblock-labs/magicblock-svm.git", rev = "5bd1d56" } solana-address-lookup-table-interface = "3.1" solana-commitment-config = "3.1.1" diff --git a/test-integration/configs/chainlink-conf.devnet.toml b/test-integration/configs/chainlink-conf.devnet.toml index 171c4d3f2..1f00f35cb 100644 --- a/test-integration/configs/chainlink-conf.devnet.toml +++ b/test-integration/configs/chainlink-conf.devnet.toml @@ -47,5 +47,12 @@ id = "MiniV31111111111111111111111111111111111111" path = "../target/deploy/miniv3/program_mini.so" auth = "MiniV3AUTH111111111111111111111111111111111" +[[programs]] +id = "DEL2rPzhFaS5qzo8XY9ZNxSzuunWueySq3p2dxJfwPbT" +path = "../programs/compressed_delegation/compressed_delegation.so" + +[compression] +photon-url = "http://localhost:8784" + [metrics] address = "0.0.0.0:9000" # Default if not specified, was disabled before but struct requires address diff --git a/test-integration/configs/committor-conf.devnet.toml b/test-integration/configs/committor-conf.devnet.toml index 97f871b0d..04d74de3a 100644 --- a/test-integration/configs/committor-conf.devnet.toml +++ b/test-integration/configs/committor-conf.devnet.toml @@ -43,6 +43,13 @@ path = "../target/deploy/program_schedulecommit.so" id = "f1exzKGtdeVX3d6UXZ89cY7twiNJe9S5uq84RTA4Rq4" path = "../target/deploy/program_flexi_counter.so" +[[programs]] +id = "DEL2rPzhFaS5qzo8XY9ZNxSzuunWueySq3p2dxJfwPbT" +path = "../programs/compressed_delegation/compressed_delegation.so" + +[compression] +photon-url = "http://localhost:8784" + [geyser-grpc] port = 10001 diff --git a/test-integration/configs/schedulecommit-conf-fees.ephem.toml b/test-integration/configs/schedulecommit-conf-fees.ephem.toml index 04a62c568..8f7265759 100644 --- a/test-integration/configs/schedulecommit-conf-fees.ephem.toml +++ b/test-integration/configs/schedulecommit-conf-fees.ephem.toml @@ -36,5 +36,8 @@ path = "test-integration/target/deploy/program_schedulecommit.so" id = "4RaQH3CUBMSMQsSHPVaww2ifeNEEuaDZjF9CUdFwr3xr" path = "test-integration/target/deploy/program_schedulecommit_security.so" +[compression] +photon-url = "http://localhost:8784" + [metrics] address = "0.0.0.0:9000" diff --git a/test-integration/configs/schedulecommit-conf.devnet.toml b/test-integration/configs/schedulecommit-conf.devnet.toml index 9da9049ca..95e792e3c 100644 --- a/test-integration/configs/schedulecommit-conf.devnet.toml +++ b/test-integration/configs/schedulecommit-conf.devnet.toml @@ -48,5 +48,16 @@ path = "../target/deploy/program_schedulecommit.so" id = "4RaQH3CUBMSMQsSHPVaww2ifeNEEuaDZjF9CUdFwr3xr" path = "../target/deploy/program_schedulecommit_security.so" +[[programs]] +id = "f1exzKGtdeVX3d6UXZ89cY7twiNJe9S5uq84RTA4Rq4" +path = "../target/deploy/program_flexi_counter.so" + +[[programs]] +id = "DEL2rPzhFaS5qzo8XY9ZNxSzuunWueySq3p2dxJfwPbT" +path = "../programs/compressed_delegation/compressed_delegation.so" + +[compression] +photon-url = "http://localhost:8784" + [metrics] address = "0.0.0.0:9000" diff --git a/test-integration/programs/compressed_delegation/compressed_delegation.so b/test-integration/programs/compressed_delegation/compressed_delegation.so new file mode 100755 index 000000000..6b0090a5a Binary files /dev/null and b/test-integration/programs/compressed_delegation/compressed_delegation.so differ diff --git a/test-integration/programs/flexi-counter/Cargo.toml b/test-integration/programs/flexi-counter/Cargo.toml index 4e9f424a4..cbdf5cd36 100644 --- a/test-integration/programs/flexi-counter/Cargo.toml +++ b/test-integration/programs/flexi-counter/Cargo.toml @@ -6,11 +6,16 @@ version.workspace = true [dependencies] bincode = { workspace = true } borsh = { workspace = true } +compressed-delegation-api = { workspace = true } +compressed-delegation-client = { workspace = true } ephemeral-rollups-sdk = { workspace = true } +light-hasher = { workspace = true } +light-sdk = { workspace = true, features = ["v2"] } +light-sdk-types = { workspace = true, features = ["v2"] } magicblock-magic-program-api = { workspace = true } serde = { workspace = true } solana-program = { workspace = true } -solana-system-interface = { workspace = true } +solana-system-interface = { workspace = true, features = ["bincode"] } [lib] crate-type = ["cdylib", "lib"] diff --git a/test-integration/programs/flexi-counter/src/instruction.rs b/test-integration/programs/flexi-counter/src/instruction.rs index 795458892..b8182fd85 100644 --- a/test-integration/programs/flexi-counter/src/instruction.rs +++ b/test-integration/programs/flexi-counter/src/instruction.rs @@ -1,4 +1,7 @@ use borsh::{BorshDeserialize, BorshSerialize}; +use compressed_delegation_api::instruction::{ + CdpCompressedAccountMeta, CdpPackedAddressTreeInfo, CdpValidityProof, +}; use ephemeral_rollups_sdk::{ consts::{MAGIC_CONTEXT_ID, MAGIC_PROGRAM_ID}, delegate_args::{DelegateAccountMetas, DelegateAccounts}, @@ -32,6 +35,20 @@ pub struct CancelArgs { pub task_id: i64, } +#[derive(BorshSerialize, BorshDeserialize, Debug, Clone)] +pub struct InitDelegationRecordArgs { + pub validity_proof: CdpValidityProof, + pub address_tree_info: CdpPackedAddressTreeInfo, + pub output_state_tree_index: u8, +} + +#[derive(BorshSerialize, BorshDeserialize, Debug, Clone)] +pub struct DelegateCompressedArgs { + pub validator: Option, + pub validity_proof: CdpValidityProof, + pub account_meta: CdpCompressedAccountMeta, +} + pub const MAX_ACCOUNT_ALLOC_PER_INSTRUCTION_SIZE: u16 = 10_240; /// The counter has both mul and add instructions in order to facilitate tests where @@ -267,6 +284,38 @@ pub enum FlexiCounterInstruction { num_commit: u8, num_commit_finalize: u8, }, + + /// Initializes a compressed delegation record for the FlexiCounter account + /// + /// Accounts: + /// 0. `[signer]` The payer that is initializing the delegation record. + /// 1. `[write]` The counter PDA account that will be initialized. + /// 2. `[]` The compressed delegation program id + /// 3. `[]` The CPI signer of the compressed delegation program + /// 4. `[]` The system program + /// + /// 5..N `[]` Remaining accounts using by the Light program + InitCompressedDelegationRecord(InitDelegationRecordArgs), + + /// Compressed delegation of the FlexiCounter account to an ephemaral validator + /// + /// Accounts: + /// 0. `[signer]` The payer that is delegating the account. + /// 1. `[write]` The counter PDA account that will be delegated. + /// 2. `[]` The compressed delegation program id + /// 3. `[]` The CPI signer of the compressed delegation program + /// + /// 4..N `[]` Remaining accounts using by the Light program + DelegateCompressed(DelegateCompressedArgs), + + /// Commits the compressed FlexiCounter + /// + /// Accounts: + /// 0. `[signer]` The payer that created the account. + /// 1. `[write]` The counter PDA account that will be updated. + /// 2. `[]` MagicContext (used to record scheduled commit) + /// 3. `[]` MagicBlock Program (used to schedule commit) + ScheduleCommitCompressed, } pub fn create_init_ix(payer: Pubkey, label: String) -> Instruction { @@ -687,3 +736,65 @@ pub fn create_intent_bundle_commit_and_finalize_ix( accounts, ) } +pub fn create_init_compressed_delegation_record_ix( + payer: Pubkey, + remaining_accounts: &[AccountMeta], + args: InitDelegationRecordArgs, +) -> Instruction { + let program_id = &crate::id(); + let (pda, _) = FlexiCounter::pda(&payer); + let mut accounts = vec![ + AccountMeta::new(payer, true), + AccountMeta::new(pda, false), + AccountMeta::new_readonly(compressed_delegation_api::ID, false), + ]; + accounts.extend(remaining_accounts.iter().cloned()); + Instruction::new_with_borsh( + *program_id, + &FlexiCounterInstruction::InitCompressedDelegationRecord(args), + accounts, + ) +} + +pub fn create_delegate_compressed_ix( + payer: Pubkey, + remaining_accounts: &[AccountMeta], + args: DelegateCompressedArgs, +) -> Instruction { + let program_id = &crate::id(); + let (pda, _) = FlexiCounter::pda(&payer); + let mut accounts = vec![ + AccountMeta::new(payer, true), + AccountMeta::new(pda, false), + AccountMeta::new_readonly(compressed_delegation_api::ID, false), + ]; + accounts.extend(remaining_accounts.iter().cloned()); + Instruction::new_with_borsh( + *program_id, + &FlexiCounterInstruction::DelegateCompressed(args), + accounts, + ) +} + +pub fn create_schedule_commit_compressed_ix( + payer: &Pubkey, + validator: &Pubkey, +) -> Instruction { + let program_id = &crate::id(); + let (pda, _) = FlexiCounter::pda(payer); + let accounts = vec![ + AccountMeta::new(*payer, true), + AccountMeta::new(pda, false), + AccountMeta::new(MAGIC_CONTEXT_ID, false), + AccountMeta::new_readonly(MAGIC_PROGRAM_ID, false), + AccountMeta::new( + dlp_api::pda::magic_fee_vault_pda_from_validator(validator), + false, + ), + ]; + Instruction::new_with_borsh( + *program_id, + &FlexiCounterInstruction::ScheduleCommitCompressed, + accounts, + ) +} diff --git a/test-integration/programs/flexi-counter/src/processor.rs b/test-integration/programs/flexi-counter/src/processor.rs index 6e4a6b6fb..754e72407 100644 --- a/test-integration/programs/flexi-counter/src/processor.rs +++ b/test-integration/programs/flexi-counter/src/processor.rs @@ -4,12 +4,21 @@ mod schedule_intent; mod transfer_intent; use borsh::{to_vec, BorshDeserialize}; +use compressed_delegation_api::{ + ExternalUndelegateArgs, EXTERNAL_UNDELEGATE_DISCRIMINATOR_COMPRESSED, +}; use ephemeral_rollups_sdk::{ - consts::{EXTERNAL_UNDELEGATE_DISCRIMINATOR, MAGIC_PROGRAM_ID}, + consts::{ + DEFAULT_VALIDATOR_IDENTITY, EXTERNAL_UNDELEGATE_DISCRIMINATOR, + MAGIC_PROGRAM_ID, + }, cpi::{ delegate_account, undelegate_account, DelegateAccounts, DelegateConfig, }, - ephem::{commit_accounts, commit_and_undelegate_accounts}, + ephem::{ + commit_accounts, commit_and_undelegate_accounts, FoldableIntentBuilder, + MagicIntentBundleBuilder, + }, }; use magicblock_magic_program_api::{ args::ScheduleTaskArgs, instruction::MagicBlockInstruction, @@ -30,7 +39,8 @@ use solana_system_interface::instruction as system_instruction; use crate::{ instruction::{ create_add_error_ix, create_add_ix, create_add_unsigned_ix, CancelArgs, - DelegateArgs, FlexiCounterInstruction, ScheduleArgs, + DelegateArgs, DelegateCompressedArgs, FlexiCounterInstruction, + InitDelegationRecordArgs, ScheduleArgs, MAX_ACCOUNT_ALLOC_PER_INSTRUCTION_SIZE, }, processor::{ @@ -67,6 +77,11 @@ pub fn process( if disc == TRANSFER_CALLBACK_DISCRIMINATOR { return process_transfer_callback(accounts, data); } + + if disc == EXTERNAL_UNDELEGATE_DISCRIMINATOR_COMPRESSED { + let args = ExternalUndelegateArgs::try_from_slice(data)?; + return process_external_undelegate_compressed(accounts, args); + } } let ix = FlexiCounterInstruction::try_from_slice(instruction_data)?; @@ -148,6 +163,13 @@ pub fn process( TransferActionHandler { amount, fail } => { process_transfer_action_handler(accounts, amount, fail) } + InitCompressedDelegationRecord(args) => { + process_init_compressed_delegation_record(accounts, args) + } + DelegateCompressed(args) => process_delegate_compressed(accounts, args), + ScheduleCommitCompressed => { + process_schedule_commit_compressed(accounts) + } }?; Ok(()) } @@ -555,3 +577,237 @@ fn process_cancel_task( Ok(()) } + +fn process_init_compressed_delegation_record( + accounts: &[AccountInfo], + args: InitDelegationRecordArgs, +) -> ProgramResult { + msg!("InitCompressedDelegationRecord"); + + let [payer_info, counter_pda_info, compressed_delegation_program_info, remaining_accounts @ ..] = + accounts + else { + return Err(ProgramError::NotEnoughAccountKeys); + }; + + if compressed_delegation_program_info + .key + .ne(&compressed_delegation_client::ID) + { + return Err(ProgramError::IncorrectProgramId); + } + + let pda_seeds = FlexiCounter::seeds(payer_info.key); + let (counter_pda, bump) = FlexiCounter::pda(payer_info.key); + if counter_pda_info.key.ne(&counter_pda) { + msg!( + "Invalid counter PDA {}, should be {}", + counter_pda_info.key, + counter_pda + ); + return Err(ProgramError::InvalidSeeds); + } + + // Cpi into delegation program + let bump_slice = &[bump]; + let signer_seeds = + FlexiCounter::seeds_with_bump(payer_info.key, bump_slice); + let signer = [signer_seeds.as_ref()]; + compressed_delegation_client::cpi::InitDelegationRecordCpi { + payer: payer_info.clone(), + delegated_account: counter_pda_info.clone(), + remaining_accounts: remaining_accounts + .iter() + .map(|account| { + (account.clone(), account.is_signer, account.is_writable) + }) + .collect(), + args: compressed_delegation_client::InitDelegationRecordArgs { + owner_program_id: crate::ID, + pda_seeds: pda_seeds + .iter() + .map(|seed| seed.to_vec()) + .collect::>(), + bump, + output_state_tree_index: args.output_state_tree_index, + address_tree_info: args.address_tree_info, + validity_proof: args.validity_proof, + }, + } + .invoke_signed(&signer)?; + + Ok(()) +} + +fn process_delegate_compressed( + accounts: &[AccountInfo], + args: DelegateCompressedArgs, +) -> ProgramResult { + msg!("DelegateCompressed"); + + let [payer_info, counter_pda_info, compressed_delegation_program_info, remaining_accounts @ ..] = + accounts + else { + return Err(ProgramError::NotEnoughAccountKeys); + }; + + if compressed_delegation_program_info + .key + .ne(&compressed_delegation_client::ID) + { + return Err(ProgramError::IncorrectProgramId); + } + + let pda_seeds = FlexiCounter::seeds(payer_info.key); + let (counter_pda, bump) = FlexiCounter::pda(payer_info.key); + if counter_pda_info.key.ne(&counter_pda) { + msg!( + "Invalid counter PDA {}, should be {}", + counter_pda_info.key, + counter_pda + ); + return Err(ProgramError::InvalidSeeds); + } + + // Close the counter + let account_data = { counter_pda_info.data.borrow().to_vec() }; + counter_pda_info.resize(0)?; + **payer_info.try_borrow_mut_lamports()? += counter_pda_info.lamports(); + **counter_pda_info.try_borrow_mut_lamports()? = 0; + + // Cpi into delegation program + let bump_slice = &[bump]; + let signer_seeds = + FlexiCounter::seeds_with_bump(payer_info.key, bump_slice); + let signer = [signer_seeds.as_ref()]; + compressed_delegation_client::cpi::DelegateCpi { + payer: payer_info.clone(), + delegated_account: counter_pda_info.clone(), + remaining_accounts: remaining_accounts + .iter() + .map(|account| { + (account.clone(), account.is_signer, account.is_writable) + }) + .collect(), + args: compressed_delegation_client::DelegateArgs { + validator: args.validator.unwrap_or(DEFAULT_VALIDATOR_IDENTITY), + validity_proof: args.validity_proof, + account_meta: args.account_meta, + account_data, + pda_seeds: pda_seeds + .iter() + .map(|seed| seed.to_vec()) + .collect::>(), + bump, + owner_program_id: crate::ID, + }, + } + .invoke_signed(&signer)?; + + Ok(()) +} + +fn process_schedule_commit_compressed( + accounts: &[AccountInfo], +) -> ProgramResult { + msg!("ScheduleCommitCompressed"); + + let [payer, counter, magic_context, magic_program, magic_fee_vault] = + accounts + else { + return Err(ProgramError::NotEnoughAccountKeys); + }; + + assert_keys_equal(magic_program.key, &MAGIC_PROGRAM_ID, || { + format!( + "Invalid magic program {}, should be {}", + magic_program.key, MAGIC_PROGRAM_ID + ) + })?; + + let (pda, _bump) = FlexiCounter::pda(payer.key); + assert_keys_equal(counter.key, &pda, || { + format!("Invalid counter PDA {}, should be {}", counter.key, pda) + })?; + + MagicIntentBundleBuilder::new( + payer.clone(), + magic_context.clone(), + magic_program.clone(), + ) + .magic_fee_vault(magic_fee_vault.clone()) + .commit(core::slice::from_ref(counter)) + .compressed() + .build_and_invoke()?; + + Ok(()) +} + +fn process_external_undelegate_compressed( + accounts: &[AccountInfo], + args: ExternalUndelegateArgs, +) -> ProgramResult { + msg!("External Undelegate Compressed"); + + let [payer, delegated_account, _system_program] = accounts else { + return Err(ProgramError::NotEnoughAccountKeys); + }; + + let (pda, bump) = FlexiCounter::pda(payer.key); + if &pda != delegated_account.key { + msg!("Invalid seeds: {:?} != {:?}", pda, delegated_account.key); + return Err(ProgramError::InvalidSeeds); + } + + // Recreate the account + let rent = Rent::get()?; + let rent_exemption = + rent.minimum_balance(args.delegation_record.data.len()); + let bump = &[bump]; + let seeds = FlexiCounter::seeds_with_bump(payer.key, bump); + if delegated_account.lamports() > 0 { + if rent_exemption > delegated_account.lamports() { + invoke( + &system_instruction::transfer( + payer.key, + delegated_account.key, + rent_exemption - delegated_account.lamports(), + ), + &[payer.clone(), delegated_account.clone()], + )?; + } else if rent_exemption < delegated_account.lamports() { + invoke_signed( + &system_instruction::transfer( + delegated_account.key, + payer.key, + delegated_account.lamports() - rent_exemption, + ), + &[delegated_account.clone(), payer.clone()], + &[&seeds], + )?; + } + + delegated_account.resize(args.delegation_record.data.len())?; + delegated_account.assign(&crate::ID); + } else { + invoke_signed( + &system_instruction::create_account( + payer.key, + delegated_account.key, + rent_exemption, + args.delegation_record.data.len() as u64, + &crate::ID, + ), + &[payer.clone(), delegated_account.clone()], + &[&seeds], + )?; + } + + // Reset data + delegated_account + .data + .borrow_mut() + .copy_from_slice(&args.delegation_record.data); + + Ok(()) +} diff --git a/test-integration/programs/flexi-counter/src/processor/schedule_intent.rs b/test-integration/programs/flexi-counter/src/processor/schedule_intent.rs index 8e03cf676..f1ece6acc 100644 --- a/test-integration/programs/flexi-counter/src/processor/schedule_intent.rs +++ b/test-integration/programs/flexi-counter/src/processor/schedule_intent.rs @@ -396,6 +396,8 @@ pub fn process_create_intent_bundle_commit_and_finalize( .collect(), )), commit_finalize_and_undelegate: None, + commit_finalize_compressed: None, + commit_finalize_compressed_and_undelegate: None, standalone_actions: vec![], }; diff --git a/test-integration/programs/flexi-counter/src/state.rs b/test-integration/programs/flexi-counter/src/state.rs index 2eb9a5255..d9a6c8ecc 100644 --- a/test-integration/programs/flexi-counter/src/state.rs +++ b/test-integration/programs/flexi-counter/src/state.rs @@ -1,7 +1,17 @@ use borsh::{BorshDeserialize, BorshSerialize}; +use light_sdk::{LightDiscriminator, LightHasher}; use solana_program::pubkey::Pubkey; -#[derive(BorshSerialize, BorshDeserialize, Debug, Clone, PartialEq, Eq)] +#[derive( + BorshSerialize, + BorshDeserialize, + Debug, + Clone, + PartialEq, + Eq, + LightDiscriminator, + LightHasher, +)] pub struct FlexiCounter { pub count: u64, pub updates: u64, diff --git a/test-integration/programs/schedulecommit/Cargo.toml b/test-integration/programs/schedulecommit/Cargo.toml index cd8496973..3dac943dd 100644 --- a/test-integration/programs/schedulecommit/Cargo.toml +++ b/test-integration/programs/schedulecommit/Cargo.toml @@ -6,11 +6,13 @@ version.workspace = true [dependencies] borsh = { workspace = true } ephemeral-rollups-sdk = { workspace = true } -magicblock-delegation-program-api = { workspace = true, features = ["instruction"] } +magicblock-delegation-program-api = { workspace = true, features = [ + "instruction", +] } magicblock-magic-program-api = { workspace = true } rkyv = { workspace = true } solana-program = { workspace = true } -solana-system-interface = { workspace = true } +solana-system-interface = { workspace = true, features = ["bincode"] } static_assertions = { workspace = true } [lib] diff --git a/test-integration/programs/schedulecommit/src/lib.rs b/test-integration/programs/schedulecommit/src/lib.rs index 414219861..724d8f5d7 100644 --- a/test-integration/programs/schedulecommit/src/lib.rs +++ b/test-integration/programs/schedulecommit/src/lib.rs @@ -6,13 +6,15 @@ use ephemeral_rollups_sdk::{ cpi::{ delegate_account, undelegate_account, DelegateAccounts, DelegateConfig, }, - ephem::{ - commit_accounts, commit_and_undelegate_accounts, CallHandler, - FoldableIntentBuilder, MagicIntentBundleBuilder, + ephem::{commit_accounts, commit_and_undelegate_accounts}, +}; +use magicblock_magic_program_api::{ + args::{ + ActionArgs, BaseActionArgs, CommitTypeArgs, MagicIntentBundleArgs, + ShortAccountMeta, }, - ActionArgs, ShortAccountMeta, + instruction::MagicBlockInstruction, }; -use magicblock_magic_program_api::instruction::MagicBlockInstruction; use solana_program::{ account_info::{next_account_info, AccountInfo}, declare_id, @@ -806,16 +808,16 @@ pub fn process_schedulecommit_with_vault_and_order_book_cpi( return Err(ProgramError::InvalidArgument); } - let mut builder = MagicIntentBundleBuilder::new( - payer.clone(), - magic_context.clone(), - magic_program.clone(), - ) - .magic_fee_vault(magic_fee_vault.clone()) - .commit(&committees); + let committed_accounts = (0..committees.len()) + .map(|idx| { + // Magic program CPI account layout: + // payer, magic_context, magic_fee_vault, then committed accounts. + u8::try_from(idx + 3) + }) + .collect::, _>>() + .map_err(|_| ProgramError::InvalidInstructionData)?; - if args.with_actions { - // Build the UpdateOrderBook instruction data with one hardcoded bid + let commit = if args.with_actions { let update_ix_data = to_vec(&ScheduleCommitInstruction::UpdateOrderBook(BookUpdate { bids: vec![OrderLevel { @@ -826,24 +828,63 @@ pub fn process_schedulecommit_with_vault_and_order_book_cpi( })) .map_err(|_| ProgramError::InvalidInstructionData)?; - // Post-commit action: call UpdateOrderBook on the order book account - let call_handler = CallHandler { - args: ActionArgs { - data: update_ix_data, - escrow_index: 1, // payer/escrow_authority inserted at index 1 - }, - compute_units: 50_000, - escrow_authority: payer.clone(), - destination_program: id(), - accounts: vec![ShortAccountMeta { - pubkey: *order_book.key, - is_writable: true, + CommitTypeArgs::WithBaseActions { + committed_accounts, + base_actions: vec![BaseActionArgs { + args: ActionArgs { + data: update_ix_data, + escrow_index: 1, + }, + compute_units: 50_000, + escrow_authority: 0, + destination_program: id(), + accounts: vec![ShortAccountMeta { + pubkey: *order_book.key, + is_writable: true, + }], }], - }; - builder = builder.add_post_commit_actions([call_handler]); - } + } + } else { + CommitTypeArgs::Standalone(committed_accounts) + }; + + let ix = Instruction::new_with_bincode( + *magic_program.key, + &MagicBlockInstruction::ScheduleIntentBundle(MagicIntentBundleArgs { + commit: Some(commit), + commit_and_undelegate: None, + commit_finalize: None, + commit_finalize_and_undelegate: None, + commit_finalize_compressed: None, + commit_finalize_compressed_and_undelegate: None, + standalone_actions: vec![], + }), + [ + vec![ + AccountMeta::new(*payer.key, true), + AccountMeta::new(*magic_context.key, false), + AccountMeta::new(*magic_fee_vault.key, false), + ], + committees + .iter() + .map(|account| AccountMeta { + pubkey: *account.key, + is_signer: account.is_signer, + is_writable: account.is_writable, + }) + .collect(), + ] + .concat(), + ); + + let mut cpi_accounts = vec![ + payer.clone(), + magic_context.clone(), + magic_fee_vault.clone(), + ]; + cpi_accounts.extend(committees); - builder.build_and_invoke() + invoke(&ix, &cpi_accounts) } fn process_increase_count(accounts: &[AccountInfo]) -> ProgramResult { diff --git a/test-integration/schedulecommit/test-scenarios/Cargo.toml b/test-integration/schedulecommit/test-scenarios/Cargo.toml index e3f29c57e..77e735c04 100644 --- a/test-integration/schedulecommit/test-scenarios/Cargo.toml +++ b/test-integration/schedulecommit/test-scenarios/Cargo.toml @@ -5,20 +5,26 @@ version.workspace = true [dev-dependencies] borsh = { workspace = true } +compressed-delegation-client = { workspace = true } ephemeral-rollups-sdk = { workspace = true } integration-test-tools = { workspace = true } +light-client = { workspace = true, features = ["v2"] } +light-sdk = { workspace = true, features = ["v2"] } magicblock-core = { workspace = true } magicblock-delegation-program-api = { workspace = true } magicblock-magic-program-api = { workspace = true } magicblock-program = { workspace = true } +program-flexi-counter = { workspace = true, features = ["no-entrypoint"] } program-schedulecommit = { workspace = true, features = ["no-entrypoint"] } rand = { workspace = true } schedulecommit-client = { workspace = true } serial_test = { workspace = true } solana-commitment-config = { workspace = true } +solana-compute-budget-interface = { workspace = true } solana-program = { workspace = true } solana-rpc-client = { workspace = true } solana-rpc-client-api = { workspace = true } solana-sdk = { workspace = true } test-kit = { workspace = true } +tokio = { workspace = true, features = ["full"] } tracing = { workspace = true } diff --git a/test-integration/schedulecommit/test-scenarios/tests/04_compressed_commits.rs b/test-integration/schedulecommit/test-scenarios/tests/04_compressed_commits.rs new file mode 100644 index 000000000..ead78c28b --- /dev/null +++ b/test-integration/schedulecommit/test-scenarios/tests/04_compressed_commits.rs @@ -0,0 +1,315 @@ +#![allow(clippy::result_large_err)] + +use borsh::BorshDeserialize; +use compressed_delegation_client::CompressedDelegationRecord; +use integration_test_tools::{ + loaded_accounts::DLP_TEST_AUTHORITY_BYTES, + scheduled_commits::{ + extract_scheduled_commit_sent_signature_from_logs, + extract_sent_commit_info_from_logs, + }, + IntegrationTestContext, +}; +use light_client::indexer::{ + photon_indexer::PhotonIndexer, AddressWithTree, Indexer, + ValidityProofWithContext, +}; +use light_sdk::{ + instruction::{ + account_meta::CompressedAccountMeta, PackedAccounts, + SystemAccountMetaConfig, + }, + sdk_types::PackedAddressTreeInfo, +}; +use magicblock_core::compression::{ + derive_cda_from_pda, ADDRESS_TREE, OUTPUT_QUEUE, +}; +use program_flexi_counter::{ + instruction::{ + create_delegate_compressed_ix, + create_init_compressed_delegation_record_ix, create_init_ix, + create_schedule_commit_compressed_ix, DelegateCompressedArgs, + InitDelegationRecordArgs, + }, + state::FlexiCounter, +}; +use solana_compute_budget_interface::ComputeBudgetInstruction; +use solana_rpc_client::rpc_client::RpcClient; +use solana_rpc_client_api::config::RpcSendTransactionConfig; +use solana_sdk::{ + native_token::LAMPORTS_PER_SOL, + signature::{Keypair, Signer}, + transaction::Transaction, +}; + +#[tokio::test(flavor = "multi_thread")] +async fn test_schedule_compressed_commit() { + test_kit::init_logger!(); + + let ctx = IntegrationTestContext::try_new().unwrap(); + let chain_client = ctx.chain_client.as_ref().unwrap(); + let ephem_client = ctx.ephem_client.as_ref().unwrap(); + let photon_indexer = ctx.photon_client.as_ref().unwrap(); + + let payer_chain = Keypair::new(); + let counter_auth = Keypair::new(); + let validator_identity = ctx.ephem_validator_identity.unwrap(); + + ctx.airdrop_chain(&payer_chain.pubkey(), LAMPORTS_PER_SOL * 10) + .unwrap(); + ctx.airdrop_chain(&counter_auth.pubkey(), LAMPORTS_PER_SOL * 10) + .unwrap(); + + let validator_keypair = + Keypair::try_from(&DLP_TEST_AUTHORITY_BYTES[..]).unwrap(); + ctx.ensure_magic_fee_vault_delegated_on_chain(&validator_keypair) + .unwrap(); + + let (counter_pda, compressed_record_address) = + init_and_delegate_compressed_counter( + chain_client, + photon_indexer, + &counter_auth, + validator_identity, + ) + .await; + + let (_deleg_sig, confirmed) = + ctx.delegate_account(&payer_chain, &counter_auth).unwrap(); + assert!(confirmed, "failed to delegate ephemeral fee payer"); + + let schedule_sig = ephem_client + .send_and_confirm_transaction(&Transaction::new_signed_with_payer( + &[create_schedule_commit_compressed_ix( + &counter_auth.pubkey(), + &validator_identity, + )], + Some(&counter_auth.pubkey()), + &[&counter_auth], + ephem_client.get_latest_blockhash().unwrap(), + )) + .unwrap(); + + let schedule_logs = ctx.fetch_ephemeral_logs(schedule_sig).unwrap(); + let scheduled_commit_sent_sig = + extract_scheduled_commit_sent_signature_from_logs(&schedule_logs) + .unwrap(); + let sent_logs = + ctx.fetch_ephemeral_logs(scheduled_commit_sent_sig).unwrap(); + let (included, excluded, _feepayers, chain_sigs) = + extract_sent_commit_info_from_logs(&sent_logs); + for sig in &chain_sigs { + assert!( + ctx.confirm_transaction_chain(sig, None).unwrap(), + "chain commit transaction {sig} should confirm" + ); + } + + assert!( + included.contains(&counter_pda), + "compressed counter should be included in scheduled commit result: {included:#?}" + ); + assert!( + excluded.is_empty(), + "compressed counter should not be excluded from scheduled commit result: {excluded:#?}" + ); + + let compressed_account = photon_indexer + .get_compressed_account(compressed_record_address, None) + .await + .unwrap() + .value + .unwrap(); + let compressed_record = CompressedDelegationRecord::try_from_slice( + &compressed_account.data.unwrap().data, + ) + .unwrap(); + + let committed_counter = + FlexiCounter::try_from_slice(&compressed_record.data).unwrap(); + assert_eq!( + committed_counter.count, 0, + "compressed delegation record should contain committed counter state" + ); +} + +async fn init_and_delegate_compressed_counter( + chain_client: &RpcClient, + photon_indexer: &PhotonIndexer, + counter_auth: &Keypair, + validator_identity: solana_sdk::pubkey::Pubkey, +) -> (solana_sdk::pubkey::Pubkey, [u8; 32]) { + let (counter_pda, _) = FlexiCounter::pda(&counter_auth.pubkey()); + let compressed_record_address = + derive_cda_from_pda(&counter_pda).to_bytes(); + + let init_counter_ix = + create_init_ix(counter_auth.pubkey(), "COUNTER".to_string()); + let init_record_ix = create_init_compressed_record_ix( + counter_auth.pubkey(), + compressed_record_address, + photon_indexer, + ) + .await; + + send_chain_ixs( + chain_client, + counter_auth, + &[ + ComputeBudgetInstruction::set_compute_unit_limit(300_000), + init_counter_ix, + init_record_ix, + ], + ) + .await; + + let delegate_ix = create_delegate_compressed_counter_ix( + counter_auth.pubkey(), + compressed_record_address, + photon_indexer, + validator_identity, + ) + .await; + send_chain_ixs( + chain_client, + counter_auth, + &[ + ComputeBudgetInstruction::set_compute_unit_limit(300_000), + delegate_ix, + ], + ) + .await; + + (counter_pda, compressed_record_address) +} + +async fn create_init_compressed_record_ix( + payer: solana_sdk::pubkey::Pubkey, + compressed_record_address: [u8; 32], + photon_indexer: &PhotonIndexer, +) -> solana_sdk::instruction::Instruction { + let mut remaining_accounts = packed_accounts(); + let rpc_result: ValidityProofWithContext = photon_indexer + .get_validity_proof( + vec![], + vec![AddressWithTree { + address: compressed_record_address, + tree: ADDRESS_TREE.to_bytes().into(), + }], + None, + ) + .await + .unwrap() + .value; + + let address_merkle_tree_pubkey_index = + remaining_accounts.insert_or_get(ADDRESS_TREE.to_bytes().into()); + let state_queue_pubkey_index = + remaining_accounts.insert_or_get(OUTPUT_QUEUE.to_bytes().into()); + let (remaining_accounts_metas, _, _) = + remaining_accounts.to_account_metas(); + + create_init_compressed_delegation_record_ix( + payer, + &remaining_accounts_metas + .iter() + .map(|meta| solana_sdk::message::AccountMeta { + pubkey: meta.pubkey.to_bytes().into(), + is_signer: meta.is_signer, + is_writable: meta.is_writable, + }) + .collect::>(), + InitDelegationRecordArgs { + validity_proof: rpc_result.proof.into(), + address_tree_info: PackedAddressTreeInfo { + root_index: rpc_result.addresses[0].root_index, + address_merkle_tree_pubkey_index, + address_queue_pubkey_index: address_merkle_tree_pubkey_index, + } + .into(), + output_state_tree_index: state_queue_pubkey_index, + }, + ) +} + +async fn create_delegate_compressed_counter_ix( + payer: solana_sdk::pubkey::Pubkey, + compressed_record_address: [u8; 32], + photon_indexer: &PhotonIndexer, + validator_identity: solana_sdk::pubkey::Pubkey, +) -> solana_sdk::instruction::Instruction { + let compressed_account = photon_indexer + .get_compressed_account(compressed_record_address, None) + .await + .unwrap() + .value + .unwrap(); + let mut remaining_accounts = packed_accounts(); + let rpc_result: ValidityProofWithContext = photon_indexer + .get_validity_proof(vec![compressed_account.hash], vec![], None) + .await + .unwrap() + .value; + + let state_queue_pubkey_index = + remaining_accounts.insert_or_get(OUTPUT_QUEUE.to_bytes().into()); + let packed_trees_info = rpc_result.pack_tree_infos(&mut remaining_accounts); + let packed_state_tree_info = packed_trees_info.state_trees.unwrap(); + let (remaining_accounts_metas, _, _) = + remaining_accounts.to_account_metas(); + + create_delegate_compressed_ix( + payer, + &remaining_accounts_metas + .iter() + .map(|meta| solana_sdk::message::AccountMeta { + pubkey: meta.pubkey.to_bytes().into(), + is_signer: meta.is_signer, + is_writable: meta.is_writable, + }) + .collect::>(), + DelegateCompressedArgs { + validator: Some(validator_identity), + validity_proof: rpc_result.proof.into(), + account_meta: CompressedAccountMeta { + tree_info: packed_state_tree_info.packed_tree_infos[0], + address: compressed_account.address.unwrap(), + output_state_tree_index: state_queue_pubkey_index, + } + .into(), + }, + ) +} + +fn packed_accounts() -> PackedAccounts { + let mut remaining_accounts = PackedAccounts::default(); + remaining_accounts + .add_system_accounts_v2(SystemAccountMetaConfig::new( + compressed_delegation_client::ID.to_bytes().into(), + )) + .unwrap(); + remaining_accounts +} + +async fn send_chain_ixs( + rpc_client: &RpcClient, + payer: &Keypair, + ixs: &[solana_sdk::instruction::Instruction], +) { + let latest_blockhash = rpc_client.get_latest_blockhash().unwrap(); + rpc_client + .send_and_confirm_transaction_with_spinner_and_config( + &Transaction::new_signed_with_payer( + ixs, + Some(&payer.pubkey()), + &[payer], + latest_blockhash, + ), + rpc_client.commitment(), + RpcSendTransactionConfig { + skip_preflight: true, + ..Default::default() + }, + ) + .unwrap(); +} diff --git a/test-integration/test-chainlink/Cargo.toml b/test-integration/test-chainlink/Cargo.toml index 8ab33f014..8bc22cc21 100644 --- a/test-integration/test-chainlink/Cargo.toml +++ b/test-integration/test-chainlink/Cargo.toml @@ -5,18 +5,28 @@ edition.workspace = true [dependencies] bincode = { workspace = true } +borsh = { workspace = true } +compressed-delegation-client = { workspace = true } futures = { workspace = true } tracing = { workspace = true } +light-client = { workspace = true, features = ["v2"] } +light-hasher = { workspace = true } +light-sdk = { workspace = true, features = ["v2"] } magicblock-chainlink = { workspace = true } magicblock-config = { workspace = true } +magicblock-core = { workspace = true } magicblock-delegation-program-api = { workspace = true } program-mini = { workspace = true, features = ["no-entrypoint"] } program-flexi-counter = { workspace = true, features = ["no-entrypoint"] } solana-account = { workspace = true } solana-loader-v2-interface = { workspace = true, features = ["serde"] } solana-loader-v3-interface = { workspace = true, features = ["serde"] } -solana-loader-v4-interface = { workspace = true, features = ["bincode", "serde"] } +solana-loader-v4-interface = { workspace = true, features = [ + "bincode", + "serde", +] } solana-commitment-config = { workspace = true } +solana-compute-budget-interface = { workspace = true } solana-pubkey = { workspace = true } solana-rpc-client = { workspace = true } solana-rpc-client-api = { workspace = true } diff --git a/test-integration/test-chainlink/src/ixtest_context.rs b/test-integration/test-chainlink/src/ixtest_context.rs index b9b4f0c0a..d06c6031e 100644 --- a/test-integration/test-chainlink/src/ixtest_context.rs +++ b/test-integration/test-chainlink/src/ixtest_context.rs @@ -1,6 +1,21 @@ use std::sync::Arc; +use borsh::BorshDeserialize; +use compressed_delegation_client::{ + CommitAndFinalizeArgs, CompressedDelegationRecord, UndelegateArgs, +}; use integration_test_tools::dlp_interface; +use light_client::indexer::{ + photon_indexer::PhotonIndexer, AddressWithTree, CompressedAccount, Indexer, + ValidityProofWithContext, +}; +use light_sdk::{ + instruction::{ + account_meta::CompressedAccountMeta, PackedAccounts, + SystemAccountMetaConfig, + }, + sdk_types::PackedAddressTreeInfo, +}; use magicblock_chainlink::{ accounts_bank::mock::AccountsBankStub, cloner::{AccountCloneRequest, Cloner, DelegationActions}, @@ -9,7 +24,8 @@ use magicblock_chainlink::{ native_program_accounts, remote_account_provider::{ chain_rpc_client::ChainRpcClientImpl, - chain_updates_client::ChainUpdatesClient, Endpoint, Endpoints, + chain_updates_client::ChainUpdatesClient, + photon_client::PhotonClientImpl, Endpoint, Endpoints, RemoteAccountProvider, }, submux::SubMuxClient, @@ -17,9 +33,18 @@ use magicblock_chainlink::{ Chainlink, }; use magicblock_config::config::{ChainLinkConfig, LifecycleMode}; -use program_flexi_counter::state::FlexiCounter; +use magicblock_core::compression::{ + derive_cda_from_pda, ADDRESS_TREE, OUTPUT_QUEUE, +}; +use program_flexi_counter::{ + instruction::{ + create_init_compressed_delegation_record_ix, InitDelegationRecordArgs, + }, + state::FlexiCounter, +}; use solana_account::AccountSharedData; use solana_commitment_config::CommitmentConfig; +use solana_compute_budget_interface::ComputeBudgetInstruction; use solana_pubkey::Pubkey; use solana_rpc_client::nonblocking::rpc_client::RpcClient; use solana_rpc_client_api::config::RpcSendTransactionConfig; @@ -27,7 +52,7 @@ use solana_sdk::{ native_token::LAMPORTS_PER_SOL, signature::Keypair, signer::Signer, transaction::Transaction, }; -use solana_sdk_ids::native_loader; +use solana_sdk_ids::{native_loader, system_program}; use tokio::task; use tracing::*; @@ -38,11 +63,13 @@ pub type IxtestChainlink = Chainlink< SubMuxClient, AccountsBankStub, ClonerStub, + PhotonClientImpl, >; #[derive(Clone)] pub struct IxtestContext { pub rpc_client: Arc, + pub photon_client: Arc, pub chainlink: Arc, pub bank: Arc, pub remote_account_provider: Option< @@ -50,6 +77,7 @@ pub struct IxtestContext { RemoteAccountProvider< ChainRpcClientImpl, SubMuxClient, + PhotonClientImpl, >, >, >, @@ -89,6 +117,10 @@ impl IxtestContext { url: "ws://localhost:7800".to_string(), label: "test-ws".to_string(), }, + Endpoint::Compression { + label: "test-compression".to_string(), + url: "http://localhost:8784".to_string(), + }, ]; let endpoints = Endpoints::from(endpoints_vec.as_slice()); // Add all native programs @@ -148,8 +180,11 @@ impl IxtestContext { .unwrap(); let rpc_client = IxtestContext::get_rpc_client(commitment); + let photon_client = + PhotonIndexer::new("http://localhost:8784".to_string()); Self { rpc_client: Arc::new(rpc_client), + photon_client: Arc::new(photon_client), chainlink: Arc::new(chainlink), bank, remote_account_provider, @@ -205,6 +240,7 @@ impl IxtestContext { .expect("Failed to init account"); self } + pub async fn add_accounts(&self, accs: &[(Pubkey, u64)]) { let mut joinset = task::JoinSet::new(); for (pubkey, sol) in accs { @@ -357,6 +393,352 @@ impl IxtestContext { self } + pub async fn init_compressed_delegation_record( + &self, + counter_auth: &Keypair, + ) -> &Self { + debug!( + "Initializing compressed delegation record for counter account {}", + counter_auth.pubkey() + ); + + let auth = counter_auth.pubkey(); + let (pda, _bump) = FlexiCounter::pda(&auth); + let record_address = derive_cda_from_pda(&pda); + + let mut remaining_accounts = self.get_packed_accounts(); + + let rpc_result: ValidityProofWithContext = self + .photon_client + .get_validity_proof( + vec![], + vec![AddressWithTree { + address: record_address.to_bytes(), + tree: ADDRESS_TREE.to_bytes().into(), + }], + None, + ) + .await + .unwrap() + .value; + + // Insert trees in accounts + let address_merkle_tree_pubkey_index = + remaining_accounts.insert_or_get(ADDRESS_TREE.to_bytes().into()); + let state_queue_pubkey_index = + remaining_accounts.insert_or_get(OUTPUT_QUEUE.to_bytes().into()); + + let packed_address_tree_info = PackedAddressTreeInfo { + root_index: rpc_result.addresses[0].root_index, + address_merkle_tree_pubkey_index, + address_queue_pubkey_index: address_merkle_tree_pubkey_index, + }; + + let (remaining_accounts_metas, _, _) = + remaining_accounts.to_account_metas(); + + let init_compressed_delegation_record_ix = + create_init_compressed_delegation_record_ix( + counter_auth.pubkey(), + &remaining_accounts_metas + .iter() + .map(|meta| solana_sdk::message::AccountMeta { + pubkey: meta.pubkey.to_bytes().into(), + is_signer: meta.is_signer, + is_writable: meta.is_writable, + }) + .collect::>(), + InitDelegationRecordArgs { + validity_proof: rpc_result.proof.into(), + address_tree_info: packed_address_tree_info.into(), + output_state_tree_index: state_queue_pubkey_index, + }, + ); + + let latest_block_hash = + self.rpc_client.get_latest_blockhash().await.unwrap(); + let tx = Transaction::new_signed_with_payer( + &[ + ComputeBudgetInstruction::set_compute_unit_limit(300_000), + init_compressed_delegation_record_ix, + ], + Some(&counter_auth.pubkey()), + &[&counter_auth], + latest_block_hash, + ); + debug!( + "Init compressed delegation record transaction: {:?}", + tx.signatures[0] + ); + self.rpc_client + .send_and_confirm_transaction_with_spinner_and_config( + &tx, + CommitmentConfig::confirmed(), + RpcSendTransactionConfig { + skip_preflight: true, + ..Default::default() + }, + ) + .await + .expect("Failed to init compressed delegation record"); + + // Wait for the indexer to index the account + sleep_ms(1500).await; + + self + } + + pub async fn delegate_compressed_counter( + &self, + counter_auth: &Keypair, + ) -> &Self { + debug!( + "Delegating compressed counter account {}", + counter_auth.pubkey() + ); + use program_flexi_counter::instruction::*; + + let auth = counter_auth.pubkey(); + let (pda, _bump) = FlexiCounter::pda(&auth); + let record_address = derive_cda_from_pda(&pda); + + let mut remaining_accounts = self.get_packed_accounts(); + + let (compressed_delegated_record, proof) = + self.get_compressed_account_and_proof(&record_address).await; + + let packed_state_tree = proof + .pack_tree_infos(&mut remaining_accounts) + .state_trees + .unwrap(); + let account_meta = CompressedAccountMeta { + tree_info: packed_state_tree.packed_tree_infos[0], + address: compressed_delegated_record.address.unwrap(), + output_state_tree_index: packed_state_tree.output_tree_index, + }; + + let (remaining_accounts_metas, _, _) = + remaining_accounts.to_account_metas(); + + let delegate_ix = create_delegate_compressed_ix( + counter_auth.pubkey(), + &remaining_accounts_metas + .iter() + .map(|meta| solana_sdk::message::AccountMeta { + pubkey: meta.pubkey.to_bytes().into(), + is_signer: meta.is_signer, + is_writable: meta.is_writable, + }) + .collect::>(), + DelegateCompressedArgs { + validator: Some(self.validator_kp.pubkey()), + validity_proof: proof.proof.into(), + account_meta: account_meta.into(), + }, + ); + + let latest_block_hash = + self.rpc_client.get_latest_blockhash().await.unwrap(); + let tx = Transaction::new_signed_with_payer( + &[ + ComputeBudgetInstruction::set_compute_unit_limit(300_000), + delegate_ix, + ], + Some(&counter_auth.pubkey()), + &[&counter_auth], + latest_block_hash, + ); + debug!("Delegate transaction: {:?}", tx.signatures[0]); + self.rpc_client + .send_and_confirm_transaction_with_spinner_and_config( + &tx, + CommitmentConfig::confirmed(), + RpcSendTransactionConfig { + skip_preflight: true, + ..Default::default() + }, + ) + .await + .expect("Failed to delegate account"); + + // Wait for the indexer to index the account + sleep_ms(1500).await; + + self + } + + pub async fn undelegate_compressed_counter( + &self, + counter_auth: &Keypair, + redelegate: bool, + ) -> &Self { + debug!( + "Undelegating compressed counter account {}", + counter_auth.pubkey() + ); + let counter_pda = self.counter_pda(&counter_auth.pubkey()); + // Match the non-compressed path: once commit+undelegate starts, the + // local delegated account must be treated as undelegating until the + // chain subscription delivers the post-undelegation state. + self.bank.force_undelegation(&counter_pda); + // The committor service will call this in order to have + // chainlink subscribe to account updates of the counter account + self.chainlink + .undelegation_requested(counter_pda) + .await + .unwrap(); + + // In order to make the account undelegatable we first need to + // commmit and finalize + let (pda, _bump) = FlexiCounter::pda(&counter_auth.pubkey()); + let record_address = derive_cda_from_pda(&pda); + let (compressed_account, proof) = + self.get_compressed_account_and_proof(&record_address).await; + let mut remaining_accounts = self.get_packed_accounts(); + + let packed_tree_accounts = proof + .pack_tree_infos(&mut remaining_accounts) + .state_trees + .unwrap(); + + let account_meta = CompressedAccountMeta { + tree_info: packed_tree_accounts.packed_tree_infos[0], + address: compressed_account.address.unwrap(), + output_state_tree_index: packed_tree_accounts.output_tree_index, + }; + + let (remaining_accounts_metas, _, _) = + remaining_accounts.to_account_metas(); + + let commit_ix = + compressed_delegation_client::builders::CommitAndFinalizeBuilder { + validator: self.validator_kp.pubkey(), + delegated_account: pda, + args: CommitAndFinalizeArgs { + current_compressed_delegated_account_data: + compressed_account.data.unwrap().data.to_vec(), + new_data: borsh::to_vec(&FlexiCounter::new( + "COUNTER".to_string(), + )) + .unwrap(), + account_meta: account_meta.into(), + validity_proof: proof.proof.into(), + update_nonce: 1, + allow_undelegation: true, + }, + remaining_accounts: remaining_accounts_metas + .iter() + .map(|meta| solana_sdk::message::AccountMeta { + pubkey: meta.pubkey.to_bytes().into(), + is_signer: meta.is_signer, + is_writable: meta.is_writable, + }) + .collect::>(), + } + .instruction() + .unwrap(); + + let latest_block_hash = + self.rpc_client.get_latest_blockhash().await.unwrap(); + self.rpc_client + .send_and_confirm_transaction_with_spinner_and_config( + &Transaction::new_signed_with_payer( + &[commit_ix], + Some(&self.validator_kp.pubkey()), + &[&self.validator_kp], + latest_block_hash, + ), + CommitmentConfig::confirmed(), + RpcSendTransactionConfig { + skip_preflight: true, + ..Default::default() + }, + ) + .await + .expect("Failed to commit account"); + + // Wait for the indexer to index the account + sleep_ms(500).await; + + let (compressed_account, proof) = + self.get_compressed_account_and_proof(&record_address).await; + + let mut remaining_accounts = self.get_packed_accounts(); + + let packed_state_tree = proof + .pack_tree_infos(&mut remaining_accounts) + .state_trees + .unwrap(); + let account_meta = CompressedAccountMeta { + tree_info: packed_state_tree.packed_tree_infos[0], + address: compressed_account.address.unwrap(), + output_state_tree_index: packed_state_tree.output_tree_index, + }; + + let (remaining_accounts_metas, _, _) = + remaining_accounts.to_account_metas(); + + let undelegate_ix = + compressed_delegation_client::builders::UndelegateBuilder { + payer: counter_auth.pubkey(), + delegated_account: counter_pda, + owner_program: program_flexi_counter::ID, + system_program: system_program::ID, + args: UndelegateArgs { + validity_proof: proof.proof.into(), + delegation_record_account_meta: account_meta.into(), + compressed_delegated_record: + CompressedDelegationRecord::try_from_slice( + &compressed_account.data.clone().unwrap().data, + ) + .unwrap(), + }, + remaining_accounts: remaining_accounts_metas + .iter() + .map(|meta| solana_sdk::message::AccountMeta { + pubkey: meta.pubkey.to_bytes().into(), + is_signer: meta.is_signer, + is_writable: meta.is_writable, + }) + .collect::>(), + } + .instruction() + .unwrap(); + let latest_block_hash = + self.rpc_client.get_latest_blockhash().await.unwrap(); + let tx = Transaction::new_signed_with_payer( + &[ + ComputeBudgetInstruction::set_compute_unit_limit(250_000), + undelegate_ix, + ], + Some(&counter_auth.pubkey()), + &[&counter_auth], + latest_block_hash, + ); + debug!("Undelegate transaction: {:?}", tx.signatures[0]); + self.rpc_client + .send_and_confirm_transaction_with_spinner_and_config( + &tx, + CommitmentConfig::confirmed(), + RpcSendTransactionConfig { + skip_preflight: true, + ..Default::default() + }, + ) + .await + .expect("Failed to undelegate account"); + + // Build instructions and required signers + if redelegate { + // Wait for the indexer to index the account + sleep_ms(1500).await; + + self.delegate_compressed_counter(counter_auth).await + } else { + self + } + } + pub async fn top_up_ephemeral_fee_balance( &self, payer: &Keypair, @@ -401,4 +783,35 @@ impl IxtestContext { pub fn get_rpc_client(commitment: CommitmentConfig) -> RpcClient { RpcClient::new_with_commitment(RPC_URL.to_string(), commitment) } + + fn get_packed_accounts(&self) -> PackedAccounts { + let system_account_meta_config = SystemAccountMetaConfig::new( + compressed_delegation_client::ID.to_bytes().into(), + ); + let mut remaining_accounts = PackedAccounts::default(); + remaining_accounts + .add_system_accounts_v2(system_account_meta_config) + .unwrap(); + remaining_accounts + } + + async fn get_compressed_account_and_proof( + &self, + pubkey: &Pubkey, + ) -> (CompressedAccount, ValidityProofWithContext) { + let compressed_account = self + .photon_client + .get_compressed_account(pubkey.to_bytes(), None) + .await + .unwrap() + .value + .unwrap(); + let validity_proof = self + .photon_client + .get_validity_proof(vec![compressed_account.hash], vec![], None) + .await + .unwrap() + .value; + (compressed_account, validity_proof) + } } diff --git a/test-integration/test-chainlink/src/test_context.rs b/test-integration/test-chainlink/src/test_context.rs index 22ee8f4c8..f6960613e 100644 --- a/test-integration/test-chainlink/src/test_context.rs +++ b/test-integration/test-chainlink/src/test_context.rs @@ -17,6 +17,7 @@ use magicblock_chainlink::{ accounts::account_shared_with_owner, cloner_stub::ClonerStub, deleg::add_delegation_record_for, + photon_client_mock::PhotonClientMock, rpc_client_mock::{ChainRpcClientMock, ChainRpcClientMockBuilder}, utils::{create_test_lru_cache, create_test_lru_cache_with_config}, }, @@ -37,6 +38,7 @@ pub type TestChainlink = Chainlink< ChainPubsubClientMock, AccountsBankStub, ClonerStub, + PhotonClientMock, >; #[derive(Clone)] @@ -46,7 +48,13 @@ pub struct TestContext { pub chainlink: Arc, pub bank: Arc, pub remote_account_provider: Option< - Arc>, + Arc< + RemoteAccountProvider< + ChainRpcClientMock, + ChainPubsubClientMock, + PhotonClientMock, + >, + >, >, pub cloner: Arc, pub validator_pubkey: Pubkey, @@ -54,13 +62,14 @@ pub struct TestContext { impl TestContext { pub async fn init(slot: Slot) -> Self { - let (rpc_client, pubsub_client) = { + let (rpc_client, pubsub_client, photon_client) = { let rpc_client = ChainRpcClientMockBuilder::new().slot(slot).build(); let (updates_sndr, updates_rcvr) = mpsc::channel(100); let pubsub_client = ChainPubsubClientMock::new(updates_sndr, updates_rcvr); - (rpc_client, pubsub_client) + let photon_client = PhotonClientMock::default(); + (rpc_client, pubsub_client, photon_client) }; let lifecycle_mode = LifecycleMode::Ephemeral; @@ -84,6 +93,7 @@ impl TestContext { RemoteAccountProvider::try_from_clients_and_mode( rpc_client.clone(), pubsub_client.clone(), + Some(photon_client.clone()), tx, &config, subscribed_accounts, diff --git a/test-integration/test-chainlink/tests/ix_01_ensure-accounts.rs b/test-integration/test-chainlink/tests/ix_01_ensure-accounts.rs index b48f19e6d..e2c63d7d2 100644 --- a/test-integration/test-chainlink/tests/ix_01_ensure-accounts.rs +++ b/test-integration/test-chainlink/tests/ix_01_ensure-accounts.rs @@ -94,3 +94,44 @@ async fn ixtest_write_existing_account_valid_delegation_record() { // TODO(thlorenz): @ implement this test when we can actually delegate to a specific // authority: test_write_existing_account_other_authority + +// ----------------- +// BasicScenarios: Compressed account is initialized and already delegated to us +// ----------------- +#[tokio::test] +async fn ixtest_write_existing_account_compressed() { + init_logger(); + + let ctx = IxtestContext::init().await; + + let counter_auth = Keypair::new(); + ctx.init_counter(&counter_auth) + .await + .init_compressed_delegation_record(&counter_auth) + .await + .delegate_compressed_counter(&counter_auth) + .await; + + let counter_pda = ctx.counter_pda(&counter_auth.pubkey()); + info!(counter =% counter_pda, "init"); + let pubkeys = [counter_pda]; + + ctx.chainlink + .ensure_accounts( + &pubkeys, + None, + AccountFetchOrigin::GetMultipleAccounts, + None, + ) + .await + .unwrap(); + + let account = ctx.cloner.get_account(&counter_pda).unwrap(); + assert_cloned_as_delegated!( + ctx.cloner, + &[counter_pda], + account.remote_slot(), + program_flexi_counter::id() + ); + assert_not_subscribed!(ctx.chainlink, &[&counter_pda]); +} diff --git a/test-integration/test-chainlink/tests/ix_03_deleg_after_sub.rs b/test-integration/test-chainlink/tests/ix_03_deleg_after_sub.rs index 8c91555ae..e7badfdbc 100644 --- a/test-integration/test-chainlink/tests/ix_03_deleg_after_sub.rs +++ b/test-integration/test-chainlink/tests/ix_03_deleg_after_sub.rs @@ -95,3 +95,90 @@ async fn ixtest_deleg_after_subscribe_case2() { ); } } + +#[tokio::test] +async fn ixtest_deleg_after_subscribe_case2_compressed() { + init_logger(); + + let ctx = IxtestContext::init().await; + + let counter_auth = Keypair::new(); + let counter_pda = ctx.counter_pda(&counter_auth.pubkey()); + let pubkeys = [counter_pda]; + info!(counter =% counter_pda, "init"); + + // 1. Initially the account does not exist + { + info!("1. Initially the account does not exist"); + let res = ctx + .chainlink + .ensure_accounts( + &pubkeys, + None, + AccountFetchOrigin::GetAccount, + None, + ) + .await + .unwrap(); + + assert_not_found!(res, &pubkeys); + assert_not_cloned!(ctx.cloner, &pubkeys); + assert_not_subscribed!(ctx.chainlink, &[&counter_pda]); + } + + // 2. Account created with original owner (program) + { + info!("2. Create account owned by program_flexi_counter"); + ctx.init_counter(&counter_auth).await; + + ctx.chainlink + .ensure_accounts( + &pubkeys, + Some(&pubkeys), + AccountFetchOrigin::GetAccount, + None, + ) + .await + .unwrap(); + + // Assert cloned account state matches the remote account and slot + let account = ctx.cloner.get_account(&counter_pda).unwrap(); + assert_cloned_as_undelegated!( + ctx.cloner, + &[counter_pda], + account.remote_slot(), + program_flexi_counter::id() + ); + + assert_subscribed_without_delegation_record!(ctx.chainlink, &pubkeys); + } + + // 3. Account delegated to us + { + info!("3. Delegate account to us"); + ctx.init_compressed_delegation_record(&counter_auth) + .await + .delegate_compressed_counter(&counter_auth) + .await; + + ctx.chainlink + .ensure_accounts( + &pubkeys, + None, + AccountFetchOrigin::GetAccount, + None, + ) + .await + .unwrap(); + + let account = ctx.cloner.get_account(&counter_pda).unwrap(); + assert_cloned_as_delegated!( + ctx.cloner, + &[counter_pda], + account.remote_slot(), + program_flexi_counter::id() + ); + + assert_not_subscribed!(ctx.chainlink, &[&counter_pda]); + } +} diff --git a/test-integration/test-chainlink/tests/ix_06_redeleg_us_separate_slots.rs b/test-integration/test-chainlink/tests/ix_06_redeleg_us_separate_slots.rs index 64a6821e0..6b1a2ab53 100644 --- a/test-integration/test-chainlink/tests/ix_06_redeleg_us_separate_slots.rs +++ b/test-integration/test-chainlink/tests/ix_06_redeleg_us_separate_slots.rs @@ -12,6 +12,8 @@ use solana_sdk::{signature::Keypair, signer::Signer}; use test_chainlink::{ixtest_context::IxtestContext, sleep_ms}; use tracing::*; +const RETRIES: u64 = 30; + #[tokio::test] async fn ixtest_undelegate_redelegate_to_us_in_separate_slots() { init_logger(); @@ -51,7 +53,7 @@ async fn ixtest_undelegate_redelegate_to_us_in_separate_slots() { &[counter_pda], account.remote_slot(), program_flexi_counter::id(), - 30 + RETRIES ); // Accounts delegated to us should not be tracked via subscription @@ -95,7 +97,7 @@ async fn ixtest_undelegate_redelegate_to_us_in_separate_slots() { &[counter_pda], account.remote_slot(), program_flexi_counter::id(), - 30 + RETRIES ); // Accounts delegated to us should not be tracked via subscription @@ -105,3 +107,102 @@ async fn ixtest_undelegate_redelegate_to_us_in_separate_slots() { ); } } + +#[tokio::test] +async fn ixtest_undelegate_redelegate_to_us_in_separate_slots_compressed() { + init_logger(); + + let ctx = IxtestContext::init().await; + + // Create and delegate a counter account to us + let counter_auth = Keypair::new(); + ctx.init_counter(&counter_auth) + .await + .init_compressed_delegation_record(&counter_auth) + .await + .delegate_compressed_counter(&counter_auth) + .await; + + let counter_pda = ctx.counter_pda(&counter_auth.pubkey()); + let pubkeys = [counter_pda]; + + // 1. Account delegated to us - readable and writable + { + info!("1. Account delegated to us"); + + ctx.chainlink + .ensure_accounts( + &pubkeys, + None, + AccountFetchOrigin::GetMultipleAccounts, + None, + ) + .await + .unwrap(); + sleep_ms(1_500).await; + + // Account should be cloned as delegated + let account = ctx.cloner.get_account(&counter_pda).unwrap(); + assert_cloned_as_delegated_with_retries!( + ctx.cloner, + &[counter_pda], + account.remote_slot(), + program_flexi_counter::id(), + RETRIES + ); + + // Accounts delegated to us should not be tracked via subscription + assert_not_subscribed!(ctx.chainlink, &[&counter_pda]); + } + + // 2. Account is undelegated - writes refused, subscription set + { + info!( + "2. Account is undelegated - Would refuse write (undelegated on chain)" + ); + + ctx.undelegate_compressed_counter(&counter_auth, false) + .await; + sleep_ms(1_500).await; + + // Account should be cloned as undelegated (owned by program again) + let account = ctx.cloner.get_account(&counter_pda).unwrap(); + assert_cloned_as_undelegated!( + ctx.cloner, + &[counter_pda], + account.remote_slot(), + program_flexi_counter::id() + ); + + assert_subscribed_without_delegation_record!(ctx.chainlink, &pubkeys); + } + + // 3. Account redelegated to us (separate slot) - writes allowed again + { + info!("3. Account redelegated to us - Would allow write"); + ctx.delegate_compressed_counter(&counter_auth).await; + + ctx.chainlink + .ensure_accounts( + &pubkeys, + None, + AccountFetchOrigin::GetMultipleAccounts, + None, + ) + .await + .unwrap(); + + // Account should be cloned as delegated back to us + let account = ctx.cloner.get_account(&counter_pda).unwrap(); + assert_cloned_as_delegated_with_retries!( + ctx.cloner, + &[counter_pda], + account.remote_slot(), + program_flexi_counter::id(), + RETRIES + ); + + // Accounts delegated to us should not be tracked via subscription + assert_not_subscribed!(ctx.chainlink, &[&counter_pda]); + } +} diff --git a/test-integration/test-chainlink/tests/ix_07_redeleg_us_same_slot.rs b/test-integration/test-chainlink/tests/ix_07_redeleg_us_same_slot.rs index 75641f651..94dd8d583 100644 --- a/test-integration/test-chainlink/tests/ix_07_redeleg_us_same_slot.rs +++ b/test-integration/test-chainlink/tests/ix_07_redeleg_us_same_slot.rs @@ -87,3 +87,74 @@ async fn ixtest_undelegate_redelegate_to_us_in_same_slot() { ); } } + +#[tokio::test] +async fn ixtest_undelegate_redelegate_to_us_in_same_slot_compressed() { + init_logger(); + + let ctx = IxtestContext::init().await; + + // Create and delegate a counter account to us + let counter_auth = Keypair::new(); + ctx.init_counter(&counter_auth) + .await + .init_compressed_delegation_record(&counter_auth) + .await + .delegate_compressed_counter(&counter_auth) + .await; + + let counter_pda = ctx.counter_pda(&counter_auth.pubkey()); + let pubkeys = [counter_pda]; + + // 1. Account delegated to us - readable and writable + { + info!("1. Account delegated to us"); + + ctx.chainlink + .ensure_accounts( + &pubkeys, + None, + AccountFetchOrigin::GetMultipleAccounts, + None, + ) + .await + .unwrap(); + sleep_ms(1_500).await; + + // Account should be cloned as delegated + let account = ctx.cloner.get_account(&counter_pda).unwrap(); + assert_cloned_as_delegated!( + ctx.cloner, + &[counter_pda], + account.remote_slot(), + program_flexi_counter::id() + ); + + // Accounts delegated to us should not be tracked via subscription + assert_not_subscribed!(ctx.chainlink, &[&counter_pda]); + } + + // 2. Account is undelegated and redelegated to us (same slot) - writes allowed again + { + info!( + "2. Account is undelegated and redelegated to us in the same slot" + ); + + ctx.undelegate_compressed_counter(&counter_auth, true).await; + + // Wait for pubsub update to trigger subscription handler + sleep_ms(1_500).await; + + // Account should still be cloned as delegated to us + let account = ctx.cloner.get_account(&counter_pda).unwrap(); + assert_cloned_as_delegated!( + ctx.cloner, + &[counter_pda], + account.remote_slot(), + program_flexi_counter::id() + ); + + // Accounts delegated to us should not be tracked via subscription + assert_not_subscribed!(ctx.chainlink, &[&counter_pda]); + } +} diff --git a/test-integration/test-chainlink/tests/ix_full_scenarios.rs b/test-integration/test-chainlink/tests/ix_full_scenarios.rs index 89e28a033..2885b6ad0 100644 --- a/test-integration/test-chainlink/tests/ix_full_scenarios.rs +++ b/test-integration/test-chainlink/tests/ix_full_scenarios.rs @@ -16,7 +16,6 @@ use test_chainlink::{ ixtest_context::IxtestContext, logging::{stringify_maybe_pubkeys, stringify_pubkeys}, programs::MEMOV2, - sleep_ms, }; use tokio::task; use tracing::*; @@ -207,12 +206,7 @@ async fn ixtest_accounts_for_tx_2_delegated_3_readonly_3_programs_one_native() { // After we add the account to chain and run the same request again it will // return all accounts { - ctx.rpc_client - .request_airdrop(&new_pubkey, 1_000_000_000) - .await - .unwrap(); - - sleep_ms(500).await; + ctx.add_account(&new_pubkey, 1).await; let (fetched_pubkeys, fetched_strs) = { let fetched_accounts = ctx diff --git a/test-integration/test-chainlink/tests/ix_remote_account_provider.rs b/test-integration/test-chainlink/tests/ix_remote_account_provider.rs index c1f6da65c..5821146f1 100644 --- a/test-integration/test-chainlink/tests/ix_remote_account_provider.rs +++ b/test-integration/test-chainlink/tests/ix_remote_account_provider.rs @@ -2,15 +2,15 @@ use magicblock_chainlink::{ remote_account_provider::{ chain_rpc_client::ChainRpcClientImpl, chain_updates_client::ChainUpdatesClient, - config::RemoteAccountProviderConfig, Endpoint, Endpoints, - RemoteAccountProvider, RemoteAccountUpdateSource, + config::RemoteAccountProviderConfig, photon_client::PhotonClientImpl, + Endpoint, Endpoints, RemoteAccountProvider, RemoteAccountUpdateSource, }, submux::SubMuxClient, testing::utils::{ airdrop, await_next_slot, current_slot, dump_remote_account_lamports, dump_remote_account_update_source, get_remote_account_lamports, get_remote_account_update_sources, init_logger, random_pubkey, - sleep_ms, PUBSUB_URL, RPC_URL, + sleep_ms, COMPRESSION_URL, PUBSUB_URL, RPC_URL, }, AccountFetchOrigin, }; @@ -22,9 +22,11 @@ use solana_rpc_client_api::{ use tokio::sync::mpsc; use tracing::{debug, info}; -async fn init_remote_account_provider( -) -> RemoteAccountProvider> -{ +async fn init_remote_account_provider() -> RemoteAccountProvider< + ChainRpcClientImpl, + SubMuxClient, + PhotonClientImpl, +> { let (fwd_tx, _fwd_rx) = mpsc::channel(100); let endpoints_vec = vec![ Endpoint::Rpc { @@ -35,11 +37,16 @@ async fn init_remote_account_provider( url: PUBSUB_URL.to_string(), label: "test-ws".to_string(), }, + Endpoint::Compression { + label: "test-compression".to_string(), + url: COMPRESSION_URL.to_string(), + }, ]; let endpoints = Endpoints::from(endpoints_vec.as_slice()); let provider = RemoteAccountProvider::< ChainRpcClientImpl, SubMuxClient, + PhotonClientImpl, >::try_from_urls_and_config( &endpoints, CommitmentConfig::confirmed(), diff --git a/test-integration/test-committor-service/Cargo.toml b/test-integration/test-committor-service/Cargo.toml index 53e29921d..c7f07c7c6 100644 --- a/test-integration/test-committor-service/Cargo.toml +++ b/test-integration/test-committor-service/Cargo.toml @@ -6,8 +6,12 @@ edition.workspace = true [dev-dependencies] async-trait = { workspace = true } borsh = { workspace = true } +compressed-delegation-client = { workspace = true } tracing = { workspace = true } futures = { workspace = true } +light-client = { workspace = true, features = ["v2"] } +light-sdk = { workspace = true, features = ["v2"] } +light-sdk-types = { workspace = true, features = ["v2"] } magicblock-core = { workspace = true } magicblock-committor-program = { workspace = true, features = [ "no-entrypoint", @@ -26,6 +30,7 @@ program-schedulecommit = { workspace = true, features = ["no-entrypoint"] } rand = { workspace = true } solana-account = { workspace = true } solana-commitment-config = { workspace = true } +solana-compute-budget-interface = { workspace = true } solana-pubkey = { workspace = true } solana-rpc-client = { workspace = true } solana-rpc-client-api = { workspace = true } diff --git a/test-integration/test-committor-service/tests/common.rs b/test-integration/test-committor-service/tests/common.rs index 66f896211..cb688240e 100644 --- a/test-integration/test-committor-service/tests/common.rs +++ b/test-integration/test-committor-service/tests/common.rs @@ -7,11 +7,12 @@ use std::{ }; use async_trait::async_trait; +use light_client::indexer::photon_indexer::PhotonIndexer; use magicblock_committor_service::{ intent_executor::{ task_info_fetcher::{ - CacheTaskInfoFetcher, TaskInfoFetcher, TaskInfoFetcherError, - TaskInfoFetcherResult, + CacheTaskInfoFetcher, CompressedData, TaskInfoFetcher, + TaskInfoFetcherError, TaskInfoFetcherResult, }, IntentExecutorImpl, }, @@ -45,9 +46,15 @@ pub async fn create_test_client() -> MagicblockRpcClient { MagicblockRpcClient::new(Arc::new(rpc_client)) } +pub fn create_test_photon_indexer() -> Arc { + Arc::new(PhotonIndexer::new("http://localhost:8784".to_string())) +} + // Test fixture structure pub struct TestFixture { pub rpc_client: MagicblockRpcClient, + #[allow(dead_code)] + pub photon_indexer: Arc, pub table_mania: TableMania, #[allow(dead_code)] pub authority: Keypair, @@ -63,6 +70,7 @@ impl TestFixture { pub async fn new_with_keypair(authority: Keypair) -> Self { let rpc_client = create_test_client().await; + let photon_indexer = create_test_photon_indexer(); // TableMania let gc_config = GarbageCollectorConfig::default(); @@ -81,6 +89,7 @@ impl TestFixture { let compute_budget_config = ComputeBudgetConfig::new(1_000_000); Self { rpc_client, + photon_indexer, table_mania, authority, compute_budget_config, @@ -171,6 +180,7 @@ impl TaskInfoFetcher for MockTaskInfoFetcher { async fn fetch_next_commit_nonces( &self, pubkeys: &[Pubkey], + _: bool, _: u64, ) -> TaskInfoFetcherResult> { Ok(pubkeys.iter().map(|pubkey| (*pubkey, 0)).collect()) @@ -179,6 +189,7 @@ impl TaskInfoFetcher for MockTaskInfoFetcher { async fn fetch_current_commit_nonces( &self, pubkeys: &[Pubkey], + _: bool, _: u64, ) -> TaskInfoFetcherResult> { Ok(pubkeys.iter().map(|pubkey| (*pubkey, 0)).collect()) @@ -211,6 +222,14 @@ impl TaskInfoFetcher for MockTaskInfoFetcher { .collect() }) } + + async fn get_compressed_data( + &self, + _: &Pubkey, + _: Option, + ) -> TaskInfoFetcherResult { + Ok(CompressedData::default()) + } } #[allow(dead_code)] diff --git a/test-integration/test-committor-service/tests/test_intent_executor.rs b/test-integration/test-committor-service/tests/test_intent_executor.rs index 5355379d3..13c358965 100644 --- a/test-integration/test-committor-service/tests/test_intent_executor.rs +++ b/test-integration/test-committor-service/tests/test_intent_executor.rs @@ -103,9 +103,11 @@ impl TestEnv { .await; let transaction_preparator = fixture.create_transaction_preparator(); - let task_info_fetcher = Arc::new(CacheTaskInfoFetcher::new( - RpcTaskInfoFetcher::new(fixture.rpc_client.clone()), - )); + let task_info_fetcher = + Arc::new(CacheTaskInfoFetcher::new(RpcTaskInfoFetcher::new( + fixture.rpc_client.clone(), + Some(fixture.photon_indexer.clone()), + ))); let tm = &fixture.table_mania; let mut pre_test_tablemania_state = HashMap::new(); @@ -160,6 +162,7 @@ async fn test_commit_id_error_parsing() { task_info_fetcher .fetch_next_commit_nonces( &intent.get_undelegate_intent_pubkeys().unwrap(), + false, remote_slot, ) .await @@ -486,7 +489,11 @@ async fn test_commit_id_error_recovery() { // Invalidate commit nonce cache let res = task_info_fetcher - .fetch_next_commit_nonces(&[committed_account.pubkey], remote_slot) + .fetch_next_commit_nonces( + &[committed_account.pubkey], + false, + remote_slot, + ) .await; assert!(res.is_ok()); assert!(res.unwrap().contains_key(&committed_account.pubkey)); @@ -696,7 +703,11 @@ async fn test_commit_id_and_action_errors_recovery() { // Invalidate commit nonce cache let res = task_info_fetcher - .fetch_next_commit_nonces(&[committed_account.pubkey], remote_slot) + .fetch_next_commit_nonces( + &[committed_account.pubkey], + false, + remote_slot, + ) .await; assert!(res.is_ok()); assert!(res.unwrap().contains_key(&committed_account.pubkey)); @@ -917,7 +928,7 @@ async fn test_commit_id_actions_cpi_limit_errors_recovery() { // Force CommitIDError by invalidating the commit-nonce cache before running let pubkeys: Vec<_> = committed_accounts.iter().map(|c| c.pubkey).collect(); let mut invalidated_keys = task_info_fetcher - .fetch_next_commit_nonces(&pubkeys, Default::default()) + .fetch_next_commit_nonces(&pubkeys, false, Default::default()) .await .unwrap(); @@ -1273,9 +1284,11 @@ async fn test_action_callback_fired_on_timeout() { // Build executor with zero timeout so actions time out before execution let callback_executor = MockActionsCallbackExecutor::default(); - let task_info_fetcher = Arc::new(CacheTaskInfoFetcher::new( - RpcTaskInfoFetcher::new(fixture.rpc_client.clone()), - )); + let task_info_fetcher = + Arc::new(CacheTaskInfoFetcher::new(RpcTaskInfoFetcher::new( + fixture.rpc_client.clone(), + Some(fixture.photon_indexer.clone()), + ))); let mut intent_executor = IntentExecutorImpl::new( fixture.rpc_client.clone(), fixture.create_transaction_preparator(), diff --git a/test-integration/test-committor-service/tests/test_ix_commit_local.rs b/test-integration/test-committor-service/tests/test_ix_commit_local.rs index d18d0575f..ce8c68412 100644 --- a/test-integration/test-committor-service/tests/test_ix_commit_local.rs +++ b/test-integration/test-committor-service/tests/test_ix_commit_local.rs @@ -4,7 +4,11 @@ use std::{ time::{Duration, Instant}, }; -use borsh::to_vec; +use borsh::{to_vec, BorshDeserialize}; +use compressed_delegation_client::CompressedDelegationRecord; +use light_client::indexer::{ + photon_indexer::PhotonIndexer, Indexer, IndexerRpcConfig, +}; use magicblock_committor_service::{ config::ChainConfig, intent_executor::{error::IntentExecutorError, ExecutionOutput}, @@ -12,10 +16,16 @@ use magicblock_committor_service::{ service_ext::{BaseIntentCommittorExt, CommittorServiceExt}, BaseIntentCommittor, CommittorService, ComputeBudgetConfig, }; -use magicblock_core::intent::CommittedAccount; -use magicblock_program::magic_scheduled_base_intent::{ - CommitAndUndelegate, CommitType, MagicBaseIntent, MagicIntentBundle, - ScheduledIntentBundle, UndelegateType, +use magicblock_core::{ + compression::derive_cda_from_pda, intent::CommittedAccount, +}; +use magicblock_program::{ + init_magic_sys, + magic_scheduled_base_intent::{ + CommitAndUndelegate, CommitType, MagicBaseIntent, MagicIntentBundle, + ScheduledIntentBundle, UndelegateType, + }, + test_utils::MagicSysStub, }; use magicblock_rpc_client::MagicblockRpcClient; use program_flexi_counter::state::FlexiCounter; @@ -23,6 +33,7 @@ use solana_account::{Account, ReadableAccount}; use solana_commitment_config::CommitmentConfig; use solana_pubkey::Pubkey; use solana_rpc_client::nonblocking::rpc_client::RpcClient; +use solana_rpc_client_api::config::RpcTransactionConfig; use solana_sdk::{ hash::Hash, signature::Keypair, signer::Signer, transaction::Transaction, }; @@ -37,6 +48,7 @@ use crate::utils::{ transactions::{ fund_validator_auth_and_ensure_validator_fees_vault, init_and_delegate_account_on_chain, + init_and_delegate_compressed_record_on_chain, }, }; @@ -60,6 +72,8 @@ enum CommitIntentKind { CommitAndUndelegate, CommitFinalize, CommitFinalizeAndUndelegate, + CommitFinalizeCompressed, + CommitFinalizeCompressedAndUndelegate, } fn expect_strategies( @@ -72,6 +86,11 @@ fn expect_strategies( expected_strategies } +fn setup_test() { + init_logger!(); + init_magic_sys(Arc::new(MagicSysStub::default())); +} + // ----------------- // +++++ Tests +++++ // ----------------- @@ -239,7 +258,7 @@ async fn commit_single_account( expected_strategy: CommitStrategy, commit_type: CommitIntentKind, ) { - init_logger!(); + setup_test(); let validator_auth = ensure_validator_authority(); fund_validator_auth_and_ensure_validator_fees_vault(&validator_auth).await; @@ -255,9 +274,23 @@ async fn commit_single_account( let service = CommittorServiceExt::new(Arc::new(service)); let counter_auth = Keypair::new(); - let (pubkey, mut account) = - init_and_delegate_account_on_chain(&counter_auth, bytes as u64, None) - .await; + let (pubkey, mut account) = match commit_type { + CommitIntentKind::CommitFinalizeCompressed + | CommitIntentKind::CommitFinalizeCompressedAndUndelegate => { + let (pubkey, _address, account) = + init_and_delegate_compressed_record_on_chain(&counter_auth) + .await; + (pubkey, account) + } + _ => { + init_and_delegate_account_on_chain( + &counter_auth, + bytes as u64, + None, + ) + .await + } + }; let counter = FlexiCounter { label: "Counter".to_string(), @@ -295,6 +328,19 @@ async fn commit_single_account( undelegate_action: UndelegateType::Standalone, }) } + CommitIntentKind::CommitFinalizeCompressed => { + MagicBaseIntent::CommitFinalizeCompressed(CommitType::Standalone( + vec![account], + )) + } + CommitIntentKind::CommitFinalizeCompressedAndUndelegate => { + MagicBaseIntent::CommitFinalizeAndUndelegateCompressed( + CommitAndUndelegate { + commit_action: CommitType::Standalone(vec![account]), + undelegate_action: UndelegateType::Standalone, + }, + ) + } }; let intent = ScheduledIntentBundle { @@ -321,7 +367,7 @@ async fn commit_book_order_account( expected_strategy: CommitStrategy, commit_type: CommitIntentKind, ) { - init_logger!(); + setup_test(); let validator_auth = ensure_validator_authority(); fund_validator_auth_and_ensure_validator_fees_vault(&validator_auth).await; @@ -375,6 +421,10 @@ async fn commit_book_order_account( undelegate_action: UndelegateType::Standalone, }) } + CommitIntentKind::CommitFinalizeCompressed + | CommitIntentKind::CommitFinalizeCompressedAndUndelegate => { + unimplemented!("Order book compressed delegation not yet supported") + } }; let intent = ScheduledIntentBundle { @@ -404,7 +454,6 @@ async fn commit_book_order_account( #[tokio::test] async fn test_ix_commit_two_accounts_1kb_2kb() { - init_logger!(); commit_multiple_accounts( &[1024, 2048], 1, @@ -416,7 +465,6 @@ async fn test_ix_commit_two_accounts_1kb_2kb() { #[tokio::test] async fn test_ix_commit_two_accounts_512kb() { - init_logger!(); commit_multiple_accounts( &[512, 512], 1, @@ -428,7 +476,6 @@ async fn test_ix_commit_two_accounts_512kb() { #[tokio::test] async fn test_ix_commit_three_accounts_512kb() { - init_logger!(); commit_multiple_accounts( &[512, 512, 512], 1, @@ -440,7 +487,6 @@ async fn test_ix_commit_three_accounts_512kb() { #[tokio::test] async fn test_ix_commit_six_accounts_512kb() { - init_logger!(); commit_multiple_accounts( &[512, 512, 512, 512, 512, 512], 1, @@ -452,7 +498,6 @@ async fn test_ix_commit_six_accounts_512kb() { #[tokio::test] async fn test_ix_commit_four_accounts_1kb_2kb_5kb_10kb_single_bundle() { - init_logger!(); commit_multiple_accounts( &[1024, 2 * 1024, 5 * 1024, 10 * 1024], 1, @@ -653,6 +698,7 @@ async fn test_ix_execute_intent_bundle_commit_and_cau_simultaneously_union_of_ac &[], &[1024, 2048], expect_strategies(&[(CommitStrategy::DiffBufferWithLookupTable, 4)]), + false, ) .await; } @@ -664,6 +710,7 @@ async fn test_ix_execute_intent_bundle_commit_three_accounts_cau_one_account() { &[], &[512], expect_strategies(&[(CommitStrategy::DiffBufferWithLookupTable, 4)]), + false, ) .await; } @@ -675,6 +722,7 @@ async fn test_ix_execute_intent_bundle_mixed_fits_in_args() { &[], &[20], expect_strategies(&[(CommitStrategy::StateArgs, 4)]), + false, ) .await; } @@ -686,6 +734,7 @@ async fn test_ix_execute_intent_bundle_commit_finalize_only() { &[10, 20], &[], expect_strategies(&[(CommitStrategy::StateArgs, 2)]), + false, ) .await; } @@ -697,6 +746,102 @@ async fn test_ix_execute_intent_bundle_commit_and_commit_finalize_mixed() { &[1024, 2048], &[], expect_strategies(&[(CommitStrategy::DiffArgs, 4)]), + false, + ) + .await; +} + +// ----------------- +// Compressed Account Commits +// ----------------- + +#[tokio::test] +async fn test_ix_commit_single_compressed_account_100_bytes() { + commit_n_accounts_x_bytes::<1, 100>( + 1, + expect_strategies(&[(CommitStrategy::StateArgs, 1)]), + CommitIntentKind::CommitFinalizeCompressed, + ) + .await; +} + +#[tokio::test] +async fn test_ix_commit_single_compressed_account_100_bytes_and_undelegate() { + commit_n_accounts_x_bytes::<1, 100>( + 1, + expect_strategies(&[(CommitStrategy::StateArgs, 1)]), + CommitIntentKind::CommitFinalizeCompressedAndUndelegate, + ) + .await; +} + +#[tokio::test] +async fn test_ix_commit_single_compressed_account_500_bytes() { + commit_n_accounts_x_bytes::<1, 500>( + 1, + expect_strategies(&[(CommitStrategy::StateArgs, 1)]), + CommitIntentKind::CommitFinalizeCompressed, + ) + .await; +} + +#[tokio::test] +async fn test_ix_commit_single_compressed_account_500_bytes_and_undelegate() { + commit_n_accounts_x_bytes::<1, 500>( + 1, + expect_strategies(&[(CommitStrategy::StateArgs, 1)]), + CommitIntentKind::CommitFinalizeCompressedAndUndelegate, + ) + .await; +} + +#[tokio::test] +async fn test_ix_commit_two_compressed_accounts_512_bytes() { + commit_n_accounts_x_bytes::<2, 512>( + 1, + expect_strategies(&[(CommitStrategy::StateArgs, 2)]), + CommitIntentKind::CommitFinalizeCompressed, + ) + .await; +} + +#[tokio::test] +async fn test_ix_commit_three_compressed_accounts_512_bytes() { + commit_n_accounts_x_bytes::<3, 512>( + 1, + expect_strategies(&[(CommitStrategy::StateArgs, 3)]), + CommitIntentKind::CommitFinalizeCompressed, + ) + .await; +} + +#[tokio::test] +async fn test_ix_commit_six_compressed_accounts_512_bytes() { + commit_n_accounts_x_bytes::<6, 512>( + 1, + expect_strategies(&[(CommitStrategy::StateArgs, 6)]), + CommitIntentKind::CommitFinalizeCompressed, + ) + .await; +} + +#[tokio::test] +async fn test_commit_20_compressed_accounts_100bytes_bundle_size_2() { + commit_n_accounts_x_bytes::<20, 100>( + 2, + expect_strategies(&[(CommitStrategy::StateArgs, 20)]), + CommitIntentKind::CommitFinalizeCompressed, + ) + .await; +} + +#[tokio::test] +async fn test_commit_5_compressed_accounts_100bytes_bundle_size_2_undelegate_all( +) { + commit_n_accounts_x_bytes::<5, 100>( + 2, + expect_strategies(&[(CommitStrategy::StateArgs, 5)]), + CommitIntentKind::CommitFinalizeCompressedAndUndelegate, ) .await; } @@ -706,13 +851,10 @@ async fn commit_5_accounts_1kb( expected_strategies: ExpectedStrategies, commit_type: CommitIntentKind, ) { - init_logger!(); - let accs = (0..5).map(|_| 1024).collect::>(); - commit_multiple_accounts( - &accs, + commit_n_accounts_x_bytes::<5, 1024>( bundle_size, - commit_type, expected_strategies, + commit_type, ) .await; } @@ -722,13 +864,10 @@ async fn commit_8_accounts_1kb( expected_strategies: ExpectedStrategies, commit_type: CommitIntentKind, ) { - init_logger!(); - let accs = (0..8).map(|_| 1024).collect::>(); - commit_multiple_accounts( - &accs, + commit_n_accounts_x_bytes::<8, 1024>( bundle_size, - commit_type, expected_strategies, + commit_type, ) .await; } @@ -738,8 +877,23 @@ async fn commit_20_accounts_1kb( expected_strategies: ExpectedStrategies, commit_type: CommitIntentKind, ) { - init_logger!(); - let accs = (0..20).map(|_| 1024).collect::>(); + commit_n_accounts_x_bytes::<20, 1024>( + bundle_size, + expected_strategies, + commit_type, + ) + .await; +} + +async fn commit_n_accounts_x_bytes< + const ACCOUNTS: usize, + const BYTES: usize, +>( + bundle_size: usize, + expected_strategies: ExpectedStrategies, + commit_type: CommitIntentKind, +) { + let accs = (0..ACCOUNTS).map(|_| BYTES).collect::>(); commit_multiple_accounts( &accs, bundle_size, @@ -751,18 +905,26 @@ async fn commit_20_accounts_1kb( async fn create_and_delegate_accounts( bytess: &[usize], + compressed: bool, ) -> Vec { let mut join_set = JoinSet::new(); for bytes in bytess { let bytes = *bytes; join_set.spawn(async move { let counter_auth = Keypair::new(); - let (pda, mut pda_acc) = init_and_delegate_account_on_chain( - &counter_auth, - bytes as u64, - None, - ) - .await; + let (pda, mut pda_acc) = if compressed { + let (pda, _address, account) = + init_and_delegate_compressed_record_on_chain(&counter_auth) + .await; + (pda, account) + } else { + init_and_delegate_account_on_chain( + &counter_auth, + bytes as u64, + None, + ) + .await + }; pda_acc.owner = program_flexi_counter::id(); pda_acc.data = vec![0u8; bytes]; @@ -774,15 +936,15 @@ async fn create_and_delegate_accounts( }); } - // Wait for all tasks to complete join_set.join_all().await } async fn create_bundles( bundle_size: usize, bytess: &[usize], + compressed: bool, ) -> Vec> { - let committed = create_and_delegate_accounts(bytess).await; + let committed = create_and_delegate_accounts(bytess, compressed).await; committed .chunks(bundle_size) .map(|chunk| chunk.to_vec()) @@ -795,7 +957,7 @@ async fn commit_multiple_accounts( commit_type: CommitIntentKind, expected_strategies: ExpectedStrategies, ) { - init_logger!(); + setup_test(); let validator_auth = ensure_validator_authority(); fund_validator_auth_and_ensure_validator_fees_vault(&validator_auth).await; @@ -810,7 +972,16 @@ async fn commit_multiple_accounts( let service = CommittorServiceExt::new(Arc::new(service)); // Create bundles of committed accounts - let bundles_of_committees = create_bundles(bundle_size, bytess).await; + let bundles_of_committees = create_bundles( + bundle_size, + bytess, + matches!( + commit_type, + CommitIntentKind::CommitFinalizeCompressed + | CommitIntentKind::CommitFinalizeCompressedAndUndelegate + ), + ) + .await; // Create intent for each bundle let intents = bundles_of_committees .into_iter() @@ -837,6 +1008,19 @@ async fn commit_multiple_accounts( }, ) } + CommitIntentKind::CommitFinalizeCompressed => { + MagicBaseIntent::CommitFinalizeCompressed( + CommitType::Standalone(committees), + ) + } + CommitIntentKind::CommitFinalizeCompressedAndUndelegate => { + MagicBaseIntent::CommitFinalizeAndUndelegateCompressed( + CommitAndUndelegate { + commit_action: CommitType::Standalone(committees), + undelegate_action: UndelegateType::Standalone, + }, + ) + } }) .enumerate() .map(|(id, base_intent)| ScheduledIntentBundle { @@ -863,8 +1047,9 @@ async fn execute_intent_bundle( bytess_to_commit_finalize: &[usize], bytes_to_undelegate: &[usize], expected_strategies: ExpectedStrategies, + compressed: bool, ) { - init_logger!(); + setup_test(); let validator_auth = ensure_validator_authority(); fund_validator_auth_and_ensure_validator_fees_vault(&validator_auth).await; @@ -879,10 +1064,11 @@ async fn execute_intent_bundle( let service = CommittorServiceExt::new(Arc::new(service)); // Create bundles of committed accounts - let to_commit = create_and_delegate_accounts(bytess_to_commit); + let to_commit = create_and_delegate_accounts(bytess_to_commit, compressed); let to_commit_finalize = - create_and_delegate_accounts(bytess_to_commit_finalize); - let to_undelegate = create_and_delegate_accounts(bytes_to_undelegate); + create_and_delegate_accounts(bytess_to_commit_finalize, compressed); + let to_undelegate = + create_and_delegate_accounts(bytes_to_undelegate, compressed); let (committees, commit_finalize_committees, undelegetees) = tokio::join!(to_commit, to_commit_finalize, to_undelegate); @@ -964,6 +1150,8 @@ async fn ix_commit_local( service.release_common_pubkeys().await.unwrap(); let rpc_client = RpcClient::new("http://localhost:7799".to_string()); + let photon_indexer = + PhotonIndexer::new("http://localhost:8784".to_string()); let mut strategies = ExpectedStrategies::new(); for (execution_result, base_intent) in execution_outputs .into_iter() @@ -1012,11 +1200,17 @@ async fn ix_commit_local( let undelegated_accounts = base_intent.get_undelegate_intent_accounts(); let commit_finalized_and_undelegated_accounts = base_intent.get_commit_finalize_and_undelegate_intent_accounts(); + let commit_finalize_compressed_accounts = + base_intent.get_commit_finalize_compressed_intent_accounts(); + let commit_finalize_compressed_and_undelegate_accounts = base_intent + .get_commit_finalize_compressed_and_undelegate_intent_accounts(); let has_commit_flow = committed_accounts.is_some() || undelegated_accounts.is_some(); let has_commit_finalize_flow = committed_finalize_accounts.is_some() - || commit_finalized_and_undelegated_accounts.is_some(); + || commit_finalized_and_undelegated_accounts.is_some() + || commit_finalize_compressed_accounts.is_some() + || commit_finalize_compressed_and_undelegate_accounts.is_some(); if has_commit_flow { assert!( tx_logs_contain(&rpc_client, &commit_signature, "CommitState") @@ -1038,8 +1232,10 @@ async fn ix_commit_local( ); } + let has_compressed_undelegate = + commit_finalize_compressed_and_undelegate_accounts.is_some(); let has_undelegate = base_intent.has_undelegate_intent(); - if has_undelegate { + if has_undelegate && !has_compressed_undelegate { // Undelegate is part of atomic Finalization Stage assert!( tx_logs_contain(&rpc_client, &finalize_signature, "Undelegate") @@ -1048,15 +1244,21 @@ async fn ix_commit_local( } let mut committed_accounts: HashMap = [ - (false, committed_accounts), - (true, undelegated_accounts), - (false, committed_finalize_accounts), - (true, commit_finalized_and_undelegated_accounts), + (false, false, committed_accounts), + (true, false, undelegated_accounts), + (false, false, committed_finalize_accounts), + (true, false, commit_finalized_and_undelegated_accounts), + (false, true, commit_finalize_compressed_accounts), + ( + true, + true, + commit_finalize_compressed_and_undelegate_accounts, + ), ] .into_iter() - .flat_map(|(allow_undelegation, accounts)| { + .flat_map(|(allow_undelegation, compressed, accounts)| { accounts.into_iter().flatten().map(move |account| { - (account.pubkey, (allow_undelegation, account)) + (account.pubkey, (allow_undelegation, compressed, account)) }) }) .collect(); @@ -1078,35 +1280,72 @@ async fn ix_commit_local( assert_eq!(statuses.len(), committed_accounts.len()); for commit_status in statuses { - let (is_undelegate, account) = committed_accounts + let (is_undelegate, is_compressed, account) = committed_accounts .remove(&commit_status.pubkey) .expect("Account should be persisted"); println!("account: {}", account.pubkey); - // When we finalize it is possible to also undelegate the account - let expected_owner = if is_undelegate { - program_id + if !is_compressed { + // When we finalize it is possible to also undelegate the account + let expected_owner = if is_undelegate { + program_id + } else { + dlp_api::id() + }; + + let lamports = account.account.lamports; + get_account!( + rpc_client, + account.pubkey, + "delegated state", + |acc: &Account, remaining_tries: u8| { + validate_account( + acc, + remaining_tries, + &account.account.data, + lamports, + expected_owner, + account.pubkey, + has_undelegate, + ) + } + ); } else { - dlp_api::id() - }; - - let lamports = account.account.lamports; - get_account!( - rpc_client, - account.pubkey, - "delegated state", - |acc: &Account, remaining_tries: u8| { - validate_account( - acc, - remaining_tries, - &account.account.data, - lamports, - expected_owner, - account.pubkey, - has_undelegate, + let min_context_slot = rpc_client + .get_transaction_with_config( + &commit_signature, + RpcTransactionConfig { + commitment: Some(CommitmentConfig::confirmed()), + max_supported_transaction_version: Some(0), + ..Default::default() + }, ) - } - ); + .await + .unwrap() + .slot; + + let cda = derive_cda_from_pda(&account.pubkey); + let compressed_account = photon_indexer + .get_compressed_account( + cda.to_bytes(), + Some(IndexerRpcConfig::new(min_context_slot)), + ) + .await + .unwrap() + .value + .unwrap(); + let compressed_record = + CompressedDelegationRecord::try_from_slice( + &compressed_account.data.unwrap().data, + ) + .unwrap(); + // Compressed accounts never have lamports when delegated/committed + // and they are not delegated by the validator, just marked as undelegatable + assert_eq!(compressed_record.owner, program_id); + assert_eq!(compressed_record.data, account.account.data); + assert_eq!(compressed_record.lamports, 0); + assert_eq!(compressed_record.is_undelegatable, is_undelegate); + } // Track the strategy used let strategy = commit_status.commit_strategy; diff --git a/test-integration/test-committor-service/tests/utils/instructions.rs b/test-integration/test-committor-service/tests/utils/instructions.rs index 7e4b6585f..310019349 100644 --- a/test-integration/test-committor-service/tests/utils/instructions.rs +++ b/test-integration/test-committor-service/tests/utils/instructions.rs @@ -1,6 +1,32 @@ +use std::sync::Arc; + +use light_client::indexer::{ + photon_indexer::PhotonIndexer, AddressWithTree, Indexer, + ValidityProofWithContext, +}; +use light_sdk::{ + instruction::{ + account_meta::CompressedAccountMeta, PackedAccounts, + SystemAccountMetaConfig, + }, + sdk_types::PackedAddressTreeInfo, +}; +use magicblock_core::compression::{ + derive_cda_from_pda, ADDRESS_TREE, OUTPUT_QUEUE, +}; +use magicblock_program::validator::validator_authority_id; +use program_flexi_counter::{ + instruction::{ + create_delegate_compressed_ix, + create_init_compressed_delegation_record_ix, create_init_ix, + DelegateCompressedArgs, InitDelegationRecordArgs, + }, + state::FlexiCounter, +}; use solana_pubkey::Pubkey; use solana_sdk::{instruction::Instruction, rent::Rent, signature::Keypair}; use test_kit::Signer; +use tokio::time::{sleep, Duration}; pub fn init_validator_fees_vault_ix(validator_auth: Pubkey) -> Instruction { dlp_api::instruction_builder::init_validator_fees_vault( @@ -18,6 +44,18 @@ pub struct InitAccountAndDelegateIxs { pub rent_excempt: u64, } +pub struct InitAccountAndCompressedRecordIxs { + pub init: Instruction, + pub init_record: Instruction, + pub pda: Pubkey, +} + +pub struct DelegateCompressedIx { + pub delegate: Instruction, + pub pda: Pubkey, + pub address: [u8; 32], +} + pub fn init_account_and_delegate_ixs( payer: Pubkey, bytes: u64, @@ -51,6 +89,160 @@ pub fn init_account_and_delegate_ixs( } } +pub async fn init_account_and_compressed_record_ixs( + payer: Pubkey, + photon_indexer: Arc, +) -> InitAccountAndCompressedRecordIxs { + let (pda, _bump) = FlexiCounter::pda(&payer); + let record_address = derive_cda_from_pda(&pda); + + let init_counter_ix = create_init_ix(payer, "COUNTER".to_string()); + + let system_account_meta_config = SystemAccountMetaConfig::new( + compressed_delegation_client::ID.to_bytes().into(), + ); + let mut remaining_accounts = PackedAccounts::default(); + remaining_accounts + .add_system_accounts_v2(system_account_meta_config) + .unwrap(); + + let rpc_result: ValidityProofWithContext = photon_indexer + .get_validity_proof( + vec![], + vec![AddressWithTree { + address: record_address.to_bytes(), + tree: ADDRESS_TREE.to_bytes().into(), + }], + None, + ) + .await + .unwrap() + .value; + + // Insert trees in accounts + let address_merkle_tree_pubkey_index = + remaining_accounts.insert_or_get(ADDRESS_TREE.to_bytes().into()); + let state_queue_pubkey_index = + remaining_accounts.insert_or_get(OUTPUT_QUEUE.to_bytes().into()); + + let packed_address_tree_info = PackedAddressTreeInfo { + root_index: rpc_result.addresses[0].root_index, + address_merkle_tree_pubkey_index, + address_queue_pubkey_index: address_merkle_tree_pubkey_index, + }; + + let (remaining_accounts_metas, _, _) = + remaining_accounts.to_account_metas(); + + let init_record_ix = create_init_compressed_delegation_record_ix( + payer, + &remaining_accounts_metas + .iter() + .map(|meta| solana_sdk::message::AccountMeta { + pubkey: meta.pubkey.to_bytes().into(), + is_signer: meta.is_signer, + is_writable: meta.is_writable, + }) + .collect::>(), + InitDelegationRecordArgs { + validity_proof: rpc_result.proof.into(), + address_tree_info: packed_address_tree_info.into(), + output_state_tree_index: state_queue_pubkey_index, + }, + ); + + InitAccountAndCompressedRecordIxs { + init: init_counter_ix, + init_record: init_record_ix, + pda, + } +} + +pub async fn delegate_compressed_ixs( + payer: Pubkey, + photon_indexer: Arc, +) -> DelegateCompressedIx { + let (pda, _bump) = FlexiCounter::pda(&payer); + let record_address = derive_cda_from_pda(&pda); + + let compressed_account = { + const MAX_ATTEMPTS: u32 = 150; + let mut compressed_account = None; + for attempt in 0..MAX_ATTEMPTS { + if let Ok(resp) = photon_indexer + .get_compressed_account(record_address.to_bytes(), None) + .await + { + if let Some(acc) = resp.value { + compressed_account = Some(acc); + break; + } + } + if attempt + 1 == MAX_ATTEMPTS { + panic!( + "Photon did not return compressed account for {:?} after {} ms", + record_address, + MAX_ATTEMPTS * 200 + ); + } + sleep(Duration::from_millis(200)).await; + } + compressed_account.expect("Photon indexing loop exited without account") + }; + + let system_account_meta_config = SystemAccountMetaConfig::new( + compressed_delegation_client::ID.to_bytes().into(), + ); + let mut remaining_accounts = PackedAccounts::default(); + remaining_accounts + .add_system_accounts_v2(system_account_meta_config) + .unwrap(); + + let rpc_result: ValidityProofWithContext = photon_indexer + .get_validity_proof(vec![compressed_account.hash], vec![], None) + .await + .unwrap() + .value; + + // Insert trees in accounts + let state_queue_pubkey_index = + remaining_accounts.insert_or_get(OUTPUT_QUEUE.to_bytes().into()); + + let packed_trees_info = rpc_result.pack_tree_infos(&mut remaining_accounts); + let packed_state_tree_info = packed_trees_info.state_trees.unwrap(); + + let (remaining_accounts_metas, _, _) = + remaining_accounts.to_account_metas(); + + let delegate_ix = create_delegate_compressed_ix( + payer, + &remaining_accounts_metas + .iter() + .map(|meta| solana_sdk::message::AccountMeta { + pubkey: meta.pubkey.to_bytes().into(), + is_signer: meta.is_signer, + is_writable: meta.is_writable, + }) + .collect::>(), + DelegateCompressedArgs { + validator: Some(validator_authority_id()), + validity_proof: rpc_result.proof.into(), + account_meta: CompressedAccountMeta { + tree_info: packed_state_tree_info.packed_tree_infos[0], + address: compressed_account.address.unwrap(), + output_state_tree_index: state_queue_pubkey_index, + } + .into(), + }, + ); + + DelegateCompressedIx { + delegate: delegate_ix, + pda, + address: record_address.to_bytes(), + } +} + pub struct InitOrderBookAndDelegateIxs { pub init: Instruction, pub delegate: Instruction, diff --git a/test-integration/test-committor-service/tests/utils/transactions.rs b/test-integration/test-committor-service/tests/utils/transactions.rs index 5e01d0005..2f9aa79da 100644 --- a/test-integration/test-committor-service/tests/utils/transactions.rs +++ b/test-integration/test-committor-service/tests/utils/transactions.rs @@ -1,5 +1,11 @@ +use std::sync::Arc; + +use borsh::BorshDeserialize; +use compressed_delegation_client::CompressedDelegationRecord; +use light_client::indexer::{photon_indexer::PhotonIndexer, Indexer}; use solana_account::Account; use solana_commitment_config::CommitmentConfig; +use solana_compute_budget_interface::ComputeBudgetInstruction; use solana_pubkey::Pubkey; use solana_rpc_client::nonblocking::rpc_client::RpcClient; use solana_rpc_client_api::config::{ @@ -14,8 +20,10 @@ use solana_system_interface::instruction as system_instruction; use tracing::{debug, error}; use crate::utils::instructions::{ + delegate_compressed_ixs, init_account_and_compressed_record_ixs, init_account_and_delegate_ixs, init_order_book_account_and_delegate_ixs, - init_validator_fees_vault_ix, InitAccountAndDelegateIxs, + init_validator_fees_vault_ix, DelegateCompressedIx, + InitAccountAndCompressedRecordIxs, InitAccountAndDelegateIxs, InitOrderBookAndDelegateIxs, }; @@ -104,7 +112,7 @@ pub async fn fetch_tx_logs( retries -= 1; if retries == 0 { panic!( - "Failed to get transaction after {} retries", + "Failed to get transaction {signature} after {} retries", MAX_RETRIES ); } @@ -189,6 +197,9 @@ pub async fn tx_logs_contain( log.contains(needle) || log.contains("CommitDiff") || log.contains("CommitFinalize") + || log.contains("CommitAndFinalize") + } else if needle == "CommitFinalize" { + log.contains(needle) || log.contains("CommitAndFinalize") } else { log.contains(needle) } @@ -317,6 +328,122 @@ pub async fn init_and_delegate_account_on_chain( (pda, pda_acc) } +/// This needs to be run for each test that required a new counter to be compressed delegated +#[allow(dead_code)] +pub async fn init_and_delegate_compressed_record_on_chain( + counter_auth: &Keypair, +) -> (Pubkey, [u8; 32], Account) { + let rpc_client = RpcClient::new("http://localhost:7799".to_string()); + let photon_indexer = + Arc::new(PhotonIndexer::new("http://localhost:8784".to_string())); + + airdrop_and_confirm( + &rpc_client, + &counter_auth.pubkey(), + LAMPORTS_PER_SOL, + "counter auth", + ) + .await; + debug!("Airdropped to counter auth: {} SOL", LAMPORTS_PER_SOL); + + let InitAccountAndCompressedRecordIxs { + init: init_counter_ix, + init_record: init_record_ix, + pda, + } = init_account_and_compressed_record_ixs( + counter_auth.pubkey(), + photon_indexer.clone(), + ) + .await; + + let latest_block_hash = rpc_client.get_latest_blockhash().await.unwrap(); + // 1. Init account and record + rpc_client + .send_and_confirm_transaction_with_spinner_and_config( + &Transaction::new_signed_with_payer( + &[init_counter_ix, init_record_ix], + Some(&counter_auth.pubkey()), + &[&counter_auth], + latest_block_hash, + ), + CommitmentConfig::confirmed(), + RpcSendTransactionConfig { + skip_preflight: true, + ..Default::default() + }, + ) + .await + .expect("Failed to init account"); + debug!("Init account: {:?}", pda); + + let pda_acc = get_account!(rpc_client, pda, "pda"); + + // 2. Delegate + let DelegateCompressedIx { + delegate: delegate_ix, + pda, + address, + } = delegate_compressed_ixs(counter_auth.pubkey(), photon_indexer.clone()) + .await; + let latest_block_hash = rpc_client.get_latest_blockhash().await.unwrap(); + let tx = Transaction::new_signed_with_payer( + &[ + ComputeBudgetInstruction::set_compute_unit_limit(250_000), + delegate_ix, + ], + Some(&counter_auth.pubkey()), + &[&counter_auth], + latest_block_hash, + ); + rpc_client + .send_and_confirm_transaction_with_spinner_and_config( + &tx, + CommitmentConfig::confirmed(), + RpcSendTransactionConfig { + skip_preflight: true, + ..Default::default() + }, + ) + .await + .inspect_err(|err| { + error!( + "Failed to init compressed record: {err:?}, signature: {:?}", + tx.signatures[0] + ) + }) + .expect("Failed to init compressed record"); + + // Retry until we get a valid delegation record + const MAX_RETRIES: usize = 10; + let mut retries = MAX_RETRIES; + let compressed_delegation_record = loop { + let maybe_record = photon_indexer + .get_compressed_account(address, None) + .await + .unwrap() + .value + .and_then(|compressed_account| { + compressed_account.data.and_then(|data| { + CompressedDelegationRecord::try_from_slice(&data.data).ok() + }) + }); + if let Some(compressed_delegation_record) = maybe_record { + break compressed_delegation_record; + } + retries -= 1; + if retries == 0 { + panic!( + "Failed to get compressed account after {} retries", + MAX_RETRIES + ); + } + tokio::time::sleep(tokio::time::Duration::from_millis(100)).await; + }; + debug!("Compressed record: {:?}", compressed_delegation_record); + + (pda, address, pda_acc) +} + /// This needs to be run for each test that required a new order_book to be delegated #[allow(dead_code)] pub async fn init_and_delegate_order_book_on_chain( diff --git a/test-integration/test-runner/bin/run_tests.rs b/test-integration/test-runner/bin/run_tests.rs index fadd7f727..487d388ed 100644 --- a/test-integration/test-runner/bin/run_tests.rs +++ b/test-integration/test-runner/bin/run_tests.rs @@ -9,13 +9,16 @@ use integration_test_tools::{ loaded_accounts::LoadedAccounts, toml_to_args::ProgramLoader, validator::{ - resolve_workspace_dir, start_magic_block_validator_with_config, + resolve_workspace_dir, start_light_validator_with_config, + start_magic_block_validator_with_config, start_test_validator_with_config, TestRunnerPaths, }, }; use teepee::Teepee; use test_runner::{ - cleanup::{cleanup_devnet_only, cleanup_validators}, + cleanup::{ + cleanup_devnet_only, cleanup_light_validator, cleanup_validators, + }, env_config::TestConfigViaEnvVars, signal::wait_for_ctrlc, }; @@ -152,7 +155,7 @@ fn run_restore_ledger_tests( } else { let devnet_validator = config.setup_devnet(TEST_NAME).then(start_devnet_validator); - wait_for_ctrlc(devnet_validator, None, success_output()) + wait_for_ctrlc(devnet_validator, None, None, success_output()) } } @@ -187,9 +190,9 @@ fn run_chainlink_tests( ]); loaded_chain_accounts }; - let start_devnet_validator = || match start_validator( + let start_light_validator = || match start_validator( "chainlink-conf.devnet.toml", - ValidatorCluster::Chain(None), + ValidatorCluster::Light, &loaded_chain_accounts, ) { Some(validator) => validator, @@ -199,7 +202,7 @@ fn run_chainlink_tests( }; if config.run_test(TEST_NAME) { eprintln!("======== RUNNING CHAINLINK TESTS ========"); - let mut devnet_validator = start_devnet_validator(); + let mut light_validator = start_light_validator(); let test_chainlink_dir = format!("{}/../{}", manifest_dir, "test-chainlink"); eprintln!("Running chainlink tests in {}", test_chainlink_dir); @@ -207,16 +210,16 @@ fn run_chainlink_tests( Ok(output) => output, Err(err) => { eprintln!("Failed to run chainlink tests: {:?}", err); - cleanup_devnet_only(&mut devnet_validator); + cleanup_light_validator(&mut light_validator); return Err(err.into()); } }; - cleanup_devnet_only(&mut devnet_validator); + cleanup_light_validator(&mut light_validator); Ok(output) } else { - let devnet_validator = - config.setup_devnet(TEST_NAME).then(start_devnet_validator); - wait_for_ctrlc(devnet_validator, None, success_output()) + let light_validator = + config.setup_devnet(TEST_NAME).then(start_light_validator); + wait_for_ctrlc(None, light_validator, None, success_output()) } } @@ -474,10 +477,9 @@ fn run_table_mania_and_committor_tests( let loaded_chain_accounts = LoadedAccounts::with_delegation_program_test_authority(); - - let start_devnet_validator = || match start_validator( + let start_light_validator = || match start_validator( "committor-conf.devnet.toml", - ValidatorCluster::Chain(None), + ValidatorCluster::Light, &loaded_chain_accounts, ) { Some(validator) => validator, @@ -496,7 +498,7 @@ fn run_table_mania_and_committor_tests( if run_table_mania || !active_committor_subsets.is_empty() { eprintln!("======== Starting DEVNET Validator for TableMania and Committor ========"); - let mut devnet_validator = start_devnet_validator(); + let mut light_validator = start_light_validator(); // NOTE: the table mania and committor tests run directly against // a chain validator therefore no ephemeral validator needs to be started @@ -509,7 +511,7 @@ fn run_table_mania_and_committor_tests( Ok(output) => output, Err(err) => { eprintln!("Failed to run table-mania: {:?}", err); - cleanup_devnet_only(&mut devnet_validator); + cleanup_light_validator(&mut light_validator); return Err(err.into()); } } @@ -569,7 +571,7 @@ fn run_table_mania_and_committor_tests( } Err(err) => { eprintln!("Failed to run {}: {:?}", label, err); - cleanup_devnet_only(&mut devnet_validator); + cleanup_light_validator(&mut light_validator); return Err(err.into()); } } @@ -592,7 +594,7 @@ fn run_table_mania_and_committor_tests( success_output() }; - cleanup_devnet_only(&mut devnet_validator); + cleanup_light_validator(&mut light_validator); Ok((table_mania_test_output, committor_test_output)) } else { @@ -600,9 +602,9 @@ fn run_table_mania_and_committor_tests( || committor_shards .iter() .any(|(name, _)| config.setup_devnet(name)); - let devnet_validator = setup_needed.then(start_devnet_validator); + let light_validator = setup_needed.then(start_light_validator); Ok(( - wait_for_ctrlc(devnet_validator, None, success_output())?, + wait_for_ctrlc(None, light_validator, None, success_output())?, success_output(), )) } @@ -620,9 +622,9 @@ fn run_schedule_commit_tests( let loaded_chain_accounts = LoadedAccounts::with_delegation_program_test_authority(); - let start_devnet_validator = || match start_validator( + let start_light_validator = || match start_validator( "schedulecommit-conf.devnet.toml", - ValidatorCluster::Chain(None), + ValidatorCluster::Light, &loaded_chain_accounts, ) { Some(validator) => validator, @@ -647,7 +649,7 @@ fn run_schedule_commit_tests( "======== Starting DEVNET Validator for Scenarios + Security ========" ); - let mut devnet_validator = start_devnet_validator(); + let mut light_validator = start_light_validator(); // These share a common config that includes the program to schedule commits // Thus they can run against the same validator instances @@ -667,7 +669,8 @@ fn run_schedule_commit_tests( eprintln!("Failed to run security: {:?}", err); cleanup_validators( &mut ephem_validator, - &mut devnet_validator, + &mut light_validator, + true, ); return Err(err.into()); } @@ -683,21 +686,27 @@ fn run_schedule_commit_tests( eprintln!("Failed to run scenarios: {:?}", err); cleanup_validators( &mut ephem_validator, - &mut devnet_validator, + &mut light_validator, + true, ); return Err(err.into()); } }; - cleanup_validators(&mut ephem_validator, &mut devnet_validator); + cleanup_validators(&mut ephem_validator, &mut light_validator, true); Ok((test_security_output, test_scenarios_output)) } else { - let devnet_validator = - config.setup_devnet(TEST_NAME).then(start_devnet_validator); + let light_validator = + config.setup_devnet(TEST_NAME).then(start_light_validator); let ephem_validator = config.setup_ephem(TEST_NAME).then(start_ephem_validator); eprintln!("Setup validator(s)"); - wait_for_ctrlc(devnet_validator, ephem_validator, success_output())?; + wait_for_ctrlc( + None, + light_validator, + ephem_validator, + success_output(), + )?; Ok((success_output(), success_output())) } } @@ -770,18 +779,27 @@ fn run_cloning_tests( Ok(output) => output, Err(err) => { eprintln!("Failed to run cloning tests: {:?}", err); - cleanup_validators(&mut ephem_validator, &mut devnet_validator); + cleanup_validators( + &mut ephem_validator, + &mut devnet_validator, + false, + ); return Err(err.into()); } }; - cleanup_validators(&mut ephem_validator, &mut devnet_validator); + cleanup_validators(&mut ephem_validator, &mut devnet_validator, false); Ok(output) } else { let devnet_validator = config.setup_devnet(TEST_NAME).then(start_devnet_validator); let ephem_validator = config.setup_ephem(TEST_NAME).then(start_ephem_validator); - wait_for_ctrlc(devnet_validator, ephem_validator, success_output()) + wait_for_ctrlc( + devnet_validator, + None, + ephem_validator, + success_output(), + ) } } @@ -827,18 +845,27 @@ fn run_magicblock_api_tests( let output = run_test(test_dir, Default::default()).map_err(|err| { eprintln!("Failed to magicblock api tests: {:?}", err); - cleanup_validators(&mut ephem_validator, &mut devnet_validator); + cleanup_validators( + &mut ephem_validator, + &mut devnet_validator, + false, + ); err })?; - cleanup_validators(&mut ephem_validator, &mut devnet_validator); + cleanup_validators(&mut ephem_validator, &mut devnet_validator, false); Ok(output) } else { let devnet_validator = config.setup_devnet(TEST_NAME).then(start_devnet_validator); let ephem_validator = config.setup_ephem(TEST_NAME).then(start_ephem_validator); - wait_for_ctrlc(devnet_validator, ephem_validator, success_output()) + wait_for_ctrlc( + devnet_validator, + None, + ephem_validator, + success_output(), + ) } } @@ -886,18 +913,27 @@ fn run_magicblock_pubsub_tests( let output = run_test(test_dir, Default::default()).map_err(|err| { eprintln!("Failed to magicblock pubsub tests: {:?}", err); - cleanup_validators(&mut ephem_validator, &mut devnet_validator); + cleanup_validators( + &mut ephem_validator, + &mut devnet_validator, + false, + ); err })?; - cleanup_validators(&mut ephem_validator, &mut devnet_validator); + cleanup_validators(&mut ephem_validator, &mut devnet_validator, false); Ok(output) } else { let devnet_validator = config.setup_devnet(TEST_NAME).then(start_devnet_validator); let ephem_validator = config.setup_ephem(TEST_NAME).then(start_ephem_validator); - wait_for_ctrlc(devnet_validator, ephem_validator, success_output()) + wait_for_ctrlc( + devnet_validator, + None, + ephem_validator, + success_output(), + ) } } @@ -944,7 +980,7 @@ fn run_config_tests( } else { let devnet_validator = config.setup_devnet(TEST_NAME).then(start_devnet_validator); - wait_for_ctrlc(devnet_validator, None, success_output()) + wait_for_ctrlc(devnet_validator, None, None, success_output()) } } @@ -1003,18 +1039,27 @@ fn run_schedule_intents_tests( Ok(output) => output, Err(err) => { eprintln!("Failed to run issues: {:?}", err); - cleanup_validators(&mut ephem_validator, &mut devnet_validator); + cleanup_validators( + &mut ephem_validator, + &mut devnet_validator, + false, + ); return Err(err.into()); } }; - cleanup_validators(&mut ephem_validator, &mut devnet_validator); + cleanup_validators(&mut ephem_validator, &mut devnet_validator, false); Ok(test_output) } else { let devnet_validator = config.setup_devnet(TEST_NAME).then(start_devnet_validator); let ephem_validator = config.setup_ephem(TEST_NAME).then(start_ephem_validator); - wait_for_ctrlc(devnet_validator, ephem_validator, success_output()) + wait_for_ctrlc( + devnet_validator, + None, + ephem_validator, + success_output(), + ) } } @@ -1063,7 +1108,7 @@ fn run_task_scheduler_tests( } else { let devnet_validator = config.setup_devnet(TEST_NAME).then(start_devnet_validator); - wait_for_ctrlc(devnet_validator, None, success_output()) + wait_for_ctrlc(devnet_validator, None, None, success_output()) } } @@ -1410,13 +1455,15 @@ fn resolve_paths(config_file: &str) -> TestRunnerPaths { enum ValidatorCluster { Chain(Option), Ephem, + Light, } impl ValidatorCluster { fn log_suffix(&self) -> &'static str { match self { - ValidatorCluster::Chain(_) => "CHAIN", ValidatorCluster::Ephem => "EPHEM", + ValidatorCluster::Chain(_) => "CHAIN", + ValidatorCluster::Light => "LIGHT", } } } @@ -1430,9 +1477,7 @@ fn start_validator( let test_runner_paths = resolve_paths(config_file); match cluster { - ValidatorCluster::Chain(program_loader) - if std::env::var("FORCE_MAGIC_BLOCK_VALIDATOR").is_err() => - { + ValidatorCluster::Chain(program_loader) => { start_test_validator_with_config( &test_runner_paths, program_loader, @@ -1440,6 +1485,12 @@ fn start_validator( log_suffix, ) } + ValidatorCluster::Light => start_light_validator_with_config( + &test_runner_paths, + None, + loaded_chain_accounts, + log_suffix, + ), _ => start_magic_block_validator_with_config( &test_runner_paths, log_suffix, diff --git a/test-integration/test-runner/src/cleanup.rs b/test-integration/test-runner/src/cleanup.rs index b07956442..e31f9f7e7 100644 --- a/test-integration/test-runner/src/cleanup.rs +++ b/test-integration/test-runner/src/cleanup.rs @@ -3,9 +3,14 @@ use std::process::{self, Child}; pub fn cleanup_validators( ephem_validator: &mut Child, devnet_validator: &mut Child, + uses_light_validator: bool, ) { cleanup_validator(ephem_validator, "ephemeral"); - cleanup_validator(devnet_validator, "devnet"); + if uses_light_validator { + cleanup_light_validator(devnet_validator); + } else { + cleanup_validator(devnet_validator, "devnet"); + } kill_validators(); } @@ -23,6 +28,20 @@ pub fn cleanup_validator(validator: &mut Child, label: &str) { }); } +pub fn cleanup_light_validator(validator: &mut Child) { + validator.kill().unwrap_or_else(|err| { + panic!("Failed to kill light validator ({:?})", err) + }); + let command = process::Command::new("light") + .arg("test-validator") + .arg("--stop") + .output() + .unwrap(); + if !command.status.success() { + panic!("Failed to stop light validator: {:?}", command); + } +} + fn kill_process(name: &str) { process::Command::new("pkill") .arg("-15") // SIGTERM (default) diff --git a/test-integration/test-runner/src/signal.rs b/test-integration/test-runner/src/signal.rs index 75fd97c0c..8881eb389 100644 --- a/test-integration/test-runner/src/signal.rs +++ b/test-integration/test-runner/src/signal.rs @@ -4,10 +4,13 @@ use std::{ sync::mpsc::channel, }; -use crate::cleanup::cleanup_validator; +use crate::cleanup::{ + cleanup_devnet_only, cleanup_light_validator, cleanup_validator, +}; pub fn wait_for_ctrlc( devnet_validator: Option, + light_validator: Option, ephem_validator: Option, output: Output, ) -> Result> { @@ -19,12 +22,15 @@ pub fn wait_for_ctrlc( println!("Hit Ctrl-C to stop validator(s)..."); rx.recv().expect("Could not receive from channel."); - if let Some(mut validator) = devnet_validator { - cleanup_validator(&mut validator, "devnet"); - } if let Some(mut validator) = ephem_validator { cleanup_validator(&mut validator, "ephemeral"); } + if let Some(mut validator) = devnet_validator { + cleanup_devnet_only(&mut validator); + } + if let Some(mut validator) = light_validator { + cleanup_light_validator(&mut validator); + } Ok(output) } diff --git a/test-integration/test-task-scheduler/src/lib.rs b/test-integration/test-task-scheduler/src/lib.rs index e3422bb40..0935b7986 100644 --- a/test-integration/test-task-scheduler/src/lib.rs +++ b/test-integration/test-task-scheduler/src/lib.rs @@ -32,9 +32,7 @@ use program_flexi_counter::{ state::FlexiCounter, }; use program_schedulecommit::MainAccount; -use solana_sdk::{ - signature::Keypair, signer::Signer, transaction::Transaction, -}; +use solana_sdk::{signature::Keypair, signer::Signer}; use tempfile::TempDir; pub const TASK_SCHEDULER_TICK_MILLIS: u64 = 50; @@ -88,49 +86,28 @@ pub fn create_delegated_counter( validator: &mut Child, commit_frequency_ms: u32, ) { - // Initialize the counter - let blockhash = expect!( - ctx.try_chain_client().and_then(|client| client - .get_latest_blockhash() - .map_err(|e| anyhow::anyhow!( - "Failed to get latest blockhash: {}", - e - ))), - validator - ); - expect!( - ctx.send_transaction_chain( - &mut Transaction::new_signed_with_payer( - &[create_init_ix(payer.pubkey(), "test".to_string())], - Some(&payer.pubkey()), - &[&payer], - blockhash, - ), - &[payer] - ), - format!("Failed to send init transaction: blockhash {:?}", blockhash), - validator + let init_ix = create_init_ix(payer.pubkey(), "test".to_string()); + let delegate_ix = create_delegate_ix_with_commit_frequency_ms( + payer.pubkey(), + commit_frequency_ms, ); - // Delegate the counter to the ephem validator expect!( - ctx.send_transaction_chain( - &mut Transaction::new_signed_with_payer( - &[create_delegate_ix_with_commit_frequency_ms( - payer.pubkey(), - commit_frequency_ms - )], - Some(&payer.pubkey()), - &[&payer], - blockhash, - ), - &[payer] + ctx.send_and_confirm_instructions_with_payer_chain( + &[init_ix, delegate_ix], + payer, ), validator ); - // Wait for account to be delegated - expect!(ctx.wait_for_delta_slot_ephem(10), validator); + let (counter_pda, _) = FlexiCounter::pda(&payer.pubkey()); + wait_for_incremented_counter( + ctx, + &counter_pda, + 0, + Duration::from_secs(10), + validator, + ); } pub fn wait_for_incremented_counter( @@ -141,24 +118,46 @@ pub fn wait_for_incremented_counter( validator: &mut Child, ) { let now = Instant::now(); + let mut last_count = None; + let mut last_error = None; while now.elapsed() < max_timeout { - let counter_account = expect!( - ctx.try_ephem_client().and_then(|client| client - .get_account(counter_pda) - .map_err(|e| anyhow::anyhow!("Failed to get account: {}", e))), - validator - ); - let counter = - expect!(FlexiCounter::try_decode(&counter_account.data), validator); - if counter.count == expected_count { - return; + let counter = ctx + .try_ephem_client() + .and_then(|client| { + client.get_account(counter_pda).map_err(|e| { + anyhow::anyhow!("Failed to get account: {}", e) + }) + }) + .and_then(|counter_account| { + FlexiCounter::try_decode(&counter_account.data).map_err(|e| { + anyhow::anyhow!( + "Failed to decode counter account ({} bytes): {}", + counter_account.data.len(), + e + ) + }) + }); + match counter { + Ok(counter) => { + last_count = Some(counter.count); + last_error = None; + if counter.count == expected_count { + return; + } + } + Err(err) => { + last_error = Some(err.to_string()); + } } expect!(ctx.wait_for_next_slot_ephem(), validator); } assert!( false, cleanup(validator), - "Failed to wait for incremented counter" + "Failed to wait for incremented counter; expected_count: {}, last_count: {:?}, last_error: {:?}", + expected_count, + last_count, + last_error ); } diff --git a/test-integration/test-tools/Cargo.toml b/test-integration/test-tools/Cargo.toml index ff3ace58e..3817a0d01 100644 --- a/test-integration/test-tools/Cargo.toml +++ b/test-integration/test-tools/Cargo.toml @@ -13,8 +13,12 @@ rayon = { workspace = true } serde = { workspace = true } ureq = { workspace = true } url = { workspace = true } +light-client = { workspace = true, features = ["v2"] } magicblock-config = { workspace = true } -magicblock-delegation-program-api = { workspace = true, features = ["instruction"] } +magicblock-delegation-program-api = { workspace = true, features = [ + "instruction", +] } +shlex = { workspace = true } solana-commitment-config = { workspace = true } solana-pubkey = { workspace = true } solana-rpc-client = { workspace = true } diff --git a/test-integration/test-tools/src/integration_test_context.rs b/test-integration/test-tools/src/integration_test_context.rs index f1246007d..d1cb2e7b7 100644 --- a/test-integration/test-tools/src/integration_test_context.rs +++ b/test-integration/test-tools/src/integration_test_context.rs @@ -4,6 +4,7 @@ use std::{str::FromStr, thread::sleep, time::Duration}; use anyhow::{Context, Result}; use borsh::BorshDeserialize; +use light_client::indexer::photon_indexer::PhotonIndexer; use solana_commitment_config::CommitmentConfig; use solana_rpc_client::{ nonblocking, @@ -45,6 +46,7 @@ use crate::{ const URL_CHAIN: &str = "http://localhost:7799"; const WS_URL_CHAIN: &str = "ws://localhost:7800"; const URL_EPHEM: &str = "http://localhost:8899"; +const URL_PHOTON: &str = "http://localhost:8784"; fn async_rpc_client( rpc_client: &RpcClient, @@ -83,6 +85,7 @@ pub struct IntegrationTestContext { pub commitment: CommitmentConfig, pub chain_client: Option, pub ephem_client: Option, + pub photon_client: Option, pub ephem_validator_identity: Option, } @@ -100,6 +103,7 @@ impl IntegrationTestContext { commitment, chain_client: None, ephem_client: Some(ephem_client), + photon_client: None, ephem_validator_identity: Some(validator_identity), }) } @@ -116,6 +120,7 @@ impl IntegrationTestContext { commitment, chain_client: Some(chain_client), ephem_client: None, + photon_client: None, ephem_validator_identity: None, }) } @@ -137,12 +142,14 @@ impl IntegrationTestContext { Self::url_local_ephem_at_port(port).to_string(), commitment, ); + let photon_client = PhotonIndexer::new(Self::url_photon().to_string()); let validator_identity = ephem_client.get_identity()?; Ok(Self { commitment, chain_client: Some(chain_client), ephem_client: Some(ephem_client), + photon_client: Some(photon_client), ephem_validator_identity: Some(validator_identity), }) } @@ -1371,6 +1378,9 @@ impl IntegrationTestContext { pub fn ws_url_chain() -> &'static str { WS_URL_CHAIN } + pub fn url_photon() -> &'static str { + URL_PHOTON + } // ----------------- // Prometheus Metrics diff --git a/test-integration/test-tools/src/validator.rs b/test-integration/test-tools/src/validator.rs index 8581ce146..02505324b 100644 --- a/test-integration/test-tools/src/validator.rs +++ b/test-integration/test-tools/src/validator.rs @@ -107,51 +107,7 @@ pub fn start_test_validator_with_config( let mut args = config_to_args(config_path, program_loader); let accounts_dir = workspace_dir.join("configs").join("accounts"); - let accounts = [ - ( - loaded_accounts.validator_authority().to_string(), - "validator-authority.json".to_string(), - ), - ( - loaded_accounts.luzid_authority().to_string(), - "luzid-authority.json".to_string(), - ), - ( - loaded_accounts.validator_fees_vault().to_string(), - "validator-fees-vault.json".to_string(), - ), - ( - loaded_accounts.protocol_fees_vault().to_string(), - "protocol-fees-vault.json".to_string(), - ), - ( - loaded_accounts.magic_fee_vault().to_string(), - "magic-fee-vault.json".to_string(), - ), - ( - dlp_api::pda::delegation_record_pda_from_delegated_account( - &loaded_accounts.magic_fee_vault(), - ) - .to_string(), - "magic-fee-vault-delegation-record.json".to_string(), - ), - ( - "9yXjZTevvMp1XgZSZEaziPRgFiXtAQChpnP2oX9eCpvt".to_string(), - "non-delegated-cloneable-account1.json".to_string(), - ), - ( - "BHBuATGifAD4JbRpM5nVdyhKzPgv3p2CxLEHAqwBzAj5".to_string(), - "non-delegated-cloneable-account2.json".to_string(), - ), - ( - "2o48ieM95rmHqMWC5B3tTX4DL7cLm4m1Kuwjay3keQSv".to_string(), - "non-delegated-cloneable-account3.json".to_string(), - ), - ( - "2EmfL3MqL3YHABudGNmajjCpR13NNEn9Y4LWxbDm6SwR".to_string(), - "non-delegated-cloneable-account4.json".to_string(), - ), - ]; + let accounts = devnet_accounts(loaded_accounts); let resolved_extra_accounts = loaded_accounts.extra_accounts(workspace_dir, &accounts_dir); let readiness_program_pubkeys = program_ids_from_config(config_path) @@ -227,6 +183,105 @@ pub fn start_test_validator_with_config( .then_some(validator) } +pub fn start_light_validator_with_config( + test_runner_paths: &TestRunnerPaths, + program_loader: Option, + loaded_accounts: &LoadedAccounts, + log_suffix: &str, +) -> Option { + let TestRunnerPaths { + config_path, + root_dir, + workspace_dir, + } = test_runner_paths; + + let port = rpc_port_from_config(config_path); + let mut devnet_args = config_to_args(config_path, program_loader); + + // Remove args already set by light test-validator (and their values) + let args_to_remove = [ + ("--rpc-port", true), + ("--limit-ledger-size", true), + ("--log", false), + ("-r", false), + ]; + let mut filtered_devnet_args = Vec::with_capacity(devnet_args.len()); + let mut skip_next = false; + for arg in devnet_args { + if skip_next { + skip_next = false; + continue; + } + if let Some(&(_, has_value)) = + args_to_remove.iter().find(|&&(flag, _)| flag == arg) + { + skip_next = has_value; + continue; + } + filtered_devnet_args.push(arg); + } + devnet_args = filtered_devnet_args; + + // Add accounts to the validator args + let accounts_dir = workspace_dir.join("configs").join("accounts"); + let accounts = devnet_accounts(loaded_accounts); + let resolved_extra_accounts = + loaded_accounts.extra_accounts(workspace_dir, &accounts_dir); + let account_args = accounts + .iter() + .chain(&resolved_extra_accounts) + .flat_map(|(account, file)| { + let account_path = accounts_dir.join(file).canonicalize().unwrap(); + vec![ + "--account".to_string(), + account.clone(), + account_path.to_str().unwrap().to_string(), + ] + }) + .collect::>(); + devnet_args.extend(account_args); + + // Split args using shlex so that the light CLI can pass them to the validator + let validator_args = shlex::split( + format!("--validator-args=\"{}\"", devnet_args.join(" ")).as_str(), + ) + .ok_or_else(|| anyhow::anyhow!("invalid validator args")) + .unwrap(); + + let prover_port = 3001; + let mut light_args = vec![ + "--rpc-port".to_string(), + port.to_string(), + "--prover-port".to_string(), + prover_port.to_string(), + "--no-use-surfpool".to_string(), + ]; + light_args.extend(validator_args); + + let mut script = "#!/bin/bash\nlight test-validator".to_string(); + for arg in &light_args { + script.push_str(&format!(" \\\n {}", arg)); + } + let mut command = process::Command::new("light"); + let rust_log_style = + std::env::var("RUST_LOG_STYLE").unwrap_or(log_suffix.to_string()); + command + .arg("test-validator") + .args(light_args) + .env("RUST_LOG", "solana=warn") + .env("RUST_LOG_STYLE", rust_log_style) + .current_dir(root_dir); + + eprintln!("Starting light validator with {:?}", command); + eprintln!("{}", script); + let validator = command.spawn().expect("Failed to start validator"); + // Waiting for the prover, which is the last thing to start + let child = wait_for_validator(validator, prover_port); + // Waiting more because light starts the prover immediately but is not ready to serve RPC yet + sleep(Duration::from_secs(10)); + child +} + pub fn wait_for_validator(mut validator: Child, port: u16) -> Option { const SLEEP_DURATION: Duration = Duration::from_millis(400); let max_retries = validator_startup_max_retries(); @@ -507,6 +562,54 @@ pub fn resolve_programs( // Utilities // ----------------- +fn devnet_accounts(loaded_accounts: &LoadedAccounts) -> [(String, String); 10] { + [ + ( + loaded_accounts.validator_authority().to_string(), + "validator-authority.json".to_string(), + ), + ( + loaded_accounts.luzid_authority().to_string(), + "luzid-authority.json".to_string(), + ), + ( + loaded_accounts.validator_fees_vault().to_string(), + "validator-fees-vault.json".to_string(), + ), + ( + loaded_accounts.protocol_fees_vault().to_string(), + "protocol-fees-vault.json".to_string(), + ), + ( + loaded_accounts.magic_fee_vault().to_string(), + "magic-fee-vault.json".to_string(), + ), + ( + dlp_api::pda::delegation_record_pda_from_delegated_account( + &loaded_accounts.magic_fee_vault(), + ) + .to_string(), + "magic-fee-vault-delegation-record.json".to_string(), + ), + ( + "9yXjZTevvMp1XgZSZEaziPRgFiXtAQChpnP2oX9eCpvt".to_string(), + "non-delegated-cloneable-account1.json".to_string(), + ), + ( + "BHBuATGifAD4JbRpM5nVdyhKzPgv3p2CxLEHAqwBzAj5".to_string(), + "non-delegated-cloneable-account2.json".to_string(), + ), + ( + "2o48ieM95rmHqMWC5B3tTX4DL7cLm4m1Kuwjay3keQSv".to_string(), + "non-delegated-cloneable-account3.json".to_string(), + ), + ( + "2EmfL3MqL3YHABudGNmajjCpR13NNEn9Y4LWxbDm6SwR".to_string(), + "non-delegated-cloneable-account4.json".to_string(), + ), + ] +} + /// Unwraps the provided result and ensures to kill the validator before panicking /// if the result was an error #[macro_export] diff --git a/test-kit/Cargo.toml b/test-kit/Cargo.toml index f71799b01..f2f2bedba 100644 --- a/test-kit/Cargo.toml +++ b/test-kit/Cargo.toml @@ -15,6 +15,7 @@ magicblock-ledger = { workspace = true } magicblock-processor = { workspace = true } solana-account = { workspace = true } +solana-pubkey = { workspace = true } solana-instruction = { workspace = true } solana-keypair = { workspace = true } solana-program = { workspace = true } diff --git a/test-kit/src/lib.rs b/test-kit/src/lib.rs index a9a781a6e..2e9df4350 100644 --- a/test-kit/src/lib.rs +++ b/test-kit/src/lib.rs @@ -30,9 +30,8 @@ use magicblock_processor::{ use solana_account::AccountSharedData; pub use solana_instruction::*; use solana_keypair::Keypair; -use solana_program::{ - hash::Hasher, native_token::LAMPORTS_PER_SOL, pubkey::Pubkey, -}; +use solana_program::{hash::Hasher, native_token::LAMPORTS_PER_SOL}; +use solana_pubkey::Pubkey; use solana_signature::Signature; pub use solana_signer::Signer; use solana_transaction::Transaction;