11use crate :: {
22 error:: DoubleZeroError ,
3- pda:: get_resource_extension_pda,
3+ pda:: { get_index_pda , get_resource_extension_pda} ,
44 processors:: { resource:: deallocate_ip, validation:: validate_program_account} ,
55 resource:: ResourceType ,
6+ seeds:: SEED_MULTICAST_GROUP ,
67 serializer:: { try_acc_close, try_acc_write} ,
78 state:: {
89 feature_flags:: { is_feature_enabled, FeatureFlag } ,
910 globalstate:: GlobalState ,
11+ index:: Index ,
1012 multicastgroup:: * ,
1113 } ,
1214} ;
@@ -28,14 +30,17 @@ pub struct MulticastGroupDeleteArgs {
2830 /// Requires ResourceExtension accounts and owner account.
2931 #[ incremental( default = false ) ]
3032 pub use_onchain_deallocation : bool ,
33+ /// When true, close the associated Index account alongside the multicast group.
34+ #[ incremental( default = false ) ]
35+ pub close_index : bool ,
3136}
3237
3338impl fmt:: Debug for MulticastGroupDeleteArgs {
3439 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
3540 write ! (
3641 f,
37- "use_onchain_deallocation: {}" ,
38- self . use_onchain_deallocation
42+ "use_onchain_deallocation: {}, close_index: {} " ,
43+ self . use_onchain_deallocation, self . close_index
3944 )
4045 }
4146}
@@ -50,10 +55,12 @@ pub fn process_delete_multicastgroup(
5055 let multicastgroup_account = next_account_info ( accounts_iter) ?;
5156 let globalstate_account = next_account_info ( accounts_iter) ?;
5257
53- // Optional: additional accounts for atomic deallocation (before payer)
54- // Account layout WITH deallocation (use_onchain_deallocation = true):
55- // [mgroup, globalstate, multicast_group_block, owner, payer, system]
56- // Account layout WITHOUT (legacy, use_onchain_deallocation = false):
58+ // Optional: additional accounts for atomic deallocation
59+ // Account layout WITH deallocation + index:
60+ // [mgroup, globalstate, multicast_group_block, owner, index, payer, system]
61+ // Account layout WITHOUT deallocation, with index:
62+ // [mgroup, globalstate, index, payer, system]
63+ // Legacy (no deallocation, no index):
5764 // [mgroup, globalstate, payer, system]
5865 let deallocation_accounts = if value. use_onchain_deallocation {
5966 let multicast_group_block_ext = next_account_info ( accounts_iter) ?;
@@ -63,6 +70,12 @@ pub fn process_delete_multicastgroup(
6370 None
6471 } ;
6572
73+ let index_account = if value. close_index {
74+ Some ( next_account_info ( accounts_iter) ?)
75+ } else {
76+ None
77+ } ;
78+
6679 let payer_account = next_account_info ( accounts_iter) ?;
6780 let system_program = next_account_info ( accounts_iter) ?;
6881
@@ -98,6 +111,7 @@ pub fn process_delete_multicastgroup(
98111 }
99112
100113 let multicastgroup: MulticastGroup = MulticastGroup :: try_from ( multicastgroup_account) ?;
114+ let multicastgroup_code = multicastgroup. code . clone ( ) ;
101115
102116 if matches ! ( multicastgroup. status, MulticastGroupStatus :: Deleting ) {
103117 return Err ( DoubleZeroError :: InvalidStatus . into ( ) ) ;
@@ -158,5 +172,25 @@ pub fn process_delete_multicastgroup(
158172 msg ! ( "Deleted: {:?}" , multicastgroup_account) ;
159173 }
160174
175+ // Close the Index account if provided
176+ if let Some ( index_acc) = index_account {
177+ assert_eq ! ( index_acc. owner, program_id, "Invalid Index Account Owner" ) ;
178+ assert ! ( index_acc. is_writable, "Index Account is not writable" ) ;
179+
180+ // Verify the Index PDA matches
181+ let ( expected_index_pda, _) =
182+ get_index_pda ( program_id, SEED_MULTICAST_GROUP , & multicastgroup_code) ;
183+ assert_eq ! ( index_acc. key, & expected_index_pda, "Invalid Index Pubkey" ) ;
184+
185+ // Verify it's an Index account pointing to this multicast group
186+ let index = Index :: try_from ( index_acc) ?;
187+ assert_eq ! (
188+ index. pk, * multicastgroup_account. key,
189+ "Index does not point to this MulticastGroup"
190+ ) ;
191+
192+ try_acc_close ( index_acc, payer_account) ?;
193+ }
194+
161195 Ok ( ( ) )
162196}
0 commit comments