Skip to content

Commit

Permalink
chore: Use int64 for fee config and bump to latest Babylon
Browse files Browse the repository at this point in the history
The libraries that we depend to use int64 for satoshi amount
denominations. To be fully compatible with them,
it is better if we use similar types instead of doing conversions.

Further, this PR bumps Babylon to latest and also fixes some
other type conversions and minor errors found by gosec.
  • Loading branch information
vitsalis committed Oct 12, 2024
1 parent b053ac8 commit bf8da90
Show file tree
Hide file tree
Showing 13 changed files with 115 additions and 83 deletions.
49 changes: 25 additions & 24 deletions babylonclient/babyloncontroller.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,9 @@ func (bc *BabylonController) Stop() error {
}

func (bc *BabylonController) Params() (*StakingParams, error) {
// TODO: uint64 are quite silly types for these params, probably uint8 or uint16 would be enough
// as we do not expect finalization to be more than 255 or in super extreme 65535
// TODO: it would probably be good to have separate methods for those
var bccParams *bcctypes.Params
if err := retry.Do(func() error {

response, err := bc.bbnClient.BTCCheckpointParams()
if err != nil {
return err
Expand Down Expand Up @@ -174,24 +171,24 @@ func (bc *BabylonController) Params() (*StakingParams, error) {
return nil, err
}

if bccParams.CheckpointFinalizationTimeout > math.MaxUint16 {
return nil, fmt.Errorf("checkpoint finalization timeout is bigger than uint16: %w", ErrInvalidValueReceivedFromBabylonNode)
}

minUnbondingTime := sdkmath.Max[uint16](
uint16(bccParams.CheckpointFinalizationTimeout),
stakingTrackerParams.MinUnbondingTime,
minUnbondingTimeU32 := sdkmath.Max[uint32](
bccParams.CheckpointFinalizationTimeout,
uint32(stakingTrackerParams.MinUnbondingTime),
)

if minUnbondingTimeU32 > math.MaxUint16 {
return nil, fmt.Errorf("minimum unbonding time should fit in a uint16")
}

return &StakingParams{
ConfirmationTimeBlocks: uint32(bccParams.BtcConfirmationDepth),
FinalizationTimeoutBlocks: uint32(bccParams.CheckpointFinalizationTimeout),
ConfirmationTimeBlocks: bccParams.BtcConfirmationDepth,
FinalizationTimeoutBlocks: bccParams.CheckpointFinalizationTimeout,
SlashingPkScript: stakingTrackerParams.SlashingPkScript,
CovenantPks: stakingTrackerParams.CovenantPks,
MinSlashingTxFeeSat: stakingTrackerParams.MinSlashingFee,
SlashingRate: stakingTrackerParams.SlashingRate,
CovenantQuruomThreshold: stakingTrackerParams.CovenantQuruomThreshold,
MinUnbondingTime: minUnbondingTime,
MinUnbondingTime: uint16(minUnbondingTimeU32),
UnbondingFee: stakingTrackerParams.UnbondingFee,
MinStakingTime: stakingTrackerParams.MinStakingTime,
MaxStakingTime: stakingTrackerParams.MaxStakingTime,
Expand Down Expand Up @@ -470,15 +467,15 @@ func (bc *BabylonController) QueryStakingTracker() (*StakingTrackerResponse, err
return nil, err
}

// check this early than covenant config makes sense, so that rest of the
// check early that the covenant config makes sense, so that rest of the
// code can assume that:
// 1. covenant quorum is less or equal to number of covenant pks
// 2. covenant pks are not empty
if len(response.Params.CovenantPks) == 0 {
return nil, fmt.Errorf("empty list of covenant pks: %w", ErrInvalidValueReceivedFromBabylonNode)
}

if response.Params.CovenantQuorum > uint32(len(response.Params.CovenantPks)) {
if int(response.Params.CovenantQuorum) > len(response.Params.CovenantPks) {
return nil, fmt.Errorf("covenant quorum is bigger than number of covenant pks: %w", ErrInvalidValueReceivedFromBabylonNode)
}

Expand All @@ -492,15 +489,18 @@ func (bc *BabylonController) QueryStakingTracker() (*StakingTrackerResponse, err
covenantPks = append(covenantPks, covenantBtcPk)
}

if response.Params.MinUnbondingTimeBlocks > math.MaxUint16 {
minUnbondingTimeBlocksU32 := response.Params.MinUnbondingTimeBlocks
if minUnbondingTimeBlocksU32 > math.MaxUint16 {
return nil, fmt.Errorf("min unbonding time is bigger than uint16: %w", ErrInvalidValueReceivedFromBabylonNode)
}

if response.Params.MinStakingTimeBlocks > math.MaxUint16 {
minStakingTimeBlocksU32 := response.Params.MinStakingTimeBlocks
if minStakingTimeBlocksU32 > math.MaxUint16 {
return nil, fmt.Errorf("min staking time is bigger than uint16: %w", ErrInvalidValueReceivedFromBabylonNode)
}

if response.Params.MaxStakingTimeBlocks > math.MaxUint16 {
maxStakingTimeBlocksU32 := response.Params.MaxStakingTimeBlocks
if maxStakingTimeBlocksU32 > math.MaxUint16 {
return nil, fmt.Errorf("max staking time is bigger than uint16: %w", ErrInvalidValueReceivedFromBabylonNode)
}

Expand All @@ -523,10 +523,10 @@ func (bc *BabylonController) QueryStakingTracker() (*StakingTrackerResponse, err
CovenantPks: covenantPks,
MinSlashingFee: btcutil.Amount(response.Params.MinSlashingTxFeeSat),
CovenantQuruomThreshold: response.Params.CovenantQuorum,
MinUnbondingTime: uint16(response.Params.MinUnbondingTimeBlocks),
MinUnbondingTime: uint16(minUnbondingTimeBlocksU32),
UnbondingFee: btcutil.Amount(response.Params.UnbondingFeeSat),
MinStakingTime: uint16(response.Params.MinStakingTimeBlocks),
MaxStakingTime: uint16(response.Params.MaxStakingTimeBlocks),
MinStakingTime: uint16(minStakingTimeBlocksU32),
MaxStakingTime: uint16(maxStakingTimeBlocksU32),
MinStakingValue: btcutil.Amount(response.Params.MinStakingValueSat),
MaxStakingValue: btcutil.Amount(response.Params.MaxStakingValueSat),
}, nil
Expand Down Expand Up @@ -663,7 +663,7 @@ func (bc *BabylonController) QueryFinalityProvider(btcPubKey *btcec.PublicKey) (
}, nil
}

func (bc *BabylonController) QueryHeaderDepth(headerHash *chainhash.Hash) (uint64, error) {
func (bc *BabylonController) QueryHeaderDepth(headerHash *chainhash.Hash) (uint32, error) {
ctx, cancel := getQueryContext(bc.cfg.Timeout)
defer cancel()

Expand Down Expand Up @@ -798,14 +798,15 @@ func (bc *BabylonController) QueryDelegationInfo(stakingTxHash *chainhash.Hash)
return retry.Unrecoverable(fmt.Errorf("malformed unbonding transaction: %s: %w", err.Error(), ErrInvalidValueReceivedFromBabylonNode))
}

if resp.BtcDelegation.UnbondingTime > math.MaxUint16 {
unbondingTimeU32 := resp.BtcDelegation.UnbondingTime
if unbondingTimeU32 > math.MaxUint16 {
return retry.Unrecoverable(fmt.Errorf("malformed unbonding time: %d: %w", resp.BtcDelegation.UnbondingTime, ErrInvalidValueReceivedFromBabylonNode))
}

udi = &UndelegationInfo{
UnbondingTransaction: tx,
CovenantUnbondingSignatures: coventSigInfos,
UnbondingTime: uint16(resp.BtcDelegation.UnbondingTime),
UnbondingTime: uint16(unbondingTimeU32),
}
}

Expand Down
6 changes: 3 additions & 3 deletions babylonclient/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ type BabylonClient interface {
Undelegate(req *UndelegationRequest) (*pv.RelayerTxResponse, error)
QueryFinalityProviders(limit uint64, offset uint64) (*FinalityProvidersClientResponse, error)
QueryFinalityProvider(btcPubKey *btcec.PublicKey) (*FinalityProviderClientResponse, error)
QueryHeaderDepth(headerHash *chainhash.Hash) (uint64, error)
QueryHeaderDepth(headerHash *chainhash.Hash) (uint32, error)
IsTxAlreadyPartOfDelegation(stakingTxHash *chainhash.Hash) (bool, error)
QueryDelegationInfo(stakingTxHash *chainhash.Hash) (*DelegationInfo, error)
}
Expand Down Expand Up @@ -142,9 +142,9 @@ func (m *MockBabylonClient) QueryFinalityProvider(btcPubKey *btcec.PublicKey) (*
}
}

func (m *MockBabylonClient) QueryHeaderDepth(headerHash *chainhash.Hash) (uint64, error) {
func (m *MockBabylonClient) QueryHeaderDepth(headerHash *chainhash.Hash) (uint32, error) {
// return always confirmed depth
return uint64(m.ClientParams.ConfirmationTimeBlocks) + 1, nil
return m.ClientParams.ConfirmationTimeBlocks + 1, nil
}

func (m *MockBabylonClient) IsTxAlreadyPartOfDelegation(stakingTxHash *chainhash.Hash) (bool, error) {
Expand Down
8 changes: 4 additions & 4 deletions babylonclient/msgsender.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ var (
type sendDelegationRequest struct {
utils.Request[*pv.RelayerTxResponse]
dg *DelegationData
requiredInclusionBlockDepth uint64
requiredInclusionBlockDepth uint32
}

func newSendDelegationRequest(
dg *DelegationData,
requiredInclusionBlockDepth uint64,
requiredInclusionBlockDepth uint32,
) sendDelegationRequest {
return sendDelegationRequest{
Request: utils.NewRequest[*pv.RelayerTxResponse](),
Expand Down Expand Up @@ -100,7 +100,7 @@ func (b *BabylonMsgSender) Stop() {

// isBabylonBtcLcReady checks if Babylon BTC light client is ready to receive delegation
func (b *BabylonMsgSender) isBabylonBtcLcReady(
requiredInclusionBlockDepth uint64,
requiredInclusionBlockDepth uint32,
req *DelegationData,
) error {
// no need to consult Babylon if we send delegation without inclusion proof
Expand Down Expand Up @@ -247,7 +247,7 @@ func (m *BabylonMsgSender) handleSentToBabylon() {

func (m *BabylonMsgSender) SendDelegation(
dg *DelegationData,
requiredInclusionBlockDepth uint64,
requiredInclusionBlockDepth uint32,
) (*pv.RelayerTxResponse, error) {
req := newSendDelegationRequest(dg, requiredInclusionBlockDepth)

Expand Down
4 changes: 2 additions & 2 deletions babylonclient/pop.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
)

type BabylonBtcPopType int
type BabylonBtcPopType uint32

const (
SchnorrType BabylonBtcPopType = iota
Expand All @@ -39,7 +39,7 @@ func NewBabylonPop(t BabylonBtcPopType, btcSigOverBbnAddr []byte) (*BabylonPop,
}, nil
}

// NewBabylonBip322Pop build proper BabylonPop in BIP322 style, it verifies the
// NewBabylonBip322Pop build proper BabylonPop in BIP322 style, it verifies
// the bip322 signature validity
func NewBabylonBip322Pop(
msg []byte,
Expand Down
2 changes: 1 addition & 1 deletion cmd/stakercli/admin/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func dumpCfg(c *cli.Context) error {
dir, _ := path.Split(configPath)

if _, err := os.Stat(dir); os.IsNotExist(err) {
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
if err := os.MkdirAll(dir, os.ModeDir); err != nil {
return cli.NewExitError(
fmt.Sprintf("could not create config directory: %s", err.Error()),
1,
Expand Down
11 changes: 11 additions & 0 deletions cmd/stakercli/transaction/parsers.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,14 @@ func parseTagFromHex(tagHex string) ([]byte, error) {

return tag, nil
}

func parseCovenantQuorumFromCliCtx(ctx *cli.Context) (uint32, error) {
covenantQuorumUint64 := ctx.Uint64(covenantQuorumFlag)
if covenantQuorumUint64 == 0 {
return 0, fmt.Errorf("covenant quorum should be greater than 0")
}
if covenantQuorumUint64 > math.MaxUint32 {
return 0, fmt.Errorf("covenant quorum should be less or equal to %d", math.MaxUint32)
}
return uint32(covenantQuorumUint64), nil
}
22 changes: 16 additions & 6 deletions cmd/stakercli/transaction/transactions.go
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,10 @@ func createPhase1StakingTransaction(ctx *cli.Context) error {
return err
}

covenantQuorum := uint32(ctx.Uint64(covenantQuorumFlag))
covenantQuorum, err := parseCovenantQuorumFromCliCtx(ctx)
if err != nil {
return err
}

_, tx, err := btcstaking.BuildV0IdentifiableStakingOutputsAndTx(
tag,
Expand Down Expand Up @@ -402,12 +405,14 @@ func checkPhase1StakingTransaction(ctx *cli.Context) error {
}

covenantMembersPks, err := parseCovenantKeysFromCliCtx(ctx)

if err != nil {
return err
}

covenantQuorum := uint32(ctx.Uint64(covenantQuorumFlag))
covenantQuorum, err := parseCovenantQuorumFromCliCtx(ctx)
if err != nil {
return err
}

stakingTx, err := btcstaking.ParseV0StakingTx(
tx,
Expand Down Expand Up @@ -439,9 +444,14 @@ func checkPhase1StakingTransaction(ctx *cli.Context) error {
}
}

timeBlocks := ctx.Int64(helpers.StakingTimeBlocksFlag)
if timeBlocks > 0 && uint16(timeBlocks) != stakingTx.OpReturnData.StakingTime {
return fmt.Errorf("staking time in tx %d do not match with flag %d", stakingTx.OpReturnData.StakingTime, timeBlocks)
if ctx.Int64(helpers.StakingTimeBlocksFlag) != 0 {
timeBlocks, err := parseLockTimeBlocksFromCliCtx(ctx, helpers.StakingTimeBlocksFlag)
if err != nil {
return err
}
if timeBlocks != stakingTx.OpReturnData.StakingTime {
return fmt.Errorf("staking time in tx %d do not match with flag %d", stakingTx.OpReturnData.StakingTime, timeBlocks)
}
}

txAmount := stakingTx.StakingOutput.Value
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ require (
cosmossdk.io/errors v1.0.1
cosmossdk.io/math v1.3.0
github.com/avast/retry-go/v4 v4.5.1
github.com/babylonlabs-io/babylon v0.12.0
github.com/babylonlabs-io/babylon v0.9.3-0.20241011140836-d0eca74bbfa3
github.com/babylonlabs-io/networks/parameters v0.2.2
github.com/btcsuite/btcd v0.24.2
github.com/btcsuite/btcd/btcec/v2 v2.3.2
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -287,8 +287,8 @@ github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX
github.com/aws/aws-sdk-go v1.44.312 h1:llrElfzeqG/YOLFFKjg1xNpZCFJ2xraIi3PqSuP+95k=
github.com/aws/aws-sdk-go v1.44.312/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
github.com/babylonlabs-io/babylon v0.12.0 h1:s2OTcxpk0RzrkVBnVTfnPdJVYDSqnm/33YKPQqEzNCE=
github.com/babylonlabs-io/babylon v0.12.0/go.mod h1:ZOrTde9vs2xoqGTFw4xhupu2CMulnpywiuk0eh4kPOw=
github.com/babylonlabs-io/babylon v0.9.3-0.20241011140836-d0eca74bbfa3 h1:erQaMtdl2prSINrc4sL/SZrn4+nmEsJ0vzf1FJnN5G8=
github.com/babylonlabs-io/babylon v0.9.3-0.20241011140836-d0eca74bbfa3/go.mod h1:cxRwVqVLoJ39FpyovTEHJLu1lwwrM1tE8davu7nRHwY=
github.com/babylonlabs-io/networks/parameters v0.2.2 h1:TCu39fZvjX5f6ZZrjhYe54M6wWxglNewuKu56yE+zrc=
github.com/babylonlabs-io/networks/parameters v0.2.2/go.mod h1:iEJVOzaLsE33vpP7J4u+CRGfkSIfErUAwRmgCFCBpyI=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
Expand Down
4 changes: 2 additions & 2 deletions staker/babylontypes.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ type inclusionInfo struct {

type sendDelegationRequest struct {
txHash chainhash.Hash
// optional field, if not provided, delegation will be send to Babylon without
// optional field, if not provided, delegation will be sent to Babylon without
// the inclusion proof
inclusionInfo *inclusionInfo
requiredInclusionBlockDepth uint64
requiredInclusionBlockDepth uint32
}

func (app *StakerApp) buildOwnedDelegation(
Expand Down
Loading

0 comments on commit bf8da90

Please sign in to comment.