Add safe_logs option to anonymise logs. ()

* Add safe_logs option to anonymise logs.

* Extend logger class.
This commit is contained in:
tecnovert 2025-02-22 15:54:13 +00:00 committed by GitHub
parent 8d317e4b67
commit f1c2b41714
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 735 additions and 805 deletions

View file

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019-2024 tecnovert
# Copyright (c) 2024 The Basicswap developers
# Copyright (c) 2024-2025 The Basicswap developers
# Distributed under the MIT software license, see the accompanying
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
@ -28,6 +28,9 @@ from .rpc import (
from .util import (
TemporaryError,
)
from .util.logging import (
BSXLogger,
)
from .chainparams import (
Coins,
chainparams,
@ -75,6 +78,7 @@ class BaseApp(DBMethods):
self.delay_event.set()
def prepareLogging(self):
logging.setLoggerClass(BSXLogger)
self.log = logging.getLogger(self.log_name)
self.log.propagate = False

File diff suppressed because it is too large Load diff

View file

@ -1,13 +1,13 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2024 The Basicswap developers
# Copyright (c) 2024-2025 The Basicswap developers
# Distributed under the MIT software license, see the accompanying
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
from typing import Union
from basicswap.contrib.test_framework.messages import COutPoint, CTransaction, CTxIn
from basicswap.util import b2h, b2i, ensure, i2h
from basicswap.util import b2i, ensure, i2b
from basicswap.util.script import decodePushData, decodeScriptNum
from .btc import BTCInterface, ensure_op, findOutput
from basicswap.rpc import make_rpc_func
@ -454,11 +454,14 @@ class BCHInterface(BTCInterface):
tx.rehash()
self._log.info(
"createSCLockSpendTx %s:\n fee_rate, size, fee: %ld, %ld, %ld.",
i2h(tx.sha256),
tx_fee_rate,
size,
pay_fee,
"createSCLockSpendTx {}{}.".format(
self._log.id(i2b(tx.sha256)),
(
""
if self._log.safe_logs
else f":\n fee_rate, vsize, fee: {tx_fee_rate}, {size}, {pay_fee}"
),
)
)
return tx.serialize_without_witness()
@ -506,11 +509,14 @@ class BCHInterface(BTCInterface):
tx.rehash()
self._log.info(
"createSCLockRefundTx %s:\n fee_rate, vsize, fee: %ld, %ld, %ld.",
i2h(tx.sha256),
tx_fee_rate,
vsize,
pay_fee,
"createSCLockRefundTx {}{}.".format(
self._log.id(i2b(tx.sha256)),
(
""
if self._log.safe_logs
else f":\n fee_rate, vsize, fee: {tx_fee_rate}, {vsize}, {pay_fee}"
),
)
)
return tx.serialize_without_witness(), refund_script, tx.vout[0].nValue
@ -582,11 +588,14 @@ class BCHInterface(BTCInterface):
tx.rehash()
self._log.info(
"createSCLockRefundSpendToFTx %s:\n fee_rate, vsize, fee: %ld, %ld, %ld.",
i2h(tx.sha256),
tx_fee_rate,
vsize,
pay_fee,
"createSCLockRefundSpendToFTx {}{}.".format(
self._log.id(i2b(tx.sha256)),
(
""
if self._log.safe_logs
else f":\n fee_rate, vsize, fee: {tx_fee_rate}, {vsize}, {pay_fee}"
),
)
)
return tx.serialize_without_witness()
@ -780,7 +789,7 @@ class BCHInterface(BTCInterface):
tx = self.loadTx(tx_bytes)
txid = self.getTxid(tx)
self._log.info("Verifying lock tx: {}.".format(b2h(txid)))
self._log.info("Verifying lock tx: {}.".format(self._log.id(txid)))
ensure(tx.nVersion == self.txVersion(), "Bad version")
ensure(tx.nLockTime == 0, "Bad nLockTime") # TODO match txns created by cores
@ -835,7 +844,7 @@ class BCHInterface(BTCInterface):
tx = self.loadTx(tx_bytes)
txid = self.getTxid(tx)
self._log.info("Verifying lock refund tx: {}.".format(b2h(txid)))
self._log.info("Verifying lock refund tx: {}.".format(self._log.id(txid)))
ensure(tx.nVersion == self.txVersion(), "Bad version")
ensure(tx.nLockTime == 0, "nLockTime not 0")
@ -881,7 +890,7 @@ class BCHInterface(BTCInterface):
size = self.getTxSize(tx)
vsize = size
self._log.info(
self._log.info_s(
"tx amount, vsize, fee: %ld, %ld, %ld", locked_coin, vsize, fee_paid
)
@ -905,7 +914,7 @@ class BCHInterface(BTCInterface):
# Must have only one output sending lock refund tx value - fee to leader's address, TODO: follower shouldn't need to verify destination addr
tx = self.loadTx(tx_bytes)
txid = self.getTxid(tx)
self._log.info("Verifying lock refund spend tx: {}.".format(b2h(txid)))
self._log.info("Verifying lock refund spend tx: {}.".format(self._log.id(txid)))
ensure(tx.nVersion == self.txVersion(), "Bad version")
ensure(tx.nLockTime == 0, "nLockTime not 0")
@ -947,9 +956,7 @@ class BCHInterface(BTCInterface):
size = self.getTxSize(tx)
vsize = size
self._log.info(
"tx amount, vsize, fee: %ld, %ld, %ld", tx_value, vsize, fee_paid
)
self._log.info_s(f"tx amount, vsize, fee: {tx_value}, {vsize}, {fee_paid}")
return True
@ -962,7 +969,7 @@ class BCHInterface(BTCInterface):
tx = self.loadTx(tx_bytes)
txid = self.getTxid(tx)
self._log.info("Verifying lock spend tx: {}.".format(b2h(txid)))
self._log.info("Verifying lock spend tx: {}.".format(self._log.id(txid)))
ensure(tx.nVersion == self.txVersion(), "Bad version")
ensure(tx.nLockTime == 0, "nLockTime not 0")
@ -995,7 +1002,7 @@ class BCHInterface(BTCInterface):
size = self.getTxSize(tx)
vsize = size
self._log.info(
self._log.info_s(
"tx amount, vsize, fee: %ld, %ld, %ld", tx.vout[0].nValue, vsize, fee_paid
)
@ -1115,11 +1122,14 @@ class BCHInterface(BTCInterface):
tx.rehash()
self._log.info(
"createMercyTx %s:\n fee_rate, vsize, fee: %ld, %ld, %ld.",
i2h(tx.sha256),
1,
vsize,
pay_fee,
"createMercyTx {}{}.".format(
self._log.id(i2b(tx.sha256)),
(
""
if self._log.safe_logs
else f":\n fee_rate, vsize, fee: {1}, {vsize}, {pay_fee}"
),
)
)
txHex = tx.serialize_without_witness()

View file

@ -21,7 +21,6 @@ from basicswap.basicswap_util import (
from basicswap.interface.base import Secp256k1Interface
from basicswap.util import (
ensure,
b2h,
i2b,
b2i,
i2h,
@ -319,7 +318,9 @@ class BTCInterface(Secp256k1Interface):
if wallet_name in ("mweb",):
continue
change_watchonly_wallet: bool = self._rpc_wallet_watch == self._rpc_wallet
change_watchonly_wallet: bool = (
self._rpc_wallet_watch == self._rpc_wallet
)
self._rpc_wallet = wallet_name
self._log.info(
@ -733,11 +734,14 @@ class BTCInterface(Secp256k1Interface):
tx.rehash()
self._log.info(
"createSCLockRefundTx %s:\n fee_rate, vsize, fee: %ld, %ld, %ld.",
i2h(tx.sha256),
tx_fee_rate,
vsize,
pay_fee,
"createSCLockRefundTx {}{}.".format(
self._log.id(i2b(tx.sha256)),
(
""
if self._log.safe_logs
else f":\n fee_rate, vsize, fee: {tx_fee_rate}, {vsize}, {pay_fee}"
),
)
)
return tx.serialize(), refund_script, tx.vout[0].nValue
@ -788,11 +792,14 @@ class BTCInterface(Secp256k1Interface):
tx.rehash()
self._log.info(
"createSCLockRefundSpendTx %s:\n fee_rate, vsize, fee: %ld, %ld, %ld.",
i2h(tx.sha256),
tx_fee_rate,
vsize,
pay_fee,
"createSCLockRefundSpendTx {}{}.".format(
self._log.id(i2b(tx.sha256)),
(
""
if self._log.safe_logs
else f":\n fee_rate, vsize, fee: {tx_fee_rate}, {vsize}, {pay_fee}"
),
)
)
return tx.serialize()
@ -855,11 +862,14 @@ class BTCInterface(Secp256k1Interface):
tx.rehash()
self._log.info(
"createSCLockRefundSpendToFTx %s:\n fee_rate, vsize, fee: %ld, %ld, %ld.",
i2h(tx.sha256),
tx_fee_rate,
vsize,
pay_fee,
"createSCLockRefundSpendToFTx {}{}.".format(
self._log.id(i2b(tx.sha256)),
(
""
if self._log.safe_logs
else f":\n fee_rate, vsize, fee: {tx_fee_rate}, {vsize}, {pay_fee}"
),
)
)
return tx.serialize()
@ -902,11 +912,14 @@ class BTCInterface(Secp256k1Interface):
tx.rehash()
self._log.info(
"createSCLockSpendTx %s:\n fee_rate, vsize, fee: %ld, %ld, %ld.",
i2h(tx.sha256),
tx_fee_rate,
vsize,
pay_fee,
"createSCLockSpendTx {}{}.".format(
self._log.id(i2b(tx.sha256)),
(
""
if self._log.safe_logs
else f":\n fee_rate, vsize, fee: {tx_fee_rate}, {vsize}, {pay_fee}"
),
)
)
return tx.serialize()
@ -931,7 +944,7 @@ class BTCInterface(Secp256k1Interface):
tx = self.loadTx(tx_bytes)
txid = self.getTxid(tx)
self._log.info("Verifying lock tx: {}.".format(b2h(txid)))
self._log.info("Verifying lock tx: {}.".format(self._log.id(txid)))
ensure(tx.nVersion == self.txVersion(), "Bad version")
ensure(tx.nLockTime == 0, "Bad nLockTime") # TODO match txns created by cores
@ -1019,7 +1032,7 @@ class BTCInterface(Secp256k1Interface):
tx = self.loadTx(tx_bytes)
txid = self.getTxid(tx)
self._log.info("Verifying lock refund tx: {}.".format(b2h(txid)))
self._log.info("Verifying lock refund tx: {}.".format(self._log.id(txid)))
ensure(tx.nVersion == self.txVersion(), "Bad version")
ensure(tx.nLockTime == 0, "nLockTime not 0")
@ -1058,7 +1071,7 @@ class BTCInterface(Secp256k1Interface):
vsize = self.getTxVSize(tx, add_witness_bytes=witness_bytes)
fee_rate_paid = fee_paid * 1000 // vsize
self._log.info(
self._log.info_s(
"tx amount, vsize, feerate: %ld, %ld, %ld",
locked_coin,
vsize,
@ -1087,7 +1100,7 @@ class BTCInterface(Secp256k1Interface):
# Must have only one output sending lock refund tx value - fee to leader's address, TODO: follower shouldn't need to verify destination addr
tx = self.loadTx(tx_bytes)
txid = self.getTxid(tx)
self._log.info("Verifying lock refund spend tx: {}.".format(b2h(txid)))
self._log.info("Verifying lock refund spend tx: {}.".format(self._log.id(txid)))
ensure(tx.nVersion == self.txVersion(), "Bad version")
ensure(tx.nLockTime == 0, "nLockTime not 0")
@ -1124,7 +1137,7 @@ class BTCInterface(Secp256k1Interface):
vsize = self.getTxVSize(tx, add_witness_bytes=witness_bytes)
fee_rate_paid = fee_paid * 1000 // vsize
self._log.info(
self._log.info_s(
"tx amount, vsize, feerate: %ld, %ld, %ld", tx_value, vsize, fee_rate_paid
)
@ -1142,7 +1155,7 @@ class BTCInterface(Secp256k1Interface):
tx = self.loadTx(tx_bytes)
txid = self.getTxid(tx)
self._log.info("Verifying lock spend tx: {}.".format(b2h(txid)))
self._log.info("Verifying lock spend tx: {}.".format(self._log.id(txid)))
ensure(tx.nVersion == self.txVersion(), "Bad version")
ensure(tx.nLockTime == 0, "nLockTime not 0")
@ -1180,7 +1193,7 @@ class BTCInterface(Secp256k1Interface):
vsize = self.getTxVSize(tx, add_witness_bytes=witness_bytes)
fee_rate_paid = fee_paid * 1000 // vsize
self._log.info(
self._log.info_s(
"tx amount, vsize, feerate: %ld, %ld, %ld",
tx.vout[0].nValue,
vsize,
@ -1490,7 +1503,7 @@ class BTCInterface(Secp256k1Interface):
witness_bytes = 109
vsize = self.getTxVSize(tx, add_witness_bytes=witness_bytes)
pay_fee = round(fee_rate * vsize / 1000)
self._log.info(
self._log.info_s(
f"BLockSpendTx fee_rate, vsize, fee: {fee_rate}, {vsize}, {pay_fee}."
)
return pay_fee
@ -1508,7 +1521,9 @@ class BTCInterface(Secp256k1Interface):
lock_tx_vout=None,
) -> bytes:
self._log.info(
"spendBLockTx: {} {}\n".format(chain_b_lock_txid.hex(), lock_tx_vout)
"spendBLockTx: {} {}\n".format(
self._log.id(chain_b_lock_txid), lock_tx_vout
)
)
locked_n = lock_tx_vout
@ -1589,7 +1604,9 @@ class BTCInterface(Secp256k1Interface):
# Add watchonly address and rescan if required
if not self.isAddressMine(dest_address, or_watch_only=True):
self.importWatchOnlyAddress(dest_address, "bid")
self._log.info("Imported watch-only addr: {}".format(dest_address))
self._log.info(
"Imported watch-only addr: {}".format(self._log.addr(dest_address))
)
self._log.info(
"Rescanning {} chain from height: {}".format(
self.coin_name(), rescan_from

View file

@ -27,7 +27,6 @@ from basicswap.interface.btc import (
)
from basicswap.util import (
ensure,
b2h,
b2i,
i2b,
i2h,
@ -1130,11 +1129,14 @@ class DCRInterface(Secp256k1Interface):
fee_info["size"] = size
self._log.info(
"createSCLockSpendTx %s:\n fee_rate, size, fee: %ld, %ld, %ld.",
tx.TxHash().hex(),
tx_fee_rate,
size,
pay_fee,
"createSCLockSpendTx {}{}.".format(
self._log.id(tx.TxHash()),
(
""
if self._log.safe_logs
else f":\n fee_rate, size, fee: {tx_fee_rate}, {size}, {pay_fee}"
),
)
)
return tx.serialize(TxSerializeType.NoWitness)
@ -1174,11 +1176,14 @@ class DCRInterface(Secp256k1Interface):
tx.vout[0].value = locked_coin - pay_fee
self._log.info(
"createSCLockRefundTx %s:\n fee_rate, size, fee: %ld, %ld, %ld.",
tx.TxHash().hex(),
tx_fee_rate,
size,
pay_fee,
"createSCLockRefundTx {}{}.".format(
self._log.id(tx.TxHash()),
(
""
if self._log.safe_logs
else f":\n fee_rate, size, fee: {tx_fee_rate}, {size}, {pay_fee}"
),
)
)
return tx.serialize(TxSerializeType.NoWitness), refund_script, tx.vout[0].value
@ -1222,11 +1227,14 @@ class DCRInterface(Secp256k1Interface):
tx.vout[0].value = locked_coin - pay_fee
self._log.info(
"createSCLockRefundSpendTx %s:\n fee_rate, size, fee: %ld, %ld, %ld.",
tx.TxHash().hex(),
tx_fee_rate,
size,
pay_fee,
"createSCLockRefundSpendTx {}{}.".format(
self._log.id(tx.TxHash()),
(
""
if self._log.safe_logs
else f":\n fee_rate, size, fee: {tx_fee_rate}, {size}, {pay_fee}"
),
)
)
return tx.serialize(TxSerializeType.NoWitness)
@ -1251,7 +1259,7 @@ class DCRInterface(Secp256k1Interface):
tx = self.loadTx(tx_bytes)
txid = self.getTxid(tx)
self._log.info("Verifying lock tx: {}.".format(b2h(txid)))
self._log.info("Verifying lock tx: {}.".format(self._log.id(txid)))
ensure(tx.version == self.txVersion(), "Bad version")
ensure(tx.locktime == 0, "Bad locktime")
@ -1327,7 +1335,7 @@ class DCRInterface(Secp256k1Interface):
tx = self.loadTx(tx_bytes)
txid = self.getTxid(tx)
self._log.info("Verifying lock spend tx: {}.".format(b2h(txid)))
self._log.info("Verifying lock spend tx: {}.".format(self._log.id(txid)))
ensure(tx.version == self.txVersion(), "Bad version")
ensure(tx.locktime == 0, "Bad locktime")
@ -1397,7 +1405,7 @@ class DCRInterface(Secp256k1Interface):
tx = self.loadTx(tx_bytes)
txid = self.getTxid(tx)
self._log.info("Verifying lock refund tx: {}.".format(b2h(txid)))
self._log.info("Verifying lock refund tx: {}.".format(self._log.id(txid)))
ensure(tx.version == self.txVersion(), "Bad version")
ensure(tx.locktime == 0, "locktime not 0")
@ -1460,7 +1468,7 @@ class DCRInterface(Secp256k1Interface):
# Must have only one output sending lock refund tx value - fee to leader's address, TODO: follower shouldn't need to verify destination addr
tx = self.loadTx(tx_bytes)
txid = self.getTxid(tx)
self._log.info("Verifying lock refund spend tx: {}.".format(b2h(txid)))
self._log.info("Verifying lock refund spend tx: {}.".format(self._log.id(txid)))
ensure(tx.version == self.txVersion(), "Bad version")
ensure(tx.locktime == 0, "locktime not 0")
@ -1546,11 +1554,14 @@ class DCRInterface(Secp256k1Interface):
tx.vout[0].value = locked_amount - pay_fee
self._log.info(
"createSCLockRefundSpendToFTx %s:\n fee_rate, size, fee: %ld, %ld, %ld.",
tx.TxHash().hex(),
tx_fee_rate,
size,
pay_fee,
"createSCLockRefundSpendToFTx {}{}.".format(
self._log.id(tx.TxHash()),
(
""
if self._log.safe_logs
else f":\n fee_rate, size, fee: {tx_fee_rate}, {size}, {pay_fee}"
),
)
)
return tx.serialize(TxSerializeType.NoWitness)
@ -1719,7 +1730,7 @@ class DCRInterface(Secp256k1Interface):
witness_bytes = 115
size = len(tx.serialize()) + witness_bytes
pay_fee = round(fee_rate * size / 1000)
self._log.info(
self._log.info_s(
f"BLockSpendTx fee_rate, vsize, fee: {fee_rate}, {size}, {pay_fee}."
)
return pay_fee

View file

@ -105,7 +105,9 @@ class FIROInterface(BTCInterface):
if not self.isAddressMine(dest_address, or_watch_only=True):
self.importWatchOnlyAddress(dest_address, "bid")
self._log.info("Imported watch-only addr: {}".format(dest_address))
self._log.info(
"Imported watch-only addr: {}".format(self._log.addr(dest_address))
)
self._log.info(
"Rescanning {} chain from height: {}".format(
self.coin_name(), rescan_from

View file

@ -41,7 +41,6 @@ from basicswap.util.address import (
from basicswap.util import (
b2i,
i2b,
i2h,
ensure,
)
from basicswap.basicswap_util import (
@ -552,7 +551,9 @@ class NAVInterface(BTCInterface):
if not self.isAddressMine(dest_address, or_watch_only=True):
self.importWatchOnlyAddress(dest_address, "bid")
self._log.info("Imported watch-only addr: {}".format(dest_address))
self._log.info(
"Imported watch-only addr: {}".format(self._log.addr(dest_address))
)
self._log.info(
"Rescanning {} chain from height: {}".format(
self.coin_name(), rescan_from
@ -816,11 +817,14 @@ class NAVInterface(BTCInterface):
tx.rehash()
self._log.info(
"createSCLockRefundTx %s:\n fee_rate, vsize, fee: %ld, %ld, %ld.",
i2h(tx.sha256),
tx_fee_rate,
vsize,
pay_fee,
"createSCLockRefundTx {}{}.".format(
self._log.id(i2b(tx.sha256)),
(
""
if self._log.safe_logs
else f":\n fee_rate, vsize, fee: {tx_fee_rate}, {vsize}, {pay_fee}"
),
)
)
return tx.serialize(), refund_script, tx.vout[0].nValue
@ -871,11 +875,14 @@ class NAVInterface(BTCInterface):
tx.rehash()
self._log.info(
"createSCLockRefundSpendTx %s:\n fee_rate, vsize, fee: %ld, %ld, %ld.",
i2h(tx.sha256),
tx_fee_rate,
vsize,
pay_fee,
"createSCLockRefundSpendTx {}{}.".format(
self._log.id(i2b(tx.sha256)),
(
""
if self._log.safe_logs
else f":\n fee_rate, vsize, fee: {tx_fee_rate}, {vsize}, {pay_fee}"
),
)
)
return tx.serialize()
@ -928,11 +935,14 @@ class NAVInterface(BTCInterface):
tx.rehash()
self._log.info(
"createSCLockRefundSpendToFTx %s:\n fee_rate, vsize, fee: %ld, %ld, %ld.",
i2h(tx.sha256),
tx_fee_rate,
vsize,
pay_fee,
"createSCLockRefundSpendToFTx {}{}.".format(
self._log.id(i2b(tx.sha256)),
(
""
if self._log.safe_logs
else f":\n fee_rate, vsize, fee: {tx_fee_rate}, {vsize}, {pay_fee}"
),
)
)
return tx.serialize()
@ -975,11 +985,14 @@ class NAVInterface(BTCInterface):
tx.rehash()
self._log.info(
"createSCLockSpendTx %s:\n fee_rate, vsize, fee: %ld, %ld, %ld.",
i2h(tx.sha256),
tx_fee_rate,
vsize,
pay_fee,
"createSCLockSpendTx {}{}.".format(
self._log.id(i2b(tx.sha256)),
(
""
if self._log.safe_logs
else f":\n fee_rate, vsize, fee: {tx_fee_rate}, {vsize}, {pay_fee}"
),
)
)
return tx.serialize()

View file

@ -477,7 +477,7 @@ class PARTInterfaceBlind(PARTInterface):
):
lock_tx_obj = self.rpc("decoderawtransaction", [tx_bytes.hex()])
lock_txid_hex = lock_tx_obj["txid"]
self._log.info("Verifying lock tx: {}.".format(lock_txid_hex))
self._log.info("Verifying lock tx: {}.".format(self._log.id(lock_txid_hex)))
ensure(lock_tx_obj["version"] == self.txVersion(), "Bad version")
ensure(lock_tx_obj["locktime"] == 0, "Bad nLockTime")
@ -541,7 +541,9 @@ class PARTInterfaceBlind(PARTInterface):
):
lock_refund_tx_obj = self.rpc("decoderawtransaction", [tx_bytes.hex()])
lock_refund_txid_hex = lock_refund_tx_obj["txid"]
self._log.info("Verifying lock refund tx: {}.".format(lock_refund_txid_hex))
self._log.info(
"Verifying lock refund tx: {}.".format(self._log.id(lock_refund_txid_hex))
)
ensure(lock_refund_tx_obj["version"] == self.txVersion(), "Bad version")
ensure(lock_refund_tx_obj["locktime"] == 0, "Bad nLockTime")
@ -630,7 +632,9 @@ class PARTInterfaceBlind(PARTInterface):
lock_refund_spend_tx_obj = self.rpc("decoderawtransaction", [tx_bytes.hex()])
lock_refund_spend_txid_hex = lock_refund_spend_tx_obj["txid"]
self._log.info(
"Verifying lock refund spend tx: {}.".format(lock_refund_spend_txid_hex)
"Verifying lock refund spend tx: {}.".format(
self._log.id(lock_refund_spend_txid_hex)
)
)
ensure(lock_refund_spend_tx_obj["version"] == self.txVersion(), "Bad version")
@ -789,11 +793,14 @@ class PARTInterfaceBlind(PARTInterface):
)
actual_tx_fee_rate = pay_fee * 1000 // vsize
self._log.info(
"createSCLockSpendTx %s:\n fee_rate, vsize, fee: %ld, %ld, %ld.",
lock_spend_tx_obj["txid"],
actual_tx_fee_rate,
vsize,
pay_fee,
"createSCLockSpendTx {}{}.".format(
self._log.id(lock_spend_tx_obj["txid"]),
(
""
if self._log.safe_logs
else f":\n fee_rate, vsize, fee: {actual_tx_fee_rate}, {vsize}, {pay_fee}"
),
)
)
fee_info["vsize"] = vsize
@ -808,7 +815,9 @@ class PARTInterfaceBlind(PARTInterface):
):
lock_spend_tx_obj = self.rpc("decoderawtransaction", [tx_bytes.hex()])
lock_spend_txid_hex = lock_spend_tx_obj["txid"]
self._log.info("Verifying lock spend tx: {}.".format(lock_spend_txid_hex))
self._log.info(
"Verifying lock spend tx: {}.".format(self._log.id(lock_spend_txid_hex))
)
ensure(lock_spend_tx_obj["version"] == self.txVersion(), "Bad version")
ensure(lock_spend_tx_obj["locktime"] == 0, "Bad nLockTime")

View file

@ -180,7 +180,19 @@ class XMRInterface(CoinInterface):
if self._wallet_password is not None:
params["password"] = self._wallet_password
rv = self.rpc_wallet("generate_from_keys", params)
self._log.info("generate_from_keys %s", dumpj(rv))
if "address" in rv:
new_address: str = rv["address"]
is_watch_only: bool = "Watch-only" in rv.get("info", "")
self._log.info(
"Generated{} {} wallet: {}".format(
" watch-only" if is_watch_only else "",
self.coin_name(),
self._log.addr(new_address),
)
)
else:
self._log.debug("generate_from_keys %s", dumpj(rv))
raise ValueError("generate_from_keys failed")
def openWallet(self, filename):
params = {"filename": filename}
@ -406,7 +418,9 @@ class XMRInterface(CoinInterface):
params["priority"] = self._fee_priority
rv = self.rpc_wallet("transfer", params)
self._log.info(
"publishBLockTx %s to address_b58 %s", rv["tx_hash"], shared_addr
"publishBLockTx %s to address_b58 %s",
self._log.id(rv["tx_hash"]),
self._log.addr(shared_addr),
)
tx_hash = bytes.fromhex(rv["tx_hash"])

View file

@ -44,7 +44,7 @@ def addLockRefundSigs(self, xmr_swap, ci):
def recoverNoScriptTxnWithKey(self, bid_id: bytes, encoded_key, cursor=None):
self.log.info(f"Manually recovering {bid_id.hex()}")
self.log.info(f"Manually recovering {self.log.id(bid_id)}")
# Manually recover txn if other key is known
try:
use_cursor = self.openDB(cursor)
@ -119,10 +119,7 @@ def recoverNoScriptTxnWithKey(self, bid_id: bytes, encoded_key, cursor=None):
lock_tx_vout=lock_tx_vout,
)
self.log.debug(
"Submitted lock B spend txn %s to %s chain for bid %s",
txid.hex(),
ci_follower.coin_name(),
bid_id.hex(),
f"Submitted lock B spend txn {self.log.id(txid)} to {ci_follower.coin_name()} chain for bid {self.log.id(bid_id)}."
)
self.logBidEvent(
bid.bid_id,

View file

@ -1,16 +1,16 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2022-2024 tecnovert
# Copyright (c) 2022-2025 tecnovert
# Distributed under the MIT software license, see the accompanying
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
from hashlib import sha256 as hashlib_sha256 # hashlib is faster than pycryptodome
from basicswap.contrib.blake256.blake256 import blake_hash
from Crypto.Hash import HMAC, RIPEMD160, SHA256, SHA512 # pycryptodome
from Crypto.Hash import HMAC, RIPEMD160, SHA512 # pycryptodome
def sha256(data: bytes) -> bytes:
h = SHA256.new()
h = hashlib_sha256()
h.update(data)
return h.digest()

42
basicswap/util/logging.py Normal file
View file

@ -0,0 +1,42 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2025 The Basicswap developers
# Distributed under the MIT software license, see the accompanying
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
import logging
from basicswap.util.crypto import (
sha256,
)
class BSXLogger(logging.Logger):
def __init__(self, name):
super().__init__(name)
self.safe_logs = False
self.safe_logs_prefix = b""
def addr(self, addr: str) -> str:
if self.safe_logs:
return (
"A_"
+ sha256(self.safe_logs_prefix + addr.encode(encoding="utf-8"))[
:8
].hex()
)
return addr
def id(self, concept_id: bytes, prefix: str = "") -> str:
if concept_id is None:
return prefix + "None"
if isinstance(concept_id, str):
concept_id = bytes.fromhex(concept_id)
if self.safe_logs:
return (prefix if len(prefix) > 0 else "_") + sha256(
self.safe_logs_prefix + concept_id
)[:8].hex()
return prefix + concept_id.hex()
def info_s(self, msg, *args, **kwargs):
if self.safe_logs is False:
self.info(msg, *args, **kwargs)

View file

@ -770,6 +770,14 @@ class TestFunctions(BaseTest):
class BasicSwapTest(TestFunctions):
@classmethod
def setUpClass(cls):
super(BasicSwapTest, cls).setUpClass()
if False:
for client in cls.swap_clients:
client.log.safe_logs = True
client.log.safe_logs_prefix = b"tests"
def test_001_nested_segwit(self):
# p2sh-p2wpkh
logging.info(
@ -2141,6 +2149,14 @@ class TestBTC_PARTB(TestFunctions):
start_ltc_nodes = False
base_rpc_port = BTC_BASE_RPC_PORT
@classmethod
def setUpClass(cls):
super(TestBTC_PARTB, cls).setUpClass()
if False:
for client in cls.swap_clients:
client.log.safe_logs = True
client.log.safe_logs_prefix = b"tests"
def test_01_a_full_swap(self):
self.prepare_balance(self.test_coin_to, 100.0, 1801, 1800)
self.do_test_01_full_swap(self.test_coin_from, self.test_coin_to)