@@ -258,11 +258,12 @@ def __init__(self,
258
258
self .block = None
259
259
super (BlockHeader , self ).__init__ (** fields )
260
260
261
-
262
261
@classmethod
263
262
def from_block_rlp (self , rlp_data ):
264
263
block_data = rlp .decode_lazy (rlp_data )
265
- return super (BlockHeader , self ).deserialize (block_data [0 ])
264
+ r = super (BlockHeader , self ).deserialize (block_data [0 ])
265
+ assert isinstance (r , BlockHeader )
266
+ return r
266
267
267
268
@property
268
269
def state_root (self ):
@@ -306,10 +307,12 @@ def receipts_root(self, value):
306
307
else :
307
308
self ._receipts_root = value
308
309
310
+ _fimxe_hash = None
311
+
309
312
@property
310
313
def hash (self ):
311
314
"""The binary block hash"""
312
- return utils .sha3 (rlp .encode (self ))
315
+ return self . _fimxe_hash or utils .sha3 (rlp .encode (self ))
313
316
314
317
def hex_hash (self ):
315
318
"""The hex encoded block hash"""
@@ -458,7 +461,7 @@ def __init__(self, header, transaction_list=[], uncles=[], db=None,
458
461
459
462
# do some consistency checks on parent if given
460
463
if parent :
461
- if self .db != parent .db :
464
+ if hasattr ( parent , 'db' ) and self .db != parent .db :
462
465
raise ValueError ("Parent lives in different database" )
463
466
if self .prevhash != parent .header .hash :
464
467
raise ValueError ("Block's prevhash and parent's hash do not match" )
@@ -486,12 +489,12 @@ def __init__(self, header, transaction_list=[], uncles=[], db=None,
486
489
state_unknown = (header .prevhash != GENESIS_PREVHASH and
487
490
header .state_root != trie .BLANK_ROOT and
488
491
(len (header .state_root ) != 32 or
489
- 'validated:' + self .hash not in db ) and
492
+ 'validated:' + self .hash not in db ) and
490
493
not making )
491
494
if state_unknown :
492
495
assert transaction_list is not None
493
496
if not parent :
494
- parent = self .get_parent ()
497
+ parent = self .get_parent_header ()
495
498
self .state = SecureTrie (Trie (db , parent .state_root ))
496
499
self .transaction_count = 0
497
500
self .gas_used = 0
@@ -1190,6 +1193,17 @@ def get_parent(self):
1190
1193
# assert parent.state.db.db == self.state.db.db
1191
1194
return parent
1192
1195
1196
+ def get_parent_header (self ):
1197
+ """Get the parent of this block."""
1198
+ if self .number == 0 :
1199
+ raise UnknownParentException ('Genesis block has no parent' )
1200
+ try :
1201
+ parent_header = get_block_header (self .db , self .prevhash )
1202
+ except KeyError :
1203
+ raise UnknownParentException (encode_hex (self .prevhash ))
1204
+ # assert parent.state.db.db == self.state.db.db
1205
+ return parent_header
1206
+
1193
1207
def has_parent (self ):
1194
1208
"""`True` if this block has a known parent, otherwise `False`."""
1195
1209
try :
@@ -1296,6 +1310,15 @@ def create_cached(cls, blk):
1296
1310
return blk
1297
1311
1298
1312
1313
+ def get_block_header (db , blockhash ):
1314
+ bh = BlockHeader .from_block_rlp (db .get (blockhash ))
1315
+ if bh .hash != blockhash :
1316
+ log .warn ('BlockHeader.hash is broken' )
1317
+ bh ._fimxe_hash = blockhash
1318
+
1319
+ return bh
1320
+
1321
+
1299
1322
@lru_cache (500 )
1300
1323
def get_block (db , blockhash ):
1301
1324
"""
0 commit comments