From 718dd26043eb3a4d4ebef20157d3b0ec5c8d41c9 Mon Sep 17 00:00:00 2001 From: Mike Greenberg Date: Fri, 24 Jul 2020 16:11:16 -0400 Subject: [PATCH 1/2] fix(chainwatch): Move scheduler-specific schema; Add max_height view --- cmd/lotus-chainwatch/processor/reward.go | 19 ------- .../refresh_top_miners_by_base_reward.go | 57 ++++++++++++++++++- cmd/lotus-chainwatch/scheduler/scheduler.go | 13 +++++ 3 files changed, 69 insertions(+), 20 deletions(-) diff --git a/cmd/lotus-chainwatch/processor/reward.go b/cmd/lotus-chainwatch/processor/reward.go index fb628bd6f..af339b74d 100644 --- a/cmd/lotus-chainwatch/processor/reward.go +++ b/cmd/lotus-chainwatch/processor/reward.go @@ -51,30 +51,11 @@ create table if not exists chain_power primary key, baseline_power text not null ); - -create materialized view if not exists top_miners_by_base_reward as - with total_rewards_by_miner as ( - select - b.miner, - sum(bbr.base_block_reward) as total_reward - from blocks b - inner join base_block_rewards bbr on b.parentstateroot = bbr.state_root - group by 1 - ) select - rank() over (order by total_reward desc), - miner, - total_reward - from total_rewards_by_miner - group by 2, 3; - -create index if not exists top_miners_by_base_reward_miner_index - on top_miners_by_base_reward (miner); `); err != nil { return err } return tx.Commit() - } func (p *Processor) HandleRewardChanges(ctx context.Context, rewardTips ActorTips) error { diff --git a/cmd/lotus-chainwatch/scheduler/refresh_top_miners_by_base_reward.go b/cmd/lotus-chainwatch/scheduler/refresh_top_miners_by_base_reward.go index 50bb561a1..28e164f34 100644 --- a/cmd/lotus-chainwatch/scheduler/refresh_top_miners_by_base_reward.go +++ b/cmd/lotus-chainwatch/scheduler/refresh_top_miners_by_base_reward.go @@ -8,6 +8,56 @@ import ( "golang.org/x/xerrors" ) +func setupTopMinerByBaseRewardSchema(ctx context.Context, db *sql.DB) error { + select { + case <-ctx.Done(): + return nil + default: + } + + tx, err := db.Begin() + if err != nil { + return err + } + if _, err := tx.Exec(` + create materialized view if not exists top_miners_by_base_reward as + with total_rewards_by_miner as ( + select + b.miner, + sum(bbr.base_block_reward) as total_reward + from blocks b + inner join base_block_rewards bbr on b.parentstateroot = bbr.state_root + group by 1 + ) select + rank() over (order by total_reward desc), + miner, + total_reward + from total_rewards_by_miner + group by 2, 3; + + create index if not exists top_miners_by_base_reward_miner_index + on top_miners_by_base_reward (miner); + + create materialized view if not exists top_miners_by_base_reward_max_height as + select + b."timestamp"as current_timestamp, + max(b.height) as current_height + from blocks b + join base_block_rewards bbr on b.parentstateroot = bbr.state_root + where bbr.base_block_reward is not null + group by 1 + order by 1 desc + limit 1; + `); err != nil { + return xerrors.Errorf("create top_miner_by_base_reward views", err) + } + + if err := tx.Commit(); err != nil { + return xerrors.Errorf("commiting top_miner_by_base_reward views", err) + } + return nil +} + func refreshTopMinerByBaseReward(ctx context.Context, db *sql.DB) error { select { case <-ctx.Done(): @@ -20,10 +70,15 @@ func refreshTopMinerByBaseReward(ctx context.Context, db *sql.DB) error { log.Debugw("refresh top_miners_by_base_reward", "duration", time.Since(t).String()) }() - _, err := db.Exec("REFRESH MATERIALIZED VIEW top_miners_by_base_reward;") + _, err := db.Exec("refresh materialized view top_miners_by_base_reward;") if err != nil { return xerrors.Errorf("refresh top_miners_by_base_reward: %w", err) } + _, err = db.Exec("refresh materialized view top_miners_by_base_reward_max_height;") + if err != nil { + return xerrors.Errorf("refresh top_miners_by_base_reward_max_height: %w", err) + } + return nil } diff --git a/cmd/lotus-chainwatch/scheduler/scheduler.go b/cmd/lotus-chainwatch/scheduler/scheduler.go index c5c93c310..54cc30929 100644 --- a/cmd/lotus-chainwatch/scheduler/scheduler.go +++ b/cmd/lotus-chainwatch/scheduler/scheduler.go @@ -6,6 +6,8 @@ import ( "time" logging "github.com/ipfs/go-log/v2" + + "golang.org/x/xerrors" ) var log = logging.Logger("scheduler") @@ -21,10 +23,21 @@ func PrepareScheduler(db *sql.DB) *Scheduler { return &Scheduler{db} } +func (s *Scheduler) setupSchema(ctx context.Context) error { + if err := setupTopMinerByBaseRewardSchema(ctx, s.db); err != nil { + return xerrors.Errorf("setup top miners by reward schema", err) + } + return nil +} + // Start the scheduler jobs at the defined intervals func (s *Scheduler) Start(ctx context.Context) { log.Debug("Starting Scheduler") + if err := s.setupSchema(ctx); err != nil { + log.Fatalw("applying scheduling schema", err) + } + go func() { // run once on start after schema has initialized time.Sleep(5 * time.Second) From c6e0a69bbc92c19d6825444ba1f8ab5c1040acf0 Mon Sep 17 00:00:00 2001 From: Mike Greenberg Date: Fri, 24 Jul 2020 16:19:22 -0400 Subject: [PATCH 2/2] fix(chainwatch): Consider win_count in top_miner_by_base_reward view --- .../scheduler/refresh_top_miners_by_base_reward.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/lotus-chainwatch/scheduler/refresh_top_miners_by_base_reward.go b/cmd/lotus-chainwatch/scheduler/refresh_top_miners_by_base_reward.go index 28e164f34..550f7a2bd 100644 --- a/cmd/lotus-chainwatch/scheduler/refresh_top_miners_by_base_reward.go +++ b/cmd/lotus-chainwatch/scheduler/refresh_top_miners_by_base_reward.go @@ -24,7 +24,7 @@ func setupTopMinerByBaseRewardSchema(ctx context.Context, db *sql.DB) error { with total_rewards_by_miner as ( select b.miner, - sum(bbr.base_block_reward) as total_reward + sum(bbr.base_block_reward * b.win_count) as total_reward from blocks b inner join base_block_rewards bbr on b.parentstateroot = bbr.state_root group by 1