Skip to content

Commit

Permalink
Merge pull request #379 from gobitfly/NOBIDS/Correct_slashed_and_slas…
Browse files Browse the repository at this point in the history
…hing_data

Used correct slashing data from db for summary and rewards
  • Loading branch information
Eisei24 authored Jun 6, 2024
2 parents 6ff3631 + 51b0ecf commit a38c887
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 74 deletions.
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

0 comments on commit a38c887

Please sign in to comment.