1mod helpers;
4
5use crate::{BuildMode, Error, ImageVariant, Verbosity};
6use pop_common::Docker;
7use std::path::PathBuf;
8
9pub struct DeployedContract {
11 pub rpc_endpoint: String,
13 pub contract_address: String,
15 pub build_image: ImageVariant,
17}
18
19enum ReferenceContract {
21 Local(PathBuf),
22 Deployed(DeployedContract),
23}
24
25pub struct VerifyContract {
27 verifying_path: PathBuf,
29 reference_contract: ReferenceContract,
31}
32
33impl VerifyContract {
34 pub fn new_local(verifying_path: PathBuf, reference_contract_bundle_path: PathBuf) -> Self {
40 Self {
41 verifying_path,
42 reference_contract: ReferenceContract::Local(reference_contract_bundle_path),
43 }
44 }
45
46 pub fn new_deployed(
52 verifying_path: PathBuf,
53 reference_deployed_contract: DeployedContract,
54 ) -> Self {
55 Self {
56 verifying_path,
57 reference_contract: ReferenceContract::Deployed(reference_deployed_contract),
58 }
59 }
60
61 pub async fn execute(self) -> Result<(), Error> {
63 let (build_mode, image, reference_code_hash) = match self.reference_contract {
64 ReferenceContract::Local(reference_path) => {
65 let build_info_parsed =
67 helpers::get_build_info_parsed_from_contract_bundle(&reference_path)?;
68
69 if let BuildMode::Verifiable = &build_info_parsed.build_mode {
73 Docker::ensure_running().await?;
74 } else {
75 helpers::compare_local_toolchain(&build_info_parsed.build_info)?;
76 }
77
78 (
79 build_info_parsed.build_mode,
80 build_info_parsed.image,
81 build_info_parsed.polkavm_code_hash,
82 )
83 },
84 ReferenceContract::Deployed(deployed_contract) => {
85 let reference_code_hash = helpers::get_deployed_polkavm_code_hash(
86 &deployed_contract.rpc_endpoint,
87 &deployed_contract.contract_address,
88 )
89 .await?;
90
91 Docker::ensure_running().await?;
93
94 (BuildMode::Verifiable, Some(deployed_contract.build_image), reference_code_hash)
95 },
96 };
97
98 let mut build_results = crate::build_smart_contract(
99 &self.verifying_path,
100 build_mode,
101 Verbosity::default(),
102 None,
103 image,
104 )?;
105
106 if build_results.len() == 1 {
107 helpers::verify_polkavm_code_hash_against_build_result(
108 reference_code_hash,
109 build_results.pop().expect("There's one build result; qed;"),
110 )?;
111 } else {
112 return Err(Error::Verification(format!(
113 "Only can run verification against 1 contract, found {} in the worsskpace",
114 build_results.len()
115 )));
116 }
117
118 Ok(())
119 }
120}