Skip to content

Commit

Permalink
Hashing proc macro utils (paritytech#9875)
Browse files Browse the repository at this point in the history
* hashing macro

* fmt

* use in easy place, and fix blake sizes

* fix

* Fixes, docs.
Allow ident as input.

* fix doc tests

* update error in test (nmapkey and key are same type).

* hashing crates under sp_core

* Doc updates and format.

* use all existing hashing functions.

* return array of u8

* Update primitives/core/hashing/proc-macro/src/impls.rs

Co-authored-by: Bastian Köcher <[email protected]>

* ToTokeen for an array of u8

* fix

* re

* Improve impls

* complete doc tests

* fmt

* fix doctest format

* fix ui test (nmap key type alias)

Co-authored-by: Bastian Köcher <[email protected]>
Co-authored-by: Bastian Köcher <[email protected]>
  • Loading branch information
3 people authored Nov 2, 2021
1 parent 0210ea0 commit 0465b0b
Show file tree
Hide file tree
Showing 14 changed files with 553 additions and 149 deletions.
26 changes: 26 additions & 0 deletions Cargo.lock

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

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ members = [
"primitives/consensus/pow",
"primitives/consensus/vrf",
"primitives/core",
"primitives/core/hashing",
"primitives/core/hashing/proc-macro",
"primitives/database",
"primitives/debug-derive",
"primitives/externalities",
Expand Down
1 change: 1 addition & 0 deletions client/executor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ sc-executor-wasmtime = { version = "0.10.0-dev", path = "wasmtime", optional = t
parking_lot = "0.11.1"
log = "0.4.8"
libsecp256k1 = "0.6"
sp-core-hashing-proc-macro = { version = "4.0.0-dev", path = "../../primitives/core/hashing/proc-macro" }

[dev-dependencies]
wat = "1.0"
Expand Down
2 changes: 1 addition & 1 deletion client/executor/src/wasm_runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ fn decode_version(mut version: &[u8]) -> Result<RuntimeVersion, WasmError> {
})?
.into();

let core_api_id = sp_core::hashing::blake2_64(b"Core");
let core_api_id = sp_core_hashing_proc_macro::blake2b_64!(b"Core");
if v.has_api_with(&core_api_id, |v| v >= 3) {
sp_api::RuntimeVersion::decode(&mut version).map_err(|_| {
WasmError::Instantiation("failed to decode \"Core_version\" result".into())
Expand Down
1 change: 1 addition & 0 deletions frame/support/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ bitflags = "1.3"
impl-trait-for-tuples = "0.2.1"
smallvec = "1.7.0"
log = { version = "0.4.14", default-features = false }
sp-core-hashing-proc-macro = { version = "4.0.0-dev", path = "../../primitives/core/hashing/proc-macro" }

[dev-dependencies]
assert_matches = "1.3.0"
Expand Down
6 changes: 3 additions & 3 deletions frame/support/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ pub use scale_info;
pub use serde;
pub use sp_core::Void;
#[doc(hidden)]
pub use sp_core_hashing_proc_macro;
#[doc(hidden)]
pub use sp_io::{self, storage::root as storage_root};
#[doc(hidden)]
pub use sp_runtime::RuntimeDebug;
Expand Down Expand Up @@ -427,9 +429,7 @@ macro_rules! parameter_types {
/// Returns the key for this parameter type.
#[allow(unused)]
pub fn key() -> [u8; 16] {
$crate::sp_io::hashing::twox_128(
concat!(":", stringify!($name), ":").as_bytes()
)
$crate::sp_core_hashing_proc_macro::twox_128!(b":", $name, b":")
}

/// Set the value of this parameter type in the storage.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ error[E0277]: the trait bound `Bar: MaxEncodedLen` is not satisfied
10 | #[pallet::generate_storage_info]
| ^^^^^^^^^^^^^^^^^^^^^ the trait `MaxEncodedLen` is not implemented for `Bar`
|
= note: required because of the requirements on the impl of `KeyGeneratorMaxEncodedLen` for `Key<frame_support::Twox64Concat, Bar>`
= note: required because of the requirements on the impl of `StorageInfoTrait` for `frame_support::pallet_prelude::StorageNMap<_GeneratedPrefixForStorageFoo<T>, Key<frame_support::Twox64Concat, Bar>, u32>`
= note: required because of the requirements on the impl of `KeyGeneratorMaxEncodedLen` for `NMapKey<frame_support::Twox64Concat, Bar>`
= note: required because of the requirements on the impl of `StorageInfoTrait` for `frame_support::pallet_prelude::StorageNMap<_GeneratedPrefixForStorageFoo<T>, NMapKey<frame_support::Twox64Concat, Bar>, u32>`
note: required by `storage_info`
--> $DIR/storage.rs:71:2
|
Expand Down
4 changes: 4 additions & 0 deletions primitives/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ sha2 = { version = "0.9.8", default-features = false, optional = true }
hex = { version = "0.4", default-features = false, optional = true }
twox-hash = { version = "1.6.1", default-features = false, optional = true }
libsecp256k1 = { version = "0.6", default-features = false, features = ["hmac", "static-context"], optional = true }
sp-core-hashing = { version = "4.0.0-dev", path = "./hashing", default-features = false, optional = true }
merlin = { version = "2.0", default-features = false, optional = true }
ss58-registry = "1.0.0"
sp-runtime-interface = { version = "4.0.0-dev", default-features = false, path = "../runtime-interface" }
Expand All @@ -76,6 +77,7 @@ hex-literal = "0.3.3"
rand = "0.7.2"
criterion = "0.3.3"
serde_json = "1.0"
sp-core-hashing-proc-macro = { version = "4.0.0-dev", path = "./hashing/proc-macro" }

[[bench]]
name = "bench"
Expand Down Expand Up @@ -118,6 +120,7 @@ std = [
"regex",
"num-traits/std",
"tiny-keccak",
"sp-core-hashing/std",
"sp-debug-derive/std",
"sp-externalities",
"sp-storage/std",
Expand All @@ -142,6 +145,7 @@ full_crypto = [
"sha2",
"twox-hash",
"libsecp256k1",
"sp-core-hashing",
"sp-runtime-interface/disable_target_static_assertions",
"merlin",
]
31 changes: 31 additions & 0 deletions primitives/core/hashing/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[package]
name = "sp-core-hashing"
version = "4.0.0-dev"
authors = ["Parity Technologies <[email protected]>"]
edition = "2018"
license = "Apache-2.0"
homepage = "https://substrate.dev"
repository = "https://github.com/paritytech/substrate/"
description = "Primitive core crate hashing implementation."
documentation = "https://docs.rs/sp-core-hashing"

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
sp-std = { version = "4.0.0-dev", default-features = false, path = "../../std" }
byteorder = { version = "1.3.2", default-features = false }

blake2-rfc = { version = "0.2.18", default-features = false }
tiny-keccak = { version = "2.0.1", features = ["keccak"] }
sha2 = { version = "0.9.2", default-features = false }
twox-hash = { version = "1.5.0", default-features = false }

[features]
default = ["std"]
std = [
"blake2-rfc/std",
"sha2/std",
"sp-std/std",
"twox-hash/std",
]
22 changes: 22 additions & 0 deletions primitives/core/hashing/proc-macro/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[package]
name = "sp-core-hashing-proc-macro"
version = "4.0.0-dev"
authors = ["Parity Technologies <[email protected]>"]
edition = "2018"
license = "Apache-2.0"
homepage = "https://substrate.dev"
repository = "https://github.com/paritytech/substrate/"
description = "This crate provides procedural macros for calculating static hash."
documentation = "https://docs.rs/sp-core-hashing-proc-macro"

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

[lib]
proc-macro = true

[dependencies]
syn = { version = "1.0.77", features = ["full", "parsing"] }
quote = "1.0.6"
proc-macro2 = "1.0.29"
sp-core-hashing = { version = "4.0.0-dev", path = "../", default-features = false }
124 changes: 124 additions & 0 deletions primitives/core/hashing/proc-macro/src/impls.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
// This file is part of Substrate.

// Copyright (C) 2021 Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0

// 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.

use quote::quote;
use syn::parse::{Parse, ParseStream};

use proc_macro::TokenStream;

pub(super) struct InputBytes(pub Vec<u8>);

pub(super) struct MultipleInputBytes(pub Vec<Vec<u8>>);

impl MultipleInputBytes {
pub(super) fn concatenated(mut self) -> Vec<u8> {
if self.0.len() == 0 {
Vec::new()
} else {
let mut result = core::mem::take(&mut self.0[0]);
for other in self.0[1..].iter_mut() {
result.append(other);
}
result
}
}
}

impl Parse for InputBytes {
fn parse(input: ParseStream) -> syn::Result<Self> {
match syn::ExprArray::parse(input) {
Ok(array) => {
let mut bytes = Vec::<u8>::new();
for expr in array.elems.iter() {
match expr {
syn::Expr::Lit(lit) => match &lit.lit {
syn::Lit::Int(b) => bytes.push(b.base10_parse()?),
syn::Lit::Byte(b) => bytes.push(b.value()),
_ =>
return Err(syn::Error::new(
input.span(),
"Expected array of u8 elements.".to_string(),
)),
},
_ =>
return Err(syn::Error::new(
input.span(),
"Expected array of u8 elements.".to_string(),
)),
}
}
return Ok(InputBytes(bytes))
},
Err(_e) => (),
}
// use rust names as a vec of their utf8 bytecode.
match syn::Ident::parse(input) {
Ok(ident) => return Ok(InputBytes(ident.to_string().as_bytes().to_vec())),
Err(_e) => (),
}
Ok(InputBytes(syn::LitByteStr::parse(input)?.value()))
}
}

impl Parse for MultipleInputBytes {
fn parse(input: ParseStream) -> syn::Result<Self> {
let elts =
syn::punctuated::Punctuated::<InputBytes, syn::token::Comma>::parse_terminated(input)?;
Ok(MultipleInputBytes(elts.into_iter().map(|elt| elt.0).collect()))
}
}

pub(super) fn twox_64(bytes: Vec<u8>) -> TokenStream {
bytes_to_array(sp_core_hashing::twox_64(bytes.as_slice()))
}

pub(super) fn twox_128(bytes: Vec<u8>) -> TokenStream {
bytes_to_array(sp_core_hashing::twox_128(bytes.as_slice()))
}

pub(super) fn blake2b_512(bytes: Vec<u8>) -> TokenStream {
bytes_to_array(sp_core_hashing::blake2_512(bytes.as_slice()))
}

pub(super) fn blake2b_256(bytes: Vec<u8>) -> TokenStream {
bytes_to_array(sp_core_hashing::blake2_256(bytes.as_slice()))
}

pub(super) fn blake2b_64(bytes: Vec<u8>) -> TokenStream {
bytes_to_array(sp_core_hashing::blake2_64(bytes.as_slice()))
}

pub(super) fn keccak_256(bytes: Vec<u8>) -> TokenStream {
bytes_to_array(sp_core_hashing::keccak_256(bytes.as_slice()))
}

pub(super) fn keccak_512(bytes: Vec<u8>) -> TokenStream {
bytes_to_array(sp_core_hashing::keccak_512(bytes.as_slice()))
}

pub(super) fn sha2_256(bytes: Vec<u8>) -> TokenStream {
bytes_to_array(sp_core_hashing::sha2_256(bytes.as_slice()))
}

fn bytes_to_array(bytes: impl IntoIterator<Item = u8>) -> TokenStream {
let bytes = bytes.into_iter();

quote!(
[ #( #bytes ),* ]
)
.into()
}
Loading

0 comments on commit 0465b0b

Please sign in to comment.