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

chore: update babylon v0.13 #66

Merged
merged 12 commits into from
Oct 16, 2024
Prev Previous commit
Next Next commit
Merge branch 'main' of github.com:babylonlabs-io/btc-staker into rafi…
…lx/upgrade-babylon
  • Loading branch information
RafilxTenfen committed Oct 16, 2024
commit 5387218fa68c236366df250eb8f62adaf0ca2069
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
* [#65](https://github.com/babylonlabs-io/btc-staker/pull/65) Various fixes to
pre-approval flow. Do not send signed staking transactions to Babylon.

* [#67](https://github.com/babylonlabs-io/btc-staker/pull/67) Enable concurrent
sending of multiple pre-approval staking transactions

## v0.7.2

### Bug fix
Expand Down
51 changes: 27 additions & 24 deletions staker/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,16 @@ import (
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
)

// we can make command to implement StakingEvent interface
var _ StakingEvent = (*stakingRequestCmd)(nil)

type stakingRequestCmd struct {
stakerAddress btcutil.Address
stakingTxHash chainhash.Hash
stakingTx *wire.MsgTx
stakingOutputIdx uint32
stakingOutputPkScript []byte
stakingOutput *wire.TxOut
feeRate chainfee.SatPerKVByte
stakingTime uint16
stakingValue btcutil.Amount
fpBtcPks []*btcec.PublicKey
Expand All @@ -36,9 +35,8 @@ func (req *stakingRequestCmd) isWatched() bool {

func newOwnedStakingCommand(
stakerAddress btcutil.Address,
stakingTx *wire.MsgTx,
stakingOutputIdx uint32,
stakingOutputPkScript []byte,
stakingOutput *wire.TxOut,
feeRate chainfee.SatPerKVByte,
stakingTime uint16,
stakingValue btcutil.Amount,
fpBtcPks []*btcec.PublicKey,
Expand All @@ -48,10 +46,8 @@ func newOwnedStakingCommand(
) *stakingRequestCmd {
return &stakingRequestCmd{
stakerAddress: stakerAddress,
stakingTxHash: stakingTx.TxHash(),
stakingTx: stakingTx,
stakingOutputIdx: stakingOutputIdx,
stakingOutputPkScript: stakingOutputPkScript,
stakingOutput: stakingOutput,
feeRate: feeRate,
stakingTime: stakingTime,
stakingValue: stakingValue,
fpBtcPks: fpBtcPks,
Expand All @@ -65,6 +61,12 @@ func newOwnedStakingCommand(
}

type watchTxDataCmd struct {
// watched tx data
stakingTxHash chainhash.Hash
stakingTx *wire.MsgTx
stakingOutputIdx uint32
stakingOutputPkScript []byte

slashingTx *wire.MsgTx
slashingTxSig *schnorr.Signature
stakerBabylonAddr sdk.AccAddress
Expand Down Expand Up @@ -97,32 +99,33 @@ func newWatchedStakingCmd(
) *stakingRequestCmd {
return &stakingRequestCmd{
stakerAddress: stakerAddress,
stakingTxHash: stakingTx.TxHash(),
stakingTx: stakingTx,
stakingOutputIdx: stakingOutputIdx,
stakingOutputPkScript: stakingOutputPkScript,
stakingTime: stakingTime,
stakingValue: stakingValue,
fpBtcPks: fpBtcPks,
requiredDepthOnBtcChain: confirmationTimeBlocks,
pop: pop,
watchTxData: &watchTxDataCmd{
slashingTx: slashingTx,
slashingTxSig: slashingTxSignature,
stakerBabylonAddr: stakerBabylonAddr,
stakerBtcPk: stakerBtcPk,
unbondingTx: unbondingTx,
slashUnbondingTx: slashUnbondingTx,
slashUnbondingTxSig: slashUnbondingTxSig,
unbondingTime: unbondingTime,
stakingTxHash: stakingTx.TxHash(),
stakingTx: stakingTx,
stakingOutputIdx: stakingOutputIdx,
stakingOutputPkScript: stakingOutputPkScript,
slashingTx: slashingTx,
slashingTxSig: slashingTxSignature,
stakerBabylonAddr: stakerBabylonAddr,
stakerBtcPk: stakerBtcPk,
unbondingTx: unbondingTx,
slashUnbondingTx: slashUnbondingTx,
slashUnbondingTxSig: slashUnbondingTxSig,
unbondingTime: unbondingTime,
},
errChan: make(chan error, 1),
successChan: make(chan *chainhash.Hash, 1),
}
}

func (event *stakingRequestCmd) EventId() chainhash.Hash {
return event.stakingTxHash
// we do not have has for this event
return chainhash.Hash{}
}

func (event *stakingRequestCmd) EventDesc() string {
Expand Down
102 changes: 59 additions & 43 deletions staker/stakerapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -1261,23 +1261,29 @@ func (app *StakerApp) sendDelegationToBabylonTask(
}
}

func (app *StakerApp) handlePreApprovalCmd(cmd *stakingRequestCmd) error {
func (app *StakerApp) handlePreApprovalCmd(
cmd *stakingRequestCmd,
stakingTx *wire.MsgTx,
stakingOutputIdx uint32,
) (*chainhash.Hash, error) {
// just to pass to buildAndSendDelegation
fakeStoredTx, err := stakerdb.CreateTrackedTransaction(
cmd.stakingTx,
cmd.stakingOutputIdx,
stakingTx,
stakingOutputIdx,
cmd.stakingTime,
cmd.fpBtcPks,
babylonPopToDbPop(cmd.pop),
cmd.stakerAddress,
)

if err != nil {
return err
return nil, err
}

stakingTxHash := stakingTx.TxHash()

req := &sendDelegationRequest{
txHash: cmd.stakingTxHash,
txHash: stakingTxHash,
inclusionInfo: nil,
requiredInclusionBlockDepth: cmd.requiredDepthOnBtcChain,
}
Expand All @@ -1289,12 +1295,12 @@ func (app *StakerApp) handlePreApprovalCmd(cmd *stakingRequestCmd) error {
)

if err != nil {
return err
return nil, err
}

err = app.txTracker.AddTransactionSentToBabylon(
cmd.stakingTx,
cmd.stakingOutputIdx,
stakingTx,
stakingOutputIdx,
cmd.stakingTime,
cmd.fpBtcPks,
babylonPopToDbPop(cmd.pop),
Expand All @@ -1304,70 +1310,88 @@ func (app *StakerApp) handlePreApprovalCmd(cmd *stakingRequestCmd) error {
)

if err != nil {
return err
return nil, err
}

app.wg.Add(1)
go app.checkForUnbondingTxSignaturesOnBabylon(&cmd.stakingTxHash)
go app.checkForUnbondingTxSignaturesOnBabylon(&stakingTxHash)

return nil
return &stakingTxHash, nil
}

func (app *StakerApp) handlePostApprovalCmd(cmd *stakingRequestCmd) error {
func (app *StakerApp) handlePostApprovalCmd(
cmd *stakingRequestCmd,
stakingTx *wire.MsgTx,
stakingOutputIdx uint32,
) (*chainhash.Hash, error) {
stakingTxHash := stakingTx.TxHash()

bestBlockHeight := app.currentBestBlockHeight.Load()

err := app.wc.UnlockWallet(defaultWalletUnlockTimeout)

if err != nil {
return err
return nil, err
}

tx, fullySignd, err := app.wc.SignRawTransaction(cmd.stakingTx)
tx, fullySignd, err := app.wc.SignRawTransaction(stakingTx)

if err != nil {
return err
return nil, err
}

if !fullySignd {
return fmt.Errorf("failed to fully sign transaction with hash %s", cmd.stakingTxHash)
return nil, fmt.Errorf("failed to fully sign transaction with hash %s", stakingTxHash)
}

_, err = app.wc.SendRawTransaction(tx, true)

if err != nil {
return err
return nil, err
}

stakingOutputPkScript := cmd.stakingTx.TxOut[cmd.stakingOutputIdx].PkScript
stakingOutputPkScript := stakingTx.TxOut[stakingOutputIdx].PkScript

if err := app.waitForStakingTransactionConfirmation(
&cmd.stakingTxHash,
&stakingTxHash,
stakingOutputPkScript,
cmd.requiredDepthOnBtcChain,
uint32(bestBlockHeight),
); err != nil {
return err
return nil, err
}

if err := app.txTracker.AddTransaction(
cmd.stakingTx,
cmd.stakingOutputIdx,
if err := app.txTracker.AddTransactionSentToBTC(
stakingTx,
stakingOutputIdx,
cmd.stakingTime,
cmd.fpBtcPks,
babylonPopToDbPop(cmd.pop),
cmd.stakerAddress,
); err != nil {
return err
return nil, err
}

return nil
return &stakingTxHash, nil
}

func (app *StakerApp) handleStakingCmd(cmd *stakingRequestCmd) error {
func (app *StakerApp) handleStakingCmd(cmd *stakingRequestCmd) (*chainhash.Hash, error) {
// Create unsigned transaction by wallet without signing. Signing will happen
// in next steps
stakingTx, err := app.wc.CreateTransaction(
[]*wire.TxOut{cmd.stakingOutput},
btcutil.Amount(cmd.feeRate),
cmd.stakerAddress,
app.filterUtxoFnGen(),
)
if err != nil {
return nil, fmt.Errorf("failed to build staking transaction: %w", err)
}

if cmd.usePreApprovalFlow {
return app.handlePreApprovalCmd(cmd)
return app.handlePreApprovalCmd(cmd, stakingTx, 0)
} else {
return app.handlePostApprovalCmd(cmd)
return app.handlePostApprovalCmd(cmd, stakingTx, 0)
}
}

Expand All @@ -1383,8 +1407,8 @@ func (app *StakerApp) handleStakingCommands() {
bestBlockHeight := app.currentBestBlockHeight.Load()

err := app.txTracker.AddWatchedTransaction(
cmd.stakingTx,
cmd.stakingOutputIdx,
cmd.watchTxData.stakingTx,
cmd.watchTxData.stakingOutputIdx,
cmd.stakingTime,
cmd.fpBtcPks,
babylonPopToDbPop(cmd.pop),
Expand All @@ -1406,8 +1430,8 @@ func (app *StakerApp) handleStakingCommands() {

// we assume tx is already on btc chain, so we need to wait for confirmation
if err := app.waitForStakingTransactionConfirmation(
&cmd.stakingTxHash,
cmd.stakingTx.TxOut[cmd.stakingOutputIdx].PkScript,
&cmd.watchTxData.stakingTxHash,
cmd.watchTxData.stakingTx.TxOut[cmd.watchTxData.stakingOutputIdx].PkScript,
cmd.requiredDepthOnBtcChain,
uint32(bestBlockHeight),
); err != nil {
Expand All @@ -1416,12 +1440,12 @@ func (app *StakerApp) handleStakingCommands() {
}

app.m.ValidReceivedDelegationRequests.Inc()
cmd.successChan <- &cmd.stakingTxHash
cmd.successChan <- &cmd.watchTxData.stakingTxHash
app.logStakingEventProcessed(cmd)
continue
}

err := app.handleStakingCmd(cmd)
stakingTxHash, err := app.handleStakingCmd(cmd)

if err != nil {
utils.PushOrQuit(
Expand All @@ -1432,7 +1456,7 @@ func (app *StakerApp) handleStakingCommands() {
} else {
utils.PushOrQuit(
cmd.successChan,
&cmd.stakingTxHash,
stakingTxHash,
app.quit,
)
}
Expand Down Expand Up @@ -1821,14 +1845,6 @@ func (app *StakerApp) StakeFunds(

feeRate := app.feeEstimator.EstimateFeePerKb()

// Create unsigned transaction by wallet without signing. Signing will happen
// in next steps
tx, err := app.wc.CreateTransaction([]*wire.TxOut{stakingInfo.StakingOutput}, btcutil.Amount(feeRate), stakerAddress)

if err != nil {
return nil, err
}

app.logger.WithFields(logrus.Fields{
"stakerAddress": stakerAddress,
"stakingAmount": stakingInfo.StakingOutput,
Expand Down
Loading
Loading
You are viewing a condensed version of this merge commit. You can view the full changes here.