From d4c677d8e4539aae839a0a00ec124a9cdbc245ce Mon Sep 17 00:00:00 2001 From: Ludo Galabru Date: Tue, 11 Feb 2025 17:38:13 -0500 Subject: [PATCH 1/3] feat: draft geyser plugin support --- Cargo.lock | 118 +++++++++++++++++++++++++++++- crates/core/Cargo.toml | 8 +- crates/core/src/lib.rs | 2 +- crates/core/src/rpc/full.rs | 8 +- crates/core/src/simnet/mod.rs | 134 ++++++++++++++++++++++++++++++++-- crates/core/src/types.rs | 4 +- 6 files changed, 255 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 025c5f7..c46b499 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -261,6 +261,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "agave-geyser-plugin-interface" +version = "2.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "458574532922e0c82a2ec189319d2076be44c2a32f5524c7c23867a311ceff57" +dependencies = [ + "log 0.4.25", + "solana-sdk", + "solana-transaction-status", + "thiserror 1.0.69", +] + [[package]] name = "agave-transaction-view" version = "2.1.10" @@ -1298,7 +1310,7 @@ checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" dependencies = [ "glob", "libc", - "libloading", + "libloading 0.8.6", ] [[package]] @@ -3494,6 +3506,17 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "json5" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1" +dependencies = [ + "pest", + "pest_derive", + "serde", +] + [[package]] name = "jsonrpc-client-transports" version = "18.0.0" @@ -3658,6 +3681,16 @@ version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if 1.0.0", + "winapi 0.3.9", +] + [[package]] name = "libloading" version = "0.8.6" @@ -4586,6 +4619,51 @@ dependencies = [ "num", ] +[[package]] +name = "pest" +version = "2.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc" +dependencies = [ + "memchr", + "thiserror 2.0.11", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "816518421cfc6887a0d62bf441b6ffb4536fcc926395a69e1a85852d4363f57e" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d1396fd3a870fc7838768d171b4616d5c91f6cc25e377b673d714567d99377b" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "pest_meta" +version = "2.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1e58089ea25d717bfd31fb534e4f3afcc2cc569c70de3e239778991ea3b7dea" +dependencies = [ + "once_cell", + "pest", + "sha2 0.10.8", +] + [[package]] name = "petgraph" version = "0.6.5" @@ -6604,6 +6682,33 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "solana-geyser-plugin-manager" +version = "2.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c43363b5026b258dfd6d2b396138997605c7b6b75c3ad426c1f76e4445e932aa" +dependencies = [ + "agave-geyser-plugin-interface", + "bs58", + "crossbeam-channel", + "json5", + "jsonrpc-core", + "libloading 0.7.4", + "log 0.4.25", + "serde_json", + "solana-accounts-db", + "solana-entry", + "solana-ledger", + "solana-measure", + "solana-metrics", + "solana-rpc", + "solana-runtime", + "solana-sdk", + "solana-transaction-status", + "thiserror 1.0.69", + "tokio", +] + [[package]] name = "solana-gossip" version = "2.1.10" @@ -8928,21 +9033,23 @@ dependencies = [ name = "surfpool-core" version = "0.1.7" dependencies = [ + "agave-geyser-plugin-interface", "base64 0.22.1", "bincode", "bs58", "chrono", - "clap 4.5.27", "crossbeam", "crossbeam-channel", "hiro-system-kit", "indexmap 2.7.1", "itertools 0.14.0", + "json5", "jsonrpc-core", "jsonrpc-core-client", "jsonrpc-derive", "jsonrpc-http-server", "libc", + "libloading 0.7.4", "litesvm", "log 0.4.25", "regex", @@ -8956,6 +9063,7 @@ dependencies = [ "solana-entry", "solana-faucet", "solana-feature-set", + "solana-geyser-plugin-manager", "solana-gossip", "solana-inline-spl", "solana-ledger", @@ -9792,6 +9900,12 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "ucd-trie" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" + [[package]] name = "uint" version = "0.10.0" diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index e3f0533..f46b32d 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -18,7 +18,6 @@ base64 = "0.22.1" bincode = "1.3.3" crossbeam-channel = "0.5.14" log = "0.4.22" -clap = "4.5.27" serde = "1.0.217" serde_derive = "1.0.217" # must match the serde version, see https://github.com/serde-rs/serde/issues/2584#issuecomment-1685252251 serde_json = "1.0.135" @@ -37,9 +36,8 @@ jsonrpc-http-server = "18.0.0" libc = "0.2.169" regex = "1.11.1" litesvm = { version = "0.5.0", features = ["nodejs-internal"] } -crossbeam = "0.8.4" # litesvm = { path = "../../../litesvm/crates/litesvm" } - +crossbeam = "0.8.4" solana-sdk = "=2.1.10" solana-program-test = "2.1.10" solana-rpc-client = "2.1.10" @@ -72,3 +70,7 @@ spl-token-2022 = "4.0.0" spl-token = "7.0.0" solana-streamer = "2.1.10" zstd = "0.13.2" +agave-geyser-plugin-interface = "2.1.10" +solana-geyser-plugin-manager = "2.1.10" +libloading = "0.7.4" +json5 = "0.4.1" \ No newline at end of file diff --git a/crates/core/src/lib.rs b/crates/core/src/lib.rs index a6b66e8..f8f079e 100644 --- a/crates/core/src/lib.rs +++ b/crates/core/src/lib.rs @@ -24,7 +24,7 @@ pub use solana_sdk; use types::SurfpoolConfig; pub async fn start_simnet( - config: &SurfpoolConfig, + config: SurfpoolConfig, simnet_events_tx: Sender, simnet_commands_rx: Receiver, ) -> Result<(), Box> { diff --git a/crates/core/src/rpc/full.rs b/crates/core/src/rpc/full.rs index 536f094..6a06c41 100644 --- a/crates/core/src/rpc/full.rs +++ b/crates/core/src/rpc/full.rs @@ -344,14 +344,14 @@ impl Full for SurfpoolFullRpc { .send((ctx.id.clone(), unsanitized_tx, status_update_tx)); loop { match (status_uptate_rx.recv(), config.preflight_commitment) { - ( - Ok(TransactionConfirmationStatus::Confirmed), - Some(CommitmentLevel::Confirmed), - ) => break, ( Ok(TransactionConfirmationStatus::Processed), Some(CommitmentLevel::Processed), ) => break, + ( + Ok(TransactionConfirmationStatus::Confirmed), + None | Some(CommitmentLevel::Confirmed), + ) => break, ( Ok(TransactionConfirmationStatus::Finalized), Some(CommitmentLevel::Finalized), diff --git a/crates/core/src/simnet/mod.rs b/crates/core/src/simnet/mod.rs index 834596c..6819d09 100644 --- a/crates/core/src/simnet/mod.rs +++ b/crates/core/src/simnet/mod.rs @@ -1,3 +1,6 @@ +use agave_geyser_plugin_interface::geyser_plugin_interface::{ + GeyserPlugin, ReplicaTransactionInfoV2, ReplicaTransactionInfoVersions, +}; use base64::prelude::{Engine, BASE64_STANDARD}; use chrono::{DateTime, Local, Utc}; use crossbeam::select; @@ -6,22 +9,29 @@ use jsonrpc_core::MetaIoHandler; use jsonrpc_http_server::{DomainsValidation, ServerBuilder}; use litesvm::{types::TransactionMetadata, LiteSVM}; use solana_client::{nonblocking::rpc_client::RpcClient, rpc_response::RpcPerfSample}; +use solana_geyser_plugin_manager::geyser_plugin_manager::{ + GeyserPluginManager, GeyserPluginManagerError, LoadedGeyserPlugin, +}; use solana_sdk::{ clock::Clock, epoch_info::EpochInfo, + message::v0::LoadedAddresses, pubkey::Pubkey, signature::Signature, - transaction::{Transaction, TransactionError, TransactionVersion, VersionedTransaction}, + transaction::{ + SanitizedTransaction, Transaction, TransactionError, TransactionVersion, + VersionedTransaction, + }, }; use solana_transaction_status::{ option_serializer::OptionSerializer, EncodedConfirmedTransactionWithStatusMeta, EncodedTransaction, EncodedTransactionWithStatusMeta, TransactionConfirmationStatus, - TransactionStatus, UiCompiledInstruction, UiInnerInstructions, UiInstruction, UiMessage, - UiRawMessage, UiReturnDataEncoding, UiTransaction, UiTransactionReturnData, - UiTransactionStatusMeta, + TransactionStatus, TransactionStatusMeta, UiCompiledInstruction, UiInnerInstructions, + UiInstruction, UiMessage, UiRawMessage, UiReturnDataEncoding, UiTransaction, + UiTransactionReturnData, UiTransactionStatusMeta, }; use std::{ - collections::{HashMap, VecDeque}, + collections::{HashMap, HashSet, VecDeque}, net::SocketAddr, sync::{Arc, RwLock}, thread::sleep, @@ -205,8 +215,12 @@ pub enum ClockEvent { ExpireBlockHash, } +use std::{fs::File, io::Read, path::PathBuf}; +type PluginConstructor = unsafe fn() -> *mut dyn GeyserPlugin; +use libloading::{Library, Symbol}; + pub async fn start( - config: &SurfpoolConfig, + config: SurfpoolConfig, simnet_events_tx: Sender, simnet_commands_rx: Receiver, ) -> Result<(), Box> { @@ -268,10 +282,111 @@ pub async fn start( let _ = simnet_events_tx_copy.send(SimnetEvent::Shutdown); }); + let simnet_config = config.simnet.clone(); + let (plugins_data_tx, plugins_data_rx) = unbounded::<(Transaction, TransactionMetadata)>(); + if !config.plugin_config_path.is_empty() { + let _handle = hiro_system_kit::thread_named("geyser plugins handler").spawn(move || { + let mut plugin_manager = GeyserPluginManager::new(); + + for geyser_plugin_config_file in config.plugin_config_path.iter() { + let mut file = match File::open(geyser_plugin_config_file) { + Ok(file) => file, + Err(err) => { + return Err(GeyserPluginManagerError::CannotOpenConfigFile(format!( + "Failed to open the plugin config file {geyser_plugin_config_file:?}, error: {err:?}" + ))); + } + }; + + let mut contents = String::new(); + if let Err(err) = file.read_to_string(&mut contents) { + return Err(GeyserPluginManagerError::CannotReadConfigFile(format!( + "Failed to read the plugin config file {geyser_plugin_config_file:?}, error: {err:?}" + ))); + } + + let result: serde_json::Value = match json5::from_str(&contents) { + Ok(value) => value, + Err(err) => { + return Err(GeyserPluginManagerError::InvalidConfigFileFormat(format!( + "The config file {geyser_plugin_config_file:?} is not in a valid Json5 format, error: {err:?}" + ))); + } + }; + + let libpath = result["libpath"] + .as_str() + .ok_or(GeyserPluginManagerError::LibPathNotSet)?; + let mut libpath = PathBuf::from(libpath); + if libpath.is_relative() { + let config_dir = geyser_plugin_config_file.parent().ok_or_else(|| { + GeyserPluginManagerError::CannotOpenConfigFile(format!( + "Failed to resolve parent of {geyser_plugin_config_file:?}", + )) + })?; + libpath = config_dir.join(libpath); + } + + let plugin_name = result["name"].as_str().map(|s| s.to_owned()); + + let config_file = geyser_plugin_config_file + .as_os_str() + .to_str() + .ok_or(GeyserPluginManagerError::InvalidPluginPath)?; + + let (plugin, lib) = unsafe { + let lib = Library::new(libpath) + .map_err(|e| GeyserPluginManagerError::PluginLoadError(e.to_string()))?; + let constructor: Symbol = lib + .get(b"_create_plugin") + .map_err(|e| GeyserPluginManagerError::PluginLoadError(e.to_string()))?; + let plugin_raw = constructor(); + (Box::from_raw(plugin_raw), lib) + }; + plugin_manager.plugins.push(LoadedGeyserPlugin::new(lib, plugin, plugin_name)); + } + + while let Ok((transaction, transaction_metadata)) = plugins_data_rx.recv() { + let transaction_status_meta = TransactionStatusMeta { + status: Ok(()), + fee: 0, + pre_balances: vec![], + post_balances: vec![], + inner_instructions: None, + log_messages: Some(transaction_metadata.logs.clone()), + pre_token_balances: None, + post_token_balances: None, + rewards: None, + loaded_addresses: LoadedAddresses { + writable: vec![], + readonly: vec![], + }, + return_data: Some(transaction_metadata.return_data.clone()), + compute_units_consumed: Some(transaction_metadata.compute_units_consumed), + }; + + let transaction = SanitizedTransaction::try_from_legacy_transaction(transaction, &HashSet::new()) + .unwrap(); + + let transaction_replica = ReplicaTransactionInfoV2 { + signature: &transaction_metadata.signature, + is_vote: false, + transaction: &transaction, + transaction_status_meta: &transaction_status_meta, + index: 0 + }; + for plugin in plugin_manager.plugins.iter() { + plugin.notify_transaction(ReplicaTransactionInfoVersions::V0_0_2(&transaction_replica), 0).unwrap(); + } + } + Ok(()) + }); + } + let (clock_event_tx, clock_event_rx) = unbounded::(); let (clock_command_tx, clock_command_rx) = unbounded::(); - let mut slot_time = config.simnet.slot_time; + let mut slot_time = simnet_config.slot_time; let _handle = hiro_system_kit::thread_named("clock").spawn(move || { let mut enabled = true; let mut block_hash_timeout = Instant::now(); @@ -409,7 +524,10 @@ pub async fn start( } let (meta, err) = match ctx.svm.send_transaction(transaction.clone()) { - Ok(res) => (res, None), + Ok(res) => { + let _ = plugins_data_tx.try_send((transaction.clone(), res.clone())); + (res, None) + } Err(e) => { let _ = simnet_events_tx.try_send(SimnetEvent::ErrorLog( Local::now(), diff --git a/crates/core/src/types.rs b/crates/core/src/types.rs index b26aaed..d516321 100644 --- a/crates/core/src/types.rs +++ b/crates/core/src/types.rs @@ -1,3 +1,4 @@ +use std::path::PathBuf; use solana_sdk::pubkey::Pubkey; #[derive(Clone, Debug, PartialEq, Eq)] @@ -7,10 +8,11 @@ pub enum RunloopTriggerMode { Transaction, } -#[derive(Clone, Debug)] +#[derive(Debug)] pub struct SurfpoolConfig { pub simnet: SimnetConfig, pub rpc: RpcConfig, + pub plugin_config_path: Vec, } #[derive(Clone, Debug)] From e4963c05596ab04c727a8404bae5302a76210120 Mon Sep 17 00:00:00 2001 From: Ludo Galabru Date: Tue, 11 Feb 2025 20:41:40 -0500 Subject: [PATCH 2/3] chore: cargo fmt --- crates/cli/src/cli/mod.rs | 3 +++ crates/cli/src/cli/simnet/mod.rs | 7 ++++++- crates/core/src/types.rs | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/crates/cli/src/cli/mod.rs b/crates/cli/src/cli/mod.rs index bf9d8dc..bc500f4 100644 --- a/crates/cli/src/cli/mod.rs +++ b/crates/cli/src/cli/mod.rs @@ -106,6 +106,9 @@ pub struct StartSimnet { /// Disable explorer (default: false) #[clap(long = "no-explorer")] pub no_explorer: bool, + /// List of geyser plugins to load + #[arg(long = "geyser-plugin-config", short = 'g')] + pub plugin_config_path: Vec, } #[derive(Parser, PartialEq, Clone, Debug)] diff --git a/crates/cli/src/cli/simnet/mod.rs b/crates/cli/src/cli/simnet/mod.rs index 50d33f5..2780b3d 100644 --- a/crates/cli/src/cli/simnet/mod.rs +++ b/crates/cli/src/cli/simnet/mod.rs @@ -70,6 +70,11 @@ pub async fn handle_start_simnet_command(cmd: &StartSimnet, ctx: &Context) -> Re airdrop_addresses, airdrop_token_amount: cmd.airdrop_token_amount, }, + plugin_config_path: cmd + .plugin_config_path + .iter() + .map(|f| PathBuf::from(f)) + .collect::>(), }; let remote_rpc_url = config.rpc.remote_rpc_url.clone(); let local_rpc_url = config.rpc.get_socket_address(); @@ -80,7 +85,7 @@ pub async fn handle_start_simnet_command(cmd: &StartSimnet, ctx: &Context) -> Re let ctx_cloned = ctx.clone(); let _handle = hiro_system_kit::thread_named("simnet") .spawn(move || { - let future = start_simnet(&config, simnet_events_tx, simnet_commands_rx); + let future = start_simnet(config, simnet_events_tx, simnet_commands_rx); if let Err(e) = hiro_system_kit::nestable_block_on(future) { error!(ctx_cloned.expect_logger(), "{e}"); sleep(Duration::from_millis(500)); diff --git a/crates/core/src/types.rs b/crates/core/src/types.rs index d516321..639c062 100644 --- a/crates/core/src/types.rs +++ b/crates/core/src/types.rs @@ -1,5 +1,5 @@ -use std::path::PathBuf; use solana_sdk::pubkey::Pubkey; +use std::path::PathBuf; #[derive(Clone, Debug, PartialEq, Eq)] pub enum RunloopTriggerMode { From 3d665ae75dbae1f6e51c126de6276515916e33fb Mon Sep 17 00:00:00 2001 From: Ludo Galabru Date: Tue, 11 Feb 2025 20:54:50 -0500 Subject: [PATCH 3/3] chore: update dependencies --- .github/workflows/release.yaml | 2 +- Cargo.lock | 31 ++++++++----------------------- crates/cli/Cargo.toml | 4 ++-- crates/core/Cargo.toml | 2 +- rust-toolchain | 2 +- 5 files changed, 13 insertions(+), 28 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index bf6286f..4a21694 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -85,7 +85,7 @@ jobs: # set up rust for all envs - name: Install Rust toolchain - run: rustup toolchain install 1.79 --profile minimal --target ${{ matrix.target }} + run: rustup toolchain install 1.84.0 --profile minimal --target ${{ matrix.target }} - name: Install Rust Target run: rustup target add ${{ matrix.target }} diff --git a/Cargo.lock b/Cargo.lock index c46b499..0c2468b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8632,21 +8632,6 @@ dependencies = [ "thiserror 1.0.69", ] -[[package]] -name = "spl-token" -version = "4.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e9e171cbcb4b1f72f6d78ed1e975cb467f56825c27d09b8dd2608e4e7fc8b3b" -dependencies = [ - "arrayref", - "bytemuck", - "num-derive", - "num-traits", - "num_enum", - "solana-program", - "thiserror 1.0.69", -] - [[package]] name = "spl-token" version = "6.0.0" @@ -9087,7 +9072,7 @@ dependencies = [ "solana-version", "solana-vote-program", "spl-token 7.0.0", - "spl-token-2022 4.0.0", + "spl-token-2022 6.0.0", "symlink", "tokio", "tokio-util 0.7.13", @@ -9811,9 +9796,9 @@ dependencies = [ [[package]] name = "txtx-addon-kit" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "827085dc9ece10a5beb18c3502284b87fb0cc2d526902f693253062d50ab8053" +checksum = "349567e68d1724bec1eec4ccf766232be8cdfd257f5453063e766b5b978eb90e" dependencies = [ "crossbeam-channel", "dirs 5.0.1", @@ -9844,9 +9829,9 @@ dependencies = [ [[package]] name = "txtx-addon-network-svm" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5124beb89312ba23432735a6a5b710d03f3fc32bf8ef02f00e4522fe1c9fabc5" +checksum = "2ce3a54125dcded77c3e27cc3891cffbdd12aa1f1340dfc289d6c9d31e1d5353" dependencies = [ "anchor-lang-idl", "async-recursion", @@ -9860,16 +9845,16 @@ dependencies = [ "solana-sdk", "solana_idl", "spl-associated-token-account 6.0.0", - "spl-token 4.0.2", + "spl-token 7.0.0", "tiny-bip39", "txtx-addon-kit", ] [[package]] name = "txtx-core" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c29cf07256ce4a516b9b64ad79a1e871fa166252d2e3fb4784b3e7998aff87f8" +checksum = "db49fab87668ddb4b4af2e0661566c23bbba269d3b36f4cc067dfc2863bfe1a0" dependencies = [ "base64 0.22.1", "better-debug", diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index 0680ef6..06287c2 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -18,8 +18,8 @@ surfpool-core = { workspace = true } # surfpool-core = { version = "0.1" } # txtx-core = { path = "../../../txtx/crates/txtx-core" } # txtx-addon-network-svm = { package = "txtx-addon-network-svm", path = "../../../txtx/addons/svm" } -txtx-core = { version = "0.2.1" } -txtx-addon-network-svm = { version = "0.1.2" } +txtx-core = { version = "0.2.2" } +txtx-addon-network-svm = { version = "0.1.3" } hiro-system-kit = "0.3.1" atty = "0.2.13" ansi_term = "0.12.1" diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index f46b32d..2a8f3a4 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -66,7 +66,7 @@ solana-version = "2.1.10" solana-poh = "2.1.10" solana-svm = "2.1.10" solana-program-runtime = "2.1.10" -spl-token-2022 = "4.0.0" +spl-token-2022 = "6.0.0" spl-token = "7.0.0" solana-streamer = "2.1.10" zstd = "0.13.2" diff --git a/rust-toolchain b/rust-toolchain index c572f7e..ad2fb10 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "1.84.1" +channel = "1.84.0" components = ["llvm-tools", "rustc-dev"] \ No newline at end of file