diff --git a/Cargo.lock b/Cargo.lock index 5b3311fdd..fac3bf1f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3041,6 +3041,7 @@ dependencies = [ name = "solana-frozen-abi" version = "3.1.0" dependencies = [ + "bincode", "bitflags 2.8.0", "boxcar", "bs58", @@ -3051,6 +3052,7 @@ dependencies = [ "log", "memmap2", "rand", + "rand_chacha", "serde", "serde_bytes", "serde_derive", diff --git a/frozen-abi-macro/src/lib.rs b/frozen-abi-macro/src/lib.rs index 8e2d70009..d82830116 100644 --- a/frozen-abi-macro/src/lib.rs +++ b/frozen-abi-macro/src/lib.rs @@ -345,9 +345,9 @@ fn quote_for_test( quote! { #[test] fn test_abi_digest() { - use ::rand::{SeedableRng, RngCore}; - use ::rand_chacha::ChaCha8Rng; - use ::bincode; + use ::solana_frozen_abi::rand::{SeedableRng, RngCore}; + use ::solana_frozen_abi::rand_chacha::ChaCha8Rng; + use ::solana_frozen_abi::bincode; use ::solana_frozen_abi::stable_abi::StableAbi; let mut rng = ChaCha8Rng::seed_from_u64(20666175621446498); diff --git a/frozen-abi/Cargo.toml b/frozen-abi/Cargo.toml index d7dedcddf..7d8e851ac 100644 --- a/frozen-abi/Cargo.toml +++ b/frozen-abi/Cargo.toml @@ -35,9 +35,14 @@ solana-frozen-abi-macro = { workspace = true } thiserror = { workspace = true } [target.'cfg(not(target_os = "solana"))'.dependencies] +# This dependency is used only to back `frozen-abi` StableAbi API +bincode = "1.3.3" im = { workspace = true, features = ["rayon", "serde"] } memmap2 = { workspace = true } -rand = { workspace = true } +# These dependencies are used only to back `frozen-abi` StableAbi API, +# to avoid version skew and keep digest computation stable regardless of consumer dependencies. +rand = "0.8.5" +rand_chacha = "0.3.1" [target.'cfg(not(target_os = "solana"))'.dev-dependencies] bitflags = { workspace = true, features = ["serde"] } diff --git a/frozen-abi/src/lib.rs b/frozen-abi/src/lib.rs index 43037ac51..ecc18fd76 100644 --- a/frozen-abi/src/lib.rs +++ b/frozen-abi/src/lib.rs @@ -19,6 +19,16 @@ pub mod stable_abi; #[macro_use] extern crate solana_frozen_abi_macro; +#[cfg(feature = "frozen-abi")] +#[cfg(not(target_os = "solana"))] +pub use bincode; +#[cfg(feature = "frozen-abi")] +#[cfg(not(target_os = "solana"))] +pub use rand; +#[cfg(feature = "frozen-abi")] +#[cfg(not(target_os = "solana"))] +pub use rand_chacha; + // Not public API. Previously referenced by macro-generated code. Remove the // `log` dependency from Cargo.toml when this is cleaned up in the next major // version bump diff --git a/frozen-abi/src/stable_abi.rs b/frozen-abi/src/stable_abi.rs index e479f629a..475ae86a3 100644 --- a/frozen-abi/src/stable_abi.rs +++ b/frozen-abi/src/stable_abi.rs @@ -5,6 +5,6 @@ pub trait StableAbi: Sized { where Standard: rand::distributions::Distribution, { - rng.gen::() + rng.r#gen::() } } diff --git a/vote-interface/src/state/vote_state_1_14_11.rs b/vote-interface/src/state/vote_state_1_14_11.rs index 6d7606f84..c37149b7c 100644 --- a/vote-interface/src/state/vote_state_1_14_11.rs +++ b/vote-interface/src/state/vote_state_1_14_11.rs @@ -2,13 +2,19 @@ use super::*; #[cfg(feature = "dev-context-only-utils")] use arbitrary::Arbitrary; +#[cfg(feature = "frozen-abi")] +use solana_frozen_abi_macro::{frozen_abi, AbiExample, StableAbi}; + // Offset used for VoteState version 1_14_11 const DEFAULT_PRIOR_VOTERS_OFFSET: usize = 82; #[cfg_attr( feature = "frozen-abi", - solana_frozen_abi_macro::frozen_abi(digest = "2rjXSWaNeAdoUNJDC5otC7NPR1qXHvLMuAs5faE4DPEt"), - derive(solana_frozen_abi_macro::AbiExample) + frozen_abi( + api_digest = "2rjXSWaNeAdoUNJDC5otC7NPR1qXHvLMuAs5faE4DPEt", + abi_digest = "DEmsGurYNiQfW2bkPBuxEKoMfxbPgkGejpBiNj8HywAS" + ), + derive(AbiExample, StableAbi) )] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] #[derive(Debug, Default, PartialEq, Eq, Clone)] @@ -45,6 +51,43 @@ pub struct VoteState1_14_11 { pub last_timestamp: BlockTimestamp, } +#[cfg(feature = "frozen-abi")] +impl solana_frozen_abi::rand::prelude::Distribution + for solana_frozen_abi::rand::distributions::Standard +{ + fn sample(&self, rng: &mut R) -> VoteState1_14_11 { + let votes: VecDeque<_> = (0..rng.gen_range(0..1000)) + .map(|_| Lockout::new(rng.gen())) + .collect(); + + let mut prior_voters: CircBuf<(Pubkey, Epoch, Epoch)> = CircBuf::default(); + for _ in 0..rng.gen_range(0..1000) { + prior_voters.append((Pubkey::new_from_array(rng.gen()), rng.gen(), rng.gen())); + } + let epoch_credits: Vec<_> = (0..rng.gen_range(0..1000)) + .map(|_| (rng.gen(), rng.gen(), rng.gen())) + .collect(); + + VoteState1_14_11 { + node_pubkey: Pubkey::new_from_array(rng.r#gen()), + authorized_withdrawer: Pubkey::new_from_array(rng.r#gen()), + commission: rng.r#gen(), + votes, + root_slot: Some(rng.r#gen()), + authorized_voters: AuthorizedVoters::new( + rng.r#gen(), + Pubkey::new_from_array(rng.r#gen()), + ), + prior_voters, + epoch_credits, + last_timestamp: BlockTimestamp { + slot: rng.r#gen(), + timestamp: rng.r#gen(), + }, + } + } +} + impl VoteState1_14_11 { pub fn get_rent_exempt_reserve(rent: &Rent) -> u64 { rent.minimum_balance(Self::size_of())