Commit ee6e413e authored by Julien Muchembled's avatar Julien Muchembled

master: prevent importing transaction with invalid TID

Else it leads to DB corruption and a crash of the master.
parent 9f5e14f1
...@@ -282,11 +282,14 @@ class TransactionManager(EventQueue): ...@@ -282,11 +282,14 @@ class TransactionManager(EventQueue):
if tid is None: if tid is None:
# No TID requested, generate a temporary one # No TID requested, generate a temporary one
tid = self._nextTID() tid = self._nextTID()
elif tid <= self._last_tid:
raise ProtocolError(
"new TID must be greater than the last committed one")
else: else:
# Use of specific TID requested, queue it immediately and update # Use of specific TID requested, queue it immediately and update
# last TID. # last TID.
self._queue.append(tid) self._queue.append(tid)
self.setLastTID(tid) self._last_tid = tid
txn = self._ttid_dict[tid] = Transaction(node, storage_readiness, tid) txn = self._ttid_dict[tid] = Transaction(node, storage_readiness, tid)
logging.debug('Begin %s', txn) logging.debug('Begin %s', txn)
return tid return tid
......
...@@ -2864,6 +2864,23 @@ class Test(NEOThreadedTest): ...@@ -2864,6 +2864,23 @@ class Test(NEOThreadedTest):
self.assertRaises(RuntimeError, cluster.neoctl.setClusterState, self.assertRaises(RuntimeError, cluster.neoctl.setClusterState,
ClusterStates.STARTING_BACKUP) ClusterStates.STARTING_BACKUP)
@with_cluster()
def testTpcBeginWithInvalidTID(self, cluster):
storage = cluster.getZODBStorage()
txn = transaction.Transaction()
storage.tpc_begin(txn)
storage.store(ZERO_OID, None, 'foo', '', txn)
storage.tpc_vote(txn)
tid = storage.tpc_finish(txn)
self.assertRaises(NEOStorageError, storage.tpc_begin,
transaction.Transaction(), tid)
new_tid = add64(tid, 1)
txn = transaction.Transaction()
storage.tpc_begin(txn, new_tid)
storage.store(ZERO_OID, tid, 'bar', '', txn)
storage.tpc_vote(txn)
self.assertEqual(add64(tid, 1), storage.tpc_finish(txn))
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment