Compare commits

...

7 Commits

Author SHA1 Message Date
tecnovert cf836878fd Merge branch 'dev' into cryptoguard-patch-2 2026-06-09 12:12:45 +00:00
tecnovert 37d564b4f7 Update release-notes.md
The PTX amount is already checked in getLockTxHeight.
Tested in test_run.py, test_10_bad_ptx.
2026-06-09 12:10:16 +00:00
tecnovert d2cbce0de9 Merge pull request #496 from tecnovert/strict_swap_types
Reject secret-hash offers where coin pair can use adaptor-sig
2026-06-09 12:00:00 +00:00
tecnovert 3aacc57f09 feat: reject secret-hash offers where coin pair can use adaptor sig 2026-06-09 12:05:31 +02:00
tecnovert d23665d585 build: update docker base images to debian:trixie 2026-06-09 12:03:02 +02:00
dependabot[bot] 553b5a6a32 build(deps-dev): bump black from 26.3.1 to 26.5.1
Bumps [black](https://github.com/psf/black) from 26.3.1 to 26.5.1.
- [Release notes](https://github.com/psf/black/releases)
- [Changelog](https://github.com/psf/black/blob/main/CHANGES.md)
- [Commits](https://github.com/psf/black/compare/26.3.1...26.5.1)

---
updated-dependencies:
- dependency-name: black
  dependency-version: 26.5.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-09 11:01:32 +02:00
Cryptoguard 827909b322 Update release-notes.md 2026-06-08 20:57:24 -04:00
19 changed files with 137 additions and 53 deletions
+10 -5
View File
@@ -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
+10
View File
@@ -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:
+18
View File
@@ -1,3 +1,21 @@
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.
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
============== ==============
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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 .
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+8 -3
View File
@@ -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
+1 -1
View File
@@ -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 .
+1 -1
View File
@@ -36,7 +36,7 @@ dev = [
"pre-commit", "pre-commit",
"pytest", "pytest",
"ruff", "ruff",
"black==26.3.1", "black==26.5.1",
"selenium", "selenium",
] ]
+78 -1
View File
@@ -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()
-29
View File
@@ -159,35 +159,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))
+1 -3
View File
@@ -38,9 +38,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,
) )