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

feat: replace group_offline with group_efficiency_below event #1005

Merged
merged 5 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
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
47 changes: 15 additions & 32 deletions backend/pkg/api/data_access/notifications.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ const (

DiscordWebhookFormat string = "discord"

GroupOfflineThresholdDefault float64 = 0.1
GroupEfficiencyBelowThresholdDefault float64 = 0.95
MaxCollateralThresholdDefault float64 = 1.0
MinCollateralThresholdDefault float64 = 0.2
ERC20TokenTransfersValueThresholdDefault float64 = 0.1
Expand Down Expand Up @@ -559,19 +559,6 @@ func (d *DataAccessService) GetValidatorDashboardNotificationDetails(ctx context
continue
}
notificationDetails.ValidatorBackOnline = append(notificationDetails.ValidatorBackOnline, t.NotificationEventValidatorBackOnline{Index: curNotification.ValidatorIndex, EpochCount: curNotification.Epoch})
case types.ValidatorGroupIsOfflineEventName:
LuccaBitfly marked this conversation as resolved.
Show resolved Hide resolved
// TODO type / collection not present yet, skipping
/*curNotification, ok := not.(*notification.validatorGroupIsOfflineNotification)
if !ok {
return nil, fmt.Errorf("failed to cast notification to validatorGroupIsOfflineNotification")
}
if curNotification.Status == 0 {
notificationDetails.GroupOffline = ...
notificationDetails.GroupOfflineReminder = ...
} else {
notificationDetails.GroupBackOnline = ...
}
*/
case types.ValidatorReceivedWithdrawalEventName:
curNotification, ok := notification.(*n.ValidatorWithdrawalNotification)
if !ok {
Expand Down Expand Up @@ -1447,7 +1434,7 @@ func (d *DataAccessService) GetNotificationSettings(ctx context.Context, userId

func (d *DataAccessService) GetNotificationSettingsDefaultValues(ctx context.Context) (*t.NotificationSettingsDefaultValues, error) {
return &t.NotificationSettingsDefaultValues{
GroupOfflineThreshold: GroupOfflineThresholdDefault,
GroupEfficiencyBelowThreshold: GroupEfficiencyBelowThresholdDefault,
MaxCollateralThreshold: MaxCollateralThresholdDefault,
MinCollateralThreshold: MinCollateralThresholdDefault,
ERC20TokenTransfersValueThreshold: ERC20TokenTransfersValueThresholdDefault,
Expand Down Expand Up @@ -1763,7 +1750,6 @@ func (d *DataAccessService) GetNotificationSettingsDashboards(ctx context.Contex
Network uint64 `db:"network"`
WebhookUrl sql.NullString `db:"webhook_target"`
IsWebhookDiscordEnabled sql.NullBool `db:"discord_webhook"`
IsRealTimeModeEnabled sql.NullBool `db:"realtime_notifications"`
}{}
wg.Go(func() error {
err := d.alloyReader.SelectContext(ctx, &valDashboards, `
Expand All @@ -1774,8 +1760,7 @@ func (d *DataAccessService) GetNotificationSettingsDashboards(ctx context.Contex
g.name AS group_name,
d.network,
g.webhook_target,
(g.webhook_format = $1) AS discord_webhook,
g.realtime_notifications
(g.webhook_format = $1) AS discord_webhook
FROM users_val_dashboards d
INNER JOIN users_val_dashboards_groups g ON d.id = g.dashboard_id
WHERE d.user_id = $2`, DiscordWebhookFormat, userId)
Expand Down Expand Up @@ -1850,9 +1835,9 @@ func (d *DataAccessService) GetNotificationSettingsDashboards(ctx context.Contex
if dashboardType == ValidatorDashboardEventPrefix {
resultMap[event.Filter] = &t.NotificationSettingsDashboardsTableRow{
Settings: t.NotificationSettingsValidatorDashboard{
GroupOfflineThreshold: GroupOfflineThresholdDefault,
MaxCollateralThreshold: MaxCollateralThresholdDefault,
MinCollateralThreshold: MinCollateralThresholdDefault,
GroupEfficiencyBelowThreshold: GroupEfficiencyBelowThresholdDefault,
MaxCollateralThreshold: MaxCollateralThresholdDefault,
MinCollateralThreshold: MinCollateralThresholdDefault,
},
}
} else if dashboardType == AccountDashboardEventPrefix {
Expand All @@ -1869,9 +1854,9 @@ func (d *DataAccessService) GetNotificationSettingsDashboards(ctx context.Contex
switch eventName {
case types.ValidatorIsOfflineEventName:
settings.IsValidatorOfflineSubscribed = true
case types.GroupIsOfflineEventName:
settings.IsGroupOfflineSubscribed = true
settings.GroupOfflineThreshold = event.Threshold
case types.ValidatorGroupEfficiencyEventName:
settings.IsGroupEfficiencyBelowSubscribed = true
settings.GroupEfficiencyBelowThreshold = event.Threshold
case types.ValidatorMissedAttestationEventName:
settings.IsAttestationsMissedSubscribed = true
case types.ValidatorMissedProposalEventName, types.ValidatorExecutedProposalEventName:
Expand Down Expand Up @@ -1917,9 +1902,9 @@ func (d *DataAccessService) GetNotificationSettingsDashboards(ctx context.Contex
if _, ok := resultMap[key]; !ok {
resultMap[key] = &t.NotificationSettingsDashboardsTableRow{
Settings: t.NotificationSettingsValidatorDashboard{
GroupOfflineThreshold: GroupOfflineThresholdDefault,
MaxCollateralThreshold: MaxCollateralThresholdDefault,
MinCollateralThreshold: MinCollateralThresholdDefault,
GroupEfficiencyBelowThreshold: GroupEfficiencyBelowThresholdDefault,
MaxCollateralThreshold: MaxCollateralThresholdDefault,
MinCollateralThreshold: MinCollateralThresholdDefault,
},
}
}
Expand All @@ -1936,7 +1921,6 @@ func (d *DataAccessService) GetNotificationSettingsDashboards(ctx context.Contex
if valSettings, ok := resultMap[key].Settings.(*t.NotificationSettingsValidatorDashboard); ok {
valSettings.WebhookUrl = valDashboard.WebhookUrl.String
valSettings.IsWebhookDiscordEnabled = valDashboard.IsWebhookDiscordEnabled.Bool
valSettings.IsRealTimeModeEnabled = valDashboard.IsRealTimeModeEnabled.Bool
}
}

Expand Down Expand Up @@ -2101,7 +2085,7 @@ func (d *DataAccessService) UpdateNotificationSettingsValidatorDashboard(ctx con
eventFilter := fmt.Sprintf("%s:%d:%d", ValidatorDashboardEventPrefix, dashboardId, groupId)

d.AddOrRemoveEvent(&eventsToInsert, &eventsToDelete, settings.IsValidatorOfflineSubscribed, userId, types.ValidatorIsOfflineEventName, networkName, eventFilter, epoch, 0)
d.AddOrRemoveEvent(&eventsToInsert, &eventsToDelete, settings.IsGroupOfflineSubscribed, userId, types.GroupIsOfflineEventName, networkName, eventFilter, epoch, settings.GroupOfflineThreshold)
d.AddOrRemoveEvent(&eventsToInsert, &eventsToDelete, settings.IsGroupEfficiencyBelowSubscribed, userId, types.ValidatorGroupEfficiencyEventName, networkName, eventFilter, epoch, settings.GroupEfficiencyBelowThreshold)
d.AddOrRemoveEvent(&eventsToInsert, &eventsToDelete, settings.IsAttestationsMissedSubscribed, userId, types.ValidatorMissedAttestationEventName, networkName, eventFilter, epoch, 0)
d.AddOrRemoveEvent(&eventsToInsert, &eventsToDelete, settings.IsUpcomingBlockProposalSubscribed, userId, types.ValidatorUpcomingProposalEventName, networkName, eventFilter, epoch, 0)
d.AddOrRemoveEvent(&eventsToInsert, &eventsToDelete, settings.IsSyncSubscribed, userId, types.SyncCommitteeSoon, networkName, eventFilter, epoch, 0)
Expand Down Expand Up @@ -2162,9 +2146,8 @@ func (d *DataAccessService) UpdateNotificationSettingsValidatorDashboard(ctx con
UPDATE users_val_dashboards_groups
SET
webhook_target = NULLIF($1, ''),
webhook_format = CASE WHEN $2 THEN $3 ELSE NULL END,
realtime_notifications = CASE WHEN $4 THEN TRUE ELSE NULL END
WHERE dashboard_id = $5 AND id = $6`, settings.WebhookUrl, settings.IsWebhookDiscordEnabled, DiscordWebhookFormat, settings.IsRealTimeModeEnabled, dashboardId, groupId)
webhook_format = CASE WHEN $2 THEN $3 ELSE NULL END
WHERE dashboard_id = $4 AND id = $5`, settings.WebhookUrl, settings.IsWebhookDiscordEnabled, DiscordWebhookFormat, dashboardId, groupId)
if err != nil {
return err
}
Expand Down
19 changes: 6 additions & 13 deletions backend/pkg/api/handlers/public.go
Original file line number Diff line number Diff line change
Expand Up @@ -2495,12 +2495,9 @@ func (h *HandlerService) PublicGetUserNotificationSettingsDashboards(w http.Resp
handleErr(w, r, errors.New("invalid settings type"))
return
}
if !userInfo.PremiumPerks.NotificationsValidatorDashboardGroupOffline && settings.IsGroupOfflineSubscribed {
settings.IsGroupOfflineSubscribed = false
settings.GroupOfflineThreshold = defaultSettings.GroupOfflineThreshold
}
if !userInfo.PremiumPerks.NotificationsValidatorDashboardRealTimeMode && settings.IsRealTimeModeEnabled {
settings.IsRealTimeModeEnabled = false
if !userInfo.PremiumPerks.NotificationsValidatorDashboardGroupEfficiency && settings.IsGroupEfficiencyBelowSubscribed {
settings.IsGroupEfficiencyBelowSubscribed = false
settings.GroupEfficiencyBelowThreshold = defaultSettings.GroupEfficiencyBelowThreshold
}
data[i].Settings = settings
}
Expand Down Expand Up @@ -2537,7 +2534,7 @@ func (h *HandlerService) PublicPutUserNotificationSettingsValidatorDashboard(w h
handleErr(w, r, err)
return
}
checkMinMax(&v, req.GroupOfflineThreshold, 0, 1, "group_offline_threshold")
checkMinMax(&v, req.GroupEfficiencyBelowThreshold, 0, 1, "group_offline_threshold")
vars := mux.Vars(r)
dashboardId := v.checkPrimaryDashboardId(vars["dashboard_id"])
groupId := v.checkExistingGroupId(vars["group_id"])
Expand All @@ -2553,12 +2550,8 @@ func (h *HandlerService) PublicPutUserNotificationSettingsValidatorDashboard(w h
handleErr(w, r, err)
return
}
if !userInfo.PremiumPerks.NotificationsValidatorDashboardGroupOffline && req.IsGroupOfflineSubscribed {
returnForbidden(w, r, errors.New("user does not have premium perks to subscribe group offline"))
return
}
if !userInfo.PremiumPerks.NotificationsValidatorDashboardRealTimeMode && req.IsRealTimeModeEnabled {
returnForbidden(w, r, errors.New("user does not have premium perks to subscribe real time mode"))
if !userInfo.PremiumPerks.NotificationsValidatorDashboardGroupEfficiency && req.IsGroupEfficiencyBelowSubscribed {
returnForbidden(w, r, errors.New("user does not have premium perks to subscribe group efficiency event"))
return
}

Expand Down
2 changes: 1 addition & 1 deletion backend/pkg/api/types/data_access.go
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ type MobileAppBundleStats struct {
// Notification structs

type NotificationSettingsDefaultValues struct {
GroupOfflineThreshold float64
GroupEfficiencyBelowThreshold float64
MaxCollateralThreshold float64
MinCollateralThreshold float64
ERC20TokenTransfersValueThreshold float64
Expand Down
13 changes: 5 additions & 8 deletions backend/pkg/api/types/notifications.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ type NotificationDashboardsTableRow struct {
GroupId uint64 `db:"group_id" json:"group_id"`
GroupName string `db:"group_name" json:"group_name"`
EntityCount uint64 `db:"entity_count" json:"entity_count"`
EventTypes pq.StringArray `db:"event_types" json:"event_types" tstype:"('validator_online' | 'validator_offline' | 'group_online' | 'group_offline' | 'attestation_missed' | 'proposal_success' | 'proposal_missed' | 'proposal_upcoming' | 'max_collateral' | 'min_collateral' | 'sync' | 'withdrawal' | 'validator_got_slashed' | 'validator_has_slashed' | 'incoming_tx' | 'outgoing_tx' | 'transfer_erc20' | 'transfer_erc721' | 'transfer_erc1155')[]" faker:"slice_len=2, oneof: validator_online, validator_offline, group_online, group_offline, attestation_missed, proposal_success, proposal_missed, proposal_upcoming, max_collateral, min_collateral, sync, withdrawal, validator_got_slashed, validator_has_slashed, incoming_tx, outgoing_tx, transfer_erc20, transfer_erc721, transfer_erc1155"`
EventTypes pq.StringArray `db:"event_types" json:"event_types" tstype:"('validator_online' | 'validator_offline' | 'group_efficiency_below' | 'attestation_missed' | 'proposal_success' | 'proposal_missed' | 'proposal_upcoming' | 'max_collateral' | 'min_collateral' | 'sync' | 'withdrawal' | 'validator_got_slashed' | 'validator_has_slashed' | 'incoming_tx' | 'outgoing_tx' | 'transfer_erc20' | 'transfer_erc721' | 'transfer_erc1155')[]" faker:"slice_len=2, oneof: validator_online, validator_offline, group_efficiency_below, attestation_missed, proposal_success, proposal_missed, proposal_upcoming, max_collateral, min_collateral, sync, withdrawal, validator_got_slashed, validator_has_slashed, incoming_tx, outgoing_tx, transfer_erc20, transfer_erc721, transfer_erc1155"`
}

type InternalGetUserNotificationDashboardsResponse ApiPagingResponse[NotificationDashboardsTableRow]
Expand All @@ -62,8 +62,8 @@ type NotificationEventWithdrawal struct {
type NotificationValidatorDashboardDetail struct {
DashboardName string `db:"dashboard_name" json:"dashboard_name"`
GroupName string `db:"group_name" json:"group_name"`
ValidatorOffline []uint64 `json:"validator_offline"` // validator indices
GroupOffline bool `json:"group_offline"` // TODO not filled yet
ValidatorOffline []uint64 `json:"validator_offline"` // validator indices
GroupEfficiencyBelow float64 `json:"group_efficiency_below,omitempty"` // fill with the `group_efficiency_below` threshold if event is present
ProposalMissed []IndexSlots `json:"proposal_missed"`
ProposalDone []IndexBlocks `json:"proposal_done"`
UpcomingProposals []IndexSlots `json:"upcoming_proposals"`
Expand All @@ -72,9 +72,7 @@ type NotificationValidatorDashboardDetail struct {
AttestationMissed []IndexEpoch `json:"attestation_missed"` // index (epoch)
Withdrawal []NotificationEventWithdrawal `json:"withdrawal"`
ValidatorOfflineReminder []uint64 `json:"validator_offline_reminder"` // validator indices; TODO not filled yet
GroupOfflineReminder bool `json:"group_offline_reminder"` // TODO not filled yet
ValidatorBackOnline []NotificationEventValidatorBackOnline `json:"validator_back_online"`
GroupBackOnline uint64 `json:"group_back_online"` // TODO not filled yet
MinimumCollateralReached []Address `json:"min_collateral_reached"` // node addresses
MaximumCollateralReached []Address `json:"max_collateral_reached"` // node addresses
}
Expand Down Expand Up @@ -202,11 +200,10 @@ type InternalGetUserNotificationSettingsResponse ApiDataResponse[NotificationSet
type NotificationSettingsValidatorDashboard struct {
WebhookUrl string `json:"webhook_url" faker:"url"`
IsWebhookDiscordEnabled bool `json:"is_webhook_discord_enabled"`
IsRealTimeModeEnabled bool `json:"is_real_time_mode_enabled"`

IsValidatorOfflineSubscribed bool `json:"is_validator_offline_subscribed"`
IsGroupOfflineSubscribed bool `json:"is_group_offline_subscribed"`
GroupOfflineThreshold float64 `json:"group_offline_threshold" faker:"boundary_start=0, boundary_end=1"`
IsGroupEfficiencyBelowSubscribed bool `json:"is_group_efficiency_below_subscribed"`
GroupEfficiencyBelowThreshold float64 `json:"group_efficiency_below_threshold" faker:"boundary_start=0, boundary_end=1"`
IsAttestationsMissedSubscribed bool `json:"is_attestations_missed_subscribed"`
IsBlockProposalSubscribed bool `json:"is_block_proposal_subscribed"`
IsUpcomingBlockProposalSubscribed bool `json:"is_upcoming_block_proposal_subscribed"`
Expand Down
37 changes: 18 additions & 19 deletions backend/pkg/api/types/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,25 +117,24 @@ type ExtraDashboardValidatorsPremiumAddon struct {
}

type PremiumPerks struct {
AdFree bool `json:"ad_free"` // note that this is somhow redunant, since there is already ApiPerks.NoAds
ValidatorDashboards uint64 `json:"validator_dashboards"`
ValidatorsPerDashboard uint64 `json:"validators_per_dashboard"`
ValidatorGroupsPerDashboard uint64 `json:"validator_groups_per_dashboard"`
ShareCustomDashboards bool `json:"share_custom_dashboards"`
ManageDashboardViaApi bool `json:"manage_dashboard_via_api"`
BulkAdding bool `json:"bulk_adding"`
ChartHistorySeconds ChartHistorySeconds `json:"chart_history_seconds"`
EmailNotificationsPerDay uint64 `json:"email_notifications_per_day"`
ConfigureNotificationsViaApi bool `json:"configure_notifications_via_api"`
ValidatorGroupNotifications uint64 `json:"validator_group_notifications"`
WebhookEndpoints uint64 `json:"webhook_endpoints"`
MobileAppCustomThemes bool `json:"mobile_app_custom_themes"`
MobileAppWidget bool `json:"mobile_app_widget"`
MonitorMachines uint64 `json:"monitor_machines"`
MachineMonitoringHistorySeconds uint64 `json:"machine_monitoring_history_seconds"`
NotificationsMachineCustomThreshold bool `json:"notifications_machine_custom_threshold"`
NotificationsValidatorDashboardRealTimeMode bool `json:"notifications_validator_dashboard_real_time_mode"`
NotificationsValidatorDashboardGroupOffline bool `json:"notifications_validator_dashboard_group_offline"`
AdFree bool `json:"ad_free"` // note that this is somhow redunant, since there is already ApiPerks.NoAds
ValidatorDashboards uint64 `json:"validator_dashboards"`
ValidatorsPerDashboard uint64 `json:"validators_per_dashboard"`
ValidatorGroupsPerDashboard uint64 `json:"validator_groups_per_dashboard"`
ShareCustomDashboards bool `json:"share_custom_dashboards"`
ManageDashboardViaApi bool `json:"manage_dashboard_via_api"`
BulkAdding bool `json:"bulk_adding"`
ChartHistorySeconds ChartHistorySeconds `json:"chart_history_seconds"`
EmailNotificationsPerDay uint64 `json:"email_notifications_per_day"`
ConfigureNotificationsViaApi bool `json:"configure_notifications_via_api"`
ValidatorGroupNotifications uint64 `json:"validator_group_notifications"`
WebhookEndpoints uint64 `json:"webhook_endpoints"`
MobileAppCustomThemes bool `json:"mobile_app_custom_themes"`
MobileAppWidget bool `json:"mobile_app_widget"`
MonitorMachines uint64 `json:"monitor_machines"`
MachineMonitoringHistorySeconds uint64 `json:"machine_monitoring_history_seconds"`
NotificationsMachineCustomThreshold bool `json:"notifications_machine_custom_threshold"`
NotificationsValidatorDashboardGroupEfficiency bool `json:"notifications_validator_dashboard_group_efficiency"`
}

// TODO @patrick post-beta StripeCreateCheckoutSession and StripeCustomerPortal are currently served from v1 (loadbalanced), Once V1 is not affected by this anymore, consider wrapping this with ApiDataResponse
Expand Down
Loading
Loading