Browse Source

wallet: TxMinedInfo (merged TxMinedStatus and VerifiedTxInfo)

3.3.3.1
SomberNight 6 years ago
parent
commit
c017f788ac
No known key found for this signature in database GPG Key ID: B33B5F232C6271E9
  1. 23
      electrum/address_synchronizer.py
  2. 4
      electrum/gui/qt/history_list.py
  3. 4
      electrum/tests/test_wallet.py
  4. 18
      electrum/util.py
  5. 9
      electrum/verifier.py

23
electrum/address_synchronizer.py

@ -29,7 +29,7 @@ from typing import TYPE_CHECKING, Dict, Optional
from . import bitcoin from . import bitcoin
from .bitcoin import COINBASE_MATURITY, TYPE_ADDRESS, TYPE_PUBKEY from .bitcoin import COINBASE_MATURITY, TYPE_ADDRESS, TYPE_PUBKEY
from .util import PrintError, profiler, bfh, VerifiedTxInfo, TxMinedStatus from .util import PrintError, profiler, bfh, TxMinedInfo
from .transaction import Transaction, TxOutput from .transaction import Transaction, TxOutput
from .synchronizer import Synchronizer from .synchronizer import Synchronizer
from .verifier import SPV from .verifier import SPV
@ -70,11 +70,15 @@ class AddressSynchronizer(PrintError):
self.transaction_lock = threading.RLock() self.transaction_lock = threading.RLock()
# address -> list(txid, height) # address -> list(txid, height)
self.history = storage.get('addr_history',{}) self.history = storage.get('addr_history',{})
# Verified transactions. txid -> VerifiedTxInfo. Access with self.lock. # Verified transactions. txid -> TxMinedInfo. Access with self.lock.
verified_tx = storage.get('verified_tx3', {}) verified_tx = storage.get('verified_tx3', {})
self.verified_tx = {} self.verified_tx = {} # type: Dict[str, TxMinedInfo]
for txid, (height, timestamp, txpos, header_hash) in verified_tx.items(): for txid, (height, timestamp, txpos, header_hash) in verified_tx.items():
self.verified_tx[txid] = VerifiedTxInfo(height, timestamp, txpos, header_hash) self.verified_tx[txid] = TxMinedInfo(height=height,
conf=None,
timestamp=timestamp,
txpos=txpos,
header_hash=header_hash)
# Transactions pending verification. txid -> tx_height. Access with self.lock. # Transactions pending verification. txid -> tx_height. Access with self.lock.
self.unverified_tx = defaultdict(int) self.unverified_tx = defaultdict(int)
# true when synchronized # true when synchronized
@ -562,7 +566,7 @@ class AddressSynchronizer(PrintError):
if new_height == tx_height: if new_height == tx_height:
self.unverified_tx.pop(tx_hash, None) self.unverified_tx.pop(tx_hash, None)
def add_verified_tx(self, tx_hash: str, info: VerifiedTxInfo): def add_verified_tx(self, tx_hash: str, info: TxMinedInfo):
# Remove from the unverified map and add to the verified map # Remove from the unverified map and add to the verified map
with self.lock: with self.lock:
self.unverified_tx.pop(tx_hash, None) self.unverified_tx.pop(tx_hash, None)
@ -605,19 +609,18 @@ class AddressSynchronizer(PrintError):
return cached_local_height return cached_local_height
return self.network.get_local_height() if self.network else self.storage.get('stored_height', 0) return self.network.get_local_height() if self.network else self.storage.get('stored_height', 0)
def get_tx_height(self, tx_hash: str) -> TxMinedStatus: def get_tx_height(self, tx_hash: str) -> TxMinedInfo:
""" Given a transaction, returns (height, conf, timestamp, header_hash) """
with self.lock: with self.lock:
if tx_hash in self.verified_tx: if tx_hash in self.verified_tx:
info = self.verified_tx[tx_hash] info = self.verified_tx[tx_hash]
conf = max(self.get_local_height() - info.height + 1, 0) conf = max(self.get_local_height() - info.height + 1, 0)
return TxMinedStatus(info.height, conf, info.timestamp, info.header_hash) return info._replace(conf=conf)
elif tx_hash in self.unverified_tx: elif tx_hash in self.unverified_tx:
height = self.unverified_tx[tx_hash] height = self.unverified_tx[tx_hash]
return TxMinedStatus(height, 0, None, None) return TxMinedInfo(height=height, conf=0)
else: else:
# local transaction # local transaction
return TxMinedStatus(TX_HEIGHT_LOCAL, 0, None, None) return TxMinedInfo(height=TX_HEIGHT_LOCAL, conf=0)
def set_up_to_date(self, up_to_date): def set_up_to_date(self, up_to_date):
with self.lock: with self.lock:

4
electrum/gui/qt/history_list.py

@ -31,7 +31,7 @@ from collections import OrderedDict
from electrum.address_synchronizer import TX_HEIGHT_LOCAL from electrum.address_synchronizer import TX_HEIGHT_LOCAL
from electrum.i18n import _ from electrum.i18n import _
from electrum.util import block_explorer_URL, profiler, print_error, TxMinedStatus, OrderedDictWithIndex from electrum.util import block_explorer_URL, profiler, print_error, TxMinedInfo, OrderedDictWithIndex
from .util import * from .util import *
@ -275,7 +275,7 @@ class HistoryList(MyTreeView, AcceptFileDragDrop):
value = tx_item['value'].value value = tx_item['value'].value
balance = tx_item['balance'].value balance = tx_item['balance'].value
label = tx_item['label'] label = tx_item['label']
tx_mined_status = TxMinedStatus(height, conf, timestamp, None) tx_mined_status = TxMinedInfo(height=height, conf=conf, timestamp=timestamp)
status, status_str = self.wallet.get_tx_status(tx_hash, tx_mined_status) status, status_str = self.wallet.get_tx_status(tx_hash, tx_mined_status)
has_invoice = self.wallet.invoices.paid.get(tx_hash) has_invoice = self.wallet.invoices.paid.get(tx_hash)
v_str = self.parent.format_amount(value, is_diff=True, whitespaces=True) v_str = self.parent.format_amount(value, is_diff=True, whitespaces=True)

4
electrum/tests/test_wallet.py

@ -11,7 +11,7 @@ from io import StringIO
from electrum.storage import WalletStorage, FINAL_SEED_VERSION from electrum.storage import WalletStorage, FINAL_SEED_VERSION
from electrum.wallet import Abstract_Wallet from electrum.wallet import Abstract_Wallet
from electrum.exchange_rate import ExchangeBase, FxThread from electrum.exchange_rate import ExchangeBase, FxThread
from electrum.util import TxMinedStatus from electrum.util import TxMinedInfo
from electrum.bitcoin import COIN from electrum.bitcoin import COIN
from . import SequentialTestCase from . import SequentialTestCase
@ -99,7 +99,7 @@ class FakeWallet:
def get_tx_height(self, txid): def get_tx_height(self, txid):
# because we use a current timestamp, and history is empty, # because we use a current timestamp, and history is empty,
# FxThread.history_rate will use spot prices # FxThread.history_rate will use spot prices
return TxMinedStatus(height=10, conf=10, timestamp=time.time(), header_hash='def') return TxMinedInfo(height=10, conf=10, timestamp=int(time.time()), header_hash='def')
default_fiat_value = Abstract_Wallet.default_fiat_value default_fiat_value = Abstract_Wallet.default_fiat_value
price_at_timestamp = Abstract_Wallet.price_at_timestamp price_at_timestamp = Abstract_Wallet.price_at_timestamp

18
electrum/util.py

@ -879,18 +879,12 @@ def ignore_exceptions(func):
return wrapper return wrapper
class TxMinedStatus(NamedTuple): class TxMinedInfo(NamedTuple):
height: int height: int # height of block that mined tx
conf: int conf: Optional[int] = None # number of confirmations (None means unknown)
timestamp: Optional[int] timestamp: Optional[int] = None # timestamp of block that mined tx
header_hash: Optional[str] txpos: Optional[int] = None # position of tx in serialized block
header_hash: Optional[str] = None # hash of block that mined tx
class VerifiedTxInfo(NamedTuple):
height: int
timestamp: int
txpos: int
header_hash: str
def make_aiohttp_session(proxy: dict, headers=None, timeout=None): def make_aiohttp_session(proxy: dict, headers=None, timeout=None):

9
electrum/verifier.py

@ -26,7 +26,7 @@ from typing import Sequence, Optional, TYPE_CHECKING
import aiorpcx import aiorpcx
from .util import bh2u, VerifiedTxInfo, NetworkJobOnDefaultServer from .util import bh2u, TxMinedInfo, NetworkJobOnDefaultServer
from .crypto import sha256d from .crypto import sha256d
from .bitcoin import hash_decode, hash_encode from .bitcoin import hash_decode, hash_encode
from .transaction import Transaction from .transaction import Transaction
@ -124,8 +124,11 @@ class SPV(NetworkJobOnDefaultServer):
except KeyError: pass except KeyError: pass
self.print_error("verified %s" % tx_hash) self.print_error("verified %s" % tx_hash)
header_hash = hash_header(header) header_hash = hash_header(header)
vtx_info = VerifiedTxInfo(tx_height, header.get('timestamp'), pos, header_hash) tx_info = TxMinedInfo(height=tx_height,
self.wallet.add_verified_tx(tx_hash, vtx_info) timestamp=header.get('timestamp'),
txpos=pos,
header_hash=header_hash)
self.wallet.add_verified_tx(tx_hash, tx_info)
if self.is_up_to_date() and self.wallet.is_up_to_date(): if self.is_up_to_date() and self.wallet.is_up_to_date():
self.wallet.save_verified_tx(write=True) self.wallet.save_verified_tx(write=True)

Loading…
Cancel
Save