@api_request
async def request_additions(self, request: wallet_protocol.RequestAdditions) -> Optional[Message]:
    if (request.header_hash is None):
        header_hash: Optional[bytes32] = self.full_node.blockchain.height_to_hash(request.height)
    else:
        header_hash = request.header_hash
    if (header_hash is None):
        raise ValueError(f'Block at height {request.height} not found')
    block: Optional[FullBlock] = (await self.full_node.block_store.get_full_block(header_hash))
    if ((block is None) or (block.is_transaction_block() is False) or (self.full_node.blockchain.height_to_hash(block.height) != request.header_hash)):
        reject = wallet_protocol.RejectAdditionsRequest(request.height, header_hash)
        msg = make_msg(ProtocolMessageTypes.reject_additions_request, reject)
        return msg
    assert ((block is not None) and (block.foliage_transaction_block is not None))
    additions = (await self.full_node.coin_store.get_coins_added_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')
    puzzlehash_coins_map: Dict[(bytes32, List[Coin])] = {}
    for coin_record in additions:
        if (coin_record.coin.puzzle_hash in puzzlehash_coins_map):
            puzzlehash_coins_map[coin_record.coin.puzzle_hash].append(coin_record.coin)
        else:
            puzzlehash_coins_map[coin_record.coin.puzzle_hash] = [coin_record.coin]
    coins_map: List[Tuple[(bytes32, List[Coin])]] = []
    proofs_map: List[Tuple[(bytes32, bytes, Optional[bytes])]] = []
    if (request.puzzle_hashes is None):
        for (puzzle_hash, coins) in puzzlehash_coins_map.items():
            coins_map.append((puzzle_hash, coins))
        response = wallet_protocol.RespondAdditions(block.height, block.header_hash, coins_map, None)
    else:
        addition_merkle_set = MerkleSet()
        for (puzzle, coins) in puzzlehash_coins_map.items():
            addition_merkle_set.add_already_hashed(puzzle)
            addition_merkle_set.add_already_hashed(hash_coin_list(coins))
        assert (addition_merkle_set.get_root() == block.foliage_transaction_block.additions_root)
        for puzzle_hash in request.puzzle_hashes:
            (result, proof) = addition_merkle_set.is_included_already_hashed(puzzle_hash)
            if (puzzle_hash in puzzlehash_coins_map):
                coins_map.append((puzzle_hash, puzzlehash_coins_map[puzzle_hash]))
                hash_coin_str = hash_coin_list(puzzlehash_coins_map[puzzle_hash])
                (result_2, proof_2) = addition_merkle_set.is_included_already_hashed(hash_coin_str)
                assert result
                assert result_2
                proofs_map.append((puzzle_hash, proof, proof_2))
            else:
                coins_map.append((puzzle_hash, []))
                assert (not result)
                proofs_map.append((puzzle_hash, proof, None))
        response = wallet_protocol.RespondAdditions(block.height, block.header_hash, coins_map, proofs_map)
    msg = make_msg(ProtocolMessageTypes.respond_additions, response)
    return msg
@api_request
async def request_additions(self, request: wallet_protocol.RequestAdditions) -> Optional[Message]:
    if (request.header_hash is None):
        header_hash: Optional[bytes32] = self.full_node.blockchain.height_to_hash(request.height)
    else:
        header_hash = request.header_hash
    if (header_hash is None):
        raise ValueError(f'Block at height {request.height} not found')
    block: Optional[FullBlock] = (await self.full_node.block_store.get_full_block(header_hash))
    if ((block is None) or (block.is_transaction_block() is False) or (self.full_node.blockchain.height_to_hash(block.height) != request.header_hash)):
        reject = wallet_protocol.RejectAdditionsRequest(request.height, header_hash)
        msg = make_msg(ProtocolMessageTypes.reject_additions_request, reject)
        return msg
    assert ((block is not None) and (block.foliage_transaction_block is not None))
    additions = (await self.full_node.coin_store.get_coins_added_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')
    puzzlehash_coins_map: Dict[(bytes32, List[Coin])] = {}
    for coin_record in additions:
        if (coin_record.coin.puzzle_hash in puzzlehash_coins_map):
            puzzlehash_coins_map[coin_record.coin.puzzle_hash].append(coin_record.coin)
        else:
            puzzlehash_coins_map[coin_record.coin.puzzle_hash] = [coin_record.coin]
    coins_map: List[Tuple[(bytes32, List[Coin])]] = []
    proofs_map: List[Tuple[(bytes32, bytes, Optional[bytes])]] = []
    if (request.puzzle_hashes is None):
        for (puzzle_hash, coins) in puzzlehash_coins_map.items():
            coins_map.append((puzzle_hash, coins))
        response = wallet_protocol.RespondAdditions(block.height, block.header_hash, coins_map, None)
    else:
        addition_merkle_set = MerkleSet()
        for (puzzle, coins) in puzzlehash_coins_map.items():
            addition_merkle_set.add_already_hashed(puzzle)
            addition_merkle_set.add_already_hashed(hash_coin_list(coins))
        assert (addition_merkle_set.get_root() == block.foliage_transaction_block.additions_root)
        for puzzle_hash in request.puzzle_hashes:
            (result, proof) = addition_merkle_set.is_included_already_hashed(puzzle_hash)
            if (puzzle_hash in puzzlehash_coins_map):
                coins_map.append((puzzle_hash, puzzlehash_coins_map[puzzle_hash]))
                hash_coin_str = hash_coin_list(puzzlehash_coins_map[puzzle_hash])
                (result_2, proof_2) = addition_merkle_set.is_included_already_hashed(hash_coin_str)
                assert result
                assert result_2
                proofs_map.append((puzzle_hash, proof, proof_2))
            else:
                coins_map.append((puzzle_hash, []))
                assert (not result)
                proofs_map.append((puzzle_hash, proof, None))
        response = wallet_protocol.RespondAdditions(block.height, block.header_hash, coins_map, proofs_map)
    msg = make_msg(ProtocolMessageTypes.respond_additions, response)
    return msg