diff --git a/Cargo.lock b/Cargo.lock index 759d6fe626..e7702d77e0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3770,6 +3770,7 @@ dependencies = [ "light-array-map", "light-compressed-account", "light-compressible", + "light-ctoken-interface", "light-hasher", "light-heap", "light-macros", diff --git a/program-libs/ctoken-interface/Cargo.toml b/program-libs/ctoken-interface/Cargo.toml index d0be104060..8518ab9999 100644 --- a/program-libs/ctoken-interface/Cargo.toml +++ b/program-libs/ctoken-interface/Cargo.toml @@ -9,6 +9,7 @@ license = "MIT" anchor = ["light-compressed-account/anchor", "dep:anchor-lang", "light-compressible/anchor"] solana = ["dep:solana-program-error", "dep:solana-sysvar", "solana-msg"] default = [] +test-only = [] profile-program = [] profile-heap = ["dep:light-heap"] poseidon = ["light-hasher/poseidon"] @@ -51,6 +52,7 @@ light-account-checks = { workspace = true, features = [ "solana", ] } spl-token-metadata-interface = "0.6.0" +light-ctoken-interface = { workspace = true, features = ["poseidon", "test-only"] } light-hasher = { workspace = true, features = ["keccak", "sha256", "poseidon"] } [lints.rust.unexpected_cfgs] diff --git a/program-libs/ctoken-interface/src/state/ctoken/zero_copy.rs b/program-libs/ctoken-interface/src/state/ctoken/zero_copy.rs index 8460abb1ed..f0642b4966 100644 --- a/program-libs/ctoken-interface/src/state/ctoken/zero_copy.rs +++ b/program-libs/ctoken-interface/src/state/ctoken/zero_copy.rs @@ -231,6 +231,7 @@ impl<'a> Deref for ZCToken<'a> { } } +#[cfg(feature = "test-only")] impl PartialEq for ZCToken<'_> { fn eq(&self, other: &CToken) -> bool { // Compare basic fields @@ -380,7 +381,23 @@ impl PartialEq for ZCToken<'_> { } } } - _ => return false, // Different extension types + // Mismatched known extension types (e.g., Compressible vs TokenMetadata) + ( + crate::state::extensions::ZExtensionStruct::Compressible(_), + crate::state::extensions::ExtensionStruct::TokenMetadata(_), + ) + | ( + crate::state::extensions::ZExtensionStruct::TokenMetadata(_), + crate::state::extensions::ExtensionStruct::Compressible(_), + ) => return false, + // Unknown or unhandled extension types should panic to surface bugs early + (zc_ext, regular_ext) => { + panic!( + "Unknown extension type comparison: ZCToken extension {:?} vs CToken extension {:?}", + std::mem::discriminant(zc_ext), + std::mem::discriminant(regular_ext) + ); + } } } } @@ -392,6 +409,7 @@ impl PartialEq for ZCToken<'_> { } } +#[cfg(feature = "test-only")] impl PartialEq> for CToken { fn eq(&self, other: &ZCToken<'_>) -> bool { other.eq(self) diff --git a/program-tests/utils/Cargo.toml b/program-tests/utils/Cargo.toml index 75220fea43..699a7d3103 100644 --- a/program-tests/utils/Cargo.toml +++ b/program-tests/utils/Cargo.toml @@ -21,7 +21,7 @@ solana-sdk = { workspace = true } thiserror = { workspace = true } account-compression = { workspace = true, features = ["cpi"] } light-compressed-token = { workspace = true, features = ["cpi"] } -light-ctoken-interface = { workspace = true } +light-ctoken-interface = { workspace = true, features = ["test-only"] } light-system-program-anchor = { workspace = true, features = ["cpi"] } light-registry = { workspace = true, features = ["cpi"] } spl-token = { workspace = true, features = ["no-entrypoint"] }