From b9a9e6b7de2c3f7bce979f09f1414091d1ac0a9c Mon Sep 17 00:00:00 2001 From: Crypto Minion <154598612+jrwbabylonlab@users.noreply.github.com> Date: Wed, 4 Dec 2024 21:49:25 +1100 Subject: [PATCH] fix: return the transitioned state for phase-1 delegation (#169) --- docs/docs.go | 3 -- docs/swagger.json | 3 -- docs/swagger.yaml | 2 - internal/shared/utils/state_transition.go | 5 +++ internal/v1/db/client/delegation.go | 24 ++++------ internal/v1/db/client/interface.go | 2 +- internal/v1/db/model/delegation.go | 1 - internal/v1/service/delegation.go | 2 - internal/v2/db/client/deelgation.go | 55 ----------------------- internal/v2/db/client/interface.go | 1 - internal/v2/service/delegation.go | 10 ++++- internal/v2/service/interface.go | 1 - tests/mocks/mock_db_client.go | 2 +- tests/mocks/mock_ordinal_client.go | 2 +- tests/mocks/mock_v1_db_client.go | 38 ++++++++-------- tests/mocks/mock_v2_db_client.go | 20 +-------- 16 files changed, 45 insertions(+), 126 deletions(-) delete mode 100644 internal/v2/db/client/deelgation.go diff --git a/docs/docs.go b/docs/docs.go index 45117428..e11e52bc 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -960,9 +960,6 @@ const docTemplate = `{ "is_slashed": { "type": "boolean" }, - "is_transitioned": { - "type": "boolean" - }, "staker_pk_hex": { "type": "string" }, diff --git a/docs/swagger.json b/docs/swagger.json index 12a0ac3e..fc9ca867 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -952,9 +952,6 @@ "is_slashed": { "type": "boolean" }, - "is_transitioned": { - "type": "boolean" - }, "staker_pk_hex": { "type": "string" }, diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 2e6c49cb..21c8ec2d 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -214,8 +214,6 @@ definitions: type: boolean is_slashed: type: boolean - is_transitioned: - type: boolean staker_pk_hex: type: string staking_tx: diff --git a/internal/shared/utils/state_transition.go b/internal/shared/utils/state_transition.go index 6f46f849..ab6963a5 100644 --- a/internal/shared/utils/state_transition.go +++ b/internal/shared/utils/state_transition.go @@ -43,3 +43,8 @@ func QualifiedStatesToWithdraw() []types.DelegationState { func OutdatedStatesForWithdraw() []types.DelegationState { return []types.DelegationState{types.Withdrawn} } + +// QualifiedStatesToTransitioned returns the qualified exisitng states to transition to "transitioned" +func QualifiedStatesToTransitioned() []types.DelegationState { + return []types.DelegationState{types.Active, types.UnbondingRequested} +} diff --git a/internal/v1/db/client/delegation.go b/internal/v1/db/client/delegation.go index 919a1259..045a5044 100644 --- a/internal/v1/db/client/delegation.go +++ b/internal/v1/db/client/delegation.go @@ -12,6 +12,7 @@ import ( "github.com/babylonlabs-io/staking-api-service/internal/shared/db" dbmodel "github.com/babylonlabs-io/staking-api-service/internal/shared/db/model" "github.com/babylonlabs-io/staking-api-service/internal/shared/types" + "github.com/babylonlabs-io/staking-api-service/internal/shared/utils" v1dbmodel "github.com/babylonlabs-io/staking-api-service/internal/v1/db/model" ) @@ -156,21 +157,14 @@ 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 +// TransitionToTransitionedState marks an existing delegation as transitioned +func (v1dbclient *V1Database) TransitionToTransitionedState( + ctx context.Context, stakingTxHashHex string, +) error { + return v1dbclient.transitionState( + ctx, stakingTxHashHex, types.Transitioned.ToString(), + utils.QualifiedStatesToTransitioned(), nil, + ) } // TransitionState updates the state of a staking transaction to a new state diff --git a/internal/v1/db/client/interface.go b/internal/v1/db/client/interface.go index 997bde07..eb257068 100644 --- a/internal/v1/db/client/interface.go +++ b/internal/v1/db/client/interface.go @@ -30,7 +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 + TransitionToTransitionedState(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, diff --git a/internal/v1/db/model/delegation.go b/internal/v1/db/model/delegation.go index 8f64bd4f..df148576 100644 --- a/internal/v1/db/model/delegation.go +++ b/internal/v1/db/model/delegation.go @@ -22,7 +22,6 @@ 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 { diff --git a/internal/v1/service/delegation.go b/internal/v1/service/delegation.go index 594cb333..93e8af7c 100644 --- a/internal/v1/service/delegation.go +++ b/internal/v1/service/delegation.go @@ -32,7 +32,6 @@ 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( @@ -213,7 +212,6 @@ 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 diff --git a/internal/v2/db/client/deelgation.go b/internal/v2/db/client/deelgation.go deleted file mode 100644 index c985e925..00000000 --- a/internal/v2/db/client/deelgation.go +++ /dev/null @@ -1,55 +0,0 @@ -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 -} - diff --git a/internal/v2/db/client/interface.go b/internal/v2/db/client/interface.go index 3c3e987a..61665cdf 100644 --- a/internal/v2/db/client/interface.go +++ b/internal/v2/db/client/interface.go @@ -26,5 +26,4 @@ type V2DBClient interface { SubtractStakerStats( ctx context.Context, stakingTxHashHex, stakerPkHex string, amount uint64, ) error - MarkV1DelegationAsTransitioned(ctx context.Context, stakingTxHashHex string) error } diff --git a/internal/v2/service/delegation.go b/internal/v2/service/delegation.go index b5b5c0de..5fb13d7c 100644 --- a/internal/v2/service/delegation.go +++ b/internal/v2/service/delegation.go @@ -171,12 +171,18 @@ 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) +// MarkV1DelegationAsTransitioned marks a v1 delegation as transitioned +func (s *V2Service) MarkV1DelegationAsTransitioned( + ctx context.Context, stakingTxHashHex string, +) *types.Error { + err := s.DbClients.V1DBClient.TransitionToTransitionedState(ctx, stakingTxHashHex) if err != nil { if db.IsNotFoundError(err) { + // If the delegation is not found, it means it has already been transitioned + // or not relevant to phase-1 at all. return nil } + log.Ctx(ctx).Error().Err(err).Msg("Failed to transition v1 delegation to transitioned state") return types.NewInternalServiceError(err) } return nil diff --git a/internal/v2/service/interface.go b/internal/v2/service/interface.go index 8530ecad..3f4ad5d3 100644 --- a/internal/v2/service/interface.go +++ b/internal/v2/service/interface.go @@ -24,6 +24,5 @@ type V2ServiceProvider interface { finalityProviderBtcPksHex []string, state types.DelegationState, amount uint64, ) *types.Error - SaveUnprocessableMessages(ctx context.Context, messageBody, receipt string) *types.Error } diff --git a/tests/mocks/mock_db_client.go b/tests/mocks/mock_db_client.go index 9560824e..b247612e 100644 --- a/tests/mocks/mock_db_client.go +++ b/tests/mocks/mock_db_client.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.49.1. DO NOT EDIT. +// Code generated by mockery v2.41.0. DO NOT EDIT. package mocks diff --git a/tests/mocks/mock_ordinal_client.go b/tests/mocks/mock_ordinal_client.go index 36c16566..95dff743 100644 --- a/tests/mocks/mock_ordinal_client.go +++ b/tests/mocks/mock_ordinal_client.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.49.1. DO NOT EDIT. +// Code generated by mockery v2.41.0. DO NOT EDIT. package mocks diff --git a/tests/mocks/mock_v1_db_client.go b/tests/mocks/mock_v1_db_client.go index c234b4e6..6cd0a26c 100644 --- a/tests/mocks/mock_v1_db_client.go +++ b/tests/mocks/mock_v1_db_client.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.49.1. DO NOT EDIT. +// Code generated by mockery v2.41.0. DO NOT EDIT. package mocks @@ -500,24 +500,6 @@ func (_m *V1DBClient) InsertPkAddressMappings(ctx context.Context, stakerPkHex s return r0 } -// MarkDelegationAsTransitioned provides a mock function with given fields: ctx, stakingTxHashHex -func (_m *V1DBClient) MarkDelegationAsTransitioned(ctx context.Context, stakingTxHashHex string) error { - ret := _m.Called(ctx, stakingTxHashHex) - - if len(ret) == 0 { - panic("no return value specified for MarkDelegationAsTransitioned") - } - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, string) error); ok { - r0 = rf(ctx, stakingTxHashHex) - } else { - r0 = ret.Error(0) - } - - return r0 -} - // Ping provides a mock function with given fields: ctx func (_m *V1DBClient) Ping(ctx context.Context) error { ret := _m.Called(ctx) @@ -692,6 +674,24 @@ func (_m *V1DBClient) SubtractStakerStats(ctx context.Context, stakingTxHashHex return r0 } +// TransitionToTransitionedState provides a mock function with given fields: ctx, stakingTxHashHex +func (_m *V1DBClient) TransitionToTransitionedState(ctx context.Context, stakingTxHashHex string) error { + ret := _m.Called(ctx, stakingTxHashHex) + + if len(ret) == 0 { + panic("no return value specified for TransitionToTransitionedState") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, string) error); ok { + r0 = rf(ctx, stakingTxHashHex) + } else { + r0 = ret.Error(0) + } + + return r0 +} + // TransitionToUnbondedState provides a mock function with given fields: ctx, stakingTxHashHex, eligiblePreviousState func (_m *V1DBClient) TransitionToUnbondedState(ctx context.Context, stakingTxHashHex string, eligiblePreviousState []types.DelegationState) error { ret := _m.Called(ctx, stakingTxHashHex, eligiblePreviousState) diff --git a/tests/mocks/mock_v2_db_client.go b/tests/mocks/mock_v2_db_client.go index 4c43e41e..27929f3f 100644 --- a/tests/mocks/mock_v2_db_client.go +++ b/tests/mocks/mock_v2_db_client.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.49.1. DO NOT EDIT. +// Code generated by mockery v2.41.0. DO NOT EDIT. package mocks @@ -268,24 +268,6 @@ func (_m *V2DBClient) InsertPkAddressMappings(ctx context.Context, stakerPkHex s return r0 } -// MarkV1DelegationAsTransitioned provides a mock function with given fields: ctx, stakingTxHashHex -func (_m *V2DBClient) MarkV1DelegationAsTransitioned(ctx context.Context, stakingTxHashHex string) error { - ret := _m.Called(ctx, stakingTxHashHex) - - if len(ret) == 0 { - panic("no return value specified for MarkV1DelegationAsTransitioned") - } - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, string) error); ok { - r0 = rf(ctx, stakingTxHashHex) - } else { - r0 = ret.Error(0) - } - - return r0 -} - // Ping provides a mock function with given fields: ctx func (_m *V2DBClient) Ping(ctx context.Context) error { ret := _m.Called(ctx)