From 6a28d8fece105181f84e73a3f912aaca5b633072 Mon Sep 17 00:00:00 2001 From: Swenschaeferjohann Date: Thu, 12 Feb 2026 18:39:38 +0000 Subject: [PATCH] compressed repr. should store disc as part of data --- external/photon | 2 +- sdk-libs/client/src/interface/account_interface.rs | 8 +++----- .../sdk-types/src/interface/program/compression/pda.rs | 9 +++++++-- .../src/interface/program/decompression/pda.rs | 10 +++++++--- 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/external/photon b/external/photon index 0df2397c2c..4f7ec9c0c1 160000 --- a/external/photon +++ b/external/photon @@ -1 +1 @@ -Subproject commit 0df2397c2c7d8458f45df9279e999a730ba56482 +Subproject commit 4f7ec9c0c1beb6792d521899f3824e48dd094247 diff --git a/sdk-libs/client/src/interface/account_interface.rs b/sdk-libs/client/src/interface/account_interface.rs index 22488a2511..8fb2fb97f7 100644 --- a/sdk-libs/client/src/interface/account_interface.rs +++ b/sdk-libs/client/src/interface/account_interface.rs @@ -63,15 +63,13 @@ impl AccountInterface { } /// Create a cold account interface for a PDA/mint. + /// + /// `data.data` contains the full on-chain account bytes as-is (no reassembly needed). pub fn cold(key: Pubkey, compressed: CompressedAccount, owner: Pubkey) -> Self { let data = compressed .data .as_ref() - .map(|d| { - let mut buf = d.discriminator.to_vec(); - buf.extend_from_slice(&d.data); - buf - }) + .map(|d| d.data.clone()) .unwrap_or_default(); Self { diff --git a/sdk-libs/sdk-types/src/interface/program/compression/pda.rs b/sdk-libs/sdk-types/src/interface/program/compression/pda.rs index c5ab44fce1..489543676b 100644 --- a/sdk-libs/sdk-types/src/interface/program/compression/pda.rs +++ b/sdk-libs/sdk-types/src/interface/program/compression/pda.rs @@ -3,6 +3,8 @@ //! These functions are generic over account types and can be reused by the macro. //! The compress flow uses a dispatch callback pattern (same as decompress). +use alloc::vec::Vec; + use light_account_checks::AccountInfoTrait; use light_compressed_account::{ address::derive_address, @@ -111,8 +113,11 @@ where *compressed_data.compression_info_mut()? = crate::interface::account::compression_info::CompressionInfo::compressed(); - // Hash the data (discriminator NOT included per protocol convention) - let data_bytes = borsh::to_vec(&compressed_data).map_err(|_| LightSdkTypesError::Borsh)?; + // Serialize with disc prefix: disc(8) + borsh(struct) — mirrors on-chain layout. + let borsh_bytes = borsh::to_vec(&compressed_data).map_err(|_| LightSdkTypesError::Borsh)?; + let mut data_bytes = Vec::with_capacity(8 + borsh_bytes.len()); + data_bytes.extend_from_slice(&A::LIGHT_DISCRIMINATOR); + data_bytes.extend_from_slice(&borsh_bytes); let mut output_data_hash = Sha256::hash(&data_bytes).map_err(LightSdkTypesError::Hasher)?; output_data_hash[0] = 0; // Zero first byte per protocol convention diff --git a/sdk-libs/sdk-types/src/interface/program/decompression/pda.rs b/sdk-libs/sdk-types/src/interface/program/decompression/pda.rs index 2cbf6ba77a..cd1dd16ec3 100644 --- a/sdk-libs/sdk-types/src/interface/program/decompression/pda.rs +++ b/sdk-libs/sdk-types/src/interface/program/decompression/pda.rs @@ -92,11 +92,15 @@ where return Ok(()); } - // 5. Hash with canonical CompressionInfo::compressed() for input verification - let data_bytes = account_data + // 5. Hash with canonical CompressionInfo::compressed() for input verification. + // data = disc(8) + borsh(struct) — mirrors on-chain layout. + let borsh_bytes = account_data .try_to_vec() .map_err(|_| LightSdkTypesError::Borsh)?; - let data_len = data_bytes.len(); + let data_len = borsh_bytes.len(); + let mut data_bytes = Vec::with_capacity(8 + data_len); + data_bytes.extend_from_slice(& as LightDiscriminator>::LIGHT_DISCRIMINATOR); + data_bytes.extend_from_slice(&borsh_bytes); let mut input_data_hash = Sha256BE::hash(&data_bytes)?; input_data_hash[0] = 0; // Zero first byte per protocol convention