Skip to content

Commit ed42d95

Browse files
committed
smartcontract: add feed_authority to subscriber allowlist remove auth check
1 parent f1194d0 commit ed42d95

2 files changed

Lines changed: 165 additions & 0 deletions

File tree

smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/allowlist/subscriber/remove.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ pub fn process_remove_multicast_sub_allowlist(
7979
// Check whether mgroup is authorized
8080
let is_authorized = (mgroup.owner == *payer_account.key)
8181
|| globalstate.sentinel_authority_pk == *payer_account.key
82+
|| globalstate.feed_authority_pk == *payer_account.key
8283
|| globalstate.foundation_allowlist.contains(payer_account.key);
8384
if !is_authorized {
8485
return Err(DoubleZeroError::NotAllowed.into());

smartcontract/programs/doublezero-serviceability/tests/multicastgroup_allowlist_subcriber_test.rs

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -761,3 +761,167 @@ async fn test_multicast_subscriber_allowlist_feed_authority_different_user_payer
761761
"Non-feed authority should fail when user_payer doesn't match"
762762
);
763763
}
764+
765+
/// Feed authority can remove from subscriber allowlist.
766+
#[tokio::test]
767+
async fn test_multicast_subscriber_allowlist_feed_authority_remove() {
768+
let (mut banks_client, program_id, payer, recent_blockhash) = init_test().await;
769+
770+
let client_ip = [100, 0, 0, 6].into();
771+
let user_payer = payer.pubkey();
772+
773+
let (program_config_pubkey, _) = get_program_config_pda(&program_id);
774+
let (globalstate_pubkey, _) = get_globalstate_pda(&program_id);
775+
776+
// 1. Initialize global state
777+
execute_transaction(
778+
&mut banks_client,
779+
recent_blockhash,
780+
program_id,
781+
DoubleZeroInstruction::InitGlobalState(),
782+
vec![
783+
AccountMeta::new(program_config_pubkey, false),
784+
AccountMeta::new(globalstate_pubkey, false),
785+
],
786+
&payer,
787+
)
788+
.await;
789+
790+
// 2. Create feed authority
791+
let feed = Keypair::new();
792+
transfer(&mut banks_client, &payer, &feed.pubkey(), 10_000_000_000).await;
793+
794+
execute_transaction(
795+
&mut banks_client,
796+
recent_blockhash,
797+
program_id,
798+
DoubleZeroInstruction::SetAuthority(SetAuthorityArgs {
799+
feed_authority_pk: Some(feed.pubkey()),
800+
..Default::default()
801+
}),
802+
vec![AccountMeta::new(globalstate_pubkey, false)],
803+
&payer,
804+
)
805+
.await;
806+
807+
// 3. Create and activate multicast group
808+
let globalstate = get_account_data(&mut banks_client, globalstate_pubkey)
809+
.await
810+
.expect("Unable to get Account")
811+
.get_global_state()
812+
.unwrap();
813+
814+
let (multicastgroup_pubkey, _) =
815+
get_multicastgroup_pda(&program_id, globalstate.account_index + 1);
816+
817+
execute_transaction(
818+
&mut banks_client,
819+
recent_blockhash,
820+
program_id,
821+
DoubleZeroInstruction::CreateMulticastGroup(MulticastGroupCreateArgs {
822+
code: "feed-remove".to_string(),
823+
max_bandwidth: 1_000_000_000,
824+
owner: payer.pubkey(),
825+
use_onchain_allocation: false,
826+
}),
827+
vec![
828+
AccountMeta::new(multicastgroup_pubkey, false),
829+
AccountMeta::new(globalstate_pubkey, false),
830+
],
831+
&payer,
832+
)
833+
.await;
834+
835+
execute_transaction(
836+
&mut banks_client,
837+
recent_blockhash,
838+
program_id,
839+
DoubleZeroInstruction::ActivateMulticastGroup(MulticastGroupActivateArgs {
840+
multicast_ip: [224, 254, 0, 6].into(),
841+
}),
842+
vec![
843+
AccountMeta::new(multicastgroup_pubkey, false),
844+
AccountMeta::new(globalstate_pubkey, false),
845+
],
846+
&payer,
847+
)
848+
.await;
849+
850+
// 4. Payer creates access pass and adds allowlist entry
851+
let (accesspass_pubkey, _) = get_accesspass_pda(&program_id, &client_ip, &user_payer);
852+
853+
execute_transaction(
854+
&mut banks_client,
855+
recent_blockhash,
856+
program_id,
857+
DoubleZeroInstruction::SetAccessPass(SetAccessPassArgs {
858+
accesspass_type: AccessPassType::Prepaid,
859+
client_ip,
860+
last_access_epoch: 100,
861+
allow_multiple_ip: false,
862+
}),
863+
vec![
864+
AccountMeta::new(accesspass_pubkey, false),
865+
AccountMeta::new(globalstate_pubkey, false),
866+
AccountMeta::new(user_payer, false),
867+
],
868+
&payer,
869+
)
870+
.await;
871+
872+
execute_transaction(
873+
&mut banks_client,
874+
recent_blockhash,
875+
program_id,
876+
DoubleZeroInstruction::AddMulticastGroupSubAllowlist(AddMulticastGroupSubAllowlistArgs {
877+
client_ip,
878+
user_payer,
879+
}),
880+
vec![
881+
AccountMeta::new(multicastgroup_pubkey, false),
882+
AccountMeta::new(accesspass_pubkey, false),
883+
AccountMeta::new(globalstate_pubkey, false),
884+
],
885+
&payer,
886+
)
887+
.await;
888+
889+
let accesspass = get_account_data(&mut banks_client, accesspass_pubkey)
890+
.await
891+
.expect("Unable to get Account")
892+
.get_accesspass()
893+
.unwrap();
894+
assert_eq!(accesspass.mgroup_sub_allowlist.len(), 1);
895+
896+
// 5. Feed authority removes subscriber allowlist entry — should succeed
897+
let recent_blockhash = banks_client.get_latest_blockhash().await.unwrap();
898+
let res = try_execute_transaction(
899+
&mut banks_client,
900+
recent_blockhash,
901+
program_id,
902+
DoubleZeroInstruction::RemoveMulticastGroupSubAllowlist(
903+
RemoveMulticastGroupSubAllowlistArgs {
904+
client_ip,
905+
user_payer,
906+
},
907+
),
908+
vec![
909+
AccountMeta::new(multicastgroup_pubkey, false),
910+
AccountMeta::new(accesspass_pubkey, false),
911+
AccountMeta::new(globalstate_pubkey, false),
912+
],
913+
&feed,
914+
)
915+
.await;
916+
assert!(
917+
res.is_ok(),
918+
"Feed authority should be able to remove from subscriber allowlist"
919+
);
920+
921+
let accesspass = get_account_data(&mut banks_client, accesspass_pubkey)
922+
.await
923+
.expect("Unable to get Account")
924+
.get_accesspass()
925+
.unwrap();
926+
assert_eq!(accesspass.mgroup_sub_allowlist.len(), 0);
927+
}

0 commit comments

Comments
 (0)