Modular Reasoning for Message-passing Programs