Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[management] Skip account peers update if no changes affect peers #2310

Open
wants to merge 61 commits into
base: feature/optimize-network-map-updates
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
d676c41
Remove incrementing network serial and updating peers after group del…
bcmmbaga Jul 16, 2024
dedf13d
Update account peer if posture check is linked to policy
bcmmbaga Jul 16, 2024
b6cef2c
Remove account peers update on saving setup key
bcmmbaga Jul 16, 2024
1b28d1d
Refactor group link checking into re-usable functions
bcmmbaga Jul 18, 2024
1012c2f
Add HasPeers function to group
bcmmbaga Jul 18, 2024
181e864
Refactor group management
bcmmbaga Jul 18, 2024
36d4c21
Optimize group change effects on account peers
bcmmbaga Jul 18, 2024
3e76dea
Update account peers if ns group has peers
bcmmbaga Jul 18, 2024
a723c42
Refactor group changes
bcmmbaga Jul 19, 2024
1bbd8ae
Optimize account peers update in DNS settings
bcmmbaga Jul 19, 2024
713c034
Optimize update of account peers on jwt groups sync
bcmmbaga Jul 19, 2024
26f089e
Refactor peer account updates for efficiency
bcmmbaga Jul 20, 2024
f5ec234
Optimize peer update on user deletion and changes
bcmmbaga Jul 20, 2024
bb08adc
Remove condition check for network serial update
bcmmbaga Jul 20, 2024
936215b
Optimize account peers updates on route changes
bcmmbaga Jul 22, 2024
a19c2f6
Merge branch 'refs/heads/feature/optimize-network-map-updates' into f…
bcmmbaga Jul 22, 2024
b7fcd0d
Remove UpdatePeerSSHKey method
bcmmbaga Jul 23, 2024
c48f244
Remove unused isPolicyRuleGroupsEmpty
bcmmbaga Jul 26, 2024
8455455
Add tests for peer update behavior on posture check changes
bcmmbaga Jul 29, 2024
6554b26
Add tests for peer update behavior on policy changes
bcmmbaga Jul 30, 2024
7647701
Add tests for peer update behavior on group changes
bcmmbaga Jul 30, 2024
8d9ea40
Add tests for peer update behavior on dns settings changes
bcmmbaga Jul 30, 2024
cf211f6
Refactor
bcmmbaga Jul 30, 2024
d990d95
Add tests for peer update behavior on name server changes
bcmmbaga Jul 30, 2024
c76cd1d
Add tests for peer update behavior on user changes
bcmmbaga Jul 30, 2024
02c0a9b
Add tests for peer update behavior on route changes
bcmmbaga Jul 30, 2024
8bab9dc
fix tests
bcmmbaga Jul 30, 2024
eb9aadf
Add tests for peer update behavior on setup key changes
bcmmbaga Jul 30, 2024
f0d91bc
Add tests for peer update behavior on peers changes
bcmmbaga Jul 30, 2024
1548542
Merge branch 'feature/optimize-network-map-updates' into feature/vali…
bcmmbaga Aug 13, 2024
226dc95
fix merge
bcmmbaga Aug 13, 2024
7fa7141
Fix tests
bcmmbaga Aug 14, 2024
c918bab
Merge branch 'main' into feature/validate-group-association
bcmmbaga Aug 14, 2024
fb627a3
go mod tidy
bcmmbaga Aug 14, 2024
ff19b23
Merge branch 'feature/optimize-network-map-updates' into feature/vali…
bcmmbaga Aug 14, 2024
441136e
Add NameServer and Route comparators
bcmmbaga Aug 15, 2024
151969b
Update network map diff logic with custom comparators
bcmmbaga Aug 15, 2024
ac06346
Add tests
bcmmbaga Aug 15, 2024
ca8565d
Refactor duplicate diff handling logic
bcmmbaga Aug 15, 2024
8826196
fix linter
bcmmbaga Aug 15, 2024
f29f8c0
fix tests
bcmmbaga Aug 16, 2024
c665070
Refactor policy group handling and update logic.
bcmmbaga Sep 5, 2024
75ab355
Update route check by checking if group has peers
bcmmbaga Sep 5, 2024
7523a9e
Refactor posture check policy linking logic
bcmmbaga Sep 5, 2024
5dbdeff
Simplify peer update condition in DNS management
bcmmbaga Sep 5, 2024
4e2cf9c
fix tests
bcmmbaga Sep 6, 2024
716009b
Merge branch 'feature/optimize-network-map-updates' into feature/vali…
bcmmbaga Oct 4, 2024
63c510e
fix merge
bcmmbaga Oct 6, 2024
fc7157f
add policy tests
bcmmbaga Oct 8, 2024
41acacf
add posture checks tests
bcmmbaga Oct 8, 2024
1ed44b8
fix user and setup key tests
bcmmbaga Oct 8, 2024
c74a13e
fix account and route tests
bcmmbaga Oct 8, 2024
70f1c39
fix typo
bcmmbaga Oct 8, 2024
5cc07ba
fix nameserver tests
bcmmbaga Oct 8, 2024
d4edde9
fix routes tests
bcmmbaga Oct 9, 2024
2a75164
fix group tests
bcmmbaga Oct 9, 2024
271bed5
upgrade diff package
bcmmbaga Oct 9, 2024
9ee08fc
fix nameserver tests
bcmmbaga Oct 9, 2024
ce7de03
use generic differ for netip.Addr and netip.Prefix
bcmmbaga Oct 9, 2024
6d985c5
go mod tidy
bcmmbaga Oct 9, 2024
bdf114c
add peer tests
bcmmbaga Oct 9, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ require (
github.com/pion/transport/v3 v3.0.1
github.com/pion/turn/v3 v3.0.1
github.com/prometheus/client_golang v1.19.1
github.com/r3labs/diff v1.1.0
github.com/r3labs/diff/v3 v3.0.1
github.com/rs/xid v1.3.0
github.com/shirou/gopsutil/v3 v3.24.4
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966
Expand Down Expand Up @@ -211,6 +211,8 @@ require (
github.com/tklauser/go-sysconf v0.3.14 // indirect
github.com/tklauser/numcpus v0.8.0 // indirect
github.com/vishvananda/netns v0.0.4 // indirect
github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
github.com/yuin/goldmark v1.7.1 // indirect
github.com/zeebo/blake3 v0.2.3 // indirect
go.opencensus.io v0.24.0 // indirect
Expand Down
8 changes: 6 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -605,8 +605,8 @@ github.com/prometheus/common v0.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+a
github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U=
github.com/prometheus/procfs v0.15.0 h1:A82kmvXJq2jTu5YUhSGNlYoxh85zLnKgPz4bMZgI5Ek=
github.com/prometheus/procfs v0.15.0/go.mod h1:Y0RJ/Y5g5wJpkTisOtqwDSo4HwhGmLB4VQSw2sQJLHk=
github.com/r3labs/diff v1.1.0 h1:V53xhrbTHrWFWq3gI4b94AjgEJOerO1+1l0xyHOBi8M=
github.com/r3labs/diff v1.1.0/go.mod h1:7WjXasNzi0vJetRcB/RqNl5dlIsmXcTTLmF5IoH6Xig=
github.com/r3labs/diff/v3 v3.0.1 h1:CBKqf3XmNRHXKmdU7mZP1w7TV0pDyVCis1AUHtA4Xtg=
github.com/r3labs/diff/v3 v3.0.1/go.mod h1:f1S9bourRbiM66NskseyUdo0fTmEE0qKrikYJX63dgo=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
Expand Down Expand Up @@ -699,6 +699,10 @@ github.com/vishvananda/netlink v1.2.1-beta.2/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhg
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8=
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU=
github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc=
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
Expand Down
17 changes: 9 additions & 8 deletions management/server/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ type AccountManager interface {
DeletePAT(ctx context.Context, accountID string, initiatorUserID string, targetUserID string, tokenID string) error
GetPAT(ctx context.Context, accountID string, initiatorUserID string, targetUserID string, tokenID string) (*PersonalAccessToken, error)
GetAllPATs(ctx context.Context, accountID string, initiatorUserID string, targetUserID string) ([]*PersonalAccessToken, error)
UpdatePeerSSHKey(ctx context.Context, peerID string, sshKey string) error
GetUsersFromAccount(ctx context.Context, accountID, userID string) ([]*UserInfo, error)
GetGroup(ctx context.Context, accountId, groupID, userID string) (*nbgroup.Group, error)
GetAllGroups(ctx context.Context, accountID, userID string) ([]*nbgroup.Group, error)
Expand Down Expand Up @@ -478,12 +477,12 @@ func (a *Account) GetPeerNetworkMap(
}

nm := &NetworkMap{
Peers: peersToConnect,
Network: a.Network.Copy(),
Routes: routesUpdate,
DNSConfig: dnsUpdate,
OfflinePeers: expiredPeers,
FirewallRules: firewallRules,
Peers: peersToConnect,
Network: a.Network.Copy(),
Routes: routesUpdate,
DNSConfig: dnsUpdate,
OfflinePeers: expiredPeers,
FirewallRules: firewallRules,
RoutesFirewallRules: routesFirewallRules,
}

Expand Down Expand Up @@ -1860,7 +1859,9 @@ func (am *DefaultAccountManager) syncJWTGroups(ctx context.Context, accountID st
// Propagate changes to peers if group propagation is enabled
if settings.GroupsPropagationEnabled {
log.WithContext(ctx).Tracef("user %s: JWT group membership changed, updating account peers", claims.UserId)
am.updateAccountPeers(ctx, account)
if areGroupChangesAffectPeers(account, addNewGroups) || areGroupChangesAffectPeers(account, removeOldGroups) {
am.updateAccountPeers(ctx, account)
}
}

for _, g := range addNewGroups {
Expand Down
118 changes: 102 additions & 16 deletions management/server/account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1133,14 +1133,34 @@ func TestAccountManager_AddPeerWithUserID(t *testing.T) {
func TestAccountManager_NetworkUpdates_SaveGroup(t *testing.T) {
manager, account, peer1, peer2, peer3 := setupNetworkMapTest(t)

updMsg := manager.peersUpdateManager.CreateChannel(context.Background(), peer1.ID)
defer manager.peersUpdateManager.CloseChannel(context.Background(), peer1.ID)

group := group.Group{
ID: "group-id",
ID: "groupA",
Name: "GroupA",
Peers: []string{peer1.ID, peer2.ID, peer3.ID},
Peers: []string{},
}
if err := manager.SaveGroup(context.Background(), account.Id, userID, &group); err != nil {
t.Errorf("save group: %v", err)
return
}

policy := Policy{
ID: "policy",
Enabled: true,
Rules: []*PolicyRule{
{
Enabled: true,
Sources: []string{"groupA"},
Destinations: []string{"groupA"},
Bidirectional: true,
Action: PolicyTrafficActionAccept,
},
},
}
err := manager.SavePolicy(context.Background(), account.Id, userID, &policy, false)
require.NoError(t, err)

updMsg := manager.peersUpdateManager.CreateChannel(context.Background(), peer1.ID)
defer manager.peersUpdateManager.CloseChannel(context.Background(), peer1.ID)

wg := sync.WaitGroup{}
wg.Add(1)
Expand All @@ -1154,6 +1174,7 @@ func TestAccountManager_NetworkUpdates_SaveGroup(t *testing.T) {
}
}()

group.Peers = []string{peer1.ID, peer2.ID, peer3.ID}
if err := manager.SaveGroup(context.Background(), account.Id, userID, &group); err != nil {
t.Errorf("save group: %v", err)
return
Expand Down Expand Up @@ -1189,7 +1210,17 @@ func TestAccountManager_NetworkUpdates_DeletePolicy(t *testing.T) {
}

func TestAccountManager_NetworkUpdates_SavePolicy(t *testing.T) {
manager, account, peer1, _, _ := setupNetworkMapTest(t)
manager, account, peer1, peer2, _ := setupNetworkMapTest(t)

group := group.Group{
ID: "groupA",
Name: "GroupA",
Peers: []string{peer1.ID, peer2.ID},
}
if err := manager.SaveGroup(context.Background(), account.Id, userID, &group); err != nil {
t.Errorf("save group: %v", err)
return
}

updMsg := manager.peersUpdateManager.CreateChannel(context.Background(), peer1.ID)
defer manager.peersUpdateManager.CloseChannel(context.Background(), peer1.ID)
Expand All @@ -1199,8 +1230,8 @@ func TestAccountManager_NetworkUpdates_SavePolicy(t *testing.T) {
Rules: []*PolicyRule{
{
Enabled: true,
Sources: []string{"group-id"},
Destinations: []string{"group-id"},
Sources: []string{"groupA"},
Destinations: []string{"groupA"},
Bidirectional: true,
Action: PolicyTrafficActionAccept,
},
Expand All @@ -1219,17 +1250,45 @@ func TestAccountManager_NetworkUpdates_SavePolicy(t *testing.T) {
}
}()

if err := manager.SavePolicy(context.Background(), account.Id, userID, &policy, false); err != nil {
t.Errorf("delete default rule: %v", err)
return
}
if err := manager.SavePolicy(context.Background(), account.Id, userID, &policy, false); err != nil {
t.Errorf("delete default rule: %v", err)
return
}

wg.Wait()
}

func TestAccountManager_NetworkUpdates_DeletePeer(t *testing.T) {
manager, account, peer1, _, peer3 := setupNetworkMapTest(t)

group := group.Group{
ID: "groupA",
Name: "GroupA",
Peers: []string{peer1.ID, peer3.ID},
}
if err := manager.SaveGroup(context.Background(), account.Id, userID, &group); err != nil {
t.Errorf("save group: %v", err)
return
}

policy := Policy{
Enabled: true,
Rules: []*PolicyRule{
{
Enabled: true,
Sources: []string{"groupA"},
Destinations: []string{"groupA"},
Bidirectional: true,
Action: PolicyTrafficActionAccept,
},
},
}

if err := manager.SavePolicy(context.Background(), account.Id, userID, &policy, false); err != nil {
t.Errorf("save policy: %v", err)
return
}

updMsg := manager.peersUpdateManager.CreateChannel(context.Background(), peer1.ID)
defer manager.peersUpdateManager.CloseChannel(context.Background(), peer1.ID)

Expand Down Expand Up @@ -1260,7 +1319,7 @@ func TestAccountManager_NetworkUpdates_DeleteGroup(t *testing.T) {
defer manager.peersUpdateManager.CloseChannel(context.Background(), peer1.ID)

group := group.Group{
ID: "group-id",
ID: "groupA",
Name: "GroupA",
Peers: []string{peer1.ID, peer2.ID, peer3.ID},
}
Expand All @@ -1270,8 +1329,8 @@ func TestAccountManager_NetworkUpdates_DeleteGroup(t *testing.T) {
Rules: []*PolicyRule{
{
Enabled: true,
Sources: []string{"group-id"},
Destinations: []string{"group-id"},
Sources: []string{"groupA"},
Destinations: []string{"groupA"},
Bidirectional: true,
Action: PolicyTrafficActionAccept,
},
Expand All @@ -1283,7 +1342,7 @@ func TestAccountManager_NetworkUpdates_DeleteGroup(t *testing.T) {
return
}

if err := manager.SavePolicy(context.Background(), account.Id, userID, &policy); err != nil {
if err := manager.SavePolicy(context.Background(), account.Id, userID, &policy, false); err != nil {
t.Errorf("save policy: %v", err)
return
}
Expand Down Expand Up @@ -2420,6 +2479,10 @@ func setupNetworkMapTest(t *testing.T) (*DefaultAccountManager, *Account, *nbpee
peer, _, _, err := manager.AddPeer(context.Background(), setupKey.Key, "", &nbpeer.Peer{
Key: expectedPeerKey,
Meta: nbpeer.PeerSystemMeta{Hostname: expectedPeerKey},
Status: &nbpeer.PeerStatus{
Connected: true,
LastSeen: time.Now().UTC(),
},
})
if err != nil {
t.Fatalf("expecting peer to be added, got failure %v", err)
Expand All @@ -2434,3 +2497,26 @@ func setupNetworkMapTest(t *testing.T) (*DefaultAccountManager, *Account, *nbpee

return manager, account, peer1, peer2, peer3
}

func peerShouldNotReceiveUpdate(t *testing.T, updateMessage <-chan *UpdateMessage) {
t.Helper()
select {
case msg := <-updateMessage:
t.Errorf("Unexpected message received: %+v", msg)
case <-time.After(500 * time.Millisecond):
return
}
}

func peerShouldReceiveUpdate(t *testing.T, updateMessage <-chan *UpdateMessage) {
t.Helper()

select {
case msg := <-updateMessage:
if msg == nil {
t.Errorf("Received nil update message, expected valid message")
}
case <-time.After(500 * time.Millisecond):
t.Error("Timed out waiting for update message")
}
}
82 changes: 82 additions & 0 deletions management/server/differs/netip.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package differs

import (
"fmt"
"net/netip"
"reflect"

"github.com/r3labs/diff/v3"
)

// NetIPAddr is a custom differ for netip.Addr
type NetIPAddr struct {
DiffFunc func(path []string, a, b reflect.Value, p interface{}) error
}

func (differ NetIPAddr) Match(a, b reflect.Value) bool {
return diff.AreType(a, b, reflect.TypeOf(netip.Addr{}))
}

func (differ NetIPAddr) Diff(_ diff.DiffType, _ diff.DiffFunc, cl *diff.Changelog, path []string, a, b reflect.Value, _ interface{}) error {
if a.Kind() == reflect.Invalid {
cl.Add(diff.CREATE, path, nil, b.Interface())
return nil
}

if b.Kind() == reflect.Invalid {
cl.Add(diff.DELETE, path, a.Interface(), nil)
return nil
}

fromAddr, ok1 := a.Interface().(netip.Addr)
toAddr, ok2 := b.Interface().(netip.Addr)
if !ok1 || !ok2 {
return fmt.Errorf("invalid type for netip.Addr")
}

if fromAddr.String() != toAddr.String() {
cl.Add(diff.UPDATE, path, fromAddr.String(), toAddr.String())
}

return nil
}

func (differ NetIPAddr) InsertParentDiffer(dfunc func(path []string, a, b reflect.Value, p interface{}) error) {
differ.DiffFunc = dfunc //nolint
}

// NetIPPrefix is a custom differ for netip.Prefix
type NetIPPrefix struct {
DiffFunc func(path []string, a, b reflect.Value, p interface{}) error
}

func (differ NetIPPrefix) Match(a, b reflect.Value) bool {
return diff.AreType(a, b, reflect.TypeOf(netip.Prefix{}))
}

func (differ NetIPPrefix) Diff(_ diff.DiffType, _ diff.DiffFunc, cl *diff.Changelog, path []string, a, b reflect.Value, _ interface{}) error {
if a.Kind() == reflect.Invalid {
cl.Add(diff.CREATE, path, nil, b.Interface())
return nil
}
if b.Kind() == reflect.Invalid {
cl.Add(diff.DELETE, path, a.Interface(), nil)
return nil
}

fromPrefix, ok1 := a.Interface().(netip.Prefix)
toPrefix, ok2 := b.Interface().(netip.Prefix)
if !ok1 || !ok2 {
return fmt.Errorf("invalid type for netip.Addr")
}

if fromPrefix.String() != toPrefix.String() {
cl.Add(diff.UPDATE, path, fromPrefix.String(), toPrefix.String())
}

return nil
}

func (differ NetIPPrefix) InsertParentDiffer(dfunc func(path []string, a, b reflect.Value, p interface{}) error) {
differ.DiffFunc = dfunc //nolint
}
9 changes: 6 additions & 3 deletions management/server/dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,26 +125,29 @@ func (am *DefaultAccountManager) SaveDNSSettings(ctx context.Context, accountID
oldSettings := account.DNSSettings.Copy()
account.DNSSettings = dnsSettingsToSave.Copy()

addedGroups := difference(dnsSettingsToSave.DisabledManagementGroups, oldSettings.DisabledManagementGroups)
removedGroups := difference(oldSettings.DisabledManagementGroups, dnsSettingsToSave.DisabledManagementGroups)

account.Network.IncSerial()
if err = am.Store.SaveAccount(ctx, account); err != nil {
return err
}

addedGroups := difference(dnsSettingsToSave.DisabledManagementGroups, oldSettings.DisabledManagementGroups)
for _, id := range addedGroups {
group := account.GetGroup(id)
meta := map[string]any{"group": group.Name, "group_id": group.ID}
am.StoreEvent(ctx, userID, accountID, accountID, activity.GroupAddedToDisabledManagementGroups, meta)
}

removedGroups := difference(oldSettings.DisabledManagementGroups, dnsSettingsToSave.DisabledManagementGroups)
for _, id := range removedGroups {
group := account.GetGroup(id)
meta := map[string]any{"group": group.Name, "group_id": group.ID}
am.StoreEvent(ctx, userID, accountID, accountID, activity.GroupRemovedFromDisabledManagementGroups, meta)
}

am.updateAccountPeers(ctx, account)
if anyGroupHasPeers(account, addedGroups) || anyGroupHasPeers(account, removedGroups) {
am.updateAccountPeers(ctx, account)
}

return nil
}
Expand Down
Loading
Loading