1use crate::std::borrow::ToOwned;
3
4#[cfg(all(any(feature = "merkle-lean", test), not(feature = "std")))]
5use core::any::TypeId;
6#[cfg(all(any(feature = "merkle-lean", test), feature = "std"))]
7use std::any::TypeId;
8
9#[cfg(any(feature = "merkle-standard", feature = "merkle-lean", test))]
10use crate::std::vec::Vec;
11
12#[cfg(any(feature = "merkle-lean", feature = "merkle-standard", test))]
13use external_memory_tools::AddressableBuffer;
14use external_memory_tools::ExternalMemory;
15
16#[cfg(any(feature = "merkle-standard", test))]
17use frame_metadata::v15::RuntimeMetadataV15;
18
19#[cfg(any(feature = "merkle-standard", test))]
20use merkle_cbt::{merkle_tree::Merge, CBMT};
21
22#[cfg(any(feature = "merkle-lean", test))]
23use merkle_cbt_lean::{Hasher, Leaf, MerkleProof};
24
25use parity_scale_codec::{Decode, Encode};
26
27#[cfg(any(feature = "merkle-lean", test))]
28use scale_info::interner::UntrackedSymbol;
29#[cfg(any(feature = "merkle-standard", test))]
30use scale_info::PortableType;
31use scale_info::{form::PortableForm, PortableRegistry, Type, TypeDef};
32
33#[cfg(any(feature = "merkle-lean", test))]
34use substrate_parser::traits::{SignedExtensionMetadata, SpecNameVersion};
35use substrate_parser::{error::RegistryError, traits::ResolveType};
36#[cfg(any(feature = "merkle-lean", feature = "merkle-standard", test))]
37use substrate_parser::{
38 error::SignableError, parse_transaction, parse_transaction_unmarked, traits::AsMetadata,
39 ShortSpecs, TransactionParsed, TransactionUnmarkedParsed,
40};
41
42#[cfg(any(feature = "merkle-lean", feature = "merkle-standard", test))]
43use crate::cutter::MetadataDescriptor;
44#[cfg(any(feature = "merkle-lean", test))]
45use crate::cutter::ShortMetadata;
46use crate::cutter::{add_as_enum, add_ty_as_regular, DraftRegistry, LeavesRegistry, ShortRegistry};
47
48#[cfg(any(feature = "merkle-lean", feature = "merkle-standard", test))]
49use crate::error::MetaCutError;
50#[cfg(any(feature = "merkle-lean", test))]
51use crate::error::MetadataDescriptorError;
52use crate::error::RegistryCutError;
53
54pub const LEN: usize = 32;
56
57#[derive(Debug)]
59pub struct Blake3Hasher;
60
61#[cfg(any(feature = "merkle-lean", test))]
62impl Hasher<LEN> for Blake3Hasher {
63 fn make(bytes: &[u8]) -> [u8; LEN] {
64 blake3::hash(bytes).into()
65 }
66 fn merge(left: &[u8; LEN], right: &[u8; LEN]) -> [u8; LEN] {
67 blake3::hash(&[left.as_slice(), right.as_slice()].concat()).into()
68 }
69}
70
71#[cfg(any(feature = "merkle-lean", test))]
75pub type MerkleProofMetadata<L, E> = MerkleProof<LEN, L, E, Blake3Hasher>;
76
77#[derive(Copy, Clone, Debug, Decode, Encode, Eq, PartialEq)]
80pub struct Blake3Leaf([u8; LEN]);
81
82#[cfg(any(feature = "proof-gen", test))]
83impl<E: ExternalMemory> Leaf<LEN, E> for Blake3Leaf {
84 fn read(&self, _ext_memory: &mut E) -> Result<[u8; LEN], E::ExternalMemoryError> {
85 Ok(self.0)
86 }
87 fn write(value: [u8; LEN], _ext_memory: &mut E) -> Result<Self, E::ExternalMemoryError> {
88 Ok(Self(value))
89 }
90}
91
92#[cfg(any(feature = "merkle-standard", test))]
93impl Merge for Blake3Hasher {
94 type Item = [u8; LEN];
95 fn merge(left: &Self::Item, right: &Self::Item) -> Self::Item {
96 blake3::hash(&[*left, *right].concat()).into()
97 }
98}
99
100#[cfg(any(feature = "merkle-standard", test))]
105pub fn blake3_leaf<T: Encode>(value: &T) -> [u8; LEN] {
106 blake3::hash(value.encode().as_ref()).into()
107}
108
109#[cfg(any(feature = "merkle-lean", feature = "merkle-standard", test))]
111pub trait HashableMetadata<E: ExternalMemory>: AsMetadata<E>
112where
113 <Self as AsMetadata<E>>::TypeRegistry: HashableRegistry<E>,
114{
115 fn types_merkle_root(&self, ext_memory: &mut E) -> Result<[u8; LEN], MetaCutError<E, Self>>;
121
122 fn digest_with_short_specs(
124 &self,
125 short_specs: &ShortSpecs,
126 ext_memory: &mut E,
127 ) -> Result<[u8; LEN], MetaCutError<E, Self>> {
128 let types_merkle_root = self.types_merkle_root(ext_memory)?;
129 let metadata_descriptor = MetadataDescriptor::V1 {
130 call_ty: self
131 .call_ty()
132 .map_err(|e| MetaCutError::Signable(SignableError::MetaStructure(e)))?,
133 signed_extensions: self
134 .signed_extensions()
135 .map_err(|e| MetaCutError::Signable(SignableError::MetaStructure(e)))?,
136 spec_name_version: self
137 .spec_name_version()
138 .map_err(|e| MetaCutError::Signable(SignableError::MetaStructure(e)))?,
139 base58prefix: short_specs.base58prefix,
140 decimals: short_specs.decimals,
141 unit: short_specs.unit.to_owned(),
142 };
143 #[cfg(all(feature = "merkle-standard", not(test)))]
144 {
145 let metadata_descriptor_blake3 =
146 blake3_leaf::<MetadataDescriptor>(&metadata_descriptor);
147 Ok(<Blake3Hasher as Merge>::merge(
148 &types_merkle_root,
149 &metadata_descriptor_blake3,
150 ))
151 }
152 #[cfg(any(not(feature = "merkle-standard"), test))]
153 {
154 let metadata_descriptor_blake3 = Blake3Hasher::make(&metadata_descriptor.encode());
155 Ok(<Blake3Hasher as Hasher<LEN>>::merge(
156 &types_merkle_root,
157 &metadata_descriptor_blake3,
158 ))
159 }
160 }
161}
162
163#[cfg(any(feature = "merkle-lean", feature = "merkle-standard", test))]
165pub trait ExtendedMetadata<E: ExternalMemory>: HashableMetadata<E> + Sized
166where
167 <Self as AsMetadata<E>>::TypeRegistry: HashableRegistry<E>,
168{
169 fn to_specs(&self) -> Result<ShortSpecs, <Self as AsMetadata<E>>::MetaStructureError>;
171
172 fn digest(&self, ext_memory: &mut E) -> Result<[u8; LEN], MetaCutError<E, Self>> {
174 self.digest_with_short_specs(
175 &self
176 .to_specs()
177 .map_err(|e| MetaCutError::Signable(SignableError::MetaStructure(e)))?,
178 ext_memory,
179 )
180 }
181
182 fn parse_transaction<B>(
193 &self,
194 data: &B,
195 ext_memory: &mut E,
196 ) -> Result<TransactionParsed<E, Self>, SignableError<E, Self>>
197 where
198 B: AddressableBuffer<E>,
199 {
200 parse_transaction::<B, E, Self>(data, ext_memory, self, None)
201 }
202
203 fn parse_transaction_unmarked<B>(
214 &self,
215 data: &B,
216 ext_memory: &mut E,
217 ) -> Result<TransactionUnmarkedParsed, SignableError<E, Self>>
218 where
219 B: AddressableBuffer<E>,
220 {
221 parse_transaction_unmarked::<B, E, Self>(data, ext_memory, self, None)
222 }
223}
224
225pub trait HashableRegistry<E: ExternalMemory>: ResolveType<E> {
228 fn merkle_leaves_source(&self) -> Result<LeavesRegistry, RegistryCutError>;
236}
237
238macro_rules! impl_hashable_registry {
240 ($($ty: ty), *) => {
241 $(
242 impl<E: ExternalMemory> HashableRegistry<E> for $ty {
243 fn merkle_leaves_source(&self) -> Result<LeavesRegistry, RegistryCutError> {
244 let mut draft_registry = DraftRegistry::new();
245 for registry_entry in self.types.iter() {
246 match registry_entry.ty.type_def {
247 TypeDef::Variant(ref type_def_variant) => {
248 if !type_def_variant.variants.is_empty() {
249 for variant in type_def_variant.variants.iter() {
250 add_as_enum(
251 &mut draft_registry,
252 ®istry_entry.ty.path,
253 variant.to_owned(),
254 registry_entry.id,
255 )?;
256 }
257 }
258 else {
259 add_ty_as_regular(
260 &mut draft_registry,
261 registry_entry.ty.to_owned(),
262 registry_entry.id,
263 )?;
264 }
265 }
266 _ => {
267 add_ty_as_regular(
268 &mut draft_registry,
269 registry_entry.ty.to_owned(),
270 registry_entry.id,
271 )?;
272 }
273 }
274 }
275 Ok(draft_registry.into_leaves())
276 }
277 }
278 )*
279 }
280}
281
282impl_hashable_registry!(PortableRegistry, ShortRegistry);
283
284impl<E: ExternalMemory> ResolveType<E> for ShortRegistry {
285 fn resolve_ty(
286 &self,
287 id: u32,
288 _ext_memory: &mut E,
289 ) -> Result<Type<PortableForm>, RegistryError> {
290 for short_registry_entry in self.types.iter() {
291 if short_registry_entry.id == id {
292 return Ok(short_registry_entry.ty.to_owned());
293 }
294 }
295 Err(RegistryError::TypeNotResolved { id })
296 }
297}
298
299#[cfg(any(feature = "merkle-lean", test))]
300impl<E, L> AsMetadata<E> for ShortMetadata<L, E>
301where
302 L: Leaf<LEN, E>,
303 E: ExternalMemory,
304{
305 type TypeRegistry = ShortRegistry;
306
307 type MetaStructureError = MetadataDescriptorError;
308
309 fn types(&self) -> Self::TypeRegistry {
310 self.short_registry.to_owned()
311 }
312
313 fn spec_name_version(&self) -> Result<SpecNameVersion, Self::MetaStructureError> {
314 match &self.metadata_descriptor {
315 MetadataDescriptor::V0 => Err(MetadataDescriptorError::DescriptorVersionIncompatible),
316 MetadataDescriptor::V1 {
317 call_ty: _,
318 signed_extensions: _,
319 spec_name_version,
320 base58prefix: _,
321 decimals: _,
322 unit: _,
323 } => Ok(spec_name_version.to_owned()),
324 }
325 }
326
327 fn call_ty(&self) -> Result<UntrackedSymbol<TypeId>, Self::MetaStructureError> {
328 match &self.metadata_descriptor {
329 MetadataDescriptor::V0 => Err(MetadataDescriptorError::DescriptorVersionIncompatible),
330 MetadataDescriptor::V1 {
331 call_ty,
332 signed_extensions: _,
333 spec_name_version: _,
334 base58prefix: _,
335 decimals: _,
336 unit: _,
337 } => Ok(*call_ty),
338 }
339 }
340
341 fn signed_extensions(&self) -> Result<Vec<SignedExtensionMetadata>, Self::MetaStructureError> {
342 match &self.metadata_descriptor {
343 MetadataDescriptor::V0 => Err(MetadataDescriptorError::DescriptorVersionIncompatible),
344 MetadataDescriptor::V1 {
345 call_ty: _,
346 signed_extensions,
347 spec_name_version: _,
348 base58prefix: _,
349 decimals: _,
350 unit: _,
351 } => Ok(signed_extensions.to_owned()),
352 }
353 }
354}
355
356#[cfg(any(feature = "merkle-lean", test))]
357impl<E, L> HashableMetadata<E> for ShortMetadata<L, E>
358where
359 L: Leaf<LEN, E>,
360 E: ExternalMemory,
361{
362 fn types_merkle_root(
363 &self,
364 ext_memory: &mut E,
365 ) -> Result<[u8; LEN], MetaCutError<E, ShortMetadata<L, E>>> {
366 let leaves_registry =
367 <ShortRegistry as HashableRegistry<E>>::merkle_leaves_source(&self.short_registry)
368 .map_err(MetaCutError::Registry)?;
369 let leaves: Vec<[u8; LEN]> = leaves_registry
370 .types
371 .iter()
372 .map(|entry| Blake3Hasher::make(&entry.encode()))
373 .collect();
374 let mut proof = MerkleProofMetadata::new_with_external_indices(
375 leaves,
376 self.indices.to_vec(),
377 self.lemmas.to_vec(),
378 )
379 .map_err(MetaCutError::TreeConstructProof)?;
380 proof
381 .calculate_root(ext_memory)
382 .map_err(MetaCutError::TreeCalculateRoot)
383 }
384}
385
386#[cfg(any(feature = "merkle-lean", test))]
387impl<E, L> ExtendedMetadata<E> for ShortMetadata<L, E>
388where
389 L: Leaf<LEN, E>,
390 E: ExternalMemory,
391{
392 fn to_specs(&self) -> Result<ShortSpecs, Self::MetaStructureError> {
393 match &self.metadata_descriptor {
394 MetadataDescriptor::V0 => Err(MetadataDescriptorError::DescriptorVersionIncompatible),
395 MetadataDescriptor::V1 {
396 call_ty: _,
397 signed_extensions: _,
398 spec_name_version: _,
399 base58prefix,
400 decimals,
401 unit,
402 } => Ok(ShortSpecs {
403 base58prefix: *base58prefix,
404 decimals: *decimals,
405 unit: unit.to_owned(),
406 }),
407 }
408 }
409}
410
411#[cfg(any(feature = "merkle-standard", test))]
412impl<E: ExternalMemory> HashableMetadata<E> for RuntimeMetadataV15 {
413 fn types_merkle_root(
414 &self,
415 _ext_memory: &mut E,
416 ) -> Result<[u8; LEN], MetaCutError<E, RuntimeMetadataV15>> {
417 let leaves_registry =
418 <PortableRegistry as HashableRegistry<E>>::merkle_leaves_source(&self.types)
419 .map_err(MetaCutError::Registry)?;
420 let leaves: Vec<[u8; LEN]> = leaves_registry
421 .types
422 .iter()
423 .map(blake3_leaf::<PortableType>)
424 .collect();
425 Ok(CBMT::<[u8; LEN], Blake3Hasher>::build_merkle_root(&leaves))
426 }
427}