From ec8e24332309e33b2788dd493f7946954aa8934d Mon Sep 17 00:00:00 2001 From: Victor Shyba Date: Wed, 18 Mar 2020 00:45:44 -0300 Subject: [PATCH] estimate timestamps instead of using block headers --- lbry/extras/daemon/json_response_encoder.py | 7 +++---- lbry/stream/stream_manager.py | 2 +- lbry/wallet/header.py | 14 ++++---------- lbry/wallet/ledger.py | 2 +- .../integration/blockchain/test_resolve_command.py | 4 ++-- tests/unit/stream/test_stream_manager.py | 3 +++ 6 files changed, 14 insertions(+), 18 deletions(-) diff --git a/lbry/extras/daemon/json_response_encoder.py b/lbry/extras/daemon/json_response_encoder.py index 92a43092c..d2080db8c 100644 --- a/lbry/extras/daemon/json_response_encoder.py +++ b/lbry/extras/daemon/json_response_encoder.py @@ -159,7 +159,6 @@ class JSONResponseEncoder(JSONEncoder): return tx_height = txo.tx_ref.height best_height = self.ledger.headers.height - timestamp = self.ledger.headers.synchronous_get(tx_height)['timestamp'] if 0 < tx_height <= best_height else None output = { 'txid': txo.tx_ref.id, 'nout': txo.position, @@ -167,7 +166,7 @@ class JSONResponseEncoder(JSONEncoder): 'amount': dewies_to_lbc(txo.amount), 'address': txo.get_address(self.ledger) if txo.has_address else None, 'confirmations': (best_height+1) - tx_height if tx_height > 0 else tx_height, - 'timestamp': timestamp + 'timestamp': self.ledger.headers.estimated_timestamp(tx_height) } if txo.is_spent is not None: output['is_spent'] = txo.is_spent @@ -245,7 +244,7 @@ class JSONResponseEncoder(JSONEncoder): if isinstance(value, int): meta[key] = dewies_to_lbc(value) if 0 < meta.get('creation_height', 0) <= self.ledger.headers.height: - meta['creation_timestamp'] = self.ledger.headers.synchronous_get(meta['creation_height'])['timestamp'] + meta['creation_timestamp'] = self.ledger.headers.estimated_timestamp(meta['creation_height']) return meta def encode_input(self, txi): @@ -307,7 +306,7 @@ class JSONResponseEncoder(JSONEncoder): 'added_on': managed_stream.added_on, 'height': tx_height, 'confirmations': (best_height + 1) - tx_height if tx_height > 0 else tx_height, - 'timestamp': self.ledger.headers.synchronous_get(tx_height)['timestamp'] if 0 < tx_height <= best_height else None, + 'timestamp': self.ledger.headers.estimated_timestamp(tx_height), 'is_fully_reflected': managed_stream.is_fully_reflected } diff --git a/lbry/stream/stream_manager.py b/lbry/stream/stream_manager.py index 891af7ddb..0ff206936 100644 --- a/lbry/stream/stream_manager.py +++ b/lbry/stream/stream_manager.py @@ -338,7 +338,7 @@ class StreamManager: 'claim_sequence': -1, 'address': txo.get_address(wallet_manager.ledger), 'valid_at_height': txo.meta.get('activation_height', None), - 'timestamp': wallet_manager.ledger.headers.synchronous_get(tx_height)['timestamp'], + 'timestamp': wallet_manager.ledger.headers.estimated_timestamp(tx_height), 'supports': [] } else: diff --git a/lbry/wallet/header.py b/lbry/wallet/header.py index 2adbbff02..4eae54a87 100644 --- a/lbry/wallet/header.py +++ b/lbry/wallet/header.py @@ -33,6 +33,8 @@ class Headers: genesis_hash = b'9c89283ba0f3227f6c03b70216b9f665f0118d5e0fa729cedf4fb34d6a34f463' target_timespan = 150 checkpoint = (600_000, b'100b33ca3d0b86a48f0d6d6f30458a130ecb89d5affefe4afccb134d5a40f4c2') + first_block_timestamp = 1466646588 # block 1, as 0 is off by a lot + timestamp_average_offset = 160.6855883050695 # calculated at 733447 validate_difficulty: bool = True @@ -111,12 +113,8 @@ class Headers: raise IndexError(f"{height} is out of bounds, current height: {self.height}") return self.deserialize(height, self.get_raw_header(height)) - def synchronous_get(self, height): - if isinstance(height, slice): - raise NotImplementedError("Slicing of header chain has not been implemented yet.") - if not 0 <= height <= self.height: - raise IndexError(f"{height} is out of bounds, current height: {self.height}") - return self.deserialize(height, self.get_raw_header(height)) + def estimated_timestamp(self, height): + return self.first_block_timestamp + (height * self.timestamp_average_offset) def get_raw_header(self, height) -> bytes: self.io.seek(height * self.header_size, os.SEEK_SET) @@ -283,10 +281,6 @@ class Headers: header = headers[start:end] yield self.hash_header(header), self.deserialize(height+idx, header) - @property - def claim_trie_root(self): - return self[self.height]['claim_trie_root'] - @staticmethod def header_hash_to_pow_hash(header_hash: bytes): header_hash_bytes = unhexlify(header_hash)[::-1] diff --git a/lbry/wallet/ledger.py b/lbry/wallet/ledger.py index abe407453..4d1207bee 100644 --- a/lbry/wallet/ledger.py +++ b/lbry/wallet/ledger.py @@ -899,7 +899,7 @@ class Ledger(metaclass=LedgerRegistry): headers = self.headers history = [] for tx in txs: # pylint: disable=too-many-nested-blocks - ts = headers.synchronous_get(tx.height)['timestamp'] if tx.height > 0 else None + ts = headers.estimated_timestamp(tx.height)['timestamp'] item = { 'txid': tx.id, 'timestamp': ts, diff --git a/tests/integration/blockchain/test_resolve_command.py b/tests/integration/blockchain/test_resolve_command.py index 2a9a1fe08..ea6874cfd 100644 --- a/tests/integration/blockchain/test_resolve_command.py +++ b/tests/integration/blockchain/test_resolve_command.py @@ -49,11 +49,11 @@ class ResolveCommand(BaseResolveTestCase): self.assertTrue(claim['is_channel_signature_valid']) self.assertEqual( claim['timestamp'], - self.ledger.headers.synchronous_get(claim['height'])['timestamp'] + self.ledger.headers.estimated_timestamp(claim['height']) ) self.assertEqual( claim['signing_channel']['timestamp'], - self.ledger.headers.synchronous_get(claim['signing_channel']['height'])['timestamp'] + self.ledger.headers.estimated_timestamp(claim['signing_channel']['height']) ) # resolving claim foo by itself diff --git a/tests/unit/stream/test_stream_manager.py b/tests/unit/stream/test_stream_manager.py index 4dfb76b35..e33064503 100644 --- a/tests/unit/stream/test_stream_manager.py +++ b/tests/unit/stream/test_stream_manager.py @@ -84,6 +84,9 @@ async def get_mock_wallet(sd_hash, storage, balance=10.0, fee=None): }) class FakeHeaders: + def estimated_timestamp(self, height): + return 1984 + def __init__(self, height): self.height = height