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

Used correct slashing data from db for summary and rewards #379

Merged
merged 3 commits into from
Jun 6, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
131 changes: 78 additions & 53 deletions backend/pkg/api/data_access/vdb_rewards.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ func (d *DataAccessService) GetValidatorDashboardRewards(dashboardId t.VDBId, cu
BlocksProposed uint64 `db:"blocks_proposed"`
SyncScheduled uint64 `db:"sync_scheduled"`
SyncExecuted uint64 `db:"sync_executed"`
Slashed uint64 `db:"slashed"`
SlashedInEpoch uint64 `db:"slashed_in_epoch"`
SlashedAmount uint64 `db:"slashed_amount"`
}{}

queryParams := []interface{}{}
Expand All @@ -100,7 +101,8 @@ func (d *DataAccessService) GetValidatorDashboardRewards(dashboardId t.VDBId, cu
SUM(COALESCE(e.blocks_proposed, 0)) AS blocks_proposed,
SUM(COALESCE(e.sync_scheduled, 0)) AS sync_scheduled,
SUM(COALESCE(e.sync_executed, 0)) AS sync_executed,
SUM(CASE WHEN e.slashed THEN 1 ELSE 0 END) AS slashed
SUM(CASE WHEN e.slashed_by IS NOT NULL THEN 1 ELSE 0 END) AS slashed_in_epoch,
SUM(COALESCE(s.slashed_amount, 0)) AS slashed_amount
`

if dashboardId.Validators == nil {
Expand Down Expand Up @@ -182,6 +184,7 @@ func (d *DataAccessService) GetValidatorDashboardRewards(dashboardId t.VDBId, cu
%s
FROM validator_dashboard_data_epoch e
INNER JOIN users_val_dashboards_validators v ON e.validator_index = v.validator_index
LEFT JOIN validator_dashboard_data_epoch_slashedby_count s ON e.epoch = s.epoch AND e.validator_index = s.slashed_by
%s
GROUP BY e.epoch, v.group_id
%s`, rewardsDataQuery, whereQuery, orderQuery)
Expand Down Expand Up @@ -225,6 +228,7 @@ func (d *DataAccessService) GetValidatorDashboardRewards(dashboardId t.VDBId, cu
$%d::smallint AS group_id,
%s
FROM validator_dashboard_data_epoch e
LEFT JOIN validator_dashboard_data_epoch_slashedby_count s ON e.epoch = s.epoch AND e.validator_index = s.slashed_by
%s
GROUP BY e.epoch
%s`, len(queryParams), rewardsDataQuery, whereQuery, orderQuery)
Expand All @@ -248,7 +252,7 @@ func (d *DataAccessService) GetValidatorDashboardRewards(dashboardId t.VDBId, cu
BlocksProposed uint64
SyncScheduled uint64
SyncExecuted uint64
Slashed uint64
Slashings uint64
}
totalEpochInfo := make(map[uint64]*TotalEpochInfo, 0)

Expand All @@ -266,10 +270,10 @@ func (d *DataAccessService) GetValidatorDashboardRewards(dashboardId t.VDBId, cu
SyncPercentage := (float64(res.SyncExecuted) / float64(res.SyncScheduled)) * 100.0
duty.Sync = &SyncPercentage
}
// TODO: Slashing data is not yet available in the db
slashingInfo := res.Slashed /*+ "Validators slashed"*/
if slashingInfo > 0 {
duty.Slashing = &slashingInfo

slashings := res.SlashedInEpoch + res.SlashedAmount
if slashings > 0 {
duty.Slashing = &slashings
}

if duty.Attestation != nil || duty.Proposal != nil || duty.Sync != nil || duty.Slashing != nil {
Expand Down Expand Up @@ -297,7 +301,7 @@ func (d *DataAccessService) GetValidatorDashboardRewards(dashboardId t.VDBId, cu
totalEpochInfo[res.Epoch].BlocksProposed += res.BlocksProposed
totalEpochInfo[res.Epoch].SyncScheduled += res.SyncScheduled
totalEpochInfo[res.Epoch].SyncExecuted += res.SyncExecuted
totalEpochInfo[res.Epoch].Slashed += res.Slashed
totalEpochInfo[res.Epoch].Slashings += slashings
}
}

Expand All @@ -317,17 +321,17 @@ func (d *DataAccessService) GetValidatorDashboardRewards(dashboardId t.VDBId, cu
duty.Attestation = &attestationPercentage
}
if totalInfo.BlocksScheduled > 0 {
ProposalPercentage := (float64(totalInfo.BlocksProposed) / float64(totalInfo.BlocksScheduled)) * 100.0
duty.Proposal = &ProposalPercentage
proposalPercentage := (float64(totalInfo.BlocksProposed) / float64(totalInfo.BlocksScheduled)) * 100.0
duty.Proposal = &proposalPercentage
}
if totalInfo.SyncScheduled > 0 {
SyncPercentage := (float64(totalInfo.SyncExecuted) / float64(totalInfo.SyncScheduled)) * 100.0
duty.Sync = &SyncPercentage
}
// TODO: Slashing data is not yet available in the db
slashingInfo := totalInfo.Slashed /*+ "Validators slashed"*/
if slashingInfo > 0 {
duty.Slashing = &slashingInfo

if totalInfo.Slashings > 0 {
slashings := totalInfo.Slashings
duty.Slashing = &slashings
}

totalRewards[epoch] = t.VDBRewardsTableRow{
Expand Down Expand Up @@ -418,48 +422,60 @@ func (d *DataAccessService) GetValidatorDashboardGroupRewards(dashboardId t.VDBI
SyncExecuted uint32 `db:"sync_executed"`
SyncRewards decimal.Decimal `db:"sync_rewards"`

SlashedInEpoch bool `db:"slashed_in_epoch"`
SlashedAmount uint32 `db:"slashed_amount"`
SlasherRewards decimal.Decimal `db:"slasher_reward"`

BlocksClAttestationsReward decimal.Decimal `db:"blocks_cl_attestations_reward"`
BlockClSyncAggregateReward decimal.Decimal `db:"blocks_cl_sync_aggregate_reward"`
}

query := `select
COALESCE(validator_dashboard_data_epoch.attestations_source_reward, 0) as attestations_source_reward,
COALESCE(validator_dashboard_data_epoch.attestations_target_reward, 0) as attestations_target_reward,
COALESCE(validator_dashboard_data_epoch.attestations_head_reward, 0) as attestations_head_reward,
COALESCE(validator_dashboard_data_epoch.attestations_inactivity_reward, 0) as attestations_inactivity_reward,
COALESCE(validator_dashboard_data_epoch.attestations_inclusion_reward, 0) as attestations_inclusion_reward,
COALESCE(validator_dashboard_data_epoch.attestations_scheduled, 0) as attestations_scheduled,
COALESCE(validator_dashboard_data_epoch.attestation_head_executed, 0) as attestation_head_executed,
COALESCE(validator_dashboard_data_epoch.attestation_source_executed, 0) as attestation_source_executed,
COALESCE(validator_dashboard_data_epoch.attestation_target_executed, 0) as attestation_target_executed,
COALESCE(validator_dashboard_data_epoch.blocks_scheduled, 0) as blocks_scheduled,
COALESCE(validator_dashboard_data_epoch.blocks_proposed, 0) as blocks_proposed,
COALESCE(validator_dashboard_data_epoch.blocks_cl_reward, 0) as blocks_cl_reward,
COALESCE(validator_dashboard_data_epoch.blocks_el_reward, 0) as blocks_el_reward,
COALESCE(validator_dashboard_data_epoch.sync_scheduled, 0) as sync_scheduled,
COALESCE(validator_dashboard_data_epoch.sync_executed, 0) as sync_executed,
COALESCE(validator_dashboard_data_epoch.sync_rewards, 0) as sync_rewards,
COALESCE(validator_dashboard_data_epoch.slasher_reward, 0) as slasher_reward,
COALESCE(validator_dashboard_data_epoch.blocks_cl_attestations_reward, 0) as blocks_cl_attestations_reward,
COALESCE(validator_dashboard_data_epoch.blocks_cl_sync_aggregate_reward, 0) as blocks_cl_sync_aggregate_reward
query := `SELECT
COALESCE(e.attestations_source_reward, 0) AS attestations_source_reward,
COALESCE(e.attestations_target_reward, 0) AS attestations_target_reward,
COALESCE(e.attestations_head_reward, 0) AS attestations_head_reward,
COALESCE(e.attestations_inactivity_reward, 0) AS attestations_inactivity_reward,
COALESCE(e.attestations_inclusion_reward, 0) AS attestations_inclusion_reward,
COALESCE(e.attestations_scheduled, 0) AS attestations_scheduled,
COALESCE(e.attestation_head_executed, 0) AS attestation_head_executed,
COALESCE(e.attestation_source_executed, 0) AS attestation_source_executed,
COALESCE(e.attestation_target_executed, 0) AS attestation_target_executed,
COALESCE(e.blocks_scheduled, 0) AS blocks_scheduled,
COALESCE(e.blocks_proposed, 0) AS blocks_proposed,
COALESCE(e.blocks_cl_reward, 0) AS blocks_cl_reward,
COALESCE(e.blocks_el_reward, 0) AS blocks_el_reward,
COALESCE(e.sync_scheduled, 0) AS sync_scheduled,
COALESCE(e.sync_executed, 0) AS sync_executed,
COALESCE(e.sync_rewards, 0) AS sync_rewards,
e.slashed_by IS NOT NULL AS slashed_in_epoch,
COALESCE(s.slashed_amount, 0) AS slashed_amount,
COALESCE(e.slasher_reward, 0) AS slasher_reward,
COALESCE(e.blocks_cl_attestations_reward, 0) AS blocks_cl_attestations_reward,
COALESCE(e.blocks_cl_sync_aggregate_reward, 0) AS blocks_cl_sync_aggregate_reward
`

var rows []*queryResult

// handle the case when we have a list of validators
if len(dashboardId.Validators) > 0 {
whereClause := "from validator_dashboard_data_epoch where validator_index = any($1) and epoch = $2"
whereClause := `
FROM validator_dashboard_data_epoch e
LEFT JOIN validator_dashboard_data_epoch_slashedby_count s ON e.epoch = s.epoch AND e.validator_index = s.slashed_by
WHERE e.validator_index = any($1) AND e.epoch = $2
`
query = fmt.Sprintf("%s %s", query, whereClause)
err := d.alloyReader.Select(&rows, query, pq.Array(dashboardId.Validators), epoch)
if err != nil {
log.Error(err, "error while getting validator dashboard group rewards", 0)
return nil, err
}
} else { // handle the case when we have a dashboard id and an optional group id
joinAndWhereClause := `from users_val_dashboards_validators inner join validator_dashboard_data_epoch on validator_dashboard_data_epoch.validator_index = users_val_dashboards_validators.validator_index
where (dashboard_id = $1 and (group_id = $2 or $2 = -1) and epoch = $3)`
joinAndWhereClause := `
FROM users_val_dashboards_validators v
INNER JOIN validator_dashboard_data_epoch e ON e.validator_index = v.validator_index
LEFT JOIN validator_dashboard_data_epoch_slashedby_count s ON e.epoch = s.epoch AND e.validator_index = s.slashed_by
WHERE (v.dashboard_id = $1 AND (v.group_id = $2 OR $2 = -1) AND e.epoch = $3)
`
query = fmt.Sprintf("%s %s", query, joinAndWhereClause)
err := d.alloyReader.Select(&rows, query, dashboardId.Id, groupId, epoch)
if err != nil {
Expand Down Expand Up @@ -498,11 +514,15 @@ func (d *DataAccessService) GetValidatorDashboardGroupRewards(dashboardId t.VDBI
ret.Sync.StatusCount.Success += uint64(row.SyncExecuted)
ret.Sync.StatusCount.Failed += uint64(row.SyncScheduled) - uint64(row.SyncExecuted)

ret.Slashing.Income = ret.Slashing.Income.Add(row.SlasherRewards.Mul(gWei))
ret.Slashing.StatusCount.Success += uint64(row.SlashedAmount)
if row.SlashedInEpoch {
ret.Slashing.StatusCount.Failed++
}

ret.ProposalClAttIncReward = ret.ProposalClAttIncReward.Add(row.BlocksClAttestationsReward.Mul(gWei))
ret.ProposalClSyncIncReward = ret.ProposalClSyncIncReward.Add(row.BlockClSyncAggregateReward.Mul(gWei))
ret.ProposalClSlashingIncReward = ret.ProposalClSlashingIncReward.Add(row.SlasherRewards.Mul(gWei))

// TODO: Add slashing info once available
}

return ret, nil
Expand Down Expand Up @@ -683,7 +703,8 @@ func (d *DataAccessService) GetValidatorDashboardDuties(dashboardId t.VDBId, epo
SyncScheduled uint64 `db:"sync_scheduled"`
SyncExecuted uint64 `db:"sync_executed"`
SyncRewards int64 `db:"sync_rewards"`
Slashed bool `db:"slashed"`
SlashedInEpoch bool `db:"slashed_in_epoch"`
SlashedAmount uint64 `db:"slashed_amount"`
SlasherReward int64 `db:"slasher_reward"`
BlocksScheduled uint64 `db:"blocks_scheduled"`
BlocksProposed uint64 `db:"blocks_proposed"`
Expand All @@ -694,15 +715,18 @@ func (d *DataAccessService) GetValidatorDashboardDuties(dashboardId t.VDBId, epo

queryParams := []interface{}{}

joinSubquery := ""
joinSubquery := `
LEFT JOIN validator_dashboard_data_epoch_slashedby_count s ON e.epoch = s.epoch AND e.validator_index = s.slashed_by
`

queryParams = append(queryParams, epoch)
whereSubquery := fmt.Sprintf(`WHERE epoch = $%d
whereSubquery := fmt.Sprintf(`WHERE e.epoch = $%d
AND (
COALESCE(e.attestations_scheduled, 0) +
COALESCE(e.sync_scheduled,0) +
COALESCE(e.blocks_scheduled,0) +
CASE WHEN e.slashed THEN 1 ELSE 0 END
CASE WHEN e.slashed_by IS NOT NULL THEN 1 ELSE 0 END +
COALESCE(s.slashed_amount, 0)
) > 0
`, len(queryParams))
whereQuery := ""
Expand All @@ -714,7 +738,8 @@ func (d *DataAccessService) GetValidatorDashboardDuties(dashboardId t.VDBId, epo
`, len(queryParams))

if dashboardId.Validators == nil {
joinSubquery = `INNER JOIN users_val_dashboards_validators v ON e.validator_index = v.validator_index
joinSubquery += `
INNER JOIN users_val_dashboards_validators v ON e.validator_index = v.validator_index
`

queryParams = append(queryParams, dashboardId.Id)
Expand Down Expand Up @@ -797,7 +822,8 @@ func (d *DataAccessService) GetValidatorDashboardDuties(dashboardId t.VDBId, epo
COALESCE(e.sync_scheduled, 0) AS sync_scheduled,
COALESCE(e.sync_executed, 0) AS sync_executed,
COALESCE(e.sync_rewards, 0) AS sync_rewards,
COALESCE(e.slashed, false) AS slashed,
e.slashed_by IS NOT NULL AS slashed_in_epoch,
COALESCE(s.slashed_amount, 0) AS slashed_amount,
COALESCE(e.slasher_reward, 0) AS slasher_reward,
COALESCE(e.blocks_scheduled, 0) AS blocks_scheduled,
COALESCE(e.blocks_proposed, 0) AS blocks_proposed,
Expand Down Expand Up @@ -834,19 +860,18 @@ func (d *DataAccessService) GetValidatorDashboardDuties(dashboardId t.VDBId, epo
row.Duties.SyncCount = res.SyncExecuted

// Get slashing data
// TODO: Slashing data is not yet available in the db
if res.Slashed /*|| "Validators slashed" > 0*/ {
if res.SlashedInEpoch || res.SlashedAmount > 0 {
slashedEvent := t.ValidatorHistoryEvent{
Income: utils.GWeiToWei(big.NewInt(res.SlasherReward)),
}
if res.Slashed {
// if "Validators slashed" > 0 {
// slashedEvent.Status = "partial"
// }
if res.SlashedInEpoch {
if res.SlashedAmount > 0 {
slashedEvent.Status = "partial"
}
slashedEvent.Status = "failed"
} /*else if "Validators slashed" > 0 {
} else if res.SlashedAmount > 0 {
slashedEvent.Status = "success"
}*/
}
row.Duties.Slashing = &slashedEvent
}

Expand Down
Loading
Loading