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()
Beispiel #3
0
    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)
Beispiel #4
0
    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)