From 4fa61e8e493588bc7ae29e9268bec7f7fccc18cc Mon Sep 17 00:00:00 2001 From: tecnovert Date: Mon, 4 Aug 2025 18:16:14 +0200 Subject: [PATCH] Allow lock-tx nLockTime to be > chain height + 2 --- basicswap/interface/bch.py | 10 +++++++++- basicswap/interface/btc.py | 14 ++++++++++++-- basicswap/interface/part.py | 11 ++++++++++- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/basicswap/interface/bch.py b/basicswap/interface/bch.py index 20802a0..695c5c0 100644 --- a/basicswap/interface/bch.py +++ b/basicswap/interface/bch.py @@ -818,7 +818,15 @@ class BCHInterface(BTCInterface): 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 + # locktime must be <= chainheight + 2 + # TODO: Locktime is set to 0 to keep compaitibility with older nodes. + # Set locktime to current chainheight in createSCLockTx. + if tx.nLockTime != 0: + current_height: int = self.getChainHeight() + if tx.nLockTime > current_height + 2: + raise ValueError( + f"{self.coin_name()} - Bad nLockTime {tx.nLockTime}, current height {current_height}" + ) script_pk = self.getScriptDest(script_out) locked_n = findOutput(tx, script_pk) diff --git a/basicswap/interface/btc.py b/basicswap/interface/btc.py index 50e6827..c13698e 100644 --- a/basicswap/interface/btc.py +++ b/basicswap/interface/btc.py @@ -769,6 +769,7 @@ class BTCInterface(Secp256k1Interface): ) -> bytes: tx = CTransaction() tx.nVersion = self.txVersion() + tx.nLockTime = 0 # TODO: match locktimes by core tx.vout.append(self.txoType()(value, self.getScriptDest(script))) return tx.serialize() @@ -1045,7 +1046,15 @@ class BTCInterface(Secp256k1Interface): 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 + # locktime must be <= chainheight + 2 + # TODO: Locktime is set to 0 to keep compaitibility with older nodes. + # Set locktime to current chainheight in createSCLockTx. + if tx.nLockTime != 0: + current_height: int = self.getChainHeight() + if tx.nLockTime > current_height + 2: + raise ValueError( + f"{self.coin_name()} - Bad nLockTime {tx.nLockTime}, current height {current_height}" + ) script_pk = self.getScriptDest(script_out) locked_n = findOutput(tx, script_pk) @@ -1383,7 +1392,8 @@ class BTCInterface(Secp256k1Interface): "feeRate": feerate_str, } rv = self.rpc_wallet("fundrawtransaction", [tx.hex(), options]) - return bytes.fromhex(rv["hex"]) + tx_bytes: bytes = bytes.fromhex(rv["hex"]) + return tx_bytes def getNonSegwitOutputs(self): unspents = self.rpc_wallet("listunspent", [0, 99999999]) diff --git a/basicswap/interface/part.py b/basicswap/interface/part.py index 9e33563..1475ad1 100644 --- a/basicswap/interface/part.py +++ b/basicswap/interface/part.py @@ -490,7 +490,16 @@ class PARTInterfaceBlind(PARTInterface): 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") + lock_time: int = lock_tx_obj["locktime"] + # locktime must be <= chainheight + 2 + # TODO: locktime is set to 0 to keep compaitibility with older nodes. + # Set locktime to current chainheight in createSCLockTx. + if lock_time != 0: + current_height: int = self.getChainHeight() + if lock_time > current_height + 2: + raise ValueError( + f"{self.coin_name()} - Bad nLockTime {lock_time}, current height {current_height}" + ) # Find the output of the lock tx to verify nonce = self.getScriptLockTxNonce(vkbv)