def get_transaction_by_index( self, block_number: BlockNumber, transaction_index: int, transaction_class: Type['BaseTransaction']) -> 'BaseTransaction': """ Returns the transaction at the specified `transaction_index` from the block specified by `block_number` from the canonical chain. Raises TransactionNotFound if no block """ try: block_header = self.get_canonical_block_header_by_number( block_number) except HeaderNotFound: raise TransactionNotFound( "Block {} is not in the canonical chain".format(block_number)) transaction_db = HexaryTrie(self.db, root_hash=block_header.transaction_root) encoded_index = rlp.encode(transaction_index) if encoded_index in transaction_db: encoded_transaction = transaction_db[encoded_index] return rlp.decode(encoded_transaction, sedes=transaction_class) else: raise TransactionNotFound( "No transaction is at index {} of block {}".format( transaction_index, block_number))
def get_transaction_by_index( self, block_number: BlockNumber, transaction_index: int, transaction_class: Type[SignedTransactionAPI] ) -> SignedTransactionAPI: """ Returns the transaction at the specified `transaction_index` from the block specified by `block_number` from the canonical chain. Raises TransactionNotFound if no block """ try: block_header = self.get_canonical_block_header_by_number( block_number) except HeaderNotFound: raise TransactionNotFound( f"Block {block_number} is not in the canonical chain") transaction_db = HexaryTrie(self.db, root_hash=block_header.transaction_root) encoded_index = rlp.encode(transaction_index) encoded_transaction = transaction_db[encoded_index] if encoded_transaction != b'': return rlp.decode(encoded_transaction, sedes=transaction_class) else: raise TransactionNotFound( f"No transaction is at index {transaction_index} of block {block_number}" )
def get_canonical_transaction(self, transaction_hash: Hash32) -> BaseTransaction: """ Returns the requested transaction as specified by the transaction hash from the canonical chain. Raises TransactionNotFound if no transaction with the specified hash is found in the main chain. """ (block_num, index) = self.chaindb.get_transaction_index(transaction_hash) VM = self.get_vm_class_for_block_number(block_num) transaction = self.chaindb.get_transaction_by_index( block_num, index, VM.get_transaction_class(), ) if transaction.hash == transaction_hash: return transaction else: raise TransactionNotFound("Found transaction {} instead of {} in block {} at {}".format( encode_hex(transaction.hash), encode_hex(transaction_hash), block_num, index, ))
def get_canonical_transaction( self, transaction_hash: Hash32) -> SignedTransactionAPI: """ Returns the requested transaction as specified by the transaction hash from the canonical chain. Raises TransactionNotFound if no transaction with the specified hash is found in the main chain. """ (block_num, index) = self.chaindb.get_transaction_index(transaction_hash) VM_class = self.get_vm_class_for_block_number(block_num) transaction = self.chaindb.get_transaction_by_index( block_num, index, VM_class.get_transaction_class(), ) if transaction.hash == transaction_hash: return transaction else: raise TransactionNotFound( f"Found transaction {encode_hex(transaction.hash)} " f"instead of {encode_hex(transaction_hash)} in block {block_num} at {index}" )
def get_transaction_by_index( self, block_number: BlockNumber, transaction_index: int, transaction_builder: Type[TransactionBuilderAPI]) -> SignedTransactionAPI: try: block_header = self.get_canonical_block_header_by_number(block_number) except HeaderNotFound: raise TransactionNotFound(f"Block {block_number} is not in the canonical chain") transaction_db = HexaryTrie(self.db, root_hash=block_header.transaction_root) encoded_index = rlp.encode(transaction_index) encoded_transaction = transaction_db[encoded_index] if encoded_transaction != b'': return rlp.decode(encoded_transaction, sedes=transaction_builder) else: raise TransactionNotFound( f"No transaction is at index {transaction_index} of block {block_number}" )
def get_transaction_index(self, transaction_hash: Hash32) -> Tuple[BlockNumber, int]: key = SchemaV1.make_transaction_hash_to_block_lookup_key(transaction_hash) try: encoded_key = self.db[key] except KeyError: raise TransactionNotFound( f"Transaction {encode_hex(transaction_hash)} not found in canonical chain" ) transaction_key = rlp.decode(encoded_key, sedes=TransactionKey) return (transaction_key.block_number, transaction_key.index)
def get_canonical_transaction(self, transaction_hash: Hash32) -> SignedTransactionAPI: (block_num, index) = self.chaindb.get_transaction_index(transaction_hash) transaction = self.get_canonical_transaction_by_index(block_num, index) if transaction.hash == transaction_hash: return transaction else: raise TransactionNotFound( f"Found transaction {encode_hex(transaction.hash)} " f"instead of {encode_hex(transaction_hash)} in block {block_num} at {index}" )
def get_transaction_index(self, transaction_hash: Hash32) -> Tuple[BlockNumber, int]: """ Returns a 2-tuple of (block_number, transaction_index) indicating which block the given transaction can be found in and at what index in the block transactions. Raises TransactionNotFound if the transaction_hash is not found in the canonical chain. """ key = SchemaV1.make_transaction_hash_to_block_lookup_key(transaction_hash) try: encoded_key = self.db[key] except KeyError: raise TransactionNotFound( "Transaction {} not found in canonical chain".format(encode_hex(transaction_hash))) transaction_key = rlp.decode(encoded_key, sedes=TransactionKey) return (transaction_key.block_number, transaction_key.index)