Skip to content

Commit 1984540

Browse files
committed
fixed metadat update trailing zeroes
1 parent 643c4a8 commit 1984540

File tree

12 files changed

+381
-220
lines changed

12 files changed

+381
-220
lines changed

.github/workflows/light-examples-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ jobs:
4848
matrix:
4949
include:
5050
- program: sdk-test-program
51-
sub-tests: '["cargo-test-sbf -p sdk-test"]'
51+
sub-tests: '["cargo-test-sbf -p sdk-native-test"]'
5252
- program: sdk-anchor-test-program
5353
sub-tests: '["cargo-test-sbf -p sdk-anchor-test", "cargo-test-sbf -p sdk-pinocchio-test"]'
5454

INTEGRATION_TESTING.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ program-tests/
1616
├── registry-test/ # Registry program integration tests
1717
├── sdk-anchor-test/ # SDK anchor integration tests
1818
├── sdk-pinocchio-test/ # SDK pinocchio integration tests
19-
├── sdk-test/ # Core SDK integration tests
19+
├── sdk-native-test/ # Core SDK integration tests
2020
├── sdk-token-test/ # SDK token integration tests
2121
├── system-cpi-test/ # System CPI integration tests
2222
├── system-cpi-v2-test/ # System CPI v2 integration tests
@@ -37,7 +37,7 @@ program-tests/
3737

3838
**SDK libraries also have dedicated integration tests:**
3939

40-
- **Core SDK** (`sdk-libs/sdk/`) → `program-tests/sdk-test/`
40+
- **Core SDK** (`sdk-libs/sdk/`) → `sdk-tests/sdk-native-test/`
4141
- **Compressed Token SDK** (`sdk-libs/compressed-token-sdk/`) → `program-tests/sdk-token-test/`
4242
- **Client SDK** (`sdk-libs/client/`) → `program-tests/client-test/`
4343

SECURITY_REVIEW_CPI_CONTEXT.md

Lines changed: 120 additions & 118 deletions
Large diffs are not rendered by default.

program-tests/compressed-token-test/tests/metadata.rs

Lines changed: 191 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -712,10 +712,199 @@ async fn test_metadata_comprehensive_workflow() -> Result<(), light_client::rpc:
712712
.await
713713
.unwrap();
714714

715-
// Continue with remaining steps - combined operations, field updates, etc.
716-
// (Implementation details match the original test but with proper assertions)
715+
// === STEP 2: Combined operations - Remove key, update field, change authority ===
716+
let combined_step2_actions = vec![
717+
MintActionType::RemoveMetadataKey {
718+
extension_index: 0,
719+
key: b"license".to_vec(),
720+
idempotent: 0,
721+
},
722+
MintActionType::UpdateMetadataField {
723+
extension_index: 0,
724+
field_type: 0, // Name
725+
key: vec![],
726+
value: b"Workflow Token".to_vec(),
727+
},
728+
MintActionType::UpdateMetadataAuthority {
729+
extension_index: 0,
730+
new_authority: second_authority.pubkey(),
731+
},
732+
];
733+
734+
mint_action(
735+
&mut rpc,
736+
MintActionParams {
737+
compressed_mint_address: context.compressed_mint_address,
738+
mint_seed: context.mint_seed.pubkey(),
739+
authority: context.mint_authority.pubkey(),
740+
payer: context.payer.pubkey(),
741+
actions: combined_step2_actions,
742+
new_mint: None,
743+
},
744+
&context.mint_authority,
745+
&context.payer,
746+
None,
747+
)
748+
.await?;
749+
750+
// Assert: authority changed, name updated, "license" removed
751+
let expected_after_step2 = create_expected_metadata_state(
752+
Some(second_authority.pubkey()),
753+
"Workflow Token",
754+
"TEST",
755+
"https://example.com/token.json",
756+
vec![
757+
create_additional_metadata("website", "https://mytoken.com"),
758+
create_additional_metadata("category", "DeFi"),
759+
create_additional_metadata("creator", "TokenMaker Inc."),
760+
],
761+
0,
762+
);
763+
assert_metadata_state(&mut rpc, context.compressed_mint_address, &expected_after_step2).await;
764+
765+
// === STEP 3: Update symbol field with second authority ===
766+
mint_action(
767+
&mut rpc,
768+
MintActionParams {
769+
compressed_mint_address: context.compressed_mint_address,
770+
mint_seed: context.mint_seed.pubkey(),
771+
authority: second_authority.pubkey(),
772+
payer: context.payer.pubkey(),
773+
actions: vec![MintActionType::UpdateMetadataField {
774+
extension_index: 0,
775+
field_type: 1, // Symbol
776+
key: vec![],
777+
value: b"WF".to_vec(),
778+
}],
779+
new_mint: None,
780+
},
781+
&second_authority,
782+
&context.payer,
783+
None,
784+
)
785+
.await?;
786+
787+
// === STEP 4: Transfer authority to third authority ===
788+
mint_action(
789+
&mut rpc,
790+
MintActionParams {
791+
compressed_mint_address: context.compressed_mint_address,
792+
mint_seed: context.mint_seed.pubkey(),
793+
authority: second_authority.pubkey(),
794+
payer: context.payer.pubkey(),
795+
actions: vec![MintActionType::UpdateMetadataAuthority {
796+
extension_index: 0,
797+
new_authority: third_authority.pubkey(),
798+
}],
799+
new_mint: None,
800+
},
801+
&second_authority,
802+
&context.payer,
803+
None,
804+
)
805+
.await?;
806+
807+
// === STEP 5: Update URI field with third authority ===
808+
mint_action(
809+
&mut rpc,
810+
MintActionParams {
811+
compressed_mint_address: context.compressed_mint_address,
812+
mint_seed: context.mint_seed.pubkey(),
813+
authority: third_authority.pubkey(),
814+
payer: context.payer.pubkey(),
815+
actions: vec![MintActionType::UpdateMetadataField {
816+
extension_index: 0,
817+
field_type: 2, // URI
818+
key: vec![],
819+
value: b"https://workflow.example.com/token.json".to_vec(),
820+
}],
821+
new_mint: None,
822+
},
823+
&third_authority,
824+
&context.payer,
825+
None,
826+
)
827+
.await?;
828+
829+
// === STEP 6: Remove another metadata key ===
830+
mint_action(
831+
&mut rpc,
832+
MintActionParams {
833+
compressed_mint_address: context.compressed_mint_address,
834+
mint_seed: context.mint_seed.pubkey(),
835+
authority: third_authority.pubkey(),
836+
payer: context.payer.pubkey(),
837+
actions: vec![MintActionType::RemoveMetadataKey {
838+
extension_index: 0,
839+
key: b"website".to_vec(),
840+
idempotent: 0,
841+
}],
842+
new_mint: None,
843+
},
844+
&third_authority,
845+
&context.payer,
846+
None,
847+
)
848+
.await?;
849+
850+
// === STEP 7: Transfer to fourth authority, then immediately revoke ===
851+
let combined_step7_actions = vec![
852+
MintActionType::UpdateMetadataAuthority {
853+
extension_index: 0,
854+
new_authority: fourth_authority.pubkey(),
855+
},
856+
];
857+
858+
mint_action(
859+
&mut rpc,
860+
MintActionParams {
861+
compressed_mint_address: context.compressed_mint_address,
862+
mint_seed: context.mint_seed.pubkey(),
863+
authority: third_authority.pubkey(),
864+
payer: context.payer.pubkey(),
865+
actions: combined_step7_actions,
866+
new_mint: None,
867+
},
868+
&third_authority,
869+
&context.payer,
870+
None,
871+
)
872+
.await?;
873+
874+
// === STEP 8: Revoke authority entirely ===
875+
mint_action(
876+
&mut rpc,
877+
MintActionParams {
878+
compressed_mint_address: context.compressed_mint_address,
879+
mint_seed: context.mint_seed.pubkey(),
880+
authority: fourth_authority.pubkey(),
881+
payer: context.payer.pubkey(),
882+
actions: vec![MintActionType::UpdateMetadataAuthority {
883+
extension_index: 0,
884+
new_authority: Pubkey::default(), // Revoke authority
885+
}],
886+
new_mint: None,
887+
},
888+
&fourth_authority,
889+
&context.payer,
890+
None,
891+
)
892+
.await?;
717893

718894
// Verify final state where authority is None and metadata exists
895+
let expected_final = create_expected_metadata_state(
896+
None, // Authority revoked
897+
"Workflow Token",
898+
"WF",
899+
"https://workflow.example.com/token.json",
900+
vec![
901+
create_additional_metadata("category", "DeFi"),
902+
create_additional_metadata("creator", "TokenMaker Inc."),
903+
],
904+
0,
905+
);
906+
assert_metadata_state(&mut rpc, context.compressed_mint_address, &expected_final).await;
907+
719908
// This validates the complete end-to-end workflow
720909
Ok(())
721910
}

program-tests/create-address-test-program/src/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ pub mod system_cpi_test {
6464
config: CpiAccountsConfig,
6565
small_ix: bool,
6666
inputs: Vec<u8>,
67-
write_cpi_contex: bool,
67+
write_cpi_context: bool,
6868
) -> Result<()> {
6969
let fee_payer = ctx.accounts.signer.to_account_info();
7070

@@ -74,7 +74,7 @@ pub mod system_cpi_test {
7474
CpiAccountsSmall::new_with_config(&fee_payer, ctx.remaining_accounts, config);
7575
let account_infos = cpi_accounts.to_account_infos();
7676

77-
let account_metas = if !write_cpi_contex {
77+
let account_metas = if !write_cpi_context {
7878
to_account_metas_small(cpi_accounts).map_err(|_| ErrorCode::AccountNotEnoughKeys)?
7979
} else {
8080
let mut account_metas = vec![];
@@ -237,13 +237,13 @@ pub fn create_invoke_read_only_account_info_instruction(
237237
config: CpiAccountsConfig,
238238
small: bool,
239239
remaining_accounts: Vec<AccountMeta>,
240-
write_cpi_contex: bool,
240+
write_cpi_context: bool,
241241
) -> Instruction {
242242
let ix_data = crate::instruction::InvokeWithReadOnly {
243243
small_ix: small,
244244
inputs,
245245
config,
246-
write_cpi_contex,
246+
write_cpi_context,
247247
}
248248
.data();
249249
let accounts = crate::accounts::InvokeCpiReadOnly { signer };

program-tests/sdk-anchor-test/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
{
22
"scripts": {
3-
"test": "cargo test-sbf -p sdk-test"
3+
"test": "cargo test-sbf -p sdk-native-test"
44
},
55
"dependencies": {
66
"@coral-xyz/anchor": "^0.29.0"
77
},
88
"devDependencies": {
99
"@lightprotocol/zk-compression-cli": "workspace:*",
10-
1110
"chai": "^5.2.1",
1211
"mocha": "^11.7.1",
1312
"ts-mocha": "^11.1.0",

programs/compressed-token/program/src/extensions/mod.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -78,19 +78,19 @@ fn process_token_metadata_config_with_actions(
7878
actions: &[ZAction],
7979
extension_index: usize,
8080
) {
81-
// Calculate maximum sizes needed by scanning current data and all planned updates
82-
let mut max_name_len = token_metadata_data.metadata.name.len();
83-
let mut max_symbol_len = token_metadata_data.metadata.symbol.len();
84-
let mut max_uri_len = token_metadata_data.metadata.uri.len();
81+
// Calculate final sizes by applying actions sequentially to determine the actual final state
82+
let mut final_name_len = token_metadata_data.metadata.name.len();
83+
let mut final_symbol_len = token_metadata_data.metadata.symbol.len();
84+
let mut final_uri_len = token_metadata_data.metadata.uri.len();
8585

86-
// Scan actions for field updates that affect this extension
86+
// Apply actions sequentially to determine final field sizes (last action wins)
8787
for action in actions.iter() {
8888
if let ZAction::UpdateMetadataField(update_action) = action {
8989
if update_action.extension_index as usize == extension_index {
9090
match update_action.field_type {
91-
0 => max_name_len = max_name_len.max(update_action.value.len()), // name
92-
1 => max_symbol_len = max_symbol_len.max(update_action.value.len()), // symbol
93-
2 => max_uri_len = max_uri_len.max(update_action.value.len()), // uri
91+
0 => final_name_len = update_action.value.len(), // name - last update determines final size
92+
1 => final_symbol_len = update_action.value.len(), // symbol - last update determines final size
93+
2 => final_uri_len = update_action.value.len(), // uri - last update determines final size
9494
_ => {} // custom fields handled separately
9595
}
9696
}
@@ -130,9 +130,9 @@ fn process_token_metadata_config_with_actions(
130130
let config = TokenMetadataConfig {
131131
update_authority: (token_metadata_data.update_authority.is_some(), ()),
132132
metadata: MetadataConfig {
133-
name: max_name_len as u32,
134-
symbol: max_symbol_len as u32,
135-
uri: max_uri_len as u32,
133+
name: final_name_len as u32,
134+
symbol: final_symbol_len as u32,
135+
uri: final_uri_len as u32,
136136
},
137137
additional_metadata: additional_metadata_configs,
138138
};

0 commit comments

Comments
 (0)