Skip to content

Commit d3f444f

Browse files
committed
refactor(vertex-handler): modularize methods
1 parent 1a598bc commit d3f444f

File tree

2 files changed

+77
-49
lines changed

2 files changed

+77
-49
lines changed

hathor/manager.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -957,7 +957,7 @@ def on_new_tx(
957957
:param fails_silently: if False will raise an exception when tx cannot be added
958958
:param propagate_to_peers: if True will relay the tx to other peers if it is accepted
959959
"""
960-
return self.vertex_handler.on_new_tx(
960+
return self.vertex_handler.on_new_vertex(
961961
tx,
962962
quiet=quiet,
963963
fails_silently=fails_silently,

hathor/vertex_handler/vertex_handler.py

Lines changed: 76 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -71,116 +71,144 @@ def __init__(
7171
self._pubsub = pubsub
7272
self._wallet = wallet
7373

74-
def on_new_tx(
74+
def on_new_vertex(
7575
self,
76-
tx: BaseTransaction,
76+
vertex: BaseTransaction,
7777
*,
7878
quiet: bool = False,
7979
fails_silently: bool = True,
8080
propagate_to_peers: bool = True,
81-
reject_locked_reward: bool = True
81+
reject_locked_reward: bool = True,
8282
) -> bool:
8383
""" New method for adding transactions or blocks that steps the validation state machine.
8484
85-
:param tx: transaction to be added
85+
:param vertex: transaction to be added
8686
:param quiet: if True will not log when a new tx is accepted
8787
:param fails_silently: if False will raise an exception when tx cannot be added
8888
:param propagate_to_peers: if True will relay the tx to other peers if it is accepted
8989
"""
90-
assert self._tx_storage.is_only_valid_allowed()
91-
assert tx.hash is not None
90+
is_valid = self._validate_vertex(
91+
vertex,
92+
fails_silently=fails_silently,
93+
reject_locked_reward=reject_locked_reward
94+
)
95+
96+
if not is_valid:
97+
return False
98+
99+
self._save_and_run_consensus(vertex)
100+
self._post_consensus(
101+
vertex,
102+
quiet=quiet,
103+
propagate_to_peers=propagate_to_peers,
104+
reject_locked_reward=reject_locked_reward
105+
)
106+
107+
return True
92108

109+
def _validate_vertex(
110+
self,
111+
vertex: BaseTransaction,
112+
*,
113+
fails_silently: bool,
114+
reject_locked_reward: bool,
115+
) -> bool:
116+
assert self._tx_storage.is_only_valid_allowed()
93117
already_exists = False
94-
if self._tx_storage.transaction_exists(tx.hash):
95-
self._tx_storage.compare_bytes_with_local_tx(tx)
118+
if self._tx_storage.transaction_exists(vertex.hash):
119+
self._tx_storage.compare_bytes_with_local_tx(vertex)
96120
already_exists = True
97121

98-
if tx.timestamp - self._reactor.seconds() > self._settings.MAX_FUTURE_TIMESTAMP_ALLOWED:
122+
if vertex.timestamp - self._reactor.seconds() > self._settings.MAX_FUTURE_TIMESTAMP_ALLOWED:
99123
if not fails_silently:
100124
raise InvalidNewTransaction('Ignoring transaction in the future {} (timestamp={})'.format(
101-
tx.hash_hex, tx.timestamp))
102-
self._log.warn('on_new_tx(): Ignoring transaction in the future', tx=tx.hash_hex,
103-
future_timestamp=tx.timestamp)
125+
vertex.hash_hex, vertex.timestamp))
126+
self._log.warn('on_new_tx(): Ignoring transaction in the future', tx=vertex.hash_hex,
127+
future_timestamp=vertex.timestamp)
104128
return False
105129

106-
assert self._tx_storage.indexes is not None
107-
tx.storage = self._tx_storage
130+
vertex.storage = self._tx_storage
108131

109132
try:
110-
metadata = tx.get_metadata()
133+
metadata = vertex.get_metadata()
111134
except TransactionDoesNotExist:
112135
if not fails_silently:
113136
raise InvalidNewTransaction('cannot get metadata')
114-
self._log.warn('on_new_tx(): cannot get metadata', tx=tx.hash_hex)
137+
self._log.warn('on_new_tx(): cannot get metadata', tx=vertex.hash_hex)
115138
return False
116139

117140
if already_exists and metadata.validation.is_fully_connected():
118141
if not fails_silently:
119-
raise InvalidNewTransaction('Transaction already exists {}'.format(tx.hash_hex))
120-
self._log.warn('on_new_tx(): Transaction already exists', tx=tx.hash_hex)
142+
raise InvalidNewTransaction('Transaction already exists {}'.format(vertex.hash_hex))
143+
self._log.warn('on_new_tx(): Transaction already exists', tx=vertex.hash_hex)
121144
return False
122145

123146
if metadata.validation.is_invalid():
124147
if not fails_silently:
125148
raise InvalidNewTransaction('previously marked as invalid')
126-
self._log.warn('on_new_tx(): previously marked as invalid', tx=tx.hash_hex)
149+
self._log.warn('on_new_tx(): previously marked as invalid', tx=vertex.hash_hex)
127150
return False
128151

129152
if not metadata.validation.is_fully_connected():
130153
try:
131-
self._verification_service.validate_full(tx, reject_locked_reward=reject_locked_reward)
154+
self._verification_service.validate_full(vertex, reject_locked_reward=reject_locked_reward)
132155
except HathorError as e:
133156
if not fails_silently:
134157
raise InvalidNewTransaction('full validation failed') from e
135-
self._log.warn('on_new_tx(): full validation failed', tx=tx.hash_hex, exc_info=True)
158+
self._log.warn('on_new_tx(): full validation failed', tx=vertex.hash_hex, exc_info=True)
136159
return False
137160

161+
return True
162+
163+
def _save_and_run_consensus(self, vertex: BaseTransaction) -> None:
138164
# The method below adds the tx as a child of the parents
139165
# This needs to be called right before the save because we were adding the children
140166
# in the tx parents even if the tx was invalid (failing the verifications above)
141167
# then I would have a children that was not in the storage
142-
tx.update_initial_metadata(save=False)
143-
self._tx_storage.save_transaction(tx)
144-
self._tx_storage.add_to_indexes(tx)
145-
self._consensus.update(tx)
168+
vertex.update_initial_metadata(save=False)
169+
self._tx_storage.save_transaction(vertex)
170+
self._tx_storage.add_to_indexes(vertex)
171+
self._consensus.update(vertex)
146172

147-
assert self._verification_service.validate_full(
148-
tx,
149-
skip_block_weight_verification=True,
150-
reject_locked_reward=reject_locked_reward
151-
)
152-
self._tx_storage.indexes.update(tx)
153-
if self._tx_storage.indexes.mempool_tips:
154-
self._tx_storage.indexes.mempool_tips.update(tx) # XXX: move to indexes.update
155-
self.tx_fully_validated(tx, quiet=quiet)
156-
157-
if propagate_to_peers:
158-
# Propagate to our peers.
159-
self._p2p_manager.send_tx_to_peers(tx)
160-
161-
return True
162-
163-
def tx_fully_validated(self, tx: BaseTransaction, *, quiet: bool) -> None:
173+
def _post_consensus(
174+
self,
175+
vertex: BaseTransaction,
176+
*,
177+
quiet: bool,
178+
propagate_to_peers: bool,
179+
reject_locked_reward: bool,
180+
) -> None:
164181
""" Handle operations that need to happen once the tx becomes fully validated.
165182
166183
This might happen immediately after we receive the tx, if we have all dependencies
167184
already. Or it might happen later.
168185
"""
169-
assert tx.hash is not None
170186
assert self._tx_storage.indexes is not None
187+
assert self._verification_service.validate_full(
188+
vertex,
189+
skip_block_weight_verification=True,
190+
reject_locked_reward=reject_locked_reward
191+
)
192+
self._tx_storage.indexes.update(vertex)
193+
if self._tx_storage.indexes.mempool_tips:
194+
self._tx_storage.indexes.mempool_tips.update(vertex) # XXX: move to indexes.update
171195

172196
# Publish to pubsub manager the new tx accepted, now that it's full validated
173-
self._pubsub.publish(HathorEvents.NETWORK_NEW_TX_ACCEPTED, tx=tx)
197+
self._pubsub.publish(HathorEvents.NETWORK_NEW_TX_ACCEPTED, tx=vertex)
174198

175199
if self._tx_storage.indexes.mempool_tips:
176-
self._tx_storage.indexes.mempool_tips.update(tx)
200+
self._tx_storage.indexes.mempool_tips.update(vertex)
177201

178202
if self._wallet:
179203
# TODO Remove it and use pubsub instead.
180-
self._wallet.on_new_tx(tx)
204+
self._wallet.on_new_tx(vertex)
205+
206+
self._log_new_object(vertex, 'new {}', quiet=quiet)
207+
self._log_feature_states(vertex)
181208

182-
self._log_new_object(tx, 'new {}', quiet=quiet)
183-
self._log_feature_states(tx)
209+
if propagate_to_peers:
210+
# Propagate to our peers.
211+
self._p2p_manager.send_tx_to_peers(vertex)
184212

185213
def _log_new_object(self, tx: BaseTransaction, message_fmt: str, *, quiet: bool) -> None:
186214
""" A shortcut for logging additional information for block/txs.

0 commit comments

Comments
 (0)