Skip to content

Commit 6920733

Browse files
authored
Merge pull request #96 from otter-sec/master
Added PDA upload for remote verification
2 parents 5ec4ba5 + d378d33 commit 6920733

File tree

2 files changed

+98
-5
lines changed

2 files changed

+98
-5
lines changed

src/main.rs

Lines changed: 96 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,10 @@ async fn main() -> anyhow::Result<()> {
173173
.arg(Arg::with_name("current-dir")
174174
.long("current-dir")
175175
.help("Verify in current directory"))
176+
.arg(Arg::with_name("skip-prompt")
177+
.short("y")
178+
.long("skip-prompt")
179+
.help("Skip the prompt to upload a new program"))
176180
.arg(Arg::with_name("cargo-args")
177181
.multiple(true)
178182
.last(true)
@@ -255,6 +259,7 @@ async fn main() -> anyhow::Result<()> {
255259
let library_name = sub_m.value_of("library-name").map(|s| s.to_string());
256260
let bpf_flag = sub_m.is_present("bpf");
257261
let current_dir = sub_m.is_present("current-dir");
262+
let skip_prompt = sub_m.is_present("skip-prompt");
258263
let cargo_args: Vec<String> = sub_m
259264
.values_of("cargo-args")
260265
.unwrap_or_default()
@@ -273,6 +278,7 @@ async fn main() -> anyhow::Result<()> {
273278
bpf_flag,
274279
cargo_args,
275280
current_dir,
281+
skip_prompt,
276282
&mut container_id,
277283
&mut temp_dir,
278284
)
@@ -722,11 +728,12 @@ pub async fn verify_from_repo(
722728
bpf_flag: bool,
723729
cargo_args: Vec<String>,
724730
current_dir: bool,
731+
skip_prompt: bool,
725732
container_id_opt: &mut Option<String>,
726733
temp_dir_opt: &mut Option<String>,
727734
) -> anyhow::Result<()> {
728735
if remote {
729-
let genesis_hash = get_genesis_hash(connection_url)?;
736+
let genesis_hash = get_genesis_hash(connection_url.clone())?;
730737
if genesis_hash != MAINNET_GENESIS_HASH {
731738
return Err(anyhow!("Remote verification only works with mainnet. Please omit the --remote flag to verify locally."));
732739
}
@@ -738,11 +745,95 @@ pub async fn verify_from_repo(
738745
&program_id,
739746
&library_name_opt,
740747
bpf_flag,
741-
relative_mount_path,
742-
base_image,
743-
cargo_args,
748+
relative_mount_path.clone(),
749+
base_image.clone(),
750+
cargo_args.clone(),
744751
)
745752
.await?;
753+
754+
let mut args: Vec<&str> = Vec::new();
755+
if !relative_mount_path.is_empty() {
756+
args.push("--mount-path");
757+
args.push(&relative_mount_path);
758+
}
759+
// Get the absolute build path to the solana program directory to build inside docker
760+
let mount_path = PathBuf::from(relative_mount_path.clone());
761+
println!("Build path: {:?}", mount_path);
762+
763+
args.push("--library-name");
764+
let library_name = match library_name_opt {
765+
Some(p) => p,
766+
None => {
767+
std::process::Command::new("find")
768+
.args([mount_path.to_str().unwrap(), "-name", "Cargo.toml"])
769+
.output()
770+
.map_err(|e| {
771+
anyhow::format_err!(
772+
"Failed to find Cargo.toml files in root directory: {}",
773+
e.to_string()
774+
)
775+
})
776+
.and_then(|output| {
777+
let mut options = vec![];
778+
for path in String::from_utf8(output.stdout)?.split("\n") {
779+
match get_lib_name_from_cargo_toml(path) {
780+
Ok(name) => {
781+
options.push(name);
782+
}
783+
Err(_) => {
784+
continue;
785+
}
786+
}
787+
}
788+
if options.len() != 1 {
789+
println!(
790+
"Found multiple possible targets in root directory: {:?}",
791+
options
792+
);
793+
println!(
794+
"Please explicitly specify the target with the --package-name <name> option",
795+
);
796+
Err(anyhow::format_err!(
797+
"Failed to find unique Cargo.toml file in root directory"
798+
))
799+
} else {
800+
Ok(options[0].clone())
801+
}
802+
})?
803+
}
804+
};
805+
args.push(&library_name);
806+
println!("Verifying program: {}", library_name);
807+
808+
if let Some(base_image) = &base_image {
809+
args.push("--base-image");
810+
args.push(base_image);
811+
}
812+
813+
if bpf_flag {
814+
args.push("--bpf");
815+
}
816+
817+
if !cargo_args.clone().is_empty() {
818+
args.push("--");
819+
for arg in &cargo_args {
820+
args.push(arg);
821+
}
822+
}
823+
824+
let x = upload_program(
825+
repo_url,
826+
&commit_hash.clone(),
827+
args.iter().map(|&s| s.into()).collect(),
828+
program_id,
829+
connection_url,
830+
skip_prompt,
831+
)
832+
.await;
833+
if x.is_err() {
834+
println!("Error uploading program: {:?}", x);
835+
exit(1);
836+
}
746837
return Ok(());
747838
}
748839
// Create a Vec to store solana-verify args
@@ -896,6 +987,7 @@ pub async fn verify_from_repo(
896987
args.iter().map(|&s| s.into()).collect(),
897988
program_id,
898989
connection_url,
990+
skip_prompt,
899991
)
900992
.await;
901993
if x.is_err() {

src/solana_program.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,9 @@ pub async fn upload_program(
134134
args: Vec<String>,
135135
program_address: Pubkey,
136136
connection_url: Option<String>,
137+
skip_prompt: bool,
137138
) -> anyhow::Result<()> {
138-
if prompt_user_input(
139+
if skip_prompt || prompt_user_input(
139140
"Do you want to upload the program verification to the Solana Blockchain? (y/n) ",
140141
) {
141142
println!("Uploading the program verification params to the Solana blockchain...");

0 commit comments

Comments
 (0)