From db3972b1cb078078f30251ae10b38e44d8fb2747 Mon Sep 17 00:00:00 2001 From: kevinheavey Date: Thu, 14 Nov 2024 18:48:05 +0400 Subject: [PATCH 01/24] extract transaction crate --- Cargo.lock | 35 +++ Cargo.toml | 2 + programs/sbf/Cargo.lock | 25 +++ sdk/Cargo.toml | 5 + sdk/src/lib.rs | 7 +- sdk/src/transaction.rs | 20 ++ sdk/src/wasm/transaction.rs | 57 +---- sdk/transaction/Cargo.toml | 58 +++++ .../mod.rs => transaction/src/lib.rs} | 201 ++++++++---------- .../src}/sanitized.rs | 49 ++--- .../src/simple_vote_transaction_checker.rs | 9 +- .../src}/versioned/mod.rs | 52 ++--- .../src}/versioned/sanitized.rs | 4 +- sdk/transaction/src/wasm.rs | 54 +++++ svm/examples/Cargo.lock | 25 +++ 15 files changed, 378 insertions(+), 225 deletions(-) create mode 100644 sdk/src/transaction.rs create mode 100644 sdk/transaction/Cargo.toml rename sdk/{src/transaction/mod.rs => transaction/src/lib.rs} (92%) rename sdk/{src/transaction => transaction/src}/sanitized.rs (93%) rename sdk/{ => transaction}/src/simple_vote_transaction_checker.rs (84%) rename sdk/{src/transaction => transaction/src}/versioned/mod.rs (92%) rename sdk/{src/transaction => transaction/src}/versioned/sanitized.rs (93%) create mode 100644 sdk/transaction/src/wasm.rs diff --git a/Cargo.lock b/Cargo.lock index cb541e70b69ba2..da263a508b2eba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8556,6 +8556,7 @@ dependencies = [ "solana-signer", "solana-sysvar", "solana-time-utils", + "solana-transaction", "solana-transaction-context", "solana-transaction-error", "static_assertions", @@ -9258,6 +9259,40 @@ dependencies = [ "tokio-util 0.7.12", ] +[[package]] +name = "solana-transaction" +version = "2.2.0" +dependencies = [ + "anyhow", + "bincode", + "borsh 1.5.3", + "serde", + "serde_derive", + "solana-bincode", + "solana-feature-set", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-hash", + "solana-instruction", + "solana-keypair", + "solana-nonce", + "solana-packet", + "solana-precompiles", + "solana-presigner", + "solana-program", + "solana-pubkey", + "solana-reserved-account-keys", + "solana-sanitize", + "solana-sdk", + "solana-sdk-ids", + "solana-sha256-hasher", + "solana-short-vec", + "solana-signature", + "solana-signer", + "solana-transaction", + "solana-transaction-error", +] + [[package]] name = "solana-transaction-context" version = "2.2.0" diff --git a/Cargo.toml b/Cargo.toml index 2e0985d2fa950b..3a9faced6f721e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -172,6 +172,7 @@ members = [ "sdk/sysvar", "sdk/sysvar-id", "sdk/time-utils", + "sdk/transaction", "sdk/transaction-context", "sdk/transaction-error", "send-transaction-service", @@ -567,6 +568,7 @@ solana-sysvar = { path = "sdk/sysvar", version = "=2.2.0" } solana-sysvar-id = { path = "sdk/sysvar-id", version = "=2.2.0" } solana-test-validator = { path = "test-validator", version = "=2.2.0" } solana-thin-client = { path = "thin-client", version = "=2.2.0" } +solana-transaction = { path = "sdk/transaction", version = "=2.2.0" } solana-transaction-error = { path = "sdk/transaction-error", version = "=2.2.0" } solana-tpu-client = { path = "tpu-client", version = "=2.2.0", default-features = false } solana-tpu-client-next = { path = "tpu-client-next", version = "=2.2.0" } diff --git a/programs/sbf/Cargo.lock b/programs/sbf/Cargo.lock index 58449f5348fdf7..8b8c759e11bfe8 100644 --- a/programs/sbf/Cargo.lock +++ b/programs/sbf/Cargo.lock @@ -7253,6 +7253,7 @@ dependencies = [ "solana-signature", "solana-signer", "solana-time-utils", + "solana-transaction", "solana-transaction-context", "solana-transaction-error", "thiserror 2.0.3", @@ -7769,6 +7770,30 @@ dependencies = [ "tokio-util 0.7.1", ] +[[package]] +name = "solana-transaction" +version = "2.2.0" +dependencies = [ + "serde", + "serde_derive", + "solana-bincode", + "solana-feature-set", + "solana-hash", + "solana-instruction", + "solana-nonce", + "solana-packet", + "solana-precompiles", + "solana-program", + "solana-pubkey", + "solana-reserved-account-keys", + "solana-sanitize", + "solana-sdk-ids", + "solana-short-vec", + "solana-signature", + "solana-signer", + "solana-transaction-error", +] + [[package]] name = "solana-transaction-context" version = "2.2.0" diff --git a/sdk/Cargo.toml b/sdk/Cargo.toml index 91a828853f51fe..9b7246a201a636 100644 --- a/sdk/Cargo.toml +++ b/sdk/Cargo.toml @@ -47,6 +47,7 @@ full = [ "dep:solana-seed-derivable", "dep:solana-seed-phrase", "dep:solana-signer", + "dep:solana-transaction", "dep:solana-transaction-error", ] borsh = [ @@ -173,6 +174,10 @@ solana-signature = { workspace = true, features = [ ], optional = true } solana-signer = { workspace = true, optional = true } solana-time-utils = { workspace = true } +solana-transaction = { workspace = true, features = [ + "precompiles", + "verify" +], optional = true } solana-transaction-context = { workspace = true, features = ["bincode"] } solana-transaction-error = { workspace = true, features = [ "serde", diff --git a/sdk/src/lib.rs b/sdk/src/lib.rs index b51f88e7c6ef56..ebcccb13eb8e4a 100644 --- a/sdk/src/lib.rs +++ b/sdk/src/lib.rs @@ -94,7 +94,6 @@ pub mod rpc_port; pub mod shred_version; pub mod signature; pub mod signer; -pub mod simple_vote_transaction_checker; pub mod system_transaction; pub mod transaction; pub mod transport; @@ -203,6 +202,12 @@ pub use solana_serde_varint as serde_varint; pub use solana_short_vec as short_vec; #[deprecated(since = "2.2.0", note = "Use `solana-time-utils` crate instead")] pub use solana_time_utils as timing; +#[cfg(feature = "full")] +#[deprecated( + since = "2.2.0", + note = "Use `solana_transaction::simple_vote_transaction_checker` instead" +)] +pub use solana_transaction::simple_vote_transaction_checker; #[deprecated( since = "2.2.0", note = "Use `solana-transaction-context` crate instead" diff --git a/sdk/src/transaction.rs b/sdk/src/transaction.rs new file mode 100644 index 00000000000000..ed4cf7bd83ccdf --- /dev/null +++ b/sdk/src/transaction.rs @@ -0,0 +1,20 @@ +#[deprecated(since = "2.2.0", note = "Use solana_transaction_error crate instead")] +pub use solana_transaction_error::{ + AddressLoaderError, SanitizeMessageError, TransactionError, TransactionResult as Result, + TransportError, TransportResult, +}; +#[deprecated(since = "2.2.0", note = "Use solana_transaction crate instead")] +pub use { + solana_program::message::{AddressLoader, SimpleAddressLoader}, + solana_transaction::{ + sanitized::{ + MessageHash, SanitizedTransaction, TransactionAccountLocks, MAX_TX_ACCOUNT_LOCKS, + }, + uses_durable_nonce, + versioned::{ + sanitized::SanitizedVersionedTransaction, Legacy, TransactionVersion, + VersionedTransaction, + }, + Transaction, TransactionVerificationMode, + }, +}; diff --git a/sdk/src/wasm/transaction.rs b/sdk/src/wasm/transaction.rs index 208a76bfa2d415..5c5da471a7878a 100644 --- a/sdk/src/wasm/transaction.rs +++ b/sdk/src/wasm/transaction.rs @@ -1,54 +1,3 @@ -//! `Transaction` Javascript interface -#![cfg(target_arch = "wasm32")] -#![allow(non_snake_case)] -use { - crate::{hash::Hash, message::Message, signer::keypair::Keypair, transaction::Transaction}, - solana_program::{ - pubkey::Pubkey, - wasm::{display_to_jsvalue, instructions::Instructions}, - }, - wasm_bindgen::prelude::*, -}; - -#[wasm_bindgen] -impl Transaction { - /// Create a new `Transaction` - #[wasm_bindgen(constructor)] - pub fn constructor(instructions: Instructions, payer: Option) -> Transaction { - let instructions: Vec<_> = instructions.into(); - Transaction::new_with_payer(&instructions, payer.as_ref()) - } - - /// Return a message containing all data that should be signed. - #[wasm_bindgen(js_name = message)] - pub fn js_message(&self) -> Message { - self.message.clone() - } - - /// Return the serialized message data to sign. - pub fn messageData(&self) -> Box<[u8]> { - self.message_data().into() - } - - /// Verify the transaction - #[wasm_bindgen(js_name = verify)] - pub fn js_verify(&self) -> Result<(), JsValue> { - self.verify().map_err(display_to_jsvalue) - } - - pub fn partialSign(&mut self, keypair: &Keypair, recent_blockhash: &Hash) { - self.partial_sign(&[keypair], *recent_blockhash); - } - - pub fn isSigned(&self) -> bool { - self.is_signed() - } - - pub fn toBytes(&self) -> Box<[u8]> { - bincode::serialize(self).unwrap().into() - } - - pub fn fromBytes(bytes: &[u8]) -> Result { - bincode::deserialize(bytes).map_err(display_to_jsvalue) - } -} +//! This module is empty but has not yet been removed because that would +//! technically be a breaking change. There was never anything to import +//! from here. diff --git a/sdk/transaction/Cargo.toml b/sdk/transaction/Cargo.toml new file mode 100644 index 00000000000000..f9e1e660ed747d --- /dev/null +++ b/sdk/transaction/Cargo.toml @@ -0,0 +1,58 @@ +[package] +name = "solana-transaction" +description = "Solana transaction-types" +documentation = "https://docs.rs/solana-transaction" +version = { workspace = true } +authors = { workspace = true } +repository = { workspace = true } +homepage = { workspace = true } +license = { workspace = true } +edition = { workspace = true } + +[dependencies] +serde = { workspace = true } +serde_derive = { workspace = true } +solana-bincode = { workspace = true } +solana-feature-set = { workspace = true } +solana-frozen-abi = { workspace = true, optional = true } +solana-frozen-abi-macro = { workspace = true, optional = true } +solana-hash = { workspace = true } +solana-instruction = { workspace = true } +solana-nonce = { workspace = true } +solana-packet = { workspace = true } +solana-precompiles = { workspace = true, optional = true } +solana-program = { workspace = true } +solana-pubkey = { workspace = true } +solana-reserved-account-keys = { workspace = true } +solana-sanitize = { workspace = true } +solana-sdk-ids = { workspace = true } +solana-short-vec = { workspace = true } +solana-signature = { workspace = true, features = ["serde"] } +solana-signer = { workspace = true } +solana-transaction-error = { workspace = true } + +[dev-dependencies] +anyhow = { workspace = true } +bincode = { workspace = true } +borsh = { workspace = true } +solana-hash = { workspace = true } +solana-instruction = { workspace = true, features = ["borsh"] } +solana-keypair = { workspace = true } +solana-presigner = { workspace = true } +solana-program = { workspace = true, default-features = false } +solana-pubkey = { workspace = true, features = ["rand"] } +solana-sdk = { workspace = true } +solana-sha256-hasher = { workspace = true } +solana-transaction = { path = ".", features = ["dev-context-only-utils"] } + +[features] +dev-context-only-utils = ["precompiles", "verify"] +frozen-abi = ["dep:solana-frozen-abi", "dep:solana-frozen-abi-macro"] +precompiles = ["dep:solana-precompiles"] +verify = ["solana-signature/verify"] + + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] +all-features = true +rustdoc-args = ["--cfg=docsrs"] diff --git a/sdk/src/transaction/mod.rs b/sdk/transaction/src/lib.rs similarity index 92% rename from sdk/src/transaction/mod.rs rename to sdk/transaction/src/lib.rs index 7e898bf2477e00..bb1207cc911e07 100644 --- a/sdk/src/transaction/mod.rs +++ b/sdk/transaction/src/lib.rs @@ -20,8 +20,8 @@ //! signers including remote wallets, such as Ledger devices, as represented by //! the [`RemoteKeypair`] type in the [`solana-remote-wallet`] crate. //! -//! [`Signer`]: crate::signer::Signer -//! [`Keypair`]: crate::signer::keypair::Keypair +//! [`Signer`]: https://docs.rs/solana-signer/latest/solana_signer/trait.Signer.html +//! [`Keypair`]: https://docs.rs/solana-keypair/latest/solana_keypair/struct.Keypair.html //! [`solana-remote-wallet`]: https://docs.rs/solana-remote-wallet/latest/ //! [`RemoteKeypair`]: https://docs.rs/solana-remote-wallet/latest/solana_remote_wallet/remote_keypair/struct.RemoteKeypair.html //! @@ -56,14 +56,13 @@ //! # use solana_sdk::example_mocks::solana_rpc_client; //! use anyhow::Result; //! use borsh::{BorshSerialize, BorshDeserialize}; +//! use solana_instruction::Instruction; +//! use solana_keypair::Keypair; +//! use solana_program::message::Message; +//! use solana_pubkey::Pubkey; //! use solana_rpc_client::rpc_client::RpcClient; -//! use solana_sdk::{ -//! instruction::Instruction, -//! message::Message, -//! pubkey::Pubkey, -//! signature::{Keypair, Signer}, -//! transaction::Transaction, -//! }; +//! use solana_signer::Signer; +//! use solana_transaction::Transaction; //! //! // A custom program instruction. This would typically be defined in //! // another crate so it can be shared between the on-chain program and @@ -109,43 +108,31 @@ //! # Ok::<(), anyhow::Error>(()) //! ``` -#![cfg(feature = "full")] - #[cfg(target_arch = "wasm32")] use crate::wasm_bindgen; use { - crate::{ - hash::Hash, - instruction::{CompiledInstruction, Instruction}, - message::Message, - nonce::NONCED_TX_MARKER_IX_INDEX, - precompiles::verify_if_precompile, - program_utils::limited_deserialize, - pubkey::Pubkey, - signature::{Signature, SignerError}, - signers::Signers, + serde_derive::{Deserialize, Serialize}, + solana_bincode::limited_deserialize, + solana_hash::Hash, + solana_instruction::Instruction, + solana_nonce::NONCED_TX_MARKER_IX_INDEX, + solana_program::{ + instruction::CompiledInstruction, message::Message, system_instruction::SystemInstruction, + system_program, }, - serde::Serialize, - solana_feature_set as feature_set, - solana_program::{system_instruction::SystemInstruction, system_program}, + solana_pubkey::Pubkey, solana_sanitize::{Sanitize, SanitizeError}, solana_short_vec as short_vec, + solana_signature::Signature, + solana_signer::{signers::Signers, SignerError}, + solana_transaction_error::{TransactionError, TransactionResult as Result}, std::result, }; -mod sanitized; -mod versioned; - -#[deprecated( - since = "2.2.0", - note = "Use `solana_transaction_error::TransactionResult` instead" -)] -pub use solana_transaction_error::TransactionResult as Result; -#[deprecated(since = "2.1.0", note = "Use solana_transaction_error crate instead")] -pub use solana_transaction_error::{ - AddressLoaderError, SanitizeMessageError, TransactionError, TransportError, TransportResult, -}; -pub use {sanitized::*, versioned::*}; +pub mod sanitized; +pub mod simple_vote_transaction_checker; +pub mod versioned; +mod wasm; #[derive(PartialEq, Eq, Clone, Copy, Debug)] pub enum TransactionVerificationMode { @@ -160,7 +147,7 @@ pub enum TransactionVerificationMode { /// they are submitted by clients in [`Transaction`]s containing one or /// more instructions, and signed by one or more [`Signer`]s. /// -/// [`Signer`]: crate::signer::Signer +/// [`Signer`]: https://docs.rs/solana-signer/latest/solana_signer/trait.Signer.html /// /// See the [module documentation] for more details about transactions. /// @@ -177,8 +164,8 @@ pub enum TransactionVerificationMode { #[cfg(not(target_arch = "wasm32"))] #[cfg_attr( feature = "frozen-abi", - derive(AbiExample), - frozen_abi(digest = "76BDTr3Xm3VP7h4eSiw6pZHKc5yYewDufyia3Yedh6GG") + derive(solana_frozen_abi_macro::AbiExample), + solana_frozen_abi_macro::frozen_abi(digest = "686AAhRhjXpqKidmJEdHHcJCL9XxCxebu8Xmku9shp83") )] #[derive(Debug, PartialEq, Default, Eq, Clone, Serialize, Deserialize)] pub struct Transaction { @@ -187,9 +174,9 @@ pub struct Transaction { /// is equal to [`num_required_signatures`] of the `Message`'s /// [`MessageHeader`]. /// - /// [`account_keys`]: Message::account_keys - /// [`MessageHeader`]: crate::message::MessageHeader - /// [`num_required_signatures`]: crate::message::MessageHeader::num_required_signatures + /// [`account_keys`]: https://docs.rs/solana-program/latest/solana_program/message/legacy/struct.Message.html#structfield.account_keys + /// [`MessageHeader`]: https://docs.rs/solana-program/latest/solana_program/message/struct.MessageHeader.html + /// [`num_required_signatures`]: https://docs.rs/solana-program/latest/solana_program/message/struct.MessageHeader.html#structfield.num_required_signatures // NOTE: Serialization-related changes must be paired with the direct read at sigverify. #[serde(with = "short_vec")] pub signatures: Vec, @@ -244,14 +231,13 @@ impl Transaction { /// # use solana_sdk::example_mocks::solana_rpc_client; /// use anyhow::Result; /// use borsh::{BorshSerialize, BorshDeserialize}; + /// use solana_instruction::Instruction; + /// use solana_keypair::Keypair; + /// use solana_program::message::Message; + /// use solana_pubkey::Pubkey; /// use solana_rpc_client::rpc_client::RpcClient; - /// use solana_sdk::{ - /// instruction::Instruction, - /// message::Message, - /// pubkey::Pubkey, - /// signature::{Keypair, Signer}, - /// transaction::Transaction, - /// }; + /// use solana_signer::Signer; + /// use solana_transaction::Transaction; /// /// // A custom program instruction. This would typically be defined in /// // another crate so it can be shared between the on-chain program and @@ -323,14 +309,13 @@ impl Transaction { /// # use solana_sdk::example_mocks::solana_rpc_client; /// use anyhow::Result; /// use borsh::{BorshSerialize, BorshDeserialize}; + /// use solana_instruction::Instruction; + /// use solana_keypair::Keypair; + /// use solana_program::message::Message; + /// use solana_pubkey::Pubkey; /// use solana_rpc_client::rpc_client::RpcClient; - /// use solana_sdk::{ - /// instruction::Instruction, - /// message::Message, - /// pubkey::Pubkey, - /// signature::{Keypair, Signer}, - /// transaction::Transaction, - /// }; + /// use solana_signer::Signer; + /// use solana_transaction::Transaction; /// /// // A custom program instruction. This would typically be defined in /// // another crate so it can be shared between the on-chain program and @@ -402,14 +387,13 @@ impl Transaction { /// # use solana_sdk::example_mocks::solana_rpc_client; /// use anyhow::Result; /// use borsh::{BorshSerialize, BorshDeserialize}; + /// use solana_instruction::Instruction; + /// use solana_keypair::Keypair; + /// use solana_program::message::Message; + /// use solana_pubkey::Pubkey; /// use solana_rpc_client::rpc_client::RpcClient; - /// use solana_sdk::{ - /// instruction::Instruction, - /// message::Message, - /// pubkey::Pubkey, - /// signature::{Keypair, Signer}, - /// transaction::Transaction, - /// }; + /// use solana_signer::Signer; + /// use solana_transaction::Transaction; /// /// // A custom program instruction. This would typically be defined in /// // another crate so it can be shared between the on-chain program and @@ -478,14 +462,13 @@ impl Transaction { /// # use solana_sdk::example_mocks::solana_rpc_client; /// use anyhow::Result; /// use borsh::{BorshSerialize, BorshDeserialize}; + /// use solana_instruction::Instruction; + /// use solana_keypair::Keypair; + /// use solana_program::message::Message; + /// use solana_pubkey::Pubkey; /// use solana_rpc_client::rpc_client::RpcClient; - /// use solana_sdk::{ - /// instruction::Instruction, - /// message::Message, - /// pubkey::Pubkey, - /// signature::{Keypair, Signer}, - /// transaction::Transaction, - /// }; + /// use solana_signer::Signer; + /// use solana_transaction::Transaction; /// /// // A custom program instruction. This would typically be defined in /// // another crate so it can be shared between the on-chain program and @@ -686,14 +669,13 @@ impl Transaction { /// # use solana_sdk::example_mocks::solana_rpc_client; /// use anyhow::Result; /// use borsh::{BorshSerialize, BorshDeserialize}; + /// use solana_instruction::Instruction; + /// use solana_keypair::Keypair; + /// use solana_program::message::Message; + /// use solana_pubkey::Pubkey; /// use solana_rpc_client::rpc_client::RpcClient; - /// use solana_sdk::{ - /// instruction::Instruction, - /// message::Message, - /// pubkey::Pubkey, - /// signature::{Keypair, Signer}, - /// transaction::Transaction, - /// }; + /// use solana_signer::Signer; + /// use solana_transaction::Transaction; /// /// // A custom program instruction. This would typically be defined in /// // another crate so it can be shared between the on-chain program and @@ -824,14 +806,13 @@ impl Transaction { /// # use solana_sdk::example_mocks::solana_rpc_client; /// use anyhow::Result; /// use borsh::{BorshSerialize, BorshDeserialize}; + /// use solana_instruction::Instruction; + /// use solana_keypair::Keypair; + /// use solana_program::message::Message; + /// use solana_pubkey::Pubkey; /// use solana_rpc_client::rpc_client::RpcClient; - /// use solana_sdk::{ - /// instruction::Instruction, - /// message::Message, - /// pubkey::Pubkey, - /// signature::{Keypair, Signer}, - /// transaction::Transaction, - /// }; + /// use solana_signer::Signer; + /// use solana_transaction::Transaction; /// /// // A custom program instruction. This would typically be defined in /// // another crate so it can be shared between the on-chain program and @@ -928,11 +909,11 @@ impl Transaction { /// See the documentation for the [`solana-remote-wallet`] crate for details /// on the operation of [`RemoteKeypair`] signers. /// - /// [`num_required_signatures`]: crate::message::MessageHeader::num_required_signatures + /// [`num_required_signatures`]: https://docs.rs/solana-program/latest/solana_program/message/struct.MessageHeader.html#structfield.num_required_signatures /// [`account_keys`]: Message::account_keys - /// [`Presigner`]: crate::signer::presigner::Presigner - /// [`PresignerError`]: crate::signer::presigner::PresignerError - /// [`PresignerError::VerificationFailure`]: crate::signer::presigner::PresignerError::VerificationFailure + /// [`Presigner`]: https://docs.rs/solana-presigner/latest/solana_presigner/struct.Presigner.html + /// [`PresignerError`]: https://docs.rs/solana-signer/latest/solana_signer/enum.PresignerError.html + /// [`PresignerError::VerificationFailure`]: https://docs.rs/solana-signer/latest/solana_signer/enum.PresignerError.html#variant.WrongSize /// [`solana-remote-wallet`]: https://docs.rs/solana-remote-wallet/latest/ /// [`RemoteKeypair`]: https://docs.rs/solana-remote-wallet/latest/solana_remote_wallet/remote_keypair/struct.RemoteKeypair.html pub fn try_partial_sign( @@ -987,6 +968,7 @@ impl Transaction { Signature::default() } + #[cfg(feature = "verify")] /// Verifies that all signers have signed the message. /// /// # Errors @@ -1005,6 +987,7 @@ impl Transaction { } } + #[cfg(feature = "verify")] /// Verify the transaction and hash its message. /// /// # Errors @@ -1023,6 +1006,7 @@ impl Transaction { } } + #[cfg(feature = "verify")] /// Verifies that all signers have signed the message. /// /// Returns a vector with the length of required signatures, where each @@ -1031,6 +1015,7 @@ impl Transaction { self._verify_with_results(&self.message_data()) } + #[cfg(feature = "verify")] pub(crate) fn _verify_with_results(&self, message_bytes: &[u8]) -> Vec { self.signatures .iter() @@ -1039,8 +1024,9 @@ impl Transaction { .collect() } + #[cfg(feature = "precompiles")] /// Verify the precompiled programs in this transaction. - pub fn verify_precompiles(&self, feature_set: &feature_set::FeatureSet) -> Result<()> { + pub fn verify_precompiles(&self, feature_set: &solana_feature_set::FeatureSet) -> Result<()> { for instruction in &self.message().instructions { // The Transaction may not be sanitized at this point if instruction.program_id_index as usize >= self.message().account_keys.len() { @@ -1048,7 +1034,7 @@ impl Transaction { } let program_id = &self.message().account_keys[instruction.program_id_index as usize]; - verify_if_precompile( + solana_precompiles::verify_if_precompile( program_id, instruction, &self.message().instructions, @@ -1075,6 +1061,7 @@ impl Transaction { .collect()) } + #[cfg(feature = "verify")] /// Replace all the signatures and pubkeys. pub fn replace_signatures(&mut self, signers: &[(Pubkey, Signature)]) -> Result<()> { let num_required_signatures = self.message.header.num_required_signatures as usize; @@ -1125,7 +1112,7 @@ pub fn uses_durable_nonce(tx: &Transaction) -> Option<&CompiledInstruction> { ) // Is a nonce advance instruction && matches!( - limited_deserialize(&instruction.data), + limited_deserialize(&instruction.data, solana_packet::PACKET_DATA_SIZE as u64), Ok(SystemInstruction::AdvanceNonceAccount) ) }) @@ -1137,13 +1124,13 @@ mod tests { use { super::*, - crate::{ - hash::hash, - instruction::AccountMeta, - signature::{Keypair, Presigner, Signer}, - system_instruction, - }, bincode::{deserialize, serialize, serialized_size}, + solana_instruction::AccountMeta, + solana_keypair::Keypair, + solana_presigner::Presigner, + solana_program::system_instruction, + solana_sha256_hasher::hash, + solana_signer::Signer, std::mem::size_of, }; @@ -1156,10 +1143,10 @@ mod tests { #[test] fn test_refs() { let key = Keypair::new(); - let key1 = solana_sdk::pubkey::new_rand(); - let key2 = solana_sdk::pubkey::new_rand(); - let prog1 = solana_sdk::pubkey::new_rand(); - let prog2 = solana_sdk::pubkey::new_rand(); + let key1 = solana_pubkey::new_rand(); + let key2 = solana_pubkey::new_rand(); + let prog1 = solana_pubkey::new_rand(); + let prog2 = solana_pubkey::new_rand(); let instructions = vec![ CompiledInstruction::new(3, &(), vec![0, 1]), CompiledInstruction::new(4, &(), vec![0, 2]), @@ -1227,7 +1214,7 @@ mod tests { fn test_sanitize_txs() { let key = Keypair::new(); let id0 = Pubkey::default(); - let program_id = solana_sdk::pubkey::new_rand(); + let program_id = solana_pubkey::new_rand(); let ix = Instruction::new_with_bincode( program_id, &0, @@ -1326,7 +1313,7 @@ mod tests { fn test_transaction_minimum_serialized_size() { let alice_keypair = Keypair::new(); let alice_pubkey = alice_keypair.pubkey(); - let bob_pubkey = solana_sdk::pubkey::new_rand(); + let bob_pubkey = solana_pubkey::new_rand(); let ix = system_instruction::transfer(&alice_pubkey, &bob_pubkey, 42); let expected_data_size = size_of::() + size_of::(); @@ -1404,7 +1391,7 @@ mod tests { #[should_panic] fn test_partial_sign_mismatched_key() { let keypair = Keypair::new(); - let fee_payer = solana_sdk::pubkey::new_rand(); + let fee_payer = solana_pubkey::new_rand(); let ix = Instruction::new_with_bincode( Pubkey::default(), &0, @@ -1487,7 +1474,7 @@ mod tests { let program_id = Pubkey::default(); let keypair0 = Keypair::new(); let id0 = keypair0.pubkey(); - let id1 = solana_sdk::pubkey::new_rand(); + let id1 = solana_pubkey::new_rand(); let ix = Instruction::new_with_bincode( program_id, &0, @@ -1538,7 +1525,7 @@ mod tests { assert_eq!(tx.signatures[1], presigner_sig); // Wrong key should error, not panic - let another_pubkey = solana_sdk::pubkey::new_rand(); + let another_pubkey = solana_pubkey::new_rand(); let ix = Instruction::new_with_bincode( program_id, &0, diff --git a/sdk/src/transaction/sanitized.rs b/sdk/transaction/src/sanitized.rs similarity index 93% rename from sdk/src/transaction/sanitized.rs rename to sdk/transaction/src/sanitized.rs index af21811d2bbd2b..d60c3e4659524c 100644 --- a/sdk/src/transaction/sanitized.rs +++ b/sdk/transaction/src/sanitized.rs @@ -1,26 +1,21 @@ -#![cfg(feature = "full")] - -pub use crate::message::{AddressLoader, SimpleAddressLoader}; use { - super::SanitizedVersionedTransaction, crate::{ - hash::Hash, - message::{ - legacy, - v0::{self, LoadedAddresses}, - LegacyMessage, SanitizedMessage, VersionedMessage, - }, - precompiles::verify_if_precompile, - pubkey::Pubkey, - reserved_account_keys::ReservedAccountKeys, - signature::Signature, simple_vote_transaction_checker::is_simple_vote_transaction, - transaction::{Result, Transaction, VersionedTransaction}, + versioned::{sanitized::SanitizedVersionedTransaction, VersionedTransaction}, + Transaction, }, - solana_feature_set as feature_set, - solana_program::{instruction::InstructionError, message::SanitizedVersionedMessage}, + solana_hash::Hash, + solana_program::message::{ + legacy, + v0::{self, LoadedAddresses}, + AddressLoader, LegacyMessage, SanitizedMessage, SanitizedVersionedMessage, + VersionedMessage, + }, + solana_pubkey::Pubkey, + solana_reserved_account_keys::ReservedAccountKeys, solana_sanitize::Sanitize, - solana_transaction_error::TransactionError, + solana_signature::Signature, + solana_transaction_error::{TransactionError, TransactionResult as Result}, std::collections::HashSet, }; @@ -259,6 +254,7 @@ impl SanitizedTransaction { self.message.get_durable_nonce() } + #[cfg(feature = "verify")] /// Return the serialized message data to sign. fn message_data(&self) -> Vec { match &self.message { @@ -267,6 +263,7 @@ impl SanitizedTransaction { } } + #[cfg(feature = "verify")] /// Verify the transaction signatures pub fn verify(&self) -> Result<()> { let message_bytes = self.message_data(); @@ -283,12 +280,13 @@ impl SanitizedTransaction { } } + #[cfg(feature = "precompiles")] /// Verify the precompiled programs in this transaction - pub fn verify_precompiles(&self, feature_set: &feature_set::FeatureSet) -> Result<()> { + pub fn verify_precompiles(&self, feature_set: &solana_feature_set::FeatureSet) -> Result<()> { for (index, (program_id, instruction)) in self.message.program_instructions_iter().enumerate() { - verify_if_precompile( + solana_precompiles::verify_if_precompile( program_id, instruction, self.message().instructions(), @@ -297,7 +295,7 @@ impl SanitizedTransaction { .map_err(|err| { TransactionError::InstructionError( index as u8, - InstructionError::Custom(err as u32), + solana_instruction::error::InstructionError::Custom(err as u32), ) })?; } @@ -338,14 +336,13 @@ impl SanitizedTransaction { mod tests { use { super::*, - crate::{ - reserved_account_keys::ReservedAccountKeys, - signer::{keypair::Keypair, Signer}, - }, + solana_keypair::Keypair, solana_program::{ - message::MessageHeader, + message::{MessageHeader, SimpleAddressLoader}, vote::{self, state::Vote}, }, + solana_reserved_account_keys::ReservedAccountKeys, + solana_signer::Signer, }; #[test] diff --git a/sdk/src/simple_vote_transaction_checker.rs b/sdk/transaction/src/simple_vote_transaction_checker.rs similarity index 84% rename from sdk/src/simple_vote_transaction_checker.rs rename to sdk/transaction/src/simple_vote_transaction_checker.rs index cc8ccc02f2484f..7029911552f9ce 100644 --- a/sdk/src/simple_vote_transaction_checker.rs +++ b/sdk/transaction/src/simple_vote_transaction_checker.rs @@ -1,9 +1,6 @@ -#![cfg(feature = "full")] - use { - crate::{message::VersionedMessage, transaction::SanitizedVersionedTransaction}, - solana_pubkey::Pubkey, - solana_signature::Signature, + crate::versioned::sanitized::SanitizedVersionedTransaction, + solana_program::message::VersionedMessage, solana_pubkey::Pubkey, solana_signature::Signature, }; /// Simple vote transaction meets these conditions: @@ -46,6 +43,6 @@ pub fn is_simple_vote_transaction_impl<'a>( && instruction_programs .next() .xor(instruction_programs.next()) - .map(|program_id| program_id == &solana_sdk::vote::program::ID) + .map(|program_id| program_id == &solana_sdk_ids::vote::ID) .unwrap_or(false) } diff --git a/sdk/src/transaction/versioned/mod.rs b/sdk/transaction/src/versioned/mod.rs similarity index 92% rename from sdk/src/transaction/versioned/mod.rs rename to sdk/transaction/src/versioned/mod.rs index c9a30ab5680486..cb2cc7745b80cb 100644 --- a/sdk/src/transaction/versioned/mod.rs +++ b/sdk/transaction/src/versioned/mod.rs @@ -1,32 +1,21 @@ //! Defines a transaction which supports multiple versions of messages. -#![cfg(feature = "full")] - use { - crate::{ - hash::Hash, - message::VersionedMessage, - signature::Signature, - signer::SignerError, - signers::Signers, - transaction::{Result, Transaction}, + crate::Transaction, + serde_derive::{Deserialize, Serialize}, + solana_bincode::limited_deserialize, + solana_program::{ + message::VersionedMessage, nonce::NONCED_TX_MARKER_IX_INDEX, + system_instruction::SystemInstruction, system_program, }, - serde::Serialize, solana_sanitize::SanitizeError, solana_short_vec as short_vec, - solana_transaction_error::TransactionError, + solana_signature::Signature, + solana_signer::{signers::Signers, SignerError}, std::cmp::Ordering, }; -mod sanitized; - -pub use sanitized::*; -use { - crate::program_utils::limited_deserialize, - solana_program::{ - nonce::NONCED_TX_MARKER_IX_INDEX, system_instruction::SystemInstruction, system_program, - }, -}; +pub mod sanitized; /// Type that serializes to the string "legacy" #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] @@ -48,7 +37,7 @@ impl TransactionVersion { // NOTE: Serialization-related changes must be paired with the direct read at sigverify. /// An atomic transaction -#[cfg_attr(feature = "frozen-abi", derive(AbiExample))] +#[cfg_attr(feature = "frozen-abi", derive(solana_frozen_abi_macro::AbiExample))] #[derive(Debug, PartialEq, Default, Eq, Clone, Serialize, Deserialize)] pub struct VersionedTransaction { /// List of signatures @@ -170,26 +159,31 @@ impl VersionedTransaction { } } + #[cfg(feature = "verify")] /// Verify the transaction and hash its message - pub fn verify_and_hash_message(&self) -> Result { + pub fn verify_and_hash_message( + &self, + ) -> solana_transaction_error::TransactionResult { let message_bytes = self.message.serialize(); if !self ._verify_with_results(&message_bytes) .iter() .all(|verify_result| *verify_result) { - Err(TransactionError::SignatureFailure) + Err(solana_transaction_error::TransactionError::SignatureFailure) } else { Ok(VersionedMessage::hash_raw_message(&message_bytes)) } } + #[cfg(feature = "verify")] /// Verify the transaction and return a list of verification results pub fn verify_with_results(&self) -> Vec { let message_bytes = self.message.serialize(); self._verify_with_results(&message_bytes) } + #[cfg(feature = "verify")] fn _verify_with_results(&self, message_bytes: &[u8]) -> Vec { self.signatures .iter() @@ -212,7 +206,7 @@ impl VersionedTransaction { ) // Is a nonce advance instruction && matches!( - limited_deserialize(&instruction.data), + limited_deserialize(&instruction.data, solana_packet::PACKET_DATA_SIZE as u64,), Ok(SystemInstruction::AdvanceNonceAccount) ) }) @@ -224,15 +218,15 @@ impl VersionedTransaction { mod tests { use { super::*, - crate::{ - message::Message as LegacyMessage, - signer::{keypair::Keypair, Signer}, - system_instruction, - }, + solana_hash::Hash, + solana_keypair::Keypair, solana_program::{ instruction::{AccountMeta, Instruction}, + message::Message as LegacyMessage, pubkey::Pubkey, + system_instruction, }, + solana_signer::Signer, }; #[test] diff --git a/sdk/src/transaction/versioned/sanitized.rs b/sdk/transaction/src/versioned/sanitized.rs similarity index 93% rename from sdk/src/transaction/versioned/sanitized.rs rename to sdk/transaction/src/versioned/sanitized.rs index 6243292fce3526..880f93bdca7cb5 100644 --- a/sdk/src/transaction/versioned/sanitized.rs +++ b/sdk/transaction/src/versioned/sanitized.rs @@ -1,6 +1,6 @@ use { - super::VersionedTransaction, crate::signature::Signature, - solana_program::message::SanitizedVersionedMessage, solana_sanitize::SanitizeError, + crate::versioned::VersionedTransaction, solana_program::message::SanitizedVersionedMessage, + solana_sanitize::SanitizeError, solana_signature::Signature, }; /// Wraps a sanitized `VersionedTransaction` to provide a safe API diff --git a/sdk/transaction/src/wasm.rs b/sdk/transaction/src/wasm.rs new file mode 100644 index 00000000000000..208a76bfa2d415 --- /dev/null +++ b/sdk/transaction/src/wasm.rs @@ -0,0 +1,54 @@ +//! `Transaction` Javascript interface +#![cfg(target_arch = "wasm32")] +#![allow(non_snake_case)] +use { + crate::{hash::Hash, message::Message, signer::keypair::Keypair, transaction::Transaction}, + solana_program::{ + pubkey::Pubkey, + wasm::{display_to_jsvalue, instructions::Instructions}, + }, + wasm_bindgen::prelude::*, +}; + +#[wasm_bindgen] +impl Transaction { + /// Create a new `Transaction` + #[wasm_bindgen(constructor)] + pub fn constructor(instructions: Instructions, payer: Option) -> Transaction { + let instructions: Vec<_> = instructions.into(); + Transaction::new_with_payer(&instructions, payer.as_ref()) + } + + /// Return a message containing all data that should be signed. + #[wasm_bindgen(js_name = message)] + pub fn js_message(&self) -> Message { + self.message.clone() + } + + /// Return the serialized message data to sign. + pub fn messageData(&self) -> Box<[u8]> { + self.message_data().into() + } + + /// Verify the transaction + #[wasm_bindgen(js_name = verify)] + pub fn js_verify(&self) -> Result<(), JsValue> { + self.verify().map_err(display_to_jsvalue) + } + + pub fn partialSign(&mut self, keypair: &Keypair, recent_blockhash: &Hash) { + self.partial_sign(&[keypair], *recent_blockhash); + } + + pub fn isSigned(&self) -> bool { + self.is_signed() + } + + pub fn toBytes(&self) -> Box<[u8]> { + bincode::serialize(self).unwrap().into() + } + + pub fn fromBytes(bytes: &[u8]) -> Result { + bincode::deserialize(bytes).map_err(display_to_jsvalue) + } +} diff --git a/svm/examples/Cargo.lock b/svm/examples/Cargo.lock index d768fff746d0a5..212b58601eeeb0 100644 --- a/svm/examples/Cargo.lock +++ b/svm/examples/Cargo.lock @@ -6581,6 +6581,7 @@ dependencies = [ "solana-signature", "solana-signer", "solana-time-utils", + "solana-transaction", "solana-transaction-context", "solana-transaction-error", "thiserror 2.0.3", @@ -7114,6 +7115,30 @@ dependencies = [ "tokio-util 0.7.12", ] +[[package]] +name = "solana-transaction" +version = "2.2.0" +dependencies = [ + "serde", + "serde_derive", + "solana-bincode", + "solana-feature-set", + "solana-hash", + "solana-instruction", + "solana-nonce", + "solana-packet", + "solana-precompiles", + "solana-program", + "solana-pubkey", + "solana-reserved-account-keys", + "solana-sanitize", + "solana-sdk-ids", + "solana-short-vec", + "solana-signature", + "solana-signer", + "solana-transaction-error", +] + [[package]] name = "solana-transaction-context" version = "2.2.0" From b25ea7dedd6625bacb135772dd3b5969fbc122e5 Mon Sep 17 00:00:00 2001 From: kevinheavey Date: Thu, 14 Nov 2024 19:29:20 +0400 Subject: [PATCH 02/24] make serde and bincode optional --- sdk/Cargo.toml | 2 ++ sdk/transaction/Cargo.toml | 21 +++++++++----- sdk/transaction/src/lib.rs | 27 +++++++++++------- sdk/transaction/src/versioned/mod.rs | 41 +++++++++++++++++++--------- 4 files changed, 61 insertions(+), 30 deletions(-) diff --git a/sdk/Cargo.toml b/sdk/Cargo.toml index 9b7246a201a636..0d4341c98fc749 100644 --- a/sdk/Cargo.toml +++ b/sdk/Cargo.toml @@ -175,7 +175,9 @@ solana-signature = { workspace = true, features = [ solana-signer = { workspace = true, optional = true } solana-time-utils = { workspace = true } solana-transaction = { workspace = true, features = [ + "bincode", "precompiles", + "serde", "verify" ], optional = true } solana-transaction-context = { workspace = true, features = ["bincode"] } diff --git a/sdk/transaction/Cargo.toml b/sdk/transaction/Cargo.toml index f9e1e660ed747d..994c76936f1034 100644 --- a/sdk/transaction/Cargo.toml +++ b/sdk/transaction/Cargo.toml @@ -10,15 +10,15 @@ license = { workspace = true } edition = { workspace = true } [dependencies] -serde = { workspace = true } -serde_derive = { workspace = true } -solana-bincode = { workspace = true } +serde = { workspace = true, optional = true } +serde_derive = { workspace = true, optional = true } +solana-bincode = { workspace = true, optional = true } solana-feature-set = { workspace = true } solana-frozen-abi = { workspace = true, optional = true } solana-frozen-abi-macro = { workspace = true, optional = true } solana-hash = { workspace = true } solana-instruction = { workspace = true } -solana-nonce = { workspace = true } +solana-nonce = { workspace = true, optional = true } solana-packet = { workspace = true } solana-precompiles = { workspace = true, optional = true } solana-program = { workspace = true } @@ -26,8 +26,8 @@ solana-pubkey = { workspace = true } solana-reserved-account-keys = { workspace = true } solana-sanitize = { workspace = true } solana-sdk-ids = { workspace = true } -solana-short-vec = { workspace = true } -solana-signature = { workspace = true, features = ["serde"] } +solana-short-vec = { workspace = true, optional = true } +solana-signature = { workspace = true } solana-signer = { workspace = true } solana-transaction-error = { workspace = true } @@ -46,9 +46,16 @@ solana-sha256-hasher = { workspace = true } solana-transaction = { path = ".", features = ["dev-context-only-utils"] } [features] -dev-context-only-utils = ["precompiles", "verify"] +bincode = ["dep:solana-bincode", "dep:solana-nonce", "serde"] +dev-context-only-utils = ["bincode", "precompiles", "serde", "verify"] frozen-abi = ["dep:solana-frozen-abi", "dep:solana-frozen-abi-macro"] precompiles = ["dep:solana-precompiles"] +serde = [ + "dep:serde", + "dep:serde_derive", + "dep:solana-short-vec", + "solana-signature/serde", +] verify = ["solana-signature/verify"] diff --git a/sdk/transaction/src/lib.rs b/sdk/transaction/src/lib.rs index bb1207cc911e07..d58d6830a6b0dd 100644 --- a/sdk/transaction/src/lib.rs +++ b/sdk/transaction/src/lib.rs @@ -110,19 +110,23 @@ #[cfg(target_arch = "wasm32")] use crate::wasm_bindgen; +#[cfg(feature = "serde")] use { serde_derive::{Deserialize, Serialize}, + solana_short_vec as short_vec, +}; +#[cfg(feature = "bincode")] +use { solana_bincode::limited_deserialize, + solana_nonce::NONCED_TX_MARKER_IX_INDEX, + solana_program::{system_instruction::SystemInstruction, system_program}, +}; +use { solana_hash::Hash, solana_instruction::Instruction, - solana_nonce::NONCED_TX_MARKER_IX_INDEX, - solana_program::{ - instruction::CompiledInstruction, message::Message, system_instruction::SystemInstruction, - system_program, - }, + solana_program::{instruction::CompiledInstruction, message::Message}, solana_pubkey::Pubkey, solana_sanitize::{Sanitize, SanitizeError}, - solana_short_vec as short_vec, solana_signature::Signature, solana_signer::{signers::Signers, SignerError}, solana_transaction_error::{TransactionError, TransactionResult as Result}, @@ -167,7 +171,8 @@ pub enum TransactionVerificationMode { derive(solana_frozen_abi_macro::AbiExample), solana_frozen_abi_macro::frozen_abi(digest = "686AAhRhjXpqKidmJEdHHcJCL9XxCxebu8Xmku9shp83") )] -#[derive(Debug, PartialEq, Default, Eq, Clone, Serialize, Deserialize)] +#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] +#[derive(Debug, PartialEq, Default, Eq, Clone)] pub struct Transaction { /// A set of signatures of a serialized [`Message`], signed by the first /// keys of the `Message`'s [`account_keys`], where the number of signatures @@ -178,7 +183,7 @@ pub struct Transaction { /// [`MessageHeader`]: https://docs.rs/solana-program/latest/solana_program/message/struct.MessageHeader.html /// [`num_required_signatures`]: https://docs.rs/solana-program/latest/solana_program/message/struct.MessageHeader.html#structfield.num_required_signatures // NOTE: Serialization-related changes must be paired with the direct read at sigverify. - #[serde(with = "short_vec")] + #[cfg_attr(feature = "serde", serde(with = "short_vec"))] pub signatures: Vec, /// The message to sign. @@ -195,10 +200,11 @@ pub struct Transaction { derive(AbiExample), frozen_abi(digest = "H7xQFcd1MtMv9QKZWGatBAXwhg28tpeX59P3s8ZZLAY4") )] -#[derive(Debug, PartialEq, Default, Eq, Clone, Serialize, Deserialize)] +#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] +#[derive(Debug, PartialEq, Default, Eq, Clone)] pub struct Transaction { #[wasm_bindgen(skip)] - #[serde(with = "short_vec")] + #[cfg_attr(feature = "serde", serde(with = "short_vec"))] pub signatures: Vec, #[wasm_bindgen(skip)] @@ -1098,6 +1104,7 @@ impl Transaction { } } +#[cfg(feature = "bincode")] /// Returns true if transaction begins with an advance nonce instruction. pub fn uses_durable_nonce(tx: &Transaction) -> Option<&CompiledInstruction> { let message = tx.message(); diff --git a/sdk/transaction/src/versioned/mod.rs b/sdk/transaction/src/versioned/mod.rs index cb2cc7745b80cb..71dacd213b2ff5 100644 --- a/sdk/transaction/src/versioned/mod.rs +++ b/sdk/transaction/src/versioned/mod.rs @@ -2,30 +2,43 @@ use { crate::Transaction, - serde_derive::{Deserialize, Serialize}, - solana_bincode::limited_deserialize, - solana_program::{ - message::VersionedMessage, nonce::NONCED_TX_MARKER_IX_INDEX, - system_instruction::SystemInstruction, system_program, - }, + solana_program::message::VersionedMessage, solana_sanitize::SanitizeError, - solana_short_vec as short_vec, solana_signature::Signature, solana_signer::{signers::Signers, SignerError}, std::cmp::Ordering, }; +#[cfg(feature = "serde")] +use { + serde_derive::{Deserialize, Serialize}, + solana_short_vec as short_vec, +}; +#[cfg(feature = "bincode")] +use { + solana_bincode::limited_deserialize, + solana_nonce::NONCED_TX_MARKER_IX_INDEX, + solana_program::{system_instruction::SystemInstruction, system_program}, +}; pub mod sanitized; /// Type that serializes to the string "legacy" -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] +#[cfg_attr( + feature = "serde", + derive(Deserialize, Serialize), + serde(rename_all = "camelCase") +)] +#[derive(Clone, Debug, PartialEq, Eq)] pub enum Legacy { Legacy, } -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase", untagged)] +#[cfg_attr( + feature = "serde", + derive(Deserialize, Serialize), + serde(rename_all = "camelCase", untagged) +)] +#[derive(Clone, Debug, PartialEq, Eq)] pub enum TransactionVersion { Legacy(Legacy), Number(u8), @@ -38,10 +51,11 @@ impl TransactionVersion { // NOTE: Serialization-related changes must be paired with the direct read at sigverify. /// An atomic transaction #[cfg_attr(feature = "frozen-abi", derive(solana_frozen_abi_macro::AbiExample))] -#[derive(Debug, PartialEq, Default, Eq, Clone, Serialize, Deserialize)] +#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] +#[derive(Debug, PartialEq, Default, Eq, Clone)] pub struct VersionedTransaction { /// List of signatures - #[serde(with = "short_vec")] + #[cfg_attr(feature = "serde", serde(with = "short_vec"))] pub signatures: Vec, /// Message to sign. pub message: VersionedMessage, @@ -192,6 +206,7 @@ impl VersionedTransaction { .collect() } + #[cfg(feature = "bincode")] /// Returns true if transaction begins with an advance nonce instruction. pub fn uses_durable_nonce(&self) -> bool { let message = &self.message; From 4cf2f689291df4aa66fd3a4e11304cbfd16da82c Mon Sep 17 00:00:00 2001 From: kevinheavey Date: Thu, 14 Nov 2024 21:18:18 +0400 Subject: [PATCH 03/24] fix frozen-abi support --- sdk/Cargo.toml | 3 ++- sdk/transaction/src/lib.rs | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/sdk/Cargo.toml b/sdk/Cargo.toml index 0d4341c98fc749..32c055422d8c2f 100644 --- a/sdk/Cargo.toml +++ b/sdk/Cargo.toml @@ -75,7 +75,8 @@ frozen-abi = [ "solana-reward-info/frozen-abi", "solana-short-vec/frozen-abi", "solana-signature/frozen-abi", - "solana-transaction-error/frozen-abi", + "solana-transaction/frozen-abi", + "solana-transaction-error/frozen-abi" ] # Enables the "vendored" feature of openssl inside of secp256r1-program openssl-vendored = ["solana-precompiles/openssl-vendored"] diff --git a/sdk/transaction/src/lib.rs b/sdk/transaction/src/lib.rs index d58d6830a6b0dd..684751be629c8d 100644 --- a/sdk/transaction/src/lib.rs +++ b/sdk/transaction/src/lib.rs @@ -1,3 +1,4 @@ +#![cfg_attr(feature = "frozen-abi", feature(min_specialization))] //! Atomically-committed sequences of instructions. //! //! While [`Instruction`]s are the basic unit of computation in Solana, they are From f28750c5dca0b2d259e9fca82b9ee7ef538b28d6 Mon Sep 17 00:00:00 2001 From: kevinheavey Date: Thu, 14 Nov 2024 21:22:00 +0400 Subject: [PATCH 04/24] missing dep for frozen-abi --- Cargo.lock | 1 + sdk/transaction/Cargo.toml | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index da263a508b2eba..d8a0ad4b277f0c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9275,6 +9275,7 @@ dependencies = [ "solana-hash", "solana-instruction", "solana-keypair", + "solana-logger", "solana-nonce", "solana-packet", "solana-precompiles", diff --git a/sdk/transaction/Cargo.toml b/sdk/transaction/Cargo.toml index 994c76936f1034..57811996c8629b 100644 --- a/sdk/transaction/Cargo.toml +++ b/sdk/transaction/Cargo.toml @@ -18,6 +18,7 @@ solana-frozen-abi = { workspace = true, optional = true } solana-frozen-abi-macro = { workspace = true, optional = true } solana-hash = { workspace = true } solana-instruction = { workspace = true } +solana-logger = { workspace = true, optional = true } solana-nonce = { workspace = true, optional = true } solana-packet = { workspace = true } solana-precompiles = { workspace = true, optional = true } @@ -48,7 +49,11 @@ solana-transaction = { path = ".", features = ["dev-context-only-utils"] } [features] bincode = ["dep:solana-bincode", "dep:solana-nonce", "serde"] dev-context-only-utils = ["bincode", "precompiles", "serde", "verify"] -frozen-abi = ["dep:solana-frozen-abi", "dep:solana-frozen-abi-macro"] +frozen-abi = [ + "dep:solana-frozen-abi", + "dep:solana-frozen-abi-macro", + "dep:solana-logger", +] precompiles = ["dep:solana-precompiles"] serde = [ "dep:serde", From 29a5956763c69e4cf76644982049845772644c86 Mon Sep 17 00:00:00 2001 From: kevinheavey Date: Thu, 14 Nov 2024 21:32:17 +0400 Subject: [PATCH 05/24] update digest --- sdk/transaction/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/transaction/src/lib.rs b/sdk/transaction/src/lib.rs index 684751be629c8d..4c0f195506ab4e 100644 --- a/sdk/transaction/src/lib.rs +++ b/sdk/transaction/src/lib.rs @@ -170,7 +170,7 @@ pub enum TransactionVerificationMode { #[cfg_attr( feature = "frozen-abi", derive(solana_frozen_abi_macro::AbiExample), - solana_frozen_abi_macro::frozen_abi(digest = "686AAhRhjXpqKidmJEdHHcJCL9XxCxebu8Xmku9shp83") + solana_frozen_abi_macro::frozen_abi(digest = "GESn6AYYNhpNfzJXdQ6kGjqz4VjpMw3ye9rghqaEqks7") )] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] #[derive(Debug, PartialEq, Default, Eq, Clone)] From cc9188af8e8d42c460465e2b96e672b3399fe62c Mon Sep 17 00:00:00 2001 From: kevinheavey Date: Thu, 14 Nov 2024 21:37:33 +0400 Subject: [PATCH 06/24] fix circular dep --- sdk/transaction/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/transaction/Cargo.toml b/sdk/transaction/Cargo.toml index 57811996c8629b..84bbdba73941fe 100644 --- a/sdk/transaction/Cargo.toml +++ b/sdk/transaction/Cargo.toml @@ -42,7 +42,7 @@ solana-keypair = { workspace = true } solana-presigner = { workspace = true } solana-program = { workspace = true, default-features = false } solana-pubkey = { workspace = true, features = ["rand"] } -solana-sdk = { workspace = true } +solana-sdk = { path = ".." } solana-sha256-hasher = { workspace = true } solana-transaction = { path = ".", features = ["dev-context-only-utils"] } From f2ba2fe1225c0aed7fbf0b70941d73680ecb61ae Mon Sep 17 00:00:00 2001 From: kevinheavey Date: Thu, 14 Nov 2024 23:45:04 +0400 Subject: [PATCH 07/24] fmt --- sdk/transaction/Cargo.toml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sdk/transaction/Cargo.toml b/sdk/transaction/Cargo.toml index 84bbdba73941fe..86d6a733d3c207 100644 --- a/sdk/transaction/Cargo.toml +++ b/sdk/transaction/Cargo.toml @@ -52,18 +52,17 @@ dev-context-only-utils = ["bincode", "precompiles", "serde", "verify"] frozen-abi = [ "dep:solana-frozen-abi", "dep:solana-frozen-abi-macro", - "dep:solana-logger", + "dep:solana-logger" ] precompiles = ["dep:solana-precompiles"] serde = [ "dep:serde", "dep:serde_derive", "dep:solana-short-vec", - "solana-signature/serde", + "solana-signature/serde" ] verify = ["solana-signature/verify"] - [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] all-features = true From 50bee512da9812ca1fe66b4c88f71ee12b0e5bf0 Mon Sep 17 00:00:00 2001 From: kevinheavey Date: Thu, 14 Nov 2024 23:46:45 +0400 Subject: [PATCH 08/24] missing feature activation --- sdk/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/sdk/Cargo.toml b/sdk/Cargo.toml index 32c055422d8c2f..a7f2a3da3c8ef6 100644 --- a/sdk/Cargo.toml +++ b/sdk/Cargo.toml @@ -61,6 +61,7 @@ dev-context-only-utils = [ "solana-account/dev-context-only-utils", "solana-compute-budget-interface/dev-context-only-utils", "solana-rent-debits/dev-context-only-utils", + "solana-transaction/dev-context-only-utils", "solana-transaction-context/dev-context-only-utils", ] frozen-abi = [ From 16e42e9c1b525cee31c14785f47058b2274c3a75 Mon Sep 17 00:00:00 2001 From: kevinheavey Date: Fri, 15 Nov 2024 00:40:19 +0400 Subject: [PATCH 09/24] add doc_auto_cfg --- sdk/transaction/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/sdk/transaction/src/lib.rs b/sdk/transaction/src/lib.rs index 4c0f195506ab4e..728e093332d6c9 100644 --- a/sdk/transaction/src/lib.rs +++ b/sdk/transaction/src/lib.rs @@ -1,4 +1,5 @@ #![cfg_attr(feature = "frozen-abi", feature(min_specialization))] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] //! Atomically-committed sequences of instructions. //! //! While [`Instruction`]s are the basic unit of computation in Solana, they are From 5efd4baef7d4e59fe38ebeed3d3655c3dd4df29b Mon Sep 17 00:00:00 2001 From: kevinheavey Date: Fri, 15 Nov 2024 00:42:50 +0400 Subject: [PATCH 10/24] add "wasm32-unknown-unknown" to doc targets --- sdk/instruction/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/instruction/Cargo.toml b/sdk/instruction/Cargo.toml index 5826fca227ff20..6c21e3959784ea 100644 --- a/sdk/instruction/Cargo.toml +++ b/sdk/instruction/Cargo.toml @@ -48,7 +48,7 @@ serde = [ std = [] [package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] +targets = ["x86_64-unknown-linux-gnu", "wasm32-unknown-unknown"] all-features = true rustdoc-args = ["--cfg=docsrs"] From 3a299bf9fc05be9c394b1721685344340a618fe9 Mon Sep 17 00:00:00 2001 From: kevinheavey Date: Mon, 25 Nov 2024 21:32:01 +0400 Subject: [PATCH 11/24] make solana-feature-set optional --- sdk/transaction/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/transaction/Cargo.toml b/sdk/transaction/Cargo.toml index 86d6a733d3c207..cbae136cfe57ec 100644 --- a/sdk/transaction/Cargo.toml +++ b/sdk/transaction/Cargo.toml @@ -13,7 +13,7 @@ edition = { workspace = true } serde = { workspace = true, optional = true } serde_derive = { workspace = true, optional = true } solana-bincode = { workspace = true, optional = true } -solana-feature-set = { workspace = true } +solana-feature-set = { workspace = true, optional = true } solana-frozen-abi = { workspace = true, optional = true } solana-frozen-abi-macro = { workspace = true, optional = true } solana-hash = { workspace = true } @@ -54,7 +54,7 @@ frozen-abi = [ "dep:solana-frozen-abi-macro", "dep:solana-logger" ] -precompiles = ["dep:solana-precompiles"] +precompiles = ["dep:solana-feature-set", "dep:solana-precompiles"] serde = [ "dep:serde", "dep:serde_derive", From 318683268981ef8f9c362d42ca485d701d24c81c Mon Sep 17 00:00:00 2001 From: kevinheavey Date: Tue, 26 Nov 2024 12:43:11 +0400 Subject: [PATCH 12/24] inline some consts --- Cargo.lock | 1 + programs/sbf/Cargo.lock | 2 -- sdk/transaction/Cargo.toml | 7 ++++--- sdk/transaction/src/lib.rs | 17 +++++++++++++++-- sdk/transaction/src/versioned/mod.rs | 5 ++--- svm/examples/Cargo.lock | 2 -- 6 files changed, 22 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d8a0ad4b277f0c..a824a79f65adc6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9292,6 +9292,7 @@ dependencies = [ "solana-signer", "solana-transaction", "solana-transaction-error", + "static_assertions", ] [[package]] diff --git a/programs/sbf/Cargo.lock b/programs/sbf/Cargo.lock index 8b8c759e11bfe8..12bee26fc3fad1 100644 --- a/programs/sbf/Cargo.lock +++ b/programs/sbf/Cargo.lock @@ -7780,8 +7780,6 @@ dependencies = [ "solana-feature-set", "solana-hash", "solana-instruction", - "solana-nonce", - "solana-packet", "solana-precompiles", "solana-program", "solana-pubkey", diff --git a/sdk/transaction/Cargo.toml b/sdk/transaction/Cargo.toml index cbae136cfe57ec..36b45fa78e12dd 100644 --- a/sdk/transaction/Cargo.toml +++ b/sdk/transaction/Cargo.toml @@ -19,8 +19,6 @@ solana-frozen-abi-macro = { workspace = true, optional = true } solana-hash = { workspace = true } solana-instruction = { workspace = true } solana-logger = { workspace = true, optional = true } -solana-nonce = { workspace = true, optional = true } -solana-packet = { workspace = true } solana-precompiles = { workspace = true, optional = true } solana-program = { workspace = true } solana-pubkey = { workspace = true } @@ -39,15 +37,18 @@ borsh = { workspace = true } solana-hash = { workspace = true } solana-instruction = { workspace = true, features = ["borsh"] } solana-keypair = { workspace = true } +solana-nonce = { workspace = true } +solana-packet = { workspace = true } solana-presigner = { workspace = true } solana-program = { workspace = true, default-features = false } solana-pubkey = { workspace = true, features = ["rand"] } solana-sdk = { path = ".." } solana-sha256-hasher = { workspace = true } solana-transaction = { path = ".", features = ["dev-context-only-utils"] } +static_assertions = { workspace = true } [features] -bincode = ["dep:solana-bincode", "dep:solana-nonce", "serde"] +bincode = ["dep:solana-bincode", "serde"] dev-context-only-utils = ["bincode", "precompiles", "serde", "verify"] frozen-abi = [ "dep:solana-frozen-abi", diff --git a/sdk/transaction/src/lib.rs b/sdk/transaction/src/lib.rs index 728e093332d6c9..97f16745a4eeb6 100644 --- a/sdk/transaction/src/lib.rs +++ b/sdk/transaction/src/lib.rs @@ -120,7 +120,6 @@ use { #[cfg(feature = "bincode")] use { solana_bincode::limited_deserialize, - solana_nonce::NONCED_TX_MARKER_IX_INDEX, solana_program::{system_instruction::SystemInstruction, system_program}, }; use { @@ -147,6 +146,20 @@ pub enum TransactionVerificationMode { FullVerification, } +// inlined to avoid solana-nonce dep +#[cfg(test)] +static_assertions::const_assert_eq!( + NONCED_TX_MARKER_IX_INDEX, + solana_nonce::NONCED_TX_MARKER_IX_INDEX +); +#[cfg(feature = "bincode")] +const NONCED_TX_MARKER_IX_INDEX: u8 = 0; +// inlined to avoid solana-packet dep +#[cfg(test)] +static_assertions::const_assert_eq!(PACKET_DATA_SIZE, solana_packet::PACKET_DATA_SIZE); +#[cfg(feature = "bincode")] +const PACKET_DATA_SIZE: usize = 1280 - 40 - 8; + /// An atomically-committed sequence of instructions. /// /// While [`Instruction`]s are the basic unit of computation in Solana, @@ -1121,7 +1134,7 @@ pub fn uses_durable_nonce(tx: &Transaction) -> Option<&CompiledInstruction> { ) // Is a nonce advance instruction && matches!( - limited_deserialize(&instruction.data, solana_packet::PACKET_DATA_SIZE as u64), + limited_deserialize(&instruction.data, PACKET_DATA_SIZE as u64), Ok(SystemInstruction::AdvanceNonceAccount) ) }) diff --git a/sdk/transaction/src/versioned/mod.rs b/sdk/transaction/src/versioned/mod.rs index 71dacd213b2ff5..ce19d45ec36ce1 100644 --- a/sdk/transaction/src/versioned/mod.rs +++ b/sdk/transaction/src/versioned/mod.rs @@ -16,7 +16,6 @@ use { #[cfg(feature = "bincode")] use { solana_bincode::limited_deserialize, - solana_nonce::NONCED_TX_MARKER_IX_INDEX, solana_program::{system_instruction::SystemInstruction, system_program}, }; @@ -212,7 +211,7 @@ impl VersionedTransaction { let message = &self.message; message .instructions() - .get(NONCED_TX_MARKER_IX_INDEX as usize) + .get(crate::NONCED_TX_MARKER_IX_INDEX as usize) .filter(|instruction| { // Is system program matches!( @@ -221,7 +220,7 @@ impl VersionedTransaction { ) // Is a nonce advance instruction && matches!( - limited_deserialize(&instruction.data, solana_packet::PACKET_DATA_SIZE as u64,), + limited_deserialize(&instruction.data, crate::PACKET_DATA_SIZE as u64,), Ok(SystemInstruction::AdvanceNonceAccount) ) }) diff --git a/svm/examples/Cargo.lock b/svm/examples/Cargo.lock index 212b58601eeeb0..ab50a966f4f95e 100644 --- a/svm/examples/Cargo.lock +++ b/svm/examples/Cargo.lock @@ -7125,8 +7125,6 @@ dependencies = [ "solana-feature-set", "solana-hash", "solana-instruction", - "solana-nonce", - "solana-packet", "solana-precompiles", "solana-program", "solana-pubkey", From 37058f0ad9931e798707ff3a3ac54263043298e0 Mon Sep 17 00:00:00 2001 From: kevinheavey Date: Tue, 26 Nov 2024 12:51:27 +0400 Subject: [PATCH 13/24] fix wasm support --- Cargo.lock | 1 + programs/sbf/Cargo.lock | 3 +++ sdk/transaction/Cargo.toml | 11 ++++++++--- sdk/transaction/src/lib.rs | 2 +- sdk/transaction/src/wasm.rs | 18 +++++++++++------- svm/examples/Cargo.lock | 3 +++ 6 files changed, 27 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a824a79f65adc6..a44d4f4c645df7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9293,6 +9293,7 @@ dependencies = [ "solana-transaction", "solana-transaction-error", "static_assertions", + "wasm-bindgen", ] [[package]] diff --git a/programs/sbf/Cargo.lock b/programs/sbf/Cargo.lock index 12bee26fc3fad1..99c02b7926d71a 100644 --- a/programs/sbf/Cargo.lock +++ b/programs/sbf/Cargo.lock @@ -7774,12 +7774,14 @@ dependencies = [ name = "solana-transaction" version = "2.2.0" dependencies = [ + "bincode", "serde", "serde_derive", "solana-bincode", "solana-feature-set", "solana-hash", "solana-instruction", + "solana-keypair", "solana-precompiles", "solana-program", "solana-pubkey", @@ -7790,6 +7792,7 @@ dependencies = [ "solana-signature", "solana-signer", "solana-transaction-error", + "wasm-bindgen", ] [[package]] diff --git a/sdk/transaction/Cargo.toml b/sdk/transaction/Cargo.toml index 36b45fa78e12dd..1a013ad1ede569 100644 --- a/sdk/transaction/Cargo.toml +++ b/sdk/transaction/Cargo.toml @@ -10,6 +10,7 @@ license = { workspace = true } edition = { workspace = true } [dependencies] +bincode = { workspace = true, optional = true } serde = { workspace = true, optional = true } serde_derive = { workspace = true, optional = true } solana-bincode = { workspace = true, optional = true } @@ -30,6 +31,10 @@ solana-signature = { workspace = true } solana-signer = { workspace = true } solana-transaction-error = { workspace = true } +[target.'cfg(target_arch = "wasm32")'.dependencies] +solana-keypair = { workspace = true } +wasm-bindgen = { workspace = true } + [dev-dependencies] anyhow = { workspace = true } bincode = { workspace = true } @@ -48,19 +53,19 @@ solana-transaction = { path = ".", features = ["dev-context-only-utils"] } static_assertions = { workspace = true } [features] -bincode = ["dep:solana-bincode", "serde"] +bincode = ["dep:bincode", "dep:solana-bincode", "serde"] dev-context-only-utils = ["bincode", "precompiles", "serde", "verify"] frozen-abi = [ "dep:solana-frozen-abi", "dep:solana-frozen-abi-macro", - "dep:solana-logger" + "dep:solana-logger", ] precompiles = ["dep:solana-feature-set", "dep:solana-precompiles"] serde = [ "dep:serde", "dep:serde_derive", "dep:solana-short-vec", - "solana-signature/serde" + "solana-signature/serde", ] verify = ["solana-signature/verify"] diff --git a/sdk/transaction/src/lib.rs b/sdk/transaction/src/lib.rs index 97f16745a4eeb6..71f6437a4f2ab0 100644 --- a/sdk/transaction/src/lib.rs +++ b/sdk/transaction/src/lib.rs @@ -111,7 +111,7 @@ //! ``` #[cfg(target_arch = "wasm32")] -use crate::wasm_bindgen; +use wasm_bindgen::prelude::wasm_bindgen; #[cfg(feature = "serde")] use { serde_derive::{Deserialize, Serialize}, diff --git a/sdk/transaction/src/wasm.rs b/sdk/transaction/src/wasm.rs index 208a76bfa2d415..c48723b1c7ded1 100644 --- a/sdk/transaction/src/wasm.rs +++ b/sdk/transaction/src/wasm.rs @@ -2,11 +2,11 @@ #![cfg(target_arch = "wasm32")] #![allow(non_snake_case)] use { - crate::{hash::Hash, message::Message, signer::keypair::Keypair, transaction::Transaction}, - solana_program::{ - pubkey::Pubkey, - wasm::{display_to_jsvalue, instructions::Instructions}, - }, + crate::Transaction, + solana_hash::Hash, + solana_keypair::Keypair, + solana_program::{message::Message, wasm::instructions::Instructions}, + solana_pubkey::Pubkey, wasm_bindgen::prelude::*, }; @@ -30,10 +30,12 @@ impl Transaction { self.message_data().into() } + #[cfg(feature = "verify")] /// Verify the transaction #[wasm_bindgen(js_name = verify)] pub fn js_verify(&self) -> Result<(), JsValue> { - self.verify().map_err(display_to_jsvalue) + self.verify() + .map_err(|x| std::string::ToString::to_string(&x).into()) } pub fn partialSign(&mut self, keypair: &Keypair, recent_blockhash: &Hash) { @@ -44,11 +46,13 @@ impl Transaction { self.is_signed() } + #[cfg(feature = "bincode")] pub fn toBytes(&self) -> Box<[u8]> { bincode::serialize(self).unwrap().into() } + #[cfg(feature = "bincode")] pub fn fromBytes(bytes: &[u8]) -> Result { - bincode::deserialize(bytes).map_err(display_to_jsvalue) + bincode::deserialize(bytes).map_err(|x| std::string::ToString::to_string(&x).into()) } } diff --git a/svm/examples/Cargo.lock b/svm/examples/Cargo.lock index ab50a966f4f95e..b1b426c735b1c0 100644 --- a/svm/examples/Cargo.lock +++ b/svm/examples/Cargo.lock @@ -7119,12 +7119,14 @@ dependencies = [ name = "solana-transaction" version = "2.2.0" dependencies = [ + "bincode", "serde", "serde_derive", "solana-bincode", "solana-feature-set", "solana-hash", "solana-instruction", + "solana-keypair", "solana-precompiles", "solana-program", "solana-pubkey", @@ -7135,6 +7137,7 @@ dependencies = [ "solana-signature", "solana-signer", "solana-transaction-error", + "wasm-bindgen", ] [[package]] From 6c2937938d41631dbfaae714b05f7508fbe3adf7 Mon Sep 17 00:00:00 2001 From: kevinheavey Date: Thu, 28 Nov 2024 01:45:42 +0400 Subject: [PATCH 14/24] update expected error --- rpc/src/rpc.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rpc/src/rpc.rs b/rpc/src/rpc.rs index b479536de0eaf5..f25779e0650fab 100644 --- a/rpc/src/rpc.rs +++ b/rpc/src/rpc.rs @@ -8532,7 +8532,7 @@ pub mod tests { decode_and_deserialize::(tx58, TransactionBinaryEncoding::Base58) .unwrap_err(), Error::invalid_params(format!( - "base58 encoded solana_sdk::transaction::Transaction too large: {tx58_len} bytes (max: encoded/raw {MAX_BASE58_SIZE}/{PACKET_DATA_SIZE})", + "base58 encoded solana_transaction::Transaction too large: {tx58_len} bytes (max: encoded/raw {MAX_BASE58_SIZE}/{PACKET_DATA_SIZE})", ) )); @@ -8542,7 +8542,7 @@ pub mod tests { decode_and_deserialize::(tx64, TransactionBinaryEncoding::Base64) .unwrap_err(), Error::invalid_params(format!( - "base64 encoded solana_sdk::transaction::Transaction too large: {tx64_len} bytes (max: encoded/raw {MAX_BASE64_SIZE}/{PACKET_DATA_SIZE})", + "base64 encoded solana_transaction::Transaction too large: {tx64_len} bytes (max: encoded/raw {MAX_BASE64_SIZE}/{PACKET_DATA_SIZE})", ) )); From 20b61ec768f4f57f0ccf702ef3110dd914c48905 Mon Sep 17 00:00:00 2001 From: kevinheavey Date: Thu, 28 Nov 2024 01:46:32 +0400 Subject: [PATCH 15/24] update expected error --- rpc/src/rpc.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rpc/src/rpc.rs b/rpc/src/rpc.rs index f25779e0650fab..1d433df29f3850 100644 --- a/rpc/src/rpc.rs +++ b/rpc/src/rpc.rs @@ -8553,7 +8553,7 @@ pub mod tests { decode_and_deserialize::(tx58, TransactionBinaryEncoding::Base58) .unwrap_err(), Error::invalid_params(format!( - "decoded solana_sdk::transaction::Transaction too large: {too_big} bytes (max: {PACKET_DATA_SIZE} bytes)" + "decoded solana_transaction::Transaction too large: {too_big} bytes (max: {PACKET_DATA_SIZE} bytes)" )) ); @@ -8562,7 +8562,7 @@ pub mod tests { decode_and_deserialize::(tx64, TransactionBinaryEncoding::Base64) .unwrap_err(), Error::invalid_params(format!( - "decoded solana_sdk::transaction::Transaction too large: {too_big} bytes (max: {PACKET_DATA_SIZE} bytes)" + "decoded solana_transaction::Transaction too large: {too_big} bytes (max: {PACKET_DATA_SIZE} bytes)" )) ); @@ -8572,7 +8572,7 @@ pub mod tests { decode_and_deserialize::(tx64.clone(), TransactionBinaryEncoding::Base64) .unwrap_err(), Error::invalid_params( - "failed to deserialize solana_sdk::transaction::Transaction: invalid value: \ + "failed to deserialize solana_transaction::Transaction: invalid value: \ continue signal on byte-three, expected a terminal signal on or before byte-three" .to_string() ) @@ -8590,7 +8590,7 @@ pub mod tests { decode_and_deserialize::(tx58.clone(), TransactionBinaryEncoding::Base58) .unwrap_err(), Error::invalid_params( - "failed to deserialize solana_sdk::transaction::Transaction: invalid value: \ + "failed to deserialize solana_transaction::Transaction: invalid value: \ continue signal on byte-three, expected a terminal signal on or before byte-three" .to_string() ) From 1a36b041ff58ca91828087f62d3361a65b5e4b2e Mon Sep 17 00:00:00 2001 From: kevinheavey Date: Thu, 28 Nov 2024 02:43:34 +0400 Subject: [PATCH 16/24] missing #![cfg(feature = "full")] --- sdk/src/transaction.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/sdk/src/transaction.rs b/sdk/src/transaction.rs index ed4cf7bd83ccdf..7e4864a3d3f748 100644 --- a/sdk/src/transaction.rs +++ b/sdk/src/transaction.rs @@ -1,3 +1,4 @@ +#![cfg(feature = "full")] #[deprecated(since = "2.2.0", note = "Use solana_transaction_error crate instead")] pub use solana_transaction_error::{ AddressLoaderError, SanitizeMessageError, TransactionError, TransactionResult as Result, From 97f389f9c4e1a01a0bc4eba9ea5ee57c69a82309 Mon Sep 17 00:00:00 2001 From: kevinheavey Date: Tue, 3 Dec 2024 02:26:29 +0400 Subject: [PATCH 17/24] update digest --- gossip/src/protocol.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gossip/src/protocol.rs b/gossip/src/protocol.rs index 5467e758e4f15b..d897f6d73b6209 100644 --- a/gossip/src/protocol.rs +++ b/gossip/src/protocol.rs @@ -46,7 +46,7 @@ pub(crate) const PULL_RESPONSE_MIN_SERIALIZED_SIZE: usize = 161; #[cfg_attr( feature = "frozen-abi", derive(AbiExample, AbiEnumVisitor), - frozen_abi(digest = "ESDND6D3FcRyA6UTUpDVDcS4AkESc5E6UtZWSbT7G8e8") + frozen_abi(digest = "CBR9G92mpd1WSXEmiH6dAKHziLjJky9aYWPw6S5WmJkG") )] #[derive(Serialize, Deserialize, Debug)] #[allow(clippy::large_enum_variant)] From e22445e1caaff399e096b857f42302c00ceca2a0 Mon Sep 17 00:00:00 2001 From: kevinheavey Date: Tue, 3 Dec 2024 02:33:37 +0400 Subject: [PATCH 18/24] update digest --- sdk/transaction/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/transaction/src/lib.rs b/sdk/transaction/src/lib.rs index 71f6437a4f2ab0..ad9812330fd1c3 100644 --- a/sdk/transaction/src/lib.rs +++ b/sdk/transaction/src/lib.rs @@ -184,7 +184,7 @@ const PACKET_DATA_SIZE: usize = 1280 - 40 - 8; #[cfg_attr( feature = "frozen-abi", derive(solana_frozen_abi_macro::AbiExample), - solana_frozen_abi_macro::frozen_abi(digest = "GESn6AYYNhpNfzJXdQ6kGjqz4VjpMw3ye9rghqaEqks7") + solana_frozen_abi_macro::frozen_abi(digest = "76BDTr3Xm3VP7h4eSiw6pZHKc5yYewDufyia3Yedh6GG") )] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] #[derive(Debug, PartialEq, Default, Eq, Clone)] From 8b0db58e45153435fd0b8e16ac9e2c82a429fec5 Mon Sep 17 00:00:00 2001 From: kevinheavey Date: Tue, 3 Dec 2024 18:07:57 +0400 Subject: [PATCH 19/24] remove solana-program (except for dev deps) --- Cargo.lock | 2 + programs/sbf/Cargo.lock | 3 +- sdk/Cargo.toml | 2 +- sdk/transaction/Cargo.toml | 17 +++++++-- sdk/transaction/src/lib.rs | 38 ++++++++++++------- sdk/transaction/src/sanitized.rs | 32 +++++++++------- .../src/simple_vote_transaction_checker.rs | 4 +- sdk/transaction/src/versioned/mod.rs | 23 +++++------ sdk/transaction/src/versioned/sanitized.rs | 10 ++--- sdk/transaction/src/wasm.rs | 7 +--- svm/examples/Cargo.lock | 3 +- 11 files changed, 81 insertions(+), 60 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a44d4f4c645df7..8427b071807e22 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9276,6 +9276,7 @@ dependencies = [ "solana-instruction", "solana-keypair", "solana-logger", + "solana-message", "solana-nonce", "solana-packet", "solana-precompiles", @@ -9290,6 +9291,7 @@ dependencies = [ "solana-short-vec", "solana-signature", "solana-signer", + "solana-system-interface", "solana-transaction", "solana-transaction-error", "static_assertions", diff --git a/programs/sbf/Cargo.lock b/programs/sbf/Cargo.lock index 99c02b7926d71a..e87db20ac825fb 100644 --- a/programs/sbf/Cargo.lock +++ b/programs/sbf/Cargo.lock @@ -7782,8 +7782,8 @@ dependencies = [ "solana-hash", "solana-instruction", "solana-keypair", + "solana-message", "solana-precompiles", - "solana-program", "solana-pubkey", "solana-reserved-account-keys", "solana-sanitize", @@ -7791,6 +7791,7 @@ dependencies = [ "solana-short-vec", "solana-signature", "solana-signer", + "solana-system-interface", "solana-transaction-error", "wasm-bindgen", ] diff --git a/sdk/Cargo.toml b/sdk/Cargo.toml index a7f2a3da3c8ef6..d645e470a37825 100644 --- a/sdk/Cargo.toml +++ b/sdk/Cargo.toml @@ -177,7 +177,7 @@ solana-signature = { workspace = true, features = [ solana-signer = { workspace = true, optional = true } solana-time-utils = { workspace = true } solana-transaction = { workspace = true, features = [ - "bincode", + "blake3", "precompiles", "serde", "verify" diff --git a/sdk/transaction/Cargo.toml b/sdk/transaction/Cargo.toml index 1a013ad1ede569..bfa31b15454f80 100644 --- a/sdk/transaction/Cargo.toml +++ b/sdk/transaction/Cargo.toml @@ -20,8 +20,8 @@ solana-frozen-abi-macro = { workspace = true, optional = true } solana-hash = { workspace = true } solana-instruction = { workspace = true } solana-logger = { workspace = true, optional = true } +solana-message = { workspace = true } solana-precompiles = { workspace = true, optional = true } -solana-program = { workspace = true } solana-pubkey = { workspace = true } solana-reserved-account-keys = { workspace = true } solana-sanitize = { workspace = true } @@ -29,6 +29,7 @@ solana-sdk-ids = { workspace = true } solana-short-vec = { workspace = true, optional = true } solana-signature = { workspace = true } solana-signer = { workspace = true } +solana-system-interface = { workspace = true, optional = true, features = ["bincode"] } solana-transaction-error = { workspace = true } [target.'cfg(target_arch = "wasm32")'.dependencies] @@ -53,8 +54,15 @@ solana-transaction = { path = ".", features = ["dev-context-only-utils"] } static_assertions = { workspace = true } [features] -bincode = ["dep:bincode", "dep:solana-bincode", "serde"] -dev-context-only-utils = ["bincode", "precompiles", "serde", "verify"] +bincode = [ + "dep:bincode", + "dep:solana-bincode", + "dep:solana-system-interface", + "serde", + "solana-message/bincode", +] +blake3 = ["bincode", "solana-message/blake3"] +dev-context-only-utils = ["blake3", "precompiles", "serde", "verify"] frozen-abi = [ "dep:solana-frozen-abi", "dep:solana-frozen-abi-macro", @@ -65,9 +73,10 @@ serde = [ "dep:serde", "dep:serde_derive", "dep:solana-short-vec", + "solana-message/serde", "solana-signature/serde", ] -verify = ["solana-signature/verify"] +verify = ["blake3", "solana-signature/verify"] [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] diff --git a/sdk/transaction/src/lib.rs b/sdk/transaction/src/lib.rs index ad9812330fd1c3..de4b9be21904b3 100644 --- a/sdk/transaction/src/lib.rs +++ b/sdk/transaction/src/lib.rs @@ -60,7 +60,7 @@ //! use borsh::{BorshSerialize, BorshDeserialize}; //! use solana_instruction::Instruction; //! use solana_keypair::Keypair; -//! use solana_program::message::Message; +//! use solana_message::Message; //! use solana_pubkey::Pubkey; //! use solana_rpc_client::rpc_client::RpcClient; //! use solana_signer::Signer; @@ -120,16 +120,18 @@ use { #[cfg(feature = "bincode")] use { solana_bincode::limited_deserialize, - solana_program::{system_instruction::SystemInstruction, system_program}, + solana_hash::Hash, + solana_message::compiled_instruction::CompiledInstruction, + solana_sdk_ids::system_program, + solana_signer::{signers::Signers, SignerError}, + solana_system_interface::instruction::SystemInstruction, }; use { - solana_hash::Hash, solana_instruction::Instruction, - solana_program::{instruction::CompiledInstruction, message::Message}, + solana_message::Message, solana_pubkey::Pubkey, solana_sanitize::{Sanitize, SanitizeError}, solana_signature::Signature, - solana_signer::{signers::Signers, SignerError}, solana_transaction_error::{TransactionError, TransactionResult as Result}, std::result, }; @@ -227,7 +229,7 @@ pub struct Transaction { } impl Sanitize for Transaction { - fn sanitize(&self) -> std::result::Result<(), SanitizeError> { + fn sanitize(&self) -> result::Result<(), SanitizeError> { if self.message.header.num_required_signatures as usize > self.signatures.len() { return Err(SanitizeError::IndexOutOfBounds); } @@ -254,7 +256,7 @@ impl Transaction { /// use borsh::{BorshSerialize, BorshDeserialize}; /// use solana_instruction::Instruction; /// use solana_keypair::Keypair; - /// use solana_program::message::Message; + /// use solana_message::Message; /// use solana_pubkey::Pubkey; /// use solana_rpc_client::rpc_client::RpcClient; /// use solana_signer::Signer; @@ -332,7 +334,7 @@ impl Transaction { /// use borsh::{BorshSerialize, BorshDeserialize}; /// use solana_instruction::Instruction; /// use solana_keypair::Keypair; - /// use solana_program::message::Message; + /// use solana_message::Message; /// use solana_pubkey::Pubkey; /// use solana_rpc_client::rpc_client::RpcClient; /// use solana_signer::Signer; @@ -381,6 +383,7 @@ impl Transaction { /// # /// # Ok::<(), anyhow::Error>(()) /// ``` + #[cfg(feature = "bincode")] pub fn new( from_keypairs: &T, message: Message, @@ -410,7 +413,7 @@ impl Transaction { /// use borsh::{BorshSerialize, BorshDeserialize}; /// use solana_instruction::Instruction; /// use solana_keypair::Keypair; - /// use solana_program::message::Message; + /// use solana_message::Message; /// use solana_pubkey::Pubkey; /// use solana_rpc_client::rpc_client::RpcClient; /// use solana_signer::Signer; @@ -485,7 +488,7 @@ impl Transaction { /// use borsh::{BorshSerialize, BorshDeserialize}; /// use solana_instruction::Instruction; /// use solana_keypair::Keypair; - /// use solana_program::message::Message; + /// use solana_message::Message; /// use solana_pubkey::Pubkey; /// use solana_rpc_client::rpc_client::RpcClient; /// use solana_signer::Signer; @@ -534,6 +537,7 @@ impl Transaction { /// # /// # Ok::<(), anyhow::Error>(()) /// ``` + #[cfg(feature = "bincode")] pub fn new_signed_with_payer( instructions: &[Instruction], payer: Option<&Pubkey>, @@ -559,6 +563,7 @@ impl Transaction { /// /// Panics when signing fails. See [`Transaction::try_sign`] and for a full /// description of failure conditions. + #[cfg(feature = "bincode")] pub fn new_with_compiled_instructions( from_keypairs: &T, keys: &[Pubkey], @@ -656,6 +661,7 @@ impl Transaction { &self.message } + #[cfg(feature = "bincode")] /// Return the serialized message data to sign. pub fn message_data(&self) -> Vec { self.message().serialize() @@ -692,7 +698,7 @@ impl Transaction { /// use borsh::{BorshSerialize, BorshDeserialize}; /// use solana_instruction::Instruction; /// use solana_keypair::Keypair; - /// use solana_program::message::Message; + /// use solana_message::Message; /// use solana_pubkey::Pubkey; /// use solana_rpc_client::rpc_client::RpcClient; /// use solana_signer::Signer; @@ -737,6 +743,7 @@ impl Transaction { /// # /// # Ok::<(), anyhow::Error>(()) /// ``` + #[cfg(feature = "bincode")] pub fn sign(&mut self, keypairs: &T, recent_blockhash: Hash) { if let Err(e) = self.try_sign(keypairs, recent_blockhash) { panic!("Transaction::sign failed with error {e:?}"); @@ -763,6 +770,7 @@ impl Transaction { /// handle the error. See the documentation for /// [`Transaction::try_partial_sign`] for a full description of failure /// conditions. + #[cfg(feature = "bincode")] pub fn partial_sign(&mut self, keypairs: &T, recent_blockhash: Hash) { if let Err(e) = self.try_partial_sign(keypairs, recent_blockhash) { panic!("Transaction::partial_sign failed with error {e:?}"); @@ -782,6 +790,7 @@ impl Transaction { /// /// Panics if signing fails. Use [`Transaction::try_partial_sign_unchecked`] /// to handle the error. + #[cfg(feature = "bincode")] pub fn partial_sign_unchecked( &mut self, keypairs: &T, @@ -829,7 +838,7 @@ impl Transaction { /// use borsh::{BorshSerialize, BorshDeserialize}; /// use solana_instruction::Instruction; /// use solana_keypair::Keypair; - /// use solana_program::message::Message; + /// use solana_message::Message; /// use solana_pubkey::Pubkey; /// use solana_rpc_client::rpc_client::RpcClient; /// use solana_signer::Signer; @@ -874,6 +883,7 @@ impl Transaction { /// # /// # Ok::<(), anyhow::Error>(()) /// ``` + #[cfg(feature = "bincode")] pub fn try_sign( &mut self, keypairs: &T, @@ -937,6 +947,7 @@ impl Transaction { /// [`PresignerError::VerificationFailure`]: https://docs.rs/solana-signer/latest/solana_signer/enum.PresignerError.html#variant.WrongSize /// [`solana-remote-wallet`]: https://docs.rs/solana-remote-wallet/latest/ /// [`RemoteKeypair`]: https://docs.rs/solana-remote-wallet/latest/solana_remote_wallet/remote_keypair/struct.RemoteKeypair.html + #[cfg(feature = "bincode")] pub fn try_partial_sign( &mut self, keypairs: &T, @@ -963,6 +974,7 @@ impl Transaction { /// # Errors /// /// Returns an error if signing fails. + #[cfg(feature = "bincode")] pub fn try_partial_sign_unchecked( &mut self, keypairs: &T, @@ -1150,9 +1162,9 @@ mod tests { solana_instruction::AccountMeta, solana_keypair::Keypair, solana_presigner::Presigner, - solana_program::system_instruction, solana_sha256_hasher::hash, solana_signer::Signer, + solana_system_interface::instruction as system_instruction, std::mem::size_of, }; diff --git a/sdk/transaction/src/sanitized.rs b/sdk/transaction/src/sanitized.rs index d60c3e4659524c..2d0f3639c2c222 100644 --- a/sdk/transaction/src/sanitized.rs +++ b/sdk/transaction/src/sanitized.rs @@ -1,23 +1,22 @@ use { - crate::{ - simple_vote_transaction_checker::is_simple_vote_transaction, - versioned::{sanitized::SanitizedVersionedTransaction, VersionedTransaction}, - Transaction, - }, + crate::versioned::{sanitized::SanitizedVersionedTransaction, VersionedTransaction}, solana_hash::Hash, - solana_program::message::{ + solana_message::{ legacy, v0::{self, LoadedAddresses}, AddressLoader, LegacyMessage, SanitizedMessage, SanitizedVersionedMessage, VersionedMessage, }, solana_pubkey::Pubkey, - solana_reserved_account_keys::ReservedAccountKeys, - solana_sanitize::Sanitize, solana_signature::Signature, solana_transaction_error::{TransactionError, TransactionResult as Result}, std::collections::HashSet, }; +#[cfg(feature = "blake3")] +use { + crate::Transaction, solana_reserved_account_keys::ReservedAccountKeys, + solana_sanitize::Sanitize, +}; /// Maximum number of accounts that a transaction may lock. /// 128 was chosen because it is the minimum number of accounts @@ -91,6 +90,7 @@ impl SanitizedTransaction { }) } + #[cfg(feature = "blake3")] /// Create a sanitized transaction from an un-sanitized versioned /// transaction. If the input transaction uses address tables, attempt to /// lookup the address for each table index. @@ -102,8 +102,11 @@ impl SanitizedTransaction { reserved_account_keys: &HashSet, ) -> Result { let sanitized_versioned_tx = SanitizedVersionedTransaction::try_from(tx)?; - let is_simple_vote_tx = is_simple_vote_tx - .unwrap_or_else(|| is_simple_vote_transaction(&sanitized_versioned_tx)); + let is_simple_vote_tx = is_simple_vote_tx.unwrap_or_else(|| { + crate::simple_vote_transaction_checker::is_simple_vote_transaction( + &sanitized_versioned_tx, + ) + }); let message_hash = match message_hash.into() { MessageHash::Compute => sanitized_versioned_tx.message.message.hash(), MessageHash::Precomputed(hash) => hash, @@ -118,6 +121,7 @@ impl SanitizedTransaction { } /// Create a sanitized transaction from a legacy transaction + #[cfg(feature = "blake3")] pub fn try_from_legacy_transaction( tx: Transaction, reserved_account_keys: &HashSet, @@ -136,6 +140,7 @@ impl SanitizedTransaction { } /// Create a sanitized transaction from a legacy transaction. Used for tests only. + #[cfg(feature = "blake3")] pub fn from_transaction_for_tests(tx: Transaction) -> Self { Self::try_from_legacy_transaction(tx, &ReservedAccountKeys::empty_key_set()).unwrap() } @@ -250,6 +255,7 @@ impl SanitizedTransaction { } /// If the transaction uses a durable nonce, return the pubkey of the nonce account + #[cfg(feature = "bincode")] pub fn get_durable_nonce(&self) -> Option<&Pubkey> { self.message.get_durable_nonce() } @@ -337,10 +343,8 @@ mod tests { use { super::*, solana_keypair::Keypair, - solana_program::{ - message::{MessageHeader, SimpleAddressLoader}, - vote::{self, state::Vote}, - }, + solana_message::{MessageHeader, SimpleAddressLoader}, + solana_program::vote::{self, state::Vote}, solana_reserved_account_keys::ReservedAccountKeys, solana_signer::Signer, }; diff --git a/sdk/transaction/src/simple_vote_transaction_checker.rs b/sdk/transaction/src/simple_vote_transaction_checker.rs index 7029911552f9ce..bece183670d274 100644 --- a/sdk/transaction/src/simple_vote_transaction_checker.rs +++ b/sdk/transaction/src/simple_vote_transaction_checker.rs @@ -1,6 +1,6 @@ use { - crate::versioned::sanitized::SanitizedVersionedTransaction, - solana_program::message::VersionedMessage, solana_pubkey::Pubkey, solana_signature::Signature, + crate::versioned::sanitized::SanitizedVersionedTransaction, solana_message::VersionedMessage, + solana_pubkey::Pubkey, solana_signature::Signature, }; /// Simple vote transaction meets these conditions: diff --git a/sdk/transaction/src/versioned/mod.rs b/sdk/transaction/src/versioned/mod.rs index ce19d45ec36ce1..21f8be087b3608 100644 --- a/sdk/transaction/src/versioned/mod.rs +++ b/sdk/transaction/src/versioned/mod.rs @@ -1,12 +1,8 @@ //! Defines a transaction which supports multiple versions of messages. use { - crate::Transaction, - solana_program::message::VersionedMessage, - solana_sanitize::SanitizeError, - solana_signature::Signature, - solana_signer::{signers::Signers, SignerError}, - std::cmp::Ordering, + crate::Transaction, solana_message::VersionedMessage, solana_sanitize::SanitizeError, + solana_signature::Signature, std::cmp::Ordering, }; #[cfg(feature = "serde")] use { @@ -16,7 +12,9 @@ use { #[cfg(feature = "bincode")] use { solana_bincode::limited_deserialize, - solana_program::{system_instruction::SystemInstruction, system_program}, + solana_sdk_ids::system_program, + solana_signer::{signers::Signers, SignerError}, + solana_system_interface::instruction::SystemInstruction, }; pub mod sanitized; @@ -72,6 +70,7 @@ impl From for VersionedTransaction { impl VersionedTransaction { /// Signs a versioned message and if successful, returns a signed /// transaction. + #[cfg(feature = "bincode")] pub fn try_new( message: VersionedMessage, keypairs: &T, @@ -233,14 +232,12 @@ mod tests { use { super::*, solana_hash::Hash, + solana_instruction::{AccountMeta, Instruction}, solana_keypair::Keypair, - solana_program::{ - instruction::{AccountMeta, Instruction}, - message::Message as LegacyMessage, - pubkey::Pubkey, - system_instruction, - }, + solana_message::Message as LegacyMessage, + solana_pubkey::Pubkey, solana_signer::Signer, + solana_system_interface::instruction as system_instruction, }; #[test] diff --git a/sdk/transaction/src/versioned/sanitized.rs b/sdk/transaction/src/versioned/sanitized.rs index 880f93bdca7cb5..aec6033c377ffa 100644 --- a/sdk/transaction/src/versioned/sanitized.rs +++ b/sdk/transaction/src/versioned/sanitized.rs @@ -1,5 +1,5 @@ use { - crate::versioned::VersionedTransaction, solana_program::message::SanitizedVersionedMessage, + crate::versioned::VersionedTransaction, solana_message::SanitizedVersionedMessage, solana_sanitize::SanitizeError, solana_signature::Signature, }; @@ -42,11 +42,9 @@ impl SanitizedVersionedTransaction { mod tests { use { super::*, - solana_program::{ - hash::Hash, - message::{v0, VersionedMessage}, - pubkey::Pubkey, - }, + solana_hash::Hash, + solana_message::{v0, VersionedMessage}, + solana_pubkey::Pubkey, }; #[test] diff --git a/sdk/transaction/src/wasm.rs b/sdk/transaction/src/wasm.rs index c48723b1c7ded1..cdfc5792b3e569 100644 --- a/sdk/transaction/src/wasm.rs +++ b/sdk/transaction/src/wasm.rs @@ -2,11 +2,8 @@ #![cfg(target_arch = "wasm32")] #![allow(non_snake_case)] use { - crate::Transaction, - solana_hash::Hash, - solana_keypair::Keypair, - solana_program::{message::Message, wasm::instructions::Instructions}, - solana_pubkey::Pubkey, + crate::Transaction, solana_hash::Hash, solana_instruction::wasm::Instructions, + solana_keypair::Keypair, solana_message::Message, solana_pubkey::Pubkey, wasm_bindgen::prelude::*, }; diff --git a/svm/examples/Cargo.lock b/svm/examples/Cargo.lock index b1b426c735b1c0..b74749f96a7ea9 100644 --- a/svm/examples/Cargo.lock +++ b/svm/examples/Cargo.lock @@ -7127,8 +7127,8 @@ dependencies = [ "solana-hash", "solana-instruction", "solana-keypair", + "solana-message", "solana-precompiles", - "solana-program", "solana-pubkey", "solana-reserved-account-keys", "solana-sanitize", @@ -7136,6 +7136,7 @@ dependencies = [ "solana-short-vec", "solana-signature", "solana-signer", + "solana-system-interface", "solana-transaction-error", "wasm-bindgen", ] From 11a6137e050a09ac25f7d7ca679ee8b9a7cb4fd8 Mon Sep 17 00:00:00 2001 From: kevinheavey Date: Tue, 3 Dec 2024 18:11:33 +0400 Subject: [PATCH 20/24] add wasm32-unknown-unknown to doc targets --- sdk/transaction/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/transaction/Cargo.toml b/sdk/transaction/Cargo.toml index bfa31b15454f80..a6aead454872b9 100644 --- a/sdk/transaction/Cargo.toml +++ b/sdk/transaction/Cargo.toml @@ -79,6 +79,6 @@ serde = [ verify = ["blake3", "solana-signature/verify"] [package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] +targets = ["x86_64-unknown-linux-gnu", "wasm32-unknown-unknown"] all-features = true rustdoc-args = ["--cfg=docsrs"] From 183dcf37afaa0200768367dc66889901b2badc00 Mon Sep 17 00:00:00 2001 From: kevinheavey Date: Tue, 3 Dec 2024 18:14:37 +0400 Subject: [PATCH 21/24] update docs links --- sdk/transaction/src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sdk/transaction/src/lib.rs b/sdk/transaction/src/lib.rs index de4b9be21904b3..4b883987b804c2 100644 --- a/sdk/transaction/src/lib.rs +++ b/sdk/transaction/src/lib.rs @@ -196,9 +196,9 @@ pub struct Transaction { /// is equal to [`num_required_signatures`] of the `Message`'s /// [`MessageHeader`]. /// - /// [`account_keys`]: https://docs.rs/solana-program/latest/solana_program/message/legacy/struct.Message.html#structfield.account_keys - /// [`MessageHeader`]: https://docs.rs/solana-program/latest/solana_program/message/struct.MessageHeader.html - /// [`num_required_signatures`]: https://docs.rs/solana-program/latest/solana_program/message/struct.MessageHeader.html#structfield.num_required_signatures + /// [`account_keys`]: https://docs.rs/solana-message/latest/solana_message/legacy/struct.Message.html#structfield.account_keys + /// [`MessageHeader`]: https://docs.rs/solana-message/latest/solana_message/struct.MessageHeader.html + /// [`num_required_signatures`]: https://docs.rs/solana-message/latest/solana_message/struct.MessageHeader.html#structfield.num_required_signatures // NOTE: Serialization-related changes must be paired with the direct read at sigverify. #[cfg_attr(feature = "serde", serde(with = "short_vec"))] pub signatures: Vec, @@ -940,7 +940,7 @@ impl Transaction { /// See the documentation for the [`solana-remote-wallet`] crate for details /// on the operation of [`RemoteKeypair`] signers. /// - /// [`num_required_signatures`]: https://docs.rs/solana-program/latest/solana_program/message/struct.MessageHeader.html#structfield.num_required_signatures + /// [`num_required_signatures`]: https://docs.rs/solana-message/latest/solana_message/struct.MessageHeader.html#structfield.num_required_signatures /// [`account_keys`]: Message::account_keys /// [`Presigner`]: https://docs.rs/solana-presigner/latest/solana_presigner/struct.Presigner.html /// [`PresignerError`]: https://docs.rs/solana-signer/latest/solana_signer/enum.PresignerError.html From 3ed136774e70342f316054e3d6fe13fb9663a78a Mon Sep 17 00:00:00 2001 From: kevinheavey Date: Tue, 3 Dec 2024 18:51:23 +0400 Subject: [PATCH 22/24] tighten deps --- sdk/transaction/Cargo.toml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/sdk/transaction/Cargo.toml b/sdk/transaction/Cargo.toml index a6aead454872b9..b36009e92c5266 100644 --- a/sdk/transaction/Cargo.toml +++ b/sdk/transaction/Cargo.toml @@ -23,12 +23,12 @@ solana-logger = { workspace = true, optional = true } solana-message = { workspace = true } solana-precompiles = { workspace = true, optional = true } solana-pubkey = { workspace = true } -solana-reserved-account-keys = { workspace = true } +solana-reserved-account-keys = { workspace = true, optional = true } solana-sanitize = { workspace = true } solana-sdk-ids = { workspace = true } solana-short-vec = { workspace = true, optional = true } solana-signature = { workspace = true } -solana-signer = { workspace = true } +solana-signer = { workspace = true, optional = true } solana-system-interface = { workspace = true, optional = true, features = ["bincode"] } solana-transaction-error = { workspace = true } @@ -57,11 +57,16 @@ static_assertions = { workspace = true } bincode = [ "dep:bincode", "dep:solana-bincode", + "dep:solana-signer", "dep:solana-system-interface", "serde", "solana-message/bincode", ] -blake3 = ["bincode", "solana-message/blake3"] +blake3 = [ + "dep:solana-reserved-account-keys", + "bincode", + "solana-message/blake3", +] dev-context-only-utils = ["blake3", "precompiles", "serde", "verify"] frozen-abi = [ "dep:solana-frozen-abi", From f3faa9df26f7f1ccb5dfbc91e011a398ebcda63e Mon Sep 17 00:00:00 2001 From: kevinheavey Date: Wed, 4 Dec 2024 04:18:43 +0400 Subject: [PATCH 23/24] remove extraneous commit --- sdk/instruction/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/instruction/Cargo.toml b/sdk/instruction/Cargo.toml index 6c21e3959784ea..5826fca227ff20 100644 --- a/sdk/instruction/Cargo.toml +++ b/sdk/instruction/Cargo.toml @@ -48,7 +48,7 @@ serde = [ std = [] [package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu", "wasm32-unknown-unknown"] +targets = ["x86_64-unknown-linux-gnu"] all-features = true rustdoc-args = ["--cfg=docsrs"] From 26901daea8e99c9e28c101ee68567ceb472f71f4 Mon Sep 17 00:00:00 2001 From: kevinheavey Date: Wed, 4 Dec 2024 04:22:40 +0400 Subject: [PATCH 24/24] use explicit link --- sdk/transaction/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/transaction/src/lib.rs b/sdk/transaction/src/lib.rs index 4b883987b804c2..43a913843269d3 100644 --- a/sdk/transaction/src/lib.rs +++ b/sdk/transaction/src/lib.rs @@ -941,7 +941,7 @@ impl Transaction { /// on the operation of [`RemoteKeypair`] signers. /// /// [`num_required_signatures`]: https://docs.rs/solana-message/latest/solana_message/struct.MessageHeader.html#structfield.num_required_signatures - /// [`account_keys`]: Message::account_keys + /// [`account_keys`]: https://docs.rs/solana-message/latest/solana_message/legacy/struct.Message.html#structfield.account_keys /// [`Presigner`]: https://docs.rs/solana-presigner/latest/solana_presigner/struct.Presigner.html /// [`PresignerError`]: https://docs.rs/solana-signer/latest/solana_signer/enum.PresignerError.html /// [`PresignerError::VerificationFailure`]: https://docs.rs/solana-signer/latest/solana_signer/enum.PresignerError.html#variant.WrongSize