Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: return IsEligibleForTransition in delegation #139

Merged
merged 4 commits into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion docs/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,8 @@ const docTemplate = `{
"unbonding_requested",
"unbonding",
"unbonded",
"withdrawn"
"withdrawn",
"transitioned"
],
"type": "string",
"description": "Filter by state",
Expand Down Expand Up @@ -999,6 +1000,9 @@ const docTemplate = `{
"finality_provider_pk_hex": {
"type": "string"
},
"is_eligible_for_transition": {
"type": "boolean"
},
"is_overflow": {
"type": "boolean"
},
Expand Down
6 changes: 5 additions & 1 deletion docs/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,8 @@
"unbonding_requested",
"unbonding",
"unbonded",
"withdrawn"
"withdrawn",
"transitioned"
],
"type": "string",
"description": "Filter by state",
Expand Down Expand Up @@ -991,6 +992,9 @@
"finality_provider_pk_hex": {
"type": "string"
},
"is_eligible_for_transition": {
"type": "boolean"
},
"is_overflow": {
"type": "boolean"
},
Expand Down
3 changes: 3 additions & 0 deletions docs/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,8 @@ definitions:
properties:
finality_provider_pk_hex:
type: string
is_eligible_for_transition:
type: boolean
is_overflow:
type: boolean
staker_pk_hex:
Expand Down Expand Up @@ -612,6 +614,7 @@ paths:
- unbonding
- unbonded
- withdrawn
- transitioned
in: query
name: state
type: string
Expand Down
6 changes: 6 additions & 0 deletions internal/indexer/db/client/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,10 @@ type IndexerDBClient interface {
// Staker Delegations
GetDelegation(ctx context.Context, stakingTxHashHex string) (*indexerdbmodel.IndexerDelegationDetails, error)
GetDelegations(ctx context.Context, stakerPKHex string, paginationToken string) (*db.DbResultMap[indexerdbmodel.IndexerDelegationDetails], error)
/**
* GetLastProcessedBbnHeight retrieves the last processed BBN height.
* @param ctx The context
* @return The last processed height or an error
*/
GetLastProcessedBbnHeight(ctx context.Context) (uint64, error)
}
37 changes: 37 additions & 0 deletions internal/indexer/db/client/last_processed_height.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package indexerdbclient

import (
"context"

indexerdbmodel "github.com/babylonlabs-io/staking-api-service/internal/indexer/db/model"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
)

// Use namespaced key for context to avoid collisions
const ctxKey = "indexer_db.last_processed_height"

func (db *IndexerDatabase) GetLastProcessedBbnHeight(ctx context.Context) (uint64, error) {
// Check if height is already in context
if height, ok := ctx.Value(ctxKey).(uint64); ok {
jrwbabylonlab marked this conversation as resolved.
Show resolved Hide resolved
return height, nil
}

// If not in context, query from database
var result indexerdbmodel.LastProcessedHeight
err := db.Client.Database(db.DbName).Collection(
indexerdbmodel.LastProcessedHeightCollection,
).FindOne(ctx, bson.M{}).Decode(&result)
if err == mongo.ErrNoDocuments {
// If no document exists, return 0
return 0, nil
}
if err != nil {
return 0, err
}

// Store in context for future use with namespaced key
ctx = context.WithValue(ctx, ctxKey, result.Height)

return result.Height, nil
}
5 changes: 5 additions & 0 deletions internal/indexer/db/model/last_processed_height.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package indexerdbmodel

type LastProcessedHeight struct {
Height uint64 `bson:"height"`
}
1 change: 1 addition & 0 deletions internal/indexer/db/model/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ const (
BTCDelegationDetailsCollection = "btc_delegation_details"
TimeLockCollection = "timelock"
GlobalParamsCollection = "global_params"
LastProcessedHeightCollection = "last_processed_height"
)
20 changes: 14 additions & 6 deletions internal/shared/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ import (
)

type Config struct {
Server *ServerConfig `mapstructure:"server"`
StakingDb *DbConfig `mapstructure:"staking-db"`
IndexerDb *DbConfig `mapstructure:"indexer-db"`
Queue *queue.QueueConfig `mapstructure:"queue"`
Metrics *MetricsConfig `mapstructure:"metrics"`
Assets *AssetsConfig `mapstructure:"assets"`
Server *ServerConfig `mapstructure:"server"`
StakingDb *DbConfig `mapstructure:"staking-db"`
IndexerDb *DbConfig `mapstructure:"indexer-db"`
Queue *queue.QueueConfig `mapstructure:"queue"`
Metrics *MetricsConfig `mapstructure:"metrics"`
Assets *AssetsConfig `mapstructure:"assets"`
DelegationTransition *DelegationTransitionConfig `mapstructure:"delegation_transition"`
}

func (cfg *Config) Validate() error {
Expand Down Expand Up @@ -46,6 +47,13 @@ func (cfg *Config) Validate() error {
}
}

// The DelegationTransition is optional
if cfg.DelegationTransition != nil {
if err := cfg.DelegationTransition.Validate(); err != nil {
return err
}
}

return nil
}

Expand Down
24 changes: 24 additions & 0 deletions internal/shared/config/delegation_transition.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package config

import "errors"

// DelegationTransitionConfig represents the transition cutoff height for the phase-1 delegation to phase-2.
// A delegation can transition to phase-2 if either:
// 1. The delegation's BTC staking height is less than BeforeBtcHeight, or
// 2. The current BBN height is greater than AfterBbnHeight (allowing all delegations to transition)
type DelegationTransitionConfig struct {
BeforeBtcHeight uint64 `mapstructure:"before_btc_height"`
jrwbabylonlab marked this conversation as resolved.
Show resolved Hide resolved
AfterBbnHeight uint64 `mapstructure:"after_bbn_height"`
}

func (cfg *DelegationTransitionConfig) Validate() error {
if cfg.BeforeBtcHeight == 0 {
return errors.New("before_btc_height cannot be 0")
}

if cfg.AfterBbnHeight == 0 {
return errors.New("after_bbn_height cannot be 0")
}

return nil
}
3 changes: 3 additions & 0 deletions internal/shared/types/delegation.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const (
Unbonding DelegationState = "unbonding"
Unbonded DelegationState = "unbonded"
Withdrawn DelegationState = "withdrawn"
Transitioned DelegationState = "transitioned"
)

func (s DelegationState) ToString() string {
Expand All @@ -28,6 +29,8 @@ func FromStringToDelegationState(s string) (DelegationState, error) {
return Unbonded, nil
case "withdrawn":
return Withdrawn, nil
case "transitioned":
return Transitioned, nil
default:
return "", fmt.Errorf("invalid delegation state: %s", s)
}
Expand Down
3 changes: 1 addition & 2 deletions internal/v1/api/handlers/delegation.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (

"github.com/babylonlabs-io/staking-api-service/internal/shared/api/handlers/handler"
"github.com/babylonlabs-io/staking-api-service/internal/shared/types"
v1service "github.com/babylonlabs-io/staking-api-service/internal/v1/service"
)

// GetDelegationByTxHash @Summary Get a delegation
Expand All @@ -26,5 +25,5 @@ func (h *V1Handler) GetDelegationByTxHash(request *http.Request) (*handler.Resul
return nil, err
}

return handler.NewResult(v1service.FromDelegationDocument(delegation)), nil
return handler.NewResult(delegation), nil
}
2 changes: 1 addition & 1 deletion internal/v1/db/model/delegation.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package v1dbmodel

import (
"github.com/babylonlabs-io/staking-api-service/internal/shared/types"
dbmodel "github.com/babylonlabs-io/staking-api-service/internal/shared/db/model"
"github.com/babylonlabs-io/staking-api-service/internal/shared/types"
)

type TimelockTransaction struct {
Expand Down
3 changes: 2 additions & 1 deletion internal/v1/queue/handler/expired_staking.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ func (h *V1QueueHandler) ExpiredStakingHandler(ctx context.Context, messageBody
if delErr != nil {
return delErr
}
if utils.Contains[types.DelegationState](utils.OutdatedStatesForUnbonded(), del.State) {
state := types.DelegationState(del.State)
if utils.Contains(utils.OutdatedStatesForUnbonded(), state) {
// Ignore the message as the delegation state already passed the unbonded state. This is an outdated duplication
log.Ctx(ctx).Debug().Str("StakingTxHashHex", expiredStakingEvent.StakingTxHashHex).
Msg("delegation state is outdated for unbonded event")
Expand Down
2 changes: 1 addition & 1 deletion internal/v1/queue/handler/unbonding.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func (h *V1QueueHandler) UnbondingStakingHandler(ctx context.Context, messageBod
if delErr != nil {
return delErr
}
state := del.State
state := types.DelegationState(del.State)
if utils.Contains(utils.OutdatedStatesForUnbonding(), state) {
// Ignore the message as the delegation state already passed the unbonding state. This is an outdated duplication
log.Ctx(ctx).Debug().Str("StakingTxHashHex", unbondingStakingEvent.StakingTxHashHex).
Expand Down
2 changes: 1 addition & 1 deletion internal/v1/queue/handler/withdraw.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func (h *V1QueueHandler) WithdrawStakingHandler(ctx context.Context, messageBody
if delErr != nil {
return delErr
}
state := del.State
state := types.DelegationState(del.State)

stakingTxHashHex := withdrawnStakingEvent.GetStakingTxHashHex()

Expand Down
Loading
Loading