From a5168cc09f9f3303c283eb6c72ff031098566e69 Mon Sep 17 00:00:00 2001 From: thomasv Date: Sat, 23 Mar 2013 09:23:57 +0100 Subject: [PATCH 01/17] more accurate computation of transaction fees. --- electrum | 2 +- gui/gui_classic.py | 8 ++++++-- gui/gui_gtk.py | 7 ++++++- lib/bitcoin.py | 12 ++++++++++++ lib/wallet.py | 12 +++++++++--- 5 files changed, 34 insertions(+), 7 deletions(-) diff --git a/electrum b/electrum index 28e30533..15fcb60d 100755 --- a/electrum +++ b/electrum @@ -72,7 +72,7 @@ def arg_parser(): parser.add_option("-a", "--all", action="store_true", dest="show_all", default=False, help="show all addresses") parser.add_option("-b", "--balance", action="store_true", dest="show_balance", default=False, help="show the balance of listed 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="0.005", help="set tx fee") + parser.add_option("-f", "--fee", dest="tx_fee", default=None, help="set tx fee") parser.add_option("-F", "--fromaddr", dest="from_addr", default=None, help="set source address for payto/mktx. if it isn't in the wallet, it will ask for the private key unless supplied in the format public_key:private_key. It's not saved in the wallet.") parser.add_option("-c", "--changeaddr", dest="change_addr", default=None, help="set the change address for payto/mktx. default is a spare address, or the source address if it's not in the wallet") parser.add_option("-s", "--server", dest="server", default=None, help="set server host:port:protocol, where protocol is t or h") diff --git a/gui/gui_classic.py b/gui/gui_classic.py index 5c48205d..b44d0c80 100644 --- a/gui/gui_classic.py +++ b/gui/gui_classic.py @@ -795,6 +795,10 @@ class ElectrumWindow(QMainWindow): self.show_message(str(e)) return + if tx.requires_fee(self.wallet.verifier) and fee == 0: + QMessageBox.warning(self, _('Error'), _("This transaction requires a fee, or it will not be propagated by the network."), _('OK')) + return + self.run_hook('send_tx', tx) if label: @@ -1928,8 +1932,8 @@ class ElectrumWindow(QMainWindow): fee_e = QLineEdit() fee_e.setText("%s"% str( Decimal( self.wallet.fee)/100000000 ) ) grid_wallet.addWidget(fee_e, 0, 2) - msg = _('Fee per transaction input. Transactions involving multiple inputs tend to require a higher fee.') + ' ' \ - + _('Recommended value') + ': 0.001' + msg = _('Fee per kilobyte of transaction.') + ' ' \ + + _('Recommended value') + ': 0.0001' grid_wallet.addWidget(HelpButton(msg), 0, 3) fee_e.textChanged.connect(lambda: numbify(fee_e,False)) if not self.config.is_modifiable('fee'): diff --git a/gui/gui_gtk.py b/gui/gui_gtk.py index 8568f7f5..d3261ded 100644 --- a/gui/gui_gtk.py +++ b/gui/gui_gtk.py @@ -198,7 +198,7 @@ def run_settings_dialog(wallet, parent): fee_entry.connect('changed', numbify, False) fee_entry.show() fee.pack_start(fee_entry,False,False, 10) - add_help_button(fee, 'Fee per transaction input. Transactions involving multiple inputs tend to have a higher fee. Recommended value:0.0005') + add_help_button(fee, 'Fee per kilobyte of transaction. Recommended value:0.0001') fee.show() vbox.pack_start(fee, False,False, 5) @@ -843,6 +843,11 @@ class ElectrumWindow: except BaseException, e: self.show_message(str(e)) return + + if tx.requires_fee(self.wallet.verifier) and fee == 0: + self.show_message( "This transaction requires a fee, or it will not be propagated by the network." ) + return + if label: self.wallet.labels[tx.hash()] = label diff --git a/lib/bitcoin.py b/lib/bitcoin.py index 6a8c4864..0b87b784 100644 --- a/lib/bitcoin.py +++ b/lib/bitcoin.py @@ -876,6 +876,18 @@ class Transaction: return out + def requires_fee(self, verifier): + threshold = 57600000 + size = len(self.raw)/2 + sum = 0 + for i in self.inputs: + age = verifier.get_confirmations(i["tx_hash"])[0] + sum += i["value"] * age + priority = sum / size + print_error(priority, threshold) + return priority < threshold + + def test_bip32(): diff --git a/lib/wallet.py b/lib/wallet.py index fee23d32..46531ffb 100644 --- a/lib/wallet.py +++ b/lib/wallet.py @@ -74,7 +74,7 @@ class Wallet: self.seed_version = config.get('seed_version', SEED_VERSION) self.gap_limit = config.get('gap_limit', 5) self.use_change = config.get('use_change',True) - self.fee = int(config.get('fee',100000)) + self.fee = int(config.get('fee',10000)) self.num_zeros = int(config.get('num_zeros',0)) self.use_encryption = config.get('use_encryption', False) self.seed = config.get('seed', '') # encrypted @@ -565,14 +565,20 @@ class Wallet: total += v inputs.append( item ) - fee = self.fee*len(inputs) if fixed_fee is None else fixed_fee + if fixed_fee is None: + estimated_size = len(inputs) * 180 + 80 # this assumes non-compressed keys + fee = self.fee * round(estimated_size/1024.) + if fee == 0: fee = self.fee + else: + fee = fixed_fee if total >= amount + fee: break else: - #print "not enough funds: %s %s"%(format_satoshis(total), format_satoshis(fee)) inputs = [] return inputs, total, fee + + def add_tx_change( self, outputs, amount, fee, total, change_addr=None ): change_amount = total - ( amount + fee ) if change_amount != 0: From cac030e2eed35fd5aba944b0293c62e6ec7f6e7d Mon Sep 17 00:00:00 2001 From: ecdsa Date: Sat, 23 Mar 2013 18:10:09 +0100 Subject: [PATCH 02/17] fix transaction order in history --- lib/verifier.py | 11 ++++++----- lib/wallet.py | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/verifier.py b/lib/verifier.py index 81a76619..913aa2f0 100644 --- a/lib/verifier.py +++ b/lib/verifier.py @@ -35,7 +35,7 @@ class WalletVerifier(threading.Thread): self.transactions = {} # requested verifications (with height sent by the requestor) self.interface.register_channel('verifier') - self.verified_tx = config.get('verified_tx2',{}) # height, timestamp of verified transactions + self.verified_tx = config.get('verified_tx3',{}) # height, timestamp of verified transactions self.merkle_roots = config.get('merkle_roots',{}) # hashed by me self.targets = config.get('targets',{}) # compute targets @@ -50,7 +50,7 @@ class WalletVerifier(threading.Thread): """ return the number of confirmations of a monitored transaction. """ with self.lock: if tx in self.verified_tx: - height, timestamp = self.verified_tx[tx] + height, timestamp, pos = self.verified_tx[tx] conf = (self.local_height - height + 1) else: conf = 0 @@ -183,7 +183,8 @@ class WalletVerifier(threading.Thread): def verify_merkle(self, tx_hash, result): tx_height = result.get('block_height') - self.merkle_roots[tx_hash] = self.hash_merkle_root(result['merkle'], tx_hash, result.get('pos')) + pos = result.get('pos') + self.merkle_roots[tx_hash] = self.hash_merkle_root(result['merkle'], tx_hash, pos) header = self.read_header(tx_height) if not header: return assert header.get('merkle_root') == self.merkle_roots[tx_hash] @@ -191,9 +192,9 @@ class WalletVerifier(threading.Thread): header = self.read_header(tx_height) timestamp = header.get('timestamp') with self.lock: - self.verified_tx[tx_hash] = (tx_height, timestamp) + self.verified_tx[tx_hash] = (tx_height, timestamp, pos) print_error("verified %s"%tx_hash) - self.config.set_key('verified_tx2', self.verified_tx, True) + self.config.set_key('verified_tx3', self.verified_tx, True) self.interface.trigger_callback('updated') diff --git a/lib/wallet.py b/lib/wallet.py index 46531ffb..6e9cd857 100644 --- a/lib/wallet.py +++ b/lib/wallet.py @@ -644,7 +644,7 @@ class Wallet: def get_tx_history(self): with self.lock: history = self.transactions.items() - history.sort(key = lambda x: self.verifier.get_height(x[0]) if self.verifier.get_height(x[0]) else 1e12) + history.sort(key = lambda x: self.verifier.verified_tx.get(x[0]) if self.verifier.verified_tx.get(x[0]) else (1e12,0,0)) result = [] balance = 0 From 3dc967782290198467b07088b7ec63dace3e6bf0 Mon Sep 17 00:00:00 2001 From: ecdsa Date: Sat, 23 Mar 2013 19:17:11 +0100 Subject: [PATCH 03/17] remove receipt code --- lib/wallet.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/wallet.py b/lib/wallet.py index 6e9cd857..eb7de887 100644 --- a/lib/wallet.py +++ b/lib/wallet.py @@ -103,7 +103,6 @@ class Wallet: # not saved self.prevout_values = {} # my own transaction outputs self.spent_outputs = [] - self.receipt = None # next receipt # spv self.verifier = None @@ -774,9 +773,6 @@ class Wallet: out = self.tx_result if out != tx_hash: return False, "error: " + out - if self.receipt: - self.receipts[tx_hash] = self.receipt - self.receipt = None return True, out From 29b9ffac4a3c7d4b353559cd5e580879f0fb17c7 Mon Sep 17 00:00:00 2001 From: ecdsa Date: Sun, 24 Mar 2013 07:34:28 +0100 Subject: [PATCH 04/17] transaction lock --- lib/wallet.py | 52 +++++++++++++++++++++++++-------------------------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/lib/wallet.py b/lib/wallet.py index eb7de887..c9eea98b 100644 --- a/lib/wallet.py +++ b/lib/wallet.py @@ -113,6 +113,7 @@ class Wallet: self.up_to_date = False self.lock = threading.Lock() + self.transaction_lock = threading.Lock() self.tx_event = threading.Event() if self.seed_version != SEED_VERSION: @@ -432,8 +433,7 @@ class Wallet: for item in tx.outputs: addr, value = item key = tx_hash+ ':%d'%i - with self.lock: - self.prevout_values[key] = value + self.prevout_values[key] = value i += 1 for item in tx.inputs: @@ -607,19 +607,17 @@ class Wallet: def receive_tx_callback(self, tx_hash, tx, tx_height): + if not self.check_new_tx(tx_hash, tx): # may happen due to pruning print_error("received transaction that is no longer referenced in history", tx_hash) return - with self.lock: + with self.transaction_lock: self.transactions[tx_hash] = tx - - #tx_height = tx.get('height') - if self.verifier and tx_height>0: - self.verifier.add(tx_hash, tx_height) - - self.update_tx_outputs(tx_hash) + if self.verifier and tx_height>0: + self.verifier.add(tx_hash, tx_height) + self.update_tx_outputs(tx_hash) self.save() @@ -641,29 +639,29 @@ class Wallet: def get_tx_history(self): - with self.lock: + with self.transaction_lock: history = self.transactions.items() - history.sort(key = lambda x: self.verifier.verified_tx.get(x[0]) if self.verifier.verified_tx.get(x[0]) else (1e12,0,0)) - result = [] + history.sort(key = lambda x: self.verifier.verified_tx.get(x[0]) if self.verifier.verified_tx.get(x[0]) else (1e12,0,0)) + result = [] - balance = 0 - for tx_hash, tx in history: - is_mine, v, fee = self.get_tx_value(tx) - if v is not None: balance += v - c, u = self.get_balance() + balance = 0 + for tx_hash, tx in history: + is_mine, v, fee = self.get_tx_value(tx) + if v is not None: balance += v + c, u = self.get_balance() - if balance != c+u: - v_str = format_satoshis( c+u - balance, True, self.num_zeros) - result.append( ('', 1000, 0, c+u-balance, None, c+u-balance, None ) ) + if balance != c+u: + v_str = format_satoshis( c+u - balance, True, self.num_zeros) + result.append( ('', 1000, 0, c+u-balance, None, c+u-balance, None ) ) - balance = c + u - balance - for tx_hash, tx in history: - conf, timestamp = self.verifier.get_confirmations(tx_hash) if self.verifier else (None, None) - is_mine, value, fee = self.get_tx_value(tx) - if value is not None: - balance += value + balance = c + u - balance + for tx_hash, tx in history: + conf, timestamp = self.verifier.get_confirmations(tx_hash) if self.verifier else (None, None) + is_mine, value, fee = self.get_tx_value(tx) + if value is not None: + balance += value - result.append( (tx_hash, conf, is_mine, value, fee, balance, timestamp) ) + result.append( (tx_hash, conf, is_mine, value, fee, balance, timestamp) ) return result From 3ad453fafbfbeafedfa1181800099148cabf530f Mon Sep 17 00:00:00 2001 From: ecdsa Date: Sun, 24 Mar 2013 09:24:45 +0100 Subject: [PATCH 05/17] rename fee to fee_per_kb --- gui/gui_classic.py | 2 +- gui/gui_text.py | 4 ++-- lib/wallet.py | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gui/gui_classic.py b/gui/gui_classic.py index b44d0c80..c536450c 100644 --- a/gui/gui_classic.py +++ b/gui/gui_classic.py @@ -1936,7 +1936,7 @@ class ElectrumWindow(QMainWindow): + _('Recommended value') + ': 0.0001' grid_wallet.addWidget(HelpButton(msg), 0, 3) fee_e.textChanged.connect(lambda: numbify(fee_e,False)) - if not self.config.is_modifiable('fee'): + if not self.config.is_modifiable('fee_per_kb'): for w in [fee_e, fee_label]: w.setEnabled(False) usechange_label = QLabel(_('Use change addresses')) diff --git a/gui/gui_text.py b/gui/gui_text.py index 77d70bed..58c67329 100644 --- a/gui/gui_text.py +++ b/gui/gui_text.py @@ -318,14 +318,14 @@ class ElectrumGui: def settings_dialog(self): out = self.run_dialog('Settings', [ {'label':'Default GUI', 'type':'list', 'choices':['classic','lite','gtk','text'], 'value':self.config.get('gui')}, - {'label':'Default fee', 'type':'satoshis', 'value': format_satoshis(self.config.get('fee')).strip() } + {'label':'Default fee', 'type':'satoshis', 'value': format_satoshis(self.config.get('fee_per_kb')).strip() } ], buttons = 1) if out: if out.get('Default GUI'): self.config.set_key('gui', out['Default GUI'], True) if out.get('Default fee'): fee = int ( Decimal( out['Default fee']) *10000000 ) - self.config.set_key('fee', fee, True) + self.config.set_key('fee_per_kb', fee, True) def password_dialog(self): diff --git a/lib/wallet.py b/lib/wallet.py index c9eea98b..da44b7d8 100644 --- a/lib/wallet.py +++ b/lib/wallet.py @@ -74,7 +74,7 @@ class Wallet: self.seed_version = config.get('seed_version', SEED_VERSION) self.gap_limit = config.get('gap_limit', 5) self.use_change = config.get('use_change',True) - self.fee = int(config.get('fee',10000)) + self.fee = int(config.get('fee_per_kb',10000)) self.num_zeros = int(config.get('num_zeros',0)) self.use_encryption = config.get('use_encryption', False) self.seed = config.get('seed', '') # encrypted @@ -831,7 +831,7 @@ class Wallet: s = { 'use_encryption': self.use_encryption, 'use_change': self.use_change, - 'fee': self.fee, + 'fee_per_kb': self.fee, 'accounts': self.accounts, 'addr_history': self.history, 'labels': self.labels, From 678b00dbec61743a07660b69c73e890a7edbce89 Mon Sep 17 00:00:00 2001 From: ecdsa Date: Sun, 24 Mar 2013 09:52:36 +0100 Subject: [PATCH 06/17] prune unverified transactinos during upgrade --- lib/wallet.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/wallet.py b/lib/wallet.py index da44b7d8..2d88668f 100644 --- a/lib/wallet.py +++ b/lib/wallet.py @@ -859,6 +859,12 @@ class Wallet: self.verifier.add(tx_hash, tx_height) + # if we are on a pruning server, remove unverified transactions + vr = self.verifier.transactions.keys() + self.verifier.verified_tx.keys() + for tx_hash in self.transactions.keys(): + if tx_hash not in vr: + self.transactions.pop(tx_hash) + def check_new_history(self, addr, hist): From de699150899fdaa6a735a310915ee1e2361d509c Mon Sep 17 00:00:00 2001 From: ecdsa Date: Sun, 24 Mar 2013 09:56:21 +0100 Subject: [PATCH 07/17] version 1.7.2 --- lib/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/version.py b/lib/version.py index 2c577e67..bfd43c5e 100644 --- a/lib/version.py +++ b/lib/version.py @@ -1,4 +1,4 @@ -ELECTRUM_VERSION = "1.7.1" # version of the client package +ELECTRUM_VERSION = "1.7.2" # version of the client package PROTOCOL_VERSION = '0.6' # protocol version requested SEED_VERSION = 4 # bump this every time the seed generation is modified TRANSLATION_ID = 3992 # version of the wiki page From 70e82e99eaf93e4cd26b62ff8ac2b80a080ad28c Mon Sep 17 00:00:00 2001 From: ecdsa Date: Sun, 24 Mar 2013 10:08:39 +0100 Subject: [PATCH 08/17] release notes for 1.7.2 --- RELEASE-NOTES | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 86db7b1b..caba1f92 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,3 +1,15 @@ + +# Release 1.7.2: + +* Transactions that belong in the same block are displayed in chronological order in the history. +* The client computes transaction priority and rejects zero-fee transactions that need a fee. +* The default fee was lowered to 100 uBTC per kb. +* Due to an internal format change, your history may be pruned when + you open your wallet for the first time after upgrading to 1.7.2. If + this is the case, please visit a full server to restore your full + history. You will only need to do that once. + + # Release 1.7.1: bugfixes. From fc7122008a877587e716b537a3efa15588bfb296 Mon Sep 17 00:00:00 2001 From: ecdsa Date: Sun, 24 Mar 2013 11:25:17 +0100 Subject: [PATCH 09/17] implement MIN_RELAY_TX_FEE --- gui/gui_classic.py | 5 +++-- gui/gui_gtk.py | 5 +++-- lib/bitcoin.py | 11 ++++++++++- lib/wallet.py | 1 + 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/gui/gui_classic.py b/gui/gui_classic.py index c536450c..585c4b4d 100644 --- a/gui/gui_classic.py +++ b/gui/gui_classic.py @@ -32,6 +32,7 @@ from PyQt4.QtCore import * import PyQt4.QtCore as QtCore import PyQt4.QtGui as QtGui from electrum.interface import DEFAULT_SERVERS +from electrum.bitcoin import MIN_RELAY_TX_FEE try: import icons_rc @@ -795,8 +796,8 @@ class ElectrumWindow(QMainWindow): self.show_message(str(e)) return - if tx.requires_fee(self.wallet.verifier) and fee == 0: - QMessageBox.warning(self, _('Error'), _("This transaction requires a fee, or it will not be propagated by the network."), _('OK')) + if tx.requires_fee(self.wallet.verifier) and fee < MIN_RELAY_TX_FEE: + QMessageBox.warning(self, _('Error'), _("This transaction requires a higher fee, or it will not be propagated by the network."), _('OK')) return self.run_hook('send_tx', tx) diff --git a/gui/gui_gtk.py b/gui/gui_gtk.py index d3261ded..2cec19b7 100644 --- a/gui/gui_gtk.py +++ b/gui/gui_gtk.py @@ -35,6 +35,7 @@ MONOSPACE_FONT = 'Lucida Console' if platform.system() == 'Windows' else 'monosp from electrum.util import format_satoshis from electrum.interface import DEFAULT_SERVERS +from electrum.bitcoin import MIN_RELAY_TX_FEE def numbify(entry, is_int = False): text = entry.get_text().strip() @@ -844,8 +845,8 @@ class ElectrumWindow: self.show_message(str(e)) return - if tx.requires_fee(self.wallet.verifier) and fee == 0: - self.show_message( "This transaction requires a fee, or it will not be propagated by the network." ) + if tx.requires_fee(self.wallet.verifier) and fee < MIN_RELAY_TX_FEE: + self.show_message( "This transaction requires a higher fee, or it will not be propagated by the network." ) return diff --git a/lib/bitcoin.py b/lib/bitcoin.py index 0b87b784..41f93959 100644 --- a/lib/bitcoin.py +++ b/lib/bitcoin.py @@ -577,6 +577,7 @@ class BIP32Sequence: ################################## transactions +MIN_RELAY_TX_FEE = 10000 class Transaction: @@ -877,15 +878,23 @@ class Transaction: def requires_fee(self, verifier): + # see https://en.bitcoin.it/wiki/Transaction_fees threshold = 57600000 size = len(self.raw)/2 + if size >= 10000: + return True + + for o in self.outputs: + value = o[1] + if value < 1000000: + return True sum = 0 for i in self.inputs: age = verifier.get_confirmations(i["tx_hash"])[0] sum += i["value"] * age priority = sum / size print_error(priority, threshold) - return priority < threshold + return priority < threshold diff --git a/lib/wallet.py b/lib/wallet.py index 2d88668f..65642587 100644 --- a/lib/wallet.py +++ b/lib/wallet.py @@ -912,6 +912,7 @@ class Wallet: height = None for h in ext_h: if h == ['*']: continue + print_error(h) for item in h: if item.get('tx_hash') == tx_hash: height = item.get('height') From 7c4fa714d20ddb91aa39780629110880d2bca9e7 Mon Sep 17 00:00:00 2001 From: ecdsa Date: Sun, 24 Mar 2013 11:31:43 +0100 Subject: [PATCH 10/17] set default fee to 200 uBTC --- RELEASE-NOTES | 4 ++-- lib/wallet.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index caba1f92..9134ba56 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,9 +1,9 @@ # Release 1.7.2: -* Transactions that belong in the same block are displayed in chronological order in the history. +* Transactions that are in the same block are displayed in chronological order in the history. * The client computes transaction priority and rejects zero-fee transactions that need a fee. -* The default fee was lowered to 100 uBTC per kb. +* The default fee was lowered to 200 uBTC per kb. * Due to an internal format change, your history may be pruned when you open your wallet for the first time after upgrading to 1.7.2. If this is the case, please visit a full server to restore your full diff --git a/lib/wallet.py b/lib/wallet.py index 65642587..c64813b1 100644 --- a/lib/wallet.py +++ b/lib/wallet.py @@ -74,7 +74,7 @@ class Wallet: self.seed_version = config.get('seed_version', SEED_VERSION) self.gap_limit = config.get('gap_limit', 5) self.use_change = config.get('use_change',True) - self.fee = int(config.get('fee_per_kb',10000)) + self.fee = int(config.get('fee_per_kb',20000)) self.num_zeros = int(config.get('num_zeros',0)) self.use_encryption = config.get('use_encryption', False) self.seed = config.get('seed', '') # encrypted From 01d43719a6ff42e3ee41fb1586b631fcd856650c Mon Sep 17 00:00:00 2001 From: ecdsa Date: Sun, 24 Mar 2013 12:20:13 +0100 Subject: [PATCH 11/17] simplify loops --- lib/wallet.py | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/lib/wallet.py b/lib/wallet.py index c64813b1..e3a82a19 100644 --- a/lib/wallet.py +++ b/lib/wallet.py @@ -429,12 +429,10 @@ class Wallet: def update_tx_outputs(self, tx_hash): tx = self.transactions.get(tx_hash) - i = 0 - for item in tx.outputs: - addr, value = item + + for i, (addr, value) in enumerate(tx.outputs): key = tx_hash+ ':%d'%i self.prevout_values[key] = value - i += 1 for item in tx.inputs: if self.is_mine(item.get('address')): @@ -452,13 +450,11 @@ class Wallet: for tx_hash, tx_height in h: tx = self.transactions.get(tx_hash) if not tx: continue - i = 0 - for item in tx.outputs: - addr, value = item + + for i, (addr, value) in enumerate(tx.outputs): if addr == address: key = tx_hash + ':%d'%i received_coins.append(key) - i +=1 for tx_hash, tx_height in h: tx = self.transactions.get(tx_hash) @@ -473,13 +469,10 @@ class Wallet: if key in received_coins: v -= value - i = 0 - for item in tx.outputs: - addr, value = item + for i, (addr, value) in enumerate(tx.outputs): key = tx_hash + ':%d'%i if addr == address: v += value - i += 1 if tx_height: c += v @@ -651,7 +644,7 @@ class Wallet: c, u = self.get_balance() if balance != c+u: - v_str = format_satoshis( c+u - balance, True, self.num_zeros) + #v_str = format_satoshis( c+u - balance, True, self.num_zeros) result.append( ('', 1000, 0, c+u-balance, None, c+u-balance, None ) ) balance = c + u - balance @@ -909,10 +902,10 @@ class Wallet: ext_requests.append( ('blockchain.address.get_history', [_addr]) ) ext_h = self.interface.synchronous_get(ext_requests) + print_error("sync:", ext_requests, ext_h) height = None for h in ext_h: if h == ['*']: continue - print_error(h) for item in h: if item.get('tx_hash') == tx_hash: height = item.get('height') From a54c5e88c6ef5725f34652f142d88e62f7202489 Mon Sep 17 00:00:00 2001 From: ecdsa Date: Sun, 24 Mar 2013 12:44:17 +0100 Subject: [PATCH 12/17] fix int rounding --- lib/wallet.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/wallet.py b/lib/wallet.py index e3a82a19..cfb27376 100644 --- a/lib/wallet.py +++ b/lib/wallet.py @@ -559,7 +559,7 @@ class Wallet: inputs.append( item ) if fixed_fee is None: estimated_size = len(inputs) * 180 + 80 # this assumes non-compressed keys - fee = self.fee * round(estimated_size/1024.) + fee = self.fee * int(round(estimated_size/1024.)) if fee == 0: fee = self.fee else: fee = fixed_fee From aee3918c363d0278df504a7115a20c604820780c Mon Sep 17 00:00:00 2001 From: ecdsa Date: Sun, 24 Mar 2013 13:08:41 +0100 Subject: [PATCH 13/17] fix android package --- make_packages | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/make_packages b/make_packages index 73abfebc..0d6b85b1 100755 --- a/make_packages +++ b/make_packages @@ -25,7 +25,8 @@ if __name__ == '__main__': shutil.copytree("aes",'dist/e4a-%s/aes'%version) shutil.copytree("lib",'dist/e4a-%s/lib'%version) os.mkdir('dist/e4a-%s/gui'%version) - shutil.copy("gui/gui_android.py",'dist/e4a-%s/gui'%version) + for n in ['gui_android.py', 'pyqrnative.py', 'bmp.py']: + shutil.copy("gui/%s"%n,'dist/e4a-%s/gui'%version) open('dist/e4a-%s/gui/__init__.py'%version,'w').close() os.chdir("dist") From 8d339bfc1a8daa3de91c9d3df0ac3888794bb555 Mon Sep 17 00:00:00 2001 From: ecdsa Date: Mon, 25 Mar 2013 02:52:59 +0100 Subject: [PATCH 14/17] deserialize: catch exception raised by coinbase transactions --- lib/deserialize.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/deserialize.py b/lib/deserialize.py index 96972ce3..0dd0a515 100644 --- a/lib/deserialize.py +++ b/lib/deserialize.py @@ -323,7 +323,11 @@ def match_decoded(decoded, to_match): return True def get_address_from_input_script(bytes): - decoded = [ x for x in script_GetOp(bytes) ] + try: + decoded = [ x for x in script_GetOp(bytes) ] + except: + print_error("cannot find address in input script", bytes.encode('hex')) + return [], [], "(None)" # non-generated TxIn transactions push a signature # (seventy-something bytes) and then their public key From 39799592ed7bc773ad6de9bd8e3731b3f8047ff1 Mon Sep 17 00:00:00 2001 From: thomasv Date: Mon, 25 Mar 2013 10:20:16 +0100 Subject: [PATCH 15/17] add explanation comment --- lib/deserialize.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/deserialize.py b/lib/deserialize.py index 0dd0a515..85ab97c4 100644 --- a/lib/deserialize.py +++ b/lib/deserialize.py @@ -326,6 +326,7 @@ def get_address_from_input_script(bytes): try: decoded = [ x for x in script_GetOp(bytes) ] except: + # coinbase transactions raise an exception print_error("cannot find address in input script", bytes.encode('hex')) return [], [], "(None)" From 47ae1e61d30b479f26ee9dc2650ce214b0dcf9bb Mon Sep 17 00:00:00 2001 From: rdymac Date: Fri, 29 Mar 2013 19:59:07 +0100 Subject: [PATCH 16/17] Added plugins files to be able to translate them Added plugins files to be able to translate them --- app.fil | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app.fil b/app.fil index 3ebc5174..1eaee6cf 100644 --- a/app.fil +++ b/app.fil @@ -2,3 +2,8 @@ gui/gui_gtk.py gui/gui_classic.py gui/gui_lite.py gui/history_widget.py +plugins/aliases.py +plugins/pointofsale.py +plugins/labels.py +plugins/qrscanner.py +plugins/virtualkeyboard.py From c145b69b3bd07613d87718d90737600b6266b705 Mon Sep 17 00:00:00 2001 From: rdymac Date: Fri, 29 Mar 2013 20:01:00 +0100 Subject: [PATCH 17/17] Latest version of the wikia Latest version of the wikia --- lib/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/version.py b/lib/version.py index bfd43c5e..b6dfd318 100644 --- a/lib/version.py +++ b/lib/version.py @@ -1,4 +1,4 @@ ELECTRUM_VERSION = "1.7.2" # version of the client package PROTOCOL_VERSION = '0.6' # protocol version requested SEED_VERSION = 4 # bump this every time the seed generation is modified -TRANSLATION_ID = 3992 # version of the wiki page +TRANSLATION_ID = 4012 # version of the wiki page