From 602041d1c224f278e7fedd5cd5effdbabd8af482 Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Mon, 28 Aug 2023 09:44:19 -0700 Subject: [PATCH 1/9] Allow force restarting of file shares regardless of timestamp. Move RestartFileShare to FileSharingFunctionality where it belongs. --- .../filesharing/filesharing_functionality.go | 26 ++++++++++++------- functionality/filesharing/image_previews.go | 5 ++-- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/functionality/filesharing/filesharing_functionality.go b/functionality/filesharing/filesharing_functionality.go index 22986cc..7c29d25 100644 --- a/functionality/filesharing/filesharing_functionality.go +++ b/functionality/filesharing/filesharing_functionality.go @@ -45,6 +45,8 @@ func (f *Functionality) ExperimentsToRegister() []string { func (f *Functionality) OnEvent(ev event.Event, profile peer.CwtchPeer) { if profile.IsFeatureEnabled(constants.FileSharingExperiment) { switch ev.EventType { + case event.ProtocolEngineCreated: + f.ReShareFiles(profile) case event.ManifestReceived: log.Debugf("Manifest Received Event!: %v", ev) handle := ev.Data[event.Handle] @@ -294,9 +296,10 @@ func (f *Functionality) DownloadFile(profile peer.CwtchPeer, conversationID int, } // startFileShare is a private method used to finalize a file share and publish it to the protocol engine for processing. -func (f *Functionality) startFileShare(profile peer.CwtchPeer, filekey string, manifest string) error { +// if force is set to true, this function will ignore timestamp checks... +func (f *Functionality) startFileShare(profile peer.CwtchPeer, filekey string, manifest string, force bool) error { tsStr, exists := profile.GetScopedZonedAttribute(attr.LocalScope, attr.FilesharingZone, fmt.Sprintf("%s.ts", filekey)) - if exists { + if exists && !force { ts, err := strconv.ParseInt(tsStr, 10, 64) if err != nil || ts < time.Now().Unix()-2592000 { log.Errorf("ignoring request to download a file offered more than 30 days ago") @@ -311,7 +314,14 @@ func (f *Functionality) startFileShare(profile peer.CwtchPeer, filekey string, m } // RestartFileShare takes in an existing filekey and, assuming the manifest exists, restarts sharing of the manifest +// by default this function always forces a file share, even if the file has timed out. func (f *Functionality) RestartFileShare(profile peer.CwtchPeer, filekey string) error { + return f.restartFileShareAdvanced(profile, filekey, true) +} + +// RestartFileShareAdvanced takes in an existing filekey and, assuming the manifest exists, restarts sharing of the manifest in addition +// to a set of parameters +func (f *Functionality) restartFileShareAdvanced(profile peer.CwtchPeer, filekey string, force bool) error { // assert that we are allowed to restart filesharing if !profile.IsFeatureEnabled(constants.FileSharingExperiment) { @@ -323,7 +333,7 @@ func (f *Functionality) RestartFileShare(profile peer.CwtchPeer, filekey string) if manifestExists { // everything is in order, so reshare this file with the engine log.Debugf("restarting file share: %v", filekey) - return f.startFileShare(profile, filekey, manifest) + return f.startFileShare(profile, filekey, manifest, force) } return fmt.Errorf("manifest does not exist for filekey: %v", filekey) } @@ -357,12 +367,10 @@ func (f *Functionality) ReShareFiles(profile peer.CwtchPeer) error { filekey := strings.Join(keyparts[:2], ".") sharedFile, err := f.GetFileShareInfo(profile, filekey) - // If we haven't explicitly stopped sharing the file AND - // If fewer than 30 days have passed since we originally shared this file, - // Then attempt to share this file again... - // TODO: In the future this would be the point to change the timestamp and reshare the file... + // If we haven't explicitly stopped sharing the file then attempt a reshare if err == nil && sharedFile.Active { - err := f.RestartFileShare(profile, filekey) + // this reshare can fail because we don't force sharing of files older than 30 days... + err := f.restartFileShareAdvanced(profile, filekey, false) if err != nil { log.Debugf("could not reshare file: %v", err) } @@ -456,7 +464,7 @@ func (f *Functionality) ShareFile(filepath string, profile peer.CwtchPeer) (stri profile.SetScopedZonedAttribute(attr.ConversationScope, attr.FilesharingZone, fmt.Sprintf("%s.manifest", key), string(serializedManifest)) profile.SetScopedZonedAttribute(attr.ConversationScope, attr.FilesharingZone, fmt.Sprintf("%s.manifest.size", key), strconv.Itoa(int(math.Ceil(float64(len(serializedManifest)-lenDiff)/float64(files.DefaultChunkSize))))) - err = f.startFileShare(profile, key, string(serializedManifest)) + err = f.startFileShare(profile, key, string(serializedManifest), false) return key, string(wrapperJSON), err } diff --git a/functionality/filesharing/image_previews.go b/functionality/filesharing/image_previews.go index ad509a2..6bbc794 100644 --- a/functionality/filesharing/image_previews.go +++ b/functionality/filesharing/image_previews.go @@ -75,10 +75,9 @@ func (i *ImagePreviewsFunctionality) OnEvent(ev event.Event, profile peer.CwtchP // we reset the profile image here so that it is always available. profile.SetScopedZonedAttribute(attr.LocalScope, attr.FilesharingZone, fmt.Sprintf("%s.ts", key), strconv.FormatInt(time.Now().Unix(), 10)) log.Debugf("Custom Profile Image: %v %s", key, serializedManifest) + f := Functionality{} + f.RestartFileShare(profile, key) } - // If file sharing is enabled then reshare all active files... - fsf := FunctionalityGate() - _ = fsf.ReShareFiles(profile) } } } From 0997406e510857359c3a0d11cc482dec3609404c Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Mon, 28 Aug 2023 13:17:55 -0700 Subject: [PATCH 2/9] Limit connectionRetry attempts to requested peers/servers There is a bug where spurious PeerStateChange events from failed auth attempts will make their way into contact retry plugin and result in attempts that will *always* fail. Note: This would also happen in the case of blocked peers *however* these would be short-circuit failed in engine also. --- app/plugins/contactRetry.go | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/app/plugins/contactRetry.go b/app/plugins/contactRetry.go index b3cef2c..be6e6b3 100644 --- a/app/plugins/contactRetry.go +++ b/app/plugins/contactRetry.go @@ -3,6 +3,7 @@ package plugins import ( "cwtch.im/cwtch/event" "cwtch.im/cwtch/protocol/connections" + "git.openprivacy.ca/openprivacy/connectivity/tor" "git.openprivacy.ca/openprivacy/log" "math" "strconv" @@ -123,11 +124,12 @@ type contactRetry struct { connections sync.Map //[string]*contact pendingQueue *connectionQueue priorityQueue *connectionQueue + authorizedPeers sync.Map } // NewConnectionRetry returns a Plugin that when started will retry connecting to contacts with a failedCount timing func NewConnectionRetry(bus event.Manager, onion string) Plugin { - cr := &contactRetry{bus: bus, queue: event.NewQueue(), breakChan: make(chan bool, 1), connections: sync.Map{}, ACNUp: false, ACNUpTime: time.Now(), protocolEngine: false, onion: onion, pendingQueue: newConnectionQueue(), priorityQueue: newConnectionQueue()} + cr := &contactRetry{bus: bus, queue: event.NewQueue(), breakChan: make(chan bool, 1), authorizedPeers: sync.Map{}, connections: sync.Map{}, ACNUp: false, ACNUpTime: time.Now(), protocolEngine: false, onion: onion, pendingQueue: newConnectionQueue(), priorityQueue: newConnectionQueue()} return cr } @@ -229,13 +231,17 @@ func (cr *contactRetry) run() { case event.PeerStateChange: state := connections.ConnectionStateToType()[e.Data[event.ConnectionState]] peer := e.Data[event.RemotePeer] - cr.handleEvent(peer, state, peerConn) - + // only handle state change events from pre-authorized peers; + if _,exists := cr.authorizedPeers.Load(peer); exists { + cr.handleEvent(peer, state, peerConn) + } case event.ServerStateChange: state := connections.ConnectionStateToType()[e.Data[event.ConnectionState]] server := e.Data[event.GroupServer] - cr.handleEvent(server, state, serverConn) - + // only handle state change events from pre-authorized servers; + if _,exists := cr.authorizedPeers.Load(server); exists { + cr.handleEvent(server, state, serverConn) + } case event.QueueJoinServer: fallthrough case event.QueuePeerRequest: @@ -252,7 +258,8 @@ func (cr *contactRetry) run() { id = server cr.addConnection(server, connections.DISCONNECTED, serverConn, lastSeen) } - + // this was an authorized event, and so we store this peer. + cr.authorizedPeers.Store(id, true) if c, ok := cr.connections.Load(id); ok { contact := c.(*contact) if contact.state == connections.DISCONNECTED && !contact.queued { @@ -423,6 +430,12 @@ func (cr *contactRetry) handleEvent(id string, state connections.ConnectionState return } + // reject events that contain invalid hostnames...we cannot connect to them + // and they could result in spurious connection attempts... + if tor.IsValidHostname(id) == false { + return + } + if _, exists := cr.connections.Load(id); !exists { // We have an event for something we don't know about... // The only reason this should happen is if a *new* Peer/Server connection has changed. From ca6320593449d49ffce69f706fd882eb686a9c92 Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Mon, 28 Aug 2023 13:23:25 -0700 Subject: [PATCH 3/9] Quality Fixup --- app/plugins/contactRetry.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/plugins/contactRetry.go b/app/plugins/contactRetry.go index be6e6b3..249c3dd 100644 --- a/app/plugins/contactRetry.go +++ b/app/plugins/contactRetry.go @@ -121,9 +121,9 @@ type contactRetry struct { lastCheck time.Time acnProgress int - connections sync.Map //[string]*contact - pendingQueue *connectionQueue - priorityQueue *connectionQueue + connections sync.Map //[string]*contact + pendingQueue *connectionQueue + priorityQueue *connectionQueue authorizedPeers sync.Map } @@ -232,14 +232,14 @@ func (cr *contactRetry) run() { state := connections.ConnectionStateToType()[e.Data[event.ConnectionState]] peer := e.Data[event.RemotePeer] // only handle state change events from pre-authorized peers; - if _,exists := cr.authorizedPeers.Load(peer); exists { + if _, exists := cr.authorizedPeers.Load(peer); exists { cr.handleEvent(peer, state, peerConn) } case event.ServerStateChange: state := connections.ConnectionStateToType()[e.Data[event.ConnectionState]] server := e.Data[event.GroupServer] // only handle state change events from pre-authorized servers; - if _,exists := cr.authorizedPeers.Load(server); exists { + if _, exists := cr.authorizedPeers.Load(server); exists { cr.handleEvent(server, state, serverConn) } case event.QueueJoinServer: @@ -432,7 +432,7 @@ func (cr *contactRetry) handleEvent(id string, state connections.ConnectionState // reject events that contain invalid hostnames...we cannot connect to them // and they could result in spurious connection attempts... - if tor.IsValidHostname(id) == false { + if !tor.IsValidHostname(id) { return } From 048effc91ae9540253c01ce4d1ae895c95260771 Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Mon, 28 Aug 2023 13:34:24 -0700 Subject: [PATCH 4/9] contactRetry test needs to use a valid onion --- app/plugins/contactRetry.go | 1 + app/plugins/contactRetry_test.go | 21 +++++++++++++-------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/app/plugins/contactRetry.go b/app/plugins/contactRetry.go index 249c3dd..67de66e 100644 --- a/app/plugins/contactRetry.go +++ b/app/plugins/contactRetry.go @@ -259,6 +259,7 @@ func (cr *contactRetry) run() { cr.addConnection(server, connections.DISCONNECTED, serverConn, lastSeen) } // this was an authorized event, and so we store this peer. + log.Debugf("authorizing id: %v", id); cr.authorizedPeers.Store(id, true) if c, ok := cr.connections.Load(id); ok { contact := c.(*contact) diff --git a/app/plugins/contactRetry_test.go b/app/plugins/contactRetry_test.go index adf2604..54a8052 100644 --- a/app/plugins/contactRetry_test.go +++ b/app/plugins/contactRetry_test.go @@ -23,32 +23,37 @@ func TestContactRetryQueue(t *testing.T) { cr.protocolEngine = true // fake protocol engine go cr.run() + testOnion := "2wgvbza2mbuc72a4u6r6k4hc2blcvrmk4q26bfvlwbqxv2yq5k52fcqd" + t.Logf("contact plugin up and running..sending peer connection...") // Assert that there is a peer connection identified as "test" - bus.Publish(event.NewEvent(event.QueuePeerRequest, map[event.Field]string{event.RemotePeer: "test", event.LastSeen: "test"})) + bus.Publish(event.NewEvent(event.QueuePeerRequest, map[event.Field]string{event.RemotePeer: testOnion, event.LastSeen: "test"})) // Wait until the test actually exists, and is queued // This is the worst part of this test setup. Ideally we would sleep, or some other yielding, but // go test scheduling doesn't like that and even sleeping long periods won't cause the event thread to make // progress... for { - if pinf, exists := cr.connections.Load("test"); exists { + if pinf, exists := cr.connections.Load(testOnion); exists { if pinf.(*contact).queued { - break + if _,exists := cr.authorizedPeers.Load(testOnion); exists { + t.Logf("authorized"); + break; + } } } } - pinf, _ := cr.connections.Load("test") + pinf, _ := cr.connections.Load(testOnion) if pinf.(*contact).queued == false { t.Fatalf("test connection should be queued, actually: %v", pinf.(*contact).queued) } // Asset that "test" is authenticated - cr.handleEvent("test", connections.AUTHENTICATED, peerConn) + cr.handleEvent(testOnion, connections.AUTHENTICATED, peerConn) // Assert that "test has a valid state" - pinf, _ = cr.connections.Load("test") + pinf, _ = cr.connections.Load(testOnion) if pinf.(*contact).state != 3 { t.Fatalf("test connection should be in authenticated after update, actually: %v", pinf.(*contact).state) } @@ -62,11 +67,11 @@ func TestContactRetryQueue(t *testing.T) { } // Publish a new peer request... - bus.Publish(event.NewEvent(event.QueuePeerRequest, map[event.Field]string{event.RemotePeer: "test"})) + bus.Publish(event.NewEvent(event.QueuePeerRequest, map[event.Field]string{event.RemotePeer: testOnion})) time.Sleep(time.Second) // yield for a second so the event can catch up... // Peer test should be forced to queue.... - pinf, _ = cr.connections.Load("test") + pinf, _ = cr.connections.Load(testOnion) if pinf.(*contact).queued != true { t.Fatalf("test connection should be forced to queue after new queue peer request") } From fb164b104bc80860980c7aa3c79f8c6c98206bcf Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Mon, 28 Aug 2023 13:35:54 -0700 Subject: [PATCH 5/9] Format --- app/plugins/contactRetry.go | 2 +- app/plugins/contactRetry_test.go | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/plugins/contactRetry.go b/app/plugins/contactRetry.go index 67de66e..1ed749d 100644 --- a/app/plugins/contactRetry.go +++ b/app/plugins/contactRetry.go @@ -259,7 +259,7 @@ func (cr *contactRetry) run() { cr.addConnection(server, connections.DISCONNECTED, serverConn, lastSeen) } // this was an authorized event, and so we store this peer. - log.Debugf("authorizing id: %v", id); + log.Debugf("authorizing id: %v", id) cr.authorizedPeers.Store(id, true) if c, ok := cr.connections.Load(id); ok { contact := c.(*contact) diff --git a/app/plugins/contactRetry_test.go b/app/plugins/contactRetry_test.go index 54a8052..be60309 100644 --- a/app/plugins/contactRetry_test.go +++ b/app/plugins/contactRetry_test.go @@ -36,10 +36,10 @@ func TestContactRetryQueue(t *testing.T) { for { if pinf, exists := cr.connections.Load(testOnion); exists { if pinf.(*contact).queued { - if _,exists := cr.authorizedPeers.Load(testOnion); exists { - t.Logf("authorized"); - break; - } + if _, exists := cr.authorizedPeers.Load(testOnion); exists { + t.Logf("authorized") + break + } } } } From 6d29ca322eaf303485c23a5f25230482105ce9af Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Tue, 29 Aug 2023 12:16:49 -0700 Subject: [PATCH 6/9] Redirect JoinServer Flow. Have Servers listen to QueueJoinServer Update. Handle delete contact flow for contact retry plugin --- app/plugins/contactRetry.go | 6 ++++++ functionality/servers/servers_functionality.go | 4 +++- peer/cwtch_peer.go | 4 ++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/app/plugins/contactRetry.go b/app/plugins/contactRetry.go index 1ed749d..c6f4a70 100644 --- a/app/plugins/contactRetry.go +++ b/app/plugins/contactRetry.go @@ -179,6 +179,7 @@ func (cr *contactRetry) run() { cr.bus.Subscribe(event.QueueJoinServer, cr.queue) cr.bus.Subscribe(event.ProtocolEngineShutdown, cr.queue) cr.bus.Subscribe(event.ProtocolEngineCreated, cr.queue) + cr.bus.Subscribe(event.DeleteContact, cr.queue) for { // Only attempt connection if both the ACN and the Protocol Engines are Online... @@ -228,6 +229,11 @@ func (cr *contactRetry) run() { select { case e := <-cr.queue.OutChan(): switch e.EventType { + case event.DeleteContact: + // this case covers both servers and peers (servers are peers, and go through the + // same delete conversation flow) + peer := e.Data[event.RemotePeer] + cr.authorizedPeers.Delete(peer) case event.PeerStateChange: state := connections.ConnectionStateToType()[e.Data[event.ConnectionState]] peer := e.Data[event.RemotePeer] diff --git a/functionality/servers/servers_functionality.go b/functionality/servers/servers_functionality.go index 4a039be..7cd5f37 100644 --- a/functionality/servers/servers_functionality.go +++ b/functionality/servers/servers_functionality.go @@ -30,7 +30,7 @@ func (f *Functionality) NotifySettingsUpdate(settings settings.GlobalSettings) { } func (f *Functionality) EventsToRegister() []event.Type { - return []event.Type{event.Heartbeat} + return []event.Type{event.Heartbeat, event.QueueJoinServer} } func (f *Functionality) ExperimentsToRegister() []string { @@ -45,6 +45,8 @@ func (f *Functionality) OnEvent(ev event.Event, profile peer.CwtchPeer) { // TODO: do we need a secondary heartbeat for less common updates? case event.Heartbeat: f.PublishServerUpdate(profile) + case event.QueueJoinServer: + f.PublishServerUpdate(profile) } } } diff --git a/peer/cwtch_peer.go b/peer/cwtch_peer.go index 3edbacb..50f8c33 100644 --- a/peer/cwtch_peer.go +++ b/peer/cwtch_peer.go @@ -670,7 +670,7 @@ func (cp *cwtchPeer) ImportGroup(exportedInvite string) (int, error) { cp.SetConversationAttribute(groupConversationID, attr.LocalScope.ConstructScopedZonedPath(attr.LegacyGroupZone.ConstructZonedPath(constants.GroupKey)), base64.StdEncoding.EncodeToString(gci.SharedKey)) cp.SetConversationAttribute(groupConversationID, attr.LocalScope.ConstructScopedZonedPath(attr.ProfileZone.ConstructZonedPath(constants.Name)), gci.GroupName) cp.eventBus.Publish(event.NewEvent(event.NewGroup, map[event.Field]string{event.ConversationID: strconv.Itoa(groupConversationID), event.GroupServer: gci.ServerHost, event.GroupInvite: exportedInvite, event.GroupName: gci.GroupName})) - cp.JoinServer(gci.ServerHost) + cp.QueueJoinServer(gci.ServerHost) } return groupConversationID, err } @@ -993,7 +993,7 @@ func (cp *cwtchPeer) AddServer(serverSpecification string) (string, error) { cp.SetConversationAttribute(conversationInfo.ID, attr.PublicScope.ConstructScopedZonedPath(attr.ServerKeyZone.ConstructZonedPath(k)), v) } cp.SetConversationAttribute(conversationInfo.ID, attr.PublicScope.ConstructScopedZonedPath(attr.ServerKeyZone.ConstructZonedPath(string(model.BundleType))), serverSpecification) - cp.JoinServer(onion) + cp.QueueJoinServer(onion) return onion, err } return "", err From 407902b8ee323abd4102e5b49152512f7a98a58d Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Tue, 29 Aug 2023 12:20:08 -0700 Subject: [PATCH 7/9] Minimize Event Noise for Server Updates / Handle Blocking Flow for ContactRetry plugin --- app/plugins/contactRetry.go | 10 +++++++++- functionality/servers/servers_functionality.go | 5 ++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/app/plugins/contactRetry.go b/app/plugins/contactRetry.go index c6f4a70..b36bba0 100644 --- a/app/plugins/contactRetry.go +++ b/app/plugins/contactRetry.go @@ -180,7 +180,7 @@ func (cr *contactRetry) run() { cr.bus.Subscribe(event.ProtocolEngineShutdown, cr.queue) cr.bus.Subscribe(event.ProtocolEngineCreated, cr.queue) cr.bus.Subscribe(event.DeleteContact, cr.queue) - + cr.bus.Subscribe(event.UpdateConversationAuthorization, cr.queue) for { // Only attempt connection if both the ACN and the Protocol Engines are Online... log.Debugf("restartFlow checking state") @@ -234,6 +234,14 @@ func (cr *contactRetry) run() { // same delete conversation flow) peer := e.Data[event.RemotePeer] cr.authorizedPeers.Delete(peer) + case event.UpdateConversationAuthorization: + // if we update the conversation authorization then we need to check if + // we need to remove blocked conversations from the regular flow. + peer := e.Data[event.RemotePeer] + blocked := e.Data[event.Blocked] + if blocked == "true" { + cr.authorizedPeers.Delete(peer) + } case event.PeerStateChange: state := connections.ConnectionStateToType()[e.Data[event.ConnectionState]] peer := e.Data[event.RemotePeer] diff --git a/functionality/servers/servers_functionality.go b/functionality/servers/servers_functionality.go index 7cd5f37..eef3529 100644 --- a/functionality/servers/servers_functionality.go +++ b/functionality/servers/servers_functionality.go @@ -42,9 +42,8 @@ func (f *Functionality) OnEvent(ev event.Event, profile peer.CwtchPeer) { if profile.IsFeatureEnabled(constants.GroupsExperiment) { switch ev.EventType { // keep the UI in sync with the current backend server updates... - // TODO: do we need a secondary heartbeat for less common updates? - case event.Heartbeat: - f.PublishServerUpdate(profile) + // queue join server gets triggered on load and on new servers so it's a nice + // low-noise event to hook into... case event.QueueJoinServer: f.PublishServerUpdate(profile) } From 75a3c1428501d2b1331544e0a760071594538b34 Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Tue, 29 Aug 2023 12:26:51 -0700 Subject: [PATCH 8/9] Nicer test Scheduling --- app/plugins/contactRetry_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/plugins/contactRetry_test.go b/app/plugins/contactRetry_test.go index be60309..ab55a98 100644 --- a/app/plugins/contactRetry_test.go +++ b/app/plugins/contactRetry_test.go @@ -33,12 +33,13 @@ func TestContactRetryQueue(t *testing.T) { // This is the worst part of this test setup. Ideally we would sleep, or some other yielding, but // go test scheduling doesn't like that and even sleeping long periods won't cause the event thread to make // progress... - for { + setup := false; + for !setup { if pinf, exists := cr.connections.Load(testOnion); exists { if pinf.(*contact).queued { if _, exists := cr.authorizedPeers.Load(testOnion); exists { t.Logf("authorized") - break + setup = true; } } } From 298a8d8aea6d938b0c7eab1584bfd04b4047be90 Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Tue, 29 Aug 2023 13:01:40 -0700 Subject: [PATCH 9/9] Unsub Server Functionality from Heartbeats --- functionality/servers/servers_functionality.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functionality/servers/servers_functionality.go b/functionality/servers/servers_functionality.go index eef3529..a1a3bfc 100644 --- a/functionality/servers/servers_functionality.go +++ b/functionality/servers/servers_functionality.go @@ -30,7 +30,7 @@ func (f *Functionality) NotifySettingsUpdate(settings settings.GlobalSettings) { } func (f *Functionality) EventsToRegister() []event.Type { - return []event.Type{event.Heartbeat, event.QueueJoinServer} + return []event.Type{event.QueueJoinServer} } func (f *Functionality) ExperimentsToRegister() []string {