1616import  stat 
1717import  plyvel 
1818
19+ from  blockchain_parser .transaction  import  Transaction 
20+ from  blockchain_parser .index  import  DBTransactionIndex 
21+ from  blockchain_parser  import  utils 
22+ from  binascii  import  unhexlify 
23+ from  binascii  import  hexlify 
1924from  .block  import  Block 
2025from  .index  import  DBBlockIndex 
2126from  .utils  import  format_hash 
@@ -146,7 +151,6 @@ def _index_confirmed(self, chain_indexes, num_confirmations=6):
146151                if  len (chain ) ==  num_confirmations :
147152                    return  first_block .hash  in  chain 
148153
149- 
150154    def  get_ordered_blocks (self , index , start = 0 , end = None , cache = None ):
151155        """Yields the blocks contained in the .blk files as per 
152156        the heigt extract from the leveldb index present at path 
@@ -168,8 +172,8 @@ def get_ordered_blocks(self, index, start=0, end=None, cache=None):
168172                with  open (cache , 'wb' ) as  f :
169173                    pickle .dump (blockIndexes , f )
170174
171-         # remove small forks that may have occured  while the node was live. 
172-         # Occassionally  a node will receive two different solutions to a block 
175+         # remove small forks that may have occurred  while the node was live. 
176+         # Occasionally  a node will receive two different solutions to a block 
173177        # at the same time. The Leveldb index saves both, not pruning the 
174178        # block that leads to a shorter chain once the fork is settled without 
175179        # "-reindex"ing the bitcoind block data. This leads to at least two 
@@ -217,3 +221,36 @@ def get_ordered_blocks(self, index, start=0, end=None, cache=None):
217221                break 
218222            blkFile  =  os .path .join (self .path , "blk%05d.dat"  %  blkIdx .file )
219223            yield  Block (get_block (blkFile , blkIdx .data_pos ), blkIdx .height )
224+ 
225+     def  get_transaction (self , txid , db ):
226+         """Yields the transaction contained in the .blk files as a python 
227+          object, similar to 
228+          https://developer.bitcoin.org/reference/rpc/getrawtransaction.html 
229+         """ 
230+ 
231+         byte_arr  =  bytearray .fromhex (txid )
232+         byte_arr .reverse ()
233+         tx_hash  =  hexlify (b't' ).decode ('utf-8' ) +  \
234+             hexlify (byte_arr ).decode ('utf-8' )
235+ 
236+         tx_hash_fmtd  =  unhexlify (tx_hash )
237+         raw_hex  =  db .get (tx_hash_fmtd )
238+ 
239+         tx_idx  =  DBTransactionIndex (utils .format_hash (tx_hash_fmtd ), raw_hex )
240+         blk_file  =  os .path .join (self .path , "blk%05d.dat"  %  tx_idx .blockfile_no )
241+         raw_hex  =  get_block (blk_file , tx_idx .file_offset )
242+ 
243+         offset  =  tx_idx .block_offset 
244+ 
245+         transaction_data  =  raw_hex [80 :]
246+         # Try from 1024 (1KiB) -> 1073741824 (1GiB) slice widths 
247+         for  j  in  range (0 , 20 ):
248+             try :
249+                 offset_e  =  offset  +  (1024  *  2  **  j )
250+                 transaction  =  Transaction .from_hex (
251+                     transaction_data [offset :offset_e ])
252+                 return  transaction 
253+             except  Exception :
254+                 continue 
255+ 
256+         return  None 
0 commit comments