@api_request
async def request_removals(self, request: wallet_protocol.RequestRemovals) -> Optional[Message]:
    block: Optional[FullBlock] = (await self.full_node.block_store.get_full_block(request.header_hash))
    peak_height = self.full_node.blockchain.get_peak_height()
    if ((block is None) or (block.is_transaction_block() is False) or (block.height != request.height) or ((peak_height is not None) and (block.height > peak_height)) or (self.full_node.blockchain.height_to_hash(block.height) != request.header_hash)):
        reject = wallet_protocol.RejectRemovalsRequest(request.height, request.header_hash)
        msg = make_msg(ProtocolMessageTypes.reject_removals_request, reject)
        return msg
    assert ((block is not None) and (block.foliage_transaction_block is not None))
    all_removals: List[CoinRecord] = (await self.full_node.coin_store.get_coins_removed_at_height(block.height))
    if (self.full_node.blockchain.height_to_hash(block.height) != request.header_hash):
        raise ValueError(f'Block {block.header_hash} no longer in chain')
    all_removals_dict: Dict[(bytes32, Coin)] = {}
    for coin_record in all_removals:
        all_removals_dict[coin_record.coin.name()] = coin_record.coin
    coins_map: List[Tuple[(bytes32, Optional[Coin])]] = []
    proofs_map: List[Tuple[(bytes32, bytes)]] = []
    if (block.transactions_generator is None):
        proofs: Optional[List]
        if (request.coin_names is None):
            proofs = None
        else:
            proofs = []
        response = wallet_protocol.RespondRemovals(block.height, block.header_hash, [], proofs)
    elif ((request.coin_names is None) or (len(request.coin_names) == 0)):
        for (removed_name, removed_coin) in all_removals_dict.items():
            coins_map.append((removed_name, removed_coin))
        response = wallet_protocol.RespondRemovals(block.height, block.header_hash, coins_map, None)
    else:
        assert block.transactions_generator
        removal_merkle_set = MerkleSet()
        for (removed_name, removed_coin) in all_removals_dict.items():
            removal_merkle_set.add_already_hashed(removed_name)
        assert (removal_merkle_set.get_root() == block.foliage_transaction_block.removals_root)
        for coin_name in request.coin_names:
            (result, proof) = removal_merkle_set.is_included_already_hashed(coin_name)
            proofs_map.append((coin_name, proof))
            if (coin_name in all_removals_dict):
                removed_coin = all_removals_dict[coin_name]
                coins_map.append((coin_name, removed_coin))
                assert result
            else:
                coins_map.append((coin_name, None))
                assert (not result)
        response = wallet_protocol.RespondRemovals(block.height, block.header_hash, coins_map, proofs_map)
    msg = make_msg(ProtocolMessageTypes.respond_removals, response)
    return msg
@api_request
async def request_removals(self, request: wallet_protocol.RequestRemovals) -> Optional[Message]:
    block: Optional[FullBlock] = (await self.full_node.block_store.get_full_block(request.header_hash))
    peak_height = self.full_node.blockchain.get_peak_height()
    if ((block is None) or (block.is_transaction_block() is False) or (block.height != request.height) or ((peak_height is not None) and (block.height > peak_height)) or (self.full_node.blockchain.height_to_hash(block.height) != request.header_hash)):
        reject = wallet_protocol.RejectRemovalsRequest(request.height, request.header_hash)
        msg = make_msg(ProtocolMessageTypes.reject_removals_request, reject)
        return msg
    assert ((block is not None) and (block.foliage_transaction_block is not None))
    all_removals: List[CoinRecord] = (await self.full_node.coin_store.get_coins_removed_at_height(block.height))
    if (self.full_node.blockchain.height_to_hash(block.height) != request.header_hash):
        raise ValueError(f'Block {block.header_hash} no longer in chain')
    all_removals_dict: Dict[(bytes32, Coin)] = {}
    for coin_record in all_removals:
        all_removals_dict[coin_record.coin.name()] = coin_record.coin
    coins_map: List[Tuple[(bytes32, Optional[Coin])]] = []
    proofs_map: List[Tuple[(bytes32, bytes)]] = []
    if (block.transactions_generator is None):
        proofs: Optional[List]
        if (request.coin_names is None):
            proofs = None
        else:
            proofs = []
        response = wallet_protocol.RespondRemovals(block.height, block.header_hash, [], proofs)
    elif ((request.coin_names is None) or (len(request.coin_names) == 0)):
        for (removed_name, removed_coin) in all_removals_dict.items():
            coins_map.append((removed_name, removed_coin))
        response = wallet_protocol.RespondRemovals(block.height, block.header_hash, coins_map, None)
    else:
        assert block.transactions_generator
        removal_merkle_set = MerkleSet()
        for (removed_name, removed_coin) in all_removals_dict.items():
            removal_merkle_set.add_already_hashed(removed_name)
        assert (removal_merkle_set.get_root() == block.foliage_transaction_block.removals_root)
        for coin_name in request.coin_names:
            (result, proof) = removal_merkle_set.is_included_already_hashed(coin_name)
            proofs_map.append((coin_name, proof))
            if (coin_name in all_removals_dict):
                removed_coin = all_removals_dict[coin_name]
                coins_map.append((coin_name, removed_coin))
                assert result
            else:
                coins_map.append((coin_name, None))
                assert (not result)
        response = wallet_protocol.RespondRemovals(block.height, block.header_hash, coins_map, proofs_map)
    msg = make_msg(ProtocolMessageTypes.respond_removals, response)
    return msg