Skip to content

Commit 8ed3e4b

Browse files
authored
refactor: create non-null hash property (#967)
1 parent a2ee438 commit 8ed3e4b

File tree

4 files changed

+21
-18
lines changed

4 files changed

+21
-18
lines changed

hathor/transaction/base_transaction.py

+18-13
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ def __init__(self,
168168
self.outputs = outputs or []
169169
self.parents = parents or []
170170
self.storage = storage
171-
self.hash = hash # Stored as bytes.
171+
self._hash: VertexId | None = hash # Stored as bytes.
172172

173173
@classproperty
174174
def log(cls):
@@ -253,7 +253,7 @@ def __eq__(self, other: object) -> bool:
253253
"""
254254
if not isinstance(other, BaseTransaction):
255255
return NotImplemented
256-
if self.hash and other.hash:
256+
if self._hash and other._hash:
257257
return self.hash == other.hash
258258
return False
259259

@@ -265,7 +265,6 @@ def __bytes__(self) -> bytes:
265265
return self.get_struct()
266266

267267
def __hash__(self) -> int:
268-
assert self.hash is not None
269268
return hash(self.hash)
270269

271270
@abstractmethod
@@ -276,10 +275,19 @@ def calculate_height(self) -> int:
276275
def calculate_min_height(self) -> int:
277276
raise NotImplementedError
278277

278+
@property
279+
def hash(self) -> VertexId:
280+
assert self._hash is not None, 'Vertex hash must be initialized.'
281+
return self._hash
282+
283+
@hash.setter
284+
def hash(self, value: VertexId) -> None:
285+
self._hash = value
286+
279287
@property
280288
def hash_hex(self) -> str:
281289
"""Return the current stored hash in hex string format"""
282-
if self.hash is not None:
290+
if self._hash is not None:
283291
return self.hash.hex()
284292
else:
285293
return ''
@@ -332,7 +340,7 @@ def is_genesis(self) -> bool:
332340
333341
:rtype: bool
334342
"""
335-
if self.hash is None:
343+
if self._hash is None:
336344
return False
337345
from hathor.transaction.genesis import is_genesis
338346
return is_genesis(self.hash, settings=self._settings)
@@ -451,7 +459,7 @@ def can_validate_full(self) -> bool:
451459
""" Check if this transaction is ready to be fully validated, either all deps are full-valid or one is invalid.
452460
"""
453461
assert self.storage is not None
454-
assert self.hash is not None
462+
assert self._hash is not None
455463
if self.is_genesis:
456464
return True
457465
deps = self.get_all_dependencies()
@@ -608,7 +616,6 @@ def get_metadata(self, *, force_reload: bool = False, use_storage: bool = True)
608616
else:
609617
metadata = getattr(self, '_metadata', None)
610618
if not metadata and use_storage and self.storage:
611-
assert self.hash is not None
612619
metadata = self.storage.get_metadata(self.hash)
613620
self._metadata = metadata
614621
if not metadata:
@@ -619,15 +626,15 @@ def get_metadata(self, *, force_reload: bool = False, use_storage: bool = True)
619626
score = self.weight if self.is_genesis else 0
620627

621628
metadata = TransactionMetadata(
622-
hash=self.hash,
629+
hash=self._hash,
623630
accumulated_weight=self.weight,
624631
height=height,
625632
score=score,
626633
min_height=0,
627634
)
628635
self._metadata = metadata
629636
if not metadata.hash:
630-
metadata.hash = self.hash
637+
metadata.hash = self._hash
631638
metadata._tx_ref = weakref.ref(self)
632639
return metadata
633640

@@ -638,7 +645,7 @@ def reset_metadata(self) -> None:
638645
from hathor.transaction.transaction_metadata import ValidationState
639646
assert self.storage is not None
640647
score = self.weight if self.is_genesis else 0
641-
self._metadata = TransactionMetadata(hash=self.hash,
648+
self._metadata = TransactionMetadata(hash=self._hash,
642649
score=score,
643650
accumulated_weight=self.weight)
644651
if self.is_genesis:
@@ -724,7 +731,7 @@ def _update_reward_lock_metadata(self) -> None:
724731

725732
def _update_parents_children_metadata(self) -> None:
726733
"""Update the txs/block parent's children metadata."""
727-
assert self.hash is not None
734+
assert self._hash is not None
728735
assert self.storage is not None
729736

730737
for parent in self.get_parents(existing_only=True):
@@ -792,7 +799,6 @@ def to_json(self, decode_script: bool = False, include_metadata: bool = False) -
792799
return data
793800

794801
def to_json_extended(self) -> dict[str, Any]:
795-
assert self.hash is not None
796802
assert self.storage is not None
797803

798804
def serialize_output(tx: BaseTransaction, tx_out: TxOutput) -> dict[str, Any]:
@@ -824,7 +830,6 @@ def serialize_output(tx: BaseTransaction, tx_out: TxOutput) -> dict[str, Any]:
824830
tx2 = self.storage.get_transaction(tx_in.tx_id)
825831
tx2_out = tx2.outputs[tx_in.index]
826832
output = serialize_output(tx2, tx2_out)
827-
assert tx2.hash is not None
828833
output['tx_id'] = tx2.hash_hex
829834
output['index'] = tx_in.index
830835
ret['inputs'].append(output)

hathor/transaction/token_creation_tx.py

-2
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ def update_hash(self) -> None:
6565
""" When we update the hash, we also have to update the tokens uid list
6666
"""
6767
super().update_hash()
68-
assert self.hash is not None
6968
self.tokens = [self.hash]
7069

7170
def get_funds_fields_from_struct(self, buf: bytes, *, verbose: VerboseCallback = None) -> bytes:
@@ -221,7 +220,6 @@ def _get_token_info_from_inputs(self) -> dict[TokenUid, TokenInfo]:
221220
token_dict = super()._get_token_info_from_inputs()
222221

223222
# we add the created token's info to token_dict, as the creation tx allows for mint/melt
224-
assert self.hash is not None
225223
token_dict[self.hash] = TokenInfo(0, True, True)
226224

227225
return token_dict

hathor/transaction/transaction.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ def is_double_spending(self) -> bool:
360360
tx = self.storage.get_transaction(tx_in.tx_id)
361361
meta = tx.get_metadata()
362362
spent_by = meta.get_output_spent_by(tx_in.index)
363-
if spent_by and spent_by != self.hash:
363+
if spent_by and spent_by != self._hash:
364364
return True
365365
return False
366366

tests/utils.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import time
66
import urllib.parse
77
from dataclasses import dataclass
8-
from typing import Optional, cast
8+
from typing import Optional
99

1010
import requests
1111
from hathorlib.scripts import DataScript
@@ -378,7 +378,7 @@ def create_tokens(manager: 'HathorManager', address_b58: Optional[str] = None, m
378378
assert genesis_hash is not None
379379
deposit_input = [TxInput(genesis_hash, 0, b'')]
380380
change_output = TxOutput(genesis_block.outputs[0].value - deposit_amount, script, 0)
381-
parents = [cast(bytes, tx.hash) for tx in genesis_txs]
381+
parents = [tx.hash for tx in genesis_txs]
382382
timestamp = int(manager.reactor.seconds())
383383
else:
384384
total_reward = 0

0 commit comments

Comments
 (0)