From ed1a8f23d5c375ca0175a6842548e40de30f93af Mon Sep 17 00:00:00 2001 From: Fernando Otero Date: Wed, 12 Jun 2024 07:31:23 +0100 Subject: [PATCH] Add support for legacy grouping (#80) --- .../asset/types/src/extensions/grouping.rs | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/programs/asset/types/src/extensions/grouping.rs b/programs/asset/types/src/extensions/grouping.rs index 4b08e99..11d28f8 100644 --- a/programs/asset/types/src/extensions/grouping.rs +++ b/programs/asset/types/src/extensions/grouping.rs @@ -10,6 +10,9 @@ use crate::{error::Error, state::NullablePubkey}; use super::{ExtensionBuilder, ExtensionData, ExtensionDataMut, ExtensionType, Lifecycle}; +/// Empty string used for backwards compatibility with metadata extension. +const EMPTY: [u8; 32] = [0u8; 32]; + /// Extension to define a group of assets. /// /// Assets that are intented to be use as group "markers" must have this extension @@ -36,10 +39,17 @@ impl<'a> ExtensionData<'a> for Grouping<'a> { fn from_bytes(bytes: &'a [u8]) -> Self { let (size, rest) = bytes.split_at(std::mem::size_of::()); let (max_size, delegate) = rest.split_at(std::mem::size_of::()); + Self { size: bytemuck::from_bytes(size), max_size: bytemuck::from_bytes(max_size), - delegate: bytemuck::from_bytes(delegate), + // backwards compatibility for grouping extension: if there are not enough + // bytes to read the delegate, we assume it is empty + delegate: bytemuck::from_bytes(if delegate.len() < EMPTY.len() { + &EMPTY + } else { + delegate + }), } } @@ -72,10 +82,17 @@ impl<'a> ExtensionDataMut<'a> for GroupingMut<'a> { fn from_bytes_mut(bytes: &'a mut [u8]) -> Self { let (size, rest) = bytes.split_at_mut(std::mem::size_of::()); let (max_size, delegate) = rest.split_at_mut(std::mem::size_of::()); + Self { size: bytemuck::from_bytes_mut(size), max_size: bytemuck::from_bytes_mut(max_size), - delegate: bytemuck::from_bytes_mut(delegate), + // backwards compatibility for grouping extension: if there are not enough + // bytes to read the delegate, we assume it is empty + delegate: bytemuck::from_bytes_mut(if delegate.len() < EMPTY.len() { + unsafe { (&EMPTY as *const [u8] as *mut [u8]).as_mut().unwrap() } + } else { + delegate + }), } } }