Browse Source

ui: Recover noscript txn if remote key is known.

pivx
tecnovert 3 years ago
parent
commit
e502a00341
No known key found for this signature in database GPG Key ID: 8ED6D8750C4E3F93
  1. 37
      basicswap/basicswap.py
  2. 3
      basicswap/http_server.py
  3. 12
      basicswap/interface_btc.py
  4. 9
      basicswap/interface_xmr.py
  5. 4
      basicswap/templates/bid_xmr.html
  6. 11
      basicswap/ui.py
  7. 4
      basicswap/util.py

37
basicswap/basicswap.py

@ -4926,6 +4926,40 @@ class BasicSwap(BaseApp):
finally:
self.mxDB.release()
def recoverNoScriptTxnWithKey(self, bid_id, encoded_key):
# Manually recover txn if other key is known
session = scoped_session(self.session_factory)
try:
bid, xmr_swap = self.getXmrBidFromSession(session, bid_id)
ensure(bid, 'Bid not found: {}.'.format(bid_id.hex()))
ensure(xmr_swap, 'XMR swap not found: {}.'.format(bid_id.hex()))
offer, xmr_offer = self.getXmrOfferFromSession(session, bid.offer_id, sent=False)
ensure(offer, 'Offer not found: {}.'.format(bid.offer_id.hex()))
ensure(xmr_offer, 'XMR 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
if bid.was_sent:
kbsl = ci_to.decodeKey(encoded_key)
kbsf = self.getPathKey(offer.coin_from, offer.coin_to, bid.created_at, xmr_swap.contract_count, 2, for_ed25519)
else:
kbsl = self.getPathKey(offer.coin_from, offer.coin_to, bid.created_at, xmr_swap.contract_count, 2, for_ed25519)
kbsf = ci_to.decodeKey(encoded_key)
ensure(ci_to.verifyKey(kbsl), 'Invalid kbsl')
ensure(ci_to.verifyKey(kbsf), 'Invalid kbsf')
vkbs = ci_to.sumKeys(kbsl, kbsf)
address_to = self.getCachedMainWalletAddress(ci_to)
txid = ci_to.spendBLockTx(xmr_swap.b_lock_tx_id, address_to, xmr_swap.vkbv, vkbs, bid.amount_to, xmr_offer.b_fee_rate, bid.chain_b_height_start)
self.log.debug('Submitted lock B spend txn %s to %s chain for bid %s', txid.hex(), ci_to.coin_name(), bid_id.hex())
self.logBidEvent(bid.bid_id, EventLogTypes.LOCK_TX_B_SPEND_TX_PUBLISHED, txid.hex(), session)
session.commit()
return txid.hex()
finally:
session.close()
session.remove()
def manualBidUpdate(self, bid_id, data):
self.log.info('Manually updating bid %s', bid_id.hex())
self.mxDB.acquire()
@ -4948,6 +4982,9 @@ class BasicSwap(BaseApp):
bid.debug_ind = data['debug_ind']
has_changed = True
if data['kbs_other'] is not None:
return self.recoverNoScriptTxnWithKey(bid_id, data['kbs_other'])
if has_changed:
session = scoped_session(self.session_factory)
try:

3
basicswap/http_server.py

@ -1007,7 +1007,8 @@ class HttpHandler(BaseHTTPRequestHandler):
elif b'edit_bid_submit' in form_data:
data = {
'bid_state': int(form_data[b'new_state'][0]),
'debug_ind': int(get_data_entry_or(form_data, 'debugind', -1))
'debug_ind': int(get_data_entry_or(form_data, 'debugind', -1)),
'kbs_other': get_data_entry_or(form_data, 'kbs_other', None),
}
try:
swap_client.manualBidUpdate(bid_id, data)

12
basicswap/interface_btc.py

@ -18,6 +18,7 @@ from .util import (
ensure,
make_int,
b58encode,
decodeWif,
decodeAddress,
decodeScriptNum,
pubkeyToAddress,
@ -201,8 +202,7 @@ class BTCInterface(CoinInterface):
return self.rpc_callback('getblockheader', [block_hash])
def initialiseWallet(self, key_bytes):
wif_prefix = self.chainparams_network()['key_prefix']
key_wif = toWIF(wif_prefix, key_bytes)
key_wif = self.encodeKey(key_bytes)
try:
self.rpc_callback('sethdseed', [True, key_wif])
@ -306,6 +306,10 @@ class BTCInterface(CoinInterface):
def verifyPubkey(self, pubkey_bytes):
return verify_secp256k1_point(pubkey_bytes)
def encodeKey(self, key_bytes):
wif_prefix = self.chainparams_network()['key_prefix']
return toWIF(wif_prefix, key_bytes)
def encodePubkey(self, pk):
return pointToCPK(pk)
@ -313,9 +317,7 @@ class BTCInterface(CoinInterface):
return CPKToPoint(pke)
def decodeKey(self, k):
i = b2i(k)
assert(i < ep.o)
return i
return decodeWif(k)
def sumKeys(self, ka, kb):
# TODO: Add to coincurve

9
basicswap/interface_xmr.py

@ -170,6 +170,9 @@ class XMRInterface(CoinInterface):
def pubkey(self, key):
return edf.scalarmult_B(key)
def encodeKey(self, vk):
return vk.hex()
def encodePubkey(self, pk):
return edu.encodepoint(pk)
@ -203,10 +206,8 @@ class XMRInterface(CoinInterface):
def lengthDLEAG(self):
return dleag_proof_len()
def decodeKey(self, k):
i = b2i(k)
assert(i < edf.l and i > 8)
return i
def decodeKey(self, k_hex):
return bytes.fromhex(k_hex)
def sumKeys(self, ka, kb):
return ed25519_scalar_add(ka, kb)

4
basicswap/templates/bid_xmr.html

@ -50,6 +50,7 @@
<option{% if data.debug_ind==a[0] %} selected{% endif %} value="{{ a[0] }}">{{ a[1] }}</option>
{% endfor %}
</select></td></tr>
<tr><td>Sweep No-Script TX</td><td><input type="text" id="kbs_other" name="kbs_other"></td></tr>
{% endif %}
</table>
<input name="edit_bid_cancel" type="submit" value="Cancel">
@ -74,6 +75,9 @@
{% if data.xmr_b_shared_address %}
<p class="monospace">Shared Address: {{ data.xmr_b_shared_address }}</p>
{% endif %}
{% if data.xmr_b_half_privatekey %}
<p class="monospace">Key Half: {{ data.xmr_b_half_privatekey }}</p>
{% endif %}
<h4>Transactions</h4>
<table>
<tr><th>Tx Type</th><th>Tx ID</th><th>Blocks Deep</th></tr>

11
basicswap/ui.py

@ -166,7 +166,7 @@ def describeBid(swap_client, bid, xmr_swap, offer, xmr_offer, bid_events, edit_b
state_description = bid.state_note
elif offer.swap_type == SwapTypes.XMR_SWAP:
if bid.state == BidStates.BID_SENT:
tate_description = 'Waiting for offerer to accept'
state_description = 'Waiting for offerer to accept'
if bid.state == BidStates.BID_RECEIVING:
# Offerer receiving bid from bidder
state_description = 'Waiting for bid to be fully received'
@ -205,6 +205,12 @@ def describeBid(swap_client, bid, xmr_swap, offer, xmr_offer, bid_events, edit_b
state_description = f'Waiting for offerer to spend from {ticker_to} lock tx'
elif bid.state == BidStates.XMR_SWAP_NOSCRIPT_TX_REDEEMED:
state_description = f'Waiting for {ticker_to} lock tx spend tx to confirm in chain'
elif bid.state == BidStates.XMR_SWAP_SCRIPT_TX_PREREFUND:
if bid.was_sent:
state_description = f'Waiting for offerer to redeem or locktime to expire'
else:
state_description = f'Redeeming output'
addr_label = swap_client.getAddressLabel([bid.bid_addr, ])[0]
bid_rate = offer.rate if bid.rate is None else bid.rate
@ -276,6 +282,9 @@ def describeBid(swap_client, bid, xmr_swap, offer, xmr_offer, bid_events, edit_b
data['xmr_b_shared_address'] = ci_to.encodeSharedAddress(xmr_swap.pkbv, xmr_swap.pkbs) if xmr_swap.pkbs else None
if swap_client.debug_ui:
data['xmr_b_half_privatekey'] = ci_to.encodeKey(swap_client.getPathKey(offer.coin_from, offer.coin_to, bid.created_at, xmr_swap.contract_count, 2, True if offer.coin_to == Coins.XMR else False))
if show_lock_transfers:
if xmr_swap.pkbs:
data['lock_transfers'] = json.dumps(ci_to.showLockTransfers(xmr_swap.pkbv, xmr_swap.pkbs), indent=4)

4
basicswap/util.py

@ -100,8 +100,8 @@ def b58encode(v):
return (__b58chars[0] * nPad) + result
def decodeWif(network_key):
key = b58decode(network_key)[1:-4]
def decodeWif(encoded_key):
key = b58decode(encoded_key)[1:-4]
if len(key) == 33:
return key[:-1]
return key

Loading…
Cancel
Save