Skip to content

Commit 02f7989

Browse files
committed
add location support to device update functionality
update device location instruction for reference counter management fix(tests): handle transaction processing result in try_execute_transaction
1 parent 6368c13 commit 02f7989

File tree

12 files changed

+550
-6
lines changed

12 files changed

+550
-6
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file.
1111
- Onchain programs
1212
- serviceability: add auto-assignment and validation for exchange.bgp_community
1313
- Update serviceability and telemetry program instruction args to use the `BorshDeserializeIncremental` derive macro incremental, backward-compatible, deserialization of structs.
14+
- Add the ability to update a Device’s location, managing the reference counters accordingly.
1415
- CLI
1516
- Removed `--bgp-community` option from `doublezero exchange create` since these values are now assigned automatically
1617
- Add `--next-bgp-community` option to `doublezero global-config set` so authorized users can control which bgp_community will be assigned next

smartcontract/cli/src/device/update.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ pub struct UpdateDeviceCliCommand {
3535
/// Contributor Pubkey (optional)
3636
#[arg(long, value_parser = validate_pubkey)]
3737
pub contributor: Option<String>,
38+
/// Location Pubkey (optional)
39+
#[arg(long, value_parser = validate_pubkey)]
40+
pub location: Option<String>,
3841
/// Management VRF name (optional)
3942
#[arg(long)]
4043
pub mgmt_vrf: Option<String>,
@@ -113,6 +116,10 @@ impl UpdateDeviceCliCommand {
113116
dz_prefixes: self.dz_prefixes,
114117
metrics_publisher,
115118
contributor_pk: contributor,
119+
location_pk: match &self.location {
120+
Some(location) => Some(Pubkey::from_str(location)?),
121+
None => None,
122+
},
116123
mgmt_vrf: self.mgmt_vrf,
117124
interfaces: None,
118125
max_users: self.max_users,
@@ -258,6 +265,9 @@ mod tests {
258265
contributor_pk: Some(Pubkey::from_str_const(
259266
"HQ2UUt18uJqKaQFJhgV9zaTdQxUZjNrsKFgoEDquBkcx",
260267
)),
268+
location_pk: Some(Pubkey::from_str_const(
269+
"HQ2UUt18uJqKaQFJhgV9zaTdQxUZjNrsKFgoEDquBkcx",
270+
)),
261271
mgmt_vrf: Some("default".to_string()),
262272
interfaces: None,
263273
max_users: Some(1025),
@@ -275,6 +285,7 @@ mod tests {
275285
dz_prefixes: Some("1.2.3.4/32".parse().unwrap()),
276286
metrics_publisher: Some("HQ2UUt18uJqKaQFJhgV9zaTdQxUZjNrsKFgoEDquBkcx".to_string()),
277287
contributor: Some("HQ2UUt18uJqKaQFJhgV9zaTdQxUZjNrsKFgoEDquBkcx".to_string()),
288+
location: Some("HQ2UUt18uJqKaQFJhgV9zaTdQxUZjNrsKFgoEDquBkcx".to_string()),
278289
mgmt_vrf: Some("default".to_string()),
279290
max_users: Some(1025),
280291
users_count: Some(0),
@@ -364,6 +375,7 @@ mod tests {
364375
public_ip: None,
365376
dz_prefixes: None,
366377
metrics_publisher: None,
378+
location: None,
367379
contributor: None,
368380
mgmt_vrf: None,
369381
max_users: Some(255),
@@ -453,6 +465,7 @@ mod tests {
453465
public_ip: Some([10, 20, 30, 40].into()),
454466
dz_prefixes: None,
455467
metrics_publisher: None,
468+
location: None,
456469
contributor: None,
457470
mgmt_vrf: None,
458471
max_users: None,

smartcontract/programs/doublezero-serviceability/src/error.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ pub enum DoubleZeroError {
115115
UserAccountNotFound, // variant 54
116116
#[error("Invalid BGP Community")]
117117
InvalidBgpCommunity, // variant 55
118+
#[error("Invalid Actual Location")]
119+
InvalidActualLocation, // variant 56
118120
}
119121

120122
impl From<DoubleZeroError> for ProgramError {
@@ -176,6 +178,7 @@ impl From<DoubleZeroError> for ProgramError {
176178
DoubleZeroError::AccessPassNotFound => ProgramError::Custom(53),
177179
DoubleZeroError::UserAccountNotFound => ProgramError::Custom(54),
178180
DoubleZeroError::InvalidBgpCommunity => ProgramError::Custom(55),
181+
DoubleZeroError::InvalidActualLocation => ProgramError::Custom(56),
179182
}
180183
}
181184
}
@@ -238,6 +241,7 @@ impl From<u32> for DoubleZeroError {
238241
53 => DoubleZeroError::AccessPassNotFound,
239242
54 => DoubleZeroError::UserAccountNotFound,
240243
55 => DoubleZeroError::InvalidBgpCommunity,
244+
56 => DoubleZeroError::InvalidActualLocation,
241245
_ => DoubleZeroError::Custom(e),
242246
}
243247
}
@@ -316,6 +320,11 @@ mod tests {
316320
InvalidVlanId,
317321
InvalidMaxBandwidth,
318322
InvalidMulticastIp,
323+
InvalidAccountOwner,
324+
AccessPassNotFound,
325+
UserAccountNotFound,
326+
InvalidBgpCommunity,
327+
InvalidActualLocation,
319328
];
320329
for err in variants {
321330
let pe: ProgramError = err.clone().into();

smartcontract/programs/doublezero-serviceability/src/processors/device/update.rs

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,16 @@ use crate::{
22
error::DoubleZeroError,
33
globalstate::globalstate_get,
44
helper::*,
5-
state::{accounttype::AccountType, contributor::Contributor, device::*},
5+
state::{accounttype::AccountType, contributor::Contributor, device::*, location::Location},
66
};
77
use borsh::BorshSerialize;
88
use borsh_incremental::BorshDeserializeIncremental;
99
use core::fmt;
1010
use doublezero_program_common::{types::NetworkV4List, validate_account_code};
11-
#[cfg(test)]
12-
use solana_program::msg;
1311
use solana_program::{
1412
account_info::{next_account_info, AccountInfo},
1513
entrypoint::ProgramResult,
14+
msg,
1615
pubkey::Pubkey,
1716
};
1817

@@ -71,6 +70,9 @@ pub fn process_update_device(
7170

7271
let device_account = next_account_info(accounts_iter)?;
7372
let contributor_account = next_account_info(accounts_iter)?;
73+
// Update location accounts (old and new)
74+
let location_old_account = next_account_info(accounts_iter)?;
75+
let location_new_account = next_account_info(accounts_iter)?;
7476
let globalstate_account = next_account_info(accounts_iter)?;
7577
let payer_account = next_account_info(accounts_iter)?;
7678
let system_program = next_account_info(accounts_iter)?;
@@ -144,6 +146,37 @@ pub fn process_update_device(
144146
if let Some(max_users) = value.max_users {
145147
device.max_users = max_users;
146148
}
149+
if location_old_account.key != location_new_account.key {
150+
let mut location_old = Location::try_from(location_old_account)?;
151+
let mut location_new = Location::try_from(location_new_account)?;
152+
if device.location_pk != *location_old_account.key {
153+
msg!(
154+
"Invalid location account. Device location_pk: {}, location_old_account: {}",
155+
device.location_pk,
156+
location_old_account.key
157+
);
158+
return Err(DoubleZeroError::InvalidActualLocation.into());
159+
}
160+
161+
location_old.reference_count = location_old.reference_count.saturating_sub(1);
162+
location_new.reference_count = location_new.reference_count.saturating_add(1);
163+
164+
// Set new location pk in device
165+
device.location_pk = *location_new_account.key;
166+
167+
account_write(
168+
location_old_account,
169+
&location_old,
170+
payer_account,
171+
system_program,
172+
)?;
173+
account_write(
174+
location_new_account,
175+
&location_new,
176+
payer_account,
177+
system_program,
178+
)?;
179+
}
147180

148181
account_write(device_account, &device, payer_account, system_program)?;
149182

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,8 @@ async fn test_accesspass_allow_multiple_ip() {
223223
vec![
224224
AccountMeta::new(device_pubkey, false),
225225
AccountMeta::new(contributor_pubkey, false),
226+
AccountMeta::new(location_pubkey, false),
227+
AccountMeta::new(location_pubkey, false),
226228
AccountMeta::new(globalstate_pubkey, false),
227229
],
228230
&payer,

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,8 @@ async fn test_device() {
215215
vec![
216216
AccountMeta::new(device_pubkey, false),
217217
AccountMeta::new(contributor_pubkey, false),
218+
AccountMeta::new(location_pubkey, false),
219+
AccountMeta::new(location_pubkey, false),
218220
AccountMeta::new(globalstate_pubkey, false),
219221
],
220222
&payer,
@@ -347,6 +349,8 @@ async fn test_device() {
347349
vec![
348350
AccountMeta::new(device_pubkey, false),
349351
AccountMeta::new(contributor_pubkey, false),
352+
AccountMeta::new(location_pubkey, false),
353+
AccountMeta::new(location_pubkey, false),
350354
AccountMeta::new(globalstate_pubkey, false),
351355
],
352356
&payer,
@@ -499,6 +503,8 @@ async fn test_device_update_metrics_publisher_by_foundation_allowlist_account()
499503
vec![
500504
AccountMeta::new(device_pubkey, false),
501505
AccountMeta::new(contributor_pubkey, false),
506+
AccountMeta::new(location_pubkey, false),
507+
AccountMeta::new(location_pubkey, false),
502508
AccountMeta::new(globalstate_pubkey, false),
503509
],
504510
&payer,
@@ -532,6 +538,8 @@ async fn test_device_update_metrics_publisher_by_foundation_allowlist_account()
532538
vec![
533539
AccountMeta::new(device_pubkey, false),
534540
AccountMeta::new(contributor_pubkey, false),
541+
AccountMeta::new(location_pubkey, false),
542+
AccountMeta::new(location_pubkey, false),
535543
AccountMeta::new(globalstate_pubkey, false),
536544
],
537545
&payer,

0 commit comments

Comments
 (0)