There is probably not much loss due to per message encryption. Even if a MITM determined that a message was an inv message (or bloom filter message), it wouldn't be able to extract much information. Since the hashes in those messages are fixed size, there is very little leakage.
You could make it so that the the encryption messages effectively create a second data stream and break/weaken the link between message size and wrapped message size. This requires state though, so there is a complexity tradeoff.
There is no real need to include an IV, since you are including a 32 byte context hash. The first 16 bytes of the context hash could be used as IV.
In terms of generating the context hash, it would be easier to make it linear.
context_hash_n = SHA256(context_hash_(n-1) | message_(n-1))
As the session gets longer, both nodes would have to do more and more hashing to compute the hash of the entire conversation.