Skip to content

Commit d3ed683

Browse files
authored
[Solana] tests (#1226)
* Checkpoint * Checkpoint * Checkpoint * Nice * Finally works * Cleanup * Cleanup * Cleanup * Cleanup * Checkpoint * Works * Final cleanup * Remove async * Continue
1 parent b6c39ce commit d3ed683

File tree

13 files changed

+595
-264
lines changed

13 files changed

+595
-264
lines changed

target_chains/solana/Cargo.lock

Lines changed: 32 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[package]
2+
name = "program-simulator"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[lib]
7+
crate-type = ["lib"]
8+
name = "program_simulator"
9+
10+
11+
[dependencies]
12+
solana-sdk = "1.16.20"
13+
solana-client = "1.16.20"
14+
solana-program-test = "1.16.20"
15+
solana-program = "1.16.20"
16+
bincode = "1.3.3"
17+
borsh = "0.10.3"
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
use {
2+
borsh::BorshDeserialize,
3+
solana_program::{
4+
hash::Hash,
5+
instruction::Instruction,
6+
native_token::LAMPORTS_PER_SOL,
7+
pubkey::Pubkey,
8+
system_instruction,
9+
},
10+
solana_program_test::{
11+
BanksClient,
12+
BanksClientError,
13+
ProgramTest,
14+
ProgramTestBanksClientExt,
15+
},
16+
solana_sdk::{
17+
signature::{
18+
Keypair,
19+
Signer,
20+
},
21+
transaction::Transaction,
22+
},
23+
};
24+
25+
pub struct ProgramSimulator {
26+
banks_client: BanksClient,
27+
/// Hash used to submit the last transaction. The hash must be advanced for each new
28+
/// transaction; otherwise, replayed transactions in different states can return stale
29+
/// results.
30+
last_blockhash: Hash,
31+
genesis_keypair: Keypair,
32+
}
33+
34+
impl ProgramSimulator {
35+
pub async fn start_from_program_test(program_test: ProgramTest) -> ProgramSimulator {
36+
let (banks_client, genesis_keypair, recent_blockhash) = program_test.start().await;
37+
ProgramSimulator {
38+
banks_client,
39+
genesis_keypair,
40+
last_blockhash: recent_blockhash,
41+
}
42+
}
43+
44+
/// Process a transaction containing `instruction` signed by `signers`.
45+
/// `payer` is used to pay for and sign the transaction.
46+
pub async fn process_ix(
47+
&mut self,
48+
instruction: Instruction,
49+
signers: &Vec<&Keypair>,
50+
payer: Option<&Keypair>,
51+
) -> Result<(), BanksClientError> {
52+
let actual_payer = payer.unwrap_or(&self.genesis_keypair);
53+
let mut transaction =
54+
Transaction::new_with_payer(&[instruction], Some(&actual_payer.pubkey()));
55+
56+
let blockhash = self
57+
.banks_client
58+
.get_new_latest_blockhash(&self.last_blockhash)
59+
.await
60+
.unwrap();
61+
self.last_blockhash = blockhash;
62+
63+
transaction.partial_sign(&[actual_payer], self.last_blockhash);
64+
transaction.partial_sign(signers, self.last_blockhash);
65+
66+
self.banks_client.process_transaction(transaction).await
67+
}
68+
69+
/// Send `lamports` worth of SOL to the pubkey `to`.
70+
pub async fn airdrop(&mut self, to: &Pubkey, lamports: u64) -> Result<(), BanksClientError> {
71+
let instruction =
72+
system_instruction::transfer(&self.genesis_keypair.pubkey(), to, lamports);
73+
74+
self.process_ix(instruction, &vec![], None).await
75+
}
76+
77+
pub async fn get_funded_keypair(&mut self) -> Result<Keypair, BanksClientError> {
78+
let keypair = Keypair::new();
79+
self.airdrop(&keypair.pubkey(), LAMPORTS_PER_SOL).await?;
80+
Ok(keypair)
81+
}
82+
83+
pub async fn get_anchor_account_data<T: BorshDeserialize>(
84+
&mut self,
85+
pubkey: Pubkey,
86+
) -> Result<T, BanksClientError> {
87+
let account = self
88+
.banks_client
89+
.get_account(pubkey)
90+
.await
91+
.unwrap()
92+
.unwrap();
93+
94+
Ok(T::deserialize(&mut &account.data[8..])?)
95+
}
96+
}

target_chains/solana/programs/pyth-solana-receiver/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,6 @@ bincode = "1.3.3"
3333
libsecp256k1 = "0.7.1"
3434
rand = "0.8.5"
3535
lazy_static = "1.4.0"
36+
program-simulator = { path = "../../program_simulator" }
37+
wormhole-sdk = { git = "https://github.com/wormhole-foundation/wormhole", tag = "v2.17.1" }
38+
serde_wormhole = { git = "https://github.com/wormhole-foundation/wormhole", tag = "v2.17.1"}

target_chains/solana/programs/pyth-solana-receiver/src/lib.rs

Lines changed: 2 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
use {
22
crate::error::ReceiverError,
3-
anchor_lang::{
4-
prelude::*,
5-
system_program,
6-
},
3+
anchor_lang::prelude::*,
74
pythnet_sdk::{
85
accumulators::merkle::MerkleRoot,
96
hashers::keccak256_160::Keccak160,
@@ -47,6 +44,7 @@ use {
4744
};
4845

4946
pub mod error;
47+
pub mod sdk;
5048
pub mod state;
5149

5250
declare_id!("rec5EKMGg6MxZYaMdyBfgwp4d5rB9T1VQH5pJv5LtFJ");
@@ -303,69 +301,6 @@ pub struct PostUpdatesAtomicParams {
303301
pub merkle_price_update: MerklePriceUpdate,
304302
}
305303

306-
impl crate::accounts::Initialize {
307-
pub fn populate(payer: &Pubkey) -> Self {
308-
let config = Pubkey::find_program_address(&[CONFIG_SEED.as_ref()], &crate::ID).0;
309-
crate::accounts::Initialize {
310-
payer: *payer,
311-
config,
312-
system_program: system_program::ID,
313-
}
314-
}
315-
}
316-
317-
impl crate::accounts::PostUpdatesAtomic {
318-
pub fn populate(
319-
payer: Pubkey,
320-
price_update_account: Pubkey,
321-
wormhole_address: Pubkey,
322-
guardian_set_index: u32,
323-
) -> Self {
324-
let config = Pubkey::find_program_address(&[CONFIG_SEED.as_ref()], &crate::ID).0;
325-
let treasury = Pubkey::find_program_address(&[TREASURY_SEED.as_ref()], &crate::ID).0;
326-
327-
let guardian_set = Pubkey::find_program_address(
328-
&[
329-
GuardianSet::SEED_PREFIX,
330-
guardian_set_index.to_be_bytes().as_ref(),
331-
],
332-
&wormhole_address,
333-
)
334-
.0;
335-
336-
crate::accounts::PostUpdatesAtomic {
337-
payer,
338-
guardian_set,
339-
config,
340-
treasury,
341-
price_update_account,
342-
system_program: system_program::ID,
343-
}
344-
}
345-
}
346-
347-
impl crate::accounts::PostUpdates {
348-
pub fn populate(payer: Pubkey, encoded_vaa: Pubkey, price_update_account: Pubkey) -> Self {
349-
let config = Pubkey::find_program_address(&[CONFIG_SEED.as_ref()], &crate::ID).0;
350-
let treasury = Pubkey::find_program_address(&[TREASURY_SEED.as_ref()], &crate::ID).0;
351-
352-
crate::accounts::PostUpdates {
353-
payer,
354-
encoded_vaa,
355-
config,
356-
treasury,
357-
price_update_account,
358-
system_program: system_program::ID,
359-
}
360-
}
361-
}
362-
363-
impl crate::accounts::Governance {
364-
pub fn populate(payer: Pubkey) -> Self {
365-
let config = Pubkey::find_program_address(&[CONFIG_SEED.as_ref()], &crate::ID).0;
366-
crate::accounts::Governance { payer, config }
367-
}
368-
}
369304

370305
fn deserialize_guardian_set_checked(
371306
account_info: &AccountInfo<'_>,

0 commit comments

Comments
 (0)