def __init__(self, maker, nick, oid, amount, taker_pk): self.tx = None self.i_utxo_pubkey = None self.maker = maker self.oid = oid self.cj_amount = amount if self.cj_amount <= jm_single().DUST_THRESHOLD: self.maker.msgchan.send_error(nick, 'amount below dust threshold') # the btc pubkey of the utxo that the taker plans to use as input self.taker_pk = taker_pk # create DH keypair on the fly for this Order object self.kp = init_keypair() # the encryption channel crypto box for this Order object self.crypto_box = as_init_encryption(self.kp, init_pubkey(taker_pk)) order_s = [o for o in maker.orderlist if o['oid'] == oid] if len(order_s) == 0: self.maker.msgchan.send_error(nick, 'oid not found') order = order_s[0] if amount < order['minsize'] or amount > order['maxsize']: self.maker.msgchan.send_error(nick, 'amount out of range') self.ordertype = order['ordertype'] self.txfee = order['txfee'] self.cjfee = order['cjfee'] log.debug('new cjorder nick=%s oid=%d amount=%d' % (nick, oid, amount)) self.utxos, self.cj_addr, self.change_addr = maker.oid_to_order( self, oid, amount) self.maker.wallet.update_cache_index() if not self.utxos: self.maker.msgchan.send_error( nick, 'unable to fill order constrained by dust avoidance') # TODO make up orders offers in a way that this error cant appear # check nothing has messed up with the wallet code, remove this # code after a while import pprint log.debug('maker utxos = ' + pprint.pformat(self.utxos)) utxo_list = self.utxos.keys() utxo_data = jm_single().bc_interface.query_utxo_set(utxo_list) if None in utxo_data: log.debug('wrongly using an already spent utxo. utxo_data = ' + pprint.pformat(utxo_data)) sys.exit(0) for utxo, data in zip(utxo_list, utxo_data): if self.utxos[utxo]['value'] != data['value']: fmt = 'wrongly labeled utxo, expected value: {} got {}'.format log.debug(fmt(self.utxos[utxo]['value'], data['value'])) sys.exit(0) # always a new address even if the order ends up never being # furfilled, you dont want someone pretending to fill all your # orders to find out which addresses you use self.maker.msgchan.send_pubkey(nick, self.kp.hex_pk())
def start_encryption(self, nick, maker_pk): if nick not in self.active_orders.keys(): log.debug("Counterparty not part of this transaction. Ignoring") return try: self.crypto_boxes[nick] = [maker_pk, as_init_encryption( self.kp, init_pubkey(maker_pk))] except NaclError as e: log.debug("Unable to setup crypto box with " + nick + ": " + repr(e)) self.msgchan.send_error(nick, "invalid nacl pubkey: " + maker_pk) return self.msgchan.send_auth(nick, self.reveal_commitment)
def start_encryption(self, nick, maker_pk): if nick not in self.active_orders.keys(): log.debug("Counterparty not part of this transaction. Ignoring") return self.crypto_boxes[nick] = [maker_pk, as_init_encryption( self.kp, init_pubkey(maker_pk))] # send authorisation request if self.auth_addr: my_btc_addr = self.auth_addr else: my_btc_addr = self.input_utxos.itervalues().next()['address'] my_btc_priv = self.wallet.get_key_from_addr(my_btc_addr) my_btc_pub = btc.privtopub(my_btc_priv) my_btc_sig = btc.ecdsa_sign(self.kp.hex_pk(), my_btc_priv) self.msgchan.send_auth(nick, my_btc_pub, my_btc_sig)
def start_encryption(self, nick, maker_pk): if nick not in self.active_orders.keys(): log.debug("Counterparty not part of this transaction. Ignoring") return try: self.crypto_boxes[nick] = [ maker_pk, as_init_encryption(self.kp, init_pubkey(maker_pk)) ] except NaclError as e: log.debug("Unable to setup crypto box with " + nick + ": " + repr(e)) self.msgchan.send_error(nick, "invalid nacl pubkey: " + maker_pk) return self.msgchan.send_auth(nick, self.reveal_commitment)
def start_encryption(self, nick, maker_pk): if nick not in self.active_orders.keys(): log.debug("Counterparty not part of this transaction. Ignoring") return self.crypto_boxes[nick] = [ maker_pk, as_init_encryption(self.kp, init_pubkey(maker_pk)) ] # send authorisation request if self.auth_addr: my_btc_addr = self.auth_addr else: my_btc_addr = self.input_utxos.itervalues().next()['address'] my_btc_priv = self.wallet.get_key_from_addr(my_btc_addr) my_btc_pub = btc.privtopub(my_btc_priv) my_btc_sig = btc.ecdsa_sign(self.kp.hex_pk(), my_btc_priv) self.msgchan.send_auth(nick, my_btc_pub, my_btc_sig)
def start_encryption(self, nick, maker_pk): if nick not in self.active_orders.keys(): log.debug("Counterparty not part of this transaction. Ignoring") return try: self.crypto_boxes[nick] = [maker_pk, as_init_encryption( self.kp, init_pubkey(maker_pk))] except NaclError as e: log.debug("Unable to setup crypto box with " + nick + ": " + repr(e)) self.msgchan.send_error(nick, "invalid nacl pubkey: " + maker_pk) return # send authorisation request if self.auth_addr: my_btc_addr = self.auth_addr else: my_btc_addr = self.input_utxos.itervalues().next()['address'] my_btc_priv = self.wallet.get_key_from_addr(my_btc_addr) my_btc_pub = btc.privtopub(my_btc_priv) my_btc_sig = btc.ecdsa_sign(self.kp.hex_pk(), my_btc_priv) self.msgchan.send_auth(nick, my_btc_pub, my_btc_sig)
def __init__(self, maker, nick, oid, amount, taker_pk): self.tx = None self.i_utxo_pubkey = None self.maker = maker self.oid = oid self.cj_amount = amount if self.cj_amount <= jm_single().BITCOIN_DUST_THRESHOLD: self.maker.msgchan.send_error(nick, 'amount below dust threshold') # the btc pubkey of the utxo that the taker plans to use as input self.taker_pk = taker_pk # create DH keypair on the fly for this Order object self.kp = init_keypair() # the encryption channel crypto box for this Order object. # Invalid pubkeys must be handled by giving up gracefully (otherwise DOS) try: self.crypto_box = as_init_encryption(self.kp, init_pubkey(taker_pk)) except NaclError as e: log.info("Unable to setup crypto box with counterparty: " + repr(e)) self.maker.msgchan.send_error(nick, "invalid nacl pubkey: " + taker_pk) return order_s = [o for o in maker.orderlist if o['oid'] == oid] if len(order_s) == 0: self.maker.msgchan.send_error(nick, 'oid not found') order = order_s[0] if amount < order['minsize'] or amount > order['maxsize']: self.maker.msgchan.send_error(nick, 'amount out of range') self.ordertype = order['ordertype'] self.txfee = order['txfee'] self.cjfee = order['cjfee'] log.info('new cjorder nick=%s oid=%d amount=%d' % (nick, oid, amount)) def populate_utxo_data(): self.utxos, self.cj_addr, self.change_addr = maker.oid_to_order( self, oid, amount) self.maker.wallet.update_cache_index() if not self.utxos: self.maker.msgchan.send_error( nick, 'unable to fill order constrained by dust avoidance') # TODO make up orders offers in a way that this error cant appear # check nothing has messed up with the wallet code, remove this # code after a while log.debug('maker utxos = ' + pprint.pformat(self.utxos)) utxos = self.utxos.keys() return (utxos, jm_single().bc_interface.query_utxo_set(utxos)) for i in xrange(10): ##only loop 10 times, not an infinite amount utxo_list, utxo_data = populate_utxo_data() if None not in utxo_data: break log.debug('wrongly selected stale utxos! utxo_data = ' + pprint.pformat(utxo_data)) with self.maker.wallet_unspent_lock: jm_single().bc_interface.sync_unspent(self.maker.wallet) if None in utxo_data: log.error('unable to select non-stale utxo, weird error! quitting') sys.exit(0) for utxo, data in zip(utxo_list, utxo_data): if self.utxos[utxo]['value'] != data['value']: fmt = 'wrongly labeled utxo, expected value: {} got {}'.format log.debug(fmt(self.utxos[utxo]['value'], data['value'])) sys.exit(0) # always a new address even if the order ends up never being # furfilled, you dont want someone pretending to fill all your # orders to find out which addresses you use self.maker.msgchan.send_pubkey(nick, self.kp.hex_pk())