|
| 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