chore(signals)_: Allow clients to configure a blocklist of signals

This commit is contained in:
Icaro Motta 2024-07-16 16:09:10 -03:00
parent 9403475572
commit b8a33a8d7b
No known key found for this signature in database
GPG Key ID: 009557D9D014DF07
4 changed files with 89 additions and 0 deletions

View File

@ -782,6 +782,25 @@ func StopLocalNotifications() string {
return makeJSONResponse(err)
}
// SetSignalBlocklist sets a blocklist of signal types that can turn signal.send
// a nop.
func SetSignalBlocklist(requestJSON string) string {
var request requests.SetSignalBlocklist
err := json.Unmarshal([]byte(requestJSON), &request)
if err != nil {
return makeJSONResponse(err)
}
// Index by signal type.
blocklist := make(signal.SignalBlocklist)
for _, v := range request.Blocklist {
blocklist[v] = struct{}{}
}
signal.SetSignalBlocklist(blocklist)
return makeJSONResponse(nil)
}
// SetMobileSignalHandler setup geth callback to notify about new signal
// used for gomobile builds
func SetMobileSignalHandler(handler SignalHandler) {

14
mobile/status_test.go Normal file
View File

@ -0,0 +1,14 @@
package statusgo
import (
"github.com/stretchr/testify/require"
"testing"
)
func TestSetSignalBlocklist(t *testing.T) {
request := "{\"blocklist\":[\"wakuv2.peerstats\",\"history.request.started\"]}"
require.Equal(t, "{\"error\":\"\"}", SetSignalBlocklist(request))
request = "{\"blocklist\":[]}"
require.Equal(t, "{\"error\":\"\"}", SetSignalBlocklist(request))
}

View File

@ -0,0 +1,5 @@
package requests
type SetSignalBlocklist struct {
Blocklist []string `json:"blocklist"`
}

View File

@ -15,6 +15,7 @@ import (
"sync"
"github.com/ethereum/go-ethereum/log"
"github.com/status-im/status-go/services/wallet/walletevent"
)
// MobileSignalHandler is a simple callback function that gets called when any signal is received
@ -23,6 +24,12 @@ type MobileSignalHandler func([]byte)
// storing the current signal handler here
var mobileSignalHandler MobileSignalHandler
// SignalBlocklist is an optional set of signals that should be blocklisted,
// i.e. not sent.
type SignalBlocklist map[string]struct{}
var signalBlocklist SignalBlocklist
// All general log messages in this package should be routed through this logger.
var logger = log.New("package", "status-go/signal")
@ -40,6 +47,41 @@ func NewEnvelope(typ string, event interface{}) *Envelope {
}
}
// isSignalBlocklisted returns true when a signal type is present in the
// blocklist, or when not found, if the signal type and event type are present.
//
// The convention is that clients can specify a particular event type from any
// signal by concatenating a forward slash.
//
// Example for signal "wallet" and event type
// "wallet-collectible-status-changed":
//
// "wallet/wallet-collectible-status-changed"
func isSignalBlocklisted(signal *Envelope, event any) bool {
if len(signalBlocklist) > 0 {
// If the signal type is in the blocklist, then "send" is a nop.
if _, ok := signalBlocklist[signal.Type]; ok {
logger.Info("imotta - Signal blocklisted", "signal", signal.Type)
return true
}
// A signal may encompass an event, in which case we need to concretely
// check the type of the event.
//
// THIS DOES NOT WORK because it creates a circular dependency and the
// compiler will complaint.
if e, ok := event.(walletevent.Event); ok {
name := signal.Type + "/" + string(e.Type)
logger.Info("imotta - Signal blocklisted", "signal", name)
if _, ok := signalBlocklist[name]; ok {
return true
}
}
}
return false
}
// send sends application signal (in JSON) upwards to application (via default notification handler)
func send(typ string, event interface{}) {
signal := NewEnvelope(typ, event)
@ -48,6 +90,11 @@ func send(typ string, event interface{}) {
logger.Error("Marshalling signal envelope", "error", err)
return
}
if isSignalBlocklisted(signal, event) {
return
}
// If a Go implementation of signal handler is set, let's use it.
if mobileSignalHandler != nil {
mobileSignalHandler(data)
@ -111,6 +158,10 @@ func SetMobileSignalHandler(handler MobileSignalHandler) {
mobileSignalHandler = handler
}
func SetSignalBlocklist(blocklist SignalBlocklist) {
signalBlocklist = blocklist
}
// SetSignalEventCallback set callback
// this function uses C implementation (see `signals.c` file)
func SetSignalEventCallback(cb unsafe.Pointer) {