Skip to content

Commit

Permalink
feat: really basic smoke test for RewardsDataService
Browse files Browse the repository at this point in the history
  • Loading branch information
seanmcgary committed Jan 24, 2025
1 parent 59dbaa3 commit 3ef0fa7
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 16 deletions.
2 changes: 1 addition & 1 deletion pkg/postgres/migrations/migrator.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ func (m *Migrator) Migrate(migration Migration) error {
m.Logger.Sugar().Debugf("Migration %s already run", name)
return nil
}
m.Logger.Sugar().Infof("Migration %s applied", name)
m.Logger.Sugar().Debugf("Migration %s applied", name)
return nil
}

Expand Down
52 changes: 38 additions & 14 deletions pkg/service/rewardsDataService/rewards.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,13 @@ type RewardAmount struct {
}

// GetTotalRewardsForEarner returns the total earned rewards for a given earner at a given block height.
func (rds *RewardsDataService) GetTotalRewardsForEarner(ctx context.Context, earner string, tokens []string, blockHeight uint64, claimable bool) ([]*RewardAmount, error) {
func (rds *RewardsDataService) GetTotalRewardsForEarner(
ctx context.Context,
earner string,
tokens []string,
blockHeight uint64,
claimable bool,
) ([]*RewardAmount, error) {
if earner == "" {
return nil, fmt.Errorf("earner is required")
}
Expand All @@ -169,14 +175,26 @@ func (rds *RewardsDataService) GetTotalRewardsForEarner(ctx context.Context, ear
return nil, err
}

if snapshot == nil {
return nil, fmt.Errorf("no distribution root found for blockHeight '%d'", blockHeight)
}

query := `
with token_snapshots as (
select
token,
amount
from gold_table as gt
where
earner = @earner
and snapshot <= @snapshot
order by snapshot desc
)
select
token,
sum(amount) as amount
from sidecar_mainnet_ethereum.gold_table as gt
where
earner = @earner
and snapshot <= @snapshot
from token_snapshots
group by 1
`
args := []interface{}{
sql.Named("earner", earner),
Expand All @@ -189,10 +207,9 @@ func (rds *RewardsDataService) GetTotalRewardsForEarner(ctx context.Context, ear
})
args = append(args, sql.Named("tokens", formattedTokens))
}
query += ` order by snapshot desc`

rewardAmounts := make([]*RewardAmount, 0)
res := rds.db.Raw(query, args...).Scan(&tokens)
res := rds.db.Raw(query, args...).Scan(&rewardAmounts)

if res.Error != nil {
return nil, res.Error
Expand All @@ -219,6 +236,9 @@ func (rds *RewardsDataService) GetClaimableRewardsForEarner(
if err != nil {
return nil, nil, err
}
if snapshot == nil {
return nil, nil, fmt.Errorf("no distribution root found for blockHeight '%d'", blockHeight)
}
query := `
with claimed_tokens as (
select
Expand Down Expand Up @@ -256,7 +276,7 @@ func (rds *RewardsDataService) GetClaimableRewardsForEarner(
`
args := []interface{}{
sql.Named("earner", earner),
sql.Named("blockHeight", blockHeight),
sql.Named("blockNumber", blockHeight),
sql.Named("snapshot", snapshot.GetSnapshotDate()),
}
if len(tokens) > 0 {
Expand Down Expand Up @@ -314,7 +334,7 @@ func (rds *RewardsDataService) findDistributionRootClosestToBlockHeight(blockHei
var root *eigenStateTypes.SubmittedDistributionRoot
res := rds.db.Raw(renderedQuery, sql.Named("blockHeight", blockHeight)).Scan(&root)
if res.Error != nil && !errors.Is(res.Error, gorm.ErrRecordNotFound) {
return nil, res.Error
return nil, errors.Join(fmt.Errorf("Failed to find distribution for block number '%d'", blockHeight), res.Error)
}
if errors.Is(res.Error, gorm.ErrRecordNotFound) {
return nil, fmt.Errorf("no distribution root found for blockHeight '%d'", blockHeight)
Expand Down Expand Up @@ -366,11 +386,11 @@ func (rds *RewardsDataService) GetSummarizedRewards(ctx context.Context, earner
}

// channels to aggregate results together in a thread safe way
earnedRewardsChan := make(chan *ChanResult[[]*RewardAmount])
activeRewardsChan := make(chan *ChanResult[[]*RewardAmount])
claimableRewardsChan := make(chan *ChanResult[[]*RewardAmount])
claimedRewardsChan := make(chan *ChanResult[[]*RewardAmount])
var wg sync.WaitGroup
earnedRewardsChan := make(chan *ChanResult[[]*RewardAmount], 1)
activeRewardsChan := make(chan *ChanResult[[]*RewardAmount], 1)
claimableRewardsChan := make(chan *ChanResult[[]*RewardAmount], 1)
claimedRewardsChan := make(chan *ChanResult[[]*RewardAmount], 1)
wg := sync.WaitGroup{}
wg.Add(4)

go func() {
Expand All @@ -389,6 +409,7 @@ func (rds *RewardsDataService) GetSummarizedRewards(ctx context.Context, earner
defer wg.Done()
res := &ChanResult[[]*RewardAmount]{}
activeRewards, err := rds.GetTotalRewardsForEarner(ctx, earner, tokens, blockHeight, true)

if err != nil {
res.Error = err
} else {
Expand Down Expand Up @@ -476,6 +497,9 @@ func (rds *RewardsDataService) ListAvailableRewardsTokens(ctx context.Context, e
if err != nil {
return nil, err
}
if snapshot == nil {
return nil, fmt.Errorf("no distribution root found for blockHeight '%d'", blockHeight)
}

query := `
select
Expand Down
139 changes: 139 additions & 0 deletions pkg/service/rewardsDataService/rewards_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
package rewardsDataService

import (
"context"
"fmt"
"github.com/Layr-Labs/sidecar/internal/config"
"github.com/Layr-Labs/sidecar/internal/logger"
"github.com/Layr-Labs/sidecar/internal/tests"
"github.com/Layr-Labs/sidecar/pkg/postgres"
"github.com/Layr-Labs/sidecar/pkg/rewards"
pgStorage "github.com/Layr-Labs/sidecar/pkg/storage/postgres"
"github.com/stretchr/testify/assert"
"go.uber.org/zap"
"gorm.io/gorm"
"os"
"testing"
)

func setup() (
*gorm.DB,
*zap.Logger,
*config.Config,
error,
) {
cfg := config.NewConfig()
cfg.Chain = config.Chain_Holesky
cfg.Debug = os.Getenv(config.Debug) == "true"
cfg.DatabaseConfig = *tests.GetDbConfigFromEnv()

l, _ := logger.NewLogger(&logger.LoggerConfig{Debug: cfg.Debug})

pgConfig := postgres.PostgresConfigFromDbConfig(&cfg.DatabaseConfig)
pg, err := postgres.NewPostgres(pgConfig)
if err != nil {
l.Fatal("Failed to setup postgres connection", zap.Error(err))
}

grm, err := postgres.NewGormFromPostgresConnection(pg.Db)
if err != nil {
l.Fatal("Failed to create gorm instance", zap.Error(err))
}

return grm, l, cfg, nil
}

// Test_RewardsDataService tests the rewards data service. It assumes that there is a full
// database to read data from, specifically a holesky database with rewards generated.
func Test_RewardsDataService(t *testing.T) {
if !tests.LargeTestsEnabled() {
t.Skipf("Skipping large test")
return
}

grm, l, cfg, err := setup()

t.Logf("Using database with name: %s", cfg.DatabaseConfig.DbName)

if err != nil {
t.Fatalf("Failed to setup test: %v", err)
}

mds := pgStorage.NewPostgresBlockStore(grm, l, cfg)
rc, err := rewards.NewRewardsCalculator(cfg, grm, mds, nil, l)
if err != nil {
t.Fatalf("Failed to create rewards calculator: %v", err)
}
rds := NewRewardsDataService(grm, l, cfg, rc)

t.Run("Test GetRewardsForSnapshot", func(t *testing.T) {
snapshot := "2025-01-16"

r, err := rds.GetRewardsForSnapshot(context.Background(), snapshot)
assert.Nil(t, err)
assert.NotNil(t, r)
})

t.Run("Test GetTotalClaimedRewards", func(t *testing.T) {
earner := "0x0fb39abd3740d10ac1f698f2796ee200bbdd2065"
blockNumber := uint64(3178227)

r, err := rds.GetTotalClaimedRewards(context.Background(), earner, nil, blockNumber)
assert.Nil(t, err)
assert.NotNil(t, r)
})

t.Run("Test ListClaimedRewardsByBlockRange", func(t *testing.T) {
earner := "0x0fb39abd3740d10ac1f698f2796ee200bbdd2065"
blockNumber := uint64(3178227)

r, err := rds.ListClaimedRewardsByBlockRange(context.Background(), earner, blockNumber, blockNumber, nil)
assert.Nil(t, err)
assert.NotNil(t, r)
})

t.Run("Test GetTotalRewardsForEarner for claimable tokens", func(t *testing.T) {
earner := "0x0fb39abd3740d10ac1f698f2796ee200bbdd2065"
blockNumber := uint64(3178227)

t.Run("for active tokens", func(t *testing.T) {
r, err := rds.GetTotalRewardsForEarner(context.Background(), earner, nil, blockNumber, false)
assert.Nil(t, err)
assert.NotNil(t, r)
})
t.Run("for claimable tokens", func(t *testing.T) {
r, err := rds.GetTotalRewardsForEarner(context.Background(), earner, nil, blockNumber, true)
assert.Nil(t, err)
assert.NotNil(t, r)
})
})

t.Run("Test GetClaimableRewardsForEarner", func(t *testing.T) {
earner := "0x0fb39abd3740d10ac1f698f2796ee200bbdd2065"
blockNumber := uint64(3178227)

r, root, err := rds.GetClaimableRewardsForEarner(context.Background(), earner, nil, blockNumber)
assert.Nil(t, err)
assert.NotNil(t, r)
assert.NotNil(t, root)
})

t.Run("Test GetSummarizedRewards", func(t *testing.T) {
earner := "0x0fb39abd3740d10ac1f698f2796ee200bbdd2065"
blockNumber := uint64(3178227)

r, err := rds.GetSummarizedRewards(context.Background(), earner, nil, blockNumber)
assert.Nil(t, err)
assert.NotNil(t, r)
})

t.Run("Test ListAvailableRewardsTokens", func(t *testing.T) {
earner := "0x0fb39abd3740d10ac1f698f2796ee200bbdd2065"
blockNumber := uint64(3178227)

r, err := rds.ListAvailableRewardsTokens(context.Background(), earner, blockNumber)
assert.Nil(t, err)
assert.NotNil(t, r)
fmt.Printf("Available rewards tokens: %v\n", r)
})
}
3 changes: 2 additions & 1 deletion scripts/goTest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
export PROJECT_ROOT=$(pwd)
export TESTING=true
export SIDECAR_DATABASE_HOST=${SIDECAR_DATABASE_HOST:-"localhost"}
export SIDECAR_DATABASE_DB_NAME=${SIDECAR_DATABASE_DB_NAME:-""}
export SIDECAR_DATABASE_PORT=${SIDECAR_DATABASE_PORT:-5432}
export SIDECAR_DATABASE_USER=${SIDECAR_DATABASE_USER:-""}
export SIDECAR_DATABASE_PASSWORD=${SIDECAR_DATABASE_PASSWORD:-""}
export SIDECAR_DEBUG=${SIDECAR_DEBUG:-"false"}

go test $@
go test $@

0 comments on commit 3ef0fa7

Please sign in to comment.