mirror of
https://github.com/basicswap/basicswap.git
synced 2025-01-22 10:34:34 +00:00
ui: Recover noscript txn if remote key is known.
This commit is contained in:
parent
82e2b128c9
commit
e502a00341
7 changed files with 67 additions and 13 deletions
|
@ -4926,6 +4926,40 @@ class BasicSwap(BaseApp):
|
||||||
finally:
|
finally:
|
||||||
self.mxDB.release()
|
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):
|
def manualBidUpdate(self, bid_id, data):
|
||||||
self.log.info('Manually updating bid %s', bid_id.hex())
|
self.log.info('Manually updating bid %s', bid_id.hex())
|
||||||
self.mxDB.acquire()
|
self.mxDB.acquire()
|
||||||
|
@ -4948,6 +4982,9 @@ class BasicSwap(BaseApp):
|
||||||
bid.debug_ind = data['debug_ind']
|
bid.debug_ind = data['debug_ind']
|
||||||
has_changed = True
|
has_changed = True
|
||||||
|
|
||||||
|
if data['kbs_other'] is not None:
|
||||||
|
return self.recoverNoScriptTxnWithKey(bid_id, data['kbs_other'])
|
||||||
|
|
||||||
if has_changed:
|
if has_changed:
|
||||||
session = scoped_session(self.session_factory)
|
session = scoped_session(self.session_factory)
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -1007,7 +1007,8 @@ class HttpHandler(BaseHTTPRequestHandler):
|
||||||
elif b'edit_bid_submit' in form_data:
|
elif b'edit_bid_submit' in form_data:
|
||||||
data = {
|
data = {
|
||||||
'bid_state': int(form_data[b'new_state'][0]),
|
'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:
|
try:
|
||||||
swap_client.manualBidUpdate(bid_id, data)
|
swap_client.manualBidUpdate(bid_id, data)
|
||||||
|
|
|
@ -18,6 +18,7 @@ from .util import (
|
||||||
ensure,
|
ensure,
|
||||||
make_int,
|
make_int,
|
||||||
b58encode,
|
b58encode,
|
||||||
|
decodeWif,
|
||||||
decodeAddress,
|
decodeAddress,
|
||||||
decodeScriptNum,
|
decodeScriptNum,
|
||||||
pubkeyToAddress,
|
pubkeyToAddress,
|
||||||
|
@ -201,8 +202,7 @@ class BTCInterface(CoinInterface):
|
||||||
return self.rpc_callback('getblockheader', [block_hash])
|
return self.rpc_callback('getblockheader', [block_hash])
|
||||||
|
|
||||||
def initialiseWallet(self, key_bytes):
|
def initialiseWallet(self, key_bytes):
|
||||||
wif_prefix = self.chainparams_network()['key_prefix']
|
key_wif = self.encodeKey(key_bytes)
|
||||||
key_wif = toWIF(wif_prefix, key_bytes)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.rpc_callback('sethdseed', [True, key_wif])
|
self.rpc_callback('sethdseed', [True, key_wif])
|
||||||
|
@ -306,6 +306,10 @@ class BTCInterface(CoinInterface):
|
||||||
def verifyPubkey(self, pubkey_bytes):
|
def verifyPubkey(self, pubkey_bytes):
|
||||||
return verify_secp256k1_point(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):
|
def encodePubkey(self, pk):
|
||||||
return pointToCPK(pk)
|
return pointToCPK(pk)
|
||||||
|
|
||||||
|
@ -313,9 +317,7 @@ class BTCInterface(CoinInterface):
|
||||||
return CPKToPoint(pke)
|
return CPKToPoint(pke)
|
||||||
|
|
||||||
def decodeKey(self, k):
|
def decodeKey(self, k):
|
||||||
i = b2i(k)
|
return decodeWif(k)
|
||||||
assert(i < ep.o)
|
|
||||||
return i
|
|
||||||
|
|
||||||
def sumKeys(self, ka, kb):
|
def sumKeys(self, ka, kb):
|
||||||
# TODO: Add to coincurve
|
# TODO: Add to coincurve
|
||||||
|
|
|
@ -170,6 +170,9 @@ class XMRInterface(CoinInterface):
|
||||||
def pubkey(self, key):
|
def pubkey(self, key):
|
||||||
return edf.scalarmult_B(key)
|
return edf.scalarmult_B(key)
|
||||||
|
|
||||||
|
def encodeKey(self, vk):
|
||||||
|
return vk.hex()
|
||||||
|
|
||||||
def encodePubkey(self, pk):
|
def encodePubkey(self, pk):
|
||||||
return edu.encodepoint(pk)
|
return edu.encodepoint(pk)
|
||||||
|
|
||||||
|
@ -203,10 +206,8 @@ class XMRInterface(CoinInterface):
|
||||||
def lengthDLEAG(self):
|
def lengthDLEAG(self):
|
||||||
return dleag_proof_len()
|
return dleag_proof_len()
|
||||||
|
|
||||||
def decodeKey(self, k):
|
def decodeKey(self, k_hex):
|
||||||
i = b2i(k)
|
return bytes.fromhex(k_hex)
|
||||||
assert(i < edf.l and i > 8)
|
|
||||||
return i
|
|
||||||
|
|
||||||
def sumKeys(self, ka, kb):
|
def sumKeys(self, ka, kb):
|
||||||
return ed25519_scalar_add(ka, kb)
|
return ed25519_scalar_add(ka, kb)
|
||||||
|
|
|
@ -50,6 +50,7 @@
|
||||||
<option{% if data.debug_ind==a[0] %} selected{% endif %} value="{{ a[0] }}">{{ a[1] }}</option>
|
<option{% if data.debug_ind==a[0] %} selected{% endif %} value="{{ a[0] }}">{{ a[1] }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select></td></tr>
|
</select></td></tr>
|
||||||
|
<tr><td>Sweep No-Script TX</td><td><input type="text" id="kbs_other" name="kbs_other"></td></tr>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</table>
|
</table>
|
||||||
<input name="edit_bid_cancel" type="submit" value="Cancel">
|
<input name="edit_bid_cancel" type="submit" value="Cancel">
|
||||||
|
@ -74,6 +75,9 @@
|
||||||
{% if data.xmr_b_shared_address %}
|
{% if data.xmr_b_shared_address %}
|
||||||
<p class="monospace">Shared Address: {{ data.xmr_b_shared_address }}</p>
|
<p class="monospace">Shared Address: {{ data.xmr_b_shared_address }}</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if data.xmr_b_half_privatekey %}
|
||||||
|
<p class="monospace">Key Half: {{ data.xmr_b_half_privatekey }}</p>
|
||||||
|
{% endif %}
|
||||||
<h4>Transactions</h4>
|
<h4>Transactions</h4>
|
||||||
<table>
|
<table>
|
||||||
<tr><th>Tx Type</th><th>Tx ID</th><th>Blocks Deep</th></tr>
|
<tr><th>Tx Type</th><th>Tx ID</th><th>Blocks Deep</th></tr>
|
||||||
|
|
|
@ -166,7 +166,7 @@ def describeBid(swap_client, bid, xmr_swap, offer, xmr_offer, bid_events, edit_b
|
||||||
state_description = bid.state_note
|
state_description = bid.state_note
|
||||||
elif offer.swap_type == SwapTypes.XMR_SWAP:
|
elif offer.swap_type == SwapTypes.XMR_SWAP:
|
||||||
if bid.state == BidStates.BID_SENT:
|
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:
|
if bid.state == BidStates.BID_RECEIVING:
|
||||||
# Offerer receiving bid from bidder
|
# Offerer receiving bid from bidder
|
||||||
state_description = 'Waiting for bid to be fully received'
|
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'
|
state_description = f'Waiting for offerer to spend from {ticker_to} lock tx'
|
||||||
elif bid.state == BidStates.XMR_SWAP_NOSCRIPT_TX_REDEEMED:
|
elif bid.state == BidStates.XMR_SWAP_NOSCRIPT_TX_REDEEMED:
|
||||||
state_description = f'Waiting for {ticker_to} lock tx spend tx to confirm in chain'
|
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]
|
addr_label = swap_client.getAddressLabel([bid.bid_addr, ])[0]
|
||||||
bid_rate = offer.rate if bid.rate is None else bid.rate
|
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
|
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 show_lock_transfers:
|
||||||
if xmr_swap.pkbs:
|
if xmr_swap.pkbs:
|
||||||
data['lock_transfers'] = json.dumps(ci_to.showLockTransfers(xmr_swap.pkbv, xmr_swap.pkbs), indent=4)
|
data['lock_transfers'] = json.dumps(ci_to.showLockTransfers(xmr_swap.pkbv, xmr_swap.pkbs), indent=4)
|
||||||
|
|
|
@ -100,8 +100,8 @@ def b58encode(v):
|
||||||
return (__b58chars[0] * nPad) + result
|
return (__b58chars[0] * nPad) + result
|
||||||
|
|
||||||
|
|
||||||
def decodeWif(network_key):
|
def decodeWif(encoded_key):
|
||||||
key = b58decode(network_key)[1:-4]
|
key = b58decode(encoded_key)[1:-4]
|
||||||
if len(key) == 33:
|
if len(key) == 33:
|
||||||
return key[:-1]
|
return key[:-1]
|
||||||
return key
|
return key
|
||||||
|
|
Loading…
Reference in a new issue