Merge pull request #374 from nolith/master
authorThomasV <thomasv1@gmx.de>
Sun, 10 Nov 2013 10:55:33 +0000 (02:55 -0800)
committerThomasV <thomasv1@gmx.de>
Sun, 10 Nov 2013 10:55:33 +0000 (02:55 -0800)
allow to connect to one server only

21 files changed:
.gitignore
electrum
gui/android.py
gui/gtk.py
gui/qt/lite_window.py
gui/qt/main_window.py
gui/stdio.py
gui/text.py
lib/account.py
lib/bitcoin.py
lib/blockchain.py
lib/commands.py
lib/interface.py
lib/network.py
lib/plugins.py
lib/simple_config.py
lib/transaction.py
lib/util.py
lib/wallet.py
plugins/aliases.py
plugins/qrscanner.py

index f7aa874..40fce2e 100644 (file)
@@ -1,4 +1,5 @@
 ####-*.patch
+gui/icons_rc.py
 lib/icons_rc.py
 *.pyc
 *.swp
index 4bac95f..b0185ce 100755 (executable)
--- a/electrum
+++ b/electrum
@@ -71,6 +71,7 @@ def arg_parser():
     parser.add_option("-g", "--gui", dest="gui", help="User interface: qt, lite, gtk, text or stdio")
     parser.add_option("-w", "--wallet", dest="wallet_path", help="wallet path (default: electrum.dat)")
     parser.add_option("-o", "--offline", action="store_true", dest="offline", default=False, help="remain offline")
+    parser.add_option("-C", "--concealed", action="store_true", dest="concealed", default=False, help="don't echo seed to console when restoring")
     parser.add_option("-a", "--all", action="store_true", dest="show_all", default=False, help="show all addresses")
     parser.add_option("-l", "--labels", action="store_true", dest="show_labels", default=False, help="show the labels of listed addresses")
     parser.add_option("-f", "--fee", dest="tx_fee", default=None, help="set tx fee")
@@ -103,7 +104,7 @@ def run_command(cmd, password = None, args = []):
     cmd_runner.password = password
     try:
         result = func(*args[1:])
-    except BaseException, e:
+    except Exception as e:
         import traceback
         traceback.print_exc(file=sys.stdout)
         sys.exit(1)
@@ -210,7 +211,8 @@ if __name__ == '__main__':
         if gap: wallet.change_gap_limit(int(gap))
 
         if cmd.name == 'restore':
-            seed = raw_input("seed:")
+            import getpass
+            seed = getpass.getpass(prompt = "seed:", stream = None) if options.concealed else raw_input("seed:")
             try:
                 seed.decode('hex')
             except:
index e254a46..800dc32 100644 (file)
@@ -458,7 +458,7 @@ def pay_to(recipient, amount, fee, label):
 
     try:
         tx = wallet.mktx( [(recipient, amount)], password, fee)
-    except BaseException, e:
+    except Exception as e:
         modal_dialog('error', e.message)
         droid.dialogDismiss()
         return
index 0eab4dd..7120af3 100644 (file)
@@ -242,8 +242,9 @@ def run_network_dialog( network, parent ):
         import random
         status = "Please choose a server.\nSelect cancel if you are offline."
 
-    server = interface.server
-    host, port, protocol = server.split(':')
+    if network.is_connected():
+        server = interface.server
+        host, port, protocol = server.split(':')
 
     servers = network.get_servers()
 
@@ -261,7 +262,10 @@ def run_network_dialog( network, parent ):
     host_box.pack_start(host_label, False, False, 10)
     host_entry = gtk.Entry()
     host_entry.set_size_request(200,-1)
-    host_entry.set_text(server)
+    if network.is_connected():
+        host_entry.set_text(server)
+    else:
+        host_entry.set_text("Not Connected")
     host_entry.show()
     host_box.pack_start(host_entry, False, False, 10)
     add_help_button(host_box, 'The name, port number and protocol of your Electrum server, separated by a colon. Example: "ecdsa.org:50002:s". Some servers allow you to connect through http (port 80) or https (port 443)')
@@ -286,7 +290,7 @@ def run_network_dialog( network, parent ):
 
     def current_line():
         return unicode(host_entry.get_text()).split(':')
-    
+
     def set_combobox(protocol):
         combobox.set_active('tshg'.index(protocol))
 
@@ -300,7 +304,8 @@ def run_network_dialog( network, parent ):
         host_entry.set_text( host + ':' + port + ':' + protocol)
 
     combobox.connect("changed", lambda x:set_protocol('tshg'[combobox.get_active()]))
-    set_combobox(protocol)
+    if network.is_connected():
+        set_combobox(protocol)
         
     server_list = gtk.ListStore(str)
     for host in servers.keys():
@@ -802,7 +807,7 @@ class ElectrumWindow:
 
         try:
             tx = self.wallet.mktx( [(to_address, amount)], password, fee )
-        except BaseException, e:
+        except Exception as e:
             self.show_message(str(e))
             return
 
@@ -898,8 +903,7 @@ class ElectrumWindow:
         cell.set_property('editable', True)
         def edited_cb(cell, path, new_text, h_list):
             tx = h_list.get_value( h_list.get_iter(path), 0)
-            self.wallet.labels[tx] = new_text
-            self.wallet.save() 
+            self.wallet.set_label(tx,new_text)
             self.update_history_tab()
         cell.connect('edited', edited_cb, self.history_list)
         def editing_started(cell, entry, path, h_list):
@@ -942,7 +946,7 @@ class ElectrumWindow:
 
 
     def create_recv_tab(self):
-        self.recv_list = gtk.ListStore(str, str, str)
+        self.recv_list = gtk.ListStore(str, str, str, str)
         self.add_tab( self.make_address_list(True), 'Receive')
         self.update_receiving_tab()
 
@@ -974,8 +978,7 @@ class ElectrumWindow:
         cell.set_property('editable', True)
         def edited_cb2(cell, path, new_text, liststore):
             address = liststore.get_value( liststore.get_iter(path), 0)
-            self.wallet.labels[address] = new_text
-            self.wallet.save() 
+            self.wallet.set_label(address, new_text)
             self.update_receiving_tab()
             self.update_sending_tab()
             self.update_history_tab()
@@ -989,6 +992,13 @@ class ElectrumWindow:
         tvcolumn.pack_start(cell, True)
         tvcolumn.add_attribute(cell, 'text', 2)
 
+        if is_recv:
+            tvcolumn = gtk.TreeViewColumn('Type')
+            treeview.append_column(tvcolumn)
+            cell = gtk.CellRendererText()
+            tvcolumn.pack_start(cell, True)
+            tvcolumn.add_attribute(cell, 'text', 3)
+
         scroll = gtk.ScrolledWindow()
         scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
         scroll.add(treeview)
@@ -1102,12 +1112,16 @@ class ElectrumWindow:
     def update_receiving_tab(self):
         self.recv_list.clear()
         for address in self.wallet.addresses(True):
-            if self.wallet.is_change(address):continue
+            Type = "R"
+            if self.wallet.is_change(address): Type = "C"
+            if address in self.wallet.imported_keys.keys(): Type = "I"
+            if address in self.wallet.frozen_addresses: Type = Type + "F"
+            if address in self.wallet.prioritized_addresses: Type = Type + "P"
             label = self.wallet.labels.get(address)
             h = self.wallet.history.get(address,[])
             n = len(h)
-            tx = "None" if n==0 else "%d"%n
-            self.recv_list.append((address, label, tx ))
+            tx = "0" if n==0 else "%d"%n
+            self.recv_list.append((address, label, tx, Type ))
 
     def update_sending_tab(self):
         # detect addresses that are not mine in history, add them here...
index 3f24370..5131ae0 100644 (file)
@@ -750,7 +750,7 @@ class MiniActuator:
 
         try:
             tx = self.g.wallet.mktx([(dest_address, amount)], password, fee)
-        except BaseException as error:
+        except Exception as error:
             QMessageBox.warning(parent_window, _('Error'), str(error), _('OK'))
             return False
 
@@ -778,7 +778,7 @@ class MiniActuator:
                 with open(fileName,'w') as f:
                     f.write(json.dumps(tx.as_dict(),indent=4) + '\n')
                 QMessageBox.information(QWidget(), _('Unsigned transaction created'), _("Unsigned transaction was saved to file:") + " " +fileName, _('OK'))
-            except BaseException as e:
+            except Exception as e:
                 QMessageBox.warning(QWidget(), _('Error'), _('Could not write transaction to file: %s' % e), _('OK'))
         return True
 
index aefa8df..57f8307 100644 (file)
@@ -889,7 +889,7 @@ class ElectrumWindow(QMainWindow):
 
         try:
             tx = self.wallet.mktx_from_account( [(to_address, amount)], password, fee, self.current_account)
-        except BaseException, e:
+        except Exception as e:
             traceback.print_exc(file=sys.stdout)
             self.show_message(str(e))
             return
@@ -1124,8 +1124,9 @@ class ElectrumWindow(QMainWindow):
         menu.addAction(_("Copy to clipboard"), lambda: self.app.clipboard().setText(addr))
         menu.addAction(_("QR code"), lambda: self.show_qrcode("bitcoin:" + addr, _("Address")) )
         menu.addAction(_("Edit label"), lambda: self.edit_label(True))
-        menu.addAction(_("Private key"), lambda: self.show_private_key(addr))
-        menu.addAction(_("Sign message"), lambda: self.sign_message(addr))
+        if self.wallet.seed:
+            menu.addAction(_("Private key"), lambda: self.show_private_key(addr))
+            menu.addAction(_("Sign message"), lambda: self.sign_message(addr))
         if addr in self.wallet.imported_keys:
             menu.addAction(_("Remove from wallet"), lambda: self.delete_imported_key(addr))
 
@@ -1634,7 +1635,7 @@ class ElectrumWindow(QMainWindow):
         if not address: return
         try:
             pk_list = self.wallet.get_private_key(address, password)
-        except BaseException, e:
+        except Exception as e:
             self.show_message(str(e))
             return
         QMessageBox.information(self, _('Private key'), _('Address')+ ': ' + address + '\n\n' + _('Private key') + ': ' + '\n'.join(pk_list), _('OK'))
@@ -1647,7 +1648,7 @@ class ElectrumWindow(QMainWindow):
         try:
             sig = self.wallet.sign_message(str(address.text()), message, password)
             signature.setText(sig)
-        except BaseException, e:
+        except Exception as e:
             self.show_message(str(e))
 
     def sign_message(self, address):
@@ -1839,7 +1840,7 @@ class ElectrumWindow(QMainWindow):
 
         try:
             tx = self.wallet.make_unsigned_transaction(outputs, None, None)
-        except BaseException, e:
+        except Exception as e:
             self.show_message(str(e))
             return
 
@@ -1892,7 +1893,7 @@ class ElectrumWindow(QMainWindow):
             export_error_label = _("Electrum was unable to produce a private key-export.")
             QMessageBox.critical(None, _("Unable to create csv"), export_error_label + "\n" + str(reason))
 
-        except BaseException, e:
+        except Exception as e:
           self.show_message(str(e))
           return
 
@@ -1945,7 +1946,7 @@ class ElectrumWindow(QMainWindow):
         for key in text:
             try:
                 addr = self.wallet.import_key(key, password)
-            except BaseException as e:
+            except Exception as e:
                 badkeys.append(key)
                 continue
             if not addr: 
index f252a8a..517f8bb 100644 (file)
@@ -198,7 +198,7 @@ class ElectrumGui:
 
         try:
             tx = self.wallet.mktx( [(self.str_recipient, amount)], password, fee)
-        except BaseException, e:
+        except Exception as e:
             print(str(e))
             return
             
index 437ce35..d9b9520 100644 (file)
@@ -309,7 +309,7 @@ class ElectrumGui:
 
         try:
             tx = self.wallet.mktx( [(self.str_recipient, amount)], password, fee)
-        except BaseException, e:
+        except Exception as e:
             self.show_message(str(e))
             return
             
index bf12ae1..9a262bf 100644 (file)
@@ -106,10 +106,10 @@ class OldAccount(Account):
         curve = SECP256k1
         secexp = self.stretch_key(seed)
         master_private_key = ecdsa.SigningKey.from_secret_exponent( secexp, curve = SECP256k1 )
-        master_public_key = master_private_key.get_verifying_key().to_string().encode('hex')
+        master_public_key = master_private_key.get_verifying_key().to_string()
         if master_public_key != self.mpk:
             print_error('invalid password (mpk)')
-            raise BaseException('Invalid password')
+            raise Exception('Invalid password')
         return True
 
     def redeem_script(self, sequence):
index 94d5075..36758f9 100644 (file)
@@ -115,7 +115,7 @@ def hash_160(public_key):
         md = hashlib.new('ripemd160')
         md.update(hashlib.sha256(public_key).digest())
         return md.digest()
-    except:
+    except Exception:
         import ripemd
         md = ripemd.new(hashlib.sha256(public_key).digest())
         return md.digest()
@@ -268,7 +268,7 @@ def is_valid(addr):
     if not ADDRESS_RE.match(addr): return False
     try:
         addrtype, h = bc_address_to_hash_160(addr)
-    except:
+    except Exception:
         return False
     return addr == hash_160_to_bc_address(h, addrtype)
 
@@ -277,7 +277,7 @@ def is_valid(addr):
 
 try:
     from ecdsa.ecdsa import curve_secp256k1, generator_secp256k1
-except:
+except Exception:
     print "cannot import ecdsa.curve_secp256k1. You probably need to upgrade ecdsa.\nTry: sudo pip install --upgrade ecdsa"
     exit()
 from ecdsa.curves import SECP256k1
@@ -294,7 +294,7 @@ def verify_message(address, signature, message):
     try:
         EC_KEY.verify_message(address, signature, message)
         return True
-    except BaseException as e:
+    except Exception as e:
         print_error("Verification error: {0}".format(e))
         return False
 
@@ -316,10 +316,10 @@ class EC_KEY(object):
             try:
                 self.verify_message( address, sig, message)
                 return sig
-            except:
+            except Exception:
                 continue
         else:
-            raise BaseException("error: cannot sign message")
+            raise Exception("error: cannot sign message")
 
     @classmethod
     def verify_message(self, address, signature, message):
@@ -331,11 +331,11 @@ class EC_KEY(object):
         order = G.order()
         # extract r,s from signature
         sig = base64.b64decode(signature)
-        if len(sig) != 65: raise BaseException("Wrong encoding")
+        if len(sig) != 65: raise Exception("Wrong encoding")
         r,s = util.sigdecode_string(sig[1:], order)
         nV = ord(sig[0])
         if nV < 27 or nV >= 35:
-            raise BaseException("Bad encoding")
+            raise Exception("Bad encoding")
         if nV >= 31:
             compressed = True
             nV -= 4
@@ -364,7 +364,7 @@ class EC_KEY(object):
         # check that we get the original signing address
         addr = public_key_to_bc_address( encode_point(public_key, compressed) )
         if address != addr:
-            raise BaseException("Bad signature")
+            raise Exception("Bad signature")
 
 
 ###################################### BIP32 ##############################
index c7dab20..08461d0 100644 (file)
@@ -119,7 +119,7 @@ class Blockchain(threading.Thread):
                 assert prev_hash == header.get('prev_block_hash')
                 assert bits == header.get('bits')
                 assert eval('0x'+_hash) < target
-            except:
+            except Exception:
                 return False
 
             prev_header = header
@@ -176,7 +176,7 @@ class Blockchain(threading.Thread):
             assert prev_hash == header.get('prev_block_hash')
             assert bits == header.get('bits')
             assert eval('0x'+_hash) < target
-        except:
+        except Exception:
             # this can be caused by a reorg.
             print_error("verify header failed"+ repr(header))
             verifier.undo_verifications()
@@ -227,7 +227,7 @@ class Blockchain(threading.Thread):
             print_error("downloading ", self.headers_url )
             urllib.urlretrieve(self.headers_url, filename)
             print_error("done.")
-        except:
+        except Exception:
             print_error( "download failed. creating file", filename )
             open(filename,'wb+').close()
 
@@ -411,7 +411,7 @@ class Blockchain(threading.Thread):
             index = params[0]
             try:
                 self.verify_chunk(index, result)
-            except:
+            except Exception:
                 print_error('Verify chunk failed!!')
                 return False
             requested_chunks.remove(index)
index 129b1c5..f34c10a 100644 (file)
@@ -228,7 +228,7 @@ class Commands:
         try:
             addr = self.wallet.import_key(sec,self.password)
             out = "Keypair imported: ", addr
-        except BaseException as e:
+        except Exception as e:
             out = "Error: Keypair import failed: " + str(e)
         return out
 
@@ -245,19 +245,19 @@ class Commands:
 
         for to_address, amount in outputs:
             if not is_valid(to_address):
-                raise BaseException("Invalid Bitcoin address", to_address)
+                raise Exception("Invalid Bitcoin address", to_address)
 
         if change_addr:
             if not is_valid(change_addr):
-                raise BaseException("Invalid Bitcoin address", change_addr)
+                raise Exception("Invalid Bitcoin address", change_addr)
 
         if domain is not None:
             for addr in domain:
                 if not is_valid(addr):
-                    raise BaseException("invalid Bitcoin address", addr)
+                    raise Exception("invalid Bitcoin address", addr)
             
                 if not self.wallet.is_mine(addr):
-                    raise BaseException("address not in wallet", addr)
+                    raise Exception("address not in wallet", addr)
 
         for k, v in self.wallet.labels.items():
             if change_addr and v == change_addr:
@@ -306,7 +306,7 @@ class Commands:
             tx_hash, conf, is_mine, value, fee, balance, timestamp = item
             try:
                 time_str = datetime.datetime.fromtimestamp( timestamp).isoformat(' ')[:-3]
-            except:
+            except Exception:
                 time_str = "----"
 
             label, is_default_label = self.wallet.get_label(tx_hash)
index 43b0a6c..44de285 100644 (file)
@@ -49,7 +49,7 @@ def check_cert(host, cert):
 def cert_has_expired(cert_path):
     try:
         import OpenSSL
-    except:
+    except Exception:
         print_error("Warning: cannot import OpenSSL")
         return False
     from OpenSSL import crypto as c
@@ -112,12 +112,12 @@ class Interface(threading.Thread):
         try:
             host, port, protocol = self.server.split(':')
             port = int(port)
-        except:
+        except Exception:
             self.server = None
             return
 
         if protocol not in 'ghst':
-            raise BaseException('Unknown protocol: %s'%protocol)
+            raise Exception('Unknown protocol: %s'%protocol)
 
         self.host = host
         self.port = port
@@ -196,7 +196,7 @@ class Interface(threading.Thread):
         self.connection_msg = ('https' if self.use_ssl else 'http') + '://%s:%d'%( self.host, self.port )
         try:
             self.poll()
-        except:
+        except Exception:
             print_error("http init session failed")
             self.is_connected = False
             return
@@ -218,7 +218,7 @@ class Interface(threading.Thread):
                 break
             except socket.error:
                 break
-            except:
+            except Exception:
                 traceback.print_exc(file=sys.stdout)
                 break
             
@@ -265,7 +265,7 @@ class Interface(threading.Thread):
         try:
             req = urllib2.Request(self.connection_msg, data_json, headers)
             response_stream = urllib2.urlopen(req, timeout=DEFAULT_TIMEOUT)
-        except:
+        except Exception:
             return
 
         for index, cookie in enumerate(cj):
@@ -318,7 +318,7 @@ class Interface(threading.Thread):
                 s = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
                 try:
                     s.connect((self.host, self.port))
-                except:
+                except Exception:
                     # print_error("failed to connect", self.host, self.port)
                     return
 
@@ -346,7 +346,7 @@ class Interface(threading.Thread):
 
         try:
             s.connect(( self.host.encode('ascii'), int(self.port)))
-        except:
+        except Exception:
             print_error("failed to connect", self.host, self.port)
             return
 
@@ -370,7 +370,7 @@ class Interface(threading.Thread):
                     else:
                         print_msg("wrong certificate", self.host)
                 return
-            except:
+            except Exception:
                 print_error("wrap_socket failed", self.host)
                 traceback.print_exc(file=sys.stdout)
                 return
@@ -424,7 +424,7 @@ class Interface(threading.Thread):
                     c = json.loads(c)
                     self.queue_json_response(c)
 
-        except:
+        except Exception:
             traceback.print_exc(file=sys.stdout)
 
         self.is_connected = False
index 13f5a86..beabae3 100644 (file)
@@ -7,7 +7,7 @@ from blockchain import Blockchain
 DEFAULT_PORTS = {'t':'50001', 's':'50002', 'h':'8081', 'g':'8082'}
 
 DEFAULT_SERVERS = {
-    'electrum.coinwallet.me': {'h': '8081', 's': '50002', 't': '50001', 'g': '8082'},
+    #'electrum.coinwallet.me': {'h': '8081', 's': '50002', 't': '50001', 'g': '8082'},
     'electrum.hachre.de': {'h': '8081', 's': '50002', 't': '50001', 'g': '8082'},
     'electrum.novit.ro': {'h': '8081', 's': '50002', 't': '50001', 'g': '8082'},
     'electrum.stepkrav.pw': {'h': '8081', 's': '50002', 't': '50001', 'g': '8082'},
@@ -16,8 +16,8 @@ DEFAULT_SERVERS = {
     'electrum.drollette.com': {'h': '5000', 's': '50002', 't': '50001', 'g': '8082'},
     'btc.it-zone.org': {'h': '80', 's': '110', 't': '50001', 'g': '443'},
     'btc.medoix.com': {'h': '8081', 's': '50002', 't': '50001', 'g': '8082'},
-    'spv.nybex.com': {'h': '8081', 's': '50002', 't': '50001', 'g': '8082'},
-    'electrum.pdmc.net': {'h': '8081', 's': '50002', 't': '50001', 'g': '8082'},
+    'electrum.stupidfoot.com': {'h': '8081', 's': '50002', 't': '50001', 'g': '8082'},
+    #'electrum.pdmc.net': {'h': '8081', 's': '50002', 't': '50001', 'g': '8082'},
     'electrum.be': {'h': '8081', 's': '50002', 't': '50001', 'g': '8082'}
 }
 
@@ -385,7 +385,7 @@ class Network(threading.Thread):
                     if pruning_level == '': pruning_level = '0'
             try: 
                 is_recent = float(version)>=float(PROTOCOL_VERSION)
-            except:
+            except Exception:
                 is_recent = False
 
             if out and is_recent:
index 0e7e520..a3ba5bc 100644 (file)
@@ -24,7 +24,7 @@ def init_plugins(self):
     for name, p in zip(plugin_names, plugin_modules):
         try:
             plugins.append( p.Plugin(self, name) )
-        except:
+        except Exception:
             print_msg(_("Error: cannot initialize plugin"),p)
             traceback.print_exc(file=sys.stdout)
 
@@ -45,7 +45,7 @@ def run_hook(name, *args):
 
         try:
             f(*args)
-        except:
+        except Exception:
             print_error("Plugin error")
             traceback.print_exc(file=sys.stdout)
             
index e3614f5..1ae6579 100644 (file)
@@ -103,7 +103,7 @@ a SimpleConfig instance then reads the wallet file.
             import ast
             try:
                 out = ast.literal_eval(out)
-            except:
+            except Exception:
                 print "type error for '%s': using default value"%key
                 out = default
 
@@ -154,7 +154,7 @@ a SimpleConfig instance then reads the wallet file.
                 return
             try:
                 d = ast.literal_eval( data )  #parse raw data from reading wallet file
-            except:
+            except Exception:
                 raise IOError("Cannot read config file.")
 
             self.user_config = d
index 7e36369..b1c4bf5 100644 (file)
@@ -298,7 +298,7 @@ def match_decoded(decoded, to_match):
 def get_address_from_input_script(bytes):
     try:
         decoded = [ x for x in script_GetOp(bytes) ]
-    except:
+    except Exception:
         # coinbase transactions raise an exception
         print_error("cannot find address in input script", bytes.encode('hex'))
         return [], [], "(None)"
index fb84b5d..b719fed 100644 (file)
@@ -49,7 +49,7 @@ def user_dir():
     elif 'ANDROID_DATA' in os.environ:
         return "/sdcard/electrum/"
     else:
-        #raise BaseException("No home directory found in environment variables.")
+        #raise Exception("No home directory found in environment variables.")
         return 
 
 def appdata_dir():
index 832439a..443a3d6 100644 (file)
@@ -37,6 +37,7 @@ from transaction import Transaction
 from plugins import run_hook
 
 COINBASE_MATURITY = 100
+DUST_THRESHOLD = 5430
 
 # AES encryption
 EncodeAES = lambda secret, s: base64.b64encode(aes.encryptData(secret,s))
@@ -54,8 +55,8 @@ def pw_decode(s, password):
         secret = Hash(password)
         try:
             d = DecodeAES(secret, s)
-        except:
-            raise BaseException('Invalid password')
+        except Exception:
+            raise Exception('Invalid password')
         return d
     else:
         return s
@@ -116,7 +117,7 @@ class WalletStorage:
             return
         try:
             d = ast.literal_eval( data )  #parse raw data from reading wallet file
-        except:
+        except Exception:
             raise IOError("Cannot read wallet file.")
 
         self.data = d
@@ -191,7 +192,7 @@ class Wallet:
         for k,v in tx_list.items():
             try:
                 tx = Transaction(v)
-            except:
+            except Exception:
                 print_msg("Warning: Cannot deserialize transactions. skipping")
                 continue
 
@@ -255,11 +256,11 @@ class Wallet:
         seed = self.get_seed(password)
         try:
             address = address_from_private_key(sec)
-        except:
-            raise BaseException('Invalid private key')
+        except Exception:
+            raise Exception('Invalid private key')
 
         if self.is_mine(address):
-            raise BaseException('Address already in wallet')
+            raise Exception('Address already in wallet')
         
         # store the originally requested keypair into the imported keys table
         self.imported_keys[address] = pw_encode(sec, password )
@@ -295,7 +296,7 @@ class Wallet:
         import mnemonic
         
         if self.seed: 
-            raise BaseException("a seed exists")
+            raise Exception("a seed exists")
 
         if not seed:
             self.seed = random_seed(128)
@@ -313,7 +314,7 @@ class Wallet:
             self.seed_version = 4
             self.seed = str(seed)
             return
-        except:
+        except Exception:
             pass
 
         words = seed.split()
@@ -323,7 +324,7 @@ class Wallet:
         #try:
         #    mnemonic.mn_decode(words)
         #    uses_electrum_words = True
-        #except:
+        #except Exception:
         #    uses_electrum_words = False
         #
         #if uses_electrum_words and len(words) != 13:
@@ -346,6 +347,7 @@ class Wallet:
 
         if not c0:
             self.seed_version = 4
+            self.storage.put('seed_version', self.seed_version, True)
             self.create_old_account(K0)
             return
 
@@ -354,6 +356,7 @@ class Wallet:
             "m/0'/": (c0, K0, cK0),
             }
         self.storage.put('master_public_keys', self.master_public_keys, True)
+        self.storage.put('seed_version', self.seed_version, True)
         self.create_account('1','Main account')
 
 
@@ -435,7 +438,7 @@ class Wallet:
         elif account_type == '2of3':
             return "m/3'/%d & m/4'/%d & m/5'/%d"%(i,i,i)
         else:
-            raise BaseException('unknown account type')
+            raise Exception('unknown account type')
 
 
     def num_accounts(self, account_type):
@@ -605,8 +608,8 @@ class Wallet:
         try:
             K, Kc = get_pubkeys_from_secret(master_k.decode('hex'))
             assert K.encode('hex') == master_K
-        except:
-            raise BaseException("Invalid password")
+        except Exception:
+            raise Exception("Invalid password")
         return master_k
 
 
@@ -625,7 +628,7 @@ class Wallet:
             if v == address:
                 return k, (0,0)
 
-        raise BaseException("Address not found", address)
+        raise Exception("Address not found", address)
 
 
     def get_roots(self, account):
@@ -677,9 +680,9 @@ class Wallet:
         s = pw_decode(self.seed, password)
         if self.seed_version == 4:
             seed = s
+            self.accounts[0].check_seed(seed)
         else:
             seed = mnemonic_hash(s)
-        #todo:  #self.sequences[0].check_seed(seed)
         return seed
         
 
@@ -1107,7 +1110,7 @@ class Wallet:
             if h == ['*']: continue
             for tx_hash, tx_height in h:
                 tx = self.transactions.get(tx_hash)
-                if tx is None: raise BaseException("Wallet not synchronized")
+                if tx is None: raise Exception("Wallet not synchronized")
                 is_coinbase = tx.inputs[0].get('prevout_hash') == '0'*64
                 for output in tx.d.get('outputs'):
                     if output.get('address') != addr: continue
@@ -1185,7 +1188,7 @@ class Wallet:
     def add_tx_change( self, inputs, outputs, amount, fee, total, change_addr=None):
         "add change to a transaction"
         change_amount = total - ( amount + fee )
-        if change_amount != 0:
+        if change_amount > DUST_THRESHOLD:
             if not change_addr:
 
                 # send change to one of the accounts involved in the tx
@@ -1242,7 +1245,7 @@ class Wallet:
     def receive_history_callback(self, addr, hist):
 
         if not self.check_new_history(addr, hist):
-            raise BaseException("error: received history for %s is not consistent with known transactions"%addr)
+            raise Exception("error: received history for %s is not consistent with known transactions"%addr)
             
         with self.lock:
             self.history[addr] = hist
@@ -1405,8 +1408,7 @@ class Wallet:
 
     def update_password(self, old_password, new_password):
         if new_password == '': new_password = None
-        # this will throw an exception if unicode cannot be converted
-        decoded = pw_decode(self.seed, old_password)
+        decoded = self.get_seed(old_password)
         self.seed = pw_encode( decoded, new_password)
         self.storage.put('seed', self.seed, True)
         self.use_encryption = (new_password != None)
@@ -1751,12 +1753,12 @@ class WalletSynchronizer(threading.Thread):
                             hist.append( (tx_hash, item['height']) )
 
                     if len(hist) != len(result):
-                        raise BaseException("error: server sent history with non-unique txid", result)
+                        raise Exception("error: server sent history with non-unique txid", result)
 
                     # check that the status corresponds to what was announced
                     rs = requested_histories.pop(addr)
                     if self.wallet.get_status(hist) != rs:
-                        raise BaseException("error: status mismatch: %s"%addr)
+                        raise Exception("error: status mismatch: %s"%addr)
                 
                     # store received history
                     self.wallet.receive_history_callback(addr, hist)
index c294674..0a54d6d 100644 (file)
@@ -52,7 +52,7 @@ class Plugin(BasePlugin):
     def get_alias(self, alias, interactive = False, show_message=None, question = None):
         try:
             target, signing_address, auth_name = read_alias(self, alias)
-        except BaseException, e:
+        except Exception as e:
             # raise exception if verify fails (verify the chain)
             if interactive:
                 show_message("Alias error: " + str(e))
index d76742d..4826eeb 100644 (file)
@@ -110,7 +110,7 @@ class Plugin(BasePlugin):
 
         try:
             tx = self.gui.main_window.wallet.mktx( [(to_address, amount)], None, fee)
-        except BaseException, e:
+        except Exception as e:
             self.gui.main_window.show_message(str(e))
             return
 
@@ -126,13 +126,13 @@ class Plugin(BasePlugin):
     
             input_info = []
 
-        except BaseException, e:
+        except Exception as e:
             self.gui.main_window.show_message(str(e))
 
         try:
             json_text = json.dumps(tx.as_dict()).replace(' ', '')
             self.show_tx_qrcode(json_text, 'Unsigned Transaction')
-        except BaseException, e:
+        except Exception as e:
             self.gui.main_window.show_message(str(e))
 
     def show_tx_qrcode(self, data, title):
@@ -235,7 +235,7 @@ class Plugin(BasePlugin):
             self.gui.main_window.wallet.signrawtransaction(tx, input_info, [], password)
             txtext = json.dumps(tx.as_dict()).replace(' ', '')
             self.show_tx_qrcode(txtext, 'Signed Transaction')
-        except BaseException, e:
+        except Exception as e:
             self.gui.main_window.show_message(str(e))