assertClusterSize("Wrong cluster size", 2);
final Object key = "key1";
assertKeyOwnership(key, cache(1), cache(0));
final int currentTopologyId = currentTopologyId(cache(0));
final ControlledRpcManager nodeARpcManager = replaceRpcManager(cache(0));
final NodeController nodeAController = setNodeControllerIn(cache(0));
setInitialPhaseForNodeA(nodeAController, currentTopologyId);
final NodeController nodeBController = setNodeControllerIn(cache(1));
setInitialPhaseForNodeB(nodeBController, currentTopologyId);
final NewNode nodeC = addNode(currentTopologyId);
//node A thinks that node B is the primary owner. Node B is blocking the prepare command until it thinks that
//node C is the primary owner
nodeAController.topologyManager.waitToBlock(BlockingLocalTopologyManager.LatchType.CONSISTENT_HASH_UPDATE);
nodeARpcManager.blockAfter(VersionedPrepareCommand.class);
//node C thinks that node B is the primary owner.
//nodeC.controller.topologyManager.waitToBlock(BlockingLocalTopologyManager.LatchType.CONSISTENT_HASH_UPDATE);
//after this waiting phase, node A thinks that node B is the primary owner, node B thinks that node C is the
// primary owner and node C thinks that node B is the primary owner
//lets execute the transaction...
Future<Object> tx = executeTransaction(cache(0), key);
//it waits until all nodes has replied. then, we change the topology ID and let it collect the responses.
nodeARpcManager.waitForCommandToBlock();
nodeAController.topologyManager.stopBlocking(BlockingLocalTopologyManager.LatchType.CONSISTENT_HASH_UPDATE);
awaitForTopology(currentTopologyId + 2, cache(0));
nodeARpcManager.stopBlocking();
assertNull("Wrong put() return value.", tx.get());
nodeAController.topologyManager.stopBlockingAll();
nodeBController.topologyManager.stopBlockingAll();
nodeC.controller.topologyManager.stopBlockingAll();