electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

commit 414d0e1fa10e1d6f0ef7d027c3ccc869961b8744
parent ffda5cd8663cb0e4381ecb4835e343831ffe67e9
Author: ThomasV <electrumdev@gmail.com>
Date:   Thu,  7 May 2015 15:25:09 +0200

Merge pull request #1202 from kyuupichan/offline-1

Preparation for moving the set of verified and unverified txs to the wallet
Diffstat:
Mgui/gtk.py | 4++--
Mgui/qt/main_window.py | 2+-
Mgui/qt/transaction_dialog.py | 2+-
Mlib/transaction.py | 4++--
Mlib/verifier.py | 33+--------------------------------
Mlib/wallet.py | 57++++++++++++++++++++++++++++++++++++++++++++-------------
Mscripts/merchant/merchant.py | 2+-
7 files changed, 52 insertions(+), 52 deletions(-)

diff --git a/gui/gtk.py b/gui/gtk.py @@ -813,7 +813,7 @@ class ElectrumWindow: self.show_message(str(e)) return - if tx.requires_fee(self.wallet.verifier) and fee < MIN_RELAY_TX_FEE: + if tx.requires_fee(self.wallet) 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 @@ -1200,7 +1200,7 @@ class ElectrumWindow: tx = self.wallet.transactions.get(tx_hash) tx.deserialize() is_relevant, is_mine, v, fee = self.wallet.get_wallet_delta(tx) - conf, timestamp = self.wallet.verifier.get_confirmations(tx_hash) + conf, timestamp = self.wallet.get_confirmations(tx_hash) if timestamp: time_str = datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:-3] diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py @@ -1121,7 +1121,7 @@ class ElectrumWindow(QMainWindow): self.show_message(str(e)) return - if tx.get_fee() < MIN_RELAY_TX_FEE and tx.requires_fee(self.wallet.verifier): + if tx.get_fee() < MIN_RELAY_TX_FEE and tx.requires_fee(self.wallet): QMessageBox.warning(self, _('Error'), _("This transaction requires a higher fee, or it will not be propagated by the network."), _('OK')) return diff --git a/gui/qt/transaction_dialog.py b/gui/qt/transaction_dialog.py @@ -149,7 +149,7 @@ class TxDialog(QDialog): status = _("Signed") if tx_hash in self.wallet.transactions.keys(): - conf, timestamp = self.wallet.verifier.get_confirmations(tx_hash) + conf, timestamp = self.wallet.get_confirmations(tx_hash) if timestamp: time_str = datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:-3] else: diff --git a/lib/transaction.py b/lib/transaction.py @@ -769,7 +769,7 @@ class Transaction: return out - def requires_fee(self, verifier): + def requires_fee(self, wallet): # see https://en.bitcoin.it/wiki/Transaction_fees # # size must be smaller than 1 kbyte for free tx @@ -784,7 +784,7 @@ class Transaction: threshold = 57600000 weight = 0 for txin in self.inputs: - age = verifier.get_confirmations(txin["prevout_hash"])[0] + age = wallet.get_confirmations(txin["prevout_hash"])[0] weight += txin["value"] * age priority = weight / size print_error(priority, threshold) diff --git a/lib/verifier.py b/lib/verifier.py @@ -36,41 +36,10 @@ class SPV(util.DaemonThread): self.network = network self.transactions = {} # requested verifications (with height sent by the requestor) self.verified_tx = storage.get('verified_tx3',{}) # height, timestamp of verified transactions - self.merkle_roots = storage.get('merkle_roots',{}) # hashed by me + self.merkle_roots = {} # hashed by me self.lock = threading.Lock() self.queue = Queue.Queue() - def get_confirmations(self, tx): - """ return the number of confirmations of a monitored transaction. """ - with self.lock: - if tx in self.verified_tx: - height, timestamp, pos = self.verified_tx[tx] - conf = (self.network.get_local_height() - height + 1) - if conf <= 0: timestamp = None - elif tx in self.transactions: - conf = -1 - timestamp = None - else: - conf = 0 - timestamp = None - - return conf, timestamp - - - def get_txpos(self, tx_hash): - "return position, even if the tx is unverified" - with self.lock: - x = self.verified_tx.get(tx_hash) - y = self.transactions.get(tx_hash) - if x: - height, timestamp, pos = x - return height, pos - elif y: - return y, 0 - else: - return 1e12, 0 - - def get_height(self, tx_hash): with self.lock: v = self.verified_tx.get(tx_hash) diff --git a/lib/wallet.py b/lib/wallet.py @@ -387,6 +387,41 @@ class Abstract_Wallet(object): decrypted = ec.decrypt_message(message) return decrypted + def add_unverified_tx(self, tx_hash, tx_height): + if self.verifier and tx_height > 0: + self.verifier.add(tx_hash, tx_height) + + def get_confirmations(self, tx): + """ return the number of confirmations of a monitored transaction. """ + if not self.verifier: + return (None, None) + with self.verifier.lock: + if tx in self.verifier.verified_tx: + height, timestamp, pos = self.verifier.verified_tx[tx] + conf = (self.network.get_local_height() - height + 1) + if conf <= 0: timestamp = None + elif tx in self.verifier.transactions: + conf = -1 + timestamp = None + else: + conf = 0 + timestamp = None + + return conf, timestamp + + def get_txpos(self, tx_hash): + "return position, even if the tx is unverified" + with self.verifier.lock: + x = self.verifier.verified_tx.get(tx_hash) + y = self.verifier.transactions.get(tx_hash) + if x: + height, timestamp, pos = x + return height, pos + elif y: + return y, 0 + else: + return 1e12, 0 + def is_found(self): return self.history.values() != [[]] * len(self.history) @@ -685,8 +720,7 @@ class Abstract_Wallet(object): def receive_tx_callback(self, tx_hash, tx, tx_height): self.add_transaction(tx_hash, tx, tx_height) #self.network.pending_transactions_for_notifications.append(tx) - if self.verifier and tx_height>0: - self.verifier.add(tx_hash, tx_height) + self.add_unverified_tx(tx_hash, tx_height) def receive_history_callback(self, addr, hist): @@ -701,10 +735,8 @@ class Abstract_Wallet(object): self.storage.put('addr_history', self.history, True) for tx_hash, tx_height in hist: - if tx_height>0: - # add it in case it was previously unconfirmed - if self.verifier: - self.verifier.add(tx_hash, tx_height) + # add it in case it was previously unconfirmed + self.add_unverified_tx (tx_hash, tx_height) # if addr is new, we have to recompute txi and txo tx = self.transactions.get(tx_hash) @@ -734,9 +766,9 @@ class Abstract_Wallet(object): # 2. create sorted history history = [] for tx_hash, delta in tx_deltas.items(): - conf, timestamp = self.verifier.get_confirmations(tx_hash) if self.verifier else (None, None) + conf, timestamp = self.get_confirmations(tx_hash) history.append((tx_hash, conf, delta, timestamp)) - history.sort(key = lambda x: self.verifier.get_txpos(x[0])) + history.sort(key = lambda x: self.get_txpos(x[0])) history.reverse() # 3. add balance @@ -784,7 +816,7 @@ class Abstract_Wallet(object): def estimated_fee(self, tx): estimated_size = len(tx.serialize(-1))/2 fee = int(self.fee_per_kb*estimated_size/1000.) - if fee < MIN_RELAY_TX_FEE: # and tx.requires_fee(self.verifier): + if fee < MIN_RELAY_TX_FEE: # and tx.requires_fee(self): fee = MIN_RELAY_TX_FEE return fee @@ -963,9 +995,8 @@ class Abstract_Wallet(object): # review transactions that are in the history for addr, hist in self.history.items(): for tx_hash, tx_height in hist: - if tx_height>0: - # add it in case it was previously unconfirmed - self.verifier.add(tx_hash, tx_height) + # add it in case it was previously unconfirmed + self.add_unverified_tx (tx_hash, tx_height) # if we are on a pruning server, remove unverified transactions vr = self.verifier.transactions.keys() + self.verifier.verified_tx.keys() @@ -1022,7 +1053,7 @@ class Abstract_Wallet(object): height = item.get('height') if height: print_error("found height for", tx_hash, height) - self.verifier.add(tx_hash, height) + self.add_unverified_tx(tx_hash, height) else: print_error("removing orphaned tx from history", tx_hash) self.transactions.pop(tx_hash) diff --git a/scripts/merchant/merchant.py b/scripts/merchant/merchant.py @@ -87,7 +87,7 @@ def on_wallet_update(): for tx_hash, tx_height in h: tx = wallet.transactions.get(tx_hash) if not tx: continue - if wallet.verifier.get_confirmations(tx_hash) < requested_confs: continue + if wallet.get_confirmations(tx_hash)[0] < requested_confs: continue for o in tx.outputs: o_type, o_address, o_value = o if o_address == addr: