First cleanup branch commit
authorChris Glass <tribaal@gmail.com>
Tue, 24 Jun 2014 13:12:43 +0000 (16:12 +0300)
committerChris Glass <tribaal@gmail.com>
Tue, 24 Jun 2014 13:12:43 +0000 (16:12 +0300)
This fixes some import and whitespace issues to align closer to pep8.
I added a few comments to make further contributions easier.

lib/commands.py
lib/wallet.py

index 95b72e1..77b748b 100644 (file)
 # You should have received a copy of the GNU General Public License
 # along with this program. If not, see <http://www.gnu.org/licenses/>.
 
+import datetime
 import time
-from util import *
-from bitcoin import *
+import copy
+from util import print_msg, format_satoshis
+from bitcoin import is_valid, hash_160_to_bc_address, hash_160
 from decimal import Decimal
 import bitcoin
 from transaction import Transaction
 
+
 class Command:
     def __init__(self, name, min_args, max_args, requires_network, requires_wallet, requires_password, description, syntax = '', options_syntax = ''):
         self.name = name
@@ -35,7 +38,10 @@ class Command:
         self.syntax = syntax
         self.options = options_syntax
 
+
 known_commands = {}
+
+
 def register_command(*args):
     global known_commands
     name = args[0]
@@ -105,8 +111,6 @@ register_command('getutxoaddress',       2, 2, True, False, False, 'get the addr
 register_command('sweep',                2, 3, True, False, False, 'Sweep a private key.', 'sweep privkey addr [fee]')
 
 
-
-
 class Commands:
 
     def __init__(self, wallet, network, callback = None):
@@ -115,7 +119,6 @@ class Commands:
         self._callback = callback
         self.password = None
 
-
     def _run(self, method, args, password_getter):
         cmd = known_commands[method]
         if cmd.requires_password and self.wallet.use_encryption:
@@ -127,40 +130,33 @@ class Commands:
             apply(self._callback, ())
         return result
 
-
     def getaddresshistory(self, addr):
         return self.network.synchronous_get([ ('blockchain.address.get_history',[addr]) ])[0]
 
-
     def daemon(self, arg):
         if arg=='stop':
             return self.network.stop()
         elif arg=='status':
-            return { 
-                'server':self.network.main_server(), 
+            return {
+                'server':self.network.main_server(),
                 'connected':self.network.is_connected()
             }
         else:
             return "unknown command \"%s\""% arg
 
-
     def listunspent(self):
-        import copy
         l = copy.deepcopy(self.wallet.get_unspent_coins())
         for i in l: i["value"] = str(Decimal(i["value"])/100000000)
         return l
 
-
     def getaddressunspent(self, addr):
         return self.network.synchronous_get([ ('blockchain.address.listunspent',[addr]) ])[0]
 
-
     def getutxoaddress(self, txid, num):
         r = self.network.synchronous_get([ ('blockchain.utxo.get_address',[txid, num]) ])
-        if r: 
+        if r:
             return {'address':r[0] }
 
-
     def createrawtransaction(self, inputs, outputs):
         for i in inputs:
             i['prevout_hash'] = i['txid']
@@ -169,7 +165,6 @@ class Commands:
         tx = Transaction.from_io(inputs, outputs)
         return tx
 
-
     def signrawtransaction(self, raw_tx, private_keys):
         tx = Transaction(raw_tx)
         self.wallet.signrawtransaction(tx, private_keys, self.password)
@@ -188,10 +183,10 @@ class Commands:
         redeem_script = Transaction.multisig_script(pubkeys, num)
         address = hash_160_to_bc_address(hash_160(redeem_script.decode('hex')), 5)
         return {'address':address, 'redeemScript':redeem_script}
-    
+
     def freeze(self,addr):
         return self.wallet.freeze(addr)
-        
+
     def unfreeze(self,addr):
         return self.wallet.unfreeze(addr)
 
@@ -215,7 +210,6 @@ class Commands:
         out['pubkeys'] = self.wallet.getpubkeys(addr)
         return out
 
-
     def getbalance(self, account= None):
         if account is None:
             c, u = self.wallet.get_balance()
@@ -232,7 +226,6 @@ class Commands:
         out["unconfirmed"] =  str(Decimal(out["unconfirmed"])/100000000)
         return out
 
-
     def getproof(self, addr):
         p = self.network.synchronous_get([ ('blockchain.address.get_proof',[addr]) ])[0]
         out = []
@@ -246,9 +239,9 @@ class Commands:
         return self.network.get_servers()
 
     def getversion(self):
-        import electrum 
+        import electrum  # Needs to stay here to prevent ciruclar imports
         return electrum.ELECTRUM_VERSION
+
     def getmpk(self):
         return self.wallet.get_master_public_keys()
 
@@ -264,20 +257,16 @@ class Commands:
             out = "Error: Keypair import failed: " + str(e)
         return out
 
-
     def sweep(self, privkey, to_address, fee = 0.0001):
         fee = int(Decimal(fee)*100000000)
         return Transaction.sweep([privkey], self.network, to_address, fee)
 
-
     def signmessage(self, address, message):
         return self.wallet.sign_message(address, message, self.password)
 
-
     def verifymessage(self, address, signature, message):
         return bitcoin.verify_message(address, signature, message)
 
-
     def _mktx(self, outputs, fee = None, change_addr = None, domain = None):
 
         for to_address, amount in outputs:
@@ -292,7 +281,7 @@ class Commands:
             for addr in domain:
                 if not is_valid(addr):
                     raise Exception("invalid Bitcoin address", addr)
-            
+
                 if not self.wallet.is_mine(addr):
                     raise Exception("address not in wallet", addr)
 
@@ -310,11 +299,10 @@ class Commands:
 
             amount = int(100000000*amount)
             final_outputs.append((to_address, amount))
-            
+
         if fee: fee = int(100000000*fee)
         return self.wallet.mktx(final_outputs, self.password, fee , change_addr, domain)
 
-
     def mktx(self, to_address, amount, fee = None, change_addr = None, domain = None):
         tx = self._mktx([(to_address, amount)], fee, change_addr, domain)
         return tx
@@ -323,7 +311,6 @@ class Commands:
         tx = self._mktx(outputs, fee, change_addr, domain)
         return tx
 
-
     def payto(self, to_address, amount, fee = None, change_addr = None, domain = None):
         tx = self._mktx([(to_address, amount)], fee, change_addr, domain)
         r, h = self.wallet.sendtx( tx )
@@ -334,9 +321,7 @@ class Commands:
         r, h = self.wallet.sendtx( tx )
         return h
 
-
     def history(self):
-        import datetime
         balance = 0
         out = []
         for item in self.wallet.get_tx_history():
@@ -351,20 +336,15 @@ class Commands:
             out.append({'txid':tx_hash, 'date':"%16s"%time_str, 'label':label, 'value':format_satoshis(value)})
         return out
 
-
-
     def setlabel(self, key, label):
         self.wallet.set_label(key, label)
 
-            
-
     def contacts(self):
         c = {}
         for addr in self.wallet.addressbook:
             c[addr] = self.wallet.labels.get(addr)
         return c
 
-
     def listaddresses(self, show_all = False, show_label = False):
         out = []
         for addr in self.wallet.addresses(True):
@@ -379,7 +359,7 @@ class Commands:
                     item = addr
                 out.append( item )
         return out
-                         
+
     def help(self, cmd=None):
         if cmd not in known_commands:
             print_msg("\nList of commands:", ', '.join(sorted(known_commands)))
@@ -390,9 +370,7 @@ class Commands:
             if cmd.options: print_msg("options:\n" + cmd.options)
         return None
 
-
     def getrawtransaction(self, tx_hash):
-        import transaction
         if self.wallet:
             tx = self.wallet.transactions.get(tx_hash)
             if tx:
@@ -400,17 +378,12 @@ class Commands:
 
         r = self.network.synchronous_get([ ('blockchain.transaction.get',[tx_hash]) ])[0]
         if r:
-            return transaction.Transaction(r)
+            return Transaction(r)
         else:
             return "unknown transaction"
 
-
     def encrypt(self, pubkey, message):
         return bitcoin.encrypt_message(message, pubkey)
 
-
     def decrypt(self, pubkey, message):
         return self.wallet.decrypt_message(pubkey, message, self.password)
-
-
-
index 69226da..58258d7 100644 (file)
 # along with this program. If not, see <http://www.gnu.org/licenses/>.
 
 import sys
-import base64
 import os
-import re
 import hashlib
-import copy
-import operator
 import ast
 import threading
 import random
-import aes
-import Queue
 import time
 import math
 
-from util import print_msg, print_error, format_satoshis
+from util import print_msg, print_error
+
 from bitcoin import *
 from account import *
-from transaction import Transaction, is_extended_pubkey
+from version import *
+
+from transaction import Transaction
 from plugins import run_hook
 import bitcoin
 from synchronizer import WalletSynchronizer
@@ -47,9 +44,6 @@ IMPORTED_ACCOUNT = '/x'
 
 
 
-from version import *
-
-
 class WalletStorage:
 
     def __init__(self, config):
@@ -109,7 +103,7 @@ class WalletStorage:
 
     def get(self, key, default=None):
         v = self.data.get(key)
-        if v is None: 
+        if v is None:
             v = default
         return v
 
@@ -120,7 +114,7 @@ class WalletStorage:
                 self.data[key] = value
             elif key in self.data:
                 self.data.pop(key)
-            if save: 
+            if save:
                 self.write()
 
     def write(self):
@@ -129,19 +123,13 @@ class WalletStorage:
         f.write( s )
         f.close()
         if 'ANDROID_DATA' not in os.environ:
-            import stat
+            import stat  #XXX: IS this really android only?
             os.chmod(self.path,stat.S_IREAD | stat.S_IWRITE)
 
 
-
-    
-
-        
-
 class Abstract_Wallet:
 
     def __init__(self, storage):
-
         self.storage = storage
         self.electrum_version = ELECTRUM_VERSION
         self.gap_limit_for_change = 3 # constant
@@ -198,16 +186,14 @@ class Abstract_Wallet:
         # there is a difference between wallet.up_to_date and interface.is_up_to_date()
         # interface.is_up_to_date() returns true when all requests have been answered and processed
         # wallet.up_to_date is true when the wallet is synchronized (stronger requirement)
-        
+
         self.up_to_date = False
         self.lock = threading.Lock()
         self.transaction_lock = threading.Lock()
         self.tx_event = threading.Event()
-
         for tx_hash, tx in self.transactions.items():
             self.update_tx_outputs(tx_hash)
 
-
     def add_extra_addresses(self, tx):
         h = tx.hash()
         # find the address corresponding to pay-to-pubkey inputs
@@ -217,11 +203,9 @@ class Abstract_Wallet:
                 for tx2 in self.transactions.values():
                     tx2.add_extra_addresses({h:tx})
 
-
     def get_action(self):
         pass
 
-
     def convert_imported_keys(self, password):
         for k, v in self.imported_keys.items():
             sec = pw_decode(v, password)
@@ -232,7 +216,6 @@ class Abstract_Wallet:
             self.imported_keys.pop(k)
         self.storage.put('imported_keys', self.imported_keys)
 
-
     def load_accounts(self):
         self.accounts = {}
         self.imported_keys = self.storage.get('imported_keys',{})
@@ -255,7 +238,6 @@ class Abstract_Wallet:
             else:
                 print_error("cannot load account", v)
 
-
     def synchronize(self):
         pass
 
@@ -268,15 +250,14 @@ class Abstract_Wallet:
     def is_up_to_date(self):
         with self.lock: return self.up_to_date
 
-
     def update(self):
         self.up_to_date = False
-        while not self.is_up_to_date(): 
+        while not self.is_up_to_date():
             time.sleep(0.1)
 
     def is_imported(self, addr):
         account = self.accounts.get(IMPORTED_ACCOUNT)
-        if account: 
+        if account:
             return addr in account.get_addresses(0)
         else:
             return False
@@ -294,16 +275,15 @@ class Abstract_Wallet:
 
         if self.is_mine(address):
             raise Exception('Address already in wallet')
-        
+
         if self.accounts.get(IMPORTED_ACCOUNT) is None:
             self.accounts[IMPORTED_ACCOUNT] = ImportedAccount({'imported':{}})
         self.accounts[IMPORTED_ACCOUNT].add(address, pubkey, sec, password)
         self.save_accounts()
-        
+
         if self.synchronizer:
             self.synchronizer.subscribe_to_addresses([address])
         return address
-        
 
     def delete_imported_key(self, addr):
         account = self.accounts[IMPORTED_ACCOUNT]
@@ -312,7 +292,6 @@ class Abstract_Wallet:
             self.accounts.pop(IMPORTED_ACCOUNT)
         self.save_accounts()
 
-
     def set_label(self, name, text = None):
         changed = False
         old_text = self.labels.get(name)
@@ -331,9 +310,6 @@ class Abstract_Wallet:
         run_hook('set_label', name, text, changed)
         return changed
 
-
-
-
     def addresses(self, include_change = True, _next=True):
         o = []
         for a in self.accounts.keys():
@@ -345,10 +321,8 @@ class Abstract_Wallet:
                     o += [addr]
         return o
 
-
     def is_mine(self, address):
-        return address in self.addresses(True) 
-
+        return address in self.addresses(True)
 
     def is_change(self, address):
         if not self.is_mine(address): return False
@@ -356,7 +330,6 @@ class Abstract_Wallet:
         if s is None: return False
         return s[0] == 1
 
-
     def get_address_index(self, address):
 
         for account in self.accounts.keys():
@@ -372,26 +345,22 @@ class Abstract_Wallet:
 
         raise Exception("Address not found", address)
 
-
     def getpubkeys(self, addr):
         assert is_valid(addr) and self.is_mine(addr)
         account, sequence = self.get_address_index(addr)
         a = self.accounts[account]
         return a.get_pubkeys( sequence )
 
-
     def get_private_key(self, address, password):
         if self.is_watching_only():
             return []
         account_id, sequence = self.get_address_index(address)
         return self.accounts[account_id].get_private_key(sequence, self, password)
 
-
     def get_public_keys(self, address):
         account_id, sequence = self.get_address_index(address)
         return self.accounts[account_id].get_pubkeys(sequence)
 
-
     def can_sign(self, tx):
 
         if self.is_watching_only():
@@ -411,15 +380,11 @@ class Abstract_Wallet:
                 return True
 
         return False
-            
-
 
     def add_keypairs(self, tx, keypairs, password):
-        # first check the provided password
-        seed = self.get_seed(password)
-
+        # first check the provided password. This will raise if invalid.
+        self.get_seed(password)
         addr_list, xpub_list = tx.inputs_to_sign()
-
         for addr in addr_list:
             if self.is_mine(addr):
                 private_keys = self.get_private_key(address, password)
@@ -441,12 +406,9 @@ class Abstract_Wallet:
                 pubkey = public_key_from_private_key(sec)
                 keypairs[pubkey] = sec
 
-
-
     def signrawtransaction(self, tx, private_keys, password):
-
-        # check that the password is correct
-        seed = self.get_seed(password)
+        # check that the password is correct. This will raise if it's not.
+        self.get_seed(password)
 
         # build a list of public/private keys
         keypairs = {}
@@ -462,7 +424,6 @@ class Abstract_Wallet:
         # sign the transaction
         self.sign_transaction(tx, keypairs, password)
 
-
     def sign_message(self, address, message, password):
         keys = self.get_private_key(address, password)
         assert len(keys) == 1
@@ -471,8 +432,6 @@ class Abstract_Wallet:
         compressed = is_compressed(sec)
         return key.sign_message(message, compressed, address)
 
-
-
     def decrypt_message(self, pubkey, message, password):
         address = public_key_to_bc_address(pubkey.decode('hex'))
         keys = self.get_private_key(address, password)
@@ -481,25 +440,20 @@ class Abstract_Wallet:
         decrypted = ec.decrypt_message(message)
         return decrypted
 
-
-
     def is_found(self):
-        return self.history.values() != [[]] * len(self.history) 
-
+        return self.history.values() != [[]] * len(self.history)
 
     def add_contact(self, address, label=None):
         self.addressbook.append(address)
         self.storage.put('contacts', self.addressbook, True)
-        if label:  
+        if label:
             self.set_label(address, label)
 
-
     def delete_contact(self, addr):
         if addr in self.addressbook:
             self.addressbook.remove(addr)
             self.storage.put('addressbook', self.addressbook, True)
 
-
     def fill_addressbook(self):
         for tx_hash, tx in self.transactions.items():
             is_relevant, is_send, _, _ = self.get_tx_value(tx)
@@ -511,23 +465,20 @@ class Abstract_Wallet:
         # self.update_tx_labels()
 
     def get_num_tx(self, address):
-        n = 0 
+        n = 0
         for tx in self.transactions.values():
             if address in map(lambda x:x[0], tx.outputs): n += 1
         return n
 
-
     def get_address_flags(self, addr):
-        flags = "C" if self.is_change(addr) else "I" if addr in self.imported_keys.keys() else "-" 
+        flags = "C" if self.is_change(addr) else "I" if addr in self.imported_keys.keys() else "-"
         flags += "F" if addr in self.frozen_addresses else "-"
         return flags
-        
 
     def get_tx_value(self, tx, account=None):
         domain = self.get_account_addresses(account)
         return tx.get_value(domain, self.prevout_values)
 
-    
     def update_tx_outputs(self, tx_hash):
         tx = self.transactions.get(tx_hash)
 
@@ -540,7 +491,6 @@ class Abstract_Wallet:
                 key = item['prevout_hash'] + ':%d'%item['prevout_n']
                 self.spent_outputs.append(key)
 
-
     def get_addr_balance(self, address):
         #assert self.is_mine(address)
         h = self.history.get(address,[])
@@ -567,7 +517,7 @@ class Abstract_Wallet:
                 if addr == address:
                     key = item['prevout_hash']  + ':%d'%item['prevout_n']
                     value = self.prevout_values.get( key )
-                    if key in received_coins: 
+                    if key in received_coins:
                         v -= value
 
             for i, (addr, value) in enumerate(tx.outputs):
@@ -581,18 +531,15 @@ class Abstract_Wallet:
                 u += v
         return c, u
 
-
     def get_account_name(self, k):
         return self.labels.get(k, self.accounts[k].get_name(k))
 
-
     def get_account_names(self):
         account_names = {}
         for k in self.accounts.keys():
             account_names[k] = self.get_account_name(k)
         return account_names
 
-
     def get_account_addresses(self, a, include_change=True):
         if a is None:
             o = self.addresses(True)
@@ -602,13 +549,12 @@ class Abstract_Wallet:
             if include_change: o += ac.get_addresses(1)
         return o
 
-
     def get_account_balance(self, account):
         return self.get_balance(self.get_account_addresses(account))
 
     def get_frozen_balance(self):
         return self.get_balance(self.frozen_addresses)
-        
+
     def get_balance(self, domain=None):
         if domain is None: domain = self.addresses(True)
         cc = uu = 0
@@ -618,7 +564,6 @@ class Abstract_Wallet:
             uu += u
         return cc, uu
 
-
     def get_unspent_coins(self, domain=None):
         coins = []
         if domain is None: domain = self.addresses(True)
@@ -643,11 +588,10 @@ class Abstract_Wallet:
         if coins:
             coins = sorted(coins)
             if coins[-1][0] != 0:
-                while coins[0][0] == 0: 
+                while coins[0][0] == 0:
                     coins = coins[1:] + [ coins[0] ]
         return [x[1] for x in coins]
 
-
     def choose_tx_inputs( self, amount, fixed_fee, num_outputs, domain = None, coins = None ):
         """ todo: minimize tx size """
         total = 0
@@ -665,7 +609,6 @@ class Abstract_Wallet:
         for item in coins:
             if item.get('coinbase') and item.get('height') + COINBASE_MATURITY > self.network.get_local_height():
                 continue
-            addr = item.get('address')
             v = item.get('value')
             total += v
             inputs.append(item)
@@ -676,18 +619,16 @@ class Abstract_Wallet:
 
         return inputs, total, fee
 
-
     def set_fee(self, fee):
         if self.fee != fee:
             self.fee = fee
             self.storage.put('fee_per_kb', self.fee, True)
-        
+
     def estimated_fee(self, inputs, num_outputs):
         estimated_size =  len(inputs) * 180 + num_outputs * 34    # this assumes non-compressed keys
         fee = self.fee * int(math.ceil(estimated_size/1000.))
         return fee
 
-
     def add_tx_change( self, inputs, outputs, amount, fee, total, change_addr=None):
         "add change to a transaction"
         change_amount = total - ( amount + fee )
@@ -708,12 +649,10 @@ class Abstract_Wallet:
             outputs[posn:posn] = [( change_addr,  change_amount)]
         return outputs
 
-
     def get_history(self, address):
         with self.lock:
             return self.history.get(address)
 
-
     def get_status(self, h):
         if not h: return None
         if h == ['*']: return '*'
@@ -722,7 +661,6 @@ class Abstract_Wallet:
             status += tx_hash + ':%d:' % height
         return hashlib.sha256( status ).digest().encode('hex')
 
-
     def receive_tx_callback(self, tx_hash, tx, tx_height):
 
         with self.transaction_lock:
@@ -734,11 +672,10 @@ class Abstract_Wallet:
             self.transactions[tx_hash] = tx
             self.network.pending_transactions_for_notifications.append(tx)
             self.save_transactions()
-            if self.verifier and tx_height>0: 
+            if self.verifier and tx_height>0:
                 self.verifier.add(tx_hash, tx_height)
             self.update_tx_outputs(tx_hash)
 
-
     def save_transactions(self):
         tx = {}
         for k,v in self.transactions.items():
@@ -749,7 +686,7 @@ class Abstract_Wallet:
 
         if not self.check_new_history(addr, hist):
             raise Exception("error: received history for %s is not consistent with known transactions"%addr)
-            
+
         with self.lock:
             self.history[addr] = hist
             self.storage.put('addr_history', self.history, True)
@@ -760,7 +697,6 @@ class Abstract_Wallet:
                     # add it in case it was previously unconfirmed
                     if self.verifier: self.verifier.add(tx_hash, tx_height)
 
-
     def get_tx_history(self, account=None):
         if not self.verifier:
             return []
@@ -769,7 +705,7 @@ class Abstract_Wallet:
             history = self.transactions.items()
             history.sort(key = lambda x: self.verifier.get_txpos(x[0]))
             result = []
-    
+
             balance = 0
             for tx_hash, tx in history:
                 is_relevant, is_mine, v, fee = self.get_tx_value(tx, account)
@@ -793,14 +729,12 @@ class Abstract_Wallet:
 
         return result
 
-
     def get_label(self, tx_hash):
         label = self.labels.get(tx_hash)
         is_default = (label == '') or (label is None)
         if is_default: label = self.get_default_label(tx_hash)
         return label, is_default
 
-
     def get_default_label(self, tx_hash):
         tx = self.transactions.get(tx_hash)
         default_label = ''
@@ -831,7 +765,6 @@ class Abstract_Wallet:
                         o_addr = None
 
                 if o_addr:
-                    dest_label = self.labels.get(o_addr)
                     try:
                         default_label = self.labels[o_addr]
                     except KeyError:
@@ -839,7 +772,6 @@ class Abstract_Wallet:
 
         return default_label
 
-
     def make_unsigned_transaction(self, outputs, fee=None, change_addr=None, domain=None, coins=None ):
         for address, x in outputs:
             assert is_valid(address), "Address " + address + " is invalid!"
@@ -852,7 +784,6 @@ class Abstract_Wallet:
         outputs = self.add_tx_change(inputs, outputs, amount, fee, total, change_addr)
         return Transaction.from_io(inputs, outputs)
 
-
     def mktx(self, outputs, password, fee=None, change_addr=None, domain= None, coins = None ):
         tx = self.make_unsigned_transaction(outputs, fee, change_addr, domain, coins)
         keypairs = {}
@@ -861,7 +792,6 @@ class Abstract_Wallet:
             self.sign_transaction(tx, keypairs, password)
         return tx
 
-
     def add_input_info(self, txin):
         address = txin['address']
         account_id, sequence = self.get_address_index(address)
@@ -871,19 +801,17 @@ class Abstract_Wallet:
         txin['pubkeys'] = pubkeys = account.get_pubkeys(sequence)
         txin['signatures'] = [None] * len(pubkeys)
 
-        if redeemScript: 
+        if redeemScript:
             txin['redeemScript'] = redeemScript
             txin['num_sig'] = 2
         else:
             txin['redeemPubkey'] = account.get_pubkey(*sequence)
             txin['num_sig'] = 1
 
-
     def sign_transaction(self, tx, keypairs, password):
         tx.sign(keypairs)
         run_hook('sign_transaction', tx, password)
 
-
     def sendtx(self, tx):
         # synchronous
         h = self.send_tx(tx)
@@ -901,15 +829,14 @@ class Abstract_Wallet:
         self.tx_event.set()
 
     def receive_tx(self, tx_hash, tx):
-        out = self.tx_result 
+        out = self.tx_result
         if out != tx_hash:
             return False, "error: " + out
         run_hook('receive_tx', tx, self)
         return True, out
 
-
     def update_password(self, old_password, new_password):
-        if new_password == '': 
+        if new_password == '':
             new_password = None
 
         if self.has_seed():
@@ -918,7 +845,7 @@ class Abstract_Wallet:
             self.storage.put('seed', self.seed, True)
 
         imported_account = self.accounts.get(IMPORTED_ACCOUNT)
-        if imported_account: 
+        if imported_account:
             imported_account.update_password(old_password, new_password)
             self.save_accounts()
 
@@ -931,7 +858,6 @@ class Abstract_Wallet:
         self.use_encryption = (new_password != None)
         self.storage.put('use_encryption', self.use_encryption,True)
 
-
     def freeze(self,addr):
         if self.is_mine(addr) and addr not in self.frozen_addresses:
             self.frozen_addresses.append(addr)
@@ -940,7 +866,6 @@ class Abstract_Wallet:
         else:
             return False
 
-
     def unfreeze(self,addr):
         if self.is_mine(addr) and addr in self.frozen_addresses:
             self.frozen_addresses.remove(addr)
@@ -949,7 +874,6 @@ class Abstract_Wallet:
         else:
             return False
 
-
     def set_verifier(self, verifier):
         self.verifier = verifier
 
@@ -967,9 +891,7 @@ class Abstract_Wallet:
             if tx_hash not in vr:
                 self.transactions.pop(tx_hash)
 
-
     def check_new_history(self, addr, hist):
-        
         # check that all tx in hist are relevant
         if hist != ['*']:
             for tx_hash, height in hist:
@@ -997,7 +919,7 @@ class Abstract_Wallet:
                 tx = self.transactions.get(tx_hash)
                 # tx might not be there
                 if not tx: continue
-                
+
                 # already verified?
                 if self.verifier.get_height(tx_hash):
                     continue
@@ -1026,14 +948,13 @@ class Abstract_Wallet:
 
         return True
 
-
     def check_new_tx(self, tx_hash, tx):
-        # 1 check that tx is referenced in addr_history. 
+        # 1 check that tx is referenced in addr_history.
         addresses = []
         for addr, hist in self.history.items():
             if hist == ['*']:continue
             for txh, height in hist:
-                if txh == tx_hash: 
+                if txh == tx_hash:
                     addresses.append(addr)
 
         if not addresses:
@@ -1046,7 +967,6 @@ class Abstract_Wallet:
 
         return True
 
-
     def start_threads(self, network):
         from verifier import TxVerifier
         self.network = network
@@ -1084,7 +1004,7 @@ class Abstract_Wallet:
         h = self.history.get(address,[])
         c, u = self.get_addr_balance(address)
         return len(h), len(h) > 0 and c == -u
-    
+
 
 class Imported_Wallet(Abstract_Wallet):
 
@@ -1095,7 +1015,6 @@ class Imported_Wallet(Abstract_Wallet):
             self.accounts[IMPORTED_ACCOUNT] = ImportedAccount({'imported':{}})
         self.storage.put('wallet_type', 'imported', True)
 
-
     def is_watching_only(self):
         acc = self.accounts[IMPORTED_ACCOUNT]
         n = acc.keypairs.values()
@@ -1130,11 +1049,11 @@ class Deterministic_Wallet(Abstract_Wallet):
         return not self.has_seed()
 
     def add_seed(self, seed, password):
-        if self.seed: 
+        if self.seed:
             raise Exception("a seed exists")
-        
+
         self.seed_version, self.seed = self.prepare_seed(seed)
-        if password: 
+        if password:
             self.seed = pw_encode( self.seed, password)
             self.use_encryption = True
         else:
@@ -1150,7 +1069,7 @@ class Deterministic_Wallet(Abstract_Wallet):
 
     def get_mnemonic(self, password):
         return self.get_seed(password)
-        
+
     def change_gap_limit(self, value):
         if value >= self.gap_limit:
             self.gap_limit = value
@@ -1196,7 +1115,6 @@ class Deterministic_Wallet(Abstract_Wallet):
                     if n > nmax: nmax = n
         return nmax + 1
 
-
     def address_is_old(self, address):
         age = -1
         h = self.history.get(address, [])
@@ -1211,7 +1129,6 @@ class Deterministic_Wallet(Abstract_Wallet):
                 age = tx_age
         return age > 2
 
-
     def synchronize_sequence(self, account, for_change):
         limit = self.gap_limit_for_change if for_change else self.gap_limit
         new_addresses = []
@@ -1231,7 +1148,6 @@ class Deterministic_Wallet(Abstract_Wallet):
                 new_addresses.append( address )
 
         return new_addresses
-        
 
     def check_pending_accounts(self):
         for account_id, addr in self.next_addresses.items():
@@ -1242,14 +1158,12 @@ class Deterministic_Wallet(Abstract_Wallet):
                 self.add_account(account_id, account)
                 self.next_addresses.pop(account_id)
 
-
     def synchronize_account(self, account):
         new = []
         new += self.synchronize_sequence(account, 0)
         new += self.synchronize_sequence(account, 1)
         return new
 
-
     def synchronize(self):
         self.check_pending_accounts()
         new = []
@@ -1262,7 +1176,6 @@ class Deterministic_Wallet(Abstract_Wallet):
             self.storage.put('addr_history', self.history, True)
         return new
 
-
     def restore(self, callback):
         from i18n import _
         def wait_for_wallet():
@@ -1271,8 +1184,8 @@ class Deterministic_Wallet(Abstract_Wallet):
                 msg = "%s\n%s %d\n%s %.1f"%(
                     _("Please wait..."),
                     _("Addresses generated:"),
-                    len(self.addresses(True)), 
-                    _("Kilobytes received:"), 
+                    len(self.addresses(True)),
+                    _("Kilobytes received:"),
                     self.network.interface.bytes_received/1024.)
 
                 apply(callback, (msg,))
@@ -1290,10 +1203,8 @@ class Deterministic_Wallet(Abstract_Wallet):
             wait_for_wallet()
         else:
             self.synchronize()
-            
         self.fill_addressbook()
 
-
     def create_account(self, name, password):
         i = self.num_accounts()
         account_id = self.account_id(i)
@@ -1310,8 +1221,6 @@ class Deterministic_Wallet(Abstract_Wallet):
         self.accounts[account_id] = account
         self.save_accounts()
 
-
-
     def account_is_pending(self, k):
         return type(self.accounts.get(k)) == PendingAccount
 
@@ -1327,8 +1236,6 @@ class Deterministic_Wallet(Abstract_Wallet):
         self.save_accounts()
 
 
-
-
 class NewWallet(Deterministic_Wallet):
 
     def __init__(self, storage):
@@ -1365,25 +1272,22 @@ class NewWallet(Deterministic_Wallet):
         account = BIP32_Account({'xpub':xpub})
         self.add_account("m/", account)
 
-
     def create_accounts(self, password):
-        seed = pw_decode(self.seed, password)
+        # First check the password is valid (this raises if it isn't).
+        pw_decode(self.seed, password)
         self.create_account('Main account', password)
 
-
     def add_master_public_key(self, name, mpk):
         self.master_public_keys[name] = mpk
         self.storage.put('master_public_keys', self.master_public_keys, True)
 
-
     def add_master_private_key(self, name, xpriv, password):
         self.master_private_keys[name] = pw_encode(xpriv, password)
         self.storage.put('master_private_keys', self.master_private_keys, True)
 
-
     def add_master_keys(self, root, account_id, password):
         x = self.master_private_keys.get(root)
-        if x: 
+        if x:
             master_xpriv = pw_decode(x, password )
             xpriv, xpub = bip32_private_derivation(master_xpriv, root, account_id)
             self.add_master_public_key(account_id, xpub)
@@ -1394,20 +1298,17 @@ class NewWallet(Deterministic_Wallet):
             self.add_master_public_key(account_id, xpub)
         return xpub
 
-
     def create_master_keys(self, password):
         xpriv, xpub = bip32_root(mnemonic_to_seed(self.get_seed(password),'').encode('hex'))
         self.add_master_public_key("m/", xpub)
         self.add_master_private_key("m/", xpriv, password)
 
-
     def find_root_by_master_key(self, xpub):
         for key, xpub2 in self.master_public_keys.items():
             if key == "m/":continue
             if xpub == xpub2:
                 return key
 
-
     def num_accounts(self):
         keys = []
         for k, v in self.accounts.items():
@@ -1422,13 +1323,12 @@ class NewWallet(Deterministic_Wallet):
             i += 1
         return i
 
-
     def next_account_address(self, password):
         i = self.num_accounts()
         account_id = self.account_id(i)
 
         addr = self.next_addresses.get(account_id)
-        if not addr: 
+        if not addr:
             account = self.make_account(account_id, password)
             addr = account.first_address()
             self.next_addresses[account_id] = addr
@@ -1445,7 +1345,6 @@ class NewWallet(Deterministic_Wallet):
         account = BIP32_Account({'xpub':xpub})
         return account
 
-
     def make_seed(self):
         import mnemonic, ecdsa
         entropy = ecdsa.util.randrange( pow(2,160) )
@@ -1454,7 +1353,7 @@ class NewWallet(Deterministic_Wallet):
             ss = "%040x"%(entropy+nonce)
             s = hashlib.sha256(ss.decode('hex')).digest().encode('hex')
             # we keep only 13 words, that's approximately 139 bits of entropy
-            words = mnemonic.mn_encode(s)[0:13] 
+            words = mnemonic.mn_encode(s)[0:13]
             seed = ' '.join(words)
             if is_new_seed(seed):
                 break  # this will remove 8 bits of entropy
@@ -1466,8 +1365,8 @@ class NewWallet(Deterministic_Wallet):
         return NEW_SEED_VERSION, unicodedata.normalize('NFC', unicode(seed.strip()))
 
 
-
 class Wallet_2of2(NewWallet):
+    """ This class is used for multisignature addresses"""
 
     def __init__(self, storage):
         NewWallet.__init__(self, storage)
@@ -1499,8 +1398,8 @@ class Wallet_2of2(NewWallet):
             return 'create_2of2_2'
 
 
-
 class Wallet_2of3(Wallet_2of2):
+    """ This class is used for multisignature addresses"""
 
     def __init__(self, storage):
         Wallet_2of2.__init__(self, storage)
@@ -1532,9 +1431,6 @@ class Wallet_2of3(Wallet_2of2):
             return 'create_2of3_2'
 
 
-
-
-
 class OldWallet(Deterministic_Wallet):
 
     def make_seed(self):
@@ -1557,9 +1453,8 @@ class OldWallet(Deterministic_Wallet):
         seed = mnemonic.mn_decode(words)
         if not seed:
             raise Exception("Invalid seed")
-            
-        return OLD_SEED_VERSION, seed
 
+        return OLD_SEED_VERSION, seed
 
     def create_master_keys(self, password):
         seed = self.get_seed(password)
@@ -1605,6 +1500,9 @@ class OldWallet(Deterministic_Wallet):
 
 # former WalletFactory
 class Wallet(object):
+    """The main wallet "entry point".
+    This class is actually a factory that will return a wallet of the correct
+    type when passed a WalletStorage instance."""
 
     def __new__(self, storage):
         config = storage.config
@@ -1623,7 +1521,6 @@ class Wallet(object):
         if storage.get('wallet_type') == 'imported':
             return Imported_Wallet(storage)
 
-
         if not storage.file_exists:
             seed_version = NEW_SEED_VERSION if config.get('bip32') is True else OLD_SEED_VERSION
         else:
@@ -1642,8 +1539,6 @@ class Wallet(object):
             print msg
             sys.exit(1)
 
-
-
     @classmethod
     def is_seed(self, seed):
         if not seed:
@@ -1652,7 +1547,7 @@ class Wallet(object):
             return True
         elif is_new_seed(seed):
             return True
-        else: 
+        else:
             return False
 
     @classmethod
@@ -1662,7 +1557,7 @@ class Wallet(object):
             old = True
         except:
             old = False
-            
+
         if old:
             return len(mpk) == 128
         else:
@@ -1716,7 +1611,6 @@ class Wallet(object):
 
     @classmethod
     def from_mpk(self, mpk, storage):
-
         try:
             int(mpk, 16)
             old = True