Use full txn struct instead of just txn ID

Move from dealing with just transaction ID to using the full transaction
struct in write intents and in request / response headers.

Cleaned up some code in MVCC that was unnecessarily complex and introduced
concept of transaction epochs for Put() and for ResolveIntent(). Transaction
epochs start at 0 and are incremented every time a transaction is retried.
Transactions are retried (instead of aborted) in the event that a value is
encountered within the "window of uncertainty" between RequestHeader.Timestamp
and RequestHeader.MaxTimestamp, or in the case of an SSI transaction, if
the final transaction timestamp is not equal to the initial transaction
timestamp.

Typically, when a transaction has to restart, it covers all of the same
keys on writes and increments the intents' epochs accordingly. However,
if there's conditional logic in the transaction, it might end up skipping
some keys which were written the previous run--those earlier intents should
then not be committed when the intents are resolved after txn commit.
Gotcha...I started work on EndTransaction and came to the conclusion that the Transaction object returned in the ResponseHeader shouldn't change / be supplied at all except for as a response to the first request in the transaction (specifying an empty, non-nil Transaction to start the transaction).

Instead of having the transaction timestamp being munged, we instead always rely on the client to pass up the maximum timestamp seen so far via RequestHeader.Timestamp from all ResponseHeader.Timestamps. This is far more reasonable and allows us to have a non-mutable transaction object for the length of a single run of a transaction.

I changed this PR to include a BeginTransaction API call. Here are the pros:

 - Eliminates confusion in the API as to when a txn should be supplied, whether it should be empty, whether or not isolation or priority should be included even if TxnID is missing, etc. It was getting much too confusing.
- BeginTransaction is satisfied immediately by the receiving node--despite having a key which it's targeted at (this is how we build up the locality-aware txn ID), it's not passed to the range leader; all we need to return a valid Txn struct is a clock synchronized with the cluster. This means that BeginTransaction will be as fast as a round trip to the client's gateway node.
- Building on the previous point, many transactions will want to fan out parallel writes. In order to do that, you need a txn structure. Previously, we would have had to do a "real" request of some sort which would have involved the latency incurred from either route-to-leader for read or to achieve raft consensus for write.

Cons:

- Requires a round trip to gateway node even if txn could have been done as a sequential set of commands where the first could have usefully created the Txn struct as well.

Feels like making the API more explicit weighed most heavily for me. The cost seems minimal given we only hit gateway node.