---
# System prepended metadata

title: Grafana SQL Queries updation
tags: [mev-monitoring]

---

# MEV Monitoring - Operator

## Common dashboard settings
Replace query of the variable `Operator` in the dashboard settings with:
```sql!
select name as __text, id as __value from node_operator where (${module} = -1 or staking_module_id = ${module})
```

Add new variable `Module` for specifying staking module:
```sql!
select 'all' as __text, -1 as __value union select name as __text, id as __value from staking_module
```

## Payload source
### Payload source
```sql
select
  w.url as metric,
  count(*) as value
from
  slot_storage as s
inner join
  node_operator_version as r on r.version_id = s.operator_version_id
left join
  allowed_relay_storage as w on w.pubkey = s.relay_pubkey
where
  r.operator_id = ${operator}
  and s.block_number > 0
  and s.slot_number >= ${from_slot}
  and s.slot_number <= ${to_slot}
group by
  w.url
```

### Blocks proposed via relays / total (1d MA)
```sql
with blocks as (
  select
    floor((${genesis} + s.slot_number * ${slot_seconds}) / ($__interval_ms / 1000)) * ($__interval_ms / 1000) as time,
    count(case when s.relay_pubkey is not null then 1 else null end)::float as mev_boosted,
    count(*)::float as total
  from
    slot_storage as s
  inner join
    node_operator_version as r on r.version_id = s.operator_version_id
  where
    s.is_block_indexed = true
    and s.is_operator_indexed = true
    and s.is_payload_indexed = true
    and s.propose_status = 2
    and s.slot_number >= ${from_slot}
    and s.slot_number <= ${to_slot}
    and r.id = ${operator}
  group by
    time
  order by
    time asc
)
select
  time,
  avg(mev_boosted / total) over (
    order by time asc
    rows between (24 * 60 * 60 / ${slot_seconds}) preceding and current row
  ) as value
from blocks
order by
  time asc
```

## Proposals
### Proposals
```sql
select
  floor((${genesis} + s.slot_number * ${slot_seconds}) / ($__interval_ms / 1000)) * ($__interval_ms / 1000) as time,
  (case when s.propose_status = 2 then 'Proposed' else 'Missed' end) as metric,
  count(*) as value
from
  slot_storage as s
inner join
  node_operator_version as r on r.version_id = s.operator_version_id
where
  s.is_block_indexed = true
  and s.slot_number >= ${from_slot}
  and s.slot_number <= ${to_slot}
  and r.operator_id = ${operator}
group by
  time, metric
order by
  time asc
```

### Missed proposals (limit of 100 slots)
```sql
select
  s.slot_number as slot,
  r.name as operator_name,
  smv.name as module_name,
  w.url as payload_source,
  signed_bid_value / 1e18 as value
from
  slot_storage as s
inner join
  node_operator_version as r on r.version_id = s.operator_version_id
inner join
  staking_module_version as smv on smv.version_id = r.staking_module_version_id
left join
  allowed_relay_storage as w on w.pubkey = s.relay_pubkey
where
  r.operator_id = ${operator}
  and s.is_block_indexed = true
  and s.propose_status != 2
  and s.slot_number >= ${from_slot}
  and s.slot_number <= ${to_slot}
order by
  s.slot_number desc
limit
  ${slots_limit}
```

### Proposed blocks (limit of 100 slots)
```sql
select
  (case
    when (
      ((f.type = 2 and s.delta_balance > 0) or (i.type = 2 and s.indirect_payment_value > 0))
      and w.url is not null
    ) then 'good' 
    when (
      f.type = 2 and s.delta_balance > 0
    ) then 'warning' 
    else
      'bad'
    end
  ) as check,
  s.slot_number as slot,
  s.block_number as block,
  w.url as payload_source,
  s.fee_recipient,
  s.delta_balance / 1e18 as delta_balance,
  s.indirect_fee_recipient,
  s.indirect_payment_value / 1e18 as indirect_payment
from
  slot_storage as s
inner join
  node_operator_version as r on r.version_id = s.operator_version_id
left join
  fee_recipient_storage as f on f.address = s.fee_recipient
left join
  fee_recipient_storage as i on i.address = s.indirect_fee_recipient
left join
  allowed_relay_storage as w on w.pubkey = s.relay_pubkey
where
  s.spec != 'phase0'
  and s.spec != 'altair'
  and s.block_number > 0
  and is_payload_indexed = true
  and is_value_indexed = true
  and is_payment_indexed = true
  and r.operator_id = ${operator}
  and s.slot_number >= ${from_slot}
  and s.slot_number <= ${to_slot}
order by
  s.slot_number desc
limit
  ${slots_limit}
```

## Bids
### Bids
```sql
select
  floor((${genesis} + s.slot_number * ${slot_seconds}) / ($__interval_ms / 1000)) * ($__interval_ms / 1000) as time,
  'max' as metric,
  avg(max_bid_value) / 1e18 as value
from
  slot_storage as s
inner join
  node_operator_version as r on r.version_id = s.operator_version_id
where
  s.is_block_indexed = true
  and s.is_bids_range_indexed = true
  and s.is_operator_indexed = true
  and s.propose_status = 2
  and s.slot_number >= ${from_slot}
  and s.slot_number <= ${to_slot}
  and r.operator_id = ${operator}
group by
  time
order by
  time asc
```

# MEV Monitoring DB
## Common dashboard settings
Add new variable `Module` for specifying staking module:
```sql!
select 'all' as __text, -1 as __value union select name as __text, id as __value from staking_module
```


## Summary
### Unknown FR
```sql!
select
  count(*)
from
  slot_storage as s
left join
  fee_recipient_storage as f on f.address = s.fee_recipient
left join
  fee_recipient_storage as i on i.address = s.indirect_fee_recipient
where
  s.operator_version_id is not null
  and is_payload_indexed = true
  and s.block_number > 0
  and (f.type != 2 or f.type is null)
  and (i.type != 2 or i.type is null)
  and s.slot_number >= ${from_slot}
  and s.slot_number <= ${to_slot}
```

### No payment
```sql!
select
  count(*)
from
  slot_storage as s
left join
  fee_recipient_storage as f on f.address = s.fee_recipient
left join
  fee_recipient_storage as i on i.address = s.indirect_fee_recipient
where
  s.is_block_indexed = true
  and s.is_payload_indexed = true
  and s.is_payment_indexed = true
  and s.block_number > 0
  and s.propose_status = 2
  and (
    -- no direct payment
    (f.type = 2 and s.delta_balance = 0)
    or
    -- no indirect payment
    (i.type = 2 and (f.type = 2 or f.type is null) and (s.indirect_payment_value = 0 or s.indirect_payment_value is null))
  )
  and s.operator_version_id is not null
  and s.slot_number >= ${from_slot}
  and s.slot_number <= ${to_slot}
```

### Unknown PS

```sql!
select
  count(*)
from
  slot_storage as s
left join
  allowed_relay_storage as w
on
  w.pubkey = s.relay_pubkey
where
  s.is_block_indexed = true
  and s.is_payload_indexed = true
  and s.block_number > 0
  and w.pubkey is null
  and s.propose_status = 2
  and s.operator_version_id is not null
  and s.slot_number >= ${from_slot}
  and s.slot_number <= ${to_slot}
```

### Missed slots
```sql!
select
  count(*)
from
  slot_storage
where
  is_block_indexed = true
  and propose_status != 2
  and operator_version_id is not null
  and slot_number >= ${from_slot}
  and slot_number <= ${to_slot}
```

### Free money
```sql!
select
  sum(delta_balance) / 1e18 as free_money
from
  slot_storage as s
left join
  fee_recipient_storage as f on f.address = s.fee_recipient
left join
  fee_recipient_storage as i on i.address = s.indirect_fee_recipient
where
  s.is_operator_indexed = true
  and s.is_value_indexed = true
  and s.operator_version_id is null
  and s.block_number > 0
  and (f.type = 2 or i.type = 2)
  and s.slot_number >= ${from_slot}
  and s.slot_number <= ${to_slot}
```

## Summary. Recent issues
### Unknown fee recipient (limit of 100 slots)
```sql!
select
  s.slot_number as slot,
  s.block_number as block,
  r.name as operator_name,
  smv.name as module_name,
  s.fee_recipient,
  s.indirect_fee_recipient
from
  slot_storage as s
inner join
  node_operator_version as r on r.version_id = s.operator_version_id
inner join
  staking_module_version as smv on smv.version_id = r.staking_module_version_id
left join
  fee_recipient_storage as f on f.address = s.fee_recipient
left join
  fee_recipient_storage as i on i.address = s.indirect_fee_recipient
where
  s.is_payload_indexed = true
  and (${module} = -1 or smv.staking_module_id = ${module})
  and s.block_number > 0
  and (f.type != 2 or f.type is null)
  and (i.type != 2 or i.type is null)
  and s.slot_number >= ${from_slot}
  and s.slot_number <= ${to_slot}
order by
  s.slot_number desc
limit
  ${slots_limit}
```

### No payment (limit of 100 slots)
```sql!
select
  s.slot_number as slot,
  s.block_number as block,
  r.name as operator_name,
  smv.name as module_name,
  s.delta_balance / 1e18 as delta_balance,
  s.indirect_payment_value as indirect_payment
from
  slot_storage as s
inner join
  node_operator_version as r on r.version_id = s.operator_version_id
inner join
  staking_module_version as smv on smv.version_id = r.staking_module_version_id
left join
  fee_recipient_storage as f on f.address = s.fee_recipient
left join
  fee_recipient_storage as i on i.address = s.indirect_fee_recipient
left join
  allowed_relay_storage as w on w.pubkey = s.relay_pubkey
where
  s.is_block_indexed = true
  and (${module} = -1 or smv.staking_module_id = ${module})
  and s.is_payload_indexed = true
  and s.is_payment_indexed = true
  and s.block_number > 0
  and s.propose_status = 2
  and (
    -- no direct payment
    (f.type = 2 and s.delta_balance = 0)
    or
    -- no indirect payment
    (i.type = 2 and (f.type = 2 or f.type is null) and (s.indirect_payment_value = 0 or s.indirect_payment_value is null))
  )
  and s.slot_number >= ${from_slot}
  and s.slot_number <= ${to_slot}
order by
  s.slot_number desc
limit
  ${slots_limit}
```

### Unknown payload source (limit of 100 slots)
```sql!
select
  s.slot_number as slot,
  s.block_number as block,
  r.name as operator_name,
  smv.name as module_name,
  s.fee_recipient,
  s.delta_balance / 1e18 as delta_balance,
  s.indirect_payment_value / 1e18 as indirect_payment
from
  slot_storage as s
inner join
  node_operator_version as r on r.version_id = s.operator_version_id
inner join
  staking_module_version as smv on smv.version_id = r.staking_module_version_id
left join
  fee_recipient_storage as f on f.address = s.fee_recipient
left join
  fee_recipient_storage as i on i.address = s.indirect_fee_recipient
left join
  allowed_relay_storage as w on w.pubkey = s.relay_pubkey
where
  s.block_number > 0
  and (${module} = -1 or smv.staking_module_id = ${module})
  and is_payload_indexed = true
  and is_value_indexed = true
  and is_payment_indexed = true
  and w.pubkey is null
  and s.slot_number >= ${from_slot}
  and s.slot_number <= ${to_slot}
order by
  s.slot_number desc
limit
  ${slots_limit}
```

### Missed proposals (limit of 100 slots)
```sql!
select
  s.slot_number as slot,
  r.name as operator_name,
  smv.name as module_name,
  w.url as payload_source,
  signed_bid_value / 1e18 as value
from
  slot_storage as s
inner join
  node_operator_version as r on r.version_id = s.operator_version_id
inner join
  staking_module_version as smv on smv.version_id = r.staking_module_version_id
left join
  allowed_relay_storage as w on w.pubkey = s.relay_pubkey
where
  s.is_block_indexed = true
  and (${module} = -1 or smv.staking_module_id = ${module})
  and s.propose_status != 2
  and s.slot_number >= ${from_slot}
  and s.slot_number <= ${to_slot}
order by
  s.slot_number desc
limit
  ${slots_limit}
```

## Proposals. Lido blocks
### Summary
```sql!
select
  count(case when operator_version_id is not null then 1 end) as Lido,
  count(case when operator_version_id is null then 1 end) as Others
from
  slot_storage
where
  is_operator_indexed = true
  and propose_status = 2
  and block_number > 0
  and slot_number >= ${from_slot}
  and slot_number <= ${to_slot}
```

### Proposed blocks by Lido validators (limit of 100 slots)
```sql!
select
  (case
    when (
      ((f.type = 2 and s.delta_balance > 0) or (i.type = 2 and s.indirect_payment_value > 0))
      and w.url is not null
    ) then 'good' 
    when (
      f.type = 2 and s.delta_balance > 0
    ) then 'warning' 
    else
      'bad'
    end
  ) as check,
  s.slot_number as slot,
  s.block_number as block,
  r.name as operator_name,
  smv.name as module_name,
  w.url as payload_source,
  s.fee_recipient,
  s.delta_balance / 1e18 as delta_balance,
  s.indirect_fee_recipient,
  s.indirect_payment_value / 1e18 as indirect_payment
from
  slot_storage as s
inner join
  node_operator_version as r on r.version_id = s.operator_version_id
inner join
  staking_module_version as smv on smv.version_id = r.staking_module_version_id
left join
  fee_recipient_storage as f on f.address = s.fee_recipient
left join
  fee_recipient_storage as i on i.address = s.indirect_fee_recipient
left join
  allowed_relay_storage as w on w.pubkey = s.relay_pubkey
where
  s.spec != 'phase0'
  and s.spec != 'altair'
  and (${module} = -1 or smv.staking_module_id = ${module})
  and s.block_number > 0
  and is_payload_indexed = true
  and is_value_indexed = true
  and is_payment_indexed = true
  and s.slot_number >= ${from_slot}
  and s.slot_number <= ${to_slot}
order by
  s.slot_number desc
limit
  ${slots_limit}
```

### Proposals
```sql!
select
  floor((${genesis} + s.slot_number * ${slot_seconds}) / ($__interval_ms / 1000)) * ($__interval_ms / 1000) as time,
  r.name || ' (' || smv.name || ')' as metric,
  count(*) as value
from
  slot_storage as s
inner join
  node_operator_version as r on r.version_id = s.operator_version_id
inner join
  staking_module_version as smv on smv.version_id = r.staking_module_version_id
where
  s.is_block_indexed = true
  and (${module} = -1 or smv.staking_module_id = ${module})
  and s.propose_status = 2
  and s.slot_number >= ${from_slot}
  and s.slot_number <= ${to_slot}
group by
  time, metric
order by
  time asc
```

## Proposals. Missed by Lido validators
### Lido proposing ratio
```sql!
select
  100 * (count(*) filter (where operator_version_id is not null and propose_status = 2))
  / (greatest(1, count(*) filter (where operator_version_id is not null))) as lido
from
  slot_storage
where
  is_block_indexed = true
  and is_operator_indexed = true
  and slot_number >= ${from_slot}
  and slot_number <= ${to_slot}
```

### Other proposing ratio
```sql!
select
  100 * (count(*) filter (where operator_version_id is null and propose_status = 2))
  / (greatest(1, count(*) filter (where operator_version_id is null))) as other
from
  slot_storage
where
  is_block_indexed = true
  and is_operator_indexed = true
  and slot_number >= ${from_slot}
  and slot_number <= ${to_slot}
```

### List of missed proposals (limit of 100 slots)
```sql!
select
  s.slot_number as slot,
  r.name as operator_name,
  smv.name as module_name
from
  slot_storage as s
inner join
  node_operator_version as r on r.version_id = s.operator_version_id
inner join
  staking_module_version as smv on smv.version_id = r.staking_module_version_id
left join
  allowed_relay_storage as w on w.pubkey = s.relay_pubkey
where
  s.is_block_indexed = true
  and (${module} = -1 or smv.staking_module_id = ${module})
  and s.propose_status != 2
  and s.slot_number >= ${from_slot}
  and s.slot_number <= ${to_slot}
order by
  s.slot_number desc
limit
  ${slots_limit}
```

### Missed proposals
```sql!
select
  floor((${genesis} + s.slot_number * ${slot_seconds}) / ($__interval_ms / 1000)) * ($__interval_ms / 1000) as time,
  r.name || ' (' || smv.name || ')' as metric,
  count(*) as value
from
  slot_storage as s
inner join
  node_operator_version as r on r.version_id = s.operator_version_id
inner join
  staking_module_version as smv on smv.version_id = r.staking_module_version_id
where
  s.is_block_indexed = true
  and s.propose_status != 2
  and (${module} = -1 or smv.staking_module_id = ${module})
  and s.slot_number >= ${from_slot}
  and s.slot_number <= ${to_slot}
group by
  time, metric
order by
  time asc
```

## Fee recipients. Lido blocks
### Summary
```sql!
select
  count(*) filter (where f.type = 2 or i.type = 2) as lido,
  count(*) filter (where (f.type != 2 or f.type is null) and (i.type != 2 or i.type is null)) as unknown
from
  slot_storage as s
left join
  fee_recipient_storage as f on f.address = s.fee_recipient
left join
  fee_recipient_storage as i on i.address = s.indirect_fee_recipient
where 
  s.spec != 'phase0'
  and s.operator_version_id is not null
  and s.spec != 'altair'
  and s.block_number > 0
  and s.slot_number >= ${from_slot}
  and s.slot_number <= ${to_slot}
```

### Fee recipients in proposed blocks by operators
```sql!
select
  r.index as id,
  r.name as operator_name,
  smv.name as module_name,
  count(*) filter (where f.type = 2) as direct,
  count(*) filter (where i.type = 2) as indirect,
  count(*) filter (where (f.type != 2 or f.type is null) and (i.type != 2 or i.type is null)) as unknown
from
  slot_storage as s
inner join
  node_operator_version as r on r.version_id = s.operator_version_id
inner join
  staking_module_version as smv on smv.version_id = r.staking_module_version_id
left join
  fee_recipient_storage as f on f.address = s.fee_recipient
left join
  fee_recipient_storage as i on i.address = s.indirect_fee_recipient
where
  s.block_number > 0
  and s.slot_number >= ${from_slot}
  and s.slot_number <= ${to_slot}
  and (${module} = -1 or smv.staking_module_id = ${module})
group by
  r.index,
  r.name,
  smv.name
order by
  count(*) filter (where (f.type != 2 or f.type is null) and (i.type != 2 or i.type is null)) > 0 desc,
  count(*) filter (where f.type = 2) = 0 desc,
  count(*) filter (where i.type = 2) = 0 desc,
  r.index asc
```

### Fee recipients in proposed blocks by operators
```sql!
select
  r.index as id,
  r.name as operator_name,
  smv.name as module_name,
  count(*) filter (where f.type = 2) as direct,
  count(*) filter (where i.type = 2) as indirect,
  count(*) filter (where (f.type != 2 or f.type is null) and (i.type != 2 or i.type is null)) as unknown
from
  slot_storage as s
inner join
  node_operator_version as r on r.version_id = s.operator_version_id
inner join
  staking_module_version as smv on smv.version_id = r.staking_module_version_id
left join
  fee_recipient_storage as f on f.address = s.fee_recipient
left join
  fee_recipient_storage as i on i.address = s.indirect_fee_recipient
where
  s.block_number > 0
  and s.slot_number >= ${from_slot}
  and s.slot_number <= ${to_slot}
  and (${module} = -1 or smv.staking_module_id = ${module})
group by
  r.index,
  r.name,
  smv.name
order by
  count(*) filter (where (f.type != 2 or f.type is null) and (i.type != 2 or i.type is null)) > 0 desc,
  count(*) filter (where f.type = 2) = 0 desc,
  count(*) filter (where i.type = 2) = 0 desc,
  r.index asc
```

### Blocks with unknown fee recipient (limit of 100 slots)
```sql!
select
  s.slot_number as slot,
  s.block_number as block,
  r.name as operator_name,
  smv.name as module_name,
  s.fee_recipient,
  s.indirect_fee_recipient
from
  slot_storage as s
inner join
  node_operator_version as r on r.version_id = s.operator_version_id
inner join
  staking_module_version as smv on smv.version_id = r.staking_module_version_id
left join
  fee_recipient_storage as f on f.address = s.fee_recipient
left join
  fee_recipient_storage as i on i.address = s.indirect_fee_recipient
where
  is_payload_indexed = true
  and (${module} = -1 or smv.staking_module_id = ${module})
  and s.block_number > 0
  and (f.type != 2 or f.type is null)
  and (i.type != 2 or i.type is null)
  and s.slot_number >= ${from_slot}
  and s.slot_number <= ${to_slot}
order by
  s.slot_number desc
limit
  ${slots_limit}
```

## Fee recipients. Lido FR is used by unknown validators
### Total blocks
```sql!
select
  count(*)
from
  slot_storage as s
left join
  fee_recipient_storage as f on f.address = s.fee_recipient
left join
  fee_recipient_storage as i on i.address = s.indirect_fee_recipient
where
  s.is_operator_indexed = true
  and s.operator_version_id is not null
  and s.block_number > 0
  and (f.type = 2 or i.type = 2)
  and s.slot_number >= ${from_slot}
  and s.slot_number <= ${to_slot}
```

### Free money, ETH
```sql!
select
  sum(delta_balance) / 1e18 as free_money
from
  slot_storage as s
left join
  fee_recipient_storage as f on f.address = s.fee_recipient
left join
  fee_recipient_storage as i on i.address = s.indirect_fee_recipient
where
  s.is_operator_indexed = true
  and s.operator_version_id is not null
  and s.is_value_indexed = true
  and s.block_number > 0
  and (f.type = 2 or i.type = 2)
  and s.slot_number >= ${from_slot}
  and s.slot_number <= ${to_slot}
```

### Blocks from unknown validator (limit of 100 slots)
```sql!
select
  s.slot_number as slot,
  s.block_number as block,
  s.validator_index,
  s.pubkey as validator,
  s.delta_balance / 1e18 as delta_balance,
  s.indirect_payment_value / 1e18 as indirect_payment
from
  slot_storage as s
left join
  fee_recipient_storage as f on f.address = s.fee_recipient
left join
  fee_recipient_storage as i on i.address = s.indirect_fee_recipient
where
  s.is_operator_indexed = true
  and s.operator_version_id is not null
  and s.block_number > 0
  and (f.type = 2 or i.type = 2)
  and s.slot_number >= ${from_slot}
  and s.slot_number <= ${to_slot}
order by
  s.slot_number desc
limit
  ${slots_limit}
```

## Fee recipients. Top
### Top 10
```sql!
with top as (
  select
    case when indirect_payment_value is not null then indirect_fee_recipient else fee_recipient end as metric,
    sum(case when indirect_payment_value is not null then indirect_payment_value else delta_balance end) / 1e18 as value
  from
    slot_storage
  where
    fee_recipient is not null
    and (indirect_payment_value is not null or delta_balance >= 0)
    and slot_number >= ${from_slot}
    and slot_number <= ${to_slot}
  group by
    metric
  order by
    value desc
  limit 10
)

select * from top union all

select
  'Other' as metric,
  sum(case when indirect_payment_value is not null then indirect_payment_value else delta_balance end) / 1e18 as value
from
  slot_storage
where
  fee_recipient is not null
  and (indirect_payment_value is not null or delta_balance >= 0)
  and slot_number >= ${from_slot}
  and slot_number <= ${to_slot}
  and fee_recipient not in (select metric from top)
```

### Top 10
```sql!
select
  case when indirect_payment_value is not null then indirect_fee_recipient else fee_recipient end as recipient,
  sum(case when indirect_payment_value is not null then indirect_payment_value else delta_balance end) / 1e18 as total_rewards,
  count(*) as blocks
from
  slot_storage
where 
  fee_recipient is not null
  and (indirect_payment_value is not null or delta_balance >= 0)
  and slot_number >= ${from_slot}
  and slot_number <= ${to_slot}
group by
  recipient
order by
  total_rewards desc nulls last
limit 10
```

## Payload source. Overall statistic
### Lido
```sql!
select
  case when url is null then 'unknown' else url end as metric,
  count(*) as value
from
  slot_storage as s
left join
  allowed_relay_storage as w on w.pubkey = s.relay_pubkey
where
  s.is_payload_indexed = true
  s.operator_version_id is not null
  and s.block_number > 0
  and s.slot_number >= ${from_slot}
  and s.slot_number <= ${to_slot}
group by
  w.pubkey,
  w.url
```

### Other
```sql!
select
  case when url is null then 'unknown' else url end as metric,
  count(*) as value
from
  slot_storage as s
left join
  allowed_relay_storage as w on w.pubkey = s.relay_pubkey
where
  s.operator_version_id is null
  and s.is_payload_indexed = true
  and s.block_number > 0
  and s.slot_number >= ${from_slot}
  and s.slot_number <= ${to_slot}
group by
  w.pubkey,
  w.url
```

### Payload sources by operators
```sql!
select
  r.index as id,
  r.name as operator_name,
  smv.name as module_name,
  count(*) filter (where w.pubkey is not null) as known,
  count(*) filter (where w.pubkey is null) as unknown
from
  slot_storage as s
inner join
  node_operator_version as r on r.version_id = s.operator_version_id
inner join
  staking_module_version as smv on smv.version_id = r.staking_module_version_id
left join
  allowed_relay_storage as w on w.pubkey = s.relay_pubkey
where
  s.block_number > 0
  and (${module} = -1 or smv.staking_module_id = ${module})
  and s.slot_number >= ${from_slot}
  and s.slot_number <= ${to_slot}
group by
  r.index,
  r.name
order by
  count(*) filter (where w.pubkey is null) > 0 desc,
  count(*) filter (where w.pubkey is not null) = 0 desc,
  r.index asc
```

## Payload source. Relay usage
### Blocks proposed via relays / total (1d MA)
```sql!
with blocks as (
  select
    floor((${genesis} + s.slot_number * ${slot_seconds}) / ($__interval_ms / 1000)) * ($__interval_ms / 1000) as time,
    (case when s.operator_version_id is not null then 'lido' else 'other' end) as metric,
    
    count(case when s.relay_pubkey is not null then 1 else null end)::float as mev_boosted,
    count(*)::float as total
  from
    slot_storage as s
  where
    s.is_block_indexed = true
    and s.is_operator_indexed = true
    and s.is_payload_indexed = true
    and s.propose_status = 2
    and s.slot_number >= ${from_slot}
    and s.slot_number <= ${to_slot}
  group by
    time, metric
  order by
    time asc
)
select
  time,
  metric,
  avg(mev_boosted / total) over (
    partition by metric
    order by time asc
    rows between (24 * 60 * 60 / ${slot_seconds}) preceding and current row
  ) as value
from blocks
order by
  time asc
```

## Payload source. By operator
### Payload sources by operators
```sql!
select
  r.index as id,
  r.name as operator_name,
  smv.name as module_name,
  w.url as payload_source,
  count(*) as blocks
from
  slot_storage as s
inner join
  node_operator_version as r on r.version_id = s.operator_version_id
inner join
  staking_module_version as smv on smv.version_id = r.staking_module_version_id
left join
  allowed_relay_storage as w on w.pubkey = s.relay_pubkey
where
  delta_balance is not null
  and (${module} = -1 or smv.staking_module_id = ${module})
  and s.slot_number >= ${from_slot}
  and s.slot_number <= ${to_slot}
group by
  r.index,
  r.name,
  w.url
order by
  r.index asc
```

## Payload source. Payment mismatch
### Builder payment mismatch
```sql!
select
  slot_number as slot,
  s.block_number as block,
  r.name as operator_name,
  smv.name as module_name,
  w.url as payload_source,
  delta_balance / 1e18 as delta_balance,
  indirect_payment_value / 1e18 as indirect_payment,
  s.signed_bid_value / 1e18 as bid_value
from
  slot_storage as s
left join
  node_operator_version as r on r.version_id = s.operator_version_id
left join
  staking_module_version as smv on smv.version_id = r.staking_module_version_id
    and (${module} = -1 or smv.staking_module_id = ${module})
left join
  allowed_relay_storage as w on w.pubkey = s.relay_pubkey
where
  s.is_payment_indexed = true
  and s.is_payload_indexed = true
  and (case when indirect_payment_value is not null then indirect_payment_value else delta_balance end) != s.signed_bid_value
  and s.slot_number >= ${from_slot}
  and s.slot_number <= ${to_slot}
order by
  s.slot_number desc
limit
  ${slots_limit}
```

## Payload source. All bids
### All bids
```sql!
select
  floor((${genesis} + s.slot_number * ${slot_seconds}) / ($__interval_ms / 1000)) * ($__interval_ms / 1000) as time,
  'max' as metric,
  avg(max_bid_value) / 1e18 as value
from
  slot_storage as s
where
  s.is_block_indexed = true
  and s.is_bids_range_indexed = true
  and s.is_operator_indexed = true
  and s.propose_status = 2
  and s.slot_number >= ${from_slot}
  and s.slot_number <= ${to_slot}
group by
  time
order by
  time asc
```

### Lido
```sql!
select
  floor((${genesis} + s.slot_number * ${slot_seconds}) / ($__interval_ms / 1000)) * ($__interval_ms / 1000) as time,
  'max' as metric,
  avg(max_bid_value) / 1e18 as value
from
  slot_storage as s
where
  s.is_block_indexed = true
  and s.is_bids_range_indexed = true
  and s.is_operator_indexed = true
  and s.operator_version_id is not null
  and s.propose_status = 2
  and s.slot_number >= ${from_slot}
  and s.slot_number <= ${to_slot}
group by
  time
order by
  time asc
```

### Other
```sql!
select
  floor((${genesis} + s.slot_number * ${slot_seconds}) / ($__interval_ms / 1000)) * ($__interval_ms / 1000) as time,
  'max' as metric,
  avg(max_bid_value) / 1e18 as value
from
  slot_storage as s
where
  s.is_block_indexed = true
  and s.is_bids_range_indexed = true
  and s.is_operator_indexed = true
  and s.operator_version_id is null
  and s.propose_status = 2
  and s.slot_number >= ${from_slot}
  and s.slot_number <= ${to_slot}
group by
  time
order by
  time asc
```

## Block rewards. By operator
### Extracted rewards by node operators
```sql!
select
  r.index as id,
  r.name as operator_name,
  smv.name as module_name,
  count(*) as blocks,
  avg(case when indirect_payment_value is not null then indirect_payment_value else delta_balance end) / 1e18 as average_value,
  (percentile_cont(0.5) within group(order by (case when indirect_payment_value is not null then indirect_payment_value else delta_balance end))) / 1e18 as median_value
from
  slot_storage as s
inner join
  node_operator_version as r on r.version_id = s.operator_version_id
inner join
  staking_module_version as smv on smv.version_id = r.staking_module_version_id
left join
  fee_recipient_storage as f on f.address = s.fee_recipient
where
  delta_balance is not null
  and (indirect_payment_value is not null or delta_balance >= 0)
  and (${module} = -1 or smv.staking_module_id = ${module})
  and s.slot_number >= ${from_slot}
  and s.slot_number <= ${to_slot}
group by
  r.index,
  r.name
order by
  r.index asc
```

## Block rewards. By payload source
### Rewards by payload source
```sql!
select
  w.url as payload_source,
  count(*) as blocks,
  avg(case when indirect_payment_value is not null then indirect_payment_value else delta_balance end) / 1e18 as average_value,
  (percentile_cont(0.5) within group(order by (case when indirect_payment_value is not null then indirect_payment_value else delta_balance end))) / 1e18 as median_value
from
  slot_storage as s
left join
  node_operator_version as r on r.version_id = s.operator_version_id
left join
  node_operator as nop on nop.id = r.operator_id
    and (${module} = -1 or nop.staking_module_id = ${module})
left join
  fee_recipient_storage as f on f.address = s.fee_recipient
left join
  allowed_relay_storage as w on w.pubkey = s.relay_pubkey
where
  delta_balance is not null
  and (indirect_payment_value is not null or delta_balance >= 0)
  and s.slot_number >= ${from_slot}
  and s.slot_number <= ${to_slot}
group by
  payload_source
order by
  blocks desc
```

## Block rewards. The most valued blocks
### The most valued blocks (limit of 100 slots)
```sql!
select
  s.slot_number as slot,
  s.block_number as block,
  (case when indirect_payment_value is not null then indirect_payment_value else delta_balance end) / 1e18 as value,
  r.name as operator_name,
  smv.name as module_name
from
  slot_storage as s
left join
  node_operator_version as r on r.version_id = s.operator_version_id
left join
  node_operator as nop on nop.id = r.operator_id
    and (${module} = -1 or nop.staking_module_id = ${module})
left join
  staking_module_version as smv on smv.version_id = r.staking_module_version_id
where
  (indirect_payment_value is not null or delta_balance >= 0)
  and is_operator_indexed
  and slot_number >= ${from_slot}
  and slot_number <= ${to_slot}
order by
  value desc
limit
  ${slots_limit}
```

### The most valued Lido blocks (limit of 100 slots)
```sql!
select
  s.slot_number as slot,
  s.block_number as block,
  (case when indirect_payment_value is not null then indirect_payment_value else delta_balance end) / 1e18 as value,
  r.name as operator_name,
  smv.name as module_name
from
  slot_storage as s
inner join
  node_operator_version as r on r.version_id = s.operator_version_id
inner join
  staking_module_version as smv on smv.version_id = r.staking_module_version_id
where
  (indirect_payment_value is not null or delta_balance >= 0)
  and is_operator_indexed = true
  and operator_version_id is not null
  and slot_number >= ${from_slot}
  and slot_number <= ${to_slot}
  and (${module} = -1 or smv.staking_module_id = ${module})
order by
  value desc
limit
  ${slots_limit}
```

## Block rewards. Overall statistics
### Median, ETH
```sql!
select
  (percentile_cont(0.5) within group(order by (case when indirect_payment_value is not null then indirect_payment_value else delta_balance end))) / 1e18 as lido
from
  slot_storage
where
  is_value_indexed = true
  and delta_balance is not null
  and (indirect_payment_value is not null or delta_balance >= 0)
  and operator_version_id is not null
  and slot_number >= ${from_slot}
  and slot_number <= ${to_slot}
```

### Average, ETH
```sql!
select
  avg(case when indirect_payment_value is not null then indirect_payment_value else delta_balance end) / 1e18 as lido
from
  slot_storage
where
  is_value_indexed = true
  and delta_balance is not null
  and (indirect_payment_value is not null or delta_balance >= 0)
  and operator_version_id is not null
  and slot_number >= ${from_slot}
  and slot_number <= ${to_slot}
```

### Block rewards
```sql!
select
  floor((${genesis} + s.slot_number * ${slot_seconds}) / ($__interval_ms / 1000)) * ($__interval_ms / 1000) as time,
  (case when s.operator_version_id is not null then 'lido' else 'other' end) as metric,
  avg(case when s.indirect_payment_value is not null then s.indirect_payment_value else s.delta_balance end) / 1e18 as value
from
  slot_storage as s
left join
  node_operator_version as r on r.version_id = s.operator_version_id
left join
  node_operator as nop on nop.id = r.operator_id
    and (${module} = -1 or nop.staking_module_id = ${module})
where
  s.is_block_indexed = true
  and s.is_operator_indexed = true
  and s.is_payment_indexed = true
  and s.propose_status = 2
  and (indirect_payment_value is not null or delta_balance >= 0)
  and s.slot_number >= ${from_slot}
  and s.slot_number <= ${to_slot}
group by
  time, metric
order by
  time asc
```

## Registry
### Total validators
```sql!
select
  count(*)
from
  registry_key
where
  used = true
```

### Last update time lag
```sql!
select
  (extract(epoch from now()) - timestamp::bigint)
from
  registry_meta
limit 1
```

### Last update
```sql!
select
  timestamp::bigint * 1000
from
  registry_meta
limit 1
```

### Validators
```sql!
select
  smv.name as module_name,
  nop.index as "id",
  nop.name as operator_name,
  vals.validators
from (
	select
	  r.id as node_operator_id,
	  count(*) as validators
	from node_operator as r
	inner join node_operator_key as k 
    on r.id = k.operator_id
	inner join node_operator_key_version as okv
    on okv.key_id = k.id
	where okv.meta_version_id = (
    select version_id
    from meta_version
    where status = 1
    order by timestamp desc
    limit 1
	) and (${module} = -1 or r.staking_module_id = ${module})
	group by r.id
) as vals
  inner join node_operator as nop
    on nop.id = vals.node_operator_id
  inner join staking_module as sm
    on sm.id = nop.staking_module_id
order by nop.index asc
```
