Переглянути джерело

Move secp256k1_recover to its own crate (#1656)

* move secp256k1_recover to its own crate

* move syscall definition

* remove libsecp256k1 dep from solana-program

* update sbf lock file

* update doc links

* fix doc tests and dev deps

* update deps in programs/sbf

* fmt

* add frozen-abi support

* update lock files

* use borsh directly in solana-secp256k1-recover dev deps

* re-export solana_secp256k1_recover with deprecation

* re-export in solana-program too

* use define_syscall macro now that it's available as a standalone crate

* fix macro import

* only require solana-define-syscall when target_os = "solana"

* re-export sol_secp256k1_recover with deprecation warning

* add docs.rs metadata

* don't compile doc examples to get around false positive in order-crates-for-publishing.py

* fmt

* fix AbiExample duplication

* Revert "fix AbiExample duplication"

This reverts commit 86e8671f8def10ff32d1dbcf1d6f80405e1e86f1.

* fix frozen-abi usage
Kevin Heavey 1 рік тому
батько
коміт
d809bd9851

+ 16 - 0
Cargo.lock

@@ -6833,6 +6833,7 @@ dependencies = [
  "solana-logger",
  "solana-sanitize",
  "solana-sdk-macro",
+ "solana-secp256k1-recover",
  "static_assertions",
  "thiserror",
  "wasm-bindgen",
@@ -7303,6 +7304,7 @@ dependencies = [
  "solana-sanitize",
  "solana-sdk",
  "solana-sdk-macro",
+ "solana-secp256k1-recover",
  "static_assertions",
  "thiserror",
  "tiny-bip39",
@@ -7320,6 +7322,20 @@ dependencies = [
  "syn 2.0.71",
 ]
 
+[[package]]
+name = "solana-secp256k1-recover"
+version = "2.1.0"
+dependencies = [
+ "anyhow",
+ "borsh 1.5.1",
+ "libsecp256k1",
+ "rustc_version 0.4.0",
+ "solana-define-syscall",
+ "solana-frozen-abi",
+ "solana-frozen-abi-macro",
+ "thiserror",
+]
+
 [[package]]
 name = "solana-security-txt"
 version = "1.1.1"

+ 1 - 0
Cargo.toml

@@ -397,6 +397,7 @@ solana-runtime = { path = "runtime", version = "=2.1.0" }
 solana-runtime-transaction = { path = "runtime-transaction", version = "=2.1.0" }
 solana-sdk = { path = "sdk", version = "=2.1.0" }
 solana-sdk-macro = { path = "sdk/macro", version = "=2.1.0" }
+solana-secp256k1-recover = { path = "curves/secp256k1-recover", version = "=2.1.0", default-features = false }
 solana-send-transaction-service = { path = "send-transaction-service", version = "=2.1.0" }
 solana-stake-program = { path = "programs/stake", version = "=2.1.0" }
 solana-storage-bigtable = { path = "storage-bigtable", version = "=2.1.0" }

+ 39 - 0
curves/secp256k1-recover/Cargo.toml

@@ -0,0 +1,39 @@
+[package]
+name = "solana-secp256k1-recover"
+description = "Solana SECP256K1 Recover"
+documentation = "https://docs.rs/solana-secp256k1-recover"
+version = { workspace = true }
+authors = { workspace = true }
+repository = { workspace = true }
+homepage = { workspace = true }
+license = { workspace = true }
+edition = { workspace = true }
+
+[dependencies]
+borsh = { workspace = true, optional = true }
+solana-frozen-abi = { workspace = true, optional = true }
+solana-frozen-abi-macro = { workspace = true, optional = true }
+thiserror = { workspace = true }
+
+[target.'cfg(target_os = "solana")'.dependencies]
+solana-define-syscall = { workspace = true }
+
+[target.'cfg(not(target_os = "solana"))'.dependencies]
+libsecp256k1 = { workspace = true }
+
+[dev-dependencies]
+anyhow = { workspace = true }
+borsh = { workspace = true }
+
+[target.'cfg(not(target_os = "solana"))'.dev-dependencies]
+libsecp256k1 = { workspace = true, features = ["hmac"] }
+
+[build-dependencies]
+rustc_version = { workspace = true }
+
+[features]
+borsh = ["dep:borsh"]
+frozen-abi = ["dep:solana-frozen-abi", "dep:solana-frozen-abi-macro"]
+
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]

+ 1 - 0
curves/secp256k1-recover/build.rs

@@ -0,0 +1 @@
+../../frozen-abi/build.rs

+ 13 - 9
sdk/program/src/secp256k1_recover.rs → curves/secp256k1-recover/src/lib.rs

@@ -1,3 +1,4 @@
+#![cfg_attr(RUSTC_WITH_SPECIALIZATION, feature(min_specialization))]
 //! Public key recovery from [secp256k1] ECDSA signatures.
 //!
 //! [secp256k1]: https://en.bitcoin.it/wiki/Secp256k1
@@ -21,7 +22,7 @@
 //! also provides the [secp256k1 program][sp], which is more flexible, has lower CPU
 //! cost, and can validate many signatures at once.
 //!
-//! [sp]: crate::secp256k1_program
+//! [sp]: https://docs.rs/solana-program/latest/solana_program/secp256k1_program/
 //! [`ecrecover`]: https://docs.soliditylang.org/en/v0.8.14/units-and-global-variables.html?highlight=ecrecover#mathematical-and-cryptographic-functions
 
 #[cfg(feature = "borsh")]
@@ -63,7 +64,7 @@ pub const SECP256K1_SIGNATURE_LENGTH: usize = 64;
 pub const SECP256K1_PUBLIC_KEY_LENGTH: usize = 64;
 
 #[repr(transparent)]
-#[cfg_attr(feature = "frozen-abi", derive(AbiExample))]
+#[cfg_attr(feature = "frozen-abi", derive(solana_frozen_abi_macro::AbiExample))]
 #[cfg_attr(
     feature = "borsh",
     derive(BorshSerialize, BorshDeserialize, BorshSchema),
@@ -85,6 +86,9 @@ impl Secp256k1Pubkey {
     }
 }
 
+#[cfg(target_os = "solana")]
+solana_define_syscall::define_syscall!(fn sol_secp256k1_recover(hash: *const u8, recovery_id: u64, signature: *const u8, result: *mut u8) -> u64);
+
 /// Recover the public key from a [secp256k1] ECDSA signature and
 /// cryptographically-hashed message.
 ///
@@ -110,7 +114,7 @@ impl Secp256k1Pubkey {
 /// "overflowing" signature, and this function returns an error when parsing
 /// overflowing signatures.
 ///
-/// [`keccak`]: crate::keccak
+/// [`keccak`]: https://docs.rs/solana-program/latest/solana_program/keccak/
 /// [`wrapping_sub`]: https://doc.rust-lang.org/std/primitive.u8.html#method.wrapping_sub
 ///
 /// On success this function returns a [`Secp256k1Pubkey`], a wrapper around a
@@ -123,7 +127,7 @@ impl Secp256k1Pubkey {
 /// the [secp256k1 program][sp], which is more flexible, has lower CPU cost, and
 /// can validate many signatures at once.
 ///
-/// [sp]: crate::secp256k1_program
+/// [sp]: https://docs.rs/solana-program/latest/solana_program/secp256k1_program/
 ///
 /// The `secp256k1_recover` syscall is implemented with the [`libsecp256k1`]
 /// crate, which clients may also want to use.
@@ -161,7 +165,7 @@ impl Secp256k1Pubkey {
 /// signatures with high-order `S` values. The following code will accomplish
 /// this:
 ///
-/// ```rust
+/// ```rust,ignore
 /// # use solana_program::program_error::ProgramError;
 /// # let signature_bytes = [
 /// #     0x83, 0x55, 0x81, 0xDF, 0xB1, 0x02, 0xA7, 0xD2,
@@ -257,13 +261,13 @@ impl Secp256k1Pubkey {
 /// The Solana program. Note that it uses `libsecp256k1` version 0.7.0 to parse
 /// the secp256k1 signature to prevent malleability.
 ///
-/// ```no_run
+/// ```rust,ignore
 /// use solana_program::{
 ///     entrypoint::ProgramResult,
 ///     keccak, msg,
 ///     program_error::ProgramError,
-///     secp256k1_recover::secp256k1_recover,
 /// };
+/// use solana_secp256k1_recover::secp256k1_recover;
 ///
 /// /// The key we expect to sign secp256k1 messages,
 /// /// as serialized by `libsecp256k1::PublicKey::serialize`.
@@ -327,7 +331,7 @@ impl Secp256k1Pubkey {
 ///
 /// The RPC client program:
 ///
-/// ```no_run
+/// ```rust,ignore
 /// # use solana_program::example_mocks::solana_rpc_client;
 /// # use solana_program::example_mocks::solana_sdk;
 /// use anyhow::Result;
@@ -399,7 +403,7 @@ pub fn secp256k1_recover(
     {
         let mut pubkey_buffer = [0u8; SECP256K1_PUBLIC_KEY_LENGTH];
         let result = unsafe {
-            crate::syscalls::sol_secp256k1_recover(
+            sol_secp256k1_recover(
                 hash.as_ptr(),
                 recovery_id as u64,
                 signature.as_ptr(),

+ 14 - 1
programs/sbf/Cargo.lock

@@ -5295,7 +5295,6 @@ dependencies = [
  "getrandom 0.2.10",
  "js-sys",
  "lazy_static",
- "libsecp256k1 0.6.0",
  "log",
  "memoffset 0.9.0",
  "num-bigint 0.4.6",
@@ -5313,6 +5312,7 @@ dependencies = [
  "solana-define-syscall",
  "solana-sanitize",
  "solana-sdk-macro",
+ "solana-secp256k1-recover",
  "thiserror",
  "wasm-bindgen",
 ]
@@ -6042,6 +6042,7 @@ version = "2.1.0"
 dependencies = [
  "libsecp256k1 0.7.0",
  "solana-program",
+ "solana-secp256k1-recover",
 ]
 
 [[package]]
@@ -6151,6 +6152,7 @@ dependencies = [
  "solana-program",
  "solana-sanitize",
  "solana-sdk-macro",
+ "solana-secp256k1-recover",
  "thiserror",
  "uriparse",
  "wasm-bindgen",
@@ -6166,6 +6168,17 @@ dependencies = [
  "syn 2.0.58",
 ]
 
+[[package]]
+name = "solana-secp256k1-recover"
+version = "2.1.0"
+dependencies = [
+ "borsh 1.5.1",
+ "libsecp256k1 0.6.0",
+ "rustc_version",
+ "solana-define-syscall",
+ "thiserror",
+]
+
 [[package]]
 name = "solana-security-txt"
 version = "1.1.1"

+ 1 - 0
programs/sbf/Cargo.toml

@@ -48,6 +48,7 @@ solana-sbf-rust-param-passing-dep = { path = "rust/param_passing_dep", version =
 solana-sbf-rust-realloc-dep = { path = "rust/realloc_dep", version = "=2.1.0" }
 solana-sbf-rust-realloc-invoke-dep = { path = "rust/realloc_invoke_dep", version = "=2.1.0" }
 solana-sdk = { path = "../../sdk", version = "=2.1.0" }
+solana-secp256k1-recover = { path = "../../curves/secp256k1-recover", version = "=2.1.0" }
 solana-svm = { path = "../../svm", version = "=2.1.0" }
 solana-timings = { path = "../../timings", version = "=2.1.0" }
 solana-transaction-status = { path = "../../transaction-status", version = "=2.1.0" }

+ 1 - 0
programs/sbf/rust/secp256k1_recover/Cargo.toml

@@ -11,6 +11,7 @@ edition = { workspace = true }
 [dependencies]
 libsecp256k1 = { workspace = true }
 solana-program = { workspace = true }
+solana-secp256k1-recover = { workspace = true }
 
 [lib]
 crate-type = ["cdylib"]

+ 3 - 2
programs/sbf/rust/secp256k1_recover/src/lib.rs

@@ -2,8 +2,9 @@
 //! Secp256k1Recover Syscall test
 
 extern crate solana_program;
-use solana_program::{
-    custom_heap_default, custom_panic_default, msg, secp256k1_recover::secp256k1_recover,
+use {
+    solana_program::{custom_heap_default, custom_panic_default, msg},
+    solana_secp256k1_recover::secp256k1_recover,
 };
 
 fn test_secp256k1_recover() {

+ 2 - 1
sdk/Cargo.toml

@@ -34,7 +34,7 @@ full = [
     "sha3",
     "digest",
 ]
-borsh = ["dep:borsh", "solana-program/borsh"]
+borsh = ["dep:borsh", "solana-program/borsh", "solana-secp256k1-recover/borsh"]
 dev-context-only-utils = [
   "qualifier_attr"
 ]
@@ -84,6 +84,7 @@ solana-frozen-abi-macro = { workspace = true, optional = true }
 solana-program = { workspace = true }
 solana-sanitize = { workspace = true }
 solana-sdk-macro = { workspace = true }
+solana-secp256k1-recover = { workspace = true }
 thiserror = { workspace = true }
 uriparse = { workspace = true }
 

+ 1 - 1
sdk/program/Cargo.toml

@@ -36,6 +36,7 @@ solana-frozen-abi = { workspace = true, optional = true }
 solana-frozen-abi-macro = { workspace = true, optional = true }
 solana-sanitize = { workspace = true }
 solana-sdk-macro = { workspace = true }
+solana-secp256k1-recover = { workspace = true }
 thiserror = { workspace = true }
 
 # This is currently needed to build on-chain programs reliably.
@@ -56,7 +57,6 @@ ark-serialize = { workspace = true }
 base64 = { workspace = true, features = ["alloc", "std"] }
 bitflags = { workspace = true }
 curve25519-dalek = { workspace = true }
-libsecp256k1 = { workspace = true }
 num-bigint = { workspace = true }
 rand = { workspace = true }
 

+ 2 - 1
sdk/program/src/lib.rs

@@ -519,7 +519,6 @@ pub mod program_utils;
 pub mod pubkey;
 pub mod rent;
 pub mod secp256k1_program;
-pub mod secp256k1_recover;
 pub mod serde_varint;
 pub mod serialize_utils;
 pub mod short_vec;
@@ -537,6 +536,8 @@ pub mod wasm;
 
 #[deprecated(since = "2.1.0", note = "Use `solana-sanitize` crate instead")]
 pub use solana_sanitize as sanitize;
+#[deprecated(since = "2.1.0", note = "Use `solana-secp256k1-recover` crate instead")]
+pub use solana_secp256k1_recover as secp256k1_recover;
 #[cfg(target_arch = "wasm32")]
 pub use wasm_bindgen::prelude::wasm_bindgen;
 

+ 5 - 1
sdk/program/src/syscalls/definitions.rs

@@ -1,5 +1,10 @@
 #[cfg(target_feature = "static-syscalls")]
 pub use solana_define_syscall::sys_hash;
+#[deprecated(
+    since = "2.1.0",
+    note = "Use `solana_secp256k1_recover::sol_secp256k1_recover` instead"
+)]
+pub use solana_secp256k1_recover::sol_secp256k1_recover;
 use {
     crate::{
         instruction::{AccountMeta, ProcessedSiblingInstruction},
@@ -16,7 +21,6 @@ define_syscall!(fn sol_create_program_address(seeds_addr: *const u8, seeds_len:
 define_syscall!(fn sol_try_find_program_address(seeds_addr: *const u8, seeds_len: u64, program_id_addr: *const u8, address_bytes_addr: *const u8, bump_seed_addr: *const u8) -> u64);
 define_syscall!(fn sol_sha256(vals: *const u8, val_len: u64, hash_result: *mut u8) -> u64);
 define_syscall!(fn sol_keccak256(vals: *const u8, val_len: u64, hash_result: *mut u8) -> u64);
-define_syscall!(fn sol_secp256k1_recover(hash: *const u8, recovery_id: u64, signature: *const u8, result: *mut u8) -> u64);
 define_syscall!(fn sol_blake3(vals: *const u8, val_len: u64, hash_result: *mut u8) -> u64);
 define_syscall!(fn sol_memcpy_(dst: *mut u8, src: *const u8, n: u64));
 define_syscall!(fn sol_memmove_(dst: *mut u8, src: *const u8, n: u64));

+ 5 - 4
sdk/src/lib.rs

@@ -52,10 +52,9 @@ pub use solana_program::{
     decode_error, ed25519_program, epoch_rewards, epoch_schedule, fee_calculator, impl_sysvar_get,
     incinerator, instruction, keccak, lamports, loader_instruction, loader_upgradeable_instruction,
     loader_v4, loader_v4_instruction, message, msg, native_token, nonce, program, program_error,
-    program_memory, program_option, program_pack, rent, secp256k1_program, secp256k1_recover,
-    serde_varint, serialize_utils, short_vec, slot_hashes, slot_history, stable_layout, stake,
-    stake_history, syscalls, system_instruction, system_program, sysvar, unchecked_div_by_const,
-    vote,
+    program_memory, program_option, program_pack, rent, secp256k1_program, serde_varint,
+    serialize_utils, short_vec, slot_hashes, slot_history, stable_layout, stake, stake_history,
+    syscalls, system_instruction, system_program, sysvar, unchecked_div_by_const, vote,
 };
 #[cfg(feature = "borsh")]
 pub use solana_program::{borsh, borsh0_10, borsh1};
@@ -155,6 +154,8 @@ pub use solana_sdk_macro::declare_id;
 pub use solana_sdk_macro::pubkey;
 /// Convenience macro to define multiple static public keys.
 pub use solana_sdk_macro::pubkeys;
+#[deprecated(since = "2.1.0", note = "Use `solana-secp256k1-recover` crate instead")]
+pub use solana_secp256k1_recover as secp256k1_recover;
 
 /// Convenience macro for `AddAssign` with saturating arithmetic.
 /// Replace by `std::num::Saturating` once stable