Communication and Agreement Abstractions for Fault-Tolerant Asynchronous Distributed Systems