Skip to content

Commit 9cef755

Browse files
smartcontract: replace bare asserts with validate_program_account! macro (#3490)
## Summary - Extend the `validate_program_account!` migration from #3436 to remaining user and multicastgroup allowlist processors - Replaces bare `assert_eq!(account.owner, program_id)` and `assert!(account.is_writable)` with the macro, which also adds `data_is_empty` guards that were previously missing - Covers `set_bgp_status`, `delete`, `closeaccount`, and all four multicastgroup allowlist processors (publisher/subscriber add/remove) ## Lines of Code | Section | Added | Removed | |---------|-------|---------| | Processors (user) | +5 | -14 | | Processors (multicastgroup) | +35 | -26 | | Changelog | +1 | -0 | ## Testing Verification - All 62 doublezero-serviceability tests pass, including the BGP status, user lifecycle, and multicast integration tests
1 parent 5485f03 commit 9cef755

8 files changed

Lines changed: 41 additions & 40 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ All notable changes to this project will be documented in this file.
2323
- Add human-readable error messages for serviceability program errors in the Go SDK, including program log extraction for enhanced debugging
2424
- `user get` no longer fails when no Access Pass exists; it prints a warning to stderr and continues, showing an empty access pass field
2525
- Replace manual account validation assertions with `validate_program_account!` macro across serviceability processor files, adding consistent `data_is_empty` checks and fixing a missing `is_writable` validation in `ResumeLink` ([#3436](https://github.com/malbeclabs/doublezero/pull/3436))
26+
- Extend `validate_program_account!` migration to remaining user and multicastgroup allowlist processors (`set_bgp_status`, `delete`, `closeaccount`, publisher/subscriber `add`/`remove`)
2627
- Add `OutboundIcmp` target type (`= 2`) to the geolocation onchain program, enabling ICMP-based probing as an alternative to TWAMP for outbound geolocation targets
2728
- Geolocation
2829
- geoprobe-target can now store LocationOffset messages in ClickHouse

smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/allowlist/publisher/add.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::{
22
error::DoubleZeroError,
33
pda::get_accesspass_pda,
4+
processors::validation::validate_program_account,
45
seeds::{SEED_ACCESS_PASS, SEED_PREFIX},
56
serializer::{try_acc_create, try_acc_write},
67
state::{
@@ -59,17 +60,17 @@ pub fn process_add_multicastgroup_pub_allowlist(
5960
assert!(payer_account.is_signer, "Payer must be a signer");
6061

6162
// Check the owner of the accounts
62-
assert_eq!(
63-
mgroup_account.owner, program_id,
64-
"Invalid PDA Account Owner"
63+
validate_program_account!(
64+
mgroup_account,
65+
program_id,
66+
writable = true,
67+
"MulticastGroup"
6568
);
6669
assert_eq!(
6770
*system_program.unsigned_key(),
6871
solana_system_interface::program::ID,
6972
"Invalid System Program Account Owner"
7073
);
71-
// Check if the account is writable
72-
assert!(mgroup_account.is_writable, "PDA Account is not writable");
7374

7475
// Parse the global state account
7576
let mgroup = MulticastGroup::try_from(mgroup_account)?;

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

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::{
22
error::DoubleZeroError,
3+
processors::validation::validate_program_account,
34
serializer::try_acc_write,
45
state::{accesspass::AccessPass, globalstate::GlobalState, multicastgroup::MulticastGroup},
56
};
@@ -53,24 +54,26 @@ pub fn process_remove_multicast_pub_allowlist(
5354
assert!(payer_account.is_signer, "Payer must be a signer");
5455

5556
// Check the owner of the accounts
56-
assert_eq!(
57-
mgroup_account.owner, program_id,
58-
"Invalid PDA Account Owner"
57+
validate_program_account!(
58+
mgroup_account,
59+
program_id,
60+
writable = true,
61+
"MulticastGroup"
5962
);
6063
if accesspass_account.data_is_empty() {
6164
return Err(DoubleZeroError::AccessPassNotFound.into());
6265
}
63-
assert_eq!(
64-
accesspass_account.owner, program_id,
65-
"Invalid Accesspass Account Owner"
66+
validate_program_account!(
67+
accesspass_account,
68+
program_id,
69+
writable = false,
70+
"AccessPass"
6671
);
6772
assert_eq!(
6873
*system_program.unsigned_key(),
6974
solana_system_interface::program::ID,
7075
"Invalid System Program Account Owner"
7176
);
72-
// Check if the account is writable
73-
assert!(mgroup_account.is_writable, "PDA Account is not writable");
7477

7578
// Parse the global state account
7679
let mgroup = MulticastGroup::try_from(mgroup_account)?;

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

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::{
22
error::DoubleZeroError,
33
pda::get_accesspass_pda,
4+
processors::validation::validate_program_account,
45
seeds::{SEED_ACCESS_PASS, SEED_PREFIX},
56
serializer::{try_acc_create, try_acc_write},
67
state::{
@@ -60,17 +61,17 @@ pub fn process_add_multicastgroup_sub_allowlist(
6061
assert!(payer_account.is_signer, "Payer must be a signer");
6162

6263
// Check the owner of the accounts
63-
assert_eq!(
64-
mgroup_account.owner, program_id,
65-
"Invalid PDA Account Owner"
64+
validate_program_account!(
65+
mgroup_account,
66+
program_id,
67+
writable = true,
68+
"MulticastGroup"
6669
);
6770
assert_eq!(
6871
*system_program.unsigned_key(),
6972
solana_system_interface::program::ID,
7073
"Invalid System Program Account Owner"
7174
);
72-
// Check if the account is writable
73-
assert!(mgroup_account.is_writable, "PDA Account is not writable");
7475

7576
// Parse the global state account
7677
let mgroup = MulticastGroup::try_from(mgroup_account)?;

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

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::{
22
error::DoubleZeroError,
3+
processors::validation::validate_program_account,
34
serializer::try_acc_write,
45
state::{accesspass::AccessPass, globalstate::GlobalState, multicastgroup::MulticastGroup},
56
};
@@ -53,24 +54,26 @@ pub fn process_remove_multicast_sub_allowlist(
5354
assert!(payer_account.is_signer, "Payer must be a signer");
5455

5556
// Check the owner of the accounts
56-
assert_eq!(
57-
mgroup_account.owner, program_id,
58-
"Invalid PDA Account Owner"
57+
validate_program_account!(
58+
mgroup_account,
59+
program_id,
60+
writable = true,
61+
"MulticastGroup"
5962
);
6063
if accesspass_account.data_is_empty() {
6164
return Err(DoubleZeroError::AccessPassNotFound.into());
6265
}
63-
assert_eq!(
64-
accesspass_account.owner, program_id,
65-
"Invalid Accesspass Account Owner"
66+
validate_program_account!(
67+
accesspass_account,
68+
program_id,
69+
writable = false,
70+
"AccessPass"
6671
);
6772
assert_eq!(
6873
*system_program.unsigned_key(),
6974
solana_system_interface::program::ID,
7075
"Invalid System Program Account Owner"
7176
);
72-
// Check if the account is writable
73-
assert!(mgroup_account.is_writable, "PDA Account is not writable");
7477

7578
// Parse the global state account
7679
let mgroup = MulticastGroup::try_from(mgroup_account)?;

smartcontract/programs/doublezero-serviceability/src/processors/user/closeaccount.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,7 @@ pub fn process_closeaccount_user(
245245
tenant_acc.key, &user.tenant_pk,
246246
"Tenant account doesn't match user's tenant"
247247
);
248-
assert_eq!(tenant_acc.owner, program_id, "Invalid Tenant Account Owner");
249-
assert!(tenant_acc.is_writable, "Tenant Account is not writable");
248+
validate_program_account!(tenant_acc, program_id, writable = true, "Tenant");
250249

251250
let mut tenant = Tenant::try_from(tenant_acc)?;
252251
tenant.reference_count = tenant.reference_count.saturating_sub(1);

smartcontract/programs/doublezero-serviceability/src/processors/user/delete.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -221,10 +221,7 @@ pub fn process_delete_user(
221221
let owner_account = owner_account.unwrap();
222222

223223
// Validate additional accounts
224-
assert_eq!(
225-
device_account.owner, program_id,
226-
"Invalid Device Account Owner"
227-
);
224+
validate_program_account!(device_account, program_id, writable = false, "Device");
228225

229226
if user.device_pk != *device_account.key {
230227
return Err(ProgramError::InvalidAccountData);
@@ -250,8 +247,7 @@ pub fn process_delete_user(
250247
tenant_acc.key, &user.tenant_pk,
251248
"Tenant account doesn't match user's tenant"
252249
);
253-
assert_eq!(tenant_acc.owner, program_id, "Invalid Tenant Account Owner");
254-
assert!(tenant_acc.is_writable, "Tenant Account is not writable");
250+
validate_program_account!(tenant_acc, program_id, writable = true, "Tenant");
255251

256252
let mut tenant = Tenant::try_from(tenant_acc)?;
257253
tenant.reference_count = tenant.reference_count.saturating_sub(1);

smartcontract/programs/doublezero-serviceability/src/processors/user/set_bgp_status.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::{
22
error::DoubleZeroError,
3+
processors::validation::validate_program_account,
34
serializer::try_acc_write,
45
state::{
56
device::Device,
@@ -44,13 +45,9 @@ pub fn process_set_bgp_status_user(
4445
payer_account.is_signer,
4546
"Metrics publisher must be a signer"
4647
);
47-
assert!(user_account.is_writable, "User account must be writable");
4848

49-
assert_eq!(user_account.owner, program_id, "Invalid user account owner");
50-
assert_eq!(
51-
device_account.owner, program_id,
52-
"Invalid device account owner"
53-
);
49+
validate_program_account!(user_account, program_id, writable = true, "User");
50+
validate_program_account!(device_account, program_id, writable = false, "Device");
5451

5552
let device = Device::try_from(device_account)?;
5653

0 commit comments

Comments
 (0)