Skip to content

Commit

Permalink
Add interface crate features (#25)
Browse files Browse the repository at this point in the history
* Add crate features

* Move constants

* Add crate to dev-dependency
  • Loading branch information
febo authored Nov 20, 2024
1 parent 1cab018 commit 1d1f1c4
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 50 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

11 changes: 7 additions & 4 deletions interface/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ rustdoc-args = ["--cfg=docsrs"]

[dependencies]
num-traits = "0.2"
serde = "1.0.210"
serde_derive = "1.0.210"
serde = { version = "1.0.210", optional = true }
serde_derive = { version = "1.0.210", optional = true }
solana-decode-error = "^2.1"
solana-frozen-abi = { version = "^2.1", features = ["frozen-abi"], optional = true }
solana-frozen-abi-macro = { version = "^2.1", features = ["frozen-abi"], optional = true }
solana-instruction = { version = "^2.1", features = ["bincode", "std"] }
solana-instruction = { version = "^2.1", features = ["bincode", "std"], optional = true }
solana-logger = { version = "^2.1", optional = true }
solana-pubkey = { version = "^2.1", default-features = false, features = ["serde"] }
solana-pubkey = { version = "^2.1", default-features = false }

[target.'cfg(target_arch = "wasm32")'.dependencies]
js-sys = "0.3.72"
Expand All @@ -37,15 +37,18 @@ solana-program = { version = "^2.1", default-features = false }
solana-program-entrypoint = "^2.1"
solana-program-error = { version = "^2.1", features = ["borsh"] }
solana-pubkey = { version = "^2.1", features = ["std"] }
solana-system-interface = { path = ".", features = ["bincode"] }
static_assertions = "1.1.0"
strum = "0.24"
strum_macros = "0.24"

[features]
bincode = ["dep:solana-instruction", "serde"]
frozen-abi = [
"dep:solana-frozen-abi",
"dep:solana-frozen-abi-macro",
"dep:solana-logger",
"solana-pubkey/frozen-abi",
"solana-pubkey/std"
]
serde = ["dep:serde", "dep:serde_derive", "solana-pubkey/serde"]
7 changes: 5 additions & 2 deletions interface/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use num_traits::{FromPrimitive, ToPrimitive};
use serde_derive::{Deserialize, Serialize};
use solana_decode_error::DecodeError;

// Use strum when testing to ensure our FromPrimitive
// impl is exhaustive
#[cfg_attr(test, derive(strum_macros::FromRepr, strum_macros::EnumIter))]
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Deserialize, serde_derive::Serialize)
)]
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum SystemError {
/// An account with the same address already exists.
AccountAlreadyInUse,
Expand Down
64 changes: 59 additions & 5 deletions interface/src/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,31 @@
//! [`invoke_signed`]: https://docs.rs/solana-cpi/latest/solana_cpi/fn.invoke_signed.html
//! [`AccountInfo`]: https://docs.rs/solana-account-info/latest/solana_account_info/struct.AccountInfo.html
use serde_derive::{Deserialize, Serialize};
use solana_instruction::{AccountMeta, Instruction};
use solana_pubkey::Pubkey;
#[cfg(feature = "bincode")]
use {
crate::program::ID,
solana_instruction::{AccountMeta, Instruction},
};

use crate::{program::ID, NONCE_STATE_SIZE, RECENT_BLOCKHASHES_ID, RENT_ID};
// Inline some constants to avoid dependencies.
//
// Note: replace these inline IDs with the corresponding value from
// `solana_sdk_ids` once the version is updated to 2.2.0.

#[cfg(feature = "bincode")]
const RECENT_BLOCKHASHES_ID: Pubkey =
Pubkey::from_str_const("SysvarRecentB1ockHashes11111111111111111111");

#[cfg(feature = "bincode")]
const RENT_ID: Pubkey = Pubkey::from_str_const("SysvarRent111111111111111111111111111111111");

#[cfg(feature = "bincode")]
#[cfg(test)]
static_assertions::const_assert_eq!(solana_nonce::state::State::size(), NONCE_STATE_SIZE);
/// The serialized size of the nonce state.
#[cfg(feature = "bincode")]
const NONCE_STATE_SIZE: usize = 80;

/// An instruction to the system program.
#[cfg_attr(
Expand All @@ -52,7 +72,11 @@ use crate::{program::ID, NONCE_STATE_SIZE, RECENT_BLOCKHASHES_ID, RENT_ID};
solana_frozen_abi_macro::AbiEnumVisitor
)
)]
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Deserialize, serde_derive::Serialize)
)]
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum SystemInstruction {
/// Create a new account
///
Expand Down Expand Up @@ -378,6 +402,7 @@ pub enum SystemInstruction {
/// Ok(())
/// }
/// ```
#[cfg(feature = "bincode")]
pub fn create_account(
from_pubkey: &Pubkey,
to_pubkey: &Pubkey,
Expand All @@ -402,6 +427,7 @@ pub fn create_account(

// we accept `to` as a parameter so that callers do their own error handling when
// calling create_with_seed()
#[cfg(feature = "bincode")]
pub fn create_account_with_seed(
from_pubkey: &Pubkey,
to_pubkey: &Pubkey, // must match create_with_seed(base, seed, owner)
Expand Down Expand Up @@ -591,6 +617,7 @@ pub fn create_account_with_seed(
/// Ok(())
/// }
/// ```
#[cfg(feature = "bincode")]
pub fn assign(pubkey: &Pubkey, owner: &Pubkey) -> Instruction {
let account_metas = vec![AccountMeta::new(*pubkey, true)];
Instruction::new_with_bincode(
Expand All @@ -600,6 +627,7 @@ pub fn assign(pubkey: &Pubkey, owner: &Pubkey) -> Instruction {
)
}

#[cfg(feature = "bincode")]
pub fn assign_with_seed(
address: &Pubkey, // must match create_with_seed(base, seed, owner)
base: &Pubkey,
Expand Down Expand Up @@ -783,6 +811,7 @@ pub fn assign_with_seed(
/// Ok(())
/// }
/// ```
#[cfg(feature = "bincode")]
pub fn transfer(from_pubkey: &Pubkey, to_pubkey: &Pubkey, lamports: u64) -> Instruction {
let account_metas = vec![
AccountMeta::new(*from_pubkey, true),
Expand All @@ -791,6 +820,7 @@ pub fn transfer(from_pubkey: &Pubkey, to_pubkey: &Pubkey, lamports: u64) -> Inst
Instruction::new_with_bincode(ID, &SystemInstruction::Transfer { lamports }, account_metas)
}

#[cfg(feature = "bincode")]
pub fn transfer_with_seed(
from_pubkey: &Pubkey, // must match create_with_seed(base, seed, owner)
from_base: &Pubkey,
Expand Down Expand Up @@ -979,11 +1009,13 @@ pub fn transfer_with_seed(
/// Ok(())
/// }
/// ```
#[cfg(feature = "bincode")]
pub fn allocate(pubkey: &Pubkey, space: u64) -> Instruction {
let account_metas = vec![AccountMeta::new(*pubkey, true)];
Instruction::new_with_bincode(ID, &SystemInstruction::Allocate { space }, account_metas)
}

#[cfg(feature = "bincode")]
pub fn allocate_with_seed(
address: &Pubkey, // must match create_with_seed(base, seed, owner)
base: &Pubkey,
Expand Down Expand Up @@ -1142,13 +1174,15 @@ pub fn allocate_with_seed(
/// Ok(())
/// }
/// ```
#[cfg(feature = "bincode")]
pub fn transfer_many(from_pubkey: &Pubkey, to_lamports: &[(Pubkey, u64)]) -> Vec<Instruction> {
to_lamports
.iter()
.map(|(to_pubkey, lamports)| transfer(from_pubkey, to_pubkey, *lamports))
.collect()
}

#[cfg(feature = "bincode")]
pub fn create_nonce_account_with_seed(
from_pubkey: &Pubkey,
nonce_pubkey: &Pubkey,
Expand Down Expand Up @@ -1290,6 +1324,7 @@ pub fn create_nonce_account_with_seed(
/// #
/// # Ok::<(), anyhow::Error>(())
/// ```
#[cfg(feature = "bincode")]
pub fn create_nonce_account(
from_pubkey: &Pubkey,
nonce_pubkey: &Pubkey,
Expand Down Expand Up @@ -1439,6 +1474,7 @@ pub fn create_nonce_account(
/// #
/// # Ok::<(), anyhow::Error>(())
/// ```
#[cfg(feature = "bincode")]
pub fn advance_nonce_account(nonce_pubkey: &Pubkey, authorized_pubkey: &Pubkey) -> Instruction {
let account_metas = vec![
AccountMeta::new(*nonce_pubkey, false),
Expand Down Expand Up @@ -1521,6 +1557,7 @@ pub fn advance_nonce_account(nonce_pubkey: &Pubkey, authorized_pubkey: &Pubkey)
/// #
/// # Ok::<(), anyhow::Error>(())
/// ```
#[cfg(feature = "bincode")]
pub fn withdraw_nonce_account(
nonce_pubkey: &Pubkey,
authorized_pubkey: &Pubkey,
Expand Down Expand Up @@ -1603,6 +1640,7 @@ pub fn withdraw_nonce_account(
/// #
/// # Ok::<(), anyhow::Error>(())
/// ```
#[cfg(feature = "bincode")]
pub fn authorize_nonce_account(
nonce_pubkey: &Pubkey,
authorized_pubkey: &Pubkey,
Expand All @@ -1621,19 +1659,35 @@ pub fn authorize_nonce_account(

/// One-time idempotent upgrade of legacy nonce versions in order to bump
/// them out of chain blockhash domain.
#[cfg(feature = "bincode")]
pub fn upgrade_nonce_account(nonce_pubkey: Pubkey) -> Instruction {
let account_metas = vec![AccountMeta::new(nonce_pubkey, /*is_signer:*/ false)];
Instruction::new_with_bincode(ID, &SystemInstruction::UpgradeNonceAccount, account_metas)
}

#[cfg(feature = "bincode")]
#[cfg(test)]
mod tests {
use super::*;
use solana_program::sysvar::SysvarId;

fn get_keys(instruction: &Instruction) -> Vec<Pubkey> {
instruction.accounts.iter().map(|x| x.pubkey).collect()
}

#[allow(deprecated)]
#[test]
fn test_constants() {
// Ensure that the constants are in sync with the solana program.
assert_eq!(
RECENT_BLOCKHASHES_ID,
solana_program::sysvar::recent_blockhashes::RecentBlockhashes::id(),
);

// Ensure that the constants are in sync with the solana rent.
assert_eq!(RENT_ID, solana_program::sysvar::rent::Rent::id());
}

#[test]
fn test_move_many() {
let alice_pubkey = Pubkey::new_unique();
Expand All @@ -1655,7 +1709,7 @@ mod tests {
let ixs = create_nonce_account(&from_pubkey, &nonce_pubkey, &authorized, 42);
assert_eq!(ixs.len(), 2);
let ix = &ixs[0];
assert_eq!(ix.program_id, ID);
assert_eq!(ix.program_id, crate::program::ID);
let pubkeys: Vec<_> = ix.accounts.iter().map(|am| am.pubkey).collect();
assert!(pubkeys.contains(&from_pubkey));
assert!(pubkeys.contains(&nonce_pubkey));
Expand Down
40 changes: 1 addition & 39 deletions interface/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,6 @@ pub mod instruction;
#[cfg(target_arch = "wasm32")]
mod wasm;

use solana_pubkey::Pubkey;

// Inline some constants to avoid dependencies.
//
// Note: replace these inline IDs with the corresponding value from
// `solana_sdk_ids` once the version is updated to 2.2.0.

const RECENT_BLOCKHASHES_ID: Pubkey =
Pubkey::from_str_const("SysvarRecentB1ockHashes11111111111111111111");

const RENT_ID: Pubkey = Pubkey::from_str_const("SysvarRent111111111111111111111111111111111");

#[cfg(test)]
static_assertions::const_assert_eq!(solana_nonce::state::State::size(), NONCE_STATE_SIZE);
/// The serialized size of the nonce state.
const NONCE_STATE_SIZE: usize = 80;

#[cfg(test)]
static_assertions::const_assert!(MAX_PERMITTED_DATA_LENGTH <= u32::MAX as u64);
/// Maximum permitted size of account data (10 MiB).
Expand All @@ -44,26 +27,5 @@ pub const MAX_PERMITTED_ACCOUNTS_DATA_ALLOCATIONS_PER_TRANSACTION: i64 =
MAX_PERMITTED_DATA_LENGTH as i64 * 2;

pub mod program {
use solana_pubkey::declare_id;

declare_id!("11111111111111111111111111111111");
}

#[cfg(test)]
mod tests {
use super::*;
use solana_program::sysvar::SysvarId;

#[allow(deprecated)]
#[test]
fn test_constants() {
// Ensure that the constants are in sync with the solana program.
assert_eq!(
RECENT_BLOCKHASHES_ID,
solana_program::sysvar::recent_blockhashes::RecentBlockhashes::id(),
);

// Ensure that the constants are in sync with the solana rent.
assert_eq!(RENT_ID, solana_program::sysvar::rent::Rent::id());
}
solana_pubkey::declare_id!("11111111111111111111111111111111");
}

0 comments on commit 1d1f1c4

Please sign in to comment.