Skip to content

Commit acd9e65

Browse files
committed
cli: use dz ip to find user during status lookup
1 parent 4aed5b0 commit acd9e65

File tree

2 files changed

+143
-1
lines changed

2 files changed

+143
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ All notable changes to this project will be documented in this file.
1212
- IP address lookup responses that do not contain a valid IPv4 address (such as upstream timeout messages) are now treated as retryable errors instead of being parsed as IPs.
1313
- `doublezero resource` commands added for managing ResourceExtension accounts.
1414
- Added health_oracle to the smart contract global configuration to manage and authorize health-related operations.
15+
- Use DZ IP for user lookup during status command instead of client IP
1516
- Onchain programs
1617
- Allow contributor owner to update ops manager key
1718
- Add new arguments on create interface cli command

client/doublezero/src/command/status.rs

Lines changed: 142 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ impl StatusCliCommand {
6363
let mut metro = None;
6464
let user = users
6565
.iter()
66-
.find(|(_, u)| Some(u.client_ip.to_string()) == response.tunnel_src)
66+
.find(|(_, u)| Some(u.dz_ip.to_string()) == response.doublezero_ip)
6767
.map(|(_, u)| u);
6868
if let Some(user) = user {
6969
current_device = Some(&user.device_pk);
@@ -483,4 +483,145 @@ mod tests {
483483
assert_eq!(result[0].metro, "N/A".to_string());
484484
assert_eq!(result[0].network, "testnet".to_string());
485485
}
486+
487+
#[tokio::test]
488+
async fn test_status_command_matches_dz_ip_not_client_ip() {
489+
let mut mock_command = MockCliCommand::new();
490+
let mut mock_controller = MockServiceController::new();
491+
492+
let mut devices = std::collections::HashMap::<Pubkey, Device>::new();
493+
let mut users = std::collections::HashMap::<Pubkey, User>::new();
494+
let mut exchanges = std::collections::HashMap::<Pubkey, Exchange>::new();
495+
let status_responses = vec![StatusResponse {
496+
doublezero_status: DoubleZeroStatus {
497+
session_status: "up".to_string(),
498+
last_session_update: Some(1625247600),
499+
},
500+
tunnel_name: Some("tunnel_name".to_string()),
501+
tunnel_src: Some("20.20.20.20".to_string()),
502+
tunnel_dst: Some("42.42.42.42".to_string()),
503+
doublezero_ip: Some("1.2.3.4".to_string()),
504+
user_type: Some("IBRL".to_string()),
505+
}];
506+
507+
let exchange_pk = Pubkey::new_unique();
508+
exchanges.insert(
509+
exchange_pk,
510+
Exchange {
511+
account_type: AccountType::Exchange,
512+
owner: Pubkey::default(),
513+
index: 0,
514+
bump_seed: 0,
515+
lat: 0.0,
516+
lng: 0.0,
517+
bgp_community: 0,
518+
unused: 0,
519+
status: ExchangeStatus::Activated,
520+
code: "met".to_string(),
521+
name: "metro".to_string(),
522+
reference_count: 0,
523+
device1_pk: Pubkey::default(),
524+
device2_pk: Pubkey::default(),
525+
},
526+
);
527+
528+
let device1_pk = Pubkey::new_unique();
529+
devices.insert(
530+
device1_pk,
531+
Device {
532+
account_type: AccountType::Device,
533+
owner: Pubkey::default(),
534+
index: 0,
535+
bump_seed: 0,
536+
location_pk: Pubkey::default(),
537+
exchange_pk,
538+
device_type: DeviceType::Hybrid,
539+
public_ip: "5.6.7.8".parse().unwrap(),
540+
status: DeviceStatus::Activated,
541+
code: "device1".to_string(),
542+
dz_prefixes: NetworkV4List::default(),
543+
metrics_publisher_pk: Pubkey::default(),
544+
contributor_pk: Pubkey::default(),
545+
mgmt_vrf: "default".to_string(),
546+
interfaces: vec![],
547+
reference_count: 0,
548+
users_count: 64,
549+
max_users: 128,
550+
},
551+
);
552+
553+
let user_pk = Pubkey::new_unique();
554+
users.insert(
555+
user_pk,
556+
User {
557+
account_type: AccountType::User,
558+
owner: Pubkey::default(),
559+
index: 0,
560+
bump_seed: 0,
561+
user_type: UserType::IBRL,
562+
tenant_pk: Pubkey::default(),
563+
device_pk: device1_pk,
564+
cyoa_type: UserCYOA::GREOverDIA,
565+
client_ip: "10.10.10.10".parse().unwrap(),
566+
dz_ip: "1.2.3.4".parse().unwrap(),
567+
tunnel_id: 501,
568+
tunnel_net: NetworkV4::default(),
569+
status: UserStatus::Activated,
570+
publishers: vec![],
571+
subscribers: vec![],
572+
validator_pubkey: Pubkey::default(),
573+
},
574+
);
575+
576+
let latencies = vec![LatencyRecord {
577+
device_pk: device1_pk.to_string(),
578+
device_code: "device1".to_string(),
579+
device_ip: "5.6.7.8".to_string(),
580+
min_latency_ns: 5000000,
581+
max_latency_ns: 5000000,
582+
avg_latency_ns: 5000000,
583+
reachable: true,
584+
}];
585+
586+
mock_controller
587+
.expect_status()
588+
.returning(move || Ok(status_responses.clone()));
589+
mock_controller
590+
.expect_latency()
591+
.returning(move || Ok(latencies.clone()));
592+
mock_command
593+
.expect_get_environment()
594+
.return_const(doublezero_config::Environment::Testnet);
595+
mock_command
596+
.expect_list_device()
597+
.with(eq(ListDeviceCommand))
598+
.returning({
599+
let devices = devices.clone();
600+
move |_| Ok(devices.clone())
601+
});
602+
mock_command
603+
.expect_list_user()
604+
.with(eq(ListUserCommand))
605+
.returning({
606+
let users = users.clone();
607+
move |_| Ok(users.clone())
608+
});
609+
mock_command
610+
.expect_list_exchange()
611+
.with(eq(ListExchangeCommand))
612+
.returning({
613+
let exchanges = exchanges.clone();
614+
move |_| Ok(exchanges.clone())
615+
});
616+
617+
let result = StatusCliCommand { json: true }
618+
.command_impl(&mock_command, &mock_controller)
619+
.await;
620+
621+
assert!(result.is_ok());
622+
let result = result.unwrap();
623+
assert_eq!(result.len(), 1);
624+
assert_eq!(result[0].current_device, "device1".to_string());
625+
assert_eq!(result[0].metro, "metro".to_string());
626+
}
486627
}

0 commit comments

Comments
 (0)