diff --git a/CHANGELOG.md b/CHANGELOG.md index 80a5d10e..bdcfd39b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) * [#84](https://github.com/babylonlabs-io/vigilante/pull/84) fix spawning more go routines than needed when activating delegations, add more logging +### Improvements +* [#87](https://github.com/babylonlabs-io/vigilante/pull/87) adr 029 for generalized unbonding ## v0.13.0 diff --git a/btcstaking-tracker/btcslasher/bootstrapping.go b/btcstaking-tracker/btcslasher/bootstrapping.go index 119c4b20..4c522c49 100644 --- a/btcstaking-tracker/btcslasher/bootstrapping.go +++ b/btcstaking-tracker/btcslasher/bootstrapping.go @@ -2,6 +2,7 @@ package btcslasher import ( "fmt" + "github.com/babylonlabs-io/babylon/types" ftypes "github.com/babylonlabs-io/babylon/x/finality/types" "github.com/cosmos/cosmos-sdk/types/query" @@ -22,16 +23,29 @@ func (bs *BTCSlasher) Bootstrap(startHeight uint64) error { // handle all evidences since the given start height, i.e., for each evidence, // extract its SK and try to slash all BTC delegations under it - err := bs.handleAllEvidences(startHeight, func(evidences []*ftypes.Evidence) error { + err := bs.handleAllEvidences(startHeight, func(evidences []*ftypes.EvidenceResponse) error { var accumulatedErrs error // we use this variable to accumulate errors for _, evidence := range evidences { - fpBTCPK := evidence.FpBtcPk - fpBTCPKHex := fpBTCPK.MarshalHex() + fpBTCPKHex := evidence.FpBtcPkHex bs.logger.Infof("found evidence for finality provider %s at height %d after start height %d", fpBTCPKHex, evidence.BlockHeight, startHeight) + btcPK, err := types.NewBIP340PubKeyFromHex(fpBTCPKHex) + if err != nil { + return fmt.Errorf("err parsing fp btc %w", err) + } + + e := ftypes.Evidence{ + FpBtcPk: btcPK, + BlockHeight: evidence.BlockHeight, + PubRand: evidence.PubRand, + CanonicalAppHash: evidence.CanonicalAppHash, + ForkAppHash: evidence.ForkAppHash, + CanonicalFinalitySig: evidence.CanonicalFinalitySig, + ForkFinalitySig: evidence.ForkFinalitySig, + } // extract the SK of the slashed finality provider - fpBTCSK, err := evidence.ExtractBTCSK() + fpBTCSK, err := e.ExtractBTCSK() if err != nil { bs.logger.Errorf("failed to extract BTC SK of the slashed finality provider %s: %v", fpBTCPKHex, err) accumulatedErrs = multierror.Append(accumulatedErrs, err) @@ -57,7 +71,7 @@ func (bs *BTCSlasher) Bootstrap(startHeight uint64) error { return nil } -func (bs *BTCSlasher) handleAllEvidences(startHeight uint64, handleFunc func(evidences []*ftypes.Evidence) error) error { +func (bs *BTCSlasher) handleAllEvidences(startHeight uint64, handleFunc func(evidences []*ftypes.EvidenceResponse) error) error { pagination := query.PageRequest{Limit: defaultPaginationLimit} for { resp, err := bs.BBNQuerier.ListEvidences(startHeight, &pagination) diff --git a/btcstaking-tracker/btcslasher/bootstrapping_test.go b/btcstaking-tracker/btcslasher/bootstrapping_test.go index 5582aa70..d0c6b4ba 100644 --- a/btcstaking-tracker/btcslasher/bootstrapping_test.go +++ b/btcstaking-tracker/btcslasher/bootstrapping_test.go @@ -98,8 +98,17 @@ func FuzzSlasher_Bootstrapping(f *testing.F) { // mock an evidence with this finality provider evidence, err := datagen.GenRandomEvidence(r, fpSK, 100) require.NoError(t, err) + er := &ftypes.EvidenceResponse{ + FpBtcPkHex: evidence.FpBtcPk.MarshalHex(), + BlockHeight: evidence.BlockHeight, + PubRand: evidence.PubRand, + CanonicalAppHash: evidence.CanonicalAppHash, + ForkAppHash: evidence.ForkAppHash, + CanonicalFinalitySig: evidence.CanonicalFinalitySig, + ForkFinalitySig: evidence.ForkFinalitySig, + } mockBabylonQuerier.EXPECT().ListEvidences(gomock.Any(), gomock.Any()).Return(&ftypes.QueryListEvidencesResponse{ - Evidences: []*ftypes.Evidence{evidence}, + Evidences: []*ftypes.EvidenceResponse{er}, Pagination: &query.PageResponse{NextKey: nil}, }, nil).Times(1) diff --git a/btcstaking-tracker/btcslasher/slasher_test.go b/btcstaking-tracker/btcslasher/slasher_test.go index d9f3dca8..5e68a5cb 100644 --- a/btcstaking-tracker/btcslasher/slasher_test.go +++ b/btcstaking-tracker/btcslasher/slasher_test.go @@ -261,10 +261,10 @@ func FuzzSlasher(f *testing.F) { err = unbondingSlashingInfo.UnbondingTx.Serialize(&unbondingTxBuffer) require.NoError(t, err) unbondingBTCDel.BtcUndelegation = &bstypes.BTCUndelegation{ - UnbondingTx: unbondingTxBuffer.Bytes(), - SlashingTx: unbondingSlashingInfo.SlashingTx, - DelegatorSlashingSig: delSlashingSig, - DelegatorUnbondingSig: delSlashingSig, + UnbondingTx: unbondingTxBuffer.Bytes(), + SlashingTx: unbondingSlashingInfo.SlashingTx, + DelegatorSlashingSig: delSlashingSig, + DelegatorUnbondingInfo: &bstypes.DelegatorUnbondingInfo{SpendStakeTx: unbondingTxBuffer.Bytes()}, // TODO: currently requires only one sig, in reality requires all of them CovenantSlashingSigs: covenantSlashingSigs, CovenantUnbondingSigList: covenantUnbondingSigs, diff --git a/btcstaking-tracker/btcslasher/slasher_utils.go b/btcstaking-tracker/btcslasher/slasher_utils.go index b4a5959b..db6a98b5 100644 --- a/btcstaking-tracker/btcslasher/slasher_utils.go +++ b/btcstaking-tracker/btcslasher/slasher_utils.go @@ -423,8 +423,7 @@ func (bs *BTCSlasher) getAllActiveAndUnbondedBTCDelegations( activeDels = append(activeDels, dels.Dels[i]) } if strings.EqualFold(del.StatusDesc, bstypes.BTCDelegationStatus_UNBONDED.String()) && - len(del.UndelegationResponse.CovenantSlashingSigs) >= int(bsParams.CovenantQuorum) && - len(del.UndelegationResponse.DelegatorUnbondingSigHex) > 0 { + len(del.UndelegationResponse.CovenantSlashingSigs) >= int(bsParams.CovenantQuorum) { // NOTE: Babylon considers a BTC delegation to be unbonded once it // receives staker signature for unbonding transaction, no matter // whether the unbonding tx's timelock has expired. In monitor's view we need to try to slash every diff --git a/btcstaking-tracker/stakingeventwatcher/expected_babylon_client.go b/btcstaking-tracker/stakingeventwatcher/expected_babylon_client.go index 52537ce0..63a47ba2 100644 --- a/btcstaking-tracker/stakingeventwatcher/expected_babylon_client.go +++ b/btcstaking-tracker/stakingeventwatcher/expected_babylon_client.go @@ -10,7 +10,6 @@ import ( bbnclient "github.com/babylonlabs-io/babylon/client/client" bbn "github.com/babylonlabs-io/babylon/types" btcstakingtypes "github.com/babylonlabs-io/babylon/x/btcstaking/types" - "github.com/btcsuite/btcd/btcec/v2/schnorr" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/wire" "github.com/cosmos/cosmos-sdk/types/query" @@ -28,7 +27,8 @@ type BabylonNodeAdapter interface { DelegationsByStatus(status btcstakingtypes.BTCDelegationStatus, offset uint64, limit uint64) ([]Delegation, error) IsDelegationActive(stakingTxHash chainhash.Hash) (bool, error) IsDelegationVerified(stakingTxHash chainhash.Hash) (bool, error) - ReportUnbonding(ctx context.Context, stakingTxHash chainhash.Hash, stakerUnbondingSig *schnorr.Signature) error + ReportUnbonding(ctx context.Context, stakingTxHash chainhash.Hash, stakeSpendingTx *wire.MsgTx, + inclusionProof *btcstakingtypes.InclusionProof) error BtcClientTipHeight() (uint32, error) ActivateDelegation(ctx context.Context, stakingTxHash chainhash.Hash, proof *btcctypes.BTCSpvProof) error } @@ -111,17 +111,23 @@ func (bca *BabylonClientAdapter) IsDelegationVerified(stakingTxHash chainhash.Ha func (bca *BabylonClientAdapter) ReportUnbonding( ctx context.Context, stakingTxHash chainhash.Hash, - stakerUnbondingSig *schnorr.Signature) error { + stakeSpendingTx *wire.MsgTx, + inclusionProof *btcstakingtypes.InclusionProof) error { signer := bca.babylonClient.MustGetAddr() + stakeSpendingBytes, err := bbn.SerializeBTCTx(stakeSpendingTx) + if err != nil { + return err + } + msg := btcstakingtypes.MsgBTCUndelegate{ - Signer: signer, - StakingTxHash: stakingTxHash.String(), - UnbondingTxSig: bbn.NewBIP340SignatureFromBTCSig(stakerUnbondingSig), + Signer: signer, + StakingTxHash: stakingTxHash.String(), + StakeSpendingTx: stakeSpendingBytes, + StakeSpendingTxInclusionProof: inclusionProof, } resp, err := bca.babylonClient.ReliablySendMsg(ctx, &msg, []*errors.Error{}, []*errors.Error{}) - if err != nil && resp != nil { return fmt.Errorf("msg MsgBTCUndelegate failed exeuction with code %d and error %w", resp.Code, err) } @@ -141,7 +147,7 @@ func (bca *BabylonClientAdapter) BtcClientTipHeight() (uint32, error) { return 0, fmt.Errorf("failed to retrieve btc light client tip from babyln: %w", err) } - return uint32(resp.Header.Height), nil + return resp.Header.Height, nil } // ActivateDelegation provides inclusion proof to activate delegation diff --git a/btcstaking-tracker/stakingeventwatcher/mock_babylon_client.go b/btcstaking-tracker/stakingeventwatcher/mock_babylon_client.go index d38ea704..2daedc39 100644 --- a/btcstaking-tracker/stakingeventwatcher/mock_babylon_client.go +++ b/btcstaking-tracker/stakingeventwatcher/mock_babylon_client.go @@ -10,8 +10,8 @@ import ( types "github.com/babylonlabs-io/babylon/x/btccheckpoint/types" types0 "github.com/babylonlabs-io/babylon/x/btcstaking/types" - schnorr "github.com/btcsuite/btcd/btcec/v2/schnorr" chainhash "github.com/btcsuite/btcd/chaincfg/chainhash" + wire "github.com/btcsuite/btcd/wire" gomock "github.com/golang/mock/gomock" ) @@ -113,15 +113,15 @@ func (mr *MockBabylonNodeAdapterMockRecorder) IsDelegationVerified(stakingTxHash } // ReportUnbonding mocks base method. -func (m *MockBabylonNodeAdapter) ReportUnbonding(ctx context.Context, stakingTxHash chainhash.Hash, stakerUnbondingSig *schnorr.Signature) error { +func (m *MockBabylonNodeAdapter) ReportUnbonding(ctx context.Context, stakingTxHash chainhash.Hash, stakeSpendingTx *wire.MsgTx, inclusionProof *types0.InclusionProof) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ReportUnbonding", ctx, stakingTxHash, stakerUnbondingSig) + ret := m.ctrl.Call(m, "ReportUnbonding", ctx, stakingTxHash, stakeSpendingTx, inclusionProof) ret0, _ := ret[0].(error) return ret0 } // ReportUnbonding indicates an expected call of ReportUnbonding. -func (mr *MockBabylonNodeAdapterMockRecorder) ReportUnbonding(ctx, stakingTxHash, stakerUnbondingSig interface{}) *gomock.Call { +func (mr *MockBabylonNodeAdapterMockRecorder) ReportUnbonding(ctx, stakingTxHash, stakeSpendingTx, inclusionProof interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReportUnbonding", reflect.TypeOf((*MockBabylonNodeAdapter)(nil).ReportUnbonding), ctx, stakingTxHash, stakerUnbondingSig) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReportUnbonding", reflect.TypeOf((*MockBabylonNodeAdapter)(nil).ReportUnbonding), ctx, stakingTxHash, stakeSpendingTx, inclusionProof) } diff --git a/btcstaking-tracker/stakingeventwatcher/stakingeventwatcher.go b/btcstaking-tracker/stakingeventwatcher/stakingeventwatcher.go index 85b709da..c241da20 100644 --- a/btcstaking-tracker/stakingeventwatcher/stakingeventwatcher.go +++ b/btcstaking-tracker/stakingeventwatcher/stakingeventwatcher.go @@ -342,39 +342,11 @@ func tryParseStakerSignatureFromSpentTx(tx *wire.MsgTx, td *TrackedDelegation) ( return schnorr.ParseSignature(stakerSignature) } -// waitForDelegationToStopBeingActive polls babylon until delegation is no longer active. -func (sew *StakingEventWatcher) waitForDelegationToStopBeingActive( - ctx context.Context, - stakingTxHash chainhash.Hash, -) { - _ = retry.Do(func() error { - active, err := sew.babylonNodeAdapter.IsDelegationActive(stakingTxHash) - - if err != nil { - return fmt.Errorf("error checking if delegation is active: %v", err) - } - - if !active { - return nil - } - - return fmt.Errorf("delegation for staking tx %s is still active", stakingTxHash) - }, - retry.Context(ctx), - retryForever, - fixedDelyTypeWithJitter, - retry.MaxDelay(sew.cfg.CheckDelegationActiveInterval), - retry.MaxJitter(sew.cfg.RetryJitter), - retry.OnRetry(func(n uint, err error) { - sew.logger.Debugf("retrying checking if delegation is active for staking tx %s. Attempt: %d. Err: %v", stakingTxHash, n, err) - }), - ) -} - func (sew *StakingEventWatcher) reportUnbondingToBabylon( ctx context.Context, stakingTxHash chainhash.Hash, - unbondingSignature *schnorr.Signature, + stakeSpendingTx *wire.MsgTx, + proof *btcstakingtypes.InclusionProof, ) { _ = retry.Do(func() error { active, err := sew.babylonNodeAdapter.IsDelegationActive(stakingTxHash) @@ -394,7 +366,7 @@ func (sew *StakingEventWatcher) reportUnbondingToBabylon( return nil } - if err = sew.babylonNodeAdapter.ReportUnbonding(ctx, stakingTxHash, unbondingSignature); err != nil { + if err = sew.babylonNodeAdapter.ReportUnbonding(ctx, stakingTxHash, stakeSpendingTx, proof); err != nil { sew.metrics.FailedReportedUnbondingTransactions.Inc() return fmt.Errorf("error reporting unbonding tx %s to babylon: %v", stakingTxHash, err) } @@ -426,7 +398,7 @@ func (sew *StakingEventWatcher) watchForSpend(spendEvent *notifier.SpendEvent, t return } - schnorrSignature, err := tryParseStakerSignatureFromSpentTx(spendingTx, td) + _, err := tryParseStakerSignatureFromSpentTx(spendingTx, td) delegationId := td.StakingTx.TxHash() spendingTxHash := spendingTx.TxHash() @@ -437,13 +409,23 @@ func (sew *StakingEventWatcher) watchForSpend(spendEvent *notifier.SpendEvent, t // As we only care about unbonding transactions, we do not need to take additional actions. // We start polling babylon for delegation to stop being active, and then delete it from unbondingTracker. sew.logger.Debugf("Spending tx %s for staking tx %s is not unbonding tx. Info: %v", spendingTxHash, delegationId, err) - sew.waitForDelegationToStopBeingActive(quitCtx, delegationId) + proof, err := sew.waitForStakeSpendInclusionProof(quitCtx, spendingTx) + if err != nil { + sew.logger.Errorf("unbonding tx %s for staking tx %s proof not built", spendingTxHash, delegationId) + return + } + sew.reportUnbondingToBabylon(quitCtx, delegationId, spendingTx, proof) } else { sew.metrics.DetectedUnbondingTransactionsCounter.Inc() // We found valid unbonding tx. We need to try to report it to babylon. // We stop reporting if delegation is no longer active or we succeed. + proof, err := sew.waitForStakeSpendInclusionProof(quitCtx, spendingTx) + if err != nil { + sew.logger.Errorf("unbonding tx %s for staking tx %s proof not built", spendingTxHash, delegationId) + return + } sew.logger.Debugf("found unbonding tx %s for staking tx %s", spendingTxHash, delegationId) - sew.reportUnbondingToBabylon(quitCtx, delegationId, schnorrSignature) + sew.reportUnbondingToBabylon(quitCtx, delegationId, spendingTx, proof) sew.logger.Debugf("unbonding tx %s for staking tx %s reported to babylon", spendingTxHash, delegationId) } @@ -454,6 +436,65 @@ func (sew *StakingEventWatcher) watchForSpend(spendEvent *notifier.SpendEvent, t ) } +func (sew *StakingEventWatcher) buildSpendingTxProof(spendingTx *wire.MsgTx) (*btcstakingtypes.InclusionProof, error) { + txHash := spendingTx.TxHash() + if len(spendingTx.TxOut) == 0 { + panic(fmt.Errorf("stake spending tx has no outputs %s", spendingTx.TxHash().String())) // this is a software error + } + details, status, err := sew.btcClient.TxDetails(&txHash, spendingTx.TxOut[0].PkScript) + if err != nil { + return nil, err + } + + if status != btcclient.TxInChain { + return nil, nil + } + + btcTxs := types.GetWrappedTxs(details.Block) + ib := types.NewIndexedBlock(int32(details.BlockHeight), &details.Block.Header, btcTxs) + + proof, err := ib.GenSPVProof(int(details.TxIndex)) + if err != nil { + return nil, err + } + + return btcstakingtypes.NewInclusionProofFromSpvProof(proof), nil +} + +// waitForStakeSpendInclusionProof polls btc until stake spend tx has inclusion proof built +func (sew *StakingEventWatcher) waitForStakeSpendInclusionProof( + ctx context.Context, + spendingTx *wire.MsgTx, +) (*btcstakingtypes.InclusionProof, error) { + var ( + proof *btcstakingtypes.InclusionProof + err error + ) + _ = retry.Do(func() error { + proof, err = sew.buildSpendingTxProof(spendingTx) + if err != nil { + return err + } + + if proof == nil { + return fmt.Errorf("proof not yet built") + } + + return nil + }, + retry.Context(ctx), + retryForever, + fixedDelyTypeWithJitter, + retry.MaxDelay(sew.cfg.CheckDelegationActiveInterval), + retry.MaxJitter(sew.cfg.RetryJitter), + retry.OnRetry(func(n uint, err error) { + sew.logger.Debugf("retrying checking if stake spending tx is in chain %s. Attempt: %d. Err: %v", spendingTx.TxHash(), n, err) + }), + ) + + return proof, nil +} + func (sew *StakingEventWatcher) handleUnbondedDelegations() { defer sew.wg.Done() for { diff --git a/e2etest/atomicslasher_e2e_test.go b/e2etest/atomicslasher_e2e_test.go index aa85d872..8ada2f98 100644 --- a/e2etest/atomicslasher_e2e_test.go +++ b/e2etest/atomicslasher_e2e_test.go @@ -218,7 +218,7 @@ func TestAtomicSlasher_Unbonding(t *testing.T) { /* the victim BTC delegation unbonds */ - tm.Undelegate(t, stakingSlashingInfo, unbondingSlashingInfo, btcDelSK) + tm.Undelegate(t, stakingSlashingInfo, unbondingSlashingInfo, btcDelSK, func() { tm.CatchUpBTCLightClient(t) }) /* finality provider builds unbonding slashing tx witness and sends it to Bitcoin diff --git a/e2etest/container/config.go b/e2etest/container/config.go index f71c3840..5bdade25 100644 --- a/e2etest/container/config.go +++ b/e2etest/container/config.go @@ -24,13 +24,13 @@ const ( // NewImageConfig returns ImageConfig needed for running e2e test. func NewImageConfig(t *testing.T) ImageConfig { - babylondVersion, err := testutil.GetBabylonVersion() + babylonVersion, err := testutil.GetBabylonVersion() require.NoError(t, err) return ImageConfig{ BitcoindRepository: dockerBitcoindRepository, BitcoindVersion: dockerBitcoindVersionTag, BabylonRepository: dockerBabylondRepository, - BabylonVersion: babylondVersion, + BabylonVersion: babylonVersion, } } diff --git a/e2etest/slasher_e2e_test.go b/e2etest/slasher_e2e_test.go index 4f717706..c8e36bb8 100644 --- a/e2etest/slasher_e2e_test.go +++ b/e2etest/slasher_e2e_test.go @@ -187,7 +187,7 @@ func TestSlasher_SlashingUnbonding(t *testing.T) { stakingSlashingInfo1, unbondingSlashingInfo1, stakerPrivKey1 := tm.CreateBTCDelegation(t, fpSK) // undelegate - unbondingSlashingInfo, _ := tm.Undelegate(t, stakingSlashingInfo1, unbondingSlashingInfo1, stakerPrivKey1) + unbondingSlashingInfo, _ := tm.Undelegate(t, stakingSlashingInfo1, unbondingSlashingInfo1, stakerPrivKey1, func() { tm.CatchUpBTCLightClient(t) }) // commit public randomness, vote and equivocate tm.VoteAndEquivocate(t, fpSK) diff --git a/e2etest/test_manager_btcstaking.go b/e2etest/test_manager_btcstaking.go index 818d4e2f..1b1d1dbe 100644 --- a/e2etest/test_manager_btcstaking.go +++ b/e2etest/test_manager_btcstaking.go @@ -472,7 +472,8 @@ func (tm *TestManager) Undelegate( t *testing.T, stakingSlashingInfo *datagen.TestStakingSlashingInfo, unbondingSlashingInfo *datagen.TestUnbondingSlashingInfo, - delSK *btcec.PrivateKey) (*datagen.TestUnbondingSlashingInfo, *schnorr.Signature) { + delSK *btcec.PrivateKey, + catchUpLightClientFunc func()) (*datagen.TestUnbondingSlashingInfo, *schnorr.Signature) { signerAddr := tm.BabylonClient.MustGetAddr() // TODO: This generates unbonding tx signature, move it to undelegate @@ -491,14 +492,9 @@ func (tm *TestManager) Undelegate( ) require.NoError(t, err) - msgUndel := &bstypes.MsgBTCUndelegate{ - Signer: signerAddr, - StakingTxHash: stakingSlashingInfo.StakingTx.TxHash().String(), - UnbondingTxSig: bbn.NewBIP340SignatureFromBTCSig(unbondingTxSchnorrSig), - } - _, err = tm.BabylonClient.ReliablySendMsg(context.Background(), msgUndel, nil, nil) + var unbondingTxBuf bytes.Buffer + err = unbondingSlashingInfo.UnbondingTx.Serialize(&unbondingTxBuf) require.NoError(t, err) - t.Logf("submitted MsgBTCUndelegate") resp, err := tm.BabylonClient.BTCDelegation(stakingSlashingInfo.StakingTx.TxHash().String()) require.NoError(t, err) @@ -527,6 +523,22 @@ func (tm *TestManager) Undelegate( mBlock := tm.mineBlock(t) require.Equal(t, 2, len(mBlock.Transactions)) + catchUpLightClientFunc() + + unbondingTxInfo := getTxInfo(t, mBlock) + msgUndel := &bstypes.MsgBTCUndelegate{ + Signer: signerAddr, + StakingTxHash: stakingSlashingInfo.StakingTx.TxHash().String(), + StakeSpendingTx: unbondingTxBuf.Bytes(), + StakeSpendingTxInclusionProof: &bstypes.InclusionProof{ + Key: unbondingTxInfo.Key, + Proof: unbondingTxInfo.Proof, + }, + } + _, err = tm.BabylonClient.ReliablySendMsg(context.Background(), msgUndel, nil, nil) + require.NoError(t, err) + t.Logf("submitted MsgBTCUndelegate") + // wait until unbonding tx is on Bitcoin require.Eventually(t, func() bool { resp, err := tm.BTCClient.GetRawTransactionVerbose(unbondingTxHash) diff --git a/e2etest/unbondingwatcher_e2e_test.go b/e2etest/unbondingwatcher_e2e_test.go index f87490af..4308e890 100644 --- a/e2etest/unbondingwatcher_e2e_test.go +++ b/e2etest/unbondingwatcher_e2e_test.go @@ -103,6 +103,8 @@ func TestUnbondingWatcher(t *testing.T) { minedBlock := tm.mineBlock(t) require.Equal(t, 2, len(minedBlock.Transactions)) + tm.CatchUpBTCLightClient(t) + require.Eventually(t, func() bool { resp, err := tm.BabylonClient.BTCDelegation(stakingSlashingInfo.StakingTx.TxHash().String()) require.NoError(t, err) diff --git a/go.mod b/go.mod index c14a2009..dfe6b532 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( cosmossdk.io/log v1.4.1 cosmossdk.io/math v1.3.0 github.com/avast/retry-go/v4 v4.6.0 - github.com/babylonlabs-io/babylon v0.13.0 + github.com/babylonlabs-io/babylon v0.14.0 github.com/boljen/go-bitmap v0.0.0-20151001105940-23cd2fb0ce7d github.com/btcsuite/btcd v0.24.2 github.com/btcsuite/btcd/btcec/v2 v2.3.2 @@ -66,7 +66,7 @@ require ( github.com/99designs/keyring v1.2.1 // indirect github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect github.com/CosmWasm/wasmd v0.53.0 // indirect - github.com/CosmWasm/wasmvm/v2 v2.1.2 // indirect + github.com/CosmWasm/wasmvm/v2 v2.1.3 // indirect github.com/DataDog/datadog-go v3.2.0+incompatible // indirect github.com/DataDog/zstd v1.5.5 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect diff --git a/go.sum b/go.sum index 68a7e0ce..57a25d81 100644 --- a/go.sum +++ b/go.sum @@ -227,8 +227,8 @@ github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbi github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/CosmWasm/wasmd v0.53.0 h1:kdaoAi20bIb4VCsxw9pRaT2g5PpIp82Wqrr9DRVN9ao= github.com/CosmWasm/wasmd v0.53.0/go.mod h1:FJl/aWjdpGof3usAMFQpDe07Rkx77PUzp0cygFMOvtw= -github.com/CosmWasm/wasmvm/v2 v2.1.2 h1:GkJ5bAsRlLHfIQVg/FY1VHwLyBwlCjAhDea0B8L+e20= -github.com/CosmWasm/wasmvm/v2 v2.1.2/go.mod h1:bMhLQL4Yp9CzJi9A83aR7VO9wockOsSlZbT4ztOl6bg= +github.com/CosmWasm/wasmvm/v2 v2.1.3 h1:CSJTauZqkHyb9yic6JVYCjiGUgxI2MJV2QzfSu8m49c= +github.com/CosmWasm/wasmvm/v2 v2.1.3/go.mod h1:bMhLQL4Yp9CzJi9A83aR7VO9wockOsSlZbT4ztOl6bg= github.com/DataDog/datadog-go v3.2.0+incompatible h1:qSG2N4FghB1He/r2mFrWKCaL7dXCilEuNEeAn20fdD4= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ= @@ -283,8 +283,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.13.0 h1:h7cazmFmItePvZHEbLhDbsq2l7xN4e2AjDHRM7zDLkg= -github.com/babylonlabs-io/babylon v0.13.0/go.mod h1:cxRwVqVLoJ39FpyovTEHJLu1lwwrM1tE8davu7nRHwY= +github.com/babylonlabs-io/babylon v0.14.0 h1:JyqkRD+vk4voapWU05pgi26SCNsNT00BmE9seheTDe0= +github.com/babylonlabs-io/babylon v0.14.0/go.mod h1:xaxDB8/sJWhqTw0BkmNzYtsOzIlpKAAnmXg8xJRbCjk= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=