This commit is contained in:
mainnet-pat
2024-10-30 06:07:29 +00:00
committed by tecnovert
parent a7c2fbba1f
commit 465f910812
7 changed files with 25 additions and 82 deletions

View File

@@ -47,7 +47,6 @@ from .util import (
DeserialiseNum,
h2b,
i2b,
i2h,
zeroIfNone,
make_int,
ensure,
@@ -3009,7 +3008,6 @@ class BasicSwap(BaseApp):
lockExtraArgs['public_key'] = xmr_swap.pkal
lockExtraArgs['timelock'] = xmr_offer.lock_time_1
xmr_swap.a_lock_tx_script = pi.genScriptLockTxScript(ci_from, xmr_swap.pkal, xmr_swap.pkaf, **lockExtraArgs)
prefunded_tx = self.getPreFundedTx(Concepts.OFFER, bid.offer_id, TxTypes.ITX_PRE_FUNDED, session=use_session)
if prefunded_tx:
@@ -3950,7 +3948,7 @@ class BasicSwap(BaseApp):
return rv
if 'txid' in lock_tx_chain_info and lock_tx_chain_info['txid'] != b2h(xmr_swap.a_lock_tx_id):
# if we find that txid was changed (by funding or otherwise), we need to update it to track correctly
# if we find that txid was changed (by funding or otherwise), we need to update it to track correctly
xmr_swap.a_lock_tx_id = h2b(lock_tx_chain_info['txid'])
xmr_swap.a_lock_tx = h2b(lock_tx_chain_info['txhex'])
@@ -3972,7 +3970,7 @@ class BasicSwap(BaseApp):
# update watcher
self.watchXmrSwap(bid, offer, xmr_swap, session)
bid_changed = True
if bid.xmr_a_lock_tx.state == TxStates.TX_NONE and lock_tx_chain_info['height'] == 0:
bid.xmr_a_lock_tx.setState(TxStates.TX_IN_MEMPOOL)
@@ -4416,7 +4414,7 @@ class BasicSwap(BaseApp):
ci_from = self.ci(coin_from)
spend_tx = ci_from.loadTx(h2b(spend_txn_hex))
bid.xmr_a_lock_tx.spend_txid = spending_txid
is_spending_lock_tx = False

View File

@@ -57,6 +57,7 @@ from coincurve.ecdsaotves import (
ecdsaotves_rec_enc_key,
)
class BCHInterface(BTCInterface):
@staticmethod
def coin_type():
@@ -130,27 +131,19 @@ class BCHInterface(BTCInterface):
# Return P2PKH
return CScript([OP_DUP, OP_HASH160, pkh, OP_EQUALVERIFY, OP_CHECKSIG])
# def getScriptDest(self, script: bytearray) -> bytearray:
# # P2SH
# script_hash = hash160(script)
# assert len(script_hash) == 20
# return CScript([OP_HASH160, script_hash, OP_EQUAL])
def encodeScriptDest(self, script_dest: bytes) -> str:
# Extract hash from script
script_hash = script_dest[2:-1]
return self.sh_to_address(script_hash)
def sh_to_address(self, sh: bytes) -> str:
assert (len(sh) == 20 or len(sh) == 32)
network = self._network.upper()
address = None
if len(sh) == 20:
address = Address("P2SH20" if network == "MAINNET" else "P2SH20-"+network, sh)
address = Address("P2SH20" if network == "MAINNET" else "P2SH20-" + network, sh)
else:
address = Address("P2SH32" if network == "MAINNET" else "P2SH32-"+network, sh)
address = Address("P2SH32" if network == "MAINNET" else "P2SH32-" + network, sh)
return address.cash_address()
@@ -165,9 +158,6 @@ class BCHInterface(BTCInterface):
params = [addr_to, value, '', '', subfee, 0, False]
return self.rpc_wallet('sendtoaddress', params)
def getSpendableBalance(self) -> int:
return self.make_int(self.rpc('getwalletinfo')['unconfirmed_balance'])
def getBLockSpendTxFee(self, tx, fee_rate: int) -> int:
add_bytes = 107
size = len(tx.serialize_with_witness()) + add_bytes
@@ -188,7 +178,7 @@ class BCHInterface(BTCInterface):
return None
def getLockTxHeight(self, txid, dest_address, bid_amount, rescan_from, find_index: bool = False, vout: int = -1):
# Add watchonly address and rescan if required
# Add watchonly address and rescan if required
txid = None
# first lookup by dest_address
@@ -252,10 +242,10 @@ class BCHInterface(BTCInterface):
return CScript([
# // v4.1.0-CashTokens-Optimized
# // Based on swaplock.cash v4.1.0-CashTokens
#
#
# // Alice has XMR, wants BCH and/or CashTokens.
# // Bob has BCH and/or CashTokens, wants XMR.
#
#
# // Verify 1-in-1-out TX form
OP_TXINPUTCOUNT,
OP_1, OP_NUMEQUALVERIFY,
@@ -305,7 +295,7 @@ class BCHInterface(BTCInterface):
# // Refund will become available when timelock expires, and it would
# // expire because Alice didn't collect on time, either of her own accord
# // or because Bob bailed out and witheld the encrypted signature.
# // or because Bob bailed out and withheld the encrypted signature.
OP_ELSE,
# // int timelock_0
timelock,
@@ -340,7 +330,7 @@ class BCHInterface(BTCInterface):
def addressToLockingBytecode(self, address: str) -> bytes:
return b'\x76\xa9\x14' + bytes(Address.from_string(address).payload) + b'\x88\xac'
def getSpendableBalance(self) -> int:
return self.make_int(self.rpc_wallet('getbalance', ["*", 1, False]))
@@ -353,22 +343,13 @@ class BCHInterface(BTCInterface):
sha256(sha256(script)),
OP_EQUAL,
])
def createSCLockTx(self, value: int, script: bytearray, vkbv: bytes = None) -> bytes:
tx = CTransaction()
tx.nVersion = self.txVersion()
tx.vout.append(self.txoType()(value, self.getScriptDest(script)))
return tx.serialize_without_witness()
def getScriptForPubkeyHash(self, pkh: bytes) -> CScript:
return CScript([
OP_DUP,
OP_HASH160,
pkh,
OP_EQUALVERIFY,
OP_CHECKSIG,
])
def getTxSize(self, tx: CTransaction) -> int:
return len(tx.serialize_without_witness())
@@ -496,7 +477,7 @@ class BCHInterface(BTCInterface):
def verifyTxSig(self, tx_bytes: bytes, sig: bytes, K: bytes, input_n: int, prevout_script: bytes, prevout_value: int) -> bool:
# simple ecdsa signature verification
return self.verifyDataSig(tx_bytes, sig, K)
def verifyDataSig(self, data: bytes, sig: bytes, K: bytes) -> bool:
# simple ecdsa signature verification
pubkey = PublicKey(K)
@@ -505,37 +486,6 @@ class BCHInterface(BTCInterface):
def setTxSignature(self, tx_bytes: bytes, stack) -> bytes:
return tx_bytes
def verifySCLockTx(self, tx_bytes, script_out,
swap_value,
Kal, Kaf,
feerate,
check_lock_tx_inputs, vkbv=None):
# Verify:
#
# Not necessary to check the lock txn is mineable, as protocol will wait for it to confirm
# However by checking early we can avoid wasting time processing unmineable txns
# Check fee is reasonable
tx = self.loadTx(tx_bytes)
txid = self.getTxid(tx)
self._log.info('Verifying lock tx: {}.'.format(b2h(txid)))
ensure(tx.nVersion == self.txVersion(), 'Bad version')
ensure(tx.nLockTime == 0, 'Bad nLockTime') # TODO match txns created by cores
script_pk = self.getScriptDest(script_out)
locked_n = findOutput(tx, script_pk)
ensure(locked_n is not None, 'Output not found in tx')
locked_coin = tx.vout[locked_n].nValue
# Check value
ensure(locked_coin == swap_value, 'Bad locked value')
# TODO: better script matching, see interfaces/btc.py
return txid, locked_n
def extractScriptLockScriptValuesFromScriptSig(self, script_bytes):
signature, nb = decodePushData(script_bytes, 0)
if nb == len(script_bytes):
@@ -598,7 +548,7 @@ class BCHInterface(BTCInterface):
ensure_op(script_bytes[o] == OP_EQUALVERIFY); o += 1
public_key, nb = decodePushData(script_bytes, o); o += nb
ensure_op(script_bytes[o] == OP_CHECKDATASIG); o += 1
ensure_op(script_bytes[o] == OP_ELSE); o += 1
timelock, nb = decodeScriptNum(script_bytes, o); o += nb
ensure_op(script_bytes[o] == OP_CHECKSEQUENCEVERIFY); o += 1
@@ -708,7 +658,6 @@ class BCHInterface(BTCInterface):
ensure(public_key == _public_key, 'public_key mismatch')
ensure(timelock == _timelock, 'timelock mismatch')
fee_paid = locked_coin - mining_fee
assert (fee_paid > 0)
@@ -814,7 +763,7 @@ class BCHInterface(BTCInterface):
msg = sha256(out_1)
return ecdsaotves_enc_sign(key_sign, pubkey_encrypt, msg)
def decryptOtVES(self, k: bytes, esig: bytes) -> bytes:
return ecdsaotves_dec_sig(k, esig)

View File

@@ -32,6 +32,7 @@ def decodeScriptNum(script_bytes, o):
v += int(b) << 8 * i
return (v, 1 + num_len)
def decodePushData(script_bytes, o):
datasize = None
pushdata_type = None
@@ -76,6 +77,7 @@ def decodePushData(script_bytes, o):
# return data and the number of bytes to skip forward
return (data, i + datasize - o)
def getP2SHScriptForHash(p2sh):
return bytes((OpCodes.OP_HASH160, 0x14)) \
+ p2sh \