Preparation for moving the set of verified and unverified txs to the wallet.

The verifier will retain responsibility for verification, but will no longer
hold the transaction sets itself.

Change requires_fee to take a wallet.
Add new function add_unverified_tx()
Move get_confirmations() to the wallet from the verifier.
This commit is contained in:
Neil Booth 2015-05-07 08:52:34 +09:00
parent ffda5cd866
commit 79de458101
7 changed files with 52 additions and 52 deletions

View File

@ -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]

View File

@ -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

View File

@ -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:

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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: