From cfad66209bed16f34807685663c9cf3aebfa5786 Mon Sep 17 00:00:00 2001 From: Martin Sander Date: Wed, 8 Apr 2026 17:23:08 -0500 Subject: [PATCH 1/4] smartcontract: rename subscribe processor functions for clarity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rename subscribe_user_to_multicastgroup → update_user_multicastgroup_subscription and process_subscribe_multicastgroup → process_update_multicastgroup_subscription to reflect that these functions handle both subscribe and unsubscribe. Simplify the status guard to use a positive is_subscribe check instead of double-negated !is_unsubscribe_only. Resolves #3498 --- .../src/entrypoint.rs | 4 ++-- .../processors/multicastgroup/subscribe.rs | 20 +++++++++---------- .../src/processors/user/create_subscribe.rs | 4 ++-- .../tests/multicastgroup_subscribe_test.rs | 2 +- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/smartcontract/programs/doublezero-serviceability/src/entrypoint.rs b/smartcontract/programs/doublezero-serviceability/src/entrypoint.rs index 555fac6e0..8fdca284f 100644 --- a/smartcontract/programs/doublezero-serviceability/src/entrypoint.rs +++ b/smartcontract/programs/doublezero-serviceability/src/entrypoint.rs @@ -77,7 +77,7 @@ use crate::{ delete::process_delete_multicastgroup, reactivate::process_reactivate_multicastgroup, reject::process_reject_multicastgroup, - subscribe::process_subscribe_multicastgroup, + subscribe::process_update_multicastgroup_subscription, suspend::process_suspend_multicastgroup, update::process_update_multicastgroup, }, @@ -294,7 +294,7 @@ pub fn process_instruction( process_remove_multicast_sub_allowlist(program_id, accounts, &value)? } DoubleZeroInstruction::SubscribeMulticastGroup(value) => { - process_subscribe_multicastgroup(program_id, accounts, &value)? + process_update_multicastgroup_subscription(program_id, accounts, &value)? } DoubleZeroInstruction::CreateSubscribeUser(value) => { process_create_subscribe_user(program_id, accounts, &value)? diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/subscribe.rs b/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/subscribe.rs index 77ae39301..e102ecd8f 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/subscribe.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/subscribe.rs @@ -60,7 +60,7 @@ pub struct SubscribeUserResult { /// and post-activation subscription changes (add/remove toggle). The caller is /// responsible for setting `user.status = Updating` when /// `publisher_list_transitioned` is true and the user is already activated. -pub fn subscribe_user_to_multicastgroup( +pub fn update_user_multicastgroup_subscription( mgroup_account: &AccountInfo, accesspass: &AccessPass, user: &mut User, @@ -130,7 +130,7 @@ pub fn subscribe_user_to_multicastgroup( }) } -pub fn process_subscribe_multicastgroup( +pub fn process_update_multicastgroup_subscription( program_id: &Pubkey, accounts: &[AccountInfo], value: &MulticastGroupSubscribeArgs, @@ -171,7 +171,7 @@ pub fn process_subscribe_multicastgroup( let system_program = next_account_info(accounts_iter)?; #[cfg(test)] - msg!("process_subscribe_multicastgroup({:?})", value); + msg!("process_update_multicastgroup_subscription({:?})", value); // Check if the payer is a signer assert!(payer_account.is_signer, "Payer must be a signer"); @@ -201,12 +201,12 @@ pub fn process_subscribe_multicastgroup( // Parse and validate user let mut user: User = User::try_from(user_account)?; - // Allow subscribe for Pending users so that CreateSubscribeUser (which - // only takes one mgroup) can be followed by additional SubscribeMulticastGroup - // calls before the activator runs. Also allow pure-unsubscribe (both false) - // for any status so cleanup works before activation. - let is_unsubscribe_only = !value.publisher && !value.subscriber; - if !is_unsubscribe_only + // Unsubscribe is allowed for any status so that users + // created via CreateSubscribeUser can be cleaned up before activation. + // Subscribe is also allowed for Pending users so that CreateSubscribeUser + // (which only takes one mgroup) can be followed by additional calls. + let is_subscribe = value.publisher || value.subscriber; + if is_subscribe && user.status != UserStatus::Activated && user.status != UserStatus::Updating && user.status != UserStatus::Pending @@ -254,7 +254,7 @@ pub fn process_subscribe_multicastgroup( } } - let result = subscribe_user_to_multicastgroup( + let result = update_user_multicastgroup_subscription( mgroup_account, &accesspass, &mut user, diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/user/create_subscribe.rs b/smartcontract/programs/doublezero-serviceability/src/processors/user/create_subscribe.rs index 5bbe84e43..1434e7d5c 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/user/create_subscribe.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/user/create_subscribe.rs @@ -18,7 +18,7 @@ use super::{ create_core::{create_user_core, CreateUserCoreAccounts, PDAVersion}, resource_onchain_helpers, }; -use crate::processors::multicastgroup::subscribe::subscribe_user_to_multicastgroup; +use crate::processors::multicastgroup::subscribe::update_user_multicastgroup_subscription; #[derive(BorshSerialize, BorshDeserializeIncremental, PartialEq, Clone)] pub struct UserCreateSubscribeArgs { @@ -111,7 +111,7 @@ pub fn process_create_subscribe_user( )?; // Subscribe user to multicast group - let subscribe_result = subscribe_user_to_multicastgroup( + let subscribe_result = update_user_multicastgroup_subscription( mgroup_account, &result.accesspass, &mut result.user, diff --git a/smartcontract/programs/doublezero-serviceability/tests/multicastgroup_subscribe_test.rs b/smartcontract/programs/doublezero-serviceability/tests/multicastgroup_subscribe_test.rs index f686bb161..a5188846a 100644 --- a/smartcontract/programs/doublezero-serviceability/tests/multicastgroup_subscribe_test.rs +++ b/smartcontract/programs/doublezero-serviceability/tests/multicastgroup_subscribe_test.rs @@ -969,7 +969,7 @@ async fn test_duplicate_publisher_subscribe_is_noop() { } /// Foundation admin (payer != user.owner) can subscribe a user to a multicast group. -/// Regression test for the bug where process_subscribe_multicastgroup derived the AccessPass PDA +/// Regression test for the bug where process_update_multicastgroup_subscription derived the AccessPass PDA /// using payer_account.key instead of user.owner. #[tokio::test] async fn test_subscribe_foundation_admin_payer_differs_from_user_owner() { From ab04a629977be0883cde5d96dcb5b03a7eec7bf1 Mon Sep 17 00:00:00 2001 From: Martin Sander Date: Wed, 8 Apr 2026 17:32:54 -0500 Subject: [PATCH 2/4] smartcontract: add changelog entry for subscribe rename --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a2ab74d2a..2823b25e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ All notable changes to this project will be documented in this file. - Smartcontract - Allow `SubscribeMulticastGroup` for users in `Pending` status so that `CreateSubscribeUser` can be followed by additional subscribe calls before the activator runs ([#3521](https://github.com/malbeclabs/doublezero/pull/3521)) - Add optional `owner` field to `UpdateMulticastGroup` instruction, allowing foundation members to reassign ownership of a multicast group ([#3527](https://github.com/malbeclabs/doublezero/pull/3527)) + - Rename subscribe processor functions (`process_subscribe_multicastgroup` → `process_update_multicastgroup_subscription`) to reflect that they handle both subscribe and unsubscribe, and simplify the status validation guard - Geolocation - Add optional result destination to `GeolocationUser` so LocationOffsets can be sent to an alternate endpoint instead of the target IP; supports both IP and domain destinations (e.g., `185.199.108.1:9000` or `results.example.com:9000`); includes `SetResultDestination` onchain instruction, CLI `user set-result-destination` command, and Go SDK deserialization (backwards-compatible with existing accounts) - CLI From 819e3bc28a27d808c47d0f78561a3c94abb13da8 Mon Sep 17 00:00:00 2001 From: Martin Sander Date: Wed, 15 Apr 2026 15:18:23 -0500 Subject: [PATCH 3/4] smartcontract: use 'roles' instead of 'subscription' in rename --- CHANGELOG.md | 2 +- .../src/entrypoint.rs | 4 ++-- .../src/processors/multicastgroup/subscribe.rs | 18 +++++++++--------- .../src/processors/user/create_subscribe.rs | 4 ++-- .../tests/multicastgroup_subscribe_test.rs | 2 +- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2823b25e1..0106f1dc8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ All notable changes to this project will be documented in this file. - Smartcontract - Allow `SubscribeMulticastGroup` for users in `Pending` status so that `CreateSubscribeUser` can be followed by additional subscribe calls before the activator runs ([#3521](https://github.com/malbeclabs/doublezero/pull/3521)) - Add optional `owner` field to `UpdateMulticastGroup` instruction, allowing foundation members to reassign ownership of a multicast group ([#3527](https://github.com/malbeclabs/doublezero/pull/3527)) - - Rename subscribe processor functions (`process_subscribe_multicastgroup` → `process_update_multicastgroup_subscription`) to reflect that they handle both subscribe and unsubscribe, and simplify the status validation guard + - Rename subscribe processor functions (`process_subscribe_multicastgroup` → `process_update_multicastgroup_roles`) to clarify they manage publisher/subscriber roles, not just subscriptions - Geolocation - Add optional result destination to `GeolocationUser` so LocationOffsets can be sent to an alternate endpoint instead of the target IP; supports both IP and domain destinations (e.g., `185.199.108.1:9000` or `results.example.com:9000`); includes `SetResultDestination` onchain instruction, CLI `user set-result-destination` command, and Go SDK deserialization (backwards-compatible with existing accounts) - CLI diff --git a/smartcontract/programs/doublezero-serviceability/src/entrypoint.rs b/smartcontract/programs/doublezero-serviceability/src/entrypoint.rs index 8fdca284f..b6b8d6ecb 100644 --- a/smartcontract/programs/doublezero-serviceability/src/entrypoint.rs +++ b/smartcontract/programs/doublezero-serviceability/src/entrypoint.rs @@ -77,7 +77,7 @@ use crate::{ delete::process_delete_multicastgroup, reactivate::process_reactivate_multicastgroup, reject::process_reject_multicastgroup, - subscribe::process_update_multicastgroup_subscription, + subscribe::process_update_multicastgroup_roles, suspend::process_suspend_multicastgroup, update::process_update_multicastgroup, }, @@ -294,7 +294,7 @@ pub fn process_instruction( process_remove_multicast_sub_allowlist(program_id, accounts, &value)? } DoubleZeroInstruction::SubscribeMulticastGroup(value) => { - process_update_multicastgroup_subscription(program_id, accounts, &value)? + process_update_multicastgroup_roles(program_id, accounts, &value)? } DoubleZeroInstruction::CreateSubscribeUser(value) => { process_create_subscribe_user(program_id, accounts, &value)? diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/subscribe.rs b/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/subscribe.rs index e102ecd8f..9c2fbe150 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/subscribe.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/subscribe.rs @@ -54,13 +54,13 @@ pub struct SubscribeUserResult { pub publisher_list_transitioned: bool, } -/// Toggle a user's multicast group subscription. +/// Toggle a user's multicast group roles. /// /// Handles both create-time subscription (user lists start empty, only adds) /// and post-activation subscription changes (add/remove toggle). The caller is /// responsible for setting `user.status = Updating` when /// `publisher_list_transitioned` is true and the user is already activated. -pub fn update_user_multicastgroup_subscription( +pub fn update_user_multicastgroup_roles( mgroup_account: &AccountInfo, accesspass: &AccessPass, user: &mut User, @@ -130,7 +130,7 @@ pub fn update_user_multicastgroup_subscription( }) } -pub fn process_update_multicastgroup_subscription( +pub fn process_update_multicastgroup_roles( program_id: &Pubkey, accounts: &[AccountInfo], value: &MulticastGroupSubscribeArgs, @@ -171,7 +171,7 @@ pub fn process_update_multicastgroup_subscription( let system_program = next_account_info(accounts_iter)?; #[cfg(test)] - msg!("process_update_multicastgroup_subscription({:?})", value); + msg!("process_update_multicastgroup_roles({:?})", value); // Check if the payer is a signer assert!(payer_account.is_signer, "Payer must be a signer"); @@ -201,12 +201,12 @@ pub fn process_update_multicastgroup_subscription( // Parse and validate user let mut user: User = User::try_from(user_account)?; - // Unsubscribe is allowed for any status so that users + // Removing all roles is allowed for any status so that users // created via CreateSubscribeUser can be cleaned up before activation. - // Subscribe is also allowed for Pending users so that CreateSubscribeUser + // Adding roles is also allowed for Pending users so that CreateSubscribeUser // (which only takes one mgroup) can be followed by additional calls. - let is_subscribe = value.publisher || value.subscriber; - if is_subscribe + let has_role = value.publisher || value.subscriber; + if has_role && user.status != UserStatus::Activated && user.status != UserStatus::Updating && user.status != UserStatus::Pending @@ -254,7 +254,7 @@ pub fn process_update_multicastgroup_subscription( } } - let result = update_user_multicastgroup_subscription( + let result = update_user_multicastgroup_roles( mgroup_account, &accesspass, &mut user, diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/user/create_subscribe.rs b/smartcontract/programs/doublezero-serviceability/src/processors/user/create_subscribe.rs index 1434e7d5c..83a0b1a53 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/user/create_subscribe.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/user/create_subscribe.rs @@ -18,7 +18,7 @@ use super::{ create_core::{create_user_core, CreateUserCoreAccounts, PDAVersion}, resource_onchain_helpers, }; -use crate::processors::multicastgroup::subscribe::update_user_multicastgroup_subscription; +use crate::processors::multicastgroup::subscribe::update_user_multicastgroup_roles; #[derive(BorshSerialize, BorshDeserializeIncremental, PartialEq, Clone)] pub struct UserCreateSubscribeArgs { @@ -111,7 +111,7 @@ pub fn process_create_subscribe_user( )?; // Subscribe user to multicast group - let subscribe_result = update_user_multicastgroup_subscription( + let subscribe_result = update_user_multicastgroup_roles( mgroup_account, &result.accesspass, &mut result.user, diff --git a/smartcontract/programs/doublezero-serviceability/tests/multicastgroup_subscribe_test.rs b/smartcontract/programs/doublezero-serviceability/tests/multicastgroup_subscribe_test.rs index a5188846a..a741502d1 100644 --- a/smartcontract/programs/doublezero-serviceability/tests/multicastgroup_subscribe_test.rs +++ b/smartcontract/programs/doublezero-serviceability/tests/multicastgroup_subscribe_test.rs @@ -969,7 +969,7 @@ async fn test_duplicate_publisher_subscribe_is_noop() { } /// Foundation admin (payer != user.owner) can subscribe a user to a multicast group. -/// Regression test for the bug where process_update_multicastgroup_subscription derived the AccessPass PDA +/// Regression test for the bug where process_update_multicastgroup_roles derived the AccessPass PDA /// using payer_account.key instead of user.owner. #[tokio::test] async fn test_subscribe_foundation_admin_payer_differs_from_user_owner() { From 75f82d83da77278bbd5b64f84ba51a18f26d70a1 Mon Sep 17 00:00:00 2001 From: Martin Sander Date: Wed, 15 Apr 2026 15:27:56 -0500 Subject: [PATCH 4/4] smartcontract: rename SubscribeMulticastGroup to UpdateMulticastGroupRoles Rename instruction variant, args struct, SDK command, and trait method to use 'roles' terminology, clarifying the instruction manages both publisher and subscriber roles rather than just subscriptions. --- CHANGELOG.md | 2 +- client/doublezero/src/command/connect.rs | 52 ++++++++++--------- smartcontract/cli/src/doublezerocommand.rs | 10 ++-- smartcontract/cli/src/user/subscribe.rs | 25 ++++----- .../src/entrypoint.rs | 2 +- .../src/instructions.rs | 18 +++---- .../processors/multicastgroup/subscribe.rs | 6 +-- .../tests/create_subscribe_user_test.rs | 16 +++--- .../tests/multicastgroup_subscribe_test.rs | 42 +++++++-------- .../tests/user_onchain_allocation_test.rs | 34 ++++++------ .../src/commands/multicastgroup/subscribe.rs | 26 +++++----- .../sdk/rs/src/commands/user/delete.rs | 32 ++++++------ .../sdk/rs/src/commands/user/requestban.rs | 4 +- 13 files changed, 136 insertions(+), 133 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0106f1dc8..6ffa524f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ All notable changes to this project will be documented in this file. - Smartcontract - Allow `SubscribeMulticastGroup` for users in `Pending` status so that `CreateSubscribeUser` can be followed by additional subscribe calls before the activator runs ([#3521](https://github.com/malbeclabs/doublezero/pull/3521)) - Add optional `owner` field to `UpdateMulticastGroup` instruction, allowing foundation members to reassign ownership of a multicast group ([#3527](https://github.com/malbeclabs/doublezero/pull/3527)) - - Rename subscribe processor functions (`process_subscribe_multicastgroup` → `process_update_multicastgroup_roles`) to clarify they manage publisher/subscriber roles, not just subscriptions + - Rename `SubscribeMulticastGroup` instruction variant to `UpdateMulticastGroupRoles` and rename associated processor functions, args struct, and SDK command to use "roles" terminology, clarifying they manage publisher/subscriber roles rather than just subscriptions - Geolocation - Add optional result destination to `GeolocationUser` so LocationOffsets can be sent to an alternate endpoint instead of the target IP; supports both IP and domain destinations (e.g., `185.199.108.1:9000` or `results.example.com:9000`); includes `SetResultDestination` onchain instruction, CLI `user set-result-destination` command, and Go SDK deserialization (backwards-compatible with existing accounts) - CLI diff --git a/client/doublezero/src/command/connect.rs b/client/doublezero/src/command/connect.rs index 91e54e118..d6995876d 100644 --- a/client/doublezero/src/command/connect.rs +++ b/client/doublezero/src/command/connect.rs @@ -15,7 +15,7 @@ use doublezero_sdk::{ accesspass::get::GetAccessPassCommand, device::{get::GetDeviceCommand, list::ListDeviceCommand}, multicastgroup::{ - list::ListMulticastGroupCommand, subscribe::SubscribeMulticastGroupCommand, + list::ListMulticastGroupCommand, subscribe::UpdateMulticastGroupRolesCommand, }, tenant::get::GetTenantCommand, user::{ @@ -621,7 +621,7 @@ impl ProvisioningCliCommand { // Subscribe to remaining groups for group_pk in all_group_pks.iter().skip(1) { spinner.println(format!(" Subscribing to group: {group_pk}")); - client.subscribe_multicastgroup(SubscribeMulticastGroupCommand { + client.update_multicastgroup_roles(UpdateMulticastGroupRolesCommand { user_pk, group_pk: *group_pk, client_ip: *client_ip, @@ -647,13 +647,14 @@ impl ProvisioningCliCommand { user_pk )); - let res = client.subscribe_multicastgroup(SubscribeMulticastGroupCommand { - user_pk: *user_pk, - group_pk: *group_pk, - client_ip: *client_ip, - publisher: true, - subscriber: false, - }); + let res = + client.update_multicastgroup_roles(UpdateMulticastGroupRolesCommand { + user_pk: *user_pk, + group_pk: *group_pk, + client_ip: *client_ip, + publisher: true, + subscriber: false, + }); match res { Ok(_) => { @@ -676,13 +677,14 @@ impl ProvisioningCliCommand { user_pk )); - let res = client.subscribe_multicastgroup(SubscribeMulticastGroupCommand { - user_pk: *user_pk, - group_pk: *group_pk, - client_ip: *client_ip, - publisher: false, - subscriber: true, - }); + let res = + client.update_multicastgroup_roles(UpdateMulticastGroupRolesCommand { + user_pk: *user_pk, + group_pk: *group_pk, + client_ip: *client_ip, + publisher: false, + subscriber: true, + }); match res { Ok(_) => { @@ -757,7 +759,7 @@ impl ProvisioningCliCommand { // Subscribe to remaining groups for group_pk in all_group_pks.iter().skip(1) { spinner.println(format!(" Subscribing to group: {group_pk}")); - client.subscribe_multicastgroup(SubscribeMulticastGroupCommand { + client.update_multicastgroup_roles(UpdateMulticastGroupRolesCommand { user_pk, group_pk: *group_pk, client_ip: *client_ip, @@ -1518,7 +1520,7 @@ mod tests { } #[allow(dead_code)] - pub fn expect_subscribe_multicastgroup( + pub fn expect_update_multicastgroup_roles( &mut self, user_pk: Pubkey, mcast_group_pk: Pubkey, @@ -1526,7 +1528,7 @@ mod tests { publisher: bool, subscriber: bool, ) { - let expected_command = SubscribeMulticastGroupCommand { + let expected_command = UpdateMulticastGroupRolesCommand { user_pk, group_pk: mcast_group_pk, client_ip, @@ -1537,7 +1539,7 @@ mod tests { let users = self.users.clone(); let provisioned = self.provisioned_services.clone(); self.client - .expect_subscribe_multicastgroup() + .expect_update_multicastgroup_roles() .times(1) .with(predicate::eq(expected_command)) .returning_st(move |cmd| { @@ -1887,7 +1889,7 @@ mod tests { let user_pk = fixture.add_user(&user); // Expect subscribe to second group - fixture.expect_subscribe_multicastgroup( + fixture.expect_update_multicastgroup_roles( user_pk, mcast_group2_pk, user.client_ip, @@ -1963,8 +1965,8 @@ mod tests { user.publishers.push(mcast_group_pk); let user_pk = fixture.add_user(&user); - // Expect subscribe_multicastgroup call for the new subscriber group - fixture.expect_subscribe_multicastgroup( + // Expect update_multicastgroup_roles call for the new subscriber group + fixture.expect_update_multicastgroup_roles( user_pk, mcast_group2_pk, user.client_ip, @@ -2005,8 +2007,8 @@ mod tests { user.subscribers.push(mcast_group_pk); let user_pk = fixture.add_user(&user); - // Expect subscribe_multicastgroup call for the new publisher group - fixture.expect_subscribe_multicastgroup( + // Expect update_multicastgroup_roles call for the new publisher group + fixture.expect_update_multicastgroup_roles( user_pk, mcast_group2_pk, user.client_ip, diff --git a/smartcontract/cli/src/doublezerocommand.rs b/smartcontract/cli/src/doublezerocommand.rs index f77628ac6..0f9d97a64 100644 --- a/smartcontract/cli/src/doublezerocommand.rs +++ b/smartcontract/cli/src/doublezerocommand.rs @@ -78,7 +78,7 @@ use doublezero_sdk::{ get::GetMulticastGroupCommand, list::ListMulticastGroupCommand, reject::RejectMulticastGroupCommand, - subscribe::SubscribeMulticastGroupCommand, + subscribe::UpdateMulticastGroupRolesCommand, update::UpdateMulticastGroupCommand, }, permission::{ @@ -298,9 +298,9 @@ pub trait CliCommand { &self, cmd: DeactivateMulticastGroupCommand, ) -> eyre::Result; - fn subscribe_multicastgroup( + fn update_multicastgroup_roles( &self, - cmd: SubscribeMulticastGroupCommand, + cmd: UpdateMulticastGroupRolesCommand, ) -> eyre::Result; fn add_multicastgroup_pub_allowlist( &self, @@ -737,9 +737,9 @@ impl CliCommand for CliCommandImpl<'_> { ) -> eyre::Result { cmd.execute(self.client) } - fn subscribe_multicastgroup( + fn update_multicastgroup_roles( &self, - cmd: SubscribeMulticastGroupCommand, + cmd: UpdateMulticastGroupRolesCommand, ) -> eyre::Result { cmd.execute(self.client) } diff --git a/smartcontract/cli/src/user/subscribe.rs b/smartcontract/cli/src/user/subscribe.rs index 1c8fb6c31..40332bbc0 100644 --- a/smartcontract/cli/src/user/subscribe.rs +++ b/smartcontract/cli/src/user/subscribe.rs @@ -7,7 +7,7 @@ use crate::{ }; use clap::Args; use doublezero_sdk::commands::{ - multicastgroup::{get::GetMulticastGroupCommand, subscribe::SubscribeMulticastGroupCommand}, + multicastgroup::{get::GetMulticastGroupCommand, subscribe::UpdateMulticastGroupRolesCommand}, user::get::GetUserCommand, }; use std::io::Write; @@ -59,13 +59,14 @@ impl SubscribeUserCliCommand { // Subscribe to each group for group_pk in &group_pks { - let signature = client.subscribe_multicastgroup(SubscribeMulticastGroupCommand { - user_pk, - group_pk: *group_pk, - client_ip: user.client_ip, - publisher: self.publisher, - subscriber: self.subscriber, - })?; + let signature = + client.update_multicastgroup_roles(UpdateMulticastGroupRolesCommand { + user_pk, + group_pk: *group_pk, + client_ip: user.client_ip, + publisher: self.publisher, + subscriber: self.subscriber, + })?; writeln!(out, "Subscribed to {group_pk}: {signature}")?; } @@ -93,7 +94,7 @@ mod tests { use doublezero_sdk::{ commands::{ multicastgroup::{ - get::GetMulticastGroupCommand, subscribe::SubscribeMulticastGroupCommand, + get::GetMulticastGroupCommand, subscribe::UpdateMulticastGroupRolesCommand, }, user::get::GetUserCommand, }, @@ -172,8 +173,8 @@ mod tests { })) .returning(move |_| Ok((mgroup_pubkey, mgroup.clone()))); client - .expect_subscribe_multicastgroup() - .with(predicate::eq(SubscribeMulticastGroupCommand { + .expect_update_multicastgroup_roles() + .with(predicate::eq(UpdateMulticastGroupRolesCommand { user_pk: user_pubkey, group_pk: mgroup_pubkey, client_ip, @@ -292,7 +293,7 @@ mod tests { })) .returning(move |_| Ok((mgroup_pubkey2, mgroup2.clone()))); client - .expect_subscribe_multicastgroup() + .expect_update_multicastgroup_roles() .times(2) .returning(move |_| Ok(signature)); diff --git a/smartcontract/programs/doublezero-serviceability/src/entrypoint.rs b/smartcontract/programs/doublezero-serviceability/src/entrypoint.rs index b6b8d6ecb..28847abbd 100644 --- a/smartcontract/programs/doublezero-serviceability/src/entrypoint.rs +++ b/smartcontract/programs/doublezero-serviceability/src/entrypoint.rs @@ -293,7 +293,7 @@ pub fn process_instruction( DoubleZeroInstruction::RemoveMulticastGroupSubAllowlist(value) => { process_remove_multicast_sub_allowlist(program_id, accounts, &value)? } - DoubleZeroInstruction::SubscribeMulticastGroup(value) => { + DoubleZeroInstruction::UpdateMulticastGroupRoles(value) => { process_update_multicastgroup_roles(program_id, accounts, &value)? } DoubleZeroInstruction::CreateSubscribeUser(value) => { diff --git a/smartcontract/programs/doublezero-serviceability/src/instructions.rs b/smartcontract/programs/doublezero-serviceability/src/instructions.rs index 40f6cda8b..ff805a372 100644 --- a/smartcontract/programs/doublezero-serviceability/src/instructions.rs +++ b/smartcontract/programs/doublezero-serviceability/src/instructions.rs @@ -63,7 +63,7 @@ use crate::processors::{ delete::MulticastGroupDeleteArgs, reactivate::MulticastGroupReactivateArgs, reject::MulticastGroupRejectArgs, - subscribe::MulticastGroupSubscribeArgs, + subscribe::UpdateMulticastGroupRolesArgs, suspend::MulticastGroupSuspendArgs, update::MulticastGroupUpdateArgs, }, @@ -162,8 +162,8 @@ pub enum DoubleZeroInstruction { AddMulticastGroupSubAllowlist(AddMulticastGroupSubAllowlistArgs), // variant 56 RemoveMulticastGroupSubAllowlist(RemoveMulticastGroupSubAllowlistArgs), // variant 57 - SubscribeMulticastGroup(MulticastGroupSubscribeArgs), // variant 58 - CreateSubscribeUser(UserCreateSubscribeArgs), // variant 59 + UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs), // variant 58 + CreateSubscribeUser(UserCreateSubscribeArgs), // variant 59 CreateContributor(ContributorCreateArgs), // variant 60 UpdateContributor(ContributorUpdateArgs), // variant 61 @@ -304,7 +304,7 @@ impl DoubleZeroInstruction { 55 => Ok(Self::RemoveMulticastGroupPubAllowlist(RemoveMulticastGroupPubAllowlistArgs::try_from(rest).unwrap())), 56 => Ok(Self::AddMulticastGroupSubAllowlist(AddMulticastGroupSubAllowlistArgs::try_from(rest).unwrap())), 57 => Ok(Self::RemoveMulticastGroupSubAllowlist(RemoveMulticastGroupSubAllowlistArgs::try_from(rest).unwrap())), - 58 => Ok(Self::SubscribeMulticastGroup(MulticastGroupSubscribeArgs::try_from(rest).unwrap())), + 58 => Ok(Self::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs::try_from(rest).unwrap())), 59 => Ok(Self::CreateSubscribeUser(UserCreateSubscribeArgs::try_from(rest).unwrap())), 60 => Ok(Self::CreateContributor(ContributorCreateArgs::try_from(rest).unwrap())), @@ -438,8 +438,8 @@ impl DoubleZeroInstruction { "RemoveMulticastGroupSubAllowlist".to_string() } // variant 57 - Self::SubscribeMulticastGroup(_) => "SubscribeMulticastGroup".to_string(), // variant 58 - Self::CreateSubscribeUser(_) => "CreateSubscribeUser".to_string(), // variant 59 + Self::UpdateMulticastGroupRoles(_) => "UpdateMulticastGroupRoles".to_string(), // variant 58 + Self::CreateSubscribeUser(_) => "CreateSubscribeUser".to_string(), // variant 59 Self::CreateContributor(_) => "CreateContributor".to_string(), // variant 60 Self::UpdateContributor(_) => "UpdateContributor".to_string(), // variant 61 @@ -564,7 +564,7 @@ impl DoubleZeroInstruction { Self::DeleteMulticastGroup(args) => format!("{args:?}"), // variant 51 Self::UpdateMulticastGroup(args) => format!("{args:?}"), // variant 52 Self::DeactivateMulticastGroup(args) => format!("{args:?}"), // variant 53 - Self::SubscribeMulticastGroup(args) => format!("{args:?}"), // variant 54 + Self::UpdateMulticastGroupRoles(args) => format!("{args:?}"), // variant 54 Self::AddMulticastGroupPubAllowlist(args) => format!("{args:?}"), // variant 55 Self::RemoveMulticastGroupPubAllowlist(args) => format!("{args:?}"), // variant 56 Self::AddMulticastGroupSubAllowlist(args) => format!("{args:?}"), // variant 57 @@ -1060,13 +1060,13 @@ mod tests { "RemoveMulticastGroupSubAllowlist", ); test_instruction( - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: [1, 2, 3, 4].into(), publisher: false, subscriber: true, use_onchain_allocation: false, }), - "SubscribeMulticastGroup", + "UpdateMulticastGroupRoles", ); test_instruction( DoubleZeroInstruction::CreateSubscribeUser(UserCreateSubscribeArgs { diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/subscribe.rs b/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/subscribe.rs index 9c2fbe150..668a02a8c 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/subscribe.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/subscribe.rs @@ -27,7 +27,7 @@ use solana_program::{ }; use std::{fmt, net::Ipv4Addr}; #[derive(BorshSerialize, BorshDeserializeIncremental, PartialEq, Clone)] -pub struct MulticastGroupSubscribeArgs { +pub struct UpdateMulticastGroupRolesArgs { #[incremental(default = Ipv4Addr::UNSPECIFIED)] pub client_ip: Ipv4Addr, pub publisher: bool, @@ -36,7 +36,7 @@ pub struct MulticastGroupSubscribeArgs { pub use_onchain_allocation: bool, } -impl fmt::Debug for MulticastGroupSubscribeArgs { +impl fmt::Debug for UpdateMulticastGroupRolesArgs { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, @@ -133,7 +133,7 @@ pub fn update_user_multicastgroup_roles( pub fn process_update_multicastgroup_roles( program_id: &Pubkey, accounts: &[AccountInfo], - value: &MulticastGroupSubscribeArgs, + value: &UpdateMulticastGroupRolesArgs, ) -> ProgramResult { let num_accounts = accounts.len(); let accounts_iter = &mut accounts.iter(); diff --git a/smartcontract/programs/doublezero-serviceability/tests/create_subscribe_user_test.rs b/smartcontract/programs/doublezero-serviceability/tests/create_subscribe_user_test.rs index 17da27f48..5ff0fc58a 100644 --- a/smartcontract/programs/doublezero-serviceability/tests/create_subscribe_user_test.rs +++ b/smartcontract/programs/doublezero-serviceability/tests/create_subscribe_user_test.rs @@ -34,7 +34,7 @@ use doublezero_serviceability::{ subscriber::add::AddMulticastGroupSubAllowlistArgs, }, create::MulticastGroupCreateArgs, - subscribe::MulticastGroupSubscribeArgs, + subscribe::UpdateMulticastGroupRolesArgs, }, tenant::create::TenantCreateArgs, user::{ @@ -1095,7 +1095,7 @@ async fn test_create_subscribe_user_ignores_tenant_allowlist() { /// unsubscribing (the Updating→Activated path must NOT reset the flag). /// /// This covers the exact E2E failure scenario: publisher connects (CreateSubscribeUser → -/// ActivateUser), then disconnects (SubscribeMulticastGroup publisher=false → ActivateUser). +/// ActivateUser), then disconnects (UpdateMulticastGroupRoles publisher=false → ActivateUser). /// After disconnect, CreatedAsPublisher flag must still be set so delete decrements publishers_count. #[tokio::test] async fn test_publisher_multicast_publisher_persists_through_disconnect() { @@ -1217,7 +1217,7 @@ async fn test_publisher_multicast_publisher_persists_through_disconnect() { &mut banks_client, recent_blockhash, program_id, - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: user_ip, publisher: false, subscriber: false, @@ -1240,7 +1240,7 @@ async fn test_publisher_multicast_publisher_persists_through_disconnect() { .unwrap(); assert_eq!(user_updating.status, UserStatus::Updating); assert!(user_updating.publishers.is_empty()); - // CreatedAsPublisher flag should still be set (SubscribeMulticastGroup doesn't touch it) + // CreatedAsPublisher flag should still be set (UpdateMulticastGroupRoles doesn't touch it) assert!( TunnelFlags::is_set(user_updating.tunnel_flags, TunnelFlags::CreatedAsPublisher), "CreatedAsPublisher flag must still be set after unsubscribing (only activate.rs touches tunnel_flags)" @@ -1383,7 +1383,7 @@ async fn test_publisher_disconnect_delete_decrements_publishers_count() { &mut banks_client, recent_blockhash, program_id, - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: user_ip, publisher: false, subscriber: false, @@ -2598,7 +2598,7 @@ async fn test_unsubscribe_pending_user_created_via_create_subscribe() { &mut banks_client, recent_blockhash, program_id, - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: user_ip, publisher: false, subscriber: false, @@ -2631,7 +2631,7 @@ async fn test_unsubscribe_pending_user_created_via_create_subscribe() { } /// Subscribing a Pending user must succeed so that CreateSubscribeUser (which -/// only takes one mgroup) can be followed by additional SubscribeMulticastGroup +/// only takes one mgroup) can be followed by additional UpdateMulticastGroupRoles /// calls before the activator runs. This mirrors the shred oracle flow where a /// user is subscribed to multiple multicast groups at creation time. #[tokio::test] @@ -2695,7 +2695,7 @@ async fn test_subscribe_pending_user_succeeds() { &mut banks_client, recent_blockhash, program_id, - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: user_ip, publisher: true, subscriber: true, diff --git a/smartcontract/programs/doublezero-serviceability/tests/multicastgroup_subscribe_test.rs b/smartcontract/programs/doublezero-serviceability/tests/multicastgroup_subscribe_test.rs index a741502d1..e06811323 100644 --- a/smartcontract/programs/doublezero-serviceability/tests/multicastgroup_subscribe_test.rs +++ b/smartcontract/programs/doublezero-serviceability/tests/multicastgroup_subscribe_test.rs @@ -17,7 +17,7 @@ use doublezero_serviceability::{ subscriber::add::AddMulticastGroupSubAllowlistArgs, }, create::MulticastGroupCreateArgs, - subscribe::MulticastGroupSubscribeArgs, + subscribe::UpdateMulticastGroupRolesArgs, }, user::{activate::UserActivateArgs, create::UserCreateArgs}, }, @@ -484,7 +484,7 @@ async fn test_subscribe_first_publisher_sets_updating() { &mut banks_client, recent_blockhash, program_id, - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: [100, 0, 0, 1].into(), publisher: true, subscriber: false, @@ -542,7 +542,7 @@ async fn test_subscribe_second_publisher_does_not_set_updating() { &mut banks_client, recent_blockhash, program_id, - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: [100, 0, 0, 1].into(), publisher: true, subscriber: false, @@ -591,7 +591,7 @@ async fn test_subscribe_second_publisher_does_not_set_updating() { &mut banks_client, recent_blockhash, program_id, - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: [100, 0, 0, 1].into(), publisher: true, subscriber: false, @@ -655,7 +655,7 @@ async fn test_subscribe_subscriber_does_not_set_updating() { &mut banks_client, recent_blockhash, program_id, - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: [100, 0, 0, 1].into(), publisher: false, subscriber: true, @@ -688,7 +688,7 @@ async fn test_subscribe_subscriber_does_not_set_updating() { &mut banks_client, recent_blockhash, program_id, - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: [100, 0, 0, 1].into(), publisher: false, subscriber: true, @@ -753,7 +753,7 @@ async fn test_unsubscribe_last_publisher_sets_updating() { &mut banks_client, recent_blockhash, program_id, - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: [100, 0, 0, 1].into(), publisher: true, subscriber: false, @@ -804,7 +804,7 @@ async fn test_unsubscribe_last_publisher_sets_updating() { &mut banks_client, recent_blockhash, program_id, - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: [100, 0, 0, 1].into(), publisher: false, subscriber: false, @@ -837,7 +837,7 @@ async fn test_unsubscribe_last_publisher_sets_updating() { &mut banks_client, recent_blockhash, program_id, - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: [100, 0, 0, 1].into(), publisher: false, subscriber: false, @@ -887,7 +887,7 @@ async fn test_duplicate_publisher_subscribe_is_noop() { &mut banks_client, recent_blockhash, program_id, - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: [100, 0, 0, 1].into(), publisher: true, subscriber: false, @@ -929,7 +929,7 @@ async fn test_duplicate_publisher_subscribe_is_noop() { &mut banks_client, recent_blockhash, program_id, - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: [100, 0, 0, 1].into(), publisher: true, subscriber: false, @@ -1017,7 +1017,7 @@ async fn test_subscribe_foundation_admin_payer_differs_from_user_owner() { &mut banks_client, recent_blockhash, program_id, - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: [100, 0, 0, 1].into(), publisher: false, subscriber: true, @@ -1067,7 +1067,7 @@ async fn test_unsubscribe_foundation_admin_payer_differs_from_user_owner() { &mut banks_client, recent_blockhash, program_id, - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: [100, 0, 0, 1].into(), publisher: false, subscriber: true, @@ -1123,7 +1123,7 @@ async fn test_unsubscribe_foundation_admin_payer_differs_from_user_owner() { &mut banks_client, recent_blockhash, program_id, - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: [100, 0, 0, 1].into(), publisher: false, subscriber: false, @@ -1172,7 +1172,7 @@ async fn test_subscribe_unauthorized_payer_rejected() { &mut banks_client, recent_blockhash, program_id, - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: [100, 0, 0, 1].into(), publisher: false, subscriber: true, @@ -1220,7 +1220,7 @@ async fn test_subscribe_unauthorized_payer_rejected_without_globalstate() { &mut banks_client, recent_blockhash, program_id, - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: [100, 0, 0, 1].into(), publisher: false, subscriber: true, @@ -1309,7 +1309,7 @@ async fn test_subscribe_onchain_first_publisher_allocates_dz_ip() { &mut banks_client, recent_blockhash, program_id, - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: [100, 0, 0, 1].into(), publisher: true, subscriber: false, @@ -1391,7 +1391,7 @@ async fn test_subscribe_onchain_subscriber_no_allocation() { &mut banks_client, recent_blockhash, program_id, - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: [100, 0, 0, 1].into(), publisher: false, subscriber: true, @@ -1447,7 +1447,7 @@ async fn test_subscribe_onchain_feature_flag_disabled_fails() { &mut banks_client, recent_blockhash, program_id, - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: [100, 0, 0, 1].into(), publisher: true, subscriber: false, @@ -1511,7 +1511,7 @@ async fn test_subscribe_onchain_second_publisher_no_reallocation() { &mut banks_client, recent_blockhash, program_id, - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: [100, 0, 0, 1].into(), publisher: true, subscriber: false, @@ -1541,7 +1541,7 @@ async fn test_subscribe_onchain_second_publisher_no_reallocation() { &mut banks_client, recent_blockhash, program_id, - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: [100, 0, 0, 1].into(), publisher: true, subscriber: false, diff --git a/smartcontract/programs/doublezero-serviceability/tests/user_onchain_allocation_test.rs b/smartcontract/programs/doublezero-serviceability/tests/user_onchain_allocation_test.rs index 2bd244622..6a7d9f312 100644 --- a/smartcontract/programs/doublezero-serviceability/tests/user_onchain_allocation_test.rs +++ b/smartcontract/programs/doublezero-serviceability/tests/user_onchain_allocation_test.rs @@ -34,7 +34,7 @@ use doublezero_serviceability::{ subscriber::add::AddMulticastGroupSubAllowlistArgs, }, create::MulticastGroupCreateArgs, - subscribe::MulticastGroupSubscribeArgs, + subscribe::UpdateMulticastGroupRolesArgs, }, user::{ activate::UserActivateArgs, closeaccount::UserCloseAccountArgs, create::UserCreateArgs, @@ -1165,12 +1165,12 @@ async fn test_multicast_subscribe_reactivation_preserves_allocations() { // ========================================================================= let recent_blockhash = wait_for_new_blockhash(&mut banks_client).await; - // SubscribeMulticastGroup (6 accounts: mgroup, accesspass, user, globalstate, payer, system_program) + // UpdateMulticastGroupRoles (6 accounts: mgroup, accesspass, user, globalstate, payer, system_program) execute_transaction( &mut banks_client, recent_blockhash, program_id, - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: client_ip.into(), publisher: true, subscriber: false, @@ -1478,7 +1478,7 @@ async fn test_multicast_publisher_block_deallocation_and_reuse() { &mut banks_client, recent_blockhash, program_id, - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: client_ip.into(), publisher: true, subscriber: false, @@ -1569,7 +1569,7 @@ async fn test_multicast_publisher_block_deallocation_and_reuse() { &mut banks_client, recent_blockhash, program_id, - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: client_ip.into(), publisher: false, subscriber: false, @@ -1756,7 +1756,7 @@ async fn test_multicast_publisher_block_deallocation_and_reuse() { &mut banks_client, recent_blockhash, program_id, - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: client_ip.into(), publisher: true, subscriber: false, @@ -3705,7 +3705,7 @@ async fn test_activate_updating_does_not_set_multicast_publisher_for_non_publish &mut banks_client, recent_blockhash, program_id, - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: client_ip.into(), publisher: true, subscriber: false, @@ -3838,7 +3838,7 @@ async fn test_activate_sets_multicast_publisher_false_for_subscriber() { /// Verify that atomic DeleteUser decrements `multicast_subscribers_count` (not /// `multicast_publishers_count`) when the user was created as a non-publisher via /// CreateUser (is_publisher=false → subscribers_count++). Even after the user subscribes -/// as a publisher via SubscribeMulticastGroup and is re-activated, tunnel_flags stays +/// as a publisher via UpdateMulticastGroupRoles and is re-activated, tunnel_flags stays /// false (re-activation/Updating does not set the flag), so the correct counter is decremented. #[tokio::test] async fn test_delete_user_atomic_decrements_subscribers_count_for_non_publisher() { @@ -3958,7 +3958,7 @@ async fn test_delete_user_atomic_decrements_subscribers_count_for_non_publisher( &mut banks_client, recent_blockhash, program_id, - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: client_ip.into(), publisher: true, subscriber: false, @@ -4024,7 +4024,7 @@ async fn test_delete_user_atomic_decrements_subscribers_count_for_non_publisher( &mut banks_client, recent_blockhash, program_id, - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: client_ip.into(), publisher: false, subscriber: false, @@ -4258,7 +4258,7 @@ async fn test_delete_user_atomic_decrements_multicast_subscribers_count() { &mut banks_client, recent_blockhash, program_id, - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: client_ip.into(), publisher: false, subscriber: true, @@ -4297,7 +4297,7 @@ async fn test_delete_user_atomic_decrements_multicast_subscribers_count() { &mut banks_client, recent_blockhash, program_id, - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: client_ip.into(), publisher: false, subscriber: false, @@ -4410,7 +4410,7 @@ async fn test_delete_user_atomic_decrements_multicast_subscribers_count() { /// /// Verify that legacy CloseAccountUser correctly decrements `multicast_subscribers_count` /// when the user was created as a non-publisher (via CreateUser, is_publisher=false). -/// Even though the user later subscribed as a publisher via SubscribeMulticastGroup, +/// Even though the user later subscribed as a publisher via UpdateMulticastGroupRoles, /// the device counter that was incremented at creation time (subscribers_count) is what /// must be decremented at delete time. tunnel_flags stays clear throughout. #[tokio::test] @@ -4529,7 +4529,7 @@ async fn test_closeaccount_user_legacy_after_publisher_unsubscribed_decrements_s &mut banks_client, recent_blockhash, program_id, - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: client_ip.into(), publisher: true, subscriber: false, @@ -4594,7 +4594,7 @@ async fn test_closeaccount_user_legacy_after_publisher_unsubscribed_decrements_s &mut banks_client, recent_blockhash, program_id, - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: client_ip.into(), publisher: false, subscriber: false, @@ -4867,7 +4867,7 @@ async fn test_closeaccount_user_legacy_decrements_subscribers_count_for_non_publ &mut banks_client, recent_blockhash, program_id, - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: client_ip.into(), publisher: true, subscriber: false, @@ -4968,7 +4968,7 @@ async fn test_closeaccount_user_legacy_decrements_subscribers_count_for_non_publ &mut banks_client, recent_blockhash, program_id, - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { client_ip: client_ip.into(), publisher: false, subscriber: false, diff --git a/smartcontract/sdk/rs/src/commands/multicastgroup/subscribe.rs b/smartcontract/sdk/rs/src/commands/multicastgroup/subscribe.rs index 1979be633..d557a1e97 100644 --- a/smartcontract/sdk/rs/src/commands/multicastgroup/subscribe.rs +++ b/smartcontract/sdk/rs/src/commands/multicastgroup/subscribe.rs @@ -10,7 +10,7 @@ use crate::{ use doublezero_serviceability::{ instructions::DoubleZeroInstruction, pda::get_resource_extension_pda, - processors::multicastgroup::subscribe::MulticastGroupSubscribeArgs, + processors::multicastgroup::subscribe::UpdateMulticastGroupRolesArgs, resource::ResourceType, state::{ feature_flags::{is_feature_enabled, FeatureFlag}, @@ -21,7 +21,7 @@ use doublezero_serviceability::{ use solana_sdk::{instruction::AccountMeta, pubkey::Pubkey, signature::Signature}; #[derive(Debug, PartialEq, Clone)] -pub struct SubscribeMulticastGroupCommand { +pub struct UpdateMulticastGroupRolesCommand { pub group_pk: Pubkey, pub client_ip: Ipv4Addr, pub user_pk: Pubkey, @@ -29,7 +29,7 @@ pub struct SubscribeMulticastGroupCommand { pub subscriber: bool, } -impl SubscribeMulticastGroupCommand { +impl UpdateMulticastGroupRolesCommand { pub fn execute(&self, client: &dyn DoubleZeroClient) -> eyre::Result { let (globalstate_pubkey, globalstate) = GetGlobalStateCommand .execute(client) @@ -97,7 +97,7 @@ impl SubscribeMulticastGroupCommand { } client.execute_transaction( - DoubleZeroInstruction::SubscribeMulticastGroup(MulticastGroupSubscribeArgs { + DoubleZeroInstruction::UpdateMulticastGroupRoles(UpdateMulticastGroupRolesArgs { publisher: self.publisher, subscriber: self.subscriber, client_ip: user.client_ip, @@ -111,7 +111,7 @@ impl SubscribeMulticastGroupCommand { #[cfg(test)] mod tests { use crate::{ - commands::multicastgroup::subscribe::SubscribeMulticastGroupCommand, + commands::multicastgroup::subscribe::UpdateMulticastGroupRolesCommand, tests::utils::create_test_client, DoubleZeroClient, MockDoubleZeroClient, }; use doublezero_program_common::types::NetworkV4; @@ -121,7 +121,7 @@ mod tests { get_accesspass_pda, get_globalstate_pda, get_multicastgroup_pda, get_resource_extension_pda, }, - processors::multicastgroup::subscribe::MulticastGroupSubscribeArgs, + processors::multicastgroup::subscribe::UpdateMulticastGroupRolesArgs, resource::ResourceType, state::{ accountdata::AccountData, @@ -208,7 +208,7 @@ mod tests { flags: 0, }; - // First call in SubscribeMulticastGroupCommand::execute tries the dynamic (UNSPECIFIED) PDA, + // First call in UpdateMulticastGroupRolesCommand::execute tries the dynamic (UNSPECIFIED) PDA, // which should fail with a non-AccessPass to trigger the fallback to the fixed client_ip PDA. let (dynamic_accesspass_pubkey, _) = get_accesspass_pda( &client.get_program_id(), @@ -236,8 +236,8 @@ mod tests { client .expect_execute_transaction() .with( - predicate::eq(DoubleZeroInstruction::SubscribeMulticastGroup( - MulticastGroupSubscribeArgs { + predicate::eq(DoubleZeroInstruction::UpdateMulticastGroupRoles( + UpdateMulticastGroupRolesArgs { client_ip, publisher: true, subscriber: false, @@ -253,7 +253,7 @@ mod tests { ) .returning(|_, _| Ok(Signature::new_unique())); - let res = SubscribeMulticastGroupCommand { + let res = UpdateMulticastGroupRolesCommand { group_pk: mgroup_pubkey, user_pk: user_pubkey, client_ip, @@ -373,8 +373,8 @@ mod tests { client .expect_execute_transaction() .with( - predicate::eq(DoubleZeroInstruction::SubscribeMulticastGroup( - MulticastGroupSubscribeArgs { + predicate::eq(DoubleZeroInstruction::UpdateMulticastGroupRoles( + UpdateMulticastGroupRolesArgs { client_ip, publisher: true, subscriber: false, @@ -391,7 +391,7 @@ mod tests { ) .returning(|_, _| Ok(Signature::new_unique())); - let res = SubscribeMulticastGroupCommand { + let res = UpdateMulticastGroupRolesCommand { group_pk: mgroup_pubkey, user_pk: user_pubkey, client_ip, diff --git a/smartcontract/sdk/rs/src/commands/user/delete.rs b/smartcontract/sdk/rs/src/commands/user/delete.rs index ca98b69d2..6e1f66853 100644 --- a/smartcontract/sdk/rs/src/commands/user/delete.rs +++ b/smartcontract/sdk/rs/src/commands/user/delete.rs @@ -6,7 +6,7 @@ use crate::{ device::get::GetDeviceCommand, globalstate::get::GetGlobalStateCommand, multicastgroup::{ - list::ListMulticastGroupCommand, subscribe::SubscribeMulticastGroupCommand, + list::ListMulticastGroupCommand, subscribe::UpdateMulticastGroupRolesCommand, }, user::get::GetUserCommand, }, @@ -53,7 +53,7 @@ impl DeleteUserCommand { let multicastgroups = ListMulticastGroupCommand {}.execute(client)?; for mgroup_pk in &unique_mgroup_pks { if multicastgroups.contains_key(mgroup_pk) { - SubscribeMulticastGroupCommand { + UpdateMulticastGroupRolesCommand { group_pk: *mgroup_pk, user_pk: self.pubkey, client_ip: user.client_ip, @@ -192,7 +192,7 @@ mod tests { get_resource_extension_pda, }, processors::{ - multicastgroup::subscribe::MulticastGroupSubscribeArgs, user::delete::UserDeleteArgs, + multicastgroup::subscribe::UpdateMulticastGroupRolesArgs, user::delete::UserDeleteArgs, }, resource::ResourceType, state::{ @@ -320,7 +320,7 @@ mod tests { Ok(map) }); - // Call 3: MulticastGroup fetch in SubscribeMulticastGroupCommand + // Call 3: MulticastGroup fetch in UpdateMulticastGroupRolesCommand let mgroup_clone = mgroup.clone(); client .expect_get() @@ -329,7 +329,7 @@ mod tests { .in_sequence(&mut seq) .returning(move |_| Ok(AccountData::MulticastGroup(mgroup_clone.clone()))); - // Call 4: User fetch inside SubscribeMulticastGroupCommand - needs Activated + // Call 4: User fetch inside UpdateMulticastGroupRolesCommand - needs Activated let user_clone2 = user_activated_with_sub.clone(); client .expect_get() @@ -338,7 +338,7 @@ mod tests { .in_sequence(&mut seq) .returning(move |_| Ok(AccountData::User(user_clone2.clone()))); - // Call 5: AccessPass fetch in SubscribeMulticastGroupCommand + // Call 5: AccessPass fetch in UpdateMulticastGroupRolesCommand let accesspass_clone1 = accesspass.clone(); client .expect_get() @@ -347,12 +347,12 @@ mod tests { .in_sequence(&mut seq) .returning(move |_| Ok(AccountData::AccessPass(accesspass_clone1.clone()))); - // Execute transaction for SubscribeMulticastGroupCommand (unsubscribe) + // Execute transaction for UpdateMulticastGroupRolesCommand (unsubscribe) client .expect_execute_transaction() .with( - predicate::eq(DoubleZeroInstruction::SubscribeMulticastGroup( - MulticastGroupSubscribeArgs { + predicate::eq(DoubleZeroInstruction::UpdateMulticastGroupRoles( + UpdateMulticastGroupRolesArgs { publisher: false, subscriber: false, client_ip, @@ -558,8 +558,8 @@ mod tests { client .expect_execute_transaction() .with( - predicate::eq(DoubleZeroInstruction::SubscribeMulticastGroup( - MulticastGroupSubscribeArgs { + predicate::eq(DoubleZeroInstruction::UpdateMulticastGroupRoles( + UpdateMulticastGroupRolesArgs { publisher: false, subscriber: false, client_ip, @@ -753,7 +753,7 @@ mod tests { Ok(map) }); - // Call 3: MulticastGroup fetch in SubscribeMulticastGroupCommand + // Call 3: MulticastGroup fetch in UpdateMulticastGroupRolesCommand let mgroup_clone = mgroup.clone(); client .expect_get() @@ -762,7 +762,7 @@ mod tests { .in_sequence(&mut seq) .returning(move |_| Ok(AccountData::MulticastGroup(mgroup_clone.clone()))); - // Call 4: User fetch inside SubscribeMulticastGroupCommand + // Call 4: User fetch inside UpdateMulticastGroupRolesCommand let user_clone2 = user_with_sub.clone(); client .expect_get() @@ -771,7 +771,7 @@ mod tests { .in_sequence(&mut seq) .returning(move |_| Ok(AccountData::User(user_clone2.clone()))); - // Call 5a: UNSPECIFIED AccessPass lookup fails (fallback path) — SubscribeMulticastGroupCommand + // Call 5a: UNSPECIFIED AccessPass lookup fails (fallback path) — UpdateMulticastGroupRolesCommand let user_clone_fallback1 = user_with_sub.clone(); client .expect_get() @@ -793,8 +793,8 @@ mod tests { client .expect_execute_transaction() .with( - predicate::eq(DoubleZeroInstruction::SubscribeMulticastGroup( - MulticastGroupSubscribeArgs { + predicate::eq(DoubleZeroInstruction::UpdateMulticastGroupRoles( + UpdateMulticastGroupRolesArgs { publisher: false, subscriber: false, client_ip, diff --git a/smartcontract/sdk/rs/src/commands/user/requestban.rs b/smartcontract/sdk/rs/src/commands/user/requestban.rs index 452a8794b..40ad3aeb7 100644 --- a/smartcontract/sdk/rs/src/commands/user/requestban.rs +++ b/smartcontract/sdk/rs/src/commands/user/requestban.rs @@ -5,7 +5,7 @@ use crate::{ device::get::GetDeviceCommand, globalstate::get::GetGlobalStateCommand, multicastgroup::{ - list::ListMulticastGroupCommand, subscribe::SubscribeMulticastGroupCommand, + list::ListMulticastGroupCommand, subscribe::UpdateMulticastGroupRolesCommand, }, user::get::GetUserCommand, }, @@ -54,7 +54,7 @@ impl RequestBanUserCommand { let multicastgroups = ListMulticastGroupCommand {}.execute(client)?; for mgroup_pk in &unique_mgroup_pks { if multicastgroups.contains_key(mgroup_pk) { - SubscribeMulticastGroupCommand { + UpdateMulticastGroupRolesCommand { group_pk: *mgroup_pk, user_pk: self.pubkey, client_ip: user.client_ip,