Merge pull request #1202 from kyuupichan/offline-1
Preparation for moving the set of verified and unverified txs to the wallet
This commit is contained in:
commit
414d0e1fa1
|
@ -813,7 +813,7 @@ class ElectrumWindow:
|
||||||
self.show_message(str(e))
|
self.show_message(str(e))
|
||||||
return
|
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." )
|
self.show_message( "This transaction requires a higher fee, or it will not be propagated by the network." )
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -1200,7 +1200,7 @@ class ElectrumWindow:
|
||||||
tx = self.wallet.transactions.get(tx_hash)
|
tx = self.wallet.transactions.get(tx_hash)
|
||||||
tx.deserialize()
|
tx.deserialize()
|
||||||
is_relevant, is_mine, v, fee = self.wallet.get_wallet_delta(tx)
|
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:
|
if timestamp:
|
||||||
time_str = datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:-3]
|
time_str = datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:-3]
|
||||||
|
|
|
@ -1121,7 +1121,7 @@ class ElectrumWindow(QMainWindow):
|
||||||
self.show_message(str(e))
|
self.show_message(str(e))
|
||||||
return
|
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'))
|
QMessageBox.warning(self, _('Error'), _("This transaction requires a higher fee, or it will not be propagated by the network."), _('OK'))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
@ -149,7 +149,7 @@ class TxDialog(QDialog):
|
||||||
status = _("Signed")
|
status = _("Signed")
|
||||||
|
|
||||||
if tx_hash in self.wallet.transactions.keys():
|
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:
|
if timestamp:
|
||||||
time_str = datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:-3]
|
time_str = datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:-3]
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -769,7 +769,7 @@ class Transaction:
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
def requires_fee(self, verifier):
|
def requires_fee(self, wallet):
|
||||||
# see https://en.bitcoin.it/wiki/Transaction_fees
|
# see https://en.bitcoin.it/wiki/Transaction_fees
|
||||||
#
|
#
|
||||||
# size must be smaller than 1 kbyte for free tx
|
# size must be smaller than 1 kbyte for free tx
|
||||||
|
@ -784,7 +784,7 @@ class Transaction:
|
||||||
threshold = 57600000
|
threshold = 57600000
|
||||||
weight = 0
|
weight = 0
|
||||||
for txin in self.inputs:
|
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
|
weight += txin["value"] * age
|
||||||
priority = weight / size
|
priority = weight / size
|
||||||
print_error(priority, threshold)
|
print_error(priority, threshold)
|
||||||
|
|
|
@ -36,41 +36,10 @@ class SPV(util.DaemonThread):
|
||||||
self.network = network
|
self.network = network
|
||||||
self.transactions = {} # requested verifications (with height sent by the requestor)
|
self.transactions = {} # requested verifications (with height sent by the requestor)
|
||||||
self.verified_tx = storage.get('verified_tx3',{}) # height, timestamp of verified transactions
|
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.lock = threading.Lock()
|
||||||
self.queue = Queue.Queue()
|
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):
|
def get_height(self, tx_hash):
|
||||||
with self.lock:
|
with self.lock:
|
||||||
v = self.verified_tx.get(tx_hash)
|
v = self.verified_tx.get(tx_hash)
|
||||||
|
|
|
@ -387,6 +387,41 @@ class Abstract_Wallet(object):
|
||||||
decrypted = ec.decrypt_message(message)
|
decrypted = ec.decrypt_message(message)
|
||||||
return decrypted
|
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):
|
def is_found(self):
|
||||||
return self.history.values() != [[]] * len(self.history)
|
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):
|
def receive_tx_callback(self, tx_hash, tx, tx_height):
|
||||||
self.add_transaction(tx_hash, tx, tx_height)
|
self.add_transaction(tx_hash, tx, tx_height)
|
||||||
#self.network.pending_transactions_for_notifications.append(tx)
|
#self.network.pending_transactions_for_notifications.append(tx)
|
||||||
if self.verifier and tx_height>0:
|
self.add_unverified_tx(tx_hash, tx_height)
|
||||||
self.verifier.add(tx_hash, tx_height)
|
|
||||||
|
|
||||||
|
|
||||||
def receive_history_callback(self, addr, hist):
|
def receive_history_callback(self, addr, hist):
|
||||||
|
@ -701,10 +735,8 @@ class Abstract_Wallet(object):
|
||||||
self.storage.put('addr_history', self.history, True)
|
self.storage.put('addr_history', self.history, True)
|
||||||
|
|
||||||
for tx_hash, tx_height in hist:
|
for tx_hash, tx_height in hist:
|
||||||
if tx_height>0:
|
|
||||||
# add it in case it was previously unconfirmed
|
# add it in case it was previously unconfirmed
|
||||||
if self.verifier:
|
self.add_unverified_tx (tx_hash, tx_height)
|
||||||
self.verifier.add(tx_hash, tx_height)
|
|
||||||
|
|
||||||
# if addr is new, we have to recompute txi and txo
|
# if addr is new, we have to recompute txi and txo
|
||||||
tx = self.transactions.get(tx_hash)
|
tx = self.transactions.get(tx_hash)
|
||||||
|
@ -734,9 +766,9 @@ class Abstract_Wallet(object):
|
||||||
# 2. create sorted history
|
# 2. create sorted history
|
||||||
history = []
|
history = []
|
||||||
for tx_hash, delta in tx_deltas.items():
|
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.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()
|
history.reverse()
|
||||||
|
|
||||||
# 3. add balance
|
# 3. add balance
|
||||||
|
@ -784,7 +816,7 @@ class Abstract_Wallet(object):
|
||||||
def estimated_fee(self, tx):
|
def estimated_fee(self, tx):
|
||||||
estimated_size = len(tx.serialize(-1))/2
|
estimated_size = len(tx.serialize(-1))/2
|
||||||
fee = int(self.fee_per_kb*estimated_size/1000.)
|
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
|
fee = MIN_RELAY_TX_FEE
|
||||||
return fee
|
return fee
|
||||||
|
|
||||||
|
@ -963,9 +995,8 @@ class Abstract_Wallet(object):
|
||||||
# review transactions that are in the history
|
# review transactions that are in the history
|
||||||
for addr, hist in self.history.items():
|
for addr, hist in self.history.items():
|
||||||
for tx_hash, tx_height in hist:
|
for tx_hash, tx_height in hist:
|
||||||
if tx_height>0:
|
|
||||||
# add it in case it was previously unconfirmed
|
# add it in case it was previously unconfirmed
|
||||||
self.verifier.add(tx_hash, tx_height)
|
self.add_unverified_tx (tx_hash, tx_height)
|
||||||
|
|
||||||
# if we are on a pruning server, remove unverified transactions
|
# if we are on a pruning server, remove unverified transactions
|
||||||
vr = self.verifier.transactions.keys() + self.verifier.verified_tx.keys()
|
vr = self.verifier.transactions.keys() + self.verifier.verified_tx.keys()
|
||||||
|
@ -1022,7 +1053,7 @@ class Abstract_Wallet(object):
|
||||||
height = item.get('height')
|
height = item.get('height')
|
||||||
if height:
|
if height:
|
||||||
print_error("found height for", tx_hash, height)
|
print_error("found height for", tx_hash, height)
|
||||||
self.verifier.add(tx_hash, height)
|
self.add_unverified_tx(tx_hash, height)
|
||||||
else:
|
else:
|
||||||
print_error("removing orphaned tx from history", tx_hash)
|
print_error("removing orphaned tx from history", tx_hash)
|
||||||
self.transactions.pop(tx_hash)
|
self.transactions.pop(tx_hash)
|
||||||
|
|
|
@ -87,7 +87,7 @@ def on_wallet_update():
|
||||||
for tx_hash, tx_height in h:
|
for tx_hash, tx_height in h:
|
||||||
tx = wallet.transactions.get(tx_hash)
|
tx = wallet.transactions.get(tx_hash)
|
||||||
if not tx: continue
|
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:
|
for o in tx.outputs:
|
||||||
o_type, o_address, o_value = o
|
o_type, o_address, o_value = o
|
||||||
if o_address == addr:
|
if o_address == addr:
|
||||||
|
|
Loading…
Reference in New Issue