Эх сурвалжийг харах

cli: Specify programs to embed into local validator genesis via Anchor.toml

Armani Ferrante 4 жил өмнө
parent
commit
b3803aec03

+ 1 - 0
CHANGELOG.md

@@ -14,6 +14,7 @@ incremented for features.
 ## Features
 
 * ts: Allow preloading instructions for state rpc transactions ([cf9c84](https://github.com/project-serum/anchor/commit/cf9c847e4144989b5bc1936149d171e90204777b)).
+* cli: Specify programs to embed into local validator genesis via Anchor.toml while testing.
 
 ## Fixes
 

+ 19 - 3
cli/src/config.rs

@@ -8,10 +8,11 @@ use std::path::Path;
 use std::path::PathBuf;
 use std::str::FromStr;
 
-#[derive(Default)]
+#[derive(Debug, Default)]
 pub struct Config {
     pub cluster: Cluster,
     pub wallet: WalletPath,
+    pub test: Option<Test>,
 }
 
 impl Config {
@@ -61,10 +62,11 @@ impl Config {
 
 // Pubkey serializes as a byte array so use this type a hack to serialize
 // into base 58 strings.
-#[derive(Serialize, Deserialize)]
+#[derive(Debug, Serialize, Deserialize)]
 struct _Config {
     cluster: String,
     wallet: String,
+    test: Option<Test>,
 }
 
 impl ToString for Config {
@@ -72,6 +74,7 @@ impl ToString for Config {
         let cfg = _Config {
             cluster: format!("{}", self.cluster),
             wallet: self.wallet.to_string(),
+            test: self.test.clone(),
         };
 
         toml::to_string(&cfg).expect("Must be well formed")
@@ -84,14 +87,27 @@ impl FromStr for Config {
     fn from_str(s: &str) -> Result<Self, Self::Err> {
         let cfg: _Config = toml::from_str(s)
             .map_err(|e| anyhow::format_err!("Unable to deserialize config: {}", e.to_string()))?;
-
         Ok(Config {
             cluster: cfg.cluster.parse()?,
             wallet: shellexpand::tilde(&cfg.wallet).parse()?,
+            test: cfg.test,
         })
     }
 }
 
+#[derive(Debug, Clone, Serialize, Deserialize)]
+pub struct Test {
+    pub genesis: Vec<GenesisEntry>,
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize)]
+pub struct GenesisEntry {
+    // Base58 pubkey string.
+    pub address: String,
+    // Filepath to the compiled program to embed into the genesis.
+    pub program: String,
+}
+
 // TODO: this should read idl dir instead of parsing source.
 pub fn read_all_programs() -> Result<Vec<Program>> {
     let files = fs::read_dir("programs")?;

+ 9 - 2
cli/src/main.rs

@@ -591,7 +591,7 @@ fn test(skip_deploy: bool) -> Result<()> {
                 build(None)?;
                 let flags = match skip_deploy {
                     true => None,
-                    false => Some(genesis_flags()?),
+                    false => Some(genesis_flags(cfg)?),
                 };
                 Some(start_test_validator(flags)?)
             }
@@ -635,7 +635,7 @@ fn test(skip_deploy: bool) -> Result<()> {
 
 // Returns the solana-test-validator flags to embed the workspace programs
 // in the genesis block. This allows us to run tests without every deploying.
-fn genesis_flags() -> Result<Vec<String>> {
+fn genesis_flags(cfg: &Config) -> Result<Vec<String>> {
     let mut flags = Vec::new();
     for mut program in read_all_programs()? {
         let binary_path = program.binary_path().display().to_string();
@@ -656,6 +656,13 @@ fn genesis_flags() -> Result<Vec<String>> {
             .with_extension("json");
         write_idl(&program.idl, OutFile::File(idl_out))?;
     }
+    if let Some(test) = cfg.test.as_ref() {
+        for entry in &test.genesis {
+            flags.push("--bpf-program".to_string());
+            flags.push(entry.address.clone());
+            flags.push(entry.program.clone());
+        }
+    }
     Ok(flags)
 }
 

+ 4 - 0
examples/misc/Anchor.toml

@@ -1,2 +1,6 @@
 cluster = "localnet"
 wallet = "/home/armaniferrante/.config/solana/id.json"
+
+[[test.genesis]]
+address = "FtMNMKp9DZHKWUyVAsj3Q5QV8ow4P3fUPP7ZrWEQJzKr"
+program = "./target/deploy/misc.so"

+ 10 - 1
examples/misc/tests/misc.js

@@ -1,4 +1,5 @@
-const anchor = require('@project-serum/anchor');
+const anchor = require("@project-serum/anchor");
+const serumCmn = require("@project-serum/common");
 const assert = require("assert");
 
 describe("misc", () => {
@@ -24,4 +25,12 @@ describe("misc", () => {
     assert.ok(dataAccount.udata.eq(new anchor.BN(1234)));
     assert.ok(dataAccount.idata.eq(new anchor.BN(22)));
   });
+
+  it("Can embed programs into genesis from the Anchor.toml", async () => {
+    const pid = new anchor.web3.PublicKey(
+      "FtMNMKp9DZHKWUyVAsj3Q5QV8ow4P3fUPP7ZrWEQJzKr"
+    );
+    let accInfo = await anchor.getProvider().connection.getAccountInfo(pid);
+    assert.ok(accInfo.executable);
+  });
 });