URI: 
       tfollow-up 0438bbc2c26d32ec17c76a0c8f1beb69255142f2 - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 8f7a4cf876c3eb9ec5669ec3dd068a7a819636de
   DIR parent 7ebff5616e81e75542ee0d8570a5b54bcc023755
  HTML Author: SomberNight <somber.night@protonmail.com>
       Date:   Thu, 14 Jun 2018 21:46:03 +0200
       
       follow-up 0438bbc2c26d32ec17c76a0c8f1beb69255142f2
       
       tthe previous was quadratic in len(tx.inputs())
       
       Diffstat:
         M lib/transaction.py                  |      45 +++++++++++++++++++------------
       
       1 file changed, 28 insertions(+), 17 deletions(-)
       ---
   DIR diff --git a/lib/transaction.py b/lib/transaction.py
       t@@ -652,30 +652,41 @@ class Transaction:
                return pubkeys, x_pubkeys
        
            def update_signatures(self, signatures: Sequence[str]):
       -        """Add new signatures to a transaction"""
       +        """Add new signatures to a transaction
       +
       +        `signatures` is expected to be a list of sigs with signatures[i]
       +        intended for self._inputs[i].
       +        This is used by the Trezor and KeepKey plugins.
       +        """
                if self.is_complete():
                    return
       +        if len(self.inputs()) != len(signatures):
       +            raise Exception('expected {} signatures; got {}'.format(len(self.inputs()), len(signatures)))
                for i, txin in enumerate(self.inputs()):
                    pubkeys, x_pubkeys = self.get_sorted_pubkeys(txin)
       -            for sig in signatures:
       -                if sig in txin.get('signatures'):
       +            sig = signatures[i]
       +            if sig in txin.get('signatures'):
       +                continue
       +            pre_hash = Hash(bfh(self.serialize_preimage(i)))
       +            sig_string = ecc.sig_string_from_der_sig(bfh(sig[:-2]))
       +            for recid in range(4):
       +                try:
       +                    public_key = ecc.ECPubkey.from_sig_string(sig_string, recid, pre_hash)
       +                except ecc.InvalidECPointException:
       +                    # the point might not be on the curve for some recid values
                            continue
       -                pre_hash = Hash(bfh(self.serialize_preimage(i)))
       -                sig_string = ecc.sig_string_from_der_sig(bfh(sig[:-2]))
       -                for recid in range(4):
       +                pubkey_hex = public_key.get_public_key_hex(compressed=True)
       +                if pubkey_hex in pubkeys:
                            try:
       -                        public_key = ecc.ECPubkey.from_sig_string(sig_string, recid, pre_hash)
       -                    except ecc.InvalidECPointException:
       -                        # the point might not be on the curve for some recid values
       -                        continue
       -                    pubkey_hex = public_key.get_public_key_hex(compressed=True)
       -                    if pubkey_hex in pubkeys:
                                public_key.verify_message_hash(sig_string, pre_hash)
       -                        j = pubkeys.index(pubkey_hex)
       -                        print_error("adding sig", i, j, pubkey_hex, sig)
       -                        self.add_signature_to_txin(self._inputs[i], j, sig)
       -                        #self._inputs[i]['x_pubkeys'][j] = pubkey
       -                        break
       +                    except Exception:
       +                        traceback.print_exc(file=sys.stderr)
       +                        continue
       +                    j = pubkeys.index(pubkey_hex)
       +                    print_error("adding sig", i, j, pubkey_hex, sig)
       +                    self.add_signature_to_txin(self._inputs[i], j, sig)
       +                    #self._inputs[i]['x_pubkeys'][j] = pubkey
       +                    break
                # redo raw
                self.raw = self.serialize()