def on_sig(self, nick, sigb64): """Processes transaction signatures from counterparties. Returns True if all signatures received correctly, else returns False """ if self.aborted: return False sig = base64.b64decode(sigb64).encode('hex') inserted_sig = False txhex = btc.serialize(self.latest_tx) # batch retrieval of utxo data utxo = {} ctr = 0 for index, ins in enumerate(self.latest_tx['ins']): utxo_for_checking = ins['outpoint']['hash'] + ':' + str( ins['outpoint']['index']) #'deadbeef' markers mean our own input scripts are not '' if (ins['script'] != ''): continue utxo[ctr] = [index, utxo_for_checking] ctr += 1 utxo_data = jm_single().bc_interface.query_utxo_set( [x[1] for x in utxo.values()]) # insert signatures for i, u in utxo.iteritems(): if utxo_data[i] is None: continue sig_good = btc.verify_tx_input(txhex, u[0], utxo_data[i]['script'], *btc.deserialize_script(sig)) if sig_good: jlog.debug('found good sig at index=%d' % (u[0])) self.latest_tx['ins'][u[0]]['script'] = sig inserted_sig = True # check if maker has sent everything possible self.utxos[nick].remove(u[1]) if len(self.utxos[nick]) == 0: jlog.debug(('nick = {} sent all sigs, removing from ' 'nonrespondant list').format(nick)) self.nonrespondants.remove(nick) break if not inserted_sig: jlog.debug('signature did not match anything in the tx') # TODO what if the signature doesnt match anything # nothing really to do except drop it, carry on and wonder why the # other guy sent a failed signature tx_signed = True for ins in self.latest_tx['ins']: if ins['script'] == '': tx_signed = False if not tx_signed: return False assert not len(self.nonrespondants) jlog.debug('all makers have sent their signatures') self.taker_info_callback("INFO", "Transaction is valid, signing..") jlog.debug("schedule item was: " + str(self.schedule[self.schedule_index])) return self.self_sign_and_push()
def on_sig(self, nick, sigb64): """Processes transaction signatures from counterparties. Returns True if all signatures received correctly, else returns False """ if self.aborted: return False sig = base64.b64decode(sigb64).encode('hex') inserted_sig = False txhex = btc.serialize(self.latest_tx) # batch retrieval of utxo data utxo = {} ctr = 0 for index, ins in enumerate(self.latest_tx['ins']): utxo_for_checking = ins['outpoint']['hash'] + ':' + str( ins['outpoint']['index']) #'deadbeef' markers mean our own input scripts are not '' if (ins['script'] != ''): continue utxo[ctr] = [index, utxo_for_checking] ctr += 1 utxo_data = jm_single().bc_interface.query_utxo_set( [x[1] for x in utxo.values()]) # insert signatures for i, u in utxo.iteritems(): if utxo_data[i] is None: continue #Check if the sender serialize_scripted the witness #item into the sig message; if so, also pick up the amount #from the utxo data retrieved from the blockchain to verify #the segwit-style signature. Note that this allows a mixed #SW/non-SW transaction as each utxo is interpreted separately. sig_deserialized = btc.deserialize_script(sig) if len(sig_deserialized) == 2: ver_sig, ver_pub = sig_deserialized wit = None elif len(sig_deserialized) == 3: ver_sig, ver_pub, wit = sig_deserialized else: jlog.debug("Invalid signature message - more than 3 items") break ver_amt = utxo_data[i]['value'] if wit else None sig_good = btc.verify_tx_input(txhex, u[0], utxo_data[i]['script'], ver_sig, ver_pub, witness=wit, amount=ver_amt) if sig_good: jlog.debug('found good sig at index=%d' % (u[0])) if wit: self.latest_tx["ins"][u[0]]["txinwitness"] = [ ver_sig, ver_pub ] self.latest_tx["ins"][u[0]]["script"] = "16" + wit else: self.latest_tx["ins"][u[0]]["script"] = sig inserted_sig = True # check if maker has sent everything possible self.utxos[nick].remove(u[1]) if len(self.utxos[nick]) == 0: jlog.debug(('nick = {} sent all sigs, removing from ' 'nonrespondant list').format(nick)) self.nonrespondants.remove(nick) break if not inserted_sig: jlog.debug('signature did not match anything in the tx') # TODO what if the signature doesnt match anything # nothing really to do except drop it, carry on and wonder why the # other guy sent a failed signature tx_signed = True for ins in self.latest_tx['ins']: if ins['script'] == '': tx_signed = False if not tx_signed: return False assert not len(self.nonrespondants) jlog.info('all makers have sent their signatures') self.taker_info_callback("INFO", "Transaction is valid, signing..") jlog.debug("schedule item was: " + str(self.schedule[self.schedule_index])) return self.self_sign_and_push()
def add_signature(self, nick, sigb64): if nick not in self.nonrespondants: log.debug(('add_signature => nick={} ' 'not in nonrespondants {}').format( nick, self.nonrespondants)) return sig = base64.b64decode(sigb64).encode('hex') inserted_sig = False txhex = btc.serialize(self.latest_tx) # batch retrieval of utxo data utxo = {} ctr = 0 for index, ins in enumerate(self.latest_tx['ins']): utxo_for_checking = ins['outpoint']['hash'] + ':' + str( ins['outpoint']['index']) if (ins['script'] != '' or utxo_for_checking in self.input_utxos.keys()): continue utxo[ctr] = [index, utxo_for_checking] ctr += 1 utxo_data = jm_single().bc_interface.query_utxo_set( [x[1] for x in utxo.values()]) # insert signatures for i, u in utxo.iteritems(): if utxo_data[i] is None: continue sig_good = btc.verify_tx_input( txhex, u[0], utxo_data[i]['script'], *btc.deserialize_script(sig)) if sig_good: log.debug('found good sig at index=%d' % (u[0])) self.latest_tx['ins'][u[0]]['script'] = sig inserted_sig = True # check if maker has sent everything possible self.utxos[nick].remove(u[1]) if len(self.utxos[nick]) == 0: log.debug(('nick = {} sent all sigs, removing from ' 'nonrespondant list').format(nick)) self.nonrespondants.remove(nick) break if not inserted_sig: log.debug('signature did not match anything in the tx') # TODO what if the signature doesnt match anything # nothing really to do except drop it, carry on and wonder why the # other guy sent a failed signature tx_signed = True for ins in self.latest_tx['ins']: if ins['script'] == '': tx_signed = False if not tx_signed: return self.end_timeout_thread = True self.all_responded = True with self.timeout_lock: self.timeout_lock.notify() log.debug('all makers have sent their signatures') for index, ins in enumerate(self.latest_tx['ins']): # remove placeholders if ins['script'] == 'deadbeef': ins['script'] = '' if self.finishcallback is not None: log.debug("About to call finishcallback") self.finishcallback(self)
def add_signature(self, nick, sigb64): if nick not in self.nonrespondants: log.debug( ('add_signature => nick={} ' 'not in nonrespondants {}').format(nick, self.nonrespondants)) return sig = base64.b64decode(sigb64).encode('hex') inserted_sig = False txhex = btc.serialize(self.latest_tx) # batch retrieval of utxo data utxo = {} ctr = 0 for index, ins in enumerate(self.latest_tx['ins']): utxo_for_checking = ins['outpoint']['hash'] + ':' + str( ins['outpoint']['index']) if (ins['script'] != '' or utxo_for_checking in self.input_utxos.keys()): continue utxo[ctr] = [index, utxo_for_checking] ctr += 1 utxo_data = jm_single().bc_interface.query_utxo_set( [x[1] for x in utxo.values()]) # insert signatures for i, u in utxo.iteritems(): if utxo_data[i] is None: continue sig_good = btc.verify_tx_input(txhex, u[0], utxo_data[i]['script'], *btc.deserialize_script(sig)) if sig_good: log.debug('found good sig at index=%d' % (u[0])) self.latest_tx['ins'][u[0]]['script'] = sig inserted_sig = True # check if maker has sent everything possible self.utxos[nick].remove(u[1]) if len(self.utxos[nick]) == 0: log.debug(('nick = {} sent all sigs, removing from ' 'nonrespondant list').format(nick)) self.nonrespondants.remove(nick) break if not inserted_sig: log.debug('signature did not match anything in the tx') # TODO what if the signature doesnt match anything # nothing really to do except drop it, carry on and wonder why the # other guy sent a failed signature tx_signed = True for ins in self.latest_tx['ins']: if ins['script'] == '': tx_signed = False if not tx_signed: return self.end_timeout_thread = True self.all_responded = True with self.timeout_lock: self.timeout_lock.notify() log.debug('all makers have sent their signatures') for index, ins in enumerate(self.latest_tx['ins']): # remove placeholders if ins['script'] == 'deadbeef': ins['script'] = '' if self.finishcallback is not None: log.debug("About to call finishcallback") self.finishcallback(self)