raft: promise snapshot.index <= committed and applied

snapshot is set in these places:

- start an empty node

snapshot.index is set to 0, while committed and applied are set to 0.
Because committed and applied always increase, they are both always
bigger than snapshot.index.

- start from snapshot and log

snapshot.index, committed, applied is set to the index of loaded snapshot at
the first step. When raft loads state from log, it ensures that loaded
committed >= current committed. So it is fine in this case.

- receive snapshot from leader

If snapshot.index <= committed, raft ignores this snapshot. Otherwise,
snapshot.index, committed, applied is set to the index of received snapshot.

In sum, snapshot.index always <= committed and applied.
when we restart, we recover the snapshot as the first step(which sets snapshot.index and committed), and load the state(which sets committed). we need to ensure that committed doesn't become smaller than snapshot.index