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

Disallow creating new stake if allow list is enabled #96

Merged
merged 2 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)

* [#93](https://github.com/babylonlabs-io/btc-staker/pull/93) Fix linting config
* [#95](https://github.com/babylonlabs-io/btc-staker/pull/95) Bump babylon to v0.16
* [#96](https://github.com/babylonlabs-io/btc-staker/pull/96) Check allow list
expiration height before creating new delegations

## v0.10.0

Expand Down
63 changes: 39 additions & 24 deletions babylonclient/babyloncontroller.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,18 +99,19 @@ func NewBabylonController(
}

type StakingTrackerResponse struct {
SlashingPkScript []byte
SlashingRate sdkmath.LegacyDec
MinComissionRate sdkmath.LegacyDec
CovenantPks []*btcec.PublicKey
CovenantQuruomThreshold uint32
MinSlashingFee btcutil.Amount
MinUnbondingTime uint16
UnbondingFee btcutil.Amount
MinStakingTime uint16
MaxStakingTime uint16
MinStakingValue btcutil.Amount
MaxStakingValue btcutil.Amount
SlashingPkScript []byte
SlashingRate sdkmath.LegacyDec
MinComissionRate sdkmath.LegacyDec
CovenantPks []*btcec.PublicKey
CovenantQuruomThreshold uint32
MinSlashingFee btcutil.Amount
MinUnbondingTime uint16
UnbondingFee btcutil.Amount
MinStakingTime uint16
MaxStakingTime uint16
MinStakingValue btcutil.Amount
MaxStakingValue btcutil.Amount
AllowListExpirationHeight uint64
}

type FinalityProviderInfo struct {
Expand Down Expand Up @@ -193,6 +194,7 @@ func (bc *BabylonController) Params() (*StakingParams, error) {
MaxStakingTime: stakingTrackerParams.MaxStakingTime,
MinStakingValue: stakingTrackerParams.MinStakingValue,
MaxStakingValue: stakingTrackerParams.MaxStakingValue,
AllowListExpirationHeight: stakingTrackerParams.AllowListExpirationHeight,
}, nil
}

Expand All @@ -217,6 +219,18 @@ func (bc *BabylonController) GetKeyAddress() sdk.AccAddress {
return addr
}

func (bc *BabylonController) GetLatestBlockHeight() (uint64, error) {
ctx, cancel := getQueryContext(bc.cfg.Timeout)
defer cancel()

status, err := bc.bbnClient.RPCClient.Status(ctx)
if err != nil {
return 0, err
}

return uint64(status.SyncInfo.LatestBlockHeight), nil
}

func (bc *BabylonController) getTxSigner() string {
signer := bc.GetKeyAddress()
prefix := bc.cfg.AccountPrefix
Expand Down Expand Up @@ -501,18 +515,19 @@ func (bc *BabylonController) QueryStakingTracker() (*StakingTrackerResponse, err
}

return &StakingTrackerResponse{
SlashingPkScript: response.Params.SlashingPkScript,
SlashingRate: response.Params.SlashingRate,
MinComissionRate: response.Params.MinCommissionRate,
CovenantPks: covenantPks,
MinSlashingFee: btcutil.Amount(response.Params.MinSlashingTxFeeSat),
CovenantQuruomThreshold: response.Params.CovenantQuorum,
MinUnbondingTime: uint16(minUnbondingTimeBlocksU32),
UnbondingFee: btcutil.Amount(response.Params.UnbondingFeeSat),
MinStakingTime: uint16(minStakingTimeBlocksU32),
MaxStakingTime: uint16(maxStakingTimeBlocksU32),
MinStakingValue: btcutil.Amount(response.Params.MinStakingValueSat),
MaxStakingValue: btcutil.Amount(response.Params.MaxStakingValueSat),
SlashingPkScript: response.Params.SlashingPkScript,
SlashingRate: response.Params.SlashingRate,
MinComissionRate: response.Params.MinCommissionRate,
CovenantPks: covenantPks,
MinSlashingFee: btcutil.Amount(response.Params.MinSlashingTxFeeSat),
CovenantQuruomThreshold: response.Params.CovenantQuorum,
MinUnbondingTime: uint16(minUnbondingTimeBlocksU32),
UnbondingFee: btcutil.Amount(response.Params.UnbondingFeeSat),
MinStakingTime: uint16(minStakingTimeBlocksU32),
MaxStakingTime: uint16(maxStakingTimeBlocksU32),
MinStakingValue: btcutil.Amount(response.Params.MinStakingValueSat),
MaxStakingValue: btcutil.Amount(response.Params.MaxStakingValueSat),
AllowListExpirationHeight: response.Params.AllowListExpirationHeight,
}, nil
}

Expand Down
8 changes: 8 additions & 0 deletions babylonclient/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ type StakingParams struct {

// Maximum staking value required by babylon
MaxStakingValue btcutil.Amount

// AllowList expiration height
AllowListExpirationHeight uint64
}

// SingleKeyCosmosKeyring represents a keyring that supports only one pritvate/public key pair
Expand All @@ -72,6 +75,7 @@ type BabylonClient interface {
QueryHeaderDepth(headerHash *chainhash.Hash) (uint32, error)
IsTxAlreadyPartOfDelegation(stakingTxHash *chainhash.Hash) (bool, error)
QueryDelegationInfo(stakingTxHash *chainhash.Hash) (*DelegationInfo, error)
GetLatestBlockHeight() (uint64, error)
}

type MockBabylonClient struct {
Expand Down Expand Up @@ -159,6 +163,10 @@ func (m *MockBabylonClient) Undelegate(
return &pv.RelayerTxResponse{Code: 0}, nil
}

func (m *MockBabylonClient) GetLatestBlockHeight() (uint64, error) {
return 0, nil
}

func GetMockClient() *MockBabylonClient {
covenantPk, err := btcec.NewPrivateKey()
if err != nil {
Expand Down
15 changes: 15 additions & 0 deletions staker/stakerapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -1783,6 +1783,21 @@ func (app *App) StakeFunds(
return nil, err
}

// Allow list is enabled, check if we are past the expiration height and we can
// create new delegations
if params.AllowListExpirationHeight > 0 {
latestBlockHeight, err := app.babylonClient.GetLatestBlockHeight()

if err != nil {
return nil, fmt.Errorf("failed to get latest block height: %w", err)
}
// we add +1 to account for comet bft lazy execution
if latestBlockHeight <= params.AllowListExpirationHeight+1 {
Comment on lines +1794 to +1795
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

trying to understand this. So, this check means if AllowListExpirationHeight = 100, new delegations can be made when the latest block height is >= 102. Is this expected? I thought new delegations should be able to be made if latest block height is >=100 as they will be included in 101 which is > AllowListExpirationHeight=100

return nil, fmt.Errorf("allow is enabled, cannot create new delegations. Latest block height %d is before allow list expiration height %d",
latestBlockHeight, params.AllowListExpirationHeight)
}
}

slashingFee := app.getSlashingFee(params.MinSlashingTxFeeSat)

if stakingAmount <= slashingFee {
Expand Down
Loading