We must allow committing and aborting prepared transactions while downgrading to 4.0 because they block the completion of that downgrade. We already do this but we also have to make sure that if they were prepared while using the multiple oplog entries transaction format, the corresponding commit or abort respects that format's logic for assigning the statementId for the commit or abort oplog entry. What this means is that we should be assigning the next consecutive statementId not just in the "fully upgraded to 4.2" case, but also in the "downgrading to 4.0" case. If we don't do this, then the commit or abort entries written mid-downgrade will receive a hard-coded stmtId of 1, which will have already been assigned at or by the time we prepared the transaction in 4.2 while using the new format. We should not be using the same stmtIds twice, so we should make the above fix to prevent that from happening. We should also investigate if there are other problems besides statementIds in this downgrade scenario.
As part of this ticket, we should also investigate whether the logic to check FCV here in OpObserverImpl::onPreparedTransactionCommit can be cleaned up or refactored, as we already have logic for disallowing prepared transactions in 4.0.