class AbstractProxyTransaction implements Identifiable<TransactionIdentifier> {

    final void canCommit(final VotingFuture<?> ret) {
        checkReadWrite();
        checkSealed();

        // Precludes startReconnect() from interfering with the fast path
        synchronized (this) {
            if (STATE_UPDATER.compareAndSet(this, SEALED, FLUSHED)) {
                final TransactionRequest<?> req = verifyNotNull(commitRequest(true));

                sendRequest(req, t -> {
                    if (t instanceof TransactionCanCommitSuccess) {
                        ret.voteYes();
                    } else if (t instanceof RequestFailure) {
                        ret.voteNo(((RequestFailure<?, ?>) t).getCause().unwrap());
                    } else {
                        ret.voteNo(unhandledResponseException(t));
                    }

                    recordSuccessfulRequest(req);
                    LOG.debug("Transaction {} canCommit completed", this);
                });

                return;
            }
        }

        // We have had some interference with successor injection, wait for it to complete and defer to the successor.
        awaitSuccessor().canCommit(ret);
    }

      AbstractProxyTransaction(final ProxyHistory parent, final boolean isDone);

}