Skip to content

Commit

Permalink
Merge branch 'main' into parketh/opcc-slashing
Browse files Browse the repository at this point in the history
  • Loading branch information
parketh authored Dec 12, 2024
2 parents 1a89528 + 242fd29 commit 0636d92
Show file tree
Hide file tree
Showing 64 changed files with 215 additions and 118 deletions.
2 changes: 1 addition & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ linters:
- misspell
- nakedret
- nilerr
# - nlreturn # Style wise I personally like this one, todo(lazar): unlax at somepoint, good practice
- nlreturn
- noctx
- nonamedreturns
- nosprintfhostport
Expand Down
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)

## Unreleased

### Bug Fixes

* [#138](https://github.com/babylonlabs-io/vigilante/pull/138) fix: panic in SendCheckpointToBTC

### Improvements

* [#139](https://github.com/babylonlabs-io/vigilante/pull/139) add opcc slashing event
* [#136](https://github.com/babylonlabs-io/vigilante/pull/136) rate limit activations
* [#141](https://github.com/babylonlabs-io/vigilante/pull/141) decrement tracked delegations in atomic slasher
* [#143](https://github.com/babylonlabs-io/vigilante/pull/143) adds nlreturn linter rule

## v0.18.0

Expand Down
6 changes: 1 addition & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,7 @@ mocks:
$(MOCKGEN_CMD) -source=btcstaking-tracker/atomicslasher/expected_babylon_client.go -package atomicslasher -destination btcstaking-tracker/atomicslasher/mock_babylon_client.go
$(MOCKGEN_CMD) -source=btcstaking-tracker/stakingeventwatcher/expected_babylon_client.go -package stakingeventwatcher -destination btcstaking-tracker/stakingeventwatcher/mock_babylon_client.go

update-changelog:
@echo ./scripts/update_changelog.sh $(sinceTag) $(upcomingTag)
./scripts/update_changelog.sh $(sinceTag) $(upcomingTag)

.PHONY: build test test-e2e build-docker rm-docker mocks update-changelog
.PHONY: build test test-e2e build-docker rm-docker mocks

proto-gen:
@$(call print, "Compiling protos.")
Expand Down
2 changes: 2 additions & 0 deletions btcclient/client_wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ func (c *Client) GetNetParams() *chaincfg.Params {
if err != nil {
panic(fmt.Errorf("failed to get BTC network params: %w", err))
}

return net
}

Expand Down Expand Up @@ -123,6 +124,7 @@ func (c *Client) GetHighUTXOAndSum() (*btcjson.ListUnspentResult, float64, error
}
sum += utxo.Amount
}

return &highUTXO, sum, nil
}

Expand Down
11 changes: 11 additions & 0 deletions btcclient/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ func (c *Client) GetBlockByHash(blockHash *chainhash.Hash) (*types.IndexedBlock,
if height < 0 || height > int64(math.MaxUint32) {
panic(fmt.Errorf("height (%d) is out of uint32 range", height)) // software bug, panic
}

return types.NewIndexedBlock(uint32(height), &mBlock.Header, btcTxs), mBlock, nil
}

Expand Down Expand Up @@ -74,6 +75,7 @@ func (c *Client) getBestBlockHashWithRetry() (*chainhash.Hash, error) {
if err != nil {
return err
}

return nil
},
retry.Delay(c.retrySleepTime),
Expand All @@ -82,6 +84,7 @@ func (c *Client) getBestBlockHashWithRetry() (*chainhash.Hash, error) {
); err != nil {
c.logger.Debug(
"failed to query the best block hash", zap.Error(err))

return nil, err
}

Expand All @@ -99,6 +102,7 @@ func (c *Client) getBlockHashWithRetry(height uint32) (*chainhash.Hash, error) {
if err != nil {
return err
}

return nil
},
retry.Delay(c.retrySleepTime),
Expand All @@ -107,6 +111,7 @@ func (c *Client) getBlockHashWithRetry(height uint32) (*chainhash.Hash, error) {
); err != nil {
c.logger.Debug(
"failed to query the block hash", zap.Uint32("height", height), zap.Error(err))

return nil, err
}

Expand All @@ -124,6 +129,7 @@ func (c *Client) getBlockWithRetry(hash *chainhash.Hash) (*wire.MsgBlock, error)
if err != nil {
return err
}

return nil
},
retry.Delay(c.retrySleepTime),
Expand All @@ -132,6 +138,7 @@ func (c *Client) getBlockWithRetry(hash *chainhash.Hash) (*wire.MsgBlock, error)
); err != nil {
c.logger.Debug(
"failed to query the block", zap.String("hash", hash.String()), zap.Error(err))

return nil, err
}

Expand All @@ -149,6 +156,7 @@ func (c *Client) getBlockVerboseWithRetry(hash *chainhash.Hash) (*btcjson.GetBlo
if err != nil {
return err
}

return nil
},
retry.Delay(c.retrySleepTime),
Expand All @@ -157,6 +165,7 @@ func (c *Client) getBlockVerboseWithRetry(hash *chainhash.Hash) (*btcjson.GetBlo
); err != nil {
c.logger.Debug(
"failed to query the block verbose", zap.String("hash", hash.String()), zap.Error(err))

return nil, err
}

Expand Down Expand Up @@ -232,13 +241,15 @@ func (c *Client) getBlockCountWithRetry() (int64, error) {
if err != nil {
return err
}

return nil
},
retry.Delay(c.retrySleepTime),
retry.MaxDelay(c.maxRetrySleepTime),
retry.Attempts(c.maxRetryTimes),
); err != nil {
c.logger.Debug("failed to query get block count", zap.Error(err))

return 0, err
}

Expand Down
3 changes: 3 additions & 0 deletions btcstaking-tracker/atomicslasher/atomic_slasher.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ func New(
) *AtomicSlasher {
logger := parentLogger.With(zap.String("module", "atomic_slasher"))
bbnAdapter := NewBabylonAdapter(logger, cfg, retrySleepTime, maxRetrySleepTime, maxRetryTimes, bbnClient)

return &AtomicSlasher{
quit: make(chan struct{}),
cfg: cfg,
Expand Down Expand Up @@ -87,6 +88,7 @@ func (as *AtomicSlasher) Start() error {

as.logger.Info("atomic slasher started")
})

return startErr
}

Expand All @@ -99,6 +101,7 @@ func (as *AtomicSlasher) Stop() error {
as.wg.Wait()
as.logger.Info("stopping atomic slasher")
})

return stopErr
}

Expand Down
3 changes: 3 additions & 0 deletions btcstaking-tracker/atomicslasher/babylon_adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ func (ba *BabylonAdapter) BTCStakingParams(ctx context.Context, version uint32)
return err
}
bsParams = &resp.Params

return nil
},
retry.Context(ctx),
Expand All @@ -71,6 +72,7 @@ func (ba *BabylonAdapter) BTCDelegation(ctx context.Context, stakingTxHashHex st
return err
}
resp = resp2

return nil
},
retry.Context(ctx),
Expand Down Expand Up @@ -132,5 +134,6 @@ func (ba *BabylonAdapter) ReportSelectiveSlashing(

// TODO: what are unrecoverable/expected errors?
_, err := ba.bbnClient.ReliablySendMsg(ctx, msg, []*errors.Error{}, []*errors.Error{})

return err
}
10 changes: 10 additions & 0 deletions btcstaking-tracker/atomicslasher/routines.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ func (as *AtomicSlasher) btcDelegationTracker() {
}
as.btcDelIndex.Add(trackedDel)
as.metrics.TrackedBTCDelegationsGauge.Inc()

return nil
})
if err != nil {
Expand All @@ -46,6 +47,7 @@ func (as *AtomicSlasher) slashingTxTracker() {
blockNotifier, err := as.btcNotifier.RegisterBlockEpochNtfn(nil)
if err != nil {
as.logger.Error("failed to register block notifier", zap.Error(err))

return
}
defer blockNotifier.Cancel()
Expand Down Expand Up @@ -73,6 +75,7 @@ func (as *AtomicSlasher) slashingTxTracker() {
zap.String("block_hash", blockEpoch.Hash.String()),
zap.Error(err),
)

continue
}
// filter out slashing tx / unbonding slashing tx, and
Expand Down Expand Up @@ -115,6 +118,7 @@ func (as *AtomicSlasher) selectiveSlashingReporter() {
zap.String("staking_tx_hash", stakingTxHashStr),
zap.Error(err),
)

continue
}
// get parameter at the version of this BTC delegation
Expand All @@ -128,6 +132,7 @@ func (as *AtomicSlasher) selectiveSlashingReporter() {
zap.Uint32("version", paramsVersion),
zap.Error(err),
)

continue
}
// get covenant Schnorr signature in tx
Expand All @@ -143,6 +148,7 @@ func (as *AtomicSlasher) selectiveSlashingReporter() {
zap.String("staking_tx_hash", stakingTxHashStr),
zap.Error(err),
)

continue
}

Expand All @@ -156,6 +162,7 @@ func (as *AtomicSlasher) selectiveSlashingReporter() {
zap.String("fp_pk", fpPK.MarshalHex()),
zap.Error(err),
)

continue
}
cancel()
Expand All @@ -166,6 +173,7 @@ func (as *AtomicSlasher) selectiveSlashingReporter() {
zap.String("fp_pk", fpPK.MarshalHex()),
zap.Error(err),
)

continue
}

Expand All @@ -186,6 +194,7 @@ func (as *AtomicSlasher) selectiveSlashingReporter() {
zap.String("staking_tx_hash", stakingTxHashStr),
zap.Error(err),
)

continue
}

Expand All @@ -208,6 +217,7 @@ func (as *AtomicSlasher) selectiveSlashingReporter() {

// stop tracking the delegations under this finality provider
as.btcDelIndex.Remove(stakingTxHash)
as.metrics.TrackedBTCDelegationsGauge.Dec()

case <-as.quit:
return
Expand Down
1 change: 1 addition & 0 deletions btcstaking-tracker/atomicslasher/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ func parseSlashingTxWitness(
if len(fpWitnessStack[i]) != 0 {
fpIdx = i
fpPK = &fpPKs[i]

break
}
}
Expand Down
2 changes: 2 additions & 0 deletions btcstaking-tracker/btcslasher/bootstrapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ func (bs *BTCSlasher) Bootstrap(startHeight uint64) error {
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)

continue
}

Expand All @@ -57,6 +58,7 @@ func (bs *BTCSlasher) Bootstrap(startHeight uint64) error {
if err := bs.SlashFinalityProvider(fpBTCSK); err != nil {
bs.logger.Errorf("failed to slash finality provider %s: %v", fpBTCPKHex, err)
accumulatedErrs = multierror.Append(accumulatedErrs, err)

continue
}
}
Expand Down
2 changes: 2 additions & 0 deletions btcstaking-tracker/btcslasher/btc_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
// TODO: ensure k-deep?
func (bs *BTCSlasher) isTxSubmittedToBitcoin(txHash *chainhash.Hash) bool {
_, err := bs.BTCClient.GetRawTransaction(txHash)

return err == nil
}

Expand Down Expand Up @@ -43,6 +44,7 @@ func (bs *BTCSlasher) isTaprootOutputSpendable(txBytes []byte, outIdx uint32) (b
"tx %s output is already unspendable",
stakingMsgTxHash.String(),
)

return false, nil
}
// spendable
Expand Down
6 changes: 6 additions & 0 deletions btcstaking-tracker/btcslasher/slasher.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ func (bs *BTCSlasher) Start() error {
// load module parameters
if err := bs.LoadParams(); err != nil {
startErr = err

return
}

Expand Down Expand Up @@ -173,13 +174,15 @@ func (bs *BTCSlasher) slashingEnforcer() {
select {
case <-bs.quit:
bs.logger.Debug("handle delegations loop quit")

return
case fpBTCSK, ok := <-bs.slashedFPSKChan:
if !ok {
// slasher receives the channel from outside, so its lifecycle
// is out of slasher's control. So we need to ensure the channel
// is not closed yet
bs.logger.Debug("slashedFKSK channel is already closed, terminating the slashing enforcer")

return
}
// slash all the BTC delegations of this finality provider
Expand Down Expand Up @@ -249,6 +252,7 @@ func (bs *BTCSlasher) equivocationTracker() {
select {
case <-bs.quit:
bs.logger.Debug("handle delegations loop quit")

return
case resultEvent := <-bs.finalitySigChan:
bs.handleEvidence(&resultEvent, false)
Expand Down Expand Up @@ -294,6 +298,7 @@ func (bs *BTCSlasher) SlashFinalityProvider(extractedFpBTCSK *btcec.PrivateKey)
// Acquire the semaphore before interacting with the BTC node
if err := sem.Acquire(ctx, 1); err != nil {
bs.logger.Errorf("failed to acquire semaphore: %v", err)

return
}
defer sem.Release(1)
Expand Down Expand Up @@ -329,5 +334,6 @@ func (bs *BTCSlasher) Stop() error {

bs.logger.Info("stopped slasher")
})

return stopErr
}
1 change: 1 addition & 0 deletions btcstaking-tracker/btcslasher/slasher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ func newBTCDelegatorDelegationsResponse(delegations []*bstypes.BTCDelegatorDeleg
delListResp = append(delListResp, bstypes.NewBTCDelegationResponse(del, status))
}
}

return &bstypes.BTCDelegatorDelegationsResponse{
Dels: delListResp,
}
Expand Down
3 changes: 3 additions & 0 deletions btcstaking-tracker/btcslasher/slasher_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ func findFPIdxInWitness(fpBTCPK *bbn.BIP340PubKey, fpBtcPkList []bbn.BIP340PubKe
return i, nil
}
}

return 0, fmt.Errorf("the given finality provider's PK is not found in the BTC delegation")
}

Expand Down Expand Up @@ -461,9 +462,11 @@ func filterEvidence(resultEvent *coretypes.ResultEvent) *ftypes.Evidence {
if err := jsonpb.UnmarshalString(eventData[0], &evidence); err != nil {
continue
}

return &evidence
}
}
}

return nil
}
Loading

0 comments on commit 0636d92

Please sign in to comment.