Skip to content
Merged
8 changes: 6 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,19 @@ All notable changes to this project will be documented in this file.

### Breaking

- Multicast group change: Regeneration of all multicast group allowlists required, as allowlists are now stored within each Access Pass instead of at the multicast group level.

### Changes

- CLI
- Added a wait in the `disconnect` command to ensure the account is fully closed before returning, preventing failures during rapid disconnect/reconnect sequences.
- Display multicast group memberships (publisher/subscriber) in AccessPass listings to improve visibility.
- Activator
- Reduce logging noise when processing snapshot events
- Wrap main select handler in loop to avoid shutdown on branch error
- Onchain programs
- Remove user-level allowlist management from CLI and admin interfaces; manage multicast group allowlists through AccessPass.
- Add Validate trait for core types (AccessPass, Contributor, Interface, etc.) and enforce runtime checks before account operations.
- Internet telemetry
- Add circuit label to metrics; create a new metric for missing circuit samples
- Create a new metric that tracks how long it takes collector tasks to run
Expand Down Expand Up @@ -93,7 +99,6 @@ All notable changes to this project will be documented in this file.
### Changes

- Onchain programs
- Add Validate trait for core types (AccessPass, Contributor, Interface, etc.) and enforce runtime checks before account operations.
- Expand DoubleZeroError with granular variants (invalid IPs, ASN, MTU, VLAN, etc.) and derive PartialEq for easier testing.
- Rename Config account type to GlobalConfig for clarity and consistency.
- Fix bug in user update that caused DZ IP to be 0.0.0.0
Expand Down Expand Up @@ -121,7 +126,6 @@ All notable changes to this project will be documented in this file.
- Contributor Operations
- Contributors must explicitly run device update to set a valid max_users and activate a Device.


## [v0.6.2](https://github.com/malbeclabs/doublezero/compare/client/v0.6.0...client/v0.6.2) – 2025-09-02

### Breaking
Expand Down
6 changes: 2 additions & 4 deletions activator/src/process/multicastgroup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,13 +156,11 @@ mod tests {
bump_seed,
multicast_ip: Ipv4Addr::UNSPECIFIED,
max_bandwidth: 10000,
pub_allowlist: vec![client.get_payer()],
sub_allowlist: vec![client.get_payer()],
publishers: vec![],
subscribers: vec![],
status: MulticastGroupStatus::Pending,
code: "test".to_string(),
tenant_pk: Pubkey::default(),
publisher_count: 0,
subscriber_count: 0,
};

let mgroup = multicastgroup.clone();
Expand Down
38 changes: 5 additions & 33 deletions client/doublezero/src/cli/user.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
use clap::{Args, Subcommand};

use doublezero_cli::{
allowlist::user::{
add::AddUserAllowlistCliCommand, list::ListUserAllowlistCliCommand,
remove::RemoveUserAllowlistCliCommand,
},
user::{
create::CreateUserCliCommand, create_subscribe::CreateSubscribeUserCliCommand,
delete::DeleteUserCliCommand, get::GetUserCliCommand, list::ListUserCliCommand,
request_ban::RequestBanUserCliCommand, subscribe::SubscribeUserCliCommand,
update::UpdateUserCliCommand,
},
use doublezero_cli::user::{
create::CreateUserCliCommand, create_subscribe::CreateSubscribeUserCliCommand,
delete::DeleteUserCliCommand, get::GetUserCliCommand, list::ListUserCliCommand,
request_ban::RequestBanUserCliCommand, subscribe::SubscribeUserCliCommand,
update::UpdateUserCliCommand,
};

#[derive(Args, Debug)]
Expand Down Expand Up @@ -42,29 +36,7 @@ pub enum UserCommands {
/// Delete a user
#[command(hide = true)]
Delete(DeleteUserCliCommand),
/// Manage user allowlist
#[command()]
Allowlist(UserAllowlistCliCommand),
/// Request a ban for a user
#[command(hide = true)]
RequestBan(RequestBanUserCliCommand),
}

#[derive(Args, Debug)]
pub struct UserAllowlistCliCommand {
#[command(subcommand)]
pub command: UserAllowlistCommands,
}

#[derive(Debug, Subcommand)]
pub enum UserAllowlistCommands {
/// List user allowlist
#[clap()]
List(ListUserAllowlistCliCommand),
/// Add a user to the allowlist
#[clap()]
Add(AddUserAllowlistCliCommand),
/// Remove a user from the allowlist
#[clap()]
Remove(RemoveUserAllowlistCliCommand),
}
14 changes: 5 additions & 9 deletions client/doublezero/src/command/connect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ impl ProvisioningCliCommand {
let (client_ip, client_ip_str) = look_for_ip(&self.client_ip, &spinner).await?;

if !check_accesspass(client, client_ip)? {
println!("❌ Unable to find a valid Access Pass for the IP: {client_ip_str}");
println!("❌ Unable to find a valid Access Pass for the IP: {client_ip_str}",);
return Err(eyre::eyre!(
"You need to have a valid Access Pass to connect. Please contact support."
));
Expand Down Expand Up @@ -774,10 +774,6 @@ mod tests {
.returning_st(move |_| Ok((Pubkey::new_unique(), global_cfg.clone())));

let payer = fixture.client.get_payer();
fixture
.client
.expect_list_user_allowlist()
.returning_st(move |_| Ok(vec![payer]));

let (accesspass_pk, _) = get_accesspass_pda(
&fixture.client.get_program_id(),
Expand All @@ -794,6 +790,8 @@ mod tests {
accesspass_type: AccessPassType::Prepaid,
connection_count: 0,
status: AccessPassStatus::Requested,
mgroup_pub_allowlist: vec![],
mgroup_sub_allowlist: vec![],
};
fixture
.client
Expand Down Expand Up @@ -909,10 +907,8 @@ mod tests {
max_bandwidth: 10_000_000_000,
status: MulticastGroupStatus::Activated,
code: code.to_string(),
pub_allowlist: vec![],
sub_allowlist: vec![],
publishers: vec![],
subscribers: vec![],
publisher_count: 0,
subscriber_count: 0,
};
mcast_groups.insert(pk, group.clone());
(pk, group)
Expand Down
7 changes: 1 addition & 6 deletions client/doublezero/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::cli::{
},
link::LinkCommands,
location::LocationCommands,
user::{UserAllowlistCommands, UserCommands},
user::UserCommands,
};
use doublezero_cli::{checkversion::check_version, doublezerocommand::CliCommandImpl};
use doublezero_sdk::{DZClient, ProgramVersion};
Expand Down Expand Up @@ -185,11 +185,6 @@ async fn main() -> eyre::Result<()> {
UserCommands::List(args) => args.execute(&client, &mut handle),
UserCommands::Get(args) => args.execute(&client, &mut handle),
UserCommands::Delete(args) => args.execute(&client, &mut handle),
UserCommands::Allowlist(command) => match command.command {
UserAllowlistCommands::List(args) => args.execute(&client, &mut handle),
UserAllowlistCommands::Add(args) => args.execute(&client, &mut handle),
UserAllowlistCommands::Remove(args) => args.execute(&client, &mut handle),
},
UserCommands::RequestBan(args) => args.execute(&client, &mut handle),
},
Command::Multicast(args) => match args.command {
Expand Down
16 changes: 0 additions & 16 deletions controlplane/controller/internal/controller/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -727,10 +727,6 @@ func TestStateCache(t *testing.T) {
{
PubKey: [32]uint8{1},
MulticastIp: [4]uint8{239, 0, 0, 1},
Subscribers: [][32]uint8{
{1},
{2},
},
},
},
Users: []serviceability.User{
Expand Down Expand Up @@ -871,10 +867,6 @@ func TestStateCache(t *testing.T) {
"4uQeVj5tqViQh7yWWGStvkEG1Zmhx6uasJtWCJziofM": {
PubKey: [32]uint8{1},
MulticastIp: [4]uint8{239, 0, 0, 1},
Subscribers: [][32]uint8{
{1},
{2},
},
},
},
Vpnv4BgpPeers: []BgpPeer{
Expand Down Expand Up @@ -1135,10 +1127,6 @@ func TestEndToEnd(t *testing.T) {
{
PubKey: [32]uint8{1},
MulticastIp: [4]uint8{239, 0, 0, 1},
Subscribers: [][32]uint8{
{1},
{2},
},
},
},
InterfacesAndPeers: true,
Expand Down Expand Up @@ -1249,10 +1237,6 @@ func TestEndToEnd(t *testing.T) {
{
PubKey: [32]uint8{1},
MulticastIp: [4]uint8{239, 0, 0, 1},
Subscribers: [][32]uint8{
{1},
{2},
},
},
},
InterfacesAndPeers: true,
Expand Down
38 changes: 5 additions & 33 deletions controlplane/doublezero-admin/src/cli/user.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
use clap::{Args, Subcommand};

use doublezero_cli::{
allowlist::user::{
add::AddUserAllowlistCliCommand, list::ListUserAllowlistCliCommand,
remove::RemoveUserAllowlistCliCommand,
},
user::{
create::CreateUserCliCommand, create_subscribe::CreateSubscribeUserCliCommand,
delete::DeleteUserCliCommand, get::GetUserCliCommand, list::ListUserCliCommand,
request_ban::RequestBanUserCliCommand, subscribe::SubscribeUserCliCommand,
update::UpdateUserCliCommand,
},
use doublezero_cli::user::{
create::CreateUserCliCommand, create_subscribe::CreateSubscribeUserCliCommand,
delete::DeleteUserCliCommand, get::GetUserCliCommand, list::ListUserCliCommand,
request_ban::RequestBanUserCliCommand, subscribe::SubscribeUserCliCommand,
update::UpdateUserCliCommand,
};

#[derive(Args, Debug)]
Expand Down Expand Up @@ -42,29 +36,7 @@ pub enum UserCommands {
/// Delete a user
#[command(hide = true)]
Delete(DeleteUserCliCommand),
/// Manage user allowlist
#[command()]
Allowlist(UserAllowlistCliCommand),
/// Request a ban for a user
#[command(hide = true)]
RequestBan(RequestBanUserCliCommand),
}

#[derive(Args, Debug)]
pub struct UserAllowlistCliCommand {
#[command(subcommand)]
pub command: UserAllowlistCommands,
}

#[derive(Debug, Subcommand)]
pub enum UserAllowlistCommands {
/// List user allowlist
#[clap()]
List(ListUserAllowlistCliCommand),
/// Add a user to the allowlist
#[clap()]
Add(AddUserAllowlistCliCommand),
/// Remove a user from the allowlist
#[clap()]
Remove(RemoveUserAllowlistCliCommand),
}
7 changes: 1 addition & 6 deletions controlplane/doublezero-admin/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::cli::{
},
link::LinkCommands,
location::LocationCommands,
user::{UserAllowlistCommands, UserCommands},
user::UserCommands,
};
use doublezero_cli::{checkversion::check_version, doublezerocommand::CliCommandImpl};
use doublezero_sdk::{DZClient, ProgramVersion};
Expand Down Expand Up @@ -155,11 +155,6 @@ async fn main() -> eyre::Result<()> {
UserCommands::List(args) => args.execute(&client, &mut handle),
UserCommands::Get(args) => args.execute(&client, &mut handle),
UserCommands::Delete(args) => args.execute(&client, &mut handle),
UserCommands::Allowlist(command) => match command.command {
UserAllowlistCommands::List(args) => args.execute(&client, &mut handle),
UserAllowlistCommands::Add(args) => args.execute(&client, &mut handle),
UserAllowlistCommands::Remove(args) => args.execute(&client, &mut handle),
},
UserCommands::RequestBan(args) => args.execute(&client, &mut handle),
},
Command::Multicast(args) => match args.command {
Expand Down
17 changes: 6 additions & 11 deletions e2e/device_maxusers_rollover_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
"github.com/stretchr/testify/require"
)


// Test that if the client's nearest device is full, the client will connect to the next nearest device instead
func TestE2E_DeviceMaxusersRollover(t *testing.T) {
t.Parallel()
Expand Down Expand Up @@ -110,21 +109,17 @@ func TestE2E_DeviceMaxusersRollover(t *testing.T) {
// Apply tc rules to the correct interface
for _, command := range [][]string{
{"bash", "-c", "tc qdisc add dev " + cyoaInterface + " root handle 1: prio bands 3"},
{"bash", "-c", "tc qdisc add dev " + cyoaInterface + " parent 1:1 handle 10: netem delay 0ms"},
{"bash", "-c", "tc qdisc add dev " + cyoaInterface + " parent 1:2 handle 20: netem delay 10ms"},
{"bash", "-c", "tc qdisc add dev " + cyoaInterface + " parent 1:3 handle 30: sfq"},
{"bash", "-c", "tc filter add dev " + cyoaInterface + " protocol ip parent 1:0 prio 1 u32 match ip dst " + device1.CYOANetworkIP + "/32 flowid 1:1"},
{"bash", "-c", "tc filter add dev " + cyoaInterface + " protocol ip parent 1:0 prio 2 u32 match ip dst " + device2.CYOANetworkIP + "/32 flowid 1:2"},
{"bash", "-c", "tc filter add dev " + cyoaInterface + " protocol ip parent 1:0 prio 3 u32 match ip dst 0.0.0.0/0 flowid 1:3"},
{"bash", "-c", "tc qdisc add dev " + cyoaInterface + " parent 1:1 handle 10: netem delay 0ms"},
{"bash", "-c", "tc qdisc add dev " + cyoaInterface + " parent 1:2 handle 20: netem delay 10ms"},
{"bash", "-c", "tc qdisc add dev " + cyoaInterface + " parent 1:3 handle 30: sfq"},
{"bash", "-c", "tc filter add dev " + cyoaInterface + " protocol ip parent 1:0 prio 1 u32 match ip dst " + device1.CYOANetworkIP + "/32 flowid 1:1"},
{"bash", "-c", "tc filter add dev " + cyoaInterface + " protocol ip parent 1:0 prio 2 u32 match ip dst " + device2.CYOANetworkIP + "/32 flowid 1:2"},
{"bash", "-c", "tc filter add dev " + cyoaInterface + " protocol ip parent 1:0 prio 3 u32 match ip dst 0.0.0.0/0 flowid 1:3"},
} {
_, err = client.Exec(t.Context(), command)
require.NoError(t, err)
}

// Add clients to user allowlist so they can open user connections.
log.Info("==> Adding clients to user allowlist")
_, err = dn.Manager.Exec(t.Context(), []string{"doublezero", "user", "allowlist", "add", "--pubkey", client.Pubkey})
require.NoError(t, err)
log.Info("--> Client added to user allowlist")

// Set access pass for the client.
Expand Down
8 changes: 0 additions & 8 deletions e2e/device_stress_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,14 +132,6 @@ func TestE2E_DeviceStress(t *testing.T) {
log.Debug(fmt.Sprintf("--> Created client %d", i+1),
"pubkey", client.Pubkey, "cyoaIP", client.CYOANetworkIP)

// Add to allowlist
log.Info(fmt.Sprintf("Adding client %d to allowlist", i+1))
_, err = dn.Manager.Exec(t.Context(), []string{
"doublezero", "user", "allowlist", "add",
"--pubkey", client.Pubkey,
})
require.NoError(t, err)

// Set access pass
cmd := fmt.Sprintf("doublezero access-pass set --accesspass-type prepaid --client-ip %s --user-payer %s --last-access-epoch 99999",
client.CYOANetworkIP, client.Pubkey)
Expand Down
Loading
Loading