From 8292263344d26ca34ae0d5352119ba372c097379 Mon Sep 17 00:00:00 2001 From: Jon C Date: Thu, 20 Jun 2024 18:44:35 +0200 Subject: [PATCH 1/3] sdk: Add `Pubkey::from_str_const` for decoding --- sdk/program/src/pubkey.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sdk/program/src/pubkey.rs b/sdk/program/src/pubkey.rs index 94438c66d81bb9..6718dd9730bff1 100644 --- a/sdk/program/src/pubkey.rs +++ b/sdk/program/src/pubkey.rs @@ -192,6 +192,16 @@ impl Pubkey { Self(pubkey_array) } + /// Decode a string into a Pubkey, usable in a const context + /// + /// Note: Until https://github.com/Nullus157/bs58-rs/pull/120 lands, this + /// function does not include a check that the output decodes to exactly 32 + /// bytes. + pub const fn from_str_const(s: &str) -> Self { + let id_array = bs58::decode(s.as_bytes()).into_array_const_unwrap::(); + Pubkey::new_from_array(id_array) + } + #[deprecated(since = "1.3.9", note = "Please use 'Pubkey::new_unique' instead")] #[cfg(not(target_os = "solana"))] pub fn new_rand() -> Self { From 5752ec44e1abefc108b6008ae5cca850e048f4f0 Mon Sep 17 00:00:00 2001 From: Jon C Date: Thu, 20 Jun 2024 18:54:20 +0200 Subject: [PATCH 2/3] package-metadata: Add package and macro --- Cargo.lock | 8 +++ Cargo.toml | 2 + sdk/package-metadata/Cargo.toml | 19 +++++++ sdk/package-metadata/src/lib.rs | 90 +++++++++++++++++++++++++++++++++ 4 files changed, 119 insertions(+) create mode 100644 sdk/package-metadata/Cargo.toml create mode 100644 sdk/package-metadata/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 36274246efb2e9..8a1b90ebafcbc0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6690,6 +6690,14 @@ dependencies = [ "solana-sdk", ] +[[package]] +name = "solana-package-metadata" +version = "2.0.0" +dependencies = [ + "solana-package-metadata-macro", + "solana-program", +] + [[package]] name = "solana-package-metadata-macro" version = "2.0.0" diff --git a/Cargo.toml b/Cargo.toml index 33cfb62a3b95de..68839f2958f18f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -99,6 +99,7 @@ members = [ "sdk/cargo-test-sbf", "sdk/gen-headers", "sdk/macro", + "sdk/package-metadata", "sdk/package-metadata-macro", "sdk/program", "send-transaction-service", @@ -365,6 +366,7 @@ solana-metrics = { path = "metrics", version = "=2.0.0" } solana-net-utils = { path = "net-utils", version = "=2.0.0" } solana-nohash-hasher = "0.2.1" solana-notifier = { path = "notifier", version = "=2.0.0" } +solana-package-metadata = { path = "sdk/package-metadata", version = "=2.0.0" } solana-package-metadata-macro = { path = "sdk/package-metadata-macro", version = "=2.0.0" } solana-perf = { path = "perf", version = "=2.0.0" } solana-poh = { path = "poh", version = "=2.0.0" } diff --git a/sdk/package-metadata/Cargo.toml b/sdk/package-metadata/Cargo.toml new file mode 100644 index 00000000000000..db07908f7487a5 --- /dev/null +++ b/sdk/package-metadata/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "solana-package-metadata" +description = "Solana Package Metadata" +documentation = "https://docs.rs/solana-package-metadata" +version = { workspace = true } +authors = { workspace = true } +repository = { workspace = true } +homepage = { workspace = true } +license = { workspace = true } +edition = { workspace = true } + +[dependencies] +solana-package-metadata-macro = { workspace = true } + +[dev-dependencies] +solana-program = { workspace = true } + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] diff --git a/sdk/package-metadata/src/lib.rs b/sdk/package-metadata/src/lib.rs new file mode 100644 index 00000000000000..4f8d8426dbf2cb --- /dev/null +++ b/sdk/package-metadata/src/lib.rs @@ -0,0 +1,90 @@ +/// Macro for accessing data from the `package.metadata` section of the Cargo manifest +/// +/// # Arguments +/// * `key` - A string slice of a dot-separated path to the TOML key of interest +/// +/// # Example +/// Given the following `Cargo.toml`: +/// ```ignore +/// [package] +/// name = "MyApp" +/// version = "0.1.0" +/// +/// [package.metadata] +/// copyright = "Copyright (c) 2024 ACME Inc." +/// ``` +/// +/// You can fetch the copyright with the following: +/// ```ignore +/// use solana_sdk_macro::package_metadata; +/// +/// pub fn main() { +/// let copyright = package_metadata!("copyright"); +/// assert_eq!(copyright, "Copyright (c) 2024 ACME Inc."); +/// } +/// ``` +/// +/// ## TOML Support +/// This macro only supports static data: +/// * Strings +/// * Integers +/// * Floating-point numbers +/// * Booleans +/// * Datetimes +/// * Arrays +/// +/// ## Array Example +/// Given the following Cargo manifest: +/// ```ignore +/// [package.metadata.arrays] +/// some_array = [ 1, 2, 3 ] +/// ``` +/// +/// This is legal: +/// ```ignore +/// static ARR: [i64; 3] = package_metadata!("arrays.some_array"); +/// ``` +/// +/// It does *not* currently support accessing TOML array elements directly. +/// TOML tables are not supported. +pub use solana_package_metadata_macro::package_metadata; + +/// Convenience macro for declaring a program id from Cargo.toml package metadata. +/// +/// # Arguments +/// * `key` - A string slice of a dot-separated path to the TOML key of interest +/// +/// # Example +/// Given the following `Cargo.toml`: +/// ```ignore +/// [package] +/// name = "my-solana-program" +/// version = "0.1.0" +/// +/// [package.metadata.solana] +/// program-id = "MyProgram1111111111111111111111111111111111" +/// ``` +/// +/// A program can use the program id declared in its `Cargo.toml` as the program +/// id in code: +/// +/// ```ignore +/// declare_id_with_package_metadata!("solana.program-id"); +/// ``` +/// +/// This program id behaves exactly as if the developer had written: +/// +/// ``` +/// solana_program::declare_id!("MyProgram1111111111111111111111111111111111"); +/// ``` +/// +/// Meaning that it's possible to refer to the program id using `crate::id()`, +/// without needing to specify the program id in multiple places. +#[macro_export] +macro_rules! declare_id_with_package_metadata { + ($key:literal) => { + solana_program::declare_id!(solana_program::pubkey::Pubkey::from_str_const( + $crate::package_metadata!($key) + )); + }; +} From cda5c021b011d75eef3f889f2a6922e0d28d5352 Mon Sep 17 00:00:00 2001 From: Jon C Date: Thu, 20 Jun 2024 18:54:40 +0200 Subject: [PATCH 3/3] Use the macro in a program as a test --- programs/sbf/Cargo.lock | 70 +++++++++++++++++++++++-- programs/sbf/Cargo.toml | 1 + programs/sbf/rust/simulation/Cargo.toml | 4 ++ programs/sbf/rust/simulation/src/lib.rs | 3 +- 4 files changed, 73 insertions(+), 5 deletions(-) diff --git a/programs/sbf/Cargo.lock b/programs/sbf/Cargo.lock index 820ba3c8ddd06e..23956da7519ab1 100644 --- a/programs/sbf/Cargo.lock +++ b/programs/sbf/Cargo.lock @@ -3546,7 +3546,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" dependencies = [ - "toml", + "toml 0.5.11", ] [[package]] @@ -3555,7 +3555,7 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" dependencies = [ - "toml_edit", + "toml_edit 0.21.1", ] [[package]] @@ -4270,6 +4270,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -5220,6 +5229,23 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b8a731ed60e89177c8a7ab05fe0f1511cedd3e70e773f288f9de33a9cfdc21e" +[[package]] +name = "solana-package-metadata" +version = "2.0.0" +dependencies = [ + "solana-package-metadata-macro", +] + +[[package]] +name = "solana-package-metadata-macro" +version = "2.0.0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.58", + "toml 0.8.12", +] + [[package]] name = "solana-perf" version = "2.0.0" @@ -6056,6 +6082,7 @@ dependencies = [ name = "solana-sbf-rust-simulation" version = "2.0.0" dependencies = [ + "solana-package-metadata", "solana-program", ] @@ -7387,11 +7414,26 @@ dependencies = [ "serde", ] +[[package]] +name = "toml" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.22.12", +] + [[package]] name = "toml_datetime" version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +dependencies = [ + "serde", +] [[package]] name = "toml_edit" @@ -7401,7 +7443,20 @@ checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ "indexmap 2.2.6", "toml_datetime", - "winnow", + "winnow 0.5.25", +] + +[[package]] +name = "toml_edit" +version = "0.22.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3328d4f68a705b2a4498da1d580585d39a6510f98318a2cec3018a7ec61ddef" +dependencies = [ + "indexmap 2.2.6", + "serde", + "serde_spanned", + "toml_datetime", + "winnow 0.6.13", ] [[package]] @@ -8055,6 +8110,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.50.0" diff --git a/programs/sbf/Cargo.toml b/programs/sbf/Cargo.toml index 742f700bec4a14..5c693ec662940b 100644 --- a/programs/sbf/Cargo.toml +++ b/programs/sbf/Cargo.toml @@ -35,6 +35,7 @@ solana-curve25519 = { path = "../../curves/curve25519", version = "=2.0.0" } solana-ledger = { path = "../../ledger", version = "=2.0.0" } solana-logger = { path = "../../logger", version = "=2.0.0" } solana-measure = { path = "../../measure", version = "=2.0.0" } +solana-package-metadata = { path = "../../sdk/package-metadata", version = "=2.0.0" } solana-poseidon = { path = "../../poseidon/", version = "=2.0.0" } solana-program = { path = "../../sdk/program", version = "=2.0.0" } solana-program-runtime = { path = "../../program-runtime", version = "=2.0.0" } diff --git a/programs/sbf/rust/simulation/Cargo.toml b/programs/sbf/rust/simulation/Cargo.toml index 3fd65622c876a4..40a0bb69d84c08 100644 --- a/programs/sbf/rust/simulation/Cargo.toml +++ b/programs/sbf/rust/simulation/Cargo.toml @@ -9,7 +9,11 @@ license = { workspace = true } edition = { workspace = true } [dependencies] +solana-package-metadata = { workspace = true } solana-program = { workspace = true } [lib] crate-type = ["cdylib"] + +[package.metadata.solana] +program-id = "Sim1jD5C35odT8mzctm8BWnjic8xW5xgeb5MbcbErTo" diff --git a/programs/sbf/rust/simulation/src/lib.rs b/programs/sbf/rust/simulation/src/lib.rs index 843a842ec4081d..4e281b392a402c 100644 --- a/programs/sbf/rust/simulation/src/lib.rs +++ b/programs/sbf/rust/simulation/src/lib.rs @@ -4,7 +4,6 @@ use { solana_program::{ account_info::{next_account_info, AccountInfo}, clock::Clock, - declare_id, entrypoint::ProgramResult, msg, pubkey::Pubkey, @@ -13,7 +12,7 @@ use { std::convert::TryInto, }; -declare_id!("Sim1jD5C35odT8mzctm8BWnjic8xW5xgeb5MbcbErTo"); +solana_package_metadata::declare_id_with_package_metadata!("solana.program-id"); solana_program::entrypoint!(process_instruction);