Skip to content

Commit 7cc4193

Browse files
authored
Update client to match builtin offchain API (#44)
* client-rust: fix up `fetch` feature * client-rust: add support for `ConfigKeys` and `get_config_data` * program: drop `ConfigKeys::serialized_size` * program: extract the rest of the offchain API * re-profile compute units * review feedback * rename module * update codama
1 parent 2c72ce1 commit 7cc4193

File tree

16 files changed

+2255
-367
lines changed

16 files changed

+2255
-367
lines changed

Cargo.lock

Lines changed: 1974 additions & 104 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ mollusk-svm-bencher = "0.0.10-solana-2.0"
2828
num-derive = "0.4"
2929
num-traits = "0.2"
3030
serde = "1.0.193"
31+
solana-client = "2.0.1"
3132
solana-program = "2.0.1"
3233
solana-sdk = "2.0.1"
3334
thiserror = "1.0.61"

clients/rust/Cargo.toml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,18 @@ license-file = { workspace = true }
99
edition = { workspace = true }
1010

1111
[features]
12+
fetch = ["dep:solana-client", "dep:solana-sdk"]
13+
serde = ["dep:bincode", "dep:serde", "kaigan/serde"]
1214
test-sbf = []
13-
serde = ["dep:serde"]
1415

1516
[dependencies]
17+
bincode = { workspace = true, optional = true }
1618
borsh = { workspace = true }
17-
kaigan = { workspace = true, features = ["serde"] }
19+
kaigan = { workspace = true }
1820
serde = { workspace = true, features = ["derive"], optional = true }
21+
solana-client = { workspace = true, optional = true }
1922
solana-program = { workspace = true, features = ["borsh"] }
23+
solana-sdk = { workspace = true, optional = true }
2024

2125
[dev-dependencies]
2226
assert_matches = { workspace = true }

clients/rust/src/generated/accounts/config.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ impl<'a> TryFrom<&solana_program::account_info::AccountInfo<'a>> for Config {
4242
#[cfg(feature = "fetch")]
4343
pub fn fetch_config(
4444
rpc: &solana_client::rpc_client::RpcClient,
45-
address: &Pubkey,
45+
address: &solana_program::pubkey::Pubkey,
4646
) -> Result<crate::shared::DecodedAccount<Config>, std::io::Error> {
4747
let accounts = fetch_all_config(rpc, &[*address])?;
4848
Ok(accounts[0].clone())
@@ -51,10 +51,10 @@ pub fn fetch_config(
5151
#[cfg(feature = "fetch")]
5252
pub fn fetch_all_config(
5353
rpc: &solana_client::rpc_client::RpcClient,
54-
addresses: &[Pubkey],
54+
addresses: &[solana_program::pubkey::Pubkey],
5555
) -> Result<Vec<crate::shared::DecodedAccount<Config>>, std::io::Error> {
5656
let accounts = rpc
57-
.get_multiple_accounts(&addresses)
57+
.get_multiple_accounts(addresses)
5858
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?;
5959
let mut decoded_accounts: Vec<crate::shared::DecodedAccount<Config>> = Vec::new();
6060
for i in 0..addresses.len() {
@@ -76,7 +76,7 @@ pub fn fetch_all_config(
7676
#[cfg(feature = "fetch")]
7777
pub fn fetch_maybe_config(
7878
rpc: &solana_client::rpc_client::RpcClient,
79-
address: &Pubkey,
79+
address: &solana_program::pubkey::Pubkey,
8080
) -> Result<crate::shared::MaybeAccount<Config>, std::io::Error> {
8181
let accounts = fetch_all_maybe_config(rpc, &[*address])?;
8282
Ok(accounts[0].clone())
@@ -85,10 +85,10 @@ pub fn fetch_maybe_config(
8585
#[cfg(feature = "fetch")]
8686
pub fn fetch_all_maybe_config(
8787
rpc: &solana_client::rpc_client::RpcClient,
88-
addresses: &[Pubkey],
88+
addresses: &[solana_program::pubkey::Pubkey],
8989
) -> Result<Vec<crate::shared::MaybeAccount<Config>>, std::io::Error> {
9090
let accounts = rpc
91-
.get_multiple_accounts(&addresses)
91+
.get_multiple_accounts(addresses)
9292
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?;
9393
let mut decoded_accounts: Vec<crate::shared::MaybeAccount<Config>> = Vec::new();
9494
for i in 0..addresses.len() {

clients/rust/src/hooked/short_vec.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,21 @@ impl<'de, T: Deserialize<'de>> Deserialize<'de> for ShortVec<T> {
9393
}
9494
}
9595

96-
/// ConfigKeys type - uses short vec.
97-
pub type ConfigKeys = ShortVec<(Pubkey, bool)>;
96+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
97+
#[derive(BorshDeserialize, BorshSerialize, Clone, Debug, Eq, PartialEq)]
98+
pub struct ConfigKeys {
99+
/// Each key tuple comprises a unique `Pubkey` identifier,
100+
/// and `bool` whether that key is a signer of the data.
101+
pub keys: ShortVec<(Pubkey, bool)>,
102+
}
103+
104+
/// Utility for extracting the `ConfigKeys` data from the account data.
105+
#[cfg(feature = "serde")]
106+
pub fn get_config_data(bytes: &[u8]) -> Result<&[u8], bincode::Error> {
107+
bincode::deserialize::<ConfigKeys>(bytes)
108+
.and_then(|keys| bincode::serialized_size(&keys))
109+
.map(|offset| &bytes[offset as usize..])
110+
}
98111

99112
#[cfg(test)]
100113
mod tests {

program/src/instruction.rs renamed to clients/rust/src/instructions_bincode.rs

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,30 @@
11
//! Program instruction helpers.
22
33
use {
4-
crate::{
5-
id,
6-
state::{ConfigKeys, ConfigState},
7-
},
4+
crate::{ConfigKeys, ShortVec, ID},
5+
bincode::serialized_size,
86
solana_program::{
97
instruction::{AccountMeta, Instruction},
108
pubkey::Pubkey,
119
system_instruction,
1210
},
1311
};
1412

13+
/// Trait defining config state to be stored at the end of the account data.
14+
pub trait ConfigState: serde::Serialize + Default {
15+
/// Maximum space that the serialized representation will require
16+
fn max_space() -> u64;
17+
}
18+
1519
fn initialize_account<T: ConfigState>(config_pubkey: &Pubkey) -> Instruction {
1620
let account_metas = vec![AccountMeta::new(*config_pubkey, true)];
17-
let account_data = (ConfigKeys { keys: vec![] }, T::default());
18-
Instruction::new_with_bincode(id(), &account_data, account_metas)
21+
let account_data = (
22+
ConfigKeys {
23+
keys: ShortVec(vec![]),
24+
},
25+
T::default(),
26+
);
27+
Instruction::new_with_bincode(ID, &account_data, account_metas)
1928
}
2029

2130
/// Create a new, empty configuration account
@@ -25,14 +34,19 @@ pub fn create_account<T: ConfigState>(
2534
lamports: u64,
2635
keys: Vec<(Pubkey, bool)>,
2736
) -> Vec<Instruction> {
28-
let space = T::max_space().saturating_add(ConfigKeys::serialized_size(keys));
37+
let space = T::max_space().saturating_add(
38+
serialized_size(&ConfigKeys {
39+
keys: ShortVec(keys),
40+
})
41+
.unwrap(),
42+
);
2943
vec![
3044
system_instruction::create_account(
3145
from_account_pubkey,
3246
config_account_pubkey,
3347
lamports,
3448
space,
35-
&id(),
49+
&ID,
3650
),
3751
initialize_account::<T>(config_account_pubkey),
3852
]
@@ -51,6 +65,11 @@ pub fn store<T: ConfigState>(
5165
account_metas.push(AccountMeta::new(*signer_pubkey, true));
5266
}
5367
}
54-
let account_data = (ConfigKeys { keys }, data);
55-
Instruction::new_with_bincode(id(), &account_data, account_metas)
68+
let account_data = (
69+
ConfigKeys {
70+
keys: ShortVec(keys),
71+
},
72+
data,
73+
);
74+
Instruction::new_with_bincode(ID, &account_data, account_metas)
5675
}

clients/rust/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1+
#![allow(clippy::arithmetic_side_effects)]
2+
13
mod generated;
24
mod hooked;
35

6+
#[cfg(feature = "serde")]
7+
pub mod instructions_bincode;
8+
49
pub use {
510
generated::{programs::SOLANA_CONFIG_ID as ID, *},
611
hooked::*,

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@
2525
"template:upgrade": "zx ./scripts/upgrade-template.mjs"
2626
},
2727
"devDependencies": {
28-
"@codama/renderers-js": "^1.2.7",
29-
"@codama/renderers-rust": "^1.0.16",
28+
"@codama/renderers-js": "^1.2.8",
29+
"@codama/renderers-rust": "^1.0.17",
3030
"@iarna/toml": "^2.2.5",
31-
"codama": "^1.2.8",
31+
"codama": "^1.2.9",
3232
"typescript": "^5.5.2",
3333
"zx": "^7.2.3"
3434
},

0 commit comments

Comments
 (0)