Skip to content

Commit

Permalink
Add test for insufficient rune balances
Browse files Browse the repository at this point in the history
  • Loading branch information
koirikivi committed Apr 28, 2024
1 parent 77841ba commit b00c023
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 3 deletions.
21 changes: 19 additions & 2 deletions bridge_node/bridge/common/ord/multisig.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,18 @@
logger = logging.getLogger(__name__)


class PSBTFundingError(ValueError):
pass


class InsufficientBTCBalanceError(PSBTFundingError):
pass


class InsufficientRuneBalanceError(PSBTFundingError):
pass


class OrdMultisig:
DUST_SAT = 1000 # dust limit in satoshis
signer_xpub: str
Expand Down Expand Up @@ -345,8 +357,13 @@ def add_psbt_input(utxo: UTXO):
# Change is handled automatically by the protocol as long as the
# default output in the Runestone is set correctly
break

# required rune amounts can get negative, because we always have to spend full utxos
# hence we have <= 0 above, and don't assert this here:
# assert all(v >= 0 for v in required_rune_amounts.values()), \
# f"Negative rune balance: {required_rune_amounts}"
else:
raise ValueError(
raise InsufficientRuneBalanceError(
f"Missing required rune balances: {required_rune_amounts}",
)

Expand Down Expand Up @@ -385,7 +402,7 @@ def add_psbt_input(utxo: UTXO):
if not ord_output.has_rune_balances():
break
except IndexError as e:
raise ValueError("Don't have enough BTC to fund PSBT") from e
raise InsufficientBTCBalanceError("Don't have enough BTC to fund PSBT") from e
if not utxo.witness_script:
logger.warning("UTXO doesn't have witnessScript, cannot use: %s", utxo)
continue
Expand Down
87 changes: 86 additions & 1 deletion bridge_node/tests/common/ord/test_ord_multisig.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@

import pytest

from bridge.common.ord.transfers import RuneTransfer, ZeroTransferAmountError
from bridge.common.ord.multisig import (
InsufficientRuneBalanceError,
)
from bridge.common.ord.transfers import (
RuneTransfer,
ZeroTransferAmountError,
)
from bridge.common.utils import (
to_base_units,
to_decimal,
Expand Down Expand Up @@ -245,4 +251,83 @@ def test_zero_transfers_are_rejected(
)


def test_creating_psbt_fails_on_insufficient_rune_balance(
ord: OrdService, # noqa A002
bitcoind: BitcoindService,
rune_factory,
multisig_factory,
):
"""
Test that create_rune_psbt rejects transfers with 0 amount.
This is an important test -- edicts have special behaviour if amount == 0
"""
multisig, _, _ = multisig_factory(
required=2,
num_signers=3,
)

test_wallet = ord.create_test_wallet("test")
supply = Decimal("100")
rune_a, rune_b = rune_factory(
"AAAAAA",
"BBBBBB",
receiver=multisig.change_address,
supply=supply,
divisibility=18,
)

with pytest.raises(InsufficientRuneBalanceError):
multisig.create_rune_psbt(
transfers=[
RuneTransfer(
rune=rune_a,
amount=to_base_units(supply, 18) + 1,
receiver=test_wallet.get_receiving_address(),
),
]
)

with pytest.raises(InsufficientRuneBalanceError):
multisig.create_rune_psbt(
transfers=[
RuneTransfer(
rune=rune_a,
amount=100,
receiver=test_wallet.get_receiving_address(),
),
RuneTransfer(
rune=rune_b,
amount=to_base_units(supply, 18) + 1,
receiver=test_wallet.get_receiving_address(),
),
]
)

# Test limits are still ok
multisig.create_rune_psbt(
transfers=[
RuneTransfer(
rune=rune_a,
amount=to_base_units(supply, 18),
receiver=test_wallet.get_receiving_address(),
),
]
)
multisig.create_rune_psbt(
transfers=[
RuneTransfer(
rune=rune_a,
amount=to_base_units(supply, 18),
receiver=test_wallet.get_receiving_address(),
),
RuneTransfer(
rune=rune_b,
amount=to_base_units(supply, 18),
receiver=test_wallet.get_receiving_address(),
),
]
)


# TODO: test more than we have balances for
# TODO: test won't use rune outputs for paying for transaction fees (though maybe it's not important)

0 comments on commit b00c023

Please sign in to comment.