Skip to content

Commit

Permalink
feat: add MarkDelegationAsTransitioned method (#163)
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremy-babylonlabs authored Dec 3, 2024
1 parent b3311ec commit 918d24a
Show file tree
Hide file tree
Showing 16 changed files with 143 additions and 4 deletions.
3 changes: 3 additions & 0 deletions docs/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -960,6 +960,9 @@ const docTemplate = `{
"is_slashed": {
"type": "boolean"
},
"is_transitioned": {
"type": "boolean"
},
"staker_pk_hex": {
"type": "string"
},
Expand Down
3 changes: 3 additions & 0 deletions docs/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -952,6 +952,9 @@
"is_slashed": {
"type": "boolean"
},
"is_transitioned": {
"type": "boolean"
},
"staker_pk_hex": {
"type": "string"
},
Expand Down
2 changes: 2 additions & 0 deletions docs/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,8 @@ definitions:
type: boolean
is_slashed:
type: boolean
is_transitioned:
type: boolean
staker_pk_hex:
type: string
staking_tx:
Expand Down
17 changes: 17 additions & 0 deletions internal/v1/db/client/delegation.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,23 @@ func (v1dbclient *V1Database) ScanDelegationsPaginated(
)
}

// MarkDelegationAsTransitioned marks an existing delegation as transitioned
func (v1dbclient *V1Database) MarkDelegationAsTransitioned(ctx context.Context, stakingTxHashHex string) error {
client := v1dbclient.Client.Database(v1dbclient.DbName).Collection(dbmodel.V1DelegationCollection)
update := bson.M{"$set": bson.M{"is_transitioned": true}}
result, err := client.UpdateOne(ctx, bson.M{"_id": stakingTxHashHex}, update)
if err != nil {
return err
}
if result.MatchedCount == 0 {
return &db.NotFoundError{
Key: stakingTxHashHex,
Message: "Delegation not found",
}
}
return nil
}

// TransitionState updates the state of a staking transaction to a new state
// It returns an NotFoundError if the staking transaction is not found or not in the eligible state to transition
func (v1dbclient *V1Database) transitionState(
Expand Down
1 change: 1 addition & 0 deletions internal/v1/db/client/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type V1DBClient interface {
ctx context.Context, stakingTxHashHex, unbondingTxHashHex, txHex, signatureHex string,
) error
FindDelegationByTxHashHex(ctx context.Context, txHashHex string) (*v1dbmodel.DelegationDocument, error)
MarkDelegationAsTransitioned(ctx context.Context, stakingTxHashHex string) error
SaveTimeLockExpireCheck(ctx context.Context, stakingTxHashHex string, expireHeight uint64, txType string) error
TransitionToUnbondedState(
ctx context.Context, stakingTxHashHex string, eligiblePreviousState []types.DelegationState,
Expand Down
1 change: 1 addition & 0 deletions internal/v1/db/model/delegation.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type DelegationDocument struct {
StakingTx *TimelockTransaction `bson:"staking_tx"` // Always exist
UnbondingTx *TimelockTransaction `bson:"unbonding_tx,omitempty"`
IsOverflow bool `bson:"is_overflow"`
IsTransitioned bool `bson:"is_transitioned"`
}

type DelegationByStakerPagination struct {
Expand Down
2 changes: 2 additions & 0 deletions internal/v1/service/delegation.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ type DelegationPublic struct {
IsOverflow bool `json:"is_overflow"`
IsEligibleForTransition bool `json:"is_eligible_for_transition"`
IsSlashed bool `json:"is_slashed"`
IsTransitioned bool `json:"is_transitioned"`
}

func (s *V1Service) DelegationsByStakerPk(
Expand Down Expand Up @@ -212,6 +213,7 @@ func (s *V1Service) FromDelegationDocument(
IsOverflow: d.IsOverflow,
IsEligibleForTransition: isFpTransitioned && !isSlashed && s.isEligibleForTransition(d, bbnHeight),
IsSlashed: isSlashed,
IsTransitioned: d.IsTransitioned,
}

// Add unbonding transaction if it exists
Expand Down
55 changes: 55 additions & 0 deletions internal/v2/db/client/deelgation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package v2dbclient

import (
"context"
"errors"

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

func (v2dbclient *V2Database) MarkV1DelegationAsTransitioned(ctx context.Context, stakingTxHashHex string) error {
session, err := v2dbclient.Client.StartSession()
if err != nil {
return err
}
defer session.EndSession(ctx)

transactionWork := func(sessCtx mongo.SessionContext) (interface{}, error) {
client := v2dbclient.Client.Database(v2dbclient.DbName).Collection(dbmodel.V1DelegationCollection)
filter := bson.M{"_id": stakingTxHashHex}

var delegation interface{}
err := client.FindOne(sessCtx, filter).Decode(&delegation)
if err != nil {
if errors.Is(err, mongo.ErrNoDocuments) {
return nil, &db.NotFoundError{
Key: stakingTxHashHex,
Message: "Delegation not found",
}
}
return nil, err
}

update := bson.M{"$set": bson.M{"is_transitioned": true}}
result, err := client.UpdateOne(sessCtx, filter, update)
if err != nil {
return nil, err
}

if result.MatchedCount == 0 {
return nil, &db.NotFoundError{
Key: stakingTxHashHex,
Message: "Delegation not found",
}
}

return nil, nil
}

_, err = session.WithTransaction(ctx, transactionWork)
return err
}

1 change: 1 addition & 0 deletions internal/v2/db/client/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ type V2DBClient interface {
SubtractStakerStats(
ctx context.Context, stakingTxHashHex, stakerPkHex string, amount uint64,
) error
MarkV1DelegationAsTransitioned(ctx context.Context, stakingTxHashHex string) error
}
6 changes: 6 additions & 0 deletions internal/v2/queue/handler/staking.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ func (h *V2QueueHandler) ActiveStakingHandler(ctx context.Context, messageBody s
return types.NewError(http.StatusBadRequest, types.BadRequest, err)
}

// Mark as v1 delegation as transitioned if it exists
if err := h.Service.MarkV1DelegationAsTransitioned(ctx, activeStakingEvent.StakingTxHashHex); err != nil {
log.Ctx(ctx).Error().Err(err).Msg("Failed to mark v1 delegation as transitioned")
return err
}

// Perform the address lookup conversion
addressLookupErr := h.performAddressLookupConversion(ctx, activeStakingEvent.StakerBtcPkHex, types.Active)
if addressLookupErr != nil {
Expand Down
11 changes: 11 additions & 0 deletions internal/v2/service/delegation.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,14 @@ func (s *V2Service) SaveUnprocessableMessages(ctx context.Context, messageBody,
}
return nil
}

func (s *V2Service) MarkV1DelegationAsTransitioned(ctx context.Context, stakingTxHashHex string) *types.Error {
err := s.DbClients.V2DBClient.MarkV1DelegationAsTransitioned(ctx, stakingTxHashHex)
if err != nil {
if db.IsNotFoundError(err) {
return nil
}
return types.NewInternalServiceError(err)
}
return nil
}
1 change: 1 addition & 0 deletions internal/v2/service/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type V2ServiceProvider interface {
IsDelegationPresent(ctx context.Context, txHashHex string) (bool, *types.Error)
GetDelegation(ctx context.Context, stakingTxHashHex string) (*StakerDelegationPublic, *types.Error)
GetDelegations(ctx context.Context, stakerPKHex string, paginationKey string) ([]*StakerDelegationPublic, string, *types.Error)
MarkV1DelegationAsTransitioned(ctx context.Context, stakingTxHashHex string) *types.Error
GetOverallStats(ctx context.Context) (*OverallStatsPublic, *types.Error)
GetStakerStats(ctx context.Context, stakerPKHex string) (*StakerStatsPublic, *types.Error)
ProcessAndSaveBtcAddresses(ctx context.Context, stakerPkHex string) *types.Error
Expand Down
2 changes: 1 addition & 1 deletion tests/mocks/mock_db_client.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion tests/mocks/mock_ordinal_client.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 19 additions & 1 deletion tests/mocks/mock_v1_db_client.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 19 additions & 1 deletion tests/mocks/mock_v2_db_client.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 918d24a

Please sign in to comment.