diff --git a/Cargo.lock b/Cargo.lock index d420016..f9c3a97 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5606,6 +5606,7 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.66", + "twox-hash", ] [[package]] diff --git a/xcq-extension/procedural/Cargo.toml b/xcq-extension/procedural/Cargo.toml index dba8d6c..a278247 100644 --- a/xcq-extension/procedural/Cargo.toml +++ b/xcq-extension/procedural/Cargo.toml @@ -13,3 +13,4 @@ proc-macro = true syn = { version = "2", features = ["full", "extra-traits"] } quote = "1" proc-macro2 = "1" +twox-hash = "1.6.3" diff --git a/xcq-extension/procedural/src/lib.rs b/xcq-extension/procedural/src/lib.rs index 0251c96..21c05e0 100644 --- a/xcq-extension/procedural/src/lib.rs +++ b/xcq-extension/procedural/src/lib.rs @@ -1,6 +1,6 @@ use proc_macro2::TokenStream; use quote::quote; -use std::hash::Hasher; +use std::hash::{Hash, Hasher}; use syn::token::Comma; use syn::{parse_macro_input, parse_quote, parse_str, spanned::Spanned}; use syn::{punctuated::Punctuated, ExprCall, Field, Ident, ItemImpl, Pat, TraitItem, Variant}; @@ -116,7 +116,7 @@ fn dispatchable_impl(trait_ident: &Ident, methods: &[Method]) -> TokenStream { } fn extension_id_impl(trait_ident: &Ident, trait_items: &[TraitItem]) -> ItemImpl { - let extension_id = calculate_hash(trait_items); + let extension_id = calculate_hash(trait_ident, trait_items); parse_quote! { impl xcq_extension::ExtensionId for Call { const EXTENSION_ID: xcq_extension::ExtensionIdTy = #extension_id; @@ -165,11 +165,14 @@ fn replace_self_to_impl(ty: &syn::Type) -> syn::Result> { Ok(Box::new(modified_ty)) } -// TODO: may rely on whole syn::File where we can replace the type alias to get stable hash results -// Or we rejects the type alias -// TODO: check hasher implementation is collision resistant and stable -fn calculate_hash(trait_items: &[TraitItem]) -> u64 { - let mut hasher = std::hash::DefaultHasher::new(); - std::hash::Hash::hash_slice(trait_items, &mut hasher); +// TODO: currently we only hash on trait ident and function names, +fn calculate_hash(trait_ident: &Ident, trait_items: &[TraitItem]) -> u64 { + let mut hasher = twox_hash::XxHash64::default(); + trait_ident.hash(&mut hasher); + for trait_item in trait_items { + if let TraitItem::Fn(method) = trait_item { + method.sig.ident.hash(&mut hasher); + } + } hasher.finish() } diff --git a/xcq-extension/tests/extension_executor_works.rs b/xcq-extension/tests/extension_executor_works.rs index 1c1ce63..7756df6 100644 --- a/xcq-extension/tests/extension_executor_works.rs +++ b/xcq-extension/tests/extension_executor_works.rs @@ -121,7 +121,7 @@ fn call_core_works() { let mut executor = ExtensionsExecutor::::new(InvokeSource::RuntimeAPI); let guest = GuestImpl { program: blob.to_vec() }; let method = CoreMethod::HasExtension { id: 0 }; - let mut input_data = 16086776565154421753u64.encode(); + let mut input_data = 980409741042475474u64.encode(); input_data.extend_from_slice(&method.encode()); let input = InputImpl { method: "main".to_string(), @@ -137,7 +137,7 @@ fn call_fungibles_works() { let mut executor = ExtensionsExecutor::::new(InvokeSource::RuntimeAPI); let guest = GuestImpl { program: blob.to_vec() }; let method = FungiblesMethod::TotalSupply { asset: 1u64 }; - let mut input_data = 18438207628271534596u64.encode(); + let mut input_data = 10604941536775757594u64.encode(); input_data.extend_from_slice(&method.encode()); let input = InputImpl { method: "main".to_string(),