Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
388 changes: 284 additions & 104 deletions Cargo.lock

Large diffs are not rendered by default.

9 changes: 5 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -195,11 +195,11 @@ openssl = "0.10.72"
pairing = "0.23.0"
parking_lot = "0.12"
pbkdf2 = { version = "0.11.0", default-features = false }
proc-macro2 = "1.0.93"
proc-macro2 = "1.0.101"
proptest = "1.6"
qstring = "0.7.2"
qualifier_attr = { version = "0.2.2", default-features = false }
quote = "1.0.35"
quote = "1.0.41"
rand = "0.8.5"
rayon = "1.10.0"
regex = "1.11"
Expand Down Expand Up @@ -323,14 +323,15 @@ static_assertions = "1.1.0"
strum = "0.24"
strum_macros = "0.24"
subtle = "2.6.1"
syn = "2.0.87"
syn = "2.0.106"
tempfile = "3.20.0"
test-case = "3.3.1"
thiserror = { version = "2.0.11", default-features = false }
thiserror = { version = "2.0.16", default-features = false }
tiny-bip39 = "2.0.0"
toml = "0.8.23"
uriparse = "0.6.4"
wasm-bindgen = "0.2.100"
wincode = { version = "0.2.1", features = ["derive"], default-features = false }

[profile.release]
split-debuginfo = "unpacked"
Expand Down
6 changes: 4 additions & 2 deletions address/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ rand = ["dep:rand", "atomic", "std"]
sanitize = ["dep:solana-sanitize"]
serde = ["dep:serde", "dep:serde_derive"]
sha2 = ["dep:solana-sha256-hasher", "error"]
std = ["decode", "borsh?/std", "serde?/std", "alloc"]
alloc = []
std = ["decode", "borsh?/std", "serde?/std", "wincode?/std", "alloc"]
alloc = ["wincode?/alloc"]
syscalls = ["dep:solana-define-syscall", "error"]
wincode = ["dep:wincode"]

[dependencies]
arbitrary = { workspace = true, features = ["derive"], optional = true }
Expand All @@ -53,6 +54,7 @@ solana-frozen-abi = { workspace = true, features = ["frozen-abi"], optional = tr
solana-frozen-abi-macro = { workspace = true, features = ["frozen-abi"], optional = true }
solana-program-error = { workspace = true, optional = true }
solana-sanitize = { workspace = true, optional = true }
wincode = { workspace = true, optional = true }

[target.'cfg(any(target_os = "solana", target_arch = "bpf"))'.dependencies]
solana-define-syscall = { workspace = true, optional = true }
Expand Down
3 changes: 3 additions & 0 deletions address/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ use core::{
};
#[cfg(feature = "serde")]
use serde_derive::{Deserialize, Serialize};
#[cfg(feature = "wincode")]
use wincode::{SchemaRead, SchemaWrite};
#[cfg(feature = "borsh")]
use {
alloc::string::ToString,
Expand Down Expand Up @@ -89,6 +91,7 @@ pub const PDA_MARKER: &[u8; 21] = b"ProgramDerivedAddress";
#[cfg_attr(feature = "borsh", derive(BorshSchema))]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
#[cfg_attr(feature = "bytemuck", derive(Pod, Zeroable))]
#[cfg_attr(feature = "wincode", derive(SchemaWrite, SchemaRead))]
#[cfg_attr(feature = "dev-context-only-utils", derive(Arbitrary))]
#[cfg_attr(not(feature = "decode"), derive(Debug))]
#[cfg_attr(feature = "copy", derive(Copy))]
Expand Down
4 changes: 3 additions & 1 deletion hash/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ default = []
frozen-abi = ["dep:solana-frozen-abi", "dep:solana-frozen-abi-macro", "std"]
sanitize = ["dep:solana-sanitize"]
serde = ["dep:serde", "dep:serde_derive"]
std = ["borsh?/std", "serde?/std"]
std = ["borsh?/std", "serde?/std", "wincode?/std"]
wincode = ["dep:wincode"]

[dependencies]
borsh = { workspace = true, optional = true }
Expand All @@ -38,6 +39,7 @@ solana-atomic-u64 = { workspace = true, optional = true }
solana-frozen-abi = { workspace = true, optional = true, features = ["frozen-abi"] }
solana-frozen-abi-macro = { workspace = true, optional = true, features = ["frozen-abi"] }
solana-sanitize = { workspace = true, optional = true }
wincode = { workspace = true, optional = true }

[dev-dependencies]
bs58 = { workspace = true, default-features = false, features = ["alloc"] }
Expand Down
3 changes: 3 additions & 0 deletions hash/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ use solana_sanitize::Sanitize;
extern crate alloc;
#[cfg(feature = "borsh")]
use alloc::string::ToString;
#[cfg(feature = "wincode")]
use wincode::{SchemaRead, SchemaWrite};

/// Size of a hash in bytes.
pub const HASH_BYTES: usize = 32;
Expand All @@ -42,6 +44,7 @@ pub const MAX_BASE58_LEN: usize = 44;
#[cfg_attr(feature = "borsh", derive(BorshSchema))]
#[cfg_attr(feature = "bytemuck", derive(Pod, Zeroable))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize,))]
#[cfg_attr(feature = "wincode", derive(SchemaWrite, SchemaRead))]
#[cfg_attr(feature = "copy", derive(Copy))]
#[cfg_attr(not(feature = "decode"), derive(Debug))]
#[derive(Clone, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
Expand Down
5 changes: 5 additions & 0 deletions message/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ serde = [
"solana-address/serde",
"solana-hash/serde",
]
wincode = ["dep:wincode", "solana-hash/wincode", "solana-address/wincode"]

[dependencies]
bincode = { workspace = true, optional = true }
Expand All @@ -51,6 +52,10 @@ solana-sanitize = { workspace = true }
solana-sdk-ids = { workspace = true }
solana-short-vec = { workspace = true, optional = true }
solana-transaction-error = { workspace = true }
wincode = { workspace = true, optional = true, features = [
"std",
"solana-short-vec",
] }

[dev-dependencies]
anyhow = { workspace = true }
Expand Down
5 changes: 5 additions & 0 deletions message/src/compiled_instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
use serde_derive::{Deserialize, Serialize};
#[cfg(feature = "frozen-abi")]
use solana_frozen_abi_macro::AbiExample;
#[cfg(feature = "wincode")]
use wincode::{containers, len::ShortU16Len, SchemaRead, SchemaWrite};
use {solana_address::Address, solana_sanitize::Sanitize};

/// A compact encoding of an instruction.
Expand All @@ -17,15 +19,18 @@ use {solana_address::Address, solana_sanitize::Sanitize};
derive(Deserialize, Serialize),
serde(rename_all = "camelCase")
)]
#[cfg_attr(feature = "wincode", derive(SchemaWrite, SchemaRead))]
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct CompiledInstruction {
/// Index into the transaction keys array indicating the program account that executes this instruction.
pub program_id_index: u8,
/// Ordered indices into the transaction keys array indicating which accounts to pass to the program.
#[cfg_attr(feature = "serde", serde(with = "solana_short_vec"))]
#[cfg_attr(feature = "wincode", wincode(with = "containers::Vec<_, ShortU16Len>"))]
pub accounts: Vec<u8>,
/// The program input data.
#[cfg_attr(feature = "serde", serde(with = "solana_short_vec"))]
#[cfg_attr(feature = "wincode", wincode(with = "containers::Vec<_, ShortU16Len>"))]
pub data: Vec<u8>,
}

Expand Down
9 changes: 9 additions & 0 deletions message/src/legacy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
use serde_derive::{Deserialize, Serialize};
#[cfg(feature = "frozen-abi")]
use solana_frozen_abi_macro::{frozen_abi, AbiExample};
#[cfg(feature = "wincode")]
use wincode::{containers, len::ShortU16Len, SchemaRead, SchemaWrite};
use {
crate::{
compiled_instruction::CompiledInstruction, compiled_keys::CompiledKeys,
Expand Down Expand Up @@ -74,6 +76,11 @@ fn compile_instructions(ixs: &[Instruction], keys: &[Address]) -> Vec<CompiledIn
derive(Deserialize, Serialize),
serde(rename_all = "camelCase")
)]
#[cfg_attr(
feature = "wincode",
derive(SchemaWrite, SchemaRead),
wincode(struct_extensions)
)]
#[derive(Default, Debug, PartialEq, Eq, Clone)]
pub struct Message {
/// The message header, identifying signed and read-only `account_keys`.
Expand All @@ -82,6 +89,7 @@ pub struct Message {

/// All the account keys used by this transaction.
#[cfg_attr(feature = "serde", serde(with = "solana_short_vec"))]
#[cfg_attr(feature = "wincode", wincode(with = "containers::Vec<_, ShortU16Len>"))]
pub account_keys: Vec<Address>,

/// The id of a recent ledger entry.
Expand All @@ -90,6 +98,7 @@ pub struct Message {
/// Programs that will be executed in sequence and committed in one atomic transaction if all
/// succeed.
#[cfg_attr(feature = "serde", serde(with = "solana_short_vec"))]
#[cfg_attr(feature = "wincode", wincode(with = "containers::Vec<_, ShortU16Len>"))]
pub instructions: Vec<CompiledInstruction>,
}

Expand Down
7 changes: 7 additions & 0 deletions message/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ pub mod legacy;
use serde_derive::{Deserialize, Serialize};
#[cfg(feature = "frozen-abi")]
use solana_frozen_abi_macro::AbiExample;
#[cfg(feature = "wincode")]
use wincode::{SchemaRead, SchemaWrite};

#[cfg(not(target_os = "solana"))]
#[path = ""]
Expand Down Expand Up @@ -112,6 +114,11 @@ pub const MESSAGE_HEADER_LENGTH: usize = 3;
derive(Deserialize, Serialize),
serde(rename_all = "camelCase")
)]
#[cfg_attr(
feature = "wincode",
derive(SchemaWrite, SchemaRead),
wincode(struct_extensions)
)]
#[derive(Default, Debug, PartialEq, Eq, Clone, Copy)]
pub struct MessageHeader {
/// The number of signatures required for this message to be considered
Expand Down
80 changes: 80 additions & 0 deletions message/src/versions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ use {
solana_sanitize::{Sanitize, SanitizeError},
std::collections::HashSet,
};
#[cfg(feature = "wincode")]
use {
core::mem::MaybeUninit,
wincode::{
io::{Reader, Writer},
ReadResult, SchemaRead, SchemaWrite, WriteResult,
},
};
#[cfg(feature = "serde")]
use {
serde::{
Expand Down Expand Up @@ -326,6 +334,78 @@ impl<'de> serde::Deserialize<'de> for VersionedMessage {
}
}

#[cfg(feature = "wincode")]
impl SchemaWrite for VersionedMessage {
type Src = Self;

#[inline(always)]
fn size_of(src: &Self::Src) -> WriteResult<usize> {
match src {
VersionedMessage::Legacy(message) => LegacyMessage::size_of(message),
// +1 for message version prefix
VersionedMessage::V0(message) => Ok(1 + v0::Message::size_of(message)?),
}
}

#[inline(always)]
fn write(writer: &mut impl Writer, src: &Self::Src) -> WriteResult<()> {
match src {
VersionedMessage::Legacy(message) => LegacyMessage::write(writer, message),
VersionedMessage::V0(message) => {
u8::write(writer, &MESSAGE_VERSION_PREFIX)?;
v0::Message::write(writer, message)
}
}
}
}

#[cfg(feature = "wincode")]
impl<'de> SchemaRead<'de> for VersionedMessage {
type Dst = Self;

fn read(reader: &mut impl Reader<'de>, dst: &mut MaybeUninit<Self::Dst>) -> ReadResult<()> {
// If the first bit is set, the remaining 7 bits will be used to determine
// which message version is serialized starting from version `0`. If the first
// is bit is not set, all bytes are used to encode the legacy `Message`
// format.
let variant = u8::get(reader)?;

if variant & MESSAGE_VERSION_PREFIX != 0 {
use wincode::error::invalid_tag_encoding;

let version = variant & !MESSAGE_VERSION_PREFIX;
return match version {
0 => {
let msg = v0::Message::get(reader)?;
dst.write(VersionedMessage::V0(msg));
Ok(())
}
_ => Err(invalid_tag_encoding(version as usize)),
};
}

let mut msg = MaybeUninit::<LegacyMessage>::uninit();
// We've already read the variant byte which, in the legacy case, represents
// the `num_required_signatures` field.
// As such, we need to write the remaining fields into the message manually,
// as calling `LegacyMessage::read` will miss the first field.
let header_uninit = LegacyMessage::uninit_header_mut(&mut msg);

MessageHeader::write_uninit_num_required_signatures(variant, header_uninit);
MessageHeader::read_num_readonly_signed_accounts(reader, header_uninit)?;
MessageHeader::read_num_readonly_unsigned_accounts(reader, header_uninit)?;

LegacyMessage::read_account_keys(reader, &mut msg)?;
LegacyMessage::read_recent_blockhash(reader, &mut msg)?;
LegacyMessage::read_instructions(reader, &mut msg)?;

let msg = unsafe { msg.assume_init() };
dst.write(VersionedMessage::Legacy(msg));

Ok(())
}
}

#[cfg(test)]
mod tests {
use {
Expand Down
9 changes: 9 additions & 0 deletions message/src/versions/v0/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ pub use loaded::*;
use serde_derive::{Deserialize, Serialize};
#[cfg(feature = "frozen-abi")]
use solana_frozen_abi_macro::AbiExample;
#[cfg(feature = "wincode")]
use wincode::{containers, len::ShortU16Len, SchemaRead, SchemaWrite};
use {
crate::{
compiled_instruction::CompiledInstruction,
Expand All @@ -38,15 +40,18 @@ mod loaded;
derive(Deserialize, Serialize),
serde(rename_all = "camelCase")
)]
#[cfg_attr(feature = "wincode", derive(SchemaWrite, SchemaRead))]
#[derive(Default, Debug, PartialEq, Eq, Clone)]
pub struct MessageAddressTableLookup {
/// Address lookup table account key
pub account_key: Address,
/// List of indexes used to load writable account addresses
#[cfg_attr(feature = "serde", serde(with = "solana_short_vec"))]
#[cfg_attr(feature = "wincode", wincode(with = "containers::Vec<_, ShortU16Len>"))]
pub writable_indexes: Vec<u8>,
/// List of indexes used to load readonly account addresses
#[cfg_attr(feature = "serde", serde(with = "solana_short_vec"))]
#[cfg_attr(feature = "wincode", wincode(with = "containers::Vec<_, ShortU16Len>"))]
pub readonly_indexes: Vec<u8>,
}

Expand All @@ -63,6 +68,7 @@ pub struct MessageAddressTableLookup {
derive(Deserialize, Serialize),
serde(rename_all = "camelCase")
)]
#[cfg_attr(feature = "wincode", derive(SchemaWrite, SchemaRead))]
#[derive(Default, Debug, PartialEq, Eq, Clone)]
pub struct Message {
/// The message header, identifying signed and read-only `account_keys`.
Expand All @@ -72,6 +78,7 @@ pub struct Message {

/// List of accounts loaded by this transaction.
#[cfg_attr(feature = "serde", serde(with = "solana_short_vec"))]
#[cfg_attr(feature = "wincode", wincode(with = "containers::Vec<_, ShortU16Len>"))]
pub account_keys: Vec<Address>,

/// The blockhash of a recent block.
Expand All @@ -91,11 +98,13 @@ pub struct Message {
/// 2) ordered list of keys loaded from `writable` lookup table indexes
/// 3) ordered list of keys loaded from `readable` lookup table indexes
#[cfg_attr(feature = "serde", serde(with = "solana_short_vec"))]
#[cfg_attr(feature = "wincode", wincode(with = "containers::Vec<_, ShortU16Len>"))]
pub instructions: Vec<CompiledInstruction>,

/// List of address table lookups used to load additional accounts
/// for this transaction.
#[cfg_attr(feature = "serde", serde(with = "solana_short_vec"))]
#[cfg_attr(feature = "wincode", wincode(with = "containers::Vec<_, ShortU16Len>"))]
pub address_table_lookups: Vec<MessageAddressTableLookup>,
}

Expand Down
6 changes: 4 additions & 2 deletions signature/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@ rustdoc-args = ["--cfg=docsrs"]

[features]
default = ["std", "alloc"]
alloc = []
alloc = ["wincode?/alloc"]
bytemuck = ["dep:bytemuck", "dep:bytemuck_derive"]
frozen-abi = ["dep:solana-frozen-abi", "dep:solana-frozen-abi-macro", "std"]
rand = ["dep:rand"]
serde = ["dep:serde", "dep:serde_derive", "dep:serde-big-array"]
std = ["alloc", "serde?/std"]
std = ["alloc", "serde?/std", "wincode?/std"]
verify = ["dep:ed25519-dalek"]
wincode = ["dep:wincode"]

[dependencies]
bytemuck = { workspace = true, optional = true }
Expand All @@ -37,6 +38,7 @@ serde_derive = { workspace = true, optional = true }
solana-frozen-abi = { workspace = true, optional = true, features = ["frozen-abi"] }
solana-frozen-abi-macro = { workspace = true, optional = true, features = ["frozen-abi"] }
solana-sanitize = { workspace = true }
wincode = { workspace = true, optional = true }

[dev-dependencies]
bincode = { workspace = true }
Expand Down
Loading