diff --git a/Cargo.lock b/Cargo.lock index d81ed52b9..b17f5291c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -641,6 +641,7 @@ checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" name = "contract-metadata" version = "2.0.0-alpha.4" dependencies = [ + "anyhow", "impl-serde 0.4.0", "pretty_assertions", "semver", diff --git a/crates/cargo-contract/src/cmd/extrinsics/upload.rs b/crates/cargo-contract/src/cmd/extrinsics/upload.rs index 6dcccf455..7087c9cbd 100644 --- a/crates/cargo-contract/src/cmd/extrinsics/upload.rs +++ b/crates/cargo-contract/src/cmd/extrinsics/upload.rs @@ -71,7 +71,14 @@ impl UploadCommand { let crate_metadata = CrateMetadata::from_manifest_path( self.extrinsic_opts.manifest_path.as_ref(), )?; - let transcoder = ContractMessageTranscoder::load(crate_metadata.metadata_path())?; + let contract_metadata = + contract_metadata::ContractMetadata::load(&crate_metadata.metadata_path())?; + let code_hash = contract_metadata.source.hash; + let transcoder = + ContractMessageTranscoder::try_from(contract_metadata).context(format!( + "Failed to deserialize ink project metadata from contract metadata {}", + crate_metadata.metadata_path().display() + ))?; let signer = super::pair_signer(self.extrinsic_opts.signer()?); let wasm_path = match &self.wasm_path { @@ -126,7 +133,11 @@ impl UploadCommand { } Ok(()) } else { - Err("This contract has already been uploaded".into()) + Err(anyhow::anyhow!( + "This contract has already been uploaded with code hash: {:?}", + code_hash + ) + .into()) } }) } diff --git a/crates/metadata/Cargo.toml b/crates/metadata/Cargo.toml index 2942b2ec3..98f434ad3 100644 --- a/crates/metadata/Cargo.toml +++ b/crates/metadata/Cargo.toml @@ -19,6 +19,7 @@ semver = { version = "1.0.14", features = ["serde"] } serde = { version = "1.0.146", default-features = false, features = ["derive"] } serde_json = "1.0.87" url = { version = "2.3.1", features = ["serde"] } +anyhow = "1.0.66" [dev-dependencies] pretty_assertions = "1.3.0" diff --git a/crates/metadata/src/lib.rs b/crates/metadata/src/lib.rs index 4735dabaf..9943f0c7d 100644 --- a/crates/metadata/src/lib.rs +++ b/crates/metadata/src/lib.rs @@ -58,6 +58,10 @@ mod byte_str; +use anyhow::{ + Context, + Result, +}; use semver::Version; use serde::{ de, @@ -75,6 +79,8 @@ use std::{ Formatter, Result as DisplayResult, }, + fs::File, + path::Path, str::FromStr, }; use url::Url; @@ -113,10 +119,24 @@ impl ContractMetadata { pub fn remove_source_wasm_attribute(&mut self) { self.source.wasm = None; } + + /// Reads the file and tries to parse it as instance of `ContractMetadata`. + pub fn load

(metadata_path: &P) -> Result + where + P: AsRef, + { + let path = metadata_path.as_ref(); + let file = File::open(path) + .context(format!("Failed to open metadata file {}", path.display()))?; + serde_json::from_reader(file).context(format!( + "Failed to deserialize metadata file {}", + path.display() + )) + } } /// Representation of the Wasm code hash. -#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)] +#[derive(Clone, Copy, Debug, Eq, PartialEq, Deserialize, Serialize)] pub struct CodeHash( #[serde( serialize_with = "byte_str::serialize_as_byte_str", diff --git a/crates/transcode/src/lib.rs b/crates/transcode/src/lib.rs index b0b9626c2..85909504a 100644 --- a/crates/transcode/src/lib.rs +++ b/crates/transcode/src/lib.rs @@ -137,7 +137,6 @@ use scale_info::{ }; use std::{ fmt::Debug, - fs::File, path::Path, }; @@ -166,13 +165,8 @@ impl ContractMessageTranscoder { P: AsRef, { let path = metadata_path.as_ref(); - let file = File::open(path) - .context(format!("Failed to open metadata file {}", path.display()))?; - let metadata: contract_metadata::ContractMetadata = serde_json::from_reader(file) - .context(format!( - "Failed to deserialize metadata file {}", - path.display() - ))?; + let metadata: contract_metadata::ContractMetadata = + contract_metadata::ContractMetadata::load(&metadata_path)?; let ink_metadata = serde_json::from_value(serde_json::Value::Object( metadata.abi, )) @@ -344,6 +338,18 @@ impl ContractMessageTranscoder { } } +impl TryFrom for ContractMessageTranscoder { + type Error = anyhow::Error; + + fn try_from( + metadata: contract_metadata::ContractMetadata, + ) -> Result { + Ok(Self::new(serde_json::from_value( + serde_json::Value::Object(metadata.abi), + )?)) + } +} + #[derive(Debug)] pub enum CompositeTypeFields { Named(Vec),