Guillermo Bescos 1 år sedan
förälder
incheckning
45910bef74

+ 13 - 1
target_chains/solana/Cargo.lock

@@ -2977,6 +2977,17 @@ dependencies = [
  "unicode-ident",
 ]
 
+[[package]]
+name = "program-simulator"
+version = "0.1.0"
+dependencies = [
+ "bincode",
+ "solana-client",
+ "solana-program",
+ "solana-program-test",
+ "solana-sdk",
+]
+
 [[package]]
 name = "pyth-sdk"
 version = "0.8.0"
@@ -3017,6 +3028,7 @@ dependencies = [
  "byteorder",
  "lazy_static",
  "libsecp256k1 0.7.1",
+ "program-simulator",
  "pyth-sdk",
  "pyth-sdk-solana",
  "pythnet-sdk",
@@ -6141,7 +6153,7 @@ dependencies = [
 [[package]]
 name = "wormhole-core-bridge-solana"
 version = "0.0.1-alpha.3"
-source = "git+https://github.com/guibescos/wormhole?branch=variable-sigs#a9b970c1bc09b9678777949bcfcac8d498f7c1fc"
+source = "git+https://github.com/guibescos/wormhole?branch=variable-sigs#4061743f3fa7d575437f343130e1b94f61d8ac3b"
 dependencies = [
  "anchor-lang",
  "cfg-if",

+ 2 - 1
target_chains/solana/Cargo.toml

@@ -1,7 +1,8 @@
 [workspace]
 members = [
     "programs/*",
-    "cli/"
+    "cli/",
+    "program_simulator/"
 ]
 
 [profile.release]

+ 16 - 0
target_chains/solana/program_simulator/Cargo.toml

@@ -0,0 +1,16 @@
+[package]
+name = "program-simulator"
+version = "0.1.0"
+edition = "2021"
+
+[lib]
+crate-type = ["lib"]
+name = "program_simulator"
+
+
+[dependencies]
+solana-sdk = "1.16.20"
+solana-client = "1.16.20"
+solana-program-test = "1.16.20"
+solana-program = "1.16.20"
+bincode = "1.3.3"

+ 44 - 83
target_chains/solana/programs/pyth-solana-receiver/tests/program_test/mod.rs → target_chains/solana/program_simulator/src/lib.rs

@@ -6,14 +6,12 @@ use {
         },
         hash::Hash,
         instruction::Instruction,
-        native_token::LAMPORTS_PER_SOL,
         pubkey::Pubkey,
         rent::Rent,
         stake_history::Epoch,
         system_instruction,
     },
     solana_program_test::{
-        read_file,
         BanksClient,
         BanksClientError,
         ProgramTest,
@@ -27,89 +25,45 @@ use {
         },
         transaction::Transaction,
     },
-    std::path::PathBuf,
 };
 
-lazy_static::lazy_static! {
-    // Build the oracle binary and make it available to the
-    // simulator. lazy_static makes this happen only once per test
-    // run.
-    static ref PYTH_RECEIVER_PROGRAM_BINARY_PATH: PathBuf = {
-
-    // Detect features and pass them onto cargo-build-bpf.
-    // IMPORTANT: All features of this crate must have gates added to this vector.
-    let features: Vec<&str> = vec![
-    #[cfg(feature = "devnet")]
-        "devnet",
-    #[cfg(feature = "mainnet")]
-        "mainnet",
-    ];
-
-    let mut cmd = std::process::Command::new("cargo");
-    cmd.arg("build-bpf");
-
-    if !features.is_empty() {
-        cmd.arg("--features");
-        cmd.args(features);
-    }
-
-    let status = cmd.status().unwrap();
-
-    if !status.success() {
-        panic!(
-        "cargo-build-bpf did not exit with 0 (code {:?})",
-        status.code()
-        );
-    }
-
-    let target_dir = concat!(env!("CARGO_MANIFEST_DIR"), "/../../target");
 
-    PathBuf::from(target_dir).join("deploy/pyth_solana_receiver.so")
-    };
-}
-
-/// Simulator for the state of the target chain program on Solana. You can run solana transactions against
-/// this struct to test how pyth instructions execute in the Solana runtime.
-pub struct ProgramSimulator {
-    pub program_id:        Pubkey,
-    banks_client:          BanksClient,
-    /// Hash used to submit the last transaction. The hash must be advanced for each new
-    /// transaction; otherwise, replayed transactions in different states can return stale
-    /// results.
-    last_blockhash:        Hash,
-    pub upgrade_authority: Keypair,
-    pub genesis_keypair:   Keypair,
+pub struct ProgramBench {
+    program_test:      ProgramTest,
+    upgrade_authority: Keypair,
 }
 
-impl ProgramSimulator {
-    /// Deploys the target chain contract as upgradable
-    pub async fn new() -> ProgramSimulator {
-        let mut bpf_data = read_file(&*PYTH_RECEIVER_PROGRAM_BINARY_PATH);
-
-        let mut program_test = ProgramTest::default();
+impl ProgramBench {
+    pub fn new() -> ProgramBench {
+        let program_test = ProgramTest::default();
+        let upgrade_authority = Keypair::new();
+        ProgramBench {
+            program_test,
+            upgrade_authority,
+        }
+    }
 
-        // This PDA is the actual address in the real world
-        // https://docs.rs/solana-program/1.6.4/solana_program/bpf_loader_upgradeable/index.html
-        let (programdata_address, _) = Pubkey::find_program_address(
-            &[&pyth_solana_receiver::ID.to_bytes()],
-            &bpf_loader_upgradeable::id(),
-        );
+    pub fn add_account(&mut self, pubkey: Pubkey, account: Account) {
+        self.program_test.add_account(pubkey, account);
+    }
 
+    pub fn add_bpf_upgradable_program(&mut self, address: Pubkey, bpf_data: Vec<u8>) {
+        let programdata_key = Pubkey::new_unique();
         let upgrade_authority_keypair = Keypair::new();
 
         let program_deserialized = UpgradeableLoaderState::Program {
-            programdata_address,
+            programdata_address: programdata_key,
         };
         let programdata_deserialized = UpgradeableLoaderState::ProgramData {
             slot:                      1,
             upgrade_authority_address: Some(upgrade_authority_keypair.pubkey()),
         };
 
-        // Program contains a pointer to programdata
+        // Program contains a pointer to progradata
         let program_vec = bincode::serialize(&program_deserialized).unwrap();
         // Programdata contains a header and the binary of the program
         let mut programdata_vec = bincode::serialize(&programdata_deserialized).unwrap();
-        programdata_vec.append(&mut bpf_data);
+        programdata_vec.extend(bpf_data);
 
         let program_account = Account {
             lamports:   Rent::default().minimum_balance(program_vec.len()),
@@ -126,30 +80,37 @@ impl ProgramSimulator {
             rent_epoch: Epoch::default(),
         };
 
-        // Add to both accounts to program test, now the program is deploy as upgradable
-        program_test.add_account(pyth_solana_receiver::ID, program_account);
-        program_test.add_account(programdata_address, programdata_account);
+        // Add both accounts to program test, now the program is deployed as upgradable
+        self.add_account(address, program_account);
+        self.add_account(programdata_key, programdata_account);
+    }
 
+    pub async fn start(self) -> ProgramSimulator {
         // Start validator
-        let (banks_client, genesis_keypair, recent_blockhash) = program_test.start().await;
+        let (banks_client, genesis_keypair, recent_blockhash) = self.program_test.start().await;
 
-        let mut result = ProgramSimulator {
-            program_id: pyth_solana_receiver::ID,
+        ProgramSimulator {
             banks_client,
-            last_blockhash: recent_blockhash,
-            upgrade_authority: upgrade_authority_keypair,
             genesis_keypair,
-        };
-
-        // Transfer money to upgrade_authority so it can call the instructions
-        result
-            .airdrop(&result.upgrade_authority.pubkey(), 1000 * LAMPORTS_PER_SOL)
-            .await
-            .unwrap();
-
-        result
+            upgrade_authority: self.upgrade_authority,
+            last_blockhash: recent_blockhash,
+        }
     }
+}
 
+/// Simulator for the state of the target chain program on Solana. You can run solana transactions against
+/// this struct to test how pyth instructions execute in the Solana runtime.
+pub struct ProgramSimulator {
+    banks_client:          BanksClient,
+    /// Hash used to submit the last transaction. The hash must be advanced for each new
+    /// transaction; otherwise, replayed transactions in different states can return stale
+    /// results.
+    last_blockhash:        Hash,
+    pub upgrade_authority: Keypair,
+    pub genesis_keypair:   Keypair,
+}
+
+impl ProgramSimulator {
     /// Process a transaction containing `instruction` signed by `signers`.
     /// `payer` is used to pay for and sign the transaction.
     pub async fn process_ix(

+ 1 - 0
target_chains/solana/programs/pyth-solana-receiver/Cargo.toml

@@ -33,3 +33,4 @@ bincode = "1.3.3"
 libsecp256k1 = "0.7.1"
 rand = "0.8.5"
 lazy_static = "1.4.0"
+program-simulator = { path = "../../program_simulator" }

+ 4 - 0
target_chains/solana/programs/pyth-solana-receiver/src/lib.rs

@@ -49,6 +49,10 @@ use {
 pub mod error;
 pub mod state;
 
+#[cfg(test)]
+mod tests;
+
+
 declare_id!("rec5EKMGg6MxZYaMdyBfgwp4d5rB9T1VQH5pJv5LtFJ");
 
 #[program]

+ 1 - 0
target_chains/solana/programs/pyth-solana-receiver/src/tests/cases/mod.rs

@@ -0,0 +1 @@
+mod test_intialize;

+ 6 - 0
target_chains/solana/programs/pyth-solana-receiver/src/tests/cases/test_intialize.rs

@@ -0,0 +1,6 @@
+use crate::tests::setup::start_receiver_test;
+
+#[tokio::test]
+async fn test_initialize() {
+    let _bench = start_receiver_test().await;
+}

+ 2 - 0
target_chains/solana/programs/pyth-solana-receiver/src/tests/mod.rs

@@ -0,0 +1,2 @@
+mod cases;
+mod setup;

+ 19 - 0
target_chains/solana/programs/pyth-solana-receiver/src/tests/setup.rs

@@ -0,0 +1,19 @@
+use {
+    crate::ID,
+    program_simulator::ProgramBench,
+    solana_program_test::read_file,
+    std::path::Path,
+};
+
+pub async fn start_receiver_test() -> ProgramBench {
+    let receiver_bpf_code = read_file(
+        std::env::current_dir()
+            .unwrap()
+            .join(Path::new("../../../target/deploy/pyth_solana_receiver.so")),
+    );
+
+    let mut program_bench = ProgramBench::new();
+    program_bench.add_bpf_upgradable_program(ID, receiver_bpf_code);
+
+    program_bench
+}

+ 0 - 1
target_chains/solana/programs/pyth-solana-receiver/tests/cases/mod.rs

@@ -1 +0,0 @@
-pub use super::program_test::*;

+ 0 - 3
target_chains/solana/programs/pyth-solana-receiver/tests/test_all.rs

@@ -1,3 +0,0 @@
-mod cases;
-
-pub mod program_test;