@@ -94,7 +94,9 @@ def get_block_uncles(self, uncles_hash: Hash32) -> List[BlockHeader]:
94
94
# Block API
95
95
#
96
96
@abstractmethod
97
- def persist_block (self , block : 'BaseBlock' ) -> None :
97
+ def persist_block (self ,
98
+ block : 'BaseBlock'
99
+ ) -> Tuple [Tuple [bytes , ...], Tuple [bytes , ...]]:
98
100
raise NotImplementedError ("ChainDB classes must implement this method" )
99
101
100
102
@abstractmethod
@@ -186,7 +188,9 @@ def get_block_uncles(self, uncles_hash: Hash32) -> List[BlockHeader]:
186
188
187
189
# TODO: This method should take a chain of headers as that's the most common use case
188
190
# and it'd be much faster than inserting each header individually.
189
- def persist_header (self , header : BlockHeader ) -> Tuple [BlockHeader , ...]:
191
+ def persist_header (self ,
192
+ header : BlockHeader
193
+ ) -> Tuple [Tuple [BlockHeader , ...], Tuple [BlockHeader , ...]]:
190
194
"""
191
195
Returns iterable of headers newly on the canonical chain
192
196
"""
@@ -214,17 +218,26 @@ def persist_header(self, header: BlockHeader) -> Tuple[BlockHeader, ...]:
214
218
try :
215
219
head_score = self .get_score (self .get_canonical_head ().hash )
216
220
except CanonicalHeadNotFound :
217
- new_headers = self ._set_as_canonical_chain_head (header )
221
+ (
222
+ new_canonical_headers ,
223
+ orphaned_canonical_headers
224
+ ) = self ._set_as_canonical_chain_head (header )
218
225
else :
219
226
if score > head_score :
220
- new_headers = self ._set_as_canonical_chain_head (header )
227
+ (
228
+ new_canonical_headers ,
229
+ orphaned_canonical_headers
230
+ ) = self ._set_as_canonical_chain_head (header )
221
231
else :
222
- new_headers = tuple ()
232
+ new_canonical_headers = tuple ()
233
+ orphaned_canonical_headers = tuple ()
223
234
224
- return new_headers
235
+ return new_canonical_headers , orphaned_canonical_headers
225
236
226
237
# TODO: update this to take a `hash` rather than a full header object.
227
- def _set_as_canonical_chain_head (self , header : BlockHeader ) -> Tuple [BlockHeader , ...]:
238
+ def _set_as_canonical_chain_head (self ,
239
+ header : BlockHeader
240
+ ) -> Tuple [Tuple [BlockHeader , ...], Tuple [BlockHeader , ...]]:
228
241
"""
229
242
Returns iterable of headers newly on the canonical head
230
243
"""
@@ -235,7 +248,7 @@ def _set_as_canonical_chain_head(self, header: BlockHeader) -> Tuple[BlockHeader
235
248
header .hash ))
236
249
237
250
new_canonical_headers = tuple (reversed (self ._find_new_ancestors (header )))
238
-
251
+ orphaned_canonical_headers = []
239
252
# remove transaction lookups for blocks that are no longer canonical
240
253
for h in new_canonical_headers :
241
254
try :
@@ -244,29 +257,30 @@ def _set_as_canonical_chain_head(self, header: BlockHeader) -> Tuple[BlockHeader
244
257
# no old block, and no more possible
245
258
break
246
259
else :
247
- old_header = self .get_block_header_by_hash (old_hash )
248
- for transaction_hash in self .get_block_transaction_hashes (old_header ):
260
+ orphaned_header = self .get_block_header_by_hash (old_hash )
261
+ orphaned_canonical_headers .append (orphaned_header )
262
+ for transaction_hash in self .get_block_transaction_hashes (orphaned_header ):
249
263
self ._remove_transaction_from_canonical_chain (transaction_hash )
250
- # TODO re-add txn to internal pending pool (only if local sender)
251
- pass
252
264
253
265
for h in new_canonical_headers :
254
266
self ._add_block_number_to_hash_lookup (h )
255
267
256
268
self .db .set (SchemaV1 .make_canonical_head_hash_lookup_key (), header .hash )
257
269
258
- return new_canonical_headers
270
+ return new_canonical_headers , tuple ( orphaned_canonical_headers )
259
271
260
272
#
261
273
# Block API
262
274
#
263
- def persist_block (self , block : 'BaseBlock' ) -> None :
275
+ def persist_block (self ,
276
+ block : 'BaseBlock'
277
+ ) -> Tuple [Tuple [bytes , ...], Tuple [bytes , ...]]:
264
278
'''
265
279
Persist the given block's header and uncles.
266
280
267
281
Assumes all block transactions have been persisted already.
268
282
'''
269
- new_canonical_headers = self .persist_header (block .header )
283
+ new_canonical_headers , orphaned_canonical_headers = self .persist_header (block .header )
270
284
271
285
for header in new_canonical_headers :
272
286
if header .hash == block .hash :
@@ -288,6 +302,11 @@ def persist_block(self, block: 'BaseBlock') -> None:
288
302
raise ValidationError (
289
303
"Block's uncles_hash (%s) does not match actual uncles' hash (%s)" ,
290
304
block .header .uncles_hash , uncles_hash )
305
+ new_canonical_header_hashes = tuple (header .hash for header in new_canonical_headers )
306
+ orphaned_canonical_header_hashes = tuple (
307
+ header .hash for header in orphaned_canonical_headers )
308
+
309
+ return new_canonical_header_hashes , orphaned_canonical_header_hashes
291
310
292
311
def persist_uncles (self , uncles : Tuple [BlockHeader ]) -> Hash32 :
293
312
"""
0 commit comments