cli: Add `anchor keys sync` command (#2505)
This commit is contained in:
parent
0c8498d195
commit
70d922301e
|
@ -18,6 +18,7 @@ The minor version will be incremented upon a breaking change and the patch versi
|
|||
- bench: Add benchmarking for compute units usage ([#2466](https://github.com/coral-xyz/anchor/pull/2466))
|
||||
- cli: `idl set-buffer`, `idl set-authority` and `idl close` take an option `--print-only`. which prints transaction in a base64 Borsh compatible format but not sent to the cluster. It's helpful when managing authority under a multisig, e.g., a user can create a proposal for a `Custom Instruction` in SPL Governance ([#2486](https://github.com/coral-xyz/anchor/pull/2486)).
|
||||
- lang: Add `emit_cpi!` and `#[event_cpi]` macros(behind `event-cpi` feature flag) to store event logs in transaction metadata ([#2438](https://github.com/coral-xyz/anchor/pull/2438)).
|
||||
- cli: Add `keys sync` command to sync program id declarations ([#2505](https://github.com/coral-xyz/anchor/pull/2505)).
|
||||
|
||||
### Fixes
|
||||
|
||||
|
|
|
@ -67,9 +67,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.19"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e"
|
||||
checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
@ -179,6 +179,7 @@ dependencies = [
|
|||
"heck 0.4.0",
|
||||
"pathdiff",
|
||||
"portpicker",
|
||||
"regex",
|
||||
"reqwest",
|
||||
"semver 1.0.16",
|
||||
"serde",
|
||||
|
@ -2155,7 +2156,7 @@ dependencies = [
|
|||
"petgraph",
|
||||
"pico-args",
|
||||
"regex",
|
||||
"regex-syntax",
|
||||
"regex-syntax 0.6.27",
|
||||
"string_cache",
|
||||
"term",
|
||||
"tiny-keccak",
|
||||
|
@ -3106,13 +3107,13 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.6.0"
|
||||
version = "1.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
|
||||
checksum = "81ca098a9821bd52d6b24fd8b10bd081f47d39c22778cafaa75a2857a62c6390"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
"regex-syntax 0.7.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3121,6 +3122,12 @@ version = "0.6.27"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78"
|
||||
|
||||
[[package]]
|
||||
name = "remove_dir_all"
|
||||
version = "0.5.3"
|
||||
|
|
|
@ -40,6 +40,7 @@ dirs = "4.0"
|
|||
heck = "0.4.0"
|
||||
flate2 = "1.0.19"
|
||||
tar = "0.4.35"
|
||||
regex = "1.8.3"
|
||||
reqwest = { version = "0.11.4", default-features = false, features = ["multipart", "blocking", "rustls-tls"] }
|
||||
tokio = "1.24"
|
||||
pathdiff = "0.2.0"
|
||||
|
|
|
@ -14,6 +14,7 @@ use flate2::read::ZlibDecoder;
|
|||
use flate2::write::{GzEncoder, ZlibEncoder};
|
||||
use flate2::Compression;
|
||||
use heck::{ToKebabCase, ToSnakeCase};
|
||||
use regex::RegexBuilder;
|
||||
use reqwest::blocking::multipart::{Form, Part};
|
||||
use reqwest::blocking::Client;
|
||||
use semver::{Version, VersionReq};
|
||||
|
@ -323,7 +324,14 @@ pub enum Command {
|
|||
|
||||
#[derive(Debug, Parser)]
|
||||
pub enum KeysCommand {
|
||||
/// List all of the program keys.
|
||||
List,
|
||||
/// Sync the program's `declare_id!` pubkey with the program's actual pubkey.
|
||||
Sync {
|
||||
/// Only sync the given program instead of all programs
|
||||
#[clap(short, long)]
|
||||
program_name: Option<String>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
|
@ -3763,6 +3771,7 @@ fn registry_api_token(_cfg_override: &ConfigOverride) -> Result<String> {
|
|||
fn keys(cfg_override: &ConfigOverride, cmd: KeysCommand) -> Result<()> {
|
||||
match cmd {
|
||||
KeysCommand::List => keys_list(cfg_override),
|
||||
KeysCommand::Sync { program_name } => keys_sync(cfg_override, program_name),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3776,6 +3785,81 @@ fn keys_list(cfg_override: &ConfigOverride) -> Result<()> {
|
|||
})
|
||||
}
|
||||
|
||||
/// Sync the program's `declare_id!` pubkey with the pubkey from `target/deploy/<KEYPAIR>.json`.
|
||||
fn keys_sync(cfg_override: &ConfigOverride, program_name: Option<String>) -> Result<()> {
|
||||
with_workspace(cfg_override, |cfg| {
|
||||
let programs = cfg.read_all_programs()?;
|
||||
let programs = match program_name {
|
||||
Some(program_name) => vec![programs
|
||||
.into_iter()
|
||||
.find(|program| program.lib_name == program_name)
|
||||
.ok_or_else(|| anyhow!("`{program_name}` is not found"))?],
|
||||
None => programs,
|
||||
};
|
||||
|
||||
let declare_id_regex = RegexBuilder::new(r#"^(([\w]+::)*)declare_id!\("(\w*)"\)"#)
|
||||
.multi_line(true)
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
for program in programs {
|
||||
// Get the pubkey from the keypair file
|
||||
let actual_program_id = program.pubkey()?.to_string();
|
||||
|
||||
// Handle declaration in program files
|
||||
let src_path = program.path.join("src");
|
||||
let files_to_check = vec![src_path.join("lib.rs"), src_path.join("id.rs")];
|
||||
|
||||
for path in files_to_check {
|
||||
let mut content = match fs::read_to_string(&path) {
|
||||
Ok(content) => content,
|
||||
Err(_) => continue,
|
||||
};
|
||||
|
||||
let incorrect_program_id = declare_id_regex
|
||||
.captures(&content)
|
||||
.and_then(|captures| captures.get(3))
|
||||
.filter(|program_id_match| program_id_match.as_str() != actual_program_id);
|
||||
if let Some(program_id_match) = incorrect_program_id {
|
||||
println!("Found incorrect program id declaration in {path:?}");
|
||||
|
||||
// Update the program id
|
||||
content.replace_range(program_id_match.range(), &actual_program_id);
|
||||
fs::write(&path, content)?;
|
||||
|
||||
println!("Updated to {actual_program_id}\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle declaration in Anchor.toml
|
||||
'outer: for programs in cfg.programs.values_mut() {
|
||||
for (name, mut deployment) in programs {
|
||||
// Skip other programs
|
||||
if name != &program.lib_name {
|
||||
continue;
|
||||
}
|
||||
|
||||
if deployment.address.to_string() != actual_program_id {
|
||||
println!("Found incorrect program id declaration in Anchor.toml for the program `{name}`");
|
||||
|
||||
// Update the program id
|
||||
deployment.address = Pubkey::from_str(&actual_program_id).unwrap();
|
||||
fs::write(cfg.path(), cfg.to_string())?;
|
||||
|
||||
println!("Updated to {actual_program_id}\n");
|
||||
break 'outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
println!("All program id declarations are synced.");
|
||||
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
fn localnet(
|
||||
cfg_override: &ConfigOverride,
|
||||
skip_build: bool,
|
||||
|
|
Loading…
Reference in New Issue