@@ -115,7 +115,7 @@ func (d *DataAccessService) GetValidatorDashboardBlocks(ctx context.Context, das
115115 Epoch uint64 `db:"epoch"`
116116 Slot uint64 `db:"slot"`
117117 Status uint64 `db:"status"`
118- Block sql.NullInt64 `db:"block "`
118+ Block sql.NullInt64 `db:"exec_block_number "`
119119 FeeRecipient []byte `db:"fee_recipient"`
120120 ElReward decimal.NullDecimal `db:"el_reward"`
121121 ClReward decimal.NullDecimal `db:"cl_reward"`
@@ -132,7 +132,7 @@ func (d *DataAccessService) GetValidatorDashboardBlocks(ctx context.Context, das
132132 if colSort .Desc {
133133 sortOrder = ` DESC`
134134 }
135- val := t . VDBValidator ( 0 )
135+ var val any
136136 sortColName := `slot`
137137 switch colSort .Column {
138138 case enums .VDBBlockProposer :
@@ -142,8 +142,8 @@ func (d *DataAccessService) GetValidatorDashboardBlocks(ctx context.Context, das
142142 sortColName = `status`
143143 val = currentCursor .Status
144144 case enums .VDBBlockProposerReward :
145- sortColName = `reward `
146- val = currentCursor .Reward . BigInt (). Uint64 ()
145+ sortColName = `el_reward + cl_reward `
146+ val = currentCursor .Reward
147147 }
148148 onlyPrimarySort := sortColName == `slot`
149149 if currentCursor .IsValid () {
@@ -218,78 +218,28 @@ func (d *DataAccessService) GetValidatorDashboardBlocks(ctx context.Context, das
218218 } else {
219219 log .Debugf ("duties info not available, skipping scheduled slots: %s" , err )
220220 }
221- if len (scheduledProposers ) > 0 {
222- // make sure the distinct clause filters out the correct duplicated row (e.g. block=nil)
223- orderBy += `, block`
224- }
225221 }
226222
227223 groupIdCol := "group_id"
228- // this is actually just used for sorting for "reward".. will not consider EL rewards of unfinalized blocks atm
229- reward := "reward"
230224 if dashboardId .Validators != nil {
231225 groupIdCol = fmt .Sprintf ("%d AS %s" , t .DefaultGroupId , groupIdCol )
232- reward = "coalesce(rb.value / 1e18, ep.fee_recipient_reward) AS " + reward
233226 }
234227 selectFields := fmt .Sprintf (`
235- r.proposer,
228+ blocks.proposer,
229+ blocks.epoch,
230+ blocks.slot,
236231 %s,
237- r.epoch,
238- r.slot,
239- r.status,
240- block,
232+ blocks.status,
233+ exec_block_number,
241234 COALESCE(rb.proposer_fee_recipient, blocks.exec_fee_recipient) AS fee_recipient,
242235 COALESCE(rb.value / 1e18, ep.fee_recipient_reward) AS el_reward,
243236 cp.cl_attestations_reward / 1e9 + cp.cl_sync_aggregate_reward / 1e9 + cp.cl_slashing_inclusion_reward / 1e9 as cl_reward,
244- r.graffiti_text` , groupIdCol )
245- query := fmt .Sprintf (`SELECT distinct on (slot)
246- %s
247- FROM ( SELECT * FROM (` , selectFields )
248- // supply scheduled proposals, if any
249- if len (scheduledProposers ) > 0 {
250- // distinct to filter out duplicates in an edge case (if dutiesInfo didn't update yet after a block was proposed, but the blocks table was)
251- // might be possible to remove this once the TODO in service_slot_viz.go:startSlotVizDataService is resolved
252- distinct := "slot"
253- if ! onlyPrimarySort {
254- distinct = sortColName + ", " + distinct
255- }
256- params = append (params , scheduledProposers )
257- params = append (params , scheduledEpochs )
258- params = append (params , scheduledSlots )
259- query = fmt .Sprintf (`SELECT distinct on (%s)
237+ blocks.graffiti_text` , groupIdCol )
238+ cte := fmt .Sprintf (`WITH past_blocks AS (SELECT
260239 %s
261- FROM ( SELECT * FROM (WITH scheduled_proposals (
262- proposer,
263- epoch,
264- slot,
265- status,
266- block,
267- reward,
268- graffiti_text
269- ) AS (SELECT
270- *,
271- '0',
272- null::int,
273- null::int,
274- ''
275- FROM unnest($%d::int[], $%d::int[], $%d::int[]))
276- SELECT * FROM scheduled_proposals
277- UNION
278- (` , distinct , selectFields , len (params )- 2 , len (params )- 1 , len (params ))
279- }
280- query += fmt .Sprintf (`
281- SELECT
282- proposer,
283- epoch,
284- blocks.slot,
285- status,
286- exec_block_number AS block,
287- %s,
288- graffiti_text
289- FROM blocks
290- ` , reward )
291-
292- if dashboardId .Validators == nil {
240+ FROM blocks
241+ ` , selectFields )
242+ /*if dashboardId.Validators == nil {
293243 query += `
294244 LEFT JOIN cached_proposal_rewards ON cached_proposal_rewards.dashboard_id = $1 AND blocks.slot = cached_proposal_rewards.slot
295245 `
@@ -304,32 +254,97 @@ func (d *DataAccessService) GetValidatorDashboardBlocks(ctx context.Context, das
304254 if len(scheduledProposers) > 0 {
305255 query += `)`
306256 }
307- query += `) as u `
257+ query += `) as u `*/
308258 if dashboardId .Validators == nil {
309- query += fmt .Sprintf (`
259+ cte += fmt .Sprintf (`
310260 INNER JOIN (%s) validators ON validators.validator_index = proposer
311261 ` , filteredValidatorsQuery )
312262 } else {
313- query += `WHERE proposer = ANY($1) `
263+ if len (where ) == 0 {
264+ where += `WHERE `
265+ } else {
266+ where += `AND `
267+ }
268+ where += `proposer = ANY($1) `
314269 }
315270
316271 params = append (params , limit + 1 )
317272 limitStr := fmt .Sprintf (`
318273 LIMIT $%d
319274 ` , len (params ))
320- rewardsStr := `) r
321- LEFT JOIN consensus_payloads cp on r.slot = cp.slot
322- LEFT JOIN blocks on r .slot = blocks .slot
275+ // relay bribe deduplication; select most likely (=max) relay bribe value for each block
276+ cte += `
277+ LEFT JOIN consensus_payloads cp on blocks .slot = cp .slot
323278 LEFT JOIN execution_payloads ep ON ep.block_hash = blocks.exec_block_hash
324- LEFT JOIN relays_blocks rb ON rb.exec_block_hash = blocks.exec_block_hash
279+ LEFT JOIN LATERAL (SELECT exec_block_hash, proposer_fee_recipient, max(value) as value
280+ FROM relays_blocks
281+ WHERE relays_blocks.exec_block_hash = blocks.exec_block_hash
282+ GROUP BY exec_block_hash, proposer_fee_recipient
283+ ) rb ON rb.exec_block_hash = blocks.exec_block_hash
284+ )
325285 `
326- // relay bribe deduplication; select most likely (=max) relay bribe value for each block
327- relayOrder := ``
328- if colSort .Column != enums .VDBBlockProposerReward {
329- relayOrder += `, rb.value ` + secSort
286+
287+ distinct := ""
288+ if ! onlyPrimarySort {
289+ distinct = sortColName
290+ }
291+ from := `past_blocks `
292+ selectStr := `SELECT * FROM ` + from
293+ if len (distinct ) > 0 {
294+ selectStr = `SELECT DISTINCT ON (` + distinct + `) * FROM ` + from
295+ }
296+
297+ query := selectStr + from + where + orderBy + limitStr
298+ // supply scheduled proposals, if any
299+ if len (scheduledProposers ) > 0 {
300+ // distinct to filter out duplicates in an edge case (if dutiesInfo didn't update yet after a block was proposed, but the blocks table was)
301+ // might be possible to remove this once the TODO in service_slot_viz.go:startSlotVizDataService is resolved
302+ params = append (params , scheduledProposers )
303+ params = append (params , scheduledEpochs )
304+ params = append (params , scheduledSlots )
305+ cte += fmt .Sprintf (`,
306+ scheduled_blocks as (
307+ SELECT
308+ prov.proposer,
309+ prov.epoch,
310+ prov.slot,
311+ %s,
312+ '0'::text AS status,
313+ NULL::int AS exec_block_number,
314+ ''::bytea AS fee_recipient,
315+ NULL::float AS el_reward,
316+ NULL::float AS cl_reward,
317+ ''::text AS graffiti_text
318+ FROM unnest($%d::int[], $%d::int[], $%d::int[]) AS prov(proposer, epoch, slot)
319+ ` , groupIdCol , len (params )- 2 , len (params )- 1 , len (params ))
320+ if dashboardId .Validators == nil {
321+ // add group id
322+ cte += fmt .Sprintf (`INNER JOIN users_val_dashboards_validators validators
323+ ON validators.dashboard_id = $1
324+ AND validators.validator_index = ANY($%d::int[])
325+ ` , len (params )- 2 )
326+ }
327+ cte += `) `
328+ if len (distinct ) != 0 {
329+ distinct += ", "
330+ }
331+ // keep all ordering, sorting etc
332+ distinct += "slot"
333+ selectStr = `SELECT DISTINCT ON (` + distinct + `) * FROM `
334+ // encapsulate past blocks query to ensure performance
335+ from = `(
336+ ( ` + query + ` )
337+ UNION ALL
338+ SELECT * FROM scheduled_blocks
339+ ) as combined
340+ `
341+ // make sure the distinct clause filters out the correct duplicated row (e.g. block=nil)
342+ orderBy += `, exec_block_number NULLS LAST`
343+ query = selectStr + from + where + orderBy + limitStr
330344 }
345+
331346 startTime := time .Now ()
332- err = d .alloyReader .SelectContext (ctx , & proposals , query + where + orderBy + limitStr + rewardsStr + orderBy + relayOrder , params ... )
347+ err = d .alloyReader .SelectContext (ctx , & proposals , cte + query , params ... )
333348 log .Debugf ("=== getting past blocks took %s" , time .Since (startTime ))
334349 if err != nil {
335350 return nil , nil , err
0 commit comments