From d4a6eb8d5618ef2258a1e2d458e51e387099f495 Mon Sep 17 00:00:00 2001 From: Shady Khalifa Date: Fri, 1 Nov 2024 18:31:16 +0200 Subject: [PATCH] fix(sdk): Return `Bytes` when using `Vec` in params and result Closes #427 --- sdk/src/event_listener/tangle/mod.rs | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/sdk/src/event_listener/tangle/mod.rs b/sdk/src/event_listener/tangle/mod.rs index 02d22aec..c082fcb5 100644 --- a/sdk/src/event_listener/tangle/mod.rs +++ b/sdk/src/event_listener/tangle/mod.rs @@ -220,13 +220,28 @@ impl_value_to_field_type!( AccountId32 => Field::AccountId ); -impl ValueIntoFieldType for Vec { +impl ValueIntoFieldType for Vec { fn into_field_type(self) -> Field { - Field::Array(BoundedVec( - self.into_iter() - .map(ValueIntoFieldType::into_field_type) - .collect(), - )) + if core::any::TypeId::of::() == core::any::TypeId::of::() { + let (ptr, length, capacity) = { + let mut me = core::mem::ManuallyDrop::new(self); + (me.as_mut_ptr() as *mut u8, me.len(), me.capacity()) + }; + // SAFETY: We are converting a Vec to Vec only when T is u8. + // This is safe because the memory layout of Vec is the same as Vec when T is u8. + // We use ManuallyDrop to prevent double-freeing the memory. + // Vec::from_raw_parts takes ownership of the raw parts, ensuring proper deallocation. + #[allow(unsafe_code)] + Field::Bytes(BoundedVec(unsafe { + Vec::from_raw_parts(ptr, length, capacity) + })) + } else { + Field::List(BoundedVec( + self.into_iter() + .map(ValueIntoFieldType::into_field_type) + .collect(), + )) + } } }