mirror of
https://github.com/basicswap/basicswap.git
synced 2025-11-06 02:38:11 +01:00
Fix recoverNoScriptTxnWithKey for reverse bids.
This commit is contained in:
@@ -7659,6 +7659,9 @@ class BasicSwap(BaseApp):
|
||||
return
|
||||
|
||||
bid = self.getBid(bid_id)
|
||||
if bid is None:
|
||||
raise ValueError('Bid not found.')
|
||||
|
||||
bid.debug_ind = debug_ind
|
||||
|
||||
# Update in memory copy. TODO: Improve
|
||||
|
||||
@@ -351,7 +351,7 @@ class XmrSwap(Base):
|
||||
|
||||
vkbv = sa.Column(sa.LargeBinary) # chain b view private key
|
||||
pkbv = sa.Column(sa.LargeBinary) # chain b view public key
|
||||
pkbs = sa.Column(sa.LargeBinary) # chain b view spend key
|
||||
pkbs = sa.Column(sa.LargeBinary) # chain b spend public key
|
||||
|
||||
a_lock_tx = sa.Column(sa.LargeBinary)
|
||||
a_lock_tx_script = sa.Column(sa.LargeBinary)
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
import json
|
||||
import logging
|
||||
|
||||
import basicswap.contrib.ed25519_fast as edf
|
||||
@@ -452,6 +451,8 @@ class XMRInterface(CoinInterface):
|
||||
if len(txns) > 0:
|
||||
txid = txns[0]['txid']
|
||||
self._log.warning(f'spendBLockTx detected spending tx: {txid}.')
|
||||
|
||||
# Should check for address_to, but only the from address is found in the output
|
||||
if txns[0]['address'] == address_b58:
|
||||
return bytes.fromhex(txid)
|
||||
|
||||
@@ -472,7 +473,6 @@ class XMRInterface(CoinInterface):
|
||||
params['priority'] = self._fee_priority
|
||||
|
||||
rv = self.rpc_wallet('sweep_all', params)
|
||||
self._log.debug('sweep_all {}'.format(json.dumps(rv)))
|
||||
|
||||
return bytes.fromhex(rv['tx_hash_list'][0])
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
import traceback
|
||||
|
||||
from basicswap.util import (
|
||||
ensure,
|
||||
)
|
||||
@@ -41,7 +43,7 @@ def addLockRefundSigs(self, xmr_swap, ci):
|
||||
|
||||
|
||||
def recoverNoScriptTxnWithKey(self, bid_id: bytes, encoded_key, session=None):
|
||||
self.log.info('Manually recovering %s', bid_id.hex())
|
||||
self.log.info(f'Manually recovering {bid_id.hex()}')
|
||||
# Manually recover txn if other key is known
|
||||
try:
|
||||
use_session = self.openSession(session)
|
||||
@@ -51,37 +53,57 @@ def recoverNoScriptTxnWithKey(self, bid_id: bytes, encoded_key, session=None):
|
||||
offer, xmr_offer = self.getXmrOfferFromSession(use_session, bid.offer_id, sent=False)
|
||||
ensure(offer, 'Offer not found: {}.'.format(bid.offer_id.hex()))
|
||||
ensure(xmr_offer, 'Adaptor-sig offer not found: {}.'.format(bid.offer_id.hex()))
|
||||
ci_to = self.ci(offer.coin_to)
|
||||
|
||||
for_ed25519 = True if Coins(offer.coin_to) == Coins.XMR else False
|
||||
# The no-script coin is always the follower
|
||||
reverse_bid: bool = self.is_reverse_ads_bid(offer.coin_from)
|
||||
ci_from = self.ci(Coins(offer.coin_from))
|
||||
ci_to = self.ci(Coins(offer.coin_to))
|
||||
ci_leader = ci_to if reverse_bid else ci_from
|
||||
ci_follower = ci_from if reverse_bid else ci_to
|
||||
|
||||
try:
|
||||
decoded_key_half = ci_to.decodeKey(encoded_key)
|
||||
decoded_key_half = ci_follower.decodeKey(encoded_key)
|
||||
except Exception as e:
|
||||
raise ValueError('Failed to decode provided key-half: ', str(e))
|
||||
|
||||
if bid.was_sent:
|
||||
kbsl = decoded_key_half
|
||||
kbsf = self.getPathKey(offer.coin_from, offer.coin_to, bid.created_at, xmr_swap.contract_count, KeyTypes.KBSF, for_ed25519)
|
||||
else:
|
||||
kbsl = self.getPathKey(offer.coin_from, offer.coin_to, bid.created_at, xmr_swap.contract_count, KeyTypes.KBSL, for_ed25519)
|
||||
kbsf = decoded_key_half
|
||||
ensure(ci_to.verifyKey(kbsl), 'Invalid kbsl')
|
||||
ensure(ci_to.verifyKey(kbsf), 'Invalid kbsf')
|
||||
vkbs = ci_to.sumKeys(kbsl, kbsf)
|
||||
was_sent: bool = bid.was_received if reverse_bid else bid.was_sent
|
||||
|
||||
if offer.coin_to == Coins.XMR:
|
||||
address_to = self.getCachedMainWalletAddress(ci_to, use_session)
|
||||
localkeyhalf = ci_follower.decodeKey(getChainBSplitKey(self, bid, xmr_swap, offer))
|
||||
if was_sent:
|
||||
kbsl = decoded_key_half
|
||||
kbsf = localkeyhalf
|
||||
else:
|
||||
address_to = self.getCachedStealthAddressForCoin(offer.coin_to, use_session)
|
||||
kbsl = localkeyhalf
|
||||
kbsf = decoded_key_half
|
||||
|
||||
ensure(ci_follower.verifyKey(kbsl), 'Invalid kbsl')
|
||||
ensure(ci_follower.verifyKey(kbsf), 'Invalid kbsf')
|
||||
vkbs = ci_follower.sumKeys(kbsl, kbsf)
|
||||
|
||||
# Ensure summed key matches the expected pubkey
|
||||
summed_pkbs = ci_follower.getPubkey(vkbs)
|
||||
if (summed_pkbs != xmr_swap.pkbs):
|
||||
err_msg: str = 'Summed key does not match expected wallet'
|
||||
have_pk = summed_pkbs.hex()
|
||||
expect_pk = xmr_swap.pkbs.hex()
|
||||
self.log.error(f'{err_msg}. Got: {have_pk}, Expect: {expect_pk}')
|
||||
raise ValueError(err_msg)
|
||||
|
||||
if ci_follower.coin_type() in (Coins.XMR, Coins.WOW):
|
||||
address_to = self.getCachedMainWalletAddress(ci_follower, use_session)
|
||||
else:
|
||||
address_to = self.getCachedStealthAddressForCoin(ci_follower.coin_type(), use_session)
|
||||
amount = bid.amount_to
|
||||
lock_tx_vout = bid.getLockTXBVout()
|
||||
txid = ci_to.spendBLockTx(xmr_swap.b_lock_tx_id, address_to, xmr_swap.vkbv, vkbs, amount, xmr_offer.b_fee_rate, bid.chain_b_height_start, spend_actual_balance=True, lock_tx_vout=lock_tx_vout)
|
||||
self.log.debug('Submitted lock B spend txn %s to %s chain for bid %s', txid.hex(), ci_to.coin_name(), bid_id.hex())
|
||||
txid = ci_follower.spendBLockTx(xmr_swap.b_lock_tx_id, address_to, xmr_swap.vkbv, vkbs, amount, xmr_offer.b_fee_rate, bid.chain_b_height_start, spend_actual_balance=True, 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())
|
||||
self.logBidEvent(bid.bid_id, EventLogTypes.LOCK_TX_B_SPEND_TX_PUBLISHED, txid.hex(), use_session)
|
||||
use_session.commit()
|
||||
|
||||
return txid
|
||||
except Exception as e:
|
||||
self.log.error(traceback.format_exc())
|
||||
raise (e)
|
||||
finally:
|
||||
if session is None:
|
||||
self.closeSession(use_session, commit=False)
|
||||
@@ -89,10 +111,14 @@ def recoverNoScriptTxnWithKey(self, bid_id: bytes, encoded_key, session=None):
|
||||
|
||||
def getChainBSplitKey(swap_client, bid, xmr_swap, offer):
|
||||
reverse_bid: bool = offer.bid_reversed
|
||||
ci_leader = swap_client.ci(offer.coin_to if reverse_bid else offer.coin_from)
|
||||
ci_follower = swap_client.ci(offer.coin_from if reverse_bid else offer.coin_to)
|
||||
|
||||
key_type = KeyTypes.KBSF if bid.was_sent else KeyTypes.KBSL
|
||||
return ci_follower.encodeKey(swap_client.getPathKey(offer.coin_from, offer.coin_to, bid.created_at, xmr_swap.contract_count, key_type, True if ci_follower.coin_type() == Coins.XMR else False))
|
||||
for_ed25519: bool = True if ci_follower.curve_type() == Curves.ed25519 else False
|
||||
was_sent: bool = bid.was_received if reverse_bid else bid.was_sent
|
||||
|
||||
key_type = KeyTypes.KBSF if was_sent else KeyTypes.KBSL
|
||||
return ci_follower.encodeKey(swap_client.getPathKey(ci_leader.coin_type(), ci_follower.coin_type(), bid.created_at, xmr_swap.contract_count, key_type, for_ed25519))
|
||||
|
||||
|
||||
def getChainBRemoteSplitKey(swap_client, bid, xmr_swap, offer):
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
<p class="font-normal text-coolGray-200 dark:text-white"><span class="bold">BID ID:</span> {{ bid_id }}</p>
|
||||
</div>
|
||||
<div class="w-full md:w-1/2 p-3 p-6 container flex flex-wrap items-center justify-end items-center mx-auto">
|
||||
{% if refresh %}
|
||||
{% if refresh %}
|
||||
<a id="refresh" href="/bid/{{ bid_id }}" class="rounded-full flex flex-wrap justify-center px-5 py-3 bg-blue-500 hover:bg-blue-600 font-medium text-sm text-white border dark:bg-gray-500 dark:hover:bg-gray-700 border-blue-500 rounded-md shadow-button focus:ring-0 focus:outline-none">
|
||||
{{ circular_arrows_svg | safe }}
|
||||
<span>Refresh {{ refresh }} seconds</span>
|
||||
@@ -378,13 +378,13 @@
|
||||
{% if data.xmr_b_half_privatekey %}
|
||||
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
||||
<td class="py-3 px-6 bold">Key Half (WARNING key data!):</td>
|
||||
<td class="py-3 px-6 monospace">{{ data.xmr_b_half_privatekey }}</td>
|
||||
<td class="py-3 px-6 monospace" id="localkeyhalf">{{ data.xmr_b_half_privatekey }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if data.xmr_b_half_privatekey_remote %}
|
||||
<tr class="opacity-100 text-gray-500 dark:text-gray-100 hover:bg-coolGray-200 dark:hover:bg-gray-600">
|
||||
<td class="py-3 px-6 bold">Remote Key Half:</td>
|
||||
<td class="py-3 px-6 monospace">{{ data.xmr_b_half_privatekey_remote }}</td>
|
||||
<td class="py-3 px-6 monospace" id="remotekeyhalf">{{ data.xmr_b_half_privatekey_remote }}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</table>
|
||||
@@ -845,4 +845,4 @@
|
||||
</div>
|
||||
{% include 'footer.html' %}
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user