In the IRI `Node` class, this code segment checks to see if the requested transaction hash is the same as the received transaction hash: 

https://github.com/iotaledger/iri/blob/dev/src/main/java/com/iota/iri/network/Node.java#L284


    //Request bytes    
    //add request to reply queue (requestedHash, neighbor)
    Hash requestedHash = new Hash(receivedData, TransactionViewModel.SIZE, reqHashSize);
    if (requestedHash.equals(receivedTransactionHash)) {
         //requesting a random tip
         requestedHash = Hash.NULL_HASH;
    }


How is it possible for the request hash to be part of the received transaction hash since the received transaction hash is not known until the transaction is made?

Perhaps I am missing some detail - can someone please explain the purpose of this.


----------


History of This Code Segment
============================

After the first submitted answer below, and after Come_From_Beyond made some comments, I did some digging to see the commit history of this code.

According to the earliest available commits for the  `Node` class, when the transaction hash and the requested hash were the same, the request was to be the Milestone that is requested. Perhaps someone can shed some light on why this existed like this and why it was changed.

**Oct 24, 2016 - If the requested hash is same, then return a Milestone**
https://github.com/iotaledger/iri/blob/5db789222fabd11a9880b457b2b9f24cd783789f/src/iri/Node.java#L90



    if (Arrays.equals(requestedTransaction, receivedTransaction.hash)) {
        transactionPointer = Storage.transactionPointer(Milestone.latestMilestone.bytes);
    } else {
        transactionPointer = Storage.transactionPointer(requestedTransaction);
    }

**Dec 23, 2016 - Introduces Concept of 'Experimental Random Tip Broadcaster'**
https://github.com/iotaledger/iri/blob/577f2ad2db561a4044cbf9a81beae15da599d2ab/src/main/java/com/iota/iri/service/Node.java#L201

    if (Arrays.equals(requestedTransaction, receivedTransaction.hash)) {

        if (Configuration.booling(DefaultConfSettings.EXPERIMENTAL) &&
            ++randomTipBroadcastCounter % 3 == 0) {
            log.info("Experimental: Random Tip Broadcaster.");

            final String [] tips = StorageTransactions.instance().tips().stream()
                .map(Hash::toString)
                .toArray(size -> new String[size]);
            final String rndTipHash = tips[rnd.nextInt(tips.length)];

            transactionPointer = StorageTransactions.instance()
                .transactionPointer(rndTipHash.getBytes());
        } else {
            transactionPointer = StorageTransactions.instance()
                .transactionPointer(Milestone.latestMilestone.bytes());
        }
    } else {
        transactionPointer = StorageTransactions.instance().transactionPointer(requestedTransaction);
    }

**Jan 29, 2017 - Compare changed to NULL HASH and other changes to scheme**
https://github.com/iotaledger/iri/blob/61ad77be4ce01ee1cc8530320f7c234ee660c822/src/main/java/com/iota/iri/service/Node.java#L205

(truncated for brevity)

    if (Arrays.equals(requestedTransaction, Hash.NULL_HASH.bytes())) {
        if (randomTipBroadcastCounter % 9 == 0) {
            // see code "Random Broadcaster - latestMilestone index==0."
        }
        else if (randomTipBroadcastCounter % 6 == 0) {
            // see code re Milestone
        }
        else if (randomTipBroadcastCounter % 3 == 0) {
            // see code "Random Broadcaster - random tip."
        }
    } else {
        transactionPointer = StorageTransactions.instance().transactionPointer(requestedTransaction);
    }