Skip to content

Commit 38754b6

Browse files
committed
Add migration to update validator stats view
1 parent 7ae0a61 commit 38754b6

File tree

1 file changed

+143
-0
lines changed

1 file changed

+143
-0
lines changed
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
package post_sync_migrations
2+
3+
import (
4+
"context"
5+
6+
"github.com/uptrace/bun"
7+
)
8+
9+
func init() {
10+
Migrations.MustRegister(func(ctx context.Context, db *bun.DB) error {
11+
_, err := db.Exec(`
12+
CREATE OR REPLACE VIEW snapshot_validator as
13+
select *,
14+
rank() over (partition by snapshot_at_epoch_number order by total_stake_amount_nanos desc, badger_key desc) -
15+
1 as validator_rank
16+
from snapshot_validator_entry;
17+
18+
CREATE OR REPLACE VIEW epoch_details_for_block as
19+
select block_hash, epoch_number, bls.pkid as proposer_pkid, epoch_entry.snapshot_at_epoch_number, height
20+
from block
21+
left join epoch_entry
22+
on block.height between epoch_entry.initial_block_height and epoch_entry.final_block_height
23+
left join bls_public_key_pkid_pair_snapshot_entry bls
24+
on bls.snapshot_at_epoch_number = epoch_entry.snapshot_at_epoch_number and
25+
block.proposer_voting_public_key = bls.bls_public_key;
26+
CREATE UNIQUE INDEX epoch_details_for_block_unique_index ON epoch_details_for_block (block_hash, epoch_number);
27+
28+
CREATE OR REPLACE VIEW block_validator_signers as
29+
select sv.*, edfb.block_hash, edfb.height
30+
from epoch_details_for_block edfb
31+
join snapshot_validator sv on edfb.snapshot_at_epoch_number = sv.snapshot_at_epoch_number
32+
join block_signer bs on bs.block_hash = edfb.block_hash and bs.signer_index = sv.validator_rank-1;
33+
34+
comment on table snapshot_validator_entry is E'@omit';
35+
36+
comment on column snapshot_validator.badger_key is E'@omit';
37+
38+
comment on view snapshot_validator is E'@foreignKey (validator_pkid) references validator_entry (validator_pkid)|@foreignFieldName snapshotValidatorEntries|@fieldName validatorEntry';
39+
comment on view block_validator_signers is E'@foreignKey (block_hash) references block (block_hash)|@foreignFieldName snapshotValidatorSigners|@fieldName block\n@foreignKey (validator_pkid) references validator_entry (validator_pkid)|@foreignFieldName signedBlocks|@fieldName validatorEntry';
40+
41+
DROP MATERIALIZED VIEW IF EXISTS validator_stats;
42+
43+
create materialized view validator_stats as
44+
select validator_entry.validator_pkid,
45+
rank()
46+
OVER ( order by (case when validator_entry.jailed_at_epoch_number = 0 then 0 else 1 end), validator_entry.total_stake_amount_nanos desc, validator_entry.jailed_at_epoch_number desc, validator_entry.validator_pkid) as validator_rank,
47+
validator_entry.total_stake_amount_nanos::float /
48+
coalesce(nullif(staking_summary.global_stake_amount_nanos::float, 0),
49+
1) as percent_total_stake,
50+
coalesce(time_in_jail, 0) +
51+
(case
52+
when jailed_at_epoch_number = 0 then 0
53+
else (staking_summary.current_epoch_number - jailed_at_epoch_number) END) epochs_in_jail,
54+
coalesce(leader_schedule_summary.num_epochs_in_leader_schedule, 0) as num_epochs_in_leader_schedule,
55+
coalesce(leader_schedule_summary.num_epochs_in_leader_schedule, 0)::float /
56+
coalesce(nullif(staking_summary.num_epochs_in_leader_schedule::float, 0),
57+
1) as percent_epochs_in_leader_schedule,
58+
coalesce(total_rewards, 0) as total_stake_reward_nanos,
59+
latest_block_signed.height as latest_block_signed
60+
from staking_summary,
61+
validator_entry
62+
left join (select validator_pkid, sum(jhe.unjailed_at_epoch_number - jhe.jailed_at_epoch_number) time_in_jail
63+
from jailed_history_event jhe
64+
group by validator_pkid) jhe
65+
on jhe.validator_pkid = validator_entry.validator_pkid
66+
left join (select validator_pkid, count(*) as num_epochs_in_leader_schedule
67+
from leader_schedule_entry
68+
group by validator_pkid) leader_schedule_summary
69+
on leader_schedule_summary.validator_pkid = validator_entry.validator_pkid
70+
left join (select validator_pkid, sum(reward_nanos) as total_rewards
71+
from stake_reward
72+
group by validator_pkid) as total_stake_rewards
73+
on total_stake_rewards.validator_pkid = validator_entry.validator_pkid
74+
left join (select validator_pkid, max(height) as height
75+
from block_validator_signers bvs
76+
group by validator_pkid) as latest_block_signed
77+
on latest_block_signed.validator_pkid = validator_entry.validator_pkid;
78+
79+
CREATE UNIQUE INDEX validator_stats_unique_index ON validator_stats (validator_pkid);
80+
comment on materialized view validator_stats is E'@primaryKey validator_pkid\n@unique validator_rank\n@foreignKey (validator_pkid) references validator_entry (validator_pkid)|@foreignFieldName validatorStats|@fieldName validatorEntry';
81+
`)
82+
if err != nil {
83+
return err
84+
}
85+
86+
return nil
87+
}, func(ctx context.Context, db *bun.DB) error {
88+
_, err := db.Exec(`
89+
DROP MATERIALIZED VIEW IF EXISTS validator_stats;
90+
create materialized view validator_stats as
91+
select validator_entry.validator_pkid,
92+
rank()
93+
OVER ( order by (case when validator_entry.jailed_at_epoch_number = 0 then 0 else 1 end), validator_entry.total_stake_amount_nanos desc, validator_entry.jailed_at_epoch_number desc, validator_entry.validator_pkid) as validator_rank,
94+
validator_entry.total_stake_amount_nanos::float /
95+
coalesce(nullif(staking_summary.global_stake_amount_nanos::float, 0),
96+
1) as percent_total_stake,
97+
coalesce(time_in_jail, 0) +
98+
(case
99+
when jailed_at_epoch_number = 0 then 0
100+
else (staking_summary.current_epoch_number - jailed_at_epoch_number) END) epochs_in_jail,
101+
coalesce(leader_schedule_summary.num_epochs_in_leader_schedule, 0) as num_epochs_in_leader_schedule,
102+
coalesce(leader_schedule_summary.num_epochs_in_leader_schedule, 0)::float /
103+
coalesce(nullif(staking_summary.num_epochs_in_leader_schedule::float, 0),
104+
1) as percent_epochs_in_leader_schedule,
105+
coalesce(total_rewards, 0) as total_stake_reward_nanos
106+
from staking_summary,
107+
validator_entry
108+
left join (select validator_pkid, sum(jhe.unjailed_at_epoch_number - jhe.jailed_at_epoch_number) time_in_jail
109+
from jailed_history_event jhe
110+
group by validator_pkid) jhe
111+
on jhe.validator_pkid = validator_entry.validator_pkid
112+
left join (select validator_pkid, count(*) as num_epochs_in_leader_schedule
113+
from leader_schedule_entry
114+
group by validator_pkid) leader_schedule_summary
115+
on leader_schedule_summary.validator_pkid = validator_entry.validator_pkid
116+
left join (select validator_pkid, sum(reward_nanos) as total_rewards
117+
from stake_reward
118+
group by validator_pkid) as total_stake_rewards
119+
on total_stake_rewards.validator_pkid = validator_entry.validator_pkid;
120+
CREATE UNIQUE INDEX validator_stats_unique_index ON validator_stats (validator_pkid);
121+
comment on materialized view validator_stats is E'@primaryKey validator_pkid\n@unique validator_rank\n@foreignKey (validator_pkid) references validator_entry (validator_pkid)|@foreignFieldName validatorStats|@fieldName validatorEntry';
122+
drop view if exists block_validator_signers CASCADE;
123+
DROP VIEW IF EXISTS snapshot_validator CASCADE;
124+
CREATE OR REPLACE VIEW epoch_details_for_block as
125+
select block_hash, epoch_number, bls.pkid as proposer_pkid
126+
from block
127+
left join epoch_entry
128+
on epoch_entry.initial_block_height <= block.height and
129+
epoch_entry.final_block_height >= block.height
130+
left join bls_public_key_pkid_pair_snapshot_entry bls
131+
on bls.snapshot_at_epoch_number = epoch_entry.snapshot_at_epoch_number and
132+
block.proposer_voting_public_key = bls.bls_public_key;
133+
comment on table snapshot_validator_entry is null;
134+
135+
comment on column snapshot_validator.badger_key is null;
136+
`)
137+
if err != nil {
138+
return err
139+
}
140+
141+
return nil
142+
})
143+
}

0 commit comments

Comments
 (0)