Fault Tolerance in Distributed Systems