Skip to content

Commit ba02efe

Browse files
Add interface crate (#47)
* add interface crate * use solana-config-interface in solana-config-program * rename config_instruction to instruction * explicit feature activation * move to state.rs * remove code no longer required externally * client: deprecate instructions_bincode --------- Co-authored-by: Joe Caulfield <[email protected]>
1 parent a3bd8fa commit ba02efe

File tree

15 files changed

+170
-80
lines changed

15 files changed

+170
-80
lines changed

Cargo.lock

Lines changed: 17 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
[workspace]
22
resolver = "2"
3-
members = ["clients/rust", "program"]
3+
members = [
4+
"clients/rust",
5+
"interface",
6+
"program",
7+
]
48

59
[workspace.package]
610
authors = ["Anza Technology Maintainers <[email protected]>"]
@@ -28,7 +32,15 @@ mollusk-svm-bencher = "0.1.3"
2832
num-derive = "0.4"
2933
num-traits = "0.2"
3034
serde = "1.0.193"
35+
serde_derive = "1.0.193"
36+
solana-account = "2.2.1"
3137
solana-client = "2.2.1"
38+
solana-config-interface = { path = "interface", version = "1.0.0" }
39+
solana-instruction = "2.2.1"
3240
solana-program = "2.2.1"
41+
solana-pubkey = "2.2.1"
3342
solana-sdk = "2.2.1"
43+
solana-sdk-ids = "2.2.1"
44+
solana-short-vec = "2.2.1"
45+
solana-system-interface = "1.0.0"
3446
thiserror = "1.0.61"

clients/rust/Cargo.toml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,13 @@ edition = { workspace = true }
1010

1111
[features]
1212
fetch = ["dep:solana-client", "dep:solana-sdk"]
13-
serde = ["dep:bincode", "dep:serde", "kaigan/serde"]
13+
serde = [
14+
"dep:bincode",
15+
"dep:serde",
16+
"dep:solana-config-interface",
17+
"kaigan/serde",
18+
"solana-config-interface/bincode"
19+
]
1420
test-sbf = []
1521

1622
[dependencies]
@@ -19,6 +25,7 @@ borsh = { workspace = true }
1925
kaigan = { workspace = true }
2026
serde = { workspace = true, features = ["derive"], optional = true }
2127
solana-client = { workspace = true, optional = true }
28+
solana-config-interface = { workspace = true, optional = true }
2229
solana-program = { workspace = true, features = ["borsh"] }
2330
solana-sdk = { workspace = true, optional = true }
2431

Lines changed: 2 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,7 @@
11
//! Program instruction helpers.
22
3-
use {
4-
crate::{ConfigKeys, ID},
5-
bincode::serialized_size,
6-
solana_program::{
7-
instruction::{AccountMeta, Instruction},
8-
pubkey::Pubkey,
9-
system_instruction,
10-
},
11-
};
3+
pub use solana_config_interface::instruction::{create_account_with_max_config_space, store};
4+
use solana_program::{instruction::Instruction, pubkey::Pubkey};
125

136
/// Trait defining config state to be stored at the end of the account data.
147
#[deprecated(since = "1.0.0", note = "This trait is no longer supported")]
@@ -17,12 +10,6 @@ pub trait ConfigState: serde::Serialize + Default {
1710
fn max_space() -> u64;
1811
}
1912

20-
fn initialize_account<T: Default + serde::Serialize>(config_pubkey: &Pubkey) -> Instruction {
21-
let account_metas = vec![AccountMeta::new(*config_pubkey, true)];
22-
let account_data = (ConfigKeys { keys: vec![] }, T::default());
23-
Instruction::new_with_bincode(ID, &account_data, account_metas)
24-
}
25-
2613
/// Create a new, empty configuration account
2714
#[deprecated(
2815
since = "1.0.0",
@@ -43,41 +30,3 @@ pub fn create_account<T: ConfigState>(
4330
keys,
4431
)
4532
}
46-
47-
/// Create a new, empty configuration account
48-
pub fn create_account_with_max_config_space<T: Default + serde::Serialize>(
49-
from_account_pubkey: &Pubkey,
50-
config_account_pubkey: &Pubkey,
51-
lamports: u64,
52-
max_config_space: u64,
53-
keys: Vec<(Pubkey, bool)>,
54-
) -> Vec<Instruction> {
55-
let space = max_config_space.saturating_add(serialized_size(&ConfigKeys { keys }).unwrap());
56-
vec![
57-
system_instruction::create_account(
58-
from_account_pubkey,
59-
config_account_pubkey,
60-
lamports,
61-
space,
62-
&ID,
63-
),
64-
initialize_account::<T>(config_account_pubkey),
65-
]
66-
}
67-
68-
/// Store new data in a configuration account
69-
pub fn store<T: serde::Serialize>(
70-
config_account_pubkey: &Pubkey,
71-
is_config_signer: bool,
72-
keys: Vec<(Pubkey, bool)>,
73-
data: &T,
74-
) -> Instruction {
75-
let mut account_metas = vec![AccountMeta::new(*config_account_pubkey, is_config_signer)];
76-
for (signer_pubkey, _) in keys.iter().filter(|(_, is_signer)| *is_signer) {
77-
if signer_pubkey != config_account_pubkey {
78-
account_metas.push(AccountMeta::new(*signer_pubkey, true));
79-
}
80-
}
81-
let account_data = (ConfigKeys { keys }, data);
82-
Instruction::new_with_bincode(ID, &account_data, account_metas)
83-
}

clients/rust/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
mod generated;
44
mod hooked;
5-
5+
#[deprecated(since = "1.0.0", note = "use `solana_config_interface` crate instead")]
66
#[cfg(feature = "serde")]
77
pub mod instructions_bincode;
88

interface/Cargo.toml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
[package]
2+
name = "solana-config-interface"
3+
description = "Solana config program interface."
4+
documentation = "https://docs.rs/solana-config-interface"
5+
version = "1.0.0"
6+
authors = { workspace = true }
7+
repository = { workspace = true }
8+
license-file = { workspace = true }
9+
edition = { workspace = true }
10+
11+
[dependencies]
12+
bincode = { workspace = true, optional = true }
13+
serde = { workspace = true, optional = true }
14+
serde_derive = { workspace = true, optional = true }
15+
solana-account = { workspace = true, optional = true }
16+
solana-instruction = { workspace = true, optional = true, features = [
17+
"bincode",
18+
] }
19+
solana-pubkey = { workspace = true }
20+
solana-sdk-ids = { workspace = true }
21+
solana-short-vec = { workspace = true, optional = true }
22+
solana-system-interface = { workspace = true, optional = true, features = [
23+
"bincode",
24+
] }
25+
26+
[features]
27+
bincode = [
28+
"dep:bincode",
29+
"dep:solana-account",
30+
"dep:solana-instruction",
31+
"dep:solana-system-interface",
32+
"serde",
33+
]
34+
serde = [
35+
"dep:serde",
36+
"dep:serde_derive",
37+
"dep:solana-short-vec",
38+
"solana-pubkey/serde",
39+
]
40+
41+
[package.metadata.docs.rs]
42+
targets = ["x86_64-unknown-linux-gnu"]
43+
all-features = true
44+
rustdoc-args = ["--cfg=docsrs"]

interface/src/instruction.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//! Program instruction helpers.
2+
3+
use {
4+
crate::{id, state::ConfigKeys},
5+
bincode::serialized_size,
6+
solana_instruction::{AccountMeta, Instruction},
7+
solana_pubkey::Pubkey,
8+
};
9+
10+
fn initialize_account<T: Default + serde::Serialize>(config_pubkey: &Pubkey) -> Instruction {
11+
let account_metas = vec![AccountMeta::new(*config_pubkey, true)];
12+
let account_data = (ConfigKeys { keys: vec![] }, T::default());
13+
Instruction::new_with_bincode(id(), &account_data, account_metas)
14+
}
15+
16+
/// Create a new, empty configuration account
17+
pub fn create_account_with_max_config_space<T: Default + serde::Serialize>(
18+
from_account_pubkey: &Pubkey,
19+
config_account_pubkey: &Pubkey,
20+
lamports: u64,
21+
max_config_space: u64,
22+
keys: Vec<(Pubkey, bool)>,
23+
) -> Vec<Instruction> {
24+
let space = max_config_space.saturating_add(serialized_size(&ConfigKeys { keys }).unwrap());
25+
vec![
26+
solana_system_interface::instruction::create_account(
27+
from_account_pubkey,
28+
config_account_pubkey,
29+
lamports,
30+
space,
31+
&id(),
32+
),
33+
initialize_account::<T>(config_account_pubkey),
34+
]
35+
}
36+
37+
/// Store new data in a configuration account
38+
pub fn store<T: serde::Serialize>(
39+
config_account_pubkey: &Pubkey,
40+
is_config_signer: bool,
41+
keys: Vec<(Pubkey, bool)>,
42+
data: &T,
43+
) -> Instruction {
44+
let mut account_metas = vec![AccountMeta::new(*config_account_pubkey, is_config_signer)];
45+
for (signer_pubkey, _) in keys.iter().filter(|(_, is_signer)| *is_signer) {
46+
if signer_pubkey != config_account_pubkey {
47+
account_metas.push(AccountMeta::new(*signer_pubkey, true));
48+
}
49+
}
50+
let account_data = (ConfigKeys { keys }, data);
51+
Instruction::new_with_bincode(id(), &account_data, account_metas)
52+
}

interface/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
2+
#![allow(clippy::arithmetic_side_effects)]
3+
#[cfg(feature = "bincode")]
4+
pub mod instruction;
5+
pub mod state;
6+
pub use solana_sdk_ids::config::id;

interface/src/state.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
use solana_pubkey::Pubkey;
2+
#[cfg(feature = "serde")]
3+
use {
4+
serde_derive::{Deserialize, Serialize},
5+
solana_short_vec as short_vec,
6+
};
7+
8+
/// A collection of keys to be stored in Config account data.
9+
#[derive(Debug, Default)]
10+
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
11+
pub struct ConfigKeys {
12+
// Each key tuple comprises a unique `Pubkey` identifier,
13+
// and `bool` whether that key is a signer of the data
14+
#[cfg_attr(feature = "serde", serde(with = "short_vec"))]
15+
pub keys: Vec<(Pubkey, bool)>,
16+
}

program/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,14 @@ bincode = { workspace = true }
2020
num-derive = { workspace = true }
2121
num-traits = { workspace = true }
2222
serde = { workspace = true, features = ["derive"] }
23+
solana-config-interface = { workspace = true, features = ["serde"] }
2324
solana-program = { workspace = true }
2425
thiserror = { workspace = true }
2526

2627
[dev-dependencies]
2728
mollusk-svm = { workspace = true, features = ["fuzz-fd"] }
2829
mollusk-svm-bencher = { workspace = true }
29-
solana-config-program-client = { path = "../clients/rust", features = ["serde"] }
30+
solana-config-interface = { workspace = true, features = ["bincode", "serde"] }
3031
solana-sdk = { workspace = true }
3132

3233
[lib]

0 commit comments

Comments
 (0)