diff --git a/basicswap/basicswap.py b/basicswap/basicswap.py index 6b7abe1..7ac3caf 100644 --- a/basicswap/basicswap.py +++ b/basicswap/basicswap.py @@ -4440,7 +4440,7 @@ class BasicSwap(BaseApp): bids_received += r[2] now = int(time.time()) - q = self.engine.execute('SELECT COUNT(*) FROM offers WHERE expire_at > {}'.format(now)).first() + q = self.engine.execute('SELECT COUNT(*) FROM offers WHERE active_ind = 1 AND expire_at > {}'.format(now)).first() num_offers = q[0] q = self.engine.execute('SELECT COUNT(*) FROM offers WHERE was_sent = 1').first() diff --git a/basicswap/http_server.py b/basicswap/http_server.py index 55130ec..fd9af4e 100644 --- a/basicswap/http_server.py +++ b/basicswap/http_server.py @@ -367,7 +367,13 @@ class HttpHandler(BaseHTTPRequestHandler): show_bid_form = None form_data = self.checkForm(post_string, 'offer', messages) if form_data: - if b'newbid' in form_data: + if b'revoke_offer' in form_data: + try: + swap_client.revokeOffer(offer_id) + messages.append('Offer revoked') + except Exception as ex: + messages.append('Revoke offer failed ' + str(ex)) + elif b'newbid' in form_data: show_bid_form = True else: addr_from = form_data[b'addr_from'][0].decode('utf-8') @@ -394,6 +400,7 @@ class HttpHandler(BaseHTTPRequestHandler): 'created_at': offer.created_at, 'expired_at': offer.expire_at, 'sent': 'True' if offer.was_sent else 'False', + 'was_revoked': 'True' if offer.active_ind == 2 else 'False', 'show_bid_form': show_bid_form, } diff --git a/basicswap/interface_btc.py b/basicswap/interface_btc.py index 4305965..5bbfeda 100644 --- a/basicswap/interface_btc.py +++ b/basicswap/interface_btc.py @@ -64,8 +64,6 @@ from .contrib.test_framework.script import ( SegwitV0SignatureHash, hash160) -from .contrib.test_framework.key import ECKey, ECPubKey - from .chainparams import CoinInterface, Coins, chainparams from .rpc import make_rpc_func from .util import assert_cond @@ -642,14 +640,11 @@ class BTCInterface(CoinInterface): return True def signTx(self, key_bytes, tx_bytes, prevout_n, prevout_script, prevout_value): - # TODO: use libsecp356k1 tx = self.loadTx(tx_bytes) sig_hash = SegwitV0SignatureHash(prevout_script, tx, prevout_n, SIGHASH_ALL, prevout_value) - eck = ECKey() - eck.set(key_bytes, compressed=True) - - return eck.sign_ecdsa(sig_hash) + b'\x01' # 0x1 is SIGHASH_ALL + eck = PrivateKey(key_bytes) + return eck.sign(sig_hash, hasher=None) + bytes((SIGHASH_ALL,)) def signTxOtVES(self, key_sign, pubkey_encrypt, tx_bytes, prevout_n, prevout_script, prevout_value): tx = self.loadTx(tx_bytes) @@ -663,20 +658,18 @@ class BTCInterface(CoinInterface): return ecdsaotves_enc_verify(Ks, Ke, sig_hash, ct) def decryptOtVES(self, k, esig): - return ecdsaotves_dec_sig(k, esig) + b'\x01' # 0x1 is SIGHASH_ALL + return ecdsaotves_dec_sig(k, esig) + bytes((SIGHASH_ALL,)) def verifyTxSig(self, tx_bytes, sig, K, prevout_n, prevout_script, prevout_value): tx = self.loadTx(tx_bytes) sig_hash = SegwitV0SignatureHash(prevout_script, tx, prevout_n, SIGHASH_ALL, prevout_value) - ecK = ECPubKey() - ecK.set(K) - return ecK.verify_ecdsa(sig[: -1], sig_hash) # Pop the hashtype byte + pubkey = PublicKey(K) + return pubkey.verify(sig[: -1], sig_hash, hasher=None) # Pop the hashtype byte def verifySig(self, pubkey, signed_hash, sig): - ecK = ECPubKey() - ecK.set(pubkey) - return ecK.verify_ecdsa(sig, signed_hash) + pubkey = PublicKey(pubkey) + return pubkey.verify(sig, signed_hash, hasher=None) def fundTx(self, tx, feerate): feerate_str = format_amount(feerate, self.exp()) diff --git a/basicswap/network.py b/basicswap/network.py index e26c8b8..b2706cc 100644 --- a/basicswap/network.py +++ b/basicswap/network.py @@ -9,13 +9,34 @@ TODO: ''' +import select +import socket +import logging + class Peer: pass class Network: - def __init__(self, p2p_port, network_key): + def __init__(self, p2p_host, p2p_port, network_key): + self._p2p_host = p2p_host self._p2p_port = p2p_port self._network_key = network_key self._peers = [] + + self._max_connections = 10 + self._running = True + + def listen(self): + self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self._socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + self._socket.bind((self._p2p_host, self._p2p_port)) + self._socket.listen(self._max_connections) + + while self._running: + readable, writable, errored = select.select([self._socket], [], []) + for s in readable: + client_socket, address = self._socket.accept() + read_list.append(client_socket) + logging.info('Connection from %s', address) diff --git a/basicswap/templates/bid.html b/basicswap/templates/bid.html index ab6ac61..7d1a775 100644 --- a/basicswap/templates/bid.html +++ b/basicswap/templates/bid.html @@ -53,7 +53,7 @@ {% if data.was_received == 'True' %}
{% endif %} - + {% if data.show_txns %} {% else %} @@ -74,4 +74,10 @@

home

+ + diff --git a/basicswap/templates/offer.html b/basicswap/templates/offer.html index 4ad1638..e88edd1 100644 --- a/basicswap/templates/offer.html +++ b/basicswap/templates/offer.html @@ -26,6 +26,7 @@ Created At{{ data.created_at | formatts }} Expired At{{ data.expired_at | formatts }} Sent{{ data.sent }} +Revoked{{ data.was_revoked }} {% if data.sent == 'True' %} Auto Accept Bids{{ data.auto_accept }} {% endif %} @@ -56,6 +57,9 @@ {% else %} {% endif %} +{% if data.sent == 'True' %} + +{% endif %} @@ -69,4 +73,10 @@

home

+ + diff --git a/tests/basicswap/test_other.py b/tests/basicswap/test_other.py index 8cf3f50..724a3c3 100644 --- a/tests/basicswap/test_other.py +++ b/tests/basicswap/test_other.py @@ -6,37 +6,36 @@ # file LICENSE or http://www.opensource.org/licenses/mit-license.php. import secrets +import hashlib import unittest import basicswap.contrib.ed25519_fast as edf import basicswap.ed25519_fast_util as edu -from basicswap.ecc_util import i2b from coincurve.ed25519 import ed25519_get_pubkey - from coincurve.ecdsaotves import ( ecdsaotves_enc_sign, ecdsaotves_enc_verify, ecdsaotves_dec_sig, ecdsaotves_rec_enc_key) +from coincurve.keys import ( + PrivateKey) +from basicswap.ecc_util import i2b from basicswap.interface_btc import BTCInterface from basicswap.interface_xmr import XMRInterface - from basicswap.util import ( SerialiseNum, DeserialiseNum, make_int, format_amount, - validate_amount, -) + validate_amount) from basicswap.basicswap import ( Coins, getExpectedSequence, decodeSequence, SEQUENCE_LOCK_BLOCKS, - SEQUENCE_LOCK_TIME, -) + SEQUENCE_LOCK_TIME) class Test(unittest.TestCase): @@ -182,6 +181,20 @@ class Test(unittest.TestCase): assert(vk_encrypt == recovered_key) + def test_sign(self): + coin_settings = {'rpcport': 0, 'rpcauth': 'none', 'blocks_confirmed': 1, 'conf_target': 1} + ci = BTCInterface(coin_settings, 'regtest') + + vk = i2b(ci.getNewSecretKey()) + pk = ci.getPubkey(vk) + + message = 'test signing message' + message_hash = hashlib.sha256(bytes(message, 'utf-8')).digest() + eck = PrivateKey(vk) + sig = eck.sign(message.encode('utf-8')) + + ci.verifySig(pk, message_hash, sig) + def test_sign_compact(self): coin_settings = {'rpcport': 0, 'rpcauth': 'none', 'blocks_confirmed': 1, 'conf_target': 1} ci = BTCInterface(coin_settings, 'regtest') @@ -192,6 +205,7 @@ class Test(unittest.TestCase): assert(len(sig) == 64) ci.verifyCompact(pk, 'test signing message', sig) + def test_dleag(self): coin_settings = {'rpcport': 0, 'walletrpcport': 0, 'walletrpcauth': 'none', 'blocks_confirmed': 1, 'conf_target': 1} ci = XMRInterface(coin_settings, 'regtest')