diff --git a/Cargo.lock b/Cargo.lock index 32a6a15d69..fc8d501264 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3178,6 +3178,15 @@ dependencies = [ "yasna 0.3.1", ] +[[package]] +name = "itp-binary-merkle-tree" +version = "0.8.0" +dependencies = [ + "binary-merkle-tree", + "parity-scale-codec", + "serde 1.0.193", +] + [[package]] name = "itp-component-container" version = "0.8.0" diff --git a/Cargo.toml b/Cargo.toml index cdae016af3..a850abc167 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ members = [ "core/rpc-server", "core/tls-websocket-server", "core-primitives/attestation-handler", + "core-primitives/binary-merkle-tree", "core-primitives/import-queue", "core-primitives/component-container", "core-primitives/enclave-api", diff --git a/core-primitives/binary-merkle-tree/Cargo.toml b/core-primitives/binary-merkle-tree/Cargo.toml new file mode 100644 index 0000000000..ab2acb0250 --- /dev/null +++ b/core-primitives/binary-merkle-tree/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "itp-binary-merkle-tree" +version = "0.8.0" +edition = "2021" + +[dependencies] +parity-scale-codec = { version = "3.0.0", default-features = false, features = ["derive"], package = "parity-scale-codec" } +serde = { version = "1.0", default-features = false, features = ["derive", "alloc"] } + +binary-merkle-tree = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } + +[features] +std = [ + "parity-scale-codec/std", + "serde/std", + "binary-merkle-tree/std", +] diff --git a/core-primitives/binary-merkle-tree/src/lib.rs b/core-primitives/binary-merkle-tree/src/lib.rs new file mode 100644 index 0000000000..9dc9ecd364 --- /dev/null +++ b/core-primitives/binary-merkle-tree/src/lib.rs @@ -0,0 +1,67 @@ +/* + Copyright 2021 Integritee AG and Supercomputing Systems AG + Copyright (C) 2017-2019 Baidu, Inc. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ + +// Todo: I think we can upstream the codec change, then we can delete this crate. + +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg(not(feature = "std"))] +extern crate alloc; +#[cfg(not(feature = "std"))] +use alloc::vec::Vec; + +use parity_scale_codec::{Decode, Encode}; +use serde::{Deserialize, Serialize}; + +// re-export the original one implementing all the merkle/logic. +pub use binary_merkle_tree::{merkle_proof, merkle_root, verify_proof, MerkleProof}; + +/// Custom Merkle proof that implements codec +/// The difference to the original one is that implements the scale-codec and that the fields contain u32 instead of usize. +#[derive(Debug, PartialEq, Eq, Decode, Encode, Deserialize, Serialize)] +pub struct MerkleProofWithCodec { + /// Root hash of generated merkle tree. + pub root: H, + /// Proof items (does not contain the leaf hash, nor the root obviously). + /// + /// This vec contains all inner node hashes necessary to reconstruct the root hash given the + /// leaf hash. + pub proof: Vec, + /// Number of leaves in the original tree. + /// + /// This is needed to detect a case where we have an odd number of leaves that "get promoted" + /// to upper layers. + pub number_of_leaves: u64, + /// Index of the leaf the proof is for (0-based). + pub leaf_index: u64, + /// Leaf content. + pub leaf: L, +} + +impl From> for MerkleProofWithCodec { + fn from(source: MerkleProof) -> Self { + Self { + root: source.root, + proof: source.proof, + // usize as u64 can't panic + number_of_leaves: source.number_of_leaves as u64, + leaf_index: source.leaf_index as u64, + leaf: source.leaf, + } + } +}