Skip to content

Commit

Permalink
feat: operator-directed rewards calculation (#131)
Browse files Browse the repository at this point in the history
Rewards v2 calculation for operator directed rewards.
  • Loading branch information
seanmcgary committed Dec 12, 2024
2 parents c03dcd1 + 04e19a4 commit e90f5b5
Show file tree
Hide file tree
Showing 72 changed files with 2,077 additions and 152 deletions.
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
/*.sw*
*.terraform
*.terraform*
*.sql
*.dump
/bin
/scripts/runLocal
sidecar.db*
Expand Down Expand Up @@ -30,5 +32,4 @@ node_modules
chart_releases
/snapshots/**/*.sql
/snapshots/**/*.csv
*.sql
*.dump

2 changes: 1 addition & 1 deletion .testdataVersion
Original file line number Diff line number Diff line change
@@ -1 +1 @@
e94b8e364dfddd0743746f089f89a3d570751f03
d67ef5d895bdc0ccd6a006a1683ac3e58f820ad0
40 changes: 38 additions & 2 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"strconv"
"strings"
"time"

"github.com/spf13/viper"
)
Expand Down Expand Up @@ -254,14 +255,14 @@ func (c *Config) GetForkDates() (ForkMap, error) {
Fork_Amazon: "1970-01-01", // Amazon hard fork was never on preprod as we backfilled
Fork_Nile: "2024-08-14", // Last calculation end timestamp was 8-13: https://holesky.etherscan.io/tx/0xb5a6855e88c79312b7c0e1c9f59ae9890b97f157ea27e69e4f0fadada4712b64#eventlog
Fork_Panama: "2024-10-01",
Fork_Arno: "2024-12-04",
Fork_Arno: "2024-12-12",
}, nil
case Chain_Holesky:
return ForkMap{
Fork_Amazon: "1970-01-01", // Amazon hard fork was never on testnet as we backfilled
Fork_Nile: "2024-08-13", // Last calculation end timestamp was 8-12: https://holesky.etherscan.io/tx/0x5fc81b5ed2a78b017ef313c181d8627737a97fef87eee85acedbe39fc8708c56#eventlog
Fork_Panama: "2024-10-01",
Fork_Arno: "2024-12-10",
Fork_Arno: "2024-12-13",
}, nil
case Chain_Mainnet:
return ForkMap{
Expand Down Expand Up @@ -296,6 +297,41 @@ func (c *Config) GetOperatorRestakedStrategiesStartBlock() uint64 {
return 0
}

func (c *Config) ShouldSkipRewardsGeneration(blockNumber uint64) bool {
switch c.Chain {
case Chain_Preprod:
// During this period we deployed the rewards-v2 contracts before updating the sidecar.
// This results in missed events which have to be filled by some means. To fill them in,
// we needed to manually delete delete blocks >= 2871534 and re-index. The trouble here
// is that re-indexing introduces new state which was not present at the original process time.
if blockNumber >= 2871534 && blockNumber <= 2909856 {
return true
}
case Chain_Holesky:
// Skip rewards generation for holesky
case Chain_Mainnet:
// Skip rewards generation for mainnet
}
return false
}

func (c *Config) IsRewardsV2EnabledForCutoffDate(cutoffDate string) (bool, error) {
forks, err := c.GetForkDates()
if err != nil {
return false, err
}
cutoffDateTime, err := time.Parse(time.DateOnly, cutoffDate)
if err != nil {
return false, errors.Join(fmt.Errorf("failed to parse cutoff date %s", cutoffDate), err)
}
arnoForkDateTime, err := time.Parse(time.DateOnly, forks[Fork_Arno])
if err != nil {
return false, errors.Join(fmt.Errorf("failed to parse Arno fork date %s", forks[Fork_Arno]), err)
}

return cutoffDateTime.Compare(arnoForkDateTime) >= 0, nil
}

// CanIgnoreIncorrectRewardsRoot returns true if the rewards root can be ignored for the given block number
//
// Due to inconsistencies in the rewards root calculation on testnet, we know that some roots
Expand Down
22 changes: 21 additions & 1 deletion internal/tests/testdata/avsOperators/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,24 @@ where
address = '0x135dda560e946695d6f155dacafc6f1f25c1f5af'
and event_name = 'OperatorAVSRegistrationStatusUpdated'
and block_number < 20613003
``
```

## preprod rewardsv2


```sql
select
transaction_hash,
transaction_index,
block_number,
address,
arguments,
event_name,
log_index,
output_data
from transaction_logs
where
address = '0x141d6995556135d4997b2ff72eb443be300353bc'
and event_name = 'OperatorAVSRegistrationStatusUpdated'
and block_number < 2909490
```
20 changes: 20 additions & 0 deletions internal/tests/testdata/combinedRewards/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,23 @@ select
from dbt_mainnet_ethereum_rewards.rewards_combined
where block_time < '2024-08-20'
```

## preprod rewardsv2

```sql
select
avs,
reward_hash,
token,
amount as amount,
strategy,
strategy_index,
multiplier as multiplier,
start_timestamp::timestamp(6) as start_timestamp,
end_timestamp::timestamp(6) as end_timestamp,
reward_type,
duration,
block_number as block_number
from dbt_preprod_holesky_rewards.rewards_combined
where block_time < '2024-12-10'
```
14 changes: 11 additions & 3 deletions internal/tests/testdata/fetchExpectedResults.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,28 @@ NETWORK=$1
sqlFileName="generateExpectedResults.sql"
outputFile="expectedResults.csv"

postgresPort=5432

if [[ -z $NETWORK ]]; then
echo "Usage: $0 <network>"
exit 1
fi

if [[ $NETWORK == "mainnet-reduced" ]]; then
sqlFileName="mainnetReduced_${sqlFileName}"
postgresPort=5434
fi

if [[ $NETWORK == "testnet-reduced" ]]; then
sqlFileName="testnetReduced_${sqlFileName}"
fi

for d in operatorShares; do
if [[ $NETWORK == "preprod-rewardsV2" ]]; then
sqlFileName="preprodRewardsV2_${sqlFileName}"
postgresPort=5435
fi

for d in stakerShareSnapshots; do
echo "Processing directory: $d"
if [[ $d == "7_goldStaging" ]]; then
files=$(ls "./${d}" | grep "_generateExpectedResults_")
Expand All @@ -30,12 +38,12 @@ for d in operatorShares; do
sqlFileWithPath="${d}/$f"
outputFileWithPath="${d}/expectedResults_${snapshotDate}.csv"
echo "Generating expected results for ${sqlFileWithPath} to ${outputFileWithPath}"
psql --host localhost --port 5434 --user blocklake --dbname blocklake --password < $sqlFileWithPath > $outputFileWithPath
psql --host localhost --port $postgresPort --user blocklake --dbname blocklake --password < $sqlFileWithPath > $outputFileWithPath
done
else
echo "Generating expected results for $d"
sqlFileWithPath="${d}/${sqlFileName}"
outputFileWithPath="${d}/${outputFile}"
psql --host localhost --port 5434 --user blocklake --dbname blocklake --password < $sqlFileWithPath > $outputFileWithPath
psql --host localhost --port $postgresPort --user blocklake --dbname blocklake --password < $sqlFileWithPath > $outputFileWithPath
fi
done
28 changes: 28 additions & 0 deletions internal/tests/testdata/operatorAvsRegistrationSnapshots/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,34 @@ select
from filtered
```

preprod rewardsv2

```sql
with filtered as (
SELECT
lower(t.arguments #>> '{0,Value}') as operator,
lower(t.arguments #>> '{1,Value}') as avs,
case when (t.output_data ->> 'status')::integer = 1 then true else false end as status,
t.transaction_hash,
t.log_index,
b.block_time::timestamp(6),
to_char(b.block_time, 'YYYY-MM-DD') AS block_date,
t.block_number
FROM transaction_logs t
LEFT JOIN blocks b ON t.block_sequence_id = b.id
WHERE t.address = '0x141d6995556135d4997b2ff72eb443be300353bc'
AND t.event_name = 'OperatorAVSRegistrationStatusUpdated'
AND date_trunc('day', b.block_time) < TIMESTAMP '2024-12-10'
)
select
operator,
avs,
status as registered,
log_index,
block_number
from filtered
```

## Expected results

_See `generateExpectedResults.sql`_
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
COPY (
with filtered as (
select * from dbt_testnet_holesky_rewards.operator_avs_status
where block_time < '2024-09-17'
select * from dbt_preprod_holesky_rewards.operator_avs_status
where block_time < '2024-12-11'
),
marked_statuses AS (
SELECT
Expand Down Expand Up @@ -34,7 +34,7 @@ marked_statuses AS (
operator,
avs,
block_time AS start_time,
COALESCE(next_block_time, TIMESTAMP '2024-09-01') AS end_time,
COALESCE(next_block_time, TIMESTAMP '2024-12-11') AS end_time,
registered
FROM removed_same_day_deregistrations
WHERE registered = TRUE
Expand All @@ -59,9 +59,9 @@ marked_statuses AS (
SELECT
operator,
avs,
day AS snapshot
to_char(d, 'YYYY-MM-DD') AS snapshot
FROM cleaned_records
CROSS JOIN generate_series(DATE(start_time), DATE(end_time) - interval '1' day, interval '1' day) AS day
CROSS JOIN generate_series(DATE(start_time), DATE(end_time) - interval '1' day, interval '1' day) AS d
)
select * from final_results
) TO STDOUT WITH DELIMITER ',' CSV HEADER;
18 changes: 18 additions & 0 deletions internal/tests/testdata/operatorAvsSplitSnapshots/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
## preprod rewardsv2

```sql
select
lower(arguments #>> '{1, Value}') as operator,
lower(arguments #>> '{2, Value}') as avs,
to_timestamp((output_data ->> 'activatedAt')::integer)::timestamp(6) as activated_at,
output_data ->> 'oldOperatorAVSSplitBips' as old_operator_avs_split_bips,
output_data ->> 'newOperatorAVSSplitBips' as new_operator_avs_split_bips,
block_number,
transaction_hash,
log_index
from transaction_logs
where
address = '0xb22ef643e1e067c994019a4c19e403253c05c2b0'
and event_name = 'OperatorAVSSplitBipsSet'
order by block_number desc
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
## preprod rewards-v2

```sql
WITH strategies AS (
SELECT
tl.*,
output_data->'operatorDirectedRewardsSubmission'->>'token' as token,
output_data->'operatorDirectedRewardsSubmission'->>'duration' as duration,
output_data->'operatorDirectedRewardsSubmission'->>'startTimestamp' as start_timestamp,
strategy_data,
strategy_idx - 1 as strategy_idx -- Subtract 1 for 0-based indexing
FROM transaction_logs as tl,
jsonb_array_elements(output_data->'operatorDirectedRewardsSubmission'->'strategiesAndMultipliers')
WITH ORDINALITY AS t(strategy_data, strategy_idx)
where
address = '0xb22ef643e1e067c994019a4c19e403253c05c2b0'
and event_name = 'OperatorDirectedAVSRewardsSubmissionCreated'
),
operators AS (
SELECT
operator_data,
output_data->'operatorDirectedRewardsSubmission' as rewards_submission,
operator_idx - 1 as operator_idx -- Subtract 1 to make it 0-based indexing
FROM transaction_logs,
jsonb_array_elements(output_data->'operatorDirectedRewardsSubmission'->'operatorRewards')
WITH ORDINALITY AS t(operator_data, operator_idx)
where
address = '0xb22ef643e1e067c994019a4c19e403253c05c2b0'
and event_name = 'OperatorDirectedAVSRewardsSubmissionCreated'
)
SELECT
lower(arguments #>> '{1, Value}') as avs,
lower(arguments #>> '{2, Value}') as reward_hash,
strategies.token,
operator_data->>'operator' as operator,
operator_idx as operator_index,
operator_data->>'amount' as amount,
strategy_data->>'strategy' as strategy,
strategy_idx as strategy_index,
strategy_data->>'multiplier' as multiplier,
(to_timestamp((rewards_submission->>'startTimestamp')::int))::timestamp(6) as start_timestamp,
(rewards_submission->>'duration')::int as duration,
to_timestamp((rewards_submission->>'startTimestamp')::int + (rewards_submission->>'duration')::int)::timestamp(6) as end_timestamp,
block_number,
transaction_hash,
log_index
FROM strategies
CROSS JOIN operators;
```
17 changes: 17 additions & 0 deletions internal/tests/testdata/operatorPISplitSnapshots/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@

## preprod rewardsV2
```sql
select
lower(arguments #>> '{1, Value}') as operator,
to_timestamp((output_data ->> 'activatedAt')::integer)::timestamp(6) as activated_at,
output_data ->> 'oldOperatorPISplitBips' as old_operator_pi_split_bips,
output_data ->> 'newOperatorPISplitBips' as new_operator_pi_split_bips,
block_number,
transaction_hash,
log_index
from transaction_logs
where
address = '0xb22ef643e1e067c994019a4c19e403253c05c2b0'
and event_name = 'OperatorPISplitBipsSet'
order by block_number desc
```
15 changes: 15 additions & 0 deletions internal/tests/testdata/operatorRestakedStrategies/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,21 @@ where avs_directory_address = '0x135dda560e946695d6f155dacafc6f1f25c1f5af'
and block_time < '2024-08-20'
```

preprod rewardsV2

```sql
select
block_number,
operator,
avs,
strategy,
block_time::timestamp(6),
avs_directory_address
from operator_restaked_strategies
where avs_directory_address = '0x141d6995556135d4997b2ff72eb443be300353bc'
and block_time < '2024-12-10'
```

## Expected results

_See `generateExpectedResults.sql`_
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ copy (with ranked_records AS (
ORDER BY block_time DESC
) AS rn
FROM public.operator_restaked_strategies
WHERE avs_directory_address = lower('0x055733000064333caddbc92763c58bf0192ffebf')
and block_time < '2024-09-17'
WHERE avs_directory_address = lower('0x141d6995556135d4997b2ff72eb443be300353bc')
and block_time < '2024-12-11'
),
latest_records AS (
SELECT
Expand Down Expand Up @@ -102,11 +102,11 @@ SELECT
operator,
avs,
strategy,
cast(day AS DATE) AS snapshot
to_char(d, 'YYYY-MM-DD') AS snapshot
FROM
cleaned_records
CROSS JOIN
generate_series(DATE(start_time), DATE(end_time) - interval '1' day, interval '1' day) AS day
generate_series(DATE(start_time), DATE(end_time) - interval '1' day, interval '1' day) AS d
)
select * from final_results
) to STDOUT DELIMITER ',' CSV HEADER;
9 changes: 9 additions & 0 deletions internal/tests/testdata/operatorShareSnapshots/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ from dbt_mainnet_ethereum_rewards.operator_shares
where block_time < '2024-08-20'
```

preprod-rewardsV2

```sql
select
*
from dbt_preprod_holesky_rewards.operator_shares
where block_time < '2024-12-10'
```

## Expected results

_See `generateExpectedResults.sql`_
Expand Down
Loading

0 comments on commit e90f5b5

Please sign in to comment.