Skip to content

Commit

Permalink
Deserialize metadata (#368)
Browse files Browse the repository at this point in the history
* Expose public metadata fields

* Implement full metadata decoding

* Fix clippy warning

* Fix wasm serialization

* Add comments

* Added test

* Fmt

* Update CHANGELOG.md
  • Loading branch information
ascjones authored Nov 25, 2021
1 parent b8e3076 commit 7182997
Show file tree
Hide file tree
Showing 5 changed files with 338 additions and 73 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed
- Use of `-Clinker-plugin-lto` flag(reduces the size of the contract) if `lto` is enabled - [#358](https://github.com/paritytech/cargo-contract/pull/358)
- Deserialize metadata - [#368](https://github.com/paritytech/cargo-contract/pull/368)

### Added
- Disabled overflow checks in the `cargo contract new` template - [#372](https://github.com/paritytech/cargo-contract/pull/372)
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions metadata/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ include = ["Cargo.toml", "*.rs", "LICENSE"]
path = "lib.rs"

[dependencies]
impl-serde = "0.3.2"
semver = { version = "1.0.4", features = ["serde"] }
serde = { version = "1.0.130", default-features = false, features = ["derive"] }
serde_json = "1.0.71"
Expand Down
97 changes: 97 additions & 0 deletions metadata/byte_str.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// Copyright 2018-2021 Parity Technologies (UK) Ltd.
// This file is part of cargo-contract.
//
// cargo-contract is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// cargo-contract is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with cargo-contract. If not, see <http://www.gnu.org/licenses/>.

use impl_serde::serialize as serde_hex;

/// Serializes the given bytes as byte string.
pub fn serialize_as_byte_str<S>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
if bytes.is_empty() {
// Return empty string without prepended `0x`.
return serializer.serialize_str("");
}
serde_hex::serialize(bytes, serializer)
}

/// Deserializes the given hex string with optional `0x` prefix.
pub fn deserialize_from_byte_str<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
where
D: serde::Deserializer<'de>,
{
struct Visitor;

impl<'b> serde::de::Visitor<'b> for Visitor {
type Value = Vec<u8>;

fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(formatter, "hex string with optional 0x prefix")
}

fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<Self::Value, E> {
let result = from_hex(v);
result.map_err(E::custom)
}

fn visit_string<E: serde::de::Error>(self, v: String) -> Result<Self::Value, E> {
self.visit_str(&v)
}
}

deserializer.deserialize_str(Visitor)
}

/// Deserializes the given hex string with optional `0x` prefix.
pub fn deserialize_from_byte_str_array<'de, D>(deserializer: D) -> Result<[u8; 32], D::Error>
where
D: serde::Deserializer<'de>,
{
struct Visitor;

impl<'b> serde::de::Visitor<'b> for Visitor {
type Value = [u8; 32];

fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(formatter, "hex string with optional 0x prefix")
}

fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<Self::Value, E> {
let result = from_hex(v).map_err(E::custom)?;
if result.len() != 32 {
Err(E::custom("Expected exactly 32 bytes"))
} else {
let mut arr = [0u8; 32];
arr.copy_from_slice(&result[..]);
Ok(arr)
}
}

fn visit_string<E: serde::de::Error>(self, v: String) -> Result<Self::Value, E> {
self.visit_str(&v)
}
}

deserializer.deserialize_str(Visitor)
}

fn from_hex(v: &str) -> Result<Vec<u8>, serde_hex::FromHexError> {
if v.starts_with("0x") {
serde_hex::from_hex(v)
} else {
serde_hex::from_hex(&format!("0x{}", v))
}
}
Loading

0 comments on commit 7182997

Please sign in to comment.