-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: utilize split in existing rewards calculation (#117)
Utilize the `OperatorAVSSplit` and `OperatorPISplit` in the existing rewards v1 and Programmatic incentives calculation (instead of the hardcoded 10% split).
- Loading branch information
Showing
10 changed files
with
327 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 31 additions & 0 deletions
31
pkg/postgres/migrations/202411221331_operatorAVSSplitSnapshots/up.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package _202411221331_operatorAVSSplitSnapshots | ||
|
||
import ( | ||
"database/sql" | ||
|
||
"gorm.io/gorm" | ||
) | ||
|
||
type Migration struct { | ||
} | ||
|
||
func (m *Migration) Up(db *sql.DB, grm *gorm.DB) error { | ||
queries := []string{ | ||
`CREATE TABLE IF NOT EXISTS operator_avs_split_snapshots ( | ||
operator varchar not null, | ||
avs varchar not null, | ||
split integer not null, | ||
snapshot date not null | ||
)`, | ||
} | ||
for _, query := range queries { | ||
if _, err := db.Exec(query); err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func (m *Migration) GetName() string { | ||
return "202411221331_operatorAVSSplitSnapshots" | ||
} |
30 changes: 30 additions & 0 deletions
30
pkg/postgres/migrations/202411221331_operatorPISplitSnapshots/up.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package _202411221331_operatorPISplitSnapshots | ||
|
||
import ( | ||
"database/sql" | ||
|
||
"gorm.io/gorm" | ||
) | ||
|
||
type Migration struct { | ||
} | ||
|
||
func (m *Migration) Up(db *sql.DB, grm *gorm.DB) error { | ||
queries := []string{ | ||
`CREATE TABLE IF NOT EXISTS operator_pi_split_snapshots ( | ||
operator varchar not null, | ||
split integer not null, | ||
snapshot date not null | ||
)`, | ||
} | ||
for _, query := range queries { | ||
if _, err := db.Exec(query); err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func (m *Migration) GetName() string { | ||
return "202411221331_operatorPISplitSnapshots" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package rewards | ||
|
||
const operatorAvsSplitSnapshotQuery = ` | ||
WITH operator_avs_splits_with_block_info as ( | ||
select | ||
oas.operator, | ||
oas.avs, | ||
oas.activated_at::timestamp(6) as activated_at, | ||
oas.new_operator_avs_split_bips as split, | ||
oas.block_number, | ||
oas.log_index, | ||
b.block_time::timestamp(6) as block_time | ||
from operator_avs_splits as oas | ||
join blocks as b on (b.number = oas.block_number) | ||
where activated_at < TIMESTAMP '{{.cutoffDate}}' | ||
), | ||
-- Rank the records for each combination of (operator, avs, activation date) by activation time, block time and log index | ||
ranked_operator_avs_split_records as ( | ||
SELECT *, | ||
ROW_NUMBER() OVER (PARTITION BY operator, avs, cast(activated_at AS DATE) ORDER BY activated_at DESC, block_time DESC, log_index DESC) AS rn | ||
FROM operator_avs_splits_with_block_info | ||
), | ||
-- Get the latest record for each day & round up to the snapshot day | ||
snapshotted_records as ( | ||
SELECT | ||
operator, | ||
avs, | ||
split, | ||
block_time, | ||
date_trunc('day', activated_at) + INTERVAL '1' day AS snapshot_time | ||
from ranked_operator_avs_split_records | ||
where rn = 1 | ||
), | ||
-- Get the range for each operator, avs pairing | ||
operator_avs_split_windows as ( | ||
SELECT | ||
operator, avs, split, snapshot_time as start_time, | ||
CASE | ||
-- If the range does not have the end, use the current timestamp truncated to 0 UTC | ||
WHEN LEAD(snapshot_time) OVER (PARTITION BY operator, avs ORDER BY snapshot_time) is null THEN date_trunc('day', TIMESTAMP '{{.cutoffDate}}') | ||
ELSE LEAD(snapshot_time) OVER (PARTITION BY operator, avs ORDER BY snapshot_time) | ||
END AS end_time | ||
FROM snapshotted_records | ||
), | ||
-- Clean up any records where start_time >= end_time | ||
cleaned_records as ( | ||
SELECT * FROM operator_avs_split_windows | ||
WHERE start_time < end_time | ||
), | ||
-- Generate a snapshot for each day in the range | ||
final_results as ( | ||
SELECT | ||
operator, | ||
avs, | ||
split, | ||
d AS snapshot | ||
FROM | ||
cleaned_records | ||
CROSS JOIN | ||
generate_series(DATE(start_time), DATE(end_time) - interval '1' day, interval '1' day) AS d | ||
) | ||
select * from final_results | ||
` | ||
|
||
func (r *RewardsCalculator) GenerateAndInsertOperatorAvsSplitSnapshots(snapshotDate string) error { | ||
tableName := "operator_avs_split_snapshots" | ||
|
||
query, err := renderQueryTemplate(operatorAvsSplitSnapshotQuery, map[string]string{ | ||
"cutoffDate": snapshotDate, | ||
}) | ||
if err != nil { | ||
r.logger.Sugar().Errorw("Failed to render query template", "error", err) | ||
return err | ||
} | ||
|
||
err = r.generateAndInsertFromQuery(tableName, query, nil) | ||
if err != nil { | ||
r.logger.Sugar().Errorw("Failed to generate operator_avs_split_snapshots", "error", err) | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
func (r *RewardsCalculator) ListOperatorAvsSplitSnapshots() ([]*OperatorAVSSplitSnapshots, error) { | ||
var snapshots []*OperatorAVSSplitSnapshots | ||
res := r.grm.Model(&OperatorAVSSplitSnapshots{}).Find(&snapshots) | ||
if res.Error != nil { | ||
r.logger.Sugar().Errorw("Failed to list operator avs split snapshots", "error", res.Error) | ||
return nil, res.Error | ||
} | ||
return snapshots, nil | ||
} |
Oops, something went wrong.