diff --git a/Cargo.lock b/Cargo.lock index 1467f4e8105338..636378ac3db666 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6106,6 +6106,16 @@ dependencies = [ "tungstenite", ] +[[package]] +name = "solana-clock" +version = "2.1.0" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-macro", + "static_assertions", +] + [[package]] name = "solana-compute-budget" version = "2.1.0" @@ -6996,6 +7006,7 @@ dependencies = [ "sha2 0.10.8", "sha3", "solana-atomic-u64", + "solana-clock", "solana-decode-error", "solana-define-syscall", "solana-frozen-abi", diff --git a/Cargo.toml b/Cargo.toml index 77eb27a151acf2..9ca4a0cdc98298 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -103,6 +103,7 @@ members = [ "sdk/atomic-u64", "sdk/cargo-build-sbf", "sdk/cargo-test-sbf", + "sdk/clock", "sdk/decode-error", "sdk/gen-headers", "sdk/macro", @@ -366,6 +367,7 @@ solana-cli = { path = "cli", version = "=2.1.0" } solana-cli-config = { path = "cli-config", version = "=2.1.0" } solana-cli-output = { path = "cli-output", version = "=2.1.0" } solana-client = { path = "client", version = "=2.1.0" } +solana-clock = { path = "sdk/clock", version = "=2.1.0" } solana-compute-budget = { path = "compute-budget", version = "=2.1.0" } solana-compute-budget-program = { path = "programs/compute-budget", version = "=2.1.0" } solana-config-program = { path = "programs/config", version = "=2.1.0" } diff --git a/programs/sbf/Cargo.lock b/programs/sbf/Cargo.lock index b1758b3277f087..458f977bc76e7a 100644 --- a/programs/sbf/Cargo.lock +++ b/programs/sbf/Cargo.lock @@ -4839,6 +4839,15 @@ dependencies = [ "tokio", ] +[[package]] +name = "solana-clock" +version = "2.1.0" +dependencies = [ + "serde", + "serde_derive", + "solana-sdk-macro", +] + [[package]] name = "solana-compute-budget" version = "2.1.0" @@ -5411,6 +5420,7 @@ dependencies = [ "sha2 0.10.8", "sha3", "solana-atomic-u64", + "solana-clock", "solana-decode-error", "solana-define-syscall", "solana-msg", diff --git a/sdk/clock/Cargo.toml b/sdk/clock/Cargo.toml new file mode 100644 index 00000000000000..677c3f61d6a9ec --- /dev/null +++ b/sdk/clock/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "solana-clock" +description = "Solana Clock and Time Definitions" +documentation = "https://docs.rs/solana-clock" +version = { workspace = true } +authors = { workspace = true } +repository = { workspace = true } +homepage = { workspace = true } +license = { workspace = true } +edition = { workspace = true } + +[dependencies] +serde = { workspace = true, optional = true } +serde_derive = { workspace = true, optional = true } +solana-sdk-macro = { workspace = true } + +[dev-dependencies] +static_assertions = { workspace = true } + +[features] +serde = ["dep:serde", "dep:serde_derive"] + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/sdk/program/src/clock.rs b/sdk/clock/src/lib.rs similarity index 97% rename from sdk/program/src/clock.rs rename to sdk/clock/src/lib.rs index 5cf609d3000c26..870265f9c18eb9 100644 --- a/sdk/program/src/clock.rs +++ b/sdk/clock/src/lib.rs @@ -20,6 +20,8 @@ //! //! [oracle]: https://docs.solanalabs.com/implemented-proposals/validator-timestamp-oracle +#[cfg(feature = "serde")] +use serde_derive::{Deserialize, Serialize}; use solana_sdk_macro::CloneZeroed; /// The default tick rate that the cluster attempts to achieve (160 per second). @@ -172,7 +174,8 @@ pub type UnixTimestamp = i64; /// /// All members of `Clock` start from 0 upon network boot. #[repr(C)] -#[derive(Serialize, Deserialize, Debug, CloneZeroed, Default, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Debug, CloneZeroed, Default, PartialEq, Eq)] pub struct Clock { /// The current `Slot`. pub slot: Slot, diff --git a/sdk/program/Cargo.toml b/sdk/program/Cargo.toml index a5b525aaf0dca0..b711393274ef97 100644 --- a/sdk/program/Cargo.toml +++ b/sdk/program/Cargo.toml @@ -32,6 +32,7 @@ serde_derive = { workspace = true } sha2 = { workspace = true } sha3 = { workspace = true } solana-atomic-u64 = { workspace = true } +solana-clock = { workspace = true, features = ["serde"] } solana-decode-error = { workspace = true } solana-frozen-abi = { workspace = true, optional = true, features = ["frozen-abi"] } solana-frozen-abi-macro = { workspace = true, optional = true, features = ["frozen-abi"] } diff --git a/sdk/program/src/account_info.rs b/sdk/program/src/account_info.rs index 485195381a9f64..fb7614903673b8 100644 --- a/sdk/program/src/account_info.rs +++ b/sdk/program/src/account_info.rs @@ -2,9 +2,10 @@ use { crate::{ - clock::Epoch, debug_account_data::*, entrypoint::MAX_PERMITTED_DATA_INCREASE, + debug_account_data::*, entrypoint::MAX_PERMITTED_DATA_INCREASE, program_error::ProgramError, pubkey::Pubkey, }, + solana_clock::Epoch, solana_program_memory::sol_memset, std::{ cell::{Ref, RefCell, RefMut}, diff --git a/sdk/program/src/address_lookup_table/instruction.rs b/sdk/program/src/address_lookup_table/instruction.rs index 5687ab6d05a1aa..4d73060e046ec3 100644 --- a/sdk/program/src/address_lookup_table/instruction.rs +++ b/sdk/program/src/address_lookup_table/instruction.rs @@ -1,12 +1,12 @@ use { crate::{ address_lookup_table::program::id, - clock::Slot, instruction::{AccountMeta, Instruction}, pubkey::Pubkey, system_program, }, serde_derive::{Deserialize, Serialize}, + solana_clock::Slot, }; #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] diff --git a/sdk/program/src/address_lookup_table/state.rs b/sdk/program/src/address_lookup_table/state.rs index df564f78fe2577..13a66637faa919 100644 --- a/sdk/program/src/address_lookup_table/state.rs +++ b/sdk/program/src/address_lookup_table/state.rs @@ -2,9 +2,9 @@ use solana_frozen_abi_macro::{AbiEnumVisitor, AbiExample}; use { serde_derive::{Deserialize, Serialize}, + solana_clock::Slot, solana_program::{ address_lookup_table::error::AddressLookupError, - clock::Slot, instruction::InstructionError, pubkey::Pubkey, slot_hashes::{SlotHashes, MAX_ENTRIES}, diff --git a/sdk/program/src/epoch_schedule.rs b/sdk/program/src/epoch_schedule.rs index 2e1398d86b9050..d36f34aacf64ab 100644 --- a/sdk/program/src/epoch_schedule.rs +++ b/sdk/program/src/epoch_schedule.rs @@ -11,7 +11,7 @@ //! the chain there is a "warmup" period, where epochs are short, with subsequent //! epochs increasing in slots until they last for [`DEFAULT_SLOTS_PER_EPOCH`]. -pub use crate::clock::{Epoch, Slot, DEFAULT_SLOTS_PER_EPOCH}; +pub use solana_clock::{Epoch, Slot, DEFAULT_SLOTS_PER_EPOCH}; use solana_sdk_macro::CloneZeroed; /// The default number of slots before an epoch starts to calculate the leader schedule. diff --git a/sdk/program/src/example_mocks.rs b/sdk/program/src/example_mocks.rs index b528812e36f6b3..eaa02ee02724de 100644 --- a/sdk/program/src/example_mocks.rs +++ b/sdk/program/src/example_mocks.rs @@ -123,7 +123,7 @@ pub mod solana_sdk { }; pub mod account { - use crate::{clock::Epoch, pubkey::Pubkey}; + use {crate::pubkey::Pubkey, solana_clock::Epoch}; #[derive(Clone)] pub struct Account { pub lamports: u64, diff --git a/sdk/program/src/feature.rs b/sdk/program/src/feature.rs index b46704ebcb9992..af4ab1ad287636 100644 --- a/sdk/program/src/feature.rs +++ b/sdk/program/src/feature.rs @@ -11,9 +11,12 @@ //! 2. When the next epoch is entered the runtime will check for new activation requests and //! active them. When this occurs, the activation slot is recorded in the feature account -use crate::{ - account_info::AccountInfo, clock::Slot, instruction::Instruction, program_error::ProgramError, - pubkey::Pubkey, rent::Rent, system_instruction, +use { + crate::{ + account_info::AccountInfo, instruction::Instruction, program_error::ProgramError, + pubkey::Pubkey, rent::Rent, system_instruction, + }, + solana_clock::Slot, }; crate::declare_id!("Feature111111111111111111111111111111111111"); @@ -60,7 +63,7 @@ pub fn activate_with_lamports( #[cfg(test)] mod test { - use {super::*, solana_program::clock::Slot}; + use super::*; #[test] fn test_feature_size_of() { diff --git a/sdk/program/src/fee_calculator.rs b/sdk/program/src/fee_calculator.rs index 5d753e4acaed3a..a9b616ff8f53da 100644 --- a/sdk/program/src/fee_calculator.rs +++ b/sdk/program/src/fee_calculator.rs @@ -1,7 +1,7 @@ //! Calculation of transaction fees. #![allow(clippy::arithmetic_side_effects)] -use {crate::clock::DEFAULT_MS_PER_SLOT, log::*}; +use {log::*, solana_clock::DEFAULT_MS_PER_SLOT}; #[repr(C)] #[cfg_attr(feature = "frozen-abi", derive(AbiExample))] diff --git a/sdk/program/src/last_restart_slot.rs b/sdk/program/src/last_restart_slot.rs index 7c67a574e93c45..880685a096b5b1 100644 --- a/sdk/program/src/last_restart_slot.rs +++ b/sdk/program/src/last_restart_slot.rs @@ -1,6 +1,6 @@ //! Information about the last restart slot (hard fork). -use {crate::clock::Slot, solana_sdk_macro::CloneZeroed}; +use {solana_clock::Slot, solana_sdk_macro::CloneZeroed}; #[repr(C)] #[derive(Serialize, Deserialize, Debug, CloneZeroed, PartialEq, Eq, Default)] diff --git a/sdk/program/src/lib.rs b/sdk/program/src/lib.rs index 591c4563a973ae..de4c685fdfbfba 100644 --- a/sdk/program/src/lib.rs +++ b/sdk/program/src/lib.rs @@ -482,7 +482,6 @@ pub mod borsh1; pub mod bpf_loader; pub mod bpf_loader_deprecated; pub mod bpf_loader_upgradeable; -pub mod clock; pub mod compute_units; pub mod debug_account_data; pub mod ed25519_program; @@ -530,7 +529,6 @@ pub mod sysvar; pub mod vote; pub mod wasm; -pub use solana_msg::msg; #[deprecated(since = "2.1.0", note = "Use `solana-program-memory` crate instead")] pub use solana_program_memory as program_memory; #[deprecated(since = "2.1.0", note = "Use `solana-sanitize` crate instead")] @@ -541,6 +539,7 @@ pub use solana_secp256k1_recover as secp256k1_recover; pub use solana_short_vec as short_vec; #[cfg(target_arch = "wasm32")] pub use wasm_bindgen::prelude::wasm_bindgen; +pub use {solana_clock as clock, solana_msg::msg}; /// The [config native program][np]. /// diff --git a/sdk/program/src/program.rs b/sdk/program/src/program.rs index 27a4a2a8cca957..7692b8d2b412ab 100644 --- a/sdk/program/src/program.rs +++ b/sdk/program/src/program.rs @@ -8,9 +8,12 @@ //! [`invoke_signed`]: invoke_signed //! [cpi]: https://solana.com/docs/core/cpi -use crate::{ - account_info::AccountInfo, entrypoint::ProgramResult, instruction::Instruction, pubkey::Pubkey, - stable_layout::stable_instruction::StableInstruction, +use { + crate::{ + account_info::AccountInfo, entrypoint::ProgramResult, instruction::Instruction, + pubkey::Pubkey, stable_layout::stable_instruction::StableInstruction, + }, + solana_clock::Epoch, }; /// Invoke a cross-program instruction. @@ -396,7 +399,7 @@ pub fn get_return_data() -> Option<(Pubkey, Vec)> { pub fn check_type_assumptions() { extern crate memoffset; use { - crate::{clock::Epoch, instruction::AccountMeta}, + crate::instruction::AccountMeta, memoffset::offset_of, std::{ cell::RefCell, diff --git a/sdk/program/src/rent.rs b/sdk/program/src/rent.rs index 6553125eede6d0..47308066d927cc 100644 --- a/sdk/program/src/rent.rs +++ b/sdk/program/src/rent.rs @@ -4,7 +4,7 @@ #![allow(clippy::arithmetic_side_effects)] -use {crate::clock::DEFAULT_SLOTS_PER_EPOCH, solana_sdk_macro::CloneZeroed}; +use {solana_clock::DEFAULT_SLOTS_PER_EPOCH, solana_sdk_macro::CloneZeroed}; /// Configuration of network rent. #[repr(C)] diff --git a/sdk/program/src/slot_hashes.rs b/sdk/program/src/slot_hashes.rs index f17512ac9fb124..f18d14e89f9e9c 100644 --- a/sdk/program/src/slot_hashes.rs +++ b/sdk/program/src/slot_hashes.rs @@ -6,7 +6,7 @@ //! //! [`sysvar::slot_hashes`]: crate::sysvar::slot_hashes -pub use crate::clock::Slot; +pub use solana_clock::Slot; use { crate::hash::Hash, std::{ diff --git a/sdk/program/src/stake/instruction.rs b/sdk/program/src/stake/instruction.rs index 89357050e93ca8..fff1811bc393e9 100644 --- a/sdk/program/src/stake/instruction.rs +++ b/sdk/program/src/stake/instruction.rs @@ -5,7 +5,6 @@ use { crate::{ - clock::{Epoch, UnixTimestamp}, instruction::{AccountMeta, Instruction}, program_error::ProgramError, pubkey::Pubkey, @@ -19,6 +18,7 @@ use { log::*, num_derive::{FromPrimitive, ToPrimitive}, serde_derive::{Deserialize, Serialize}, + solana_clock::{Epoch, UnixTimestamp}, solana_decode_error::DecodeError, thiserror::Error, }; diff --git a/sdk/program/src/stake/state.rs b/sdk/program/src/stake/state.rs index 139df906fc12b2..4fee1bb008fb79 100644 --- a/sdk/program/src/stake/state.rs +++ b/sdk/program/src/stake/state.rs @@ -8,7 +8,6 @@ use borsh::{io, BorshDeserialize, BorshSchema, BorshSerialize}; use { crate::{ - clock::{Clock, Epoch, UnixTimestamp}, instruction::InstructionError, pubkey::Pubkey, stake::{ @@ -17,6 +16,7 @@ use { }, stake_history::{StakeHistoryEntry, StakeHistoryGetEntry}, }, + solana_clock::{Clock, Epoch, UnixTimestamp}, std::collections::HashSet, }; diff --git a/sdk/program/src/stake/tools.rs b/sdk/program/src/stake/tools.rs index e0447f49fc69c9..73f92017bb9390 100644 --- a/sdk/program/src/stake/tools.rs +++ b/sdk/program/src/stake/tools.rs @@ -1,6 +1,7 @@ //! Utility functions -use crate::{ - clock::Epoch, program_error::ProgramError, stake::MINIMUM_DELINQUENT_EPOCHS_FOR_DEACTIVATION, +use { + crate::{program_error::ProgramError, stake::MINIMUM_DELINQUENT_EPOCHS_FOR_DEACTIVATION}, + solana_clock::Epoch, }; /// Helper function for programs to call [`GetMinimumDelegation`] and then fetch the return data diff --git a/sdk/program/src/stake_history.rs b/sdk/program/src/stake_history.rs index f1bbe3b0f81da8..9438d004c0f5f3 100644 --- a/sdk/program/src/stake_history.rs +++ b/sdk/program/src/stake_history.rs @@ -6,7 +6,7 @@ //! //! [`sysvar::stake_history`]: crate::sysvar::stake_history -pub use crate::clock::Epoch; +pub use solana_clock::Epoch; use std::ops::Deref; pub const MAX_ENTRIES: usize = 512; // it should never take as many as 512 epochs to warm up or cool down diff --git a/sdk/program/src/sysvar/clock.rs b/sdk/program/src/sysvar/clock.rs index c9f31e8fa9efcd..db87594001d578 100644 --- a/sdk/program/src/sysvar/clock.rs +++ b/sdk/program/src/sysvar/clock.rs @@ -126,8 +126,8 @@ //! # Ok::<(), anyhow::Error>(()) //! ``` -pub use crate::clock::Clock; use crate::{impl_sysvar_get, program_error::ProgramError, sysvar::Sysvar}; +pub use solana_clock::Clock; crate::declare_sysvar_id!("SysvarC1ock11111111111111111111111111111111", Clock); diff --git a/sdk/program/src/sysvar/mod.rs b/sdk/program/src/sysvar/mod.rs index 69a3c475a0decd..9cdbac0b75bc01 100644 --- a/sdk/program/src/sysvar/mod.rs +++ b/sdk/program/src/sysvar/mod.rs @@ -283,12 +283,12 @@ mod tests { use { super::*, crate::{ - clock::Epoch, entrypoint::SUCCESS, program_error::ProgramError, program_stubs::{set_syscall_stubs, SyscallStubs}, pubkey::Pubkey, }, + solana_clock::Epoch, std::{cell::RefCell, rc::Rc}, }; diff --git a/sdk/program/src/sysvar/recent_blockhashes.rs b/sdk/program/src/sysvar/recent_blockhashes.rs index ec3a69baf7adb9..1dde2fda5d29af 100644 --- a/sdk/program/src/sysvar/recent_blockhashes.rs +++ b/sdk/program/src/sysvar/recent_blockhashes.rs @@ -162,7 +162,7 @@ impl Deref for RecentBlockhashes { #[cfg(test)] mod tests { - use {super::*, crate::clock::MAX_PROCESSING_AGE}; + use {super::*, solana_clock::MAX_PROCESSING_AGE}; #[test] #[allow(clippy::assertions_on_constants)] diff --git a/sdk/program/src/sysvar/slot_hashes.rs b/sdk/program/src/sysvar/slot_hashes.rs index 69ab49dc4e124a..ab683c1802b441 100644 --- a/sdk/program/src/sysvar/slot_hashes.rs +++ b/sdk/program/src/sysvar/slot_hashes.rs @@ -49,13 +49,13 @@ pub use crate::slot_hashes::SlotHashes; use { crate::{ account_info::AccountInfo, - clock::Slot, hash::Hash, program_error::ProgramError, slot_hashes::MAX_ENTRIES, sysvar::{get_sysvar, Sysvar, SysvarId}, }, bytemuck_derive::{Pod, Zeroable}, + solana_clock::Slot, }; const U64_SIZE: usize = std::mem::size_of::(); @@ -218,7 +218,6 @@ mod tests { use { super::*, crate::{ - clock::Slot, hash::{hash, Hash}, slot_hashes::MAX_ENTRIES, sysvar::tests::mock_get_sysvar_syscall, diff --git a/sdk/program/src/sysvar/stake_history.rs b/sdk/program/src/sysvar/stake_history.rs index 6f2008bf8e44a5..0c41689b102f71 100644 --- a/sdk/program/src/sysvar/stake_history.rs +++ b/sdk/program/src/sysvar/stake_history.rs @@ -46,10 +46,12 @@ //! ``` pub use crate::stake_history::StakeHistory; -use crate::{ - clock::Epoch, - stake_history::{StakeHistoryEntry, StakeHistoryGetEntry, MAX_ENTRIES}, - sysvar::{get_sysvar, Sysvar, SysvarId}, +use { + crate::{ + stake_history::{StakeHistoryEntry, StakeHistoryGetEntry, MAX_ENTRIES}, + sysvar::{get_sysvar, Sysvar, SysvarId}, + }, + solana_clock::Epoch, }; crate::declare_sysvar_id!("SysvarStakeHistory1111111111111111111111111", StakeHistory); diff --git a/sdk/program/src/vote/authorized_voters.rs b/sdk/program/src/vote/authorized_voters.rs index 773dfa70c690de..69f1a8b4828b1f 100644 --- a/sdk/program/src/vote/authorized_voters.rs +++ b/sdk/program/src/vote/authorized_voters.rs @@ -1,8 +1,9 @@ #[cfg(test)] use arbitrary::Arbitrary; use { - crate::{clock::Epoch, pubkey::Pubkey}, + crate::pubkey::Pubkey, serde_derive::{Deserialize, Serialize}, + solana_clock::Epoch, std::collections::BTreeMap, }; diff --git a/sdk/program/src/vote/instruction.rs b/sdk/program/src/vote/instruction.rs index c4369dd26d8080..e707c9e06d05bd 100644 --- a/sdk/program/src/vote/instruction.rs +++ b/sdk/program/src/vote/instruction.rs @@ -3,7 +3,6 @@ use { super::state::TowerSync, crate::{ - clock::{Slot, UnixTimestamp}, hash::Hash, instruction::{AccountMeta, Instruction}, pubkey::Pubkey, @@ -18,6 +17,7 @@ use { }, }, serde_derive::{Deserialize, Serialize}, + solana_clock::{Slot, UnixTimestamp}, }; #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] diff --git a/sdk/program/src/vote/state/mod.rs b/sdk/program/src/vote/state/mod.rs index 8d1efa7468db5f..9944f5517660f2 100644 --- a/sdk/program/src/vote/state/mod.rs +++ b/sdk/program/src/vote/state/mod.rs @@ -9,7 +9,6 @@ use { }; use { crate::{ - clock::{Epoch, Slot, UnixTimestamp}, hash::Hash, instruction::InstructionError, pubkey::Pubkey, @@ -20,6 +19,7 @@ use { }, bincode::{serialize_into, ErrorKind}, serde_derive::{Deserialize, Serialize}, + solana_clock::{Epoch, Slot, UnixTimestamp}, std::{ collections::VecDeque, fmt::Debug, @@ -978,11 +978,7 @@ impl VoteState { pub mod serde_compact_vote_state_update { use { super::*, - crate::{ - clock::{Slot, UnixTimestamp}, - serde_varint, - vote::state::Lockout, - }, + crate::{serde_varint, vote::state::Lockout}, serde::{Deserialize, Deserializer, Serialize, Serializer}, solana_short_vec as short_vec, }; @@ -1076,11 +1072,7 @@ pub mod serde_compact_vote_state_update { pub mod serde_tower_sync { use { super::*, - crate::{ - clock::{Slot, UnixTimestamp}, - serde_varint, - vote::state::Lockout, - }, + crate::{serde_varint, vote::state::Lockout}, serde::{Deserialize, Deserializer, Serialize, Serializer}, solana_short_vec as short_vec, };