@@ -71,116 +71,144 @@ def __init__(
71
71
self ._pubsub = pubsub
72
72
self ._wallet = wallet
73
73
74
- def on_new_tx (
74
+ def on_new_vertex (
75
75
self ,
76
- tx : BaseTransaction ,
76
+ vertex : BaseTransaction ,
77
77
* ,
78
78
quiet : bool = False ,
79
79
fails_silently : bool = True ,
80
80
propagate_to_peers : bool = True ,
81
- reject_locked_reward : bool = True
81
+ reject_locked_reward : bool = True ,
82
82
) -> bool :
83
83
""" New method for adding transactions or blocks that steps the validation state machine.
84
84
85
- :param tx : transaction to be added
85
+ :param vertex : transaction to be added
86
86
:param quiet: if True will not log when a new tx is accepted
87
87
:param fails_silently: if False will raise an exception when tx cannot be added
88
88
:param propagate_to_peers: if True will relay the tx to other peers if it is accepted
89
89
"""
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
92
108
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 ()
93
117
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 )
96
120
already_exists = True
97
121
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 :
99
123
if not fails_silently :
100
124
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 )
104
128
return False
105
129
106
- assert self ._tx_storage .indexes is not None
107
- tx .storage = self ._tx_storage
130
+ vertex .storage = self ._tx_storage
108
131
109
132
try :
110
- metadata = tx .get_metadata ()
133
+ metadata = vertex .get_metadata ()
111
134
except TransactionDoesNotExist :
112
135
if not fails_silently :
113
136
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 )
115
138
return False
116
139
117
140
if already_exists and metadata .validation .is_fully_connected ():
118
141
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 )
121
144
return False
122
145
123
146
if metadata .validation .is_invalid ():
124
147
if not fails_silently :
125
148
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 )
127
150
return False
128
151
129
152
if not metadata .validation .is_fully_connected ():
130
153
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 )
132
155
except HathorError as e :
133
156
if not fails_silently :
134
157
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 )
136
159
return False
137
160
161
+ return True
162
+
163
+ def _save_and_run_consensus (self , vertex : BaseTransaction ) -> None :
138
164
# The method below adds the tx as a child of the parents
139
165
# This needs to be called right before the save because we were adding the children
140
166
# in the tx parents even if the tx was invalid (failing the verifications above)
141
167
# 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 )
146
172
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 :
164
181
""" Handle operations that need to happen once the tx becomes fully validated.
165
182
166
183
This might happen immediately after we receive the tx, if we have all dependencies
167
184
already. Or it might happen later.
168
185
"""
169
- assert tx .hash is not None
170
186
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
171
195
172
196
# 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 )
174
198
175
199
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 )
177
201
178
202
if self ._wallet :
179
203
# 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 )
181
208
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 )
184
212
185
213
def _log_new_object (self , tx : BaseTransaction , message_fmt : str , * , quiet : bool ) -> None :
186
214
""" A shortcut for logging additional information for block/txs.
0 commit comments