Skip to content

Commit

Permalink
add sanity check for transactions standards (#146)
Browse files Browse the repository at this point in the history
* add sanity check for transactions standards
  • Loading branch information
KonradStaniec authored Mar 3, 2025
1 parent 8579e3a commit d19d19c
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ configuration to enabled it (disabled by default).
* [#114](https://github.com/babylonlabs-io/btc-staker/pull/114) **Multi-staking support**.
This PR contains a series of PRs on multi-staking support and BTC staking integration.
* [#134](https://github.com/babylonlabs-io/btc-staker/pull/134) Removal of both the watch-staking endpoint and the post-approval flow, and reduction of state in the database.
* [#146](https://github.com/babylonlabs-io/btc-staker/pull/146) Sanity check that all transactions are standard

## v0.15.2

Expand Down
12 changes: 12 additions & 0 deletions staker/babylontypes.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,18 @@ func (app *App) buildDelegation(
return nil, fmt.Errorf("failed to receive unbondingSlashingSig.Signature ")
}

// sanity check that all our transactions are standard
// if they are not this can mean bug either in Babylon parameters or in Staker code
if err := utils.CheckTransaction(stakingSlashingTx); err != nil {
return nil, fmt.Errorf("failed to build delegation data: failed to build staking slashing tx: %w", err)
}
if err := utils.CheckTransaction(undelegationDesc.UnbondingTransaction); err != nil {
return nil, fmt.Errorf("failed to build delegation data: failed to build unbonding tx: %w", err)
}
if err := utils.CheckTransaction(undelegationDesc.SlashUnbondingTransaction); err != nil {
return nil, fmt.Errorf("failed to build delegation data: failed to build unbondingslashing tx: %w", err)
}

dg := createDelegationData(
req,
externalData.stakerPublicKey,
Expand Down
6 changes: 6 additions & 0 deletions staker/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

cl "github.com/babylonlabs-io/btc-staker/babylonclient"
"github.com/babylonlabs-io/btc-staker/stakerdb"
"github.com/babylonlabs-io/btc-staker/utils"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcec/v2/schnorr"
"github.com/btcsuite/btcd/btcutil"
Expand Down Expand Up @@ -211,6 +212,11 @@ func createSpendStakeTx(
return nil, nil, fmt.Errorf("too big fee rate for spend stake tx. calculated fee: %d. funding output value: %d", fee, fundingOutput.Value)
}

// sanity check that transaction is standard
if err := utils.CheckTransaction(spendTx); err != nil {
return nil, nil, fmt.Errorf("failed to build spend stake tx: %w", err)
}

return spendTx, &fee, nil
}

Expand Down
38 changes: 38 additions & 0 deletions utils/btc_utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package utils

import (
"fmt"

"github.com/btcsuite/btcd/mempool"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
)

const (
minTransactionSize = 65
)

// Perform subset of transactions standard tests:
// - whether transaction is not considered dust
// - whether transactions is not too small
func CheckTransaction(tx *wire.MsgTx) error {
if tx.SerializeSizeStripped() < minTransactionSize {
return fmt.Errorf("transaction is too small. Tx size: %d, min size: %d", tx.SerializeSizeStripped(), minTransactionSize)
}

numOpReturns := 0
for _, txOut := range tx.TxOut {
scriptClass := txscript.GetScriptClass(txOut.PkScript)
if scriptClass == txscript.NullDataTy {
numOpReturns++
} else if mempool.IsDust(txOut, mempool.DefaultMinRelayTxFee) {
return fmt.Errorf("transaction output is dust. Value: %d", txOut.Value)
}
}

if numOpReturns > 1 {
return fmt.Errorf("transaction has more than one op_return output")
}

return nil
}
9 changes: 9 additions & 0 deletions walletcontroller/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/babylonlabs-io/babylon/crypto/bip322"
"github.com/babylonlabs-io/btc-staker/stakercfg"
"github.com/babylonlabs-io/btc-staker/types"
"github.com/babylonlabs-io/btc-staker/utils"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcec/v2/schnorr"
"github.com/btcsuite/btcd/btcjson"
Expand Down Expand Up @@ -256,6 +257,14 @@ func (w *RPCWalletController) CreateTransaction(
return nil, err
}

err = utils.CheckTransaction(tx)

if err != nil {
// returning error here means our tx building code is buggy, but it will save
// user from submitting invalid transaction to the network
return nil, fmt.Errorf("transaction is not standard: %w", err)
}

return tx, err
}

Expand Down

0 comments on commit d19d19c

Please sign in to comment.