From 82cf8078b935ac5a6c5a1a6f801be454cfb9f53f Mon Sep 17 00:00:00 2001 From: Gurjot Date: Sun, 24 Nov 2024 16:12:45 +0530 Subject: [PATCH] slashing expire --- internal/services/watch_btc_events.go | 51 ++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 9 deletions(-) diff --git a/internal/services/watch_btc_events.go b/internal/services/watch_btc_events.go index d455636..c5df1d6 100644 --- a/internal/services/watch_btc_events.go +++ b/internal/services/watch_btc_events.go @@ -34,6 +34,7 @@ func (s *Service) watchForSpendStakingTx( quitCtx, spendDetail.SpendingTx, spendDetail.SpenderInputIndex, + uint32(spendDetail.SpendingHeight), delegation, ); err != nil { log.Error().Err(err).Msg("failed to handle spending staking transaction") @@ -62,6 +63,7 @@ func (s *Service) watchForSpendUnbondingTx( if err := s.handleSpendingUnbondingTransaction( quitCtx, spendDetail.SpendingTx, + uint32(spendDetail.SpendingHeight), spendDetail.SpenderInputIndex, delegation, ); err != nil { @@ -124,8 +126,9 @@ func (s *Service) watchForSpendSlashingChange( func (s *Service) handleSpendingStakingTransaction( ctx context.Context, - tx *wire.MsgTx, + spendingTx *wire.MsgTx, spendingInputIdx uint32, + spendingHeight uint32, delegation *model.BTCDelegationDetails, ) error { params, err := s.db.GetStakingParams(ctx, delegation.ParamsVersion) @@ -134,7 +137,7 @@ func (s *Service) handleSpendingStakingTransaction( } // First try to validate as unbonding tx - isUnbonding, err := s.IsValidUnbondingTx(tx, delegation, params) + isUnbonding, err := s.IsValidUnbondingTx(spendingTx, delegation, params) if err != nil { return fmt.Errorf("failed to validate unbonding tx: %w", err) } @@ -144,7 +147,7 @@ func (s *Service) handleSpendingStakingTransaction( } // Try to validate as withdrawal transaction - withdrawalErr := s.validateWithdrawalTxFromStaking(tx, spendingInputIdx, delegation, params) + withdrawalErr := s.validateWithdrawalTxFromStaking(spendingTx, spendingInputIdx, delegation, params) if withdrawalErr == nil { // It's a valid withdrawal, process it return s.handleWithdrawal(ctx, delegation, types.SubStateTimelock) @@ -156,7 +159,7 @@ func (s *Service) handleSpendingStakingTransaction( } // Try to validate as slashing transaction - if err := s.validateSlashingTxFromStaking(tx, spendingInputIdx, delegation, params); err != nil { + if err := s.validateSlashingTxFromStaking(spendingTx, spendingInputIdx, delegation, params); err != nil { if errors.Is(err, types.ErrInvalidSlashingTx) { // Neither withdrawal nor slashing - this is an invalid spend return fmt.Errorf("transaction is neither valid unbonding, withdrawal, nor slashing: %w", err) @@ -165,12 +168,19 @@ func (s *Service) handleSpendingStakingTransaction( } // It's a valid slashing tx, watch for spending change output - return s.startWatchingSlashingChange(ctx, tx, delegation, types.SubStateTimelockSlashing) + return s.startWatchingSlashingChange( + ctx, + spendingTx, + spendingHeight, + delegation, + types.SubStateTimelockSlashing, + ) } func (s *Service) handleSpendingUnbondingTransaction( ctx context.Context, - tx *wire.MsgTx, + spendingTx *wire.MsgTx, + spendingHeight uint32, spendingInputIdx uint32, delegation *model.BTCDelegationDetails, ) error { @@ -180,7 +190,7 @@ func (s *Service) handleSpendingUnbondingTransaction( } // First try to validate as withdrawal transaction - withdrawalErr := s.validateWithdrawalTxFromUnbonding(tx, delegation, spendingInputIdx, params) + withdrawalErr := s.validateWithdrawalTxFromUnbonding(spendingTx, delegation, spendingInputIdx, params) if withdrawalErr == nil { // It's a valid withdrawal, process it return s.handleWithdrawal(ctx, delegation, types.SubStateEarlyUnbonding) @@ -192,7 +202,7 @@ func (s *Service) handleSpendingUnbondingTransaction( } // Try to validate as slashing transaction - if err := s.validateSlashingTxFromUnbonding(tx, delegation, spendingInputIdx, params); err != nil { + if err := s.validateSlashingTxFromUnbonding(spendingTx, delegation, spendingInputIdx, params); err != nil { if errors.Is(err, types.ErrInvalidSlashingTx) { // Neither withdrawal nor slashing - this is an invalid spend return fmt.Errorf("transaction is neither valid withdrawal nor slashing: %w", err) @@ -201,7 +211,13 @@ func (s *Service) handleSpendingUnbondingTransaction( } // It's a valid slashing tx, watch for spending change output - return s.startWatchingSlashingChange(ctx, tx, delegation, types.SubStateEarlyUnbondingSlashing) + return s.startWatchingSlashingChange( + ctx, + spendingTx, + spendingHeight, + delegation, + types.SubStateEarlyUnbondingSlashing, + ) } func (s *Service) handleWithdrawal( @@ -231,6 +247,7 @@ func (s *Service) handleWithdrawal( func (s *Service) startWatchingSlashingChange( ctx context.Context, slashingTx *wire.MsgTx, + spendingHeight uint32, delegation *model.BTCDelegationDetails, subState types.DelegationSubState, ) error { @@ -250,6 +267,22 @@ func (s *Service) startWatchingSlashingChange( return fmt.Errorf("failed to register spend ntfn for slashing change output: %w", err) } + // TODO: confirm if we this is correct or do we need max(w, minUnbondingTime) + stakingParams, err := s.db.GetStakingParams(ctx, delegation.ParamsVersion) + if err != nil { + return fmt.Errorf("failed to get staking params: %w", err) + } + slashingExpireHeight := spendingHeight + stakingParams.MinUnbondingTimeBlocks + // Save timelock expire + if err := s.db.SaveNewTimeLockExpire( + ctx, + delegation.StakingTxHashHex, + slashingExpireHeight, + subState, + ); err != nil { + return fmt.Errorf("failed to save timelock expire: %w", err) + } + s.wg.Add(1) go s.watchForSpendSlashingChange(spendEv, delegation, subState)