Skip to content

Commit

Permalink
Add const pubkey support and make declare_id a declarative macro (#2348)
Browse files Browse the repository at this point in the history
* make declare_id a declarative macro

* remove old comment

* deprecate program_declare_id

* deprecate pubkey macro

* put deprecation on the re-export of the pubkey macro

* replace pubkey! with from_str_const in this repo

* fmt

* remove unused import

* Revert "remove unused rustc_version dep from wen-restart (wrong branch)"

This reverts commit 60dbddd.

* avoid wen-restart changes again

* fmt

* fix deprecation text

* make declare_deprecated_id a declarative macro

* put back the deprecation on the re-export of the pubkey macro

* fmt

* don't deprecate the pubkey macro, but make it a declarative macro

* update deprecation note

* re-export the new pubkey macro in solana-sdk (with deprecation) instead of the old one
  • Loading branch information
kevinheavey authored Oct 14, 2024
1 parent 49d2298 commit 2ea7fd7
Show file tree
Hide file tree
Showing 14 changed files with 208 additions and 60 deletions.
18 changes: 18 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ etcd-client = "0.11.1"
fast-math = "0.1"
fd-lock = "3.0.13"
flate2 = "1.0.31"
five8_const = "0.1.3"
fnv = "1.0.7"
fs_extra = "1.3.0"
futures = "0.3.31"
Expand Down
5 changes: 3 additions & 2 deletions keygen/src/keygen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,10 @@ use {
};

mod smallest_length_44_public_key {
use solana_sdk::{pubkey, pubkey::Pubkey};
use solana_sdk::pubkey::Pubkey;

pub(super) static PUBKEY: Pubkey = pubkey!("21111111111111111111111111111111111111111111");
pub(super) static PUBKEY: Pubkey =
Pubkey::from_str_const("21111111111111111111111111111111111111111111");

#[test]
fn assert_length() {
Expand Down
4 changes: 2 additions & 2 deletions program-runtime/src/sysvar_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ pub struct SysvarCache {

// declare_deprecated_sysvar_id doesn't support const.
// These sysvars are going away anyway.
const FEES_ID: Pubkey = solana_sdk::pubkey!("SysvarFees111111111111111111111111111111111");
const FEES_ID: Pubkey = Pubkey::from_str_const("SysvarFees111111111111111111111111111111111");
const RECENT_BLOCKHASHES_ID: Pubkey =
solana_sdk::pubkey!("SysvarRecentB1ockHashes11111111111111111111");
Pubkey::from_str_const("SysvarRecentB1ockHashes11111111111111111111");

impl SysvarCache {
/// Overwrite a sysvar. For testing purposes only.
Expand Down
18 changes: 18 additions & 0 deletions programs/sbf/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ solana-frozen-abi-macro = { workspace = true, optional = true, features = [
] }
solana-program = { workspace = true }
solana-program-memory = { workspace = true }
solana-pubkey = { workspace = true }
solana-sanitize = { workspace = true }
solana-sdk-macro = { workspace = true }
solana-secp256k1-recover = { workspace = true }
Expand Down
7 changes: 7 additions & 0 deletions sdk/macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,12 +180,14 @@ impl ToTokens for ProgramSdkIdDeprecated {
}
}

#[deprecated(since = "2.1.0", note = "Use `solana_pubkey::pubkey` instead")]
#[proc_macro]
pub fn pubkey(input: TokenStream) -> TokenStream {
let id = parse_macro_input!(input as SdkPubkey);
TokenStream::from(quote! {#id})
}

#[deprecated(since = "2.1.0", note = "Use `solana_pubkey::pubkey!` instead")]
#[proc_macro]
pub fn program_pubkey(input: TokenStream) -> TokenStream {
let id = parse_macro_input!(input as ProgramSdkPubkey);
Expand All @@ -204,12 +206,17 @@ pub fn declare_deprecated_id(input: TokenStream) -> TokenStream {
TokenStream::from(quote! {#id})
}

#[deprecated(since = "2.1.0", note = "Use `solana_pubkey::declare_id` instead")]
#[proc_macro]
pub fn program_declare_id(input: TokenStream) -> TokenStream {
let id = parse_macro_input!(input as ProgramSdkId);
TokenStream::from(quote! {#id})
}

#[deprecated(
since = "2.1.0",
note = "Use `solana_pubkey::declare_deprecated_id` instead"
)]
#[proc_macro]
pub fn program_declare_deprecated_id(input: TokenStream) -> TokenStream {
let id = parse_macro_input!(input as ProgramSdkIdDeprecated);
Expand Down
1 change: 1 addition & 0 deletions sdk/program/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ bs58 = { workspace = true, features = ["alloc"] }
bv = { workspace = true, features = ["serde"] }
bytemuck = { workspace = true }
bytemuck_derive = { workspace = true }
five8_const = { workspace = true }
lazy_static = { workspace = true }
log = { workspace = true }
memoffset = { workspace = true }
Expand Down
41 changes: 1 addition & 40 deletions sdk/program/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -597,46 +597,7 @@ pub mod sdk_ids {

#[deprecated(since = "2.1.0", note = "Use `solana-decode-error` crate instead")]
pub use solana_decode_error as decode_error;
/// Same as [`declare_id`] except that it reports that this ID has been deprecated.
pub use solana_sdk_macro::program_declare_deprecated_id as declare_deprecated_id;
/// Convenience macro to declare a static public key and functions to interact with it.
///
/// Input: a single literal base58 string representation of a program's ID.
///
/// # Example
///
/// ```
/// # // wrapper is used so that the macro invocation occurs in the item position
/// # // rather than in the statement position which isn't allowed.
/// use std::str::FromStr;
/// use solana_program::{declare_id, pubkey::Pubkey};
///
/// # mod item_wrapper {
/// # use solana_program::declare_id;
/// declare_id!("My11111111111111111111111111111111111111111");
/// # }
/// # use item_wrapper::id;
///
/// let my_id = Pubkey::from_str("My11111111111111111111111111111111111111111").unwrap();
/// assert_eq!(id(), my_id);
/// ```
pub use solana_sdk_macro::program_declare_id as declare_id;
/// Convenience macro to define a static public key.
///
/// Input: a single literal base58 string representation of a Pubkey.
///
/// # Example
///
/// ```
/// use std::str::FromStr;
/// use solana_program::{pubkey, pubkey::Pubkey};
///
/// static ID: Pubkey = pubkey!("My11111111111111111111111111111111111111111");
///
/// let my_id = Pubkey::from_str("My11111111111111111111111111111111111111111").unwrap();
/// assert_eq!(ID, my_id);
/// ```
pub use solana_sdk_macro::program_pubkey as pubkey;
pub use solana_pubkey::{declare_deprecated_id, declare_id, pubkey};

#[macro_use]
extern crate serde_derive;
Expand Down
15 changes: 15 additions & 0 deletions sdk/program/tests/test_pubkey_export.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use {
solana_program::{pubkey, pubkey::Pubkey},
std::str::FromStr,
};

// solana_program::pubkey refers to both a module and a macro.
// This test demonstrates that both imports are working
#[test]
fn test_pubkey_import() {
let pk = pubkey!("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL");
assert_eq!(
pk,
Pubkey::from_str("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL").unwrap()
);
}
1 change: 1 addition & 0 deletions sdk/pubkey/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ borsh0-10 = { package = "borsh", version = "0.10.3", optional = true }
bs58 = { workspace = true }
bytemuck = { workspace = true, optional = true }
bytemuck_derive = { workspace = true, optional = true }
five8_const = { workspace = true }
num-traits = { workspace = true }
serde = { workspace = true, optional = true }
serde_derive = { workspace = true, optional = true }
Expand Down
115 changes: 115 additions & 0 deletions sdk/pubkey/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,12 @@ impl Pubkey {
Self(pubkey_array)
}

/// Decode a string into a Pubkey, usable in a const context
pub const fn from_str_const(s: &str) -> Self {
let id_array = five8_const::decode_32_const(s);
Pubkey::new_from_array(id_array)
}

/// unique Pubkey for tests and benchmarks.
pub fn new_unique() -> Self {
use solana_atomic_u64::AtomicU64;
Expand Down Expand Up @@ -1009,6 +1015,105 @@ impl Pubkey {
}
}

/// Convenience macro to declare a static public key and functions to interact with it.
///
/// Input: a single literal base58 string representation of a program's ID.
///
/// # Example
///
/// ```
/// # // wrapper is used so that the macro invocation occurs in the item position
/// # // rather than in the statement position which isn't allowed.
/// use std::str::FromStr;
/// use solana_pubkey::{declare_id, Pubkey};
///
/// # mod item_wrapper {
/// # use solana_pubkey::declare_id;
/// declare_id!("My11111111111111111111111111111111111111111");
/// # }
/// # use item_wrapper::id;
///
/// let my_id = Pubkey::from_str("My11111111111111111111111111111111111111111").unwrap();
/// assert_eq!(id(), my_id);
/// ```
#[macro_export]
macro_rules! declare_id {
($address:expr) => {
/// The const program ID.
pub const ID: $crate::Pubkey = $crate::Pubkey::from_str_const($address);

/// Returns `true` if given pubkey is the program ID.
// TODO make this const once `derive_const` makes it out of nightly
// and we can `derive_const(PartialEq)` on `Pubkey`.
pub fn check_id(id: &$crate::Pubkey) -> bool {
id == &ID
}

/// Returns the program ID.
pub const fn id() -> $crate::Pubkey {
ID
}

#[cfg(test)]
#[test]
fn test_id() {
assert!(check_id(&id()));
}
};
}

/// Same as [`declare_id`] except that it reports that this ID has been deprecated.
#[macro_export]
macro_rules! declare_deprecated_id {
($address:expr) => {
/// The const program ID.
pub const ID: $crate::Pubkey = $crate::Pubkey::from_str_const($address);

/// Returns `true` if given pubkey is the program ID.
// TODO make this const once `derive_const` makes it out of nightly
// and we can `derive_const(PartialEq)` on `Pubkey`.
#[deprecated()]
pub fn check_id(id: &$crate::Pubkey) -> bool {
id == &ID
}

/// Returns the program ID.
#[deprecated()]
pub const fn id() -> $crate::Pubkey {
ID
}

#[cfg(test)]
#[test]
#[allow(deprecated)]
fn test_id() {
assert!(check_id(&id()));
}
};
}

/// Convenience macro to define a static public key.
///
/// Input: a single literal base58 string representation of a Pubkey.
///
/// # Example
///
/// ```
/// use std::str::FromStr;
/// use solana_pubkey::{pubkey, Pubkey};
///
/// static ID: Pubkey = pubkey!("My11111111111111111111111111111111111111111");
///
/// let my_id = Pubkey::from_str("My11111111111111111111111111111111111111111").unwrap();
/// assert_eq!(ID, my_id);
/// ```
#[macro_export]
macro_rules! pubkey {
($input:literal) => {
$crate::Pubkey::from_str_const($input)
};
}

#[cfg(test)]
mod tests {
use {super::*, strum::IntoEnumIterator};
Expand Down Expand Up @@ -1279,4 +1384,14 @@ mod tests {
);
}
}

#[test]
fn test_pubkey_macro() {
const PK: Pubkey = Pubkey::from_str_const("9h1HyLCW5dZnBVap8C5egQ9Z6pHyjsh5MNy83iPqqRuq");
assert_eq!(pubkey!("9h1HyLCW5dZnBVap8C5egQ9Z6pHyjsh5MNy83iPqqRuq"), PK);
assert_eq!(
Pubkey::from_str("9h1HyLCW5dZnBVap8C5egQ9Z6pHyjsh5MNy83iPqqRuq").unwrap(),
PK
);
}
}
Loading

0 comments on commit 2ea7fd7

Please sign in to comment.