mirror of
https://github.com/basicswap/basicswap.git
synced 2026-06-10 13:01:41 +02:00
Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0bc3226ed9 | |||
| 1aa53e38f9 | |||
| 379eaaf0db | |||
| 304e88646f | |||
| 597cdcbff5 | |||
| 176fc48ba2 | |||
| cf836878fd | |||
| 37d564b4f7 | |||
| d2cbce0de9 | |||
| 3aacc57f09 | |||
| d23665d585 | |||
| 553b5a6a32 | |||
| 827909b322 | |||
| 3af05ea5c0 | |||
| 136b311dc6 | |||
| df672d4056 | |||
| f536f8962e | |||
| ce5ffe92b4 | |||
| 32bdd11853 | |||
| 5e7dbbb22f |
@@ -28,7 +28,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
python-version: ["3.12"]
|
python-version: ["3.14"]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v6
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
|
|||||||
+10
-5
@@ -1,20 +1,25 @@
|
|||||||
FROM ubuntu:22.04
|
FROM debian:trixie-slim
|
||||||
|
|
||||||
ENV LANG=C.UTF-8 \
|
ENV LANG=C.UTF-8 \
|
||||||
DEBIAN_FRONTEND=noninteractive \
|
DEBIAN_FRONTEND=noninteractive \
|
||||||
DATADIRS="/coindata"
|
DATADIRS="/coindata" \
|
||||||
|
VIRTUAL_ENV=/opt/venv
|
||||||
|
|
||||||
RUN apt-get update; \
|
RUN apt-get update; \
|
||||||
apt-get install -y --no-install-recommends \
|
apt-get install -y --no-install-recommends \
|
||||||
python3-pip libpython3-dev gnupg pkg-config gcc libc-dev gosu tzdata cmake ninja-build;
|
python3-pip libpython3-dev python3-venv gnupg pkg-config gcc libc-dev gosu tzdata cmake ninja-build;
|
||||||
|
|
||||||
|
# Create python venv
|
||||||
|
RUN python3 -m venv $VIRTUAL_ENV
|
||||||
|
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
|
||||||
|
|
||||||
# Install requirements first so as to skip in subsequent rebuilds
|
# Install requirements first so as to skip in subsequent rebuilds
|
||||||
COPY ./requirements.txt requirements.txt
|
COPY ./requirements.txt requirements.txt
|
||||||
RUN pip3 install -r requirements.txt --require-hashes
|
RUN pip install -r requirements.txt --require-hashes
|
||||||
|
|
||||||
COPY . basicswap-master
|
COPY . basicswap-master
|
||||||
RUN cd basicswap-master; \
|
RUN cd basicswap-master; \
|
||||||
pip3 install .;
|
pip install .;
|
||||||
|
|
||||||
RUN useradd -ms /bin/bash swap_user && \
|
RUN useradd -ms /bin/bash swap_user && \
|
||||||
mkdir /coindata && chown swap_user -R /coindata
|
mkdir /coindata && chown swap_user -R /coindata
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
name = "basicswap"
|
name = "basicswap"
|
||||||
|
|
||||||
__version__ = "0.16.3"
|
__version__ = "0.16.5"
|
||||||
|
|||||||
+83
-39
@@ -3611,6 +3611,16 @@ class BasicSwap(BaseApp, BSXNetwork, UIApp):
|
|||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"Invalid swap type for: {coin_from.name} -> {coin_to.name}"
|
f"Invalid swap type for: {coin_from.name} -> {coin_to.name}"
|
||||||
)
|
)
|
||||||
|
strict_swap_type: bool = self.settings.get(
|
||||||
|
"strict_swap_type", False if self.chain == "regtest" else True
|
||||||
|
)
|
||||||
|
if strict_swap_type and (
|
||||||
|
coin_from not in self.coins_without_segwit
|
||||||
|
or coin_to not in self.coins_without_segwit
|
||||||
|
):
|
||||||
|
raise ValueError(
|
||||||
|
f"Coin pair should use adaptor sig swap type: {coin_from.name} -> {coin_to.name}"
|
||||||
|
)
|
||||||
|
|
||||||
def _process_notification_safe(self, event_type, event_data) -> None:
|
def _process_notification_safe(self, event_type, event_data) -> None:
|
||||||
try:
|
try:
|
||||||
@@ -6896,7 +6906,16 @@ class BasicSwap(BaseApp, BSXNetwork, UIApp):
|
|||||||
self.log.debug(
|
self.log.debug(
|
||||||
f"Create initiate txn for coin {ci.coin_name()} to {addr_to} for bid {self.log.id(bid_id)}"
|
f"Create initiate txn for coin {ci.coin_name()} to {addr_to} for bid {self.log.id(bid_id)}"
|
||||||
)
|
)
|
||||||
txn_signed = ci.createRawSignedTransaction(addr_to, bid.amount)
|
amount_from: int = bid.amount
|
||||||
|
if bid.debug_ind == DebugTypes.MAKE_INVALID_ITX:
|
||||||
|
amount_from -= 100
|
||||||
|
self.logBidEvent(
|
||||||
|
bid.bid_id,
|
||||||
|
EventLogTypes.DEBUG_TWEAK_APPLIED,
|
||||||
|
f"Make invalid ITx for testing: {bid.debug_ind}",
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
txn_signed = ci.createRawSignedTransaction(addr_to, amount_from)
|
||||||
|
|
||||||
txjs = ci.describeTx(txn_signed)
|
txjs = ci.describeTx(txn_signed)
|
||||||
vout = getVoutByAddress(txjs, addr_to)
|
vout = getVoutByAddress(txjs, addr_to)
|
||||||
@@ -6987,13 +7006,10 @@ class BasicSwap(BaseApp, BSXNetwork, UIApp):
|
|||||||
|
|
||||||
if bid.debug_ind == DebugTypes.MAKE_INVALID_PTX:
|
if bid.debug_ind == DebugTypes.MAKE_INVALID_PTX:
|
||||||
amount_to -= 1
|
amount_to -= 1
|
||||||
self.log.debug(
|
|
||||||
f"bid {self.log.id(bid_id)}: Make invalid PTx for testing: {bid.debug_ind}."
|
|
||||||
)
|
|
||||||
self.logBidEvent(
|
self.logBidEvent(
|
||||||
bid.bid_id,
|
bid.bid_id,
|
||||||
EventLogTypes.DEBUG_TWEAK_APPLIED,
|
EventLogTypes.DEBUG_TWEAK_APPLIED,
|
||||||
"ind {}".format(bid.debug_ind),
|
f"Make invalid PTx for testing: {bid.debug_ind}",
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -8421,12 +8437,10 @@ class BasicSwap(BaseApp, BSXNetwork, UIApp):
|
|||||||
# Verify amount
|
# Verify amount
|
||||||
vout = getVoutByAddress(initiate_txn, p2sh)
|
vout = getVoutByAddress(initiate_txn, p2sh)
|
||||||
|
|
||||||
out_value = make_int(initiate_txn["vout"][vout]["value"])
|
out_value: int = make_int(initiate_txn["vout"][vout]["value"])
|
||||||
ensure(
|
ensure(
|
||||||
out_value == int(bid.amount),
|
out_value == int(bid.amount),
|
||||||
"Incorrect output amount in initiate txn {}: {} != {}.".format(
|
f"Incorrect output amount in initiate txn {self.logIDT(initiate_txnid_hex)}: {out_value} != {bid.amount}",
|
||||||
initiate_txnid_hex, out_value, int(bid.amount)
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
bid.initiate_tx.conf = initiate_txn["confirmations"]
|
bid.initiate_tx.conf = initiate_txn["confirmations"]
|
||||||
@@ -8454,21 +8468,21 @@ class BasicSwap(BaseApp, BSXNetwork, UIApp):
|
|||||||
)
|
)
|
||||||
index = None
|
index = None
|
||||||
if found:
|
if found:
|
||||||
if (
|
if "index" not in found:
|
||||||
"value" in found
|
|
||||||
and found["value"] is not None
|
|
||||||
and found["value"] != int(bid.amount)
|
|
||||||
):
|
|
||||||
self.setBidError(
|
self.setBidError(
|
||||||
bid,
|
bid,
|
||||||
"Incorrect output amount in initiate txn {}: {} != {}.".format(
|
f"Swap output index not found for initiate txn {self.logIDT(initiate_txnid_hex)}",
|
||||||
initiate_txnid_hex, found["value"], int(bid.amount)
|
)
|
||||||
),
|
return True
|
||||||
|
txo_value: int = found.get("value", None)
|
||||||
|
if txo_value != bid.amount:
|
||||||
|
self.setBidError(
|
||||||
|
bid,
|
||||||
|
f"Incorrect output amount in initiate txn {self.logIDT(initiate_txnid_hex)}: {txo_value} != {bid.amount}",
|
||||||
)
|
)
|
||||||
return True
|
return True
|
||||||
bid.initiate_tx.conf = found["depth"]
|
bid.initiate_tx.conf = found["depth"]
|
||||||
if "index" in found:
|
index = found["index"]
|
||||||
index = found["index"]
|
|
||||||
tx_height = found["height"]
|
tx_height = found["height"]
|
||||||
|
|
||||||
if bid.initiate_tx.conf != last_initiate_txn_conf:
|
if bid.initiate_tx.conf != last_initiate_txn_conf:
|
||||||
@@ -8554,6 +8568,21 @@ class BasicSwap(BaseApp, BSXNetwork, UIApp):
|
|||||||
vout=participate_txvout,
|
vout=participate_txvout,
|
||||||
)
|
)
|
||||||
if found:
|
if found:
|
||||||
|
participate_txid_hex: str = found.get(
|
||||||
|
"txid",
|
||||||
|
None if participate_txid is None else participate_txid.hex(),
|
||||||
|
)
|
||||||
|
# Double check value
|
||||||
|
txo_value: int = found.get("value", None)
|
||||||
|
if (
|
||||||
|
txo_value != bid.amount_to
|
||||||
|
and bid.debug_ind != DebugTypes.MAKE_INVALID_PTX
|
||||||
|
):
|
||||||
|
self.setBidError(
|
||||||
|
bid,
|
||||||
|
f"Incorrect output amount in participate txn {self.logIDT(participate_txid_hex)}: {txo_value} != {bid.amount_to}",
|
||||||
|
)
|
||||||
|
return True
|
||||||
index = found.get("index", participate_txvout)
|
index = found.get("index", participate_txvout)
|
||||||
if bid.participate_tx.conf != found["depth"]:
|
if bid.participate_tx.conf != found["depth"]:
|
||||||
save_bid = True
|
save_bid = True
|
||||||
@@ -8561,15 +8590,16 @@ class BasicSwap(BaseApp, BSXNetwork, UIApp):
|
|||||||
bid.participate_tx.conf is None
|
bid.participate_tx.conf is None
|
||||||
and bid.participate_tx.state != TxStates.TX_SENT
|
and bid.participate_tx.state != TxStates.TX_SENT
|
||||||
):
|
):
|
||||||
txid = found.get(
|
|
||||||
"txid",
|
|
||||||
None if participate_txid is None else participate_txid.hex(),
|
|
||||||
)
|
|
||||||
self.log.debug(
|
self.log.debug(
|
||||||
f"Found bid {self.log.id(bid_id)} participate txn {self.log.id(txid)} in chain {ci_to.coin_name()}."
|
f"Found bid {self.log.id(bid_id)} participate txn {self.logIDT(participate_txid_hex)} in chain {ci_to.coin_name()}."
|
||||||
)
|
)
|
||||||
self.addParticipateTxn(
|
self.addParticipateTxn(
|
||||||
bid_id, bid, coin_to, txid, index, found["height"]
|
bid_id,
|
||||||
|
bid,
|
||||||
|
coin_to,
|
||||||
|
participate_txid_hex,
|
||||||
|
index,
|
||||||
|
found["height"],
|
||||||
)
|
)
|
||||||
|
|
||||||
# Only update tx state if tx hasn't already been seen
|
# Only update tx state if tx hasn't already been seen
|
||||||
@@ -8587,7 +8617,7 @@ class BasicSwap(BaseApp, BSXNetwork, UIApp):
|
|||||||
|
|
||||||
if bid.participate_tx.conf is not None:
|
if bid.participate_tx.conf is not None:
|
||||||
self.log.debug(
|
self.log.debug(
|
||||||
f"participate txid {self.log.id(bid.participate_tx.txid)} confirms {bid.participate_tx.conf}."
|
f"Participate txid {self.logIDT(bid.participate_tx.txid)} confirms {bid.participate_tx.conf}."
|
||||||
)
|
)
|
||||||
if (
|
if (
|
||||||
bid.participate_tx.conf
|
bid.participate_tx.conf
|
||||||
@@ -11647,8 +11677,11 @@ class BasicSwap(BaseApp, BSXNetwork, UIApp):
|
|||||||
txid_hex = ci_from.publishTx(lock_tx_signed)
|
txid_hex = ci_from.publishTx(lock_tx_signed)
|
||||||
|
|
||||||
if txid_hex != b2h(xmr_swap.a_lock_tx_id):
|
if txid_hex != b2h(xmr_swap.a_lock_tx_id):
|
||||||
|
if not self.isBchXmrSwap(offer):
|
||||||
|
raise ValueError("Coin A lock tx txid changed after sending!")
|
||||||
|
|
||||||
self.log.info(
|
self.log.info(
|
||||||
"Recomputing refund transactions and txids after lock tx publish."
|
f"Recomputing {ci_from.coin_name()} refund transactions and txids after lock tx publish."
|
||||||
)
|
)
|
||||||
xmr_swap.a_lock_tx = lock_tx_signed
|
xmr_swap.a_lock_tx = lock_tx_signed
|
||||||
xmr_swap.a_lock_tx_id = bytes.fromhex(txid_hex)
|
xmr_swap.a_lock_tx_id = bytes.fromhex(txid_hex)
|
||||||
@@ -12440,6 +12473,19 @@ class BasicSwap(BaseApp, BSXNetwork, UIApp):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if not self.isBchXmrSwap(offer):
|
if not self.isBchXmrSwap(offer):
|
||||||
|
self.log.info("Checking follower's lock refund tx signature.")
|
||||||
|
prevout_amount = ci_from.getLockTxSwapOutputValue(bid, xmr_swap)
|
||||||
|
v = ci_from.verifyTxSig(
|
||||||
|
xmr_swap.a_lock_refund_tx,
|
||||||
|
xmr_swap.af_lock_refund_tx_sig,
|
||||||
|
xmr_swap.pkaf,
|
||||||
|
0,
|
||||||
|
xmr_swap.a_lock_tx_script,
|
||||||
|
prevout_amount,
|
||||||
|
)
|
||||||
|
ensure(v, "Invalid coin A lock refund tx leader sig")
|
||||||
|
xmr_swap_1.addLockRefundSigs(self, xmr_swap, ci_from)
|
||||||
|
|
||||||
# segwit coins sign the transaction
|
# segwit coins sign the transaction
|
||||||
xmr_swap.af_lock_refund_spend_tx_sig = ci_from.decryptOtVES(
|
xmr_swap.af_lock_refund_spend_tx_sig = ci_from.decryptOtVES(
|
||||||
kbsl, xmr_swap.af_lock_refund_spend_tx_esig
|
kbsl, xmr_swap.af_lock_refund_spend_tx_esig
|
||||||
@@ -12454,7 +12500,16 @@ class BasicSwap(BaseApp, BSXNetwork, UIApp):
|
|||||||
xmr_swap.a_lock_refund_tx_script,
|
xmr_swap.a_lock_refund_tx_script,
|
||||||
prevout_amount,
|
prevout_amount,
|
||||||
)
|
)
|
||||||
|
self.log.info("Checking follower's lock refund spend tx signature.")
|
||||||
|
v = ci_from.verifyTxSig(
|
||||||
|
xmr_swap.a_lock_refund_spend_tx,
|
||||||
|
xmr_swap.af_lock_refund_spend_tx_sig,
|
||||||
|
xmr_swap.pkaf,
|
||||||
|
0,
|
||||||
|
xmr_swap.a_lock_refund_tx_script,
|
||||||
|
prevout_amount,
|
||||||
|
)
|
||||||
|
ensure(v, "Invalid follower signature for lock refund spend txn")
|
||||||
self.log.debug("Setting lock refund spend tx sigs.")
|
self.log.debug("Setting lock refund spend tx sigs.")
|
||||||
witness_stack = []
|
witness_stack = []
|
||||||
if coin_from not in (Coins.DCR,):
|
if coin_from not in (Coins.DCR,):
|
||||||
@@ -12472,17 +12527,6 @@ class BasicSwap(BaseApp, BSXNetwork, UIApp):
|
|||||||
)
|
)
|
||||||
ensure(signed_tx, "setTxSignature failed")
|
ensure(signed_tx, "setTxSignature failed")
|
||||||
xmr_swap.a_lock_refund_spend_tx = signed_tx
|
xmr_swap.a_lock_refund_spend_tx = signed_tx
|
||||||
|
|
||||||
v = ci_from.verifyTxSig(
|
|
||||||
xmr_swap.a_lock_refund_spend_tx,
|
|
||||||
xmr_swap.af_lock_refund_spend_tx_sig,
|
|
||||||
xmr_swap.pkaf,
|
|
||||||
0,
|
|
||||||
xmr_swap.a_lock_refund_tx_script,
|
|
||||||
prevout_amount,
|
|
||||||
)
|
|
||||||
ensure(v, "Invalid signature for lock refund spend txn")
|
|
||||||
xmr_swap_1.addLockRefundSigs(self, xmr_swap, ci_from)
|
|
||||||
else:
|
else:
|
||||||
# BCH signs the output pkh
|
# BCH signs the output pkh
|
||||||
|
|
||||||
|
|||||||
@@ -232,6 +232,7 @@ class DebugTypes(IntEnum):
|
|||||||
BID_DONT_SPEND_COIN_A_LOCK_REFUND2 = auto() # continues
|
BID_DONT_SPEND_COIN_A_LOCK_REFUND2 = auto() # continues
|
||||||
CREATE_INVALID_COIN_B_LOCK = auto()
|
CREATE_INVALID_COIN_B_LOCK = auto()
|
||||||
BUYER_STOP_AFTER_ITX = auto()
|
BUYER_STOP_AFTER_ITX = auto()
|
||||||
|
MAKE_INVALID_ITX = auto()
|
||||||
MAKE_INVALID_PTX = auto()
|
MAKE_INVALID_PTX = auto()
|
||||||
DONT_SPEND_ITX = auto()
|
DONT_SPEND_ITX = auto()
|
||||||
SKIP_LOCK_TX_REFUND = auto()
|
SKIP_LOCK_TX_REFUND = auto()
|
||||||
|
|||||||
@@ -1,3 +1,22 @@
|
|||||||
|
|
||||||
|
0.16.5
|
||||||
|
==============
|
||||||
|
|
||||||
|
- Updated docker base images to Debian Trixie.
|
||||||
|
- By default reject secret hash type offers where the coin pair could use adaptor sig swap.
|
||||||
|
- override with "strict_swap_type" setting.
|
||||||
|
- Verify follower's script chain lock refund tx sig.
|
||||||
|
|
||||||
|
|
||||||
|
0.16.4
|
||||||
|
==============
|
||||||
|
|
||||||
|
- Security: Always require the initiate tx output index and value for secret hash swaps.
|
||||||
|
- Strengthens the 0.16.3 fix: the amount check can no longer be skipped when the output value is unavailable; the swap is now rejected (fails closed) instead of proceeding.
|
||||||
|
- Security: Also double check the participate tx output amount for secret hash swaps.
|
||||||
|
- Raise minimum Python version to 3.11.
|
||||||
|
|
||||||
|
|
||||||
0.16.3
|
0.16.3
|
||||||
==============
|
==============
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ FROM i_swapclient as install_stage
|
|||||||
RUN basicswap-prepare --preparebinonly --bindir=/coin_bin --withcoin=bitcoin --withoutcoins=particl && \
|
RUN basicswap-prepare --preparebinonly --bindir=/coin_bin --withcoin=bitcoin --withoutcoins=particl && \
|
||||||
find /coin_bin -name *.tar.gz -delete
|
find /coin_bin -name *.tar.gz -delete
|
||||||
|
|
||||||
FROM debian:bullseye-slim
|
FROM debian:trixie-slim
|
||||||
COPY --from=install_stage /coin_bin .
|
COPY --from=install_stage /coin_bin .
|
||||||
|
|
||||||
ENV BITCOIN_DATA /data
|
ENV BITCOIN_DATA /data
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ FROM i_swapclient as install_stage
|
|||||||
RUN basicswap-prepare --preparebinonly --bindir=/coin_bin --withcoin=bitcoincash --withoutcoins=particl && \
|
RUN basicswap-prepare --preparebinonly --bindir=/coin_bin --withcoin=bitcoincash --withoutcoins=particl && \
|
||||||
find /coin_bin -name *.tar.gz -delete
|
find /coin_bin -name *.tar.gz -delete
|
||||||
|
|
||||||
FROM debian:bullseye-slim
|
FROM debian:trixie-slim
|
||||||
COPY --from=install_stage /coin_bin .
|
COPY --from=install_stage /coin_bin .
|
||||||
|
|
||||||
ENV BITCOINCASH_DATA /data
|
ENV BITCOINCASH_DATA /data
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ FROM i_swapclient as install_stage
|
|||||||
RUN basicswap-prepare --preparebinonly --bindir=/coin_bin --withcoin=dash --withoutcoins=particl && \
|
RUN basicswap-prepare --preparebinonly --bindir=/coin_bin --withcoin=dash --withoutcoins=particl && \
|
||||||
find /coin_bin -name *.tar.gz -delete
|
find /coin_bin -name *.tar.gz -delete
|
||||||
|
|
||||||
FROM debian:bullseye-slim
|
FROM debian:trixie-slim
|
||||||
COPY --from=install_stage /coin_bin .
|
COPY --from=install_stage /coin_bin .
|
||||||
|
|
||||||
ENV DASH_DATA /data
|
ENV DASH_DATA /data
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ FROM i_swapclient as install_stage
|
|||||||
RUN basicswap-prepare --preparebinonly --bindir=/coin_bin --withcoin=decred --withoutcoins=particl && \
|
RUN basicswap-prepare --preparebinonly --bindir=/coin_bin --withcoin=decred --withoutcoins=particl && \
|
||||||
find /coin_bin -name *.tar.gz -delete
|
find /coin_bin -name *.tar.gz -delete
|
||||||
|
|
||||||
FROM debian:bullseye-slim
|
FROM debian:trixie-slim
|
||||||
COPY --from=install_stage /coin_bin .
|
COPY --from=install_stage /coin_bin .
|
||||||
|
|
||||||
ENV DCR_DATA /data
|
ENV DCR_DATA /data
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ FROM i_swapclient as install_stage
|
|||||||
RUN basicswap-prepare --preparebinonly --bindir=/coin_bin --withcoin=dogecoin --withoutcoin=particl && \
|
RUN basicswap-prepare --preparebinonly --bindir=/coin_bin --withcoin=dogecoin --withoutcoin=particl && \
|
||||||
find /coin_bin -name *.tar.gz -delete
|
find /coin_bin -name *.tar.gz -delete
|
||||||
|
|
||||||
FROM debian:bullseye-slim
|
FROM debian:trixie-slim
|
||||||
COPY --from=install_stage /coin_bin .
|
COPY --from=install_stage /coin_bin .
|
||||||
|
|
||||||
ENV DOGECOIN_DATA /data
|
ENV DOGECOIN_DATA /data
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ FROM i_swapclient as install_stage
|
|||||||
RUN basicswap-prepare --preparebinonly --bindir=/coin_bin --withcoin=firo --withoutcoins=particl && \
|
RUN basicswap-prepare --preparebinonly --bindir=/coin_bin --withcoin=firo --withoutcoins=particl && \
|
||||||
find /coin_bin -name *.tar.gz -delete
|
find /coin_bin -name *.tar.gz -delete
|
||||||
|
|
||||||
FROM debian:bullseye-slim
|
FROM debian:trixie-slim
|
||||||
COPY --from=install_stage /coin_bin .
|
COPY --from=install_stage /coin_bin .
|
||||||
|
|
||||||
ENV FIRO_DATA /data
|
ENV FIRO_DATA /data
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ FROM i_swapclient as install_stage
|
|||||||
RUN basicswap-prepare --preparebinonly --bindir=/coin_bin --withcoin=litecoin --withoutcoin=particl && \
|
RUN basicswap-prepare --preparebinonly --bindir=/coin_bin --withcoin=litecoin --withoutcoin=particl && \
|
||||||
find /coin_bin -name *.tar.gz -delete
|
find /coin_bin -name *.tar.gz -delete
|
||||||
|
|
||||||
FROM debian:bullseye-slim
|
FROM debian:trixie-slim
|
||||||
COPY --from=install_stage /coin_bin .
|
COPY --from=install_stage /coin_bin .
|
||||||
|
|
||||||
ENV LITECOIN_DATA /data
|
ENV LITECOIN_DATA /data
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ FROM i_swapclient as install_stage
|
|||||||
|
|
||||||
RUN basicswap-prepare --preparebinonly --bindir=/coin_bin --withcoin=monero --withoutcoins=particl
|
RUN basicswap-prepare --preparebinonly --bindir=/coin_bin --withcoin=monero --withoutcoins=particl
|
||||||
|
|
||||||
FROM debian:bullseye-slim
|
FROM debian:trixie-slim
|
||||||
|
|
||||||
COPY --from=install_stage /coin_bin .
|
COPY --from=install_stage /coin_bin .
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ FROM i_swapclient as install_stage
|
|||||||
RUN basicswap-prepare --preparebinonly --bindir=/coin_bin --withcoin=particl && \
|
RUN basicswap-prepare --preparebinonly --bindir=/coin_bin --withcoin=particl && \
|
||||||
find /coin_bin -name *.tar.gz -delete
|
find /coin_bin -name *.tar.gz -delete
|
||||||
|
|
||||||
FROM debian:bullseye-slim
|
FROM debian:trixie-slim
|
||||||
COPY --from=install_stage /coin_bin .
|
COPY --from=install_stage /coin_bin .
|
||||||
|
|
||||||
ENV PARTICL_DATA /data
|
ENV PARTICL_DATA /data
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ FROM i_swapclient as install_stage
|
|||||||
RUN basicswap-prepare --preparebinonly --bindir=/coin_bin --withcoin=pivx --withoutcoins=particl && \
|
RUN basicswap-prepare --preparebinonly --bindir=/coin_bin --withcoin=pivx --withoutcoins=particl && \
|
||||||
find /coin_bin -name *.tar.gz -delete
|
find /coin_bin -name *.tar.gz -delete
|
||||||
|
|
||||||
FROM debian:bullseye-slim
|
FROM debian:trixie-slim
|
||||||
COPY --from=install_stage /coin_bin .
|
COPY --from=install_stage /coin_bin .
|
||||||
|
|
||||||
ENV PIVX_DATA /data
|
ENV PIVX_DATA /data
|
||||||
|
|||||||
@@ -1,12 +1,17 @@
|
|||||||
FROM debian:bullseye-slim
|
FROM debian:trixie-slim
|
||||||
|
|
||||||
ENV LANG=C.UTF-8 \
|
ENV LANG=C.UTF-8 \
|
||||||
DEBIAN_FRONTEND=noninteractive \
|
DEBIAN_FRONTEND=noninteractive \
|
||||||
DATADIR=/data
|
DATADIR=/data \
|
||||||
|
VIRTUAL_ENV=/opt/venv
|
||||||
|
|
||||||
RUN apt-get update; \
|
RUN apt-get update; \
|
||||||
apt-get install -y --no-install-recommends \
|
apt-get install -y --no-install-recommends \
|
||||||
python3-pip libpython3-dev gnupg pkg-config gcc libc-dev gosu tzdata wget unzip cmake ninja-build;
|
python3-pip libpython3-dev python3-venv gnupg pkg-config gcc libc-dev gosu tzdata wget unzip cmake ninja-build;
|
||||||
|
|
||||||
|
# Create python venv
|
||||||
|
RUN python3 -m venv $VIRTUAL_ENV
|
||||||
|
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
|
||||||
|
|
||||||
ARG BASICSWAP_URL=https://github.com/basicswap/basicswap/archive/master.zip
|
ARG BASICSWAP_URL=https://github.com/basicswap/basicswap/archive/master.zip
|
||||||
ARG BASICSWAP_DIR=basicswap-master
|
ARG BASICSWAP_DIR=basicswap-master
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ FROM i_swapclient as install_stage
|
|||||||
|
|
||||||
RUN basicswap-prepare --preparebinonly --bindir=/coin_bin --withcoin=wownero --withoutcoins=particl
|
RUN basicswap-prepare --preparebinonly --bindir=/coin_bin --withcoin=wownero --withoutcoins=particl
|
||||||
|
|
||||||
FROM debian:bullseye-slim
|
FROM debian:trixie-slim
|
||||||
|
|
||||||
COPY --from=install_stage /coin_bin .
|
COPY --from=install_stage /coin_bin .
|
||||||
|
|
||||||
|
|||||||
@@ -135,15 +135,15 @@
|
|||||||
(define-public basicswap
|
(define-public basicswap
|
||||||
(package
|
(package
|
||||||
(name "basicswap")
|
(name "basicswap")
|
||||||
(version "0.16.2")
|
(version "0.16.5")
|
||||||
(source (origin
|
(source (origin
|
||||||
(method git-fetch)
|
(method git-fetch)
|
||||||
(uri (git-reference
|
(uri (git-reference
|
||||||
(url "https://github.com/basicswap/basicswap")
|
(url "https://github.com/basicswap/basicswap")
|
||||||
(commit "ced017ab3a3234c68d3d8f773cf9ceb187a39adb")))
|
(commit "1aa53e38f96ffa753cc6eeaee1cc9fccbd0ce5dd")))
|
||||||
(sha256
|
(sha256
|
||||||
(base32
|
(base32
|
||||||
"0manck3zlf05by08b825ynqk7q1byzgy7p3i8chpg413mqkx7q5r"))
|
"0k2r16f0imyzh0x90a2a37m41imnd183vdlf9b8nrx4l884h543y"))
|
||||||
(file-name (git-file-name name version))))
|
(file-name (git-file-name name version))))
|
||||||
(build-system pyproject-build-system)
|
(build-system pyproject-build-system)
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -8,7 +8,7 @@ description = "Simple atomic swap system"
|
|||||||
keywords = ["crypto", "cryptocurrency", "particl", "bitcoin", "monero", "wownero"]
|
keywords = ["crypto", "cryptocurrency", "particl", "bitcoin", "monero", "wownero"]
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
license = {file = "LICENSE"}
|
license = {file = "LICENSE"}
|
||||||
requires-python = ">=3.9"
|
requires-python = ">=3.11"
|
||||||
classifiers = [
|
classifiers = [
|
||||||
"Programming Language :: Python :: 3",
|
"Programming Language :: Python :: 3",
|
||||||
"License :: OSI Approved :: MIT License",
|
"License :: OSI Approved :: MIT License",
|
||||||
@@ -36,7 +36,7 @@ dev = [
|
|||||||
"pre-commit",
|
"pre-commit",
|
||||||
"pytest",
|
"pytest",
|
||||||
"ruff",
|
"ruff",
|
||||||
"black==25.11.0",
|
"black==26.5.1",
|
||||||
"selenium",
|
"selenium",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
import hashlib
|
import hashlib
|
||||||
import logging
|
import logging
|
||||||
|
import os
|
||||||
import random
|
import random
|
||||||
import secrets
|
import secrets
|
||||||
import threading
|
import threading
|
||||||
@@ -22,10 +23,15 @@ from coincurve.ecdsaotves import (
|
|||||||
)
|
)
|
||||||
from coincurve.keys import PrivateKey
|
from coincurve.keys import PrivateKey
|
||||||
|
|
||||||
|
from basicswap.basicswap import (
|
||||||
|
Coins,
|
||||||
|
BasicSwap,
|
||||||
|
SwapTypes,
|
||||||
|
)
|
||||||
from basicswap.contrib.mnemonic import Mnemonic
|
from basicswap.contrib.mnemonic import Mnemonic
|
||||||
from basicswap.db import create_db_, DBMethods, KnownIdentity
|
from basicswap.db import create_db_, DBMethods, KnownIdentity
|
||||||
from basicswap.util import h2b
|
from basicswap.util import h2b
|
||||||
from basicswap.util.address import decodeAddress
|
from basicswap.util.address import decodeAddress, toWIF
|
||||||
from basicswap.util.crypto import ripemd160, hash160, blake256
|
from basicswap.util.crypto import ripemd160, hash160, blake256
|
||||||
from basicswap.util.extkey import ExtKeyPair
|
from basicswap.util.extkey import ExtKeyPair
|
||||||
from basicswap.util.integer import encode_varint, decode_varint
|
from basicswap.util.integer import encode_varint, decode_varint
|
||||||
@@ -60,6 +66,9 @@ from basicswap.contrib.test_framework.messages import (
|
|||||||
CTxOut,
|
CTxOut,
|
||||||
uint256_from_str,
|
uint256_from_str,
|
||||||
)
|
)
|
||||||
|
from tests.basicswap.common import (
|
||||||
|
PREFIX_SECRET_KEY_REGTEST,
|
||||||
|
)
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
|
||||||
@@ -790,6 +799,74 @@ class Test(unittest.TestCase):
|
|||||||
== "252cd6e85b99e0fd554c44d5fe638923f7ef563048362406a665cf3400feb1bd"
|
== "252cd6e85b99e0fd554c44d5fe638923f7ef563048362406a665cf3400feb1bd"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_validateSwapType(self):
|
||||||
|
logging.info("---------- Test validateSwapType")
|
||||||
|
basicswap_dir = "/tmp/bsx_test_other"
|
||||||
|
if not os.path.exists(basicswap_dir):
|
||||||
|
os.makedirs(basicswap_dir)
|
||||||
|
|
||||||
|
k = PrivateKey()
|
||||||
|
settings = {
|
||||||
|
"network_key": toWIF(PREFIX_SECRET_KEY_REGTEST, k.secret),
|
||||||
|
"network_pubkey": k.public_key.format().hex(),
|
||||||
|
}
|
||||||
|
|
||||||
|
sc = BasicSwap(
|
||||||
|
basicswap_dir,
|
||||||
|
settings,
|
||||||
|
"regtest",
|
||||||
|
log_name="bsx_test_other",
|
||||||
|
)
|
||||||
|
|
||||||
|
should_pass = [
|
||||||
|
(Coins.BTC, Coins.XMR, SwapTypes.XMR_SWAP),
|
||||||
|
(Coins.XMR, Coins.BTC, SwapTypes.XMR_SWAP),
|
||||||
|
(Coins.BTC, Coins.FIRO, SwapTypes.XMR_SWAP),
|
||||||
|
(Coins.FIRO, Coins.BTC, SwapTypes.XMR_SWAP),
|
||||||
|
(Coins.PIVX, Coins.BTC, SwapTypes.SELLER_FIRST),
|
||||||
|
(Coins.BTC, Coins.PIVX, SwapTypes.SELLER_FIRST),
|
||||||
|
(Coins.DASH, Coins.PIVX, SwapTypes.SELLER_FIRST),
|
||||||
|
(Coins.PIVX, Coins.DASH, SwapTypes.SELLER_FIRST),
|
||||||
|
]
|
||||||
|
should_fail = [
|
||||||
|
(Coins.BTC, Coins.XMR, SwapTypes.SELLER_FIRST),
|
||||||
|
(Coins.XMR, Coins.PART_ANON, SwapTypes.XMR_SWAP),
|
||||||
|
(Coins.FIRO, Coins.PART_ANON, SwapTypes.XMR_SWAP),
|
||||||
|
(Coins.PART_ANON, Coins.FIRO, SwapTypes.XMR_SWAP),
|
||||||
|
(Coins.FIRO, Coins.BTC, SwapTypes.SELLER_FIRST),
|
||||||
|
(Coins.BTC, Coins.FIRO, SwapTypes.SELLER_FIRST),
|
||||||
|
]
|
||||||
|
|
||||||
|
for case in should_pass:
|
||||||
|
sc.validateSwapType(case[0], case[1], case[2])
|
||||||
|
for case in should_fail:
|
||||||
|
self.assertRaises(
|
||||||
|
ValueError, sc.validateSwapType, case[0], case[1], case[2]
|
||||||
|
)
|
||||||
|
sc.chain = "mainnet"
|
||||||
|
for case in should_pass:
|
||||||
|
try:
|
||||||
|
sc.validateSwapType(case[0], case[1], case[2])
|
||||||
|
except Exception as e:
|
||||||
|
assert "Coin pair should use adaptor sig swap type" in str(e)
|
||||||
|
else:
|
||||||
|
if case[2] != SwapTypes.XMR_SWAP:
|
||||||
|
if (
|
||||||
|
case[0] not in sc.coins_without_segwit
|
||||||
|
or case[1] not in sc.coins_without_segwit
|
||||||
|
):
|
||||||
|
raise ValueError(f"Invalid swap pair in strict mode {case}")
|
||||||
|
for case in should_fail:
|
||||||
|
self.assertRaises(
|
||||||
|
ValueError, sc.validateSwapType, case[0], case[1], case[2]
|
||||||
|
)
|
||||||
|
|
||||||
|
sc.settings["strict_swap_type"] = False
|
||||||
|
for case in should_pass:
|
||||||
|
sc.validateSwapType(case[0], case[1], case[2])
|
||||||
|
|
||||||
|
del sc
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|||||||
+39
-52
@@ -26,11 +26,13 @@ from basicswap.basicswap import (
|
|||||||
TxStates,
|
TxStates,
|
||||||
)
|
)
|
||||||
from basicswap.basicswap_util import (
|
from basicswap.basicswap_util import (
|
||||||
|
EventLogTypes,
|
||||||
TxLockTypes,
|
TxLockTypes,
|
||||||
)
|
)
|
||||||
from basicswap.chainparams import (
|
from basicswap.chainparams import (
|
||||||
chainparams,
|
chainparams,
|
||||||
)
|
)
|
||||||
|
from basicswap.db import Concepts
|
||||||
from basicswap.util import (
|
from basicswap.util import (
|
||||||
COIN,
|
COIN,
|
||||||
make_int,
|
make_int,
|
||||||
@@ -47,6 +49,7 @@ from tests.basicswap.common import (
|
|||||||
wait_for_balance,
|
wait_for_balance,
|
||||||
wait_for_bid,
|
wait_for_bid,
|
||||||
wait_for_bid_tx_state,
|
wait_for_bid_tx_state,
|
||||||
|
wait_for_event,
|
||||||
wait_for_in_progress,
|
wait_for_in_progress,
|
||||||
wait_for_offer,
|
wait_for_offer,
|
||||||
wait_for_unspent,
|
wait_for_unspent,
|
||||||
@@ -159,35 +162,6 @@ class Test(BaseTest):
|
|||||||
rv = read_json_api(1800, "rateslist?from=PART&to=BTC")
|
rv = read_json_api(1800, "rateslist?from=PART&to=BTC")
|
||||||
assert len(rv) == 1
|
assert len(rv) == 1
|
||||||
|
|
||||||
def test_004_validateSwapType(self):
|
|
||||||
logging.info("---------- Test validateSwapType")
|
|
||||||
|
|
||||||
sc = self.swap_clients[0]
|
|
||||||
|
|
||||||
should_pass = [
|
|
||||||
(Coins.BTC, Coins.XMR, SwapTypes.XMR_SWAP),
|
|
||||||
(Coins.XMR, Coins.BTC, SwapTypes.XMR_SWAP),
|
|
||||||
(Coins.BTC, Coins.FIRO, SwapTypes.XMR_SWAP),
|
|
||||||
(Coins.FIRO, Coins.BTC, SwapTypes.XMR_SWAP),
|
|
||||||
(Coins.PIVX, Coins.BTC, SwapTypes.SELLER_FIRST),
|
|
||||||
(Coins.BTC, Coins.PIVX, SwapTypes.SELLER_FIRST),
|
|
||||||
]
|
|
||||||
should_fail = [
|
|
||||||
(Coins.BTC, Coins.XMR, SwapTypes.SELLER_FIRST),
|
|
||||||
(Coins.XMR, Coins.PART_ANON, SwapTypes.XMR_SWAP),
|
|
||||||
(Coins.FIRO, Coins.PART_ANON, SwapTypes.XMR_SWAP),
|
|
||||||
(Coins.PART_ANON, Coins.FIRO, SwapTypes.XMR_SWAP),
|
|
||||||
(Coins.FIRO, Coins.BTC, SwapTypes.SELLER_FIRST),
|
|
||||||
(Coins.BTC, Coins.FIRO, SwapTypes.SELLER_FIRST),
|
|
||||||
]
|
|
||||||
|
|
||||||
for case in should_pass:
|
|
||||||
sc.validateSwapType(case[0], case[1], case[2])
|
|
||||||
for case in should_fail:
|
|
||||||
self.assertRaises(
|
|
||||||
ValueError, sc.validateSwapType, case[0], case[1], case[2]
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_003_cltv(self):
|
def test_003_cltv(self):
|
||||||
test_coin_from = Coins.PART
|
test_coin_from = Coins.PART
|
||||||
logging.info("---------- Test {} cltv".format(test_coin_from.name))
|
logging.info("---------- Test {} cltv".format(test_coin_from.name))
|
||||||
@@ -879,7 +853,6 @@ class Test(BaseTest):
|
|||||||
swap_clients = self.swap_clients
|
swap_clients = self.swap_clients
|
||||||
|
|
||||||
swap_value = make_int(random.uniform(0.001, 10.0), scale=8, r=1)
|
swap_value = make_int(random.uniform(0.001, 10.0), scale=8, r=1)
|
||||||
logging.info("swap_value {}".format(format_amount(swap_value, 8)))
|
|
||||||
offer_id = swap_clients[0].postOffer(
|
offer_id = swap_clients[0].postOffer(
|
||||||
Coins.LTC,
|
Coins.LTC,
|
||||||
Coins.BTC,
|
Coins.BTC,
|
||||||
@@ -908,15 +881,15 @@ class Test(BaseTest):
|
|||||||
)
|
)
|
||||||
wait_for_bid(
|
wait_for_bid(
|
||||||
test_delay_event,
|
test_delay_event,
|
||||||
swap_clients[1],
|
swap_clients[0],
|
||||||
bid_id,
|
bid_id,
|
||||||
BidStates.SWAP_COMPLETED,
|
BidStates.SWAP_COMPLETED,
|
||||||
sent=True,
|
sent=True,
|
||||||
wait_for=30,
|
wait_for=30,
|
||||||
)
|
)
|
||||||
|
|
||||||
js_0_bid = read_json_api(1800, "bids/{}".format(bid_id.hex()))
|
js_0_bid = read_json_api(1800, f"bids/{bid_id.hex()}")
|
||||||
js_1_bid = read_json_api(1801, "bids/{}".format(bid_id.hex()))
|
js_1_bid = read_json_api(1801, f"bids/{bid_id.hex()}")
|
||||||
assert js_0_bid["itx_state"] == "Refunded"
|
assert js_0_bid["itx_state"] == "Refunded"
|
||||||
assert js_1_bid["ptx_state"] == "Refunded"
|
assert js_1_bid["ptx_state"] == "Refunded"
|
||||||
|
|
||||||
@@ -933,38 +906,52 @@ class Test(BaseTest):
|
|||||||
assert compare_bid_states(offerer_states, self.states_offerer_sh[1]) is True
|
assert compare_bid_states(offerer_states, self.states_offerer_sh[1]) is True
|
||||||
assert compare_bid_states(bidder_states, self.states_bidder_sh[1]) is True
|
assert compare_bid_states(bidder_states, self.states_bidder_sh[1]) is True
|
||||||
|
|
||||||
"""
|
def test_11_bad_itx(self):
|
||||||
def test_11_refund(self):
|
# Invalid ITx sent, PTx should not be sent
|
||||||
# Seller submits initiate txn, buyer doesn't respond, repeat of test 5 using debug_ind
|
logging.info("---------- Test bad ITx, LTC to BTC")
|
||||||
logging.info('---------- Test refund, LTC to BTC')
|
|
||||||
swap_clients = self.swap_clients
|
swap_clients = self.swap_clients
|
||||||
|
|
||||||
swap_value = make_int(random.uniform(0.001, 10.0), scale=8, r=1)
|
swap_value = make_int(random.uniform(0.001, 10.0), scale=8, r=1)
|
||||||
logging.info('swap_value {}'.format(format_amount(swap_value, 8)))
|
offer_id = swap_clients[0].postOffer(
|
||||||
offer_id = swap_clients[0].postOffer(Coins.LTC, Coins.BTC, swap_value, 0.1 * COIN, swap_value, SwapTypes.SELLER_FIRST,
|
Coins.LTC,
|
||||||
TxLockTypes.SEQUENCE_LOCK_BLOCKS, 10)
|
Coins.BTC,
|
||||||
|
swap_value,
|
||||||
|
0.1 * COIN,
|
||||||
|
swap_value,
|
||||||
|
SwapTypes.SELLER_FIRST,
|
||||||
|
TxLockTypes.SEQUENCE_LOCK_BLOCKS,
|
||||||
|
18,
|
||||||
|
)
|
||||||
|
|
||||||
wait_for_offer(test_delay_event, swap_clients[1], offer_id)
|
wait_for_offer(test_delay_event, swap_clients[1], offer_id)
|
||||||
offer = swap_clients[1].getOffer(offer_id)
|
offer = swap_clients[1].getOffer(offer_id)
|
||||||
bid_id = swap_clients[1].postBid(offer_id, offer.amount_from)
|
bid_id = swap_clients[1].postBid(offer_id, offer.amount_from)
|
||||||
swap_clients[1].setBidDebugInd(bid_id, DebugTypes.BUYER_STOP_AFTER_ITX)
|
|
||||||
|
|
||||||
wait_for_bid(test_delay_event, swap_clients[0], bid_id)
|
wait_for_bid(test_delay_event, swap_clients[0], bid_id)
|
||||||
|
swap_clients[0].setBidDebugInd(bid_id, DebugTypes.MAKE_INVALID_ITX)
|
||||||
swap_clients[0].acceptBid(bid_id)
|
swap_clients[0].acceptBid(bid_id)
|
||||||
|
|
||||||
wait_for_bid(test_delay_event, swap_clients[0], bid_id, BidStates.SWAP_COMPLETED, wait_for=120)
|
event = wait_for_event(
|
||||||
wait_for_bid(test_delay_event, swap_clients[1], bid_id, BidStates.BID_ABANDONED, sent=True, wait_for=30)
|
test_delay_event,
|
||||||
|
swap_clients[1],
|
||||||
|
Concepts.BID,
|
||||||
|
bid_id,
|
||||||
|
event_type=EventLogTypes.ERROR,
|
||||||
|
wait_for=120,
|
||||||
|
)
|
||||||
|
assert "Incorrect output amount in initiate txn " in event.event_msg
|
||||||
|
|
||||||
js_0_bid = read_json_api(1800, 'bids/{}'.format(bid_id.hex()))
|
wait_for_bid(
|
||||||
js_1_bid = read_json_api(1801, 'bids/{}'.format(bid_id.hex()))
|
test_delay_event,
|
||||||
assert (js_0_bid['itx_state'] == 'Refunded')
|
swap_clients[1],
|
||||||
assert (js_1_bid['ptx_state'] == 'Unknown')
|
bid_id,
|
||||||
|
BidStates.BID_ERROR,
|
||||||
|
sent=True,
|
||||||
|
wait_for=30,
|
||||||
|
)
|
||||||
|
|
||||||
js_0 = read_json_api(1800)
|
js_1_bid = read_json_api(1801, f"bids/{bid_id.hex()}")
|
||||||
js_1 = read_json_api(1801)
|
assert js_1_bid["ptx_state"] == "Unknown"
|
||||||
assert (js_0['num_swapping'] == 0 and js_0['num_watched_outputs'] == 0)
|
|
||||||
assert (js_1['num_swapping'] == 0 and js_1['num_watched_outputs'] == 0)
|
|
||||||
"""
|
|
||||||
|
|
||||||
def test_12_withdrawal(self):
|
def test_12_withdrawal(self):
|
||||||
logging.info("---------- Test LTC withdrawals")
|
logging.info("---------- Test LTC withdrawals")
|
||||||
|
|||||||
@@ -23,9 +23,7 @@ from copy import deepcopy
|
|||||||
from coincurve.keys import PrivateKey
|
from coincurve.keys import PrivateKey
|
||||||
|
|
||||||
import basicswap.config as cfg
|
import basicswap.config as cfg
|
||||||
from basicswap.db import (
|
from basicswap.db import Concepts
|
||||||
Concepts,
|
|
||||||
)
|
|
||||||
from basicswap.basicswap import (
|
from basicswap.basicswap import (
|
||||||
Coins,
|
Coins,
|
||||||
BasicSwap,
|
BasicSwap,
|
||||||
@@ -38,9 +36,7 @@ from basicswap.basicswap_util import (
|
|||||||
EventLogTypes,
|
EventLogTypes,
|
||||||
)
|
)
|
||||||
from basicswap.util import COIN, format_amount, make_int, TemporaryError
|
from basicswap.util import COIN, format_amount, make_int, TemporaryError
|
||||||
from basicswap.util.address import (
|
from basicswap.util.address import toWIF
|
||||||
toWIF,
|
|
||||||
)
|
|
||||||
from basicswap.rpc import (
|
from basicswap.rpc import (
|
||||||
callrpc,
|
callrpc,
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user