Program: 85794
Project: 85794
Buggy source:
@Test public void testChannelResume() throws Exception {
  Utils.rollMockClock(0);
  final Sha256Hash someServerId=Sha256Hash.create(new byte[]{});
  ChannelTestUtils.RecordingPair pair=ChannelTestUtils.makeRecorders(serverWallet,mockBroadcaster);
  pair.server.connectionOpen();
  PaymentChannelClient client=new PaymentChannelClient(wallet,myKey,Utils.COIN,someServerId,pair.clientRecorder);
  PaymentChannelServer server=pair.server;
  client.connectionOpen();
  server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.CLIENT_VERSION));
  client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.SERVER_VERSION));
  client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.INITIATE));
  server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.PROVIDE_REFUND));
  client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.RETURN_REFUND));
  broadcastTxPause.release();
  server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.PROVIDE_CONTRACT));
  broadcasts.take();
  client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.CHANNEL_OPEN));
  Sha256Hash contractHash=(Sha256Hash)pair.serverRecorder.q.take();
  pair.clientRecorder.checkOpened();
  assertNull(pair.serverRecorder.q.poll());
  assertNull(pair.clientRecorder.q.poll());
  client.incrementPayment(Utils.CENT);
  server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.UPDATE_PAYMENT));
  assertEquals(Utils.CENT,pair.serverRecorder.q.take());
  server.close();
  server.connectionClosed();
  client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.CLOSE));
  client.connectionClosed();
  assertFalse(client.connectionOpen);
  StoredPaymentChannelClientStates clientStoredChannels=(StoredPaymentChannelClientStates)wallet.getExtensions().get(StoredPaymentChannelClientStates.EXTENSION_ID);
  assertEquals(1,clientStoredChannels.mapChannels.size());
  assertFalse(clientStoredChannels.mapChannels.values().iterator().next().active);
  pair=ChannelTestUtils.makeRecorders(serverWallet,mockBroadcaster);
  pair.server.connectionOpen();
  pair.server.receiveMessage(Protos.TwoWayChannelMessage.newBuilder().setType(MessageType.CLIENT_VERSION).setClientVersion(Protos.ClientVersion.newBuilder().setPreviousChannelContractHash(ByteString.copyFrom(Sha256Hash.create(new byte[]{0x03}).getBytes())).setMajor(0).setMinor(42)).build());
  pair.serverRecorder.checkNextMsg(MessageType.SERVER_VERSION);
  pair.serverRecorder.checkNextMsg(MessageType.INITIATE);
  pair=ChannelTestUtils.makeRecorders(serverWallet,mockBroadcaster);
  client=new PaymentChannelClient(wallet,myKey,Utils.COIN,someServerId,pair.clientRecorder);
  server=pair.server;
  client.connectionOpen();
  server.connectionOpen();
  final Protos.TwoWayChannelMessage clientVersionMsg=pair.clientRecorder.checkNextMsg(MessageType.CLIENT_VERSION);
  assertEquals(contractHash,new Sha256Hash(clientVersionMsg.getClientVersion().getPreviousChannelContractHash().toByteArray()));
  server.receiveMessage(clientVersionMsg);
  client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.SERVER_VERSION));
  client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.CHANNEL_OPEN));
  assertEquals(contractHash,pair.serverRecorder.q.take());
  pair.clientRecorder.checkOpened();
  assertNull(pair.serverRecorder.q.poll());
  assertNull(pair.clientRecorder.q.poll());
  client.incrementPayment(Utils.CENT);
  server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.UPDATE_PAYMENT));
  pair.serverRecorder.checkTotalPayment(Utils.CENT.multiply(BigInteger.valueOf(2)));
  PaymentChannelClient openClient=client;
  ChannelTestUtils.RecordingPair openPair=pair;
  pair=ChannelTestUtils.makeRecorders(serverWallet,mockBroadcaster);
  client=new PaymentChannelClient(wallet,myKey,Utils.COIN,someServerId,pair.clientRecorder);
  server=pair.server;
  client.connectionOpen();
  server.connectionOpen();
{
    Protos.TwoWayChannelMessage msg=pair.clientRecorder.checkNextMsg(MessageType.CLIENT_VERSION);
    assertFalse(msg.getClientVersion().hasPreviousChannelContractHash());
  }
  pair=ChannelTestUtils.makeRecorders(serverWallet,mockBroadcaster);
  client=new PaymentChannelClient(wallet,myKey,Utils.COIN,someServerId,pair.clientRecorder);
  server=pair.server;
  client.connectionOpen();
  server.connectionOpen();
  pair.clientRecorder.getNextMsg();
  server.receiveMessage(Protos.TwoWayChannelMessage.newBuilder().setType(MessageType.CLIENT_VERSION).setClientVersion(Protos.ClientVersion.newBuilder().setPreviousChannelContractHash(ByteString.copyFrom(contractHash.getBytes())).setMajor(0).setMinor(42)).build());
  client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.SERVER_VERSION));
  client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.INITIATE));
  server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.PROVIDE_REFUND));
  client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.RETURN_REFUND));
  broadcastTxPause.release();
  server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.PROVIDE_CONTRACT));
  broadcasts.take();
  client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.CHANNEL_OPEN));
  Sha256Hash secondContractHash=(Sha256Hash)pair.serverRecorder.q.take();
  pair.clientRecorder.checkOpened();
  assertNull(pair.serverRecorder.q.poll());
  assertNull(pair.clientRecorder.q.poll());
  client.close();
  client.connectionClosed();
  pair.server.close();
  pair.server.connectionClosed();
  pair=ChannelTestUtils.makeRecorders(serverWallet,mockBroadcaster);
  client=new PaymentChannelClient(wallet,myKey,Utils.COIN,someServerId,pair.clientRecorder);
  server=pair.server;
  client.connectionOpen();
  server.connectionOpen();
{
    Protos.TwoWayChannelMessage msg=pair.clientRecorder.checkNextMsg(MessageType.CLIENT_VERSION);
    assertEquals(secondContractHash,new Sha256Hash(msg.getClientVersion().getPreviousChannelContractHash().toByteArray()));
    server.receiveMessage(msg);
  }
  client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.SERVER_VERSION));
  client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.CHANNEL_OPEN));
  pair.clientRecorder.checkOpened();
  assertEquals(2,clientStoredChannels.mapChannels.size());
  broadcastTxPause.release();
  client.close();
  server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.CLOSE));
  assertEquals(CloseReason.CLIENT_REQUESTED_CLOSE,pair.clientRecorder.q.take());
  server.connectionClosed();
  client.connectionClosed();
  assertFalse(clientStoredChannels.getChannel(Sha256Hash.create(new byte[]{}),secondContractHash).active);
  assertTrue(clientStoredChannels.getChannel(Sha256Hash.create(new byte[]{}),contractHash).active);
  openClient.connectionClosed();
  assertFalse(clientStoredChannels.getChannel(Sha256Hash.create(new byte[]{}),contractHash).active);
  Utils.rollMockClock(60 * 60 * 24 + 60 * 5);
  StoredPaymentChannelClientStates newClientStates=new StoredPaymentChannelClientStates(mockBroadcaster,wallet);
  newClientStates.deserializeWalletExtension(wallet,clientStoredChannels.serializeWalletExtension());
  for (int i=0; i < 2; i++) {
    broadcastTxPause.release();
    assertTrue(broadcasts.take().getOutput(0).getScriptPubKey().isSentToMultiSig());
    broadcastTxPause.release();
    assertEquals(TransactionConfidence.Source.SELF,broadcasts.take().getConfidence().getSource());
  }
  assertTrue(broadcasts.isEmpty());
  assertTrue(newClientStates.mapChannels.isEmpty());
  StoredPaymentChannelServerStates serverStoredChannels=new StoredPaymentChannelServerStates(serverWallet,mockBroadcaster);
  Thread.sleep(2000);
  assertTrue(serverStoredChannels.mapChannels.isEmpty());
}

Fixed version (ground truth):
@Test public void testChannelResume() throws Exception {
  Utils.rollMockClock(0);
  final Sha256Hash someServerId=Sha256Hash.create(new byte[]{});
  ChannelTestUtils.RecordingPair pair=ChannelTestUtils.makeRecorders(serverWallet,mockBroadcaster);
  pair.server.connectionOpen();
  PaymentChannelClient client=new PaymentChannelClient(wallet,myKey,Utils.COIN,someServerId,pair.clientRecorder);
  PaymentChannelServer server=pair.server;
  client.connectionOpen();
  server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.CLIENT_VERSION));
  client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.SERVER_VERSION));
  client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.INITIATE));
  server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.PROVIDE_REFUND));
  client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.RETURN_REFUND));
  broadcastTxPause.release();
  server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.PROVIDE_CONTRACT));
  broadcasts.take();
  client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.CHANNEL_OPEN));
  Sha256Hash contractHash=(Sha256Hash)pair.serverRecorder.q.take();
  pair.clientRecorder.checkOpened();
  assertNull(pair.serverRecorder.q.poll());
  assertNull(pair.clientRecorder.q.poll());
  client.incrementPayment(Utils.CENT);
  server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.UPDATE_PAYMENT));
  assertEquals(Utils.CENT,pair.serverRecorder.q.take());
  server.close();
  server.connectionClosed();
  client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.CLOSE));
  client.connectionClosed();
  assertFalse(client.connectionOpen);
  StoredPaymentChannelClientStates clientStoredChannels=(StoredPaymentChannelClientStates)wallet.getExtensions().get(StoredPaymentChannelClientStates.EXTENSION_ID);
  assertEquals(1,clientStoredChannels.mapChannels.size());
  assertFalse(clientStoredChannels.mapChannels.values().iterator().next().active);
  pair=ChannelTestUtils.makeRecorders(serverWallet,mockBroadcaster);
  pair.server.connectionOpen();
  pair.server.receiveMessage(Protos.TwoWayChannelMessage.newBuilder().setType(MessageType.CLIENT_VERSION).setClientVersion(Protos.ClientVersion.newBuilder().setPreviousChannelContractHash(ByteString.copyFrom(Sha256Hash.create(new byte[]{0x03}).getBytes())).setMajor(0).setMinor(42)).build());
  pair.serverRecorder.checkNextMsg(MessageType.SERVER_VERSION);
  pair.serverRecorder.checkNextMsg(MessageType.INITIATE);
  wallet=roundTripClientWallet(wallet);
  serverWallet=roundTripServerWallet(serverWallet);
  clientStoredChannels=(StoredPaymentChannelClientStates)wallet.getExtensions().get(StoredPaymentChannelClientStates.EXTENSION_ID);
  pair=ChannelTestUtils.makeRecorders(serverWallet,mockBroadcaster);
  client=new PaymentChannelClient(wallet,myKey,Utils.COIN,someServerId,pair.clientRecorder);
  server=pair.server;
  client.connectionOpen();
  server.connectionOpen();
  final Protos.TwoWayChannelMessage clientVersionMsg=pair.clientRecorder.checkNextMsg(MessageType.CLIENT_VERSION);
  assertTrue(clientVersionMsg.getClientVersion().hasPreviousChannelContractHash());
  assertEquals(contractHash,new Sha256Hash(clientVersionMsg.getClientVersion().getPreviousChannelContractHash().toByteArray()));
  server.receiveMessage(clientVersionMsg);
  client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.SERVER_VERSION));
  client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.CHANNEL_OPEN));
  assertEquals(contractHash,pair.serverRecorder.q.take());
  pair.clientRecorder.checkOpened();
  assertNull(pair.serverRecorder.q.poll());
  assertNull(pair.clientRecorder.q.poll());
  client.incrementPayment(Utils.CENT);
  server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.UPDATE_PAYMENT));
  pair.serverRecorder.checkTotalPayment(Utils.CENT.multiply(BigInteger.valueOf(2)));
  PaymentChannelClient openClient=client;
  ChannelTestUtils.RecordingPair openPair=pair;
  pair=ChannelTestUtils.makeRecorders(serverWallet,mockBroadcaster);
  client=new PaymentChannelClient(wallet,myKey,Utils.COIN,someServerId,pair.clientRecorder);
  server=pair.server;
  client.connectionOpen();
  server.connectionOpen();
{
    Protos.TwoWayChannelMessage msg=pair.clientRecorder.checkNextMsg(MessageType.CLIENT_VERSION);
    assertFalse(msg.getClientVersion().hasPreviousChannelContractHash());
  }
  pair=ChannelTestUtils.makeRecorders(serverWallet,mockBroadcaster);
  client=new PaymentChannelClient(wallet,myKey,Utils.COIN,someServerId,pair.clientRecorder);
  server=pair.server;
  client.connectionOpen();
  server.connectionOpen();
  pair.clientRecorder.getNextMsg();
  server.receiveMessage(Protos.TwoWayChannelMessage.newBuilder().setType(MessageType.CLIENT_VERSION).setClientVersion(Protos.ClientVersion.newBuilder().setPreviousChannelContractHash(ByteString.copyFrom(contractHash.getBytes())).setMajor(0).setMinor(42)).build());
  client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.SERVER_VERSION));
  client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.INITIATE));
  server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.PROVIDE_REFUND));
  client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.RETURN_REFUND));
  broadcastTxPause.release();
  server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.PROVIDE_CONTRACT));
  broadcasts.take();
  client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.CHANNEL_OPEN));
  Sha256Hash secondContractHash=(Sha256Hash)pair.serverRecorder.q.take();
  pair.clientRecorder.checkOpened();
  assertNull(pair.serverRecorder.q.poll());
  assertNull(pair.clientRecorder.q.poll());
  client.close();
  client.connectionClosed();
  pair.server.close();
  pair.server.connectionClosed();
  pair=ChannelTestUtils.makeRecorders(serverWallet,mockBroadcaster);
  client=new PaymentChannelClient(wallet,myKey,Utils.COIN,someServerId,pair.clientRecorder);
  server=pair.server;
  client.connectionOpen();
  server.connectionOpen();
{
    Protos.TwoWayChannelMessage msg=pair.clientRecorder.checkNextMsg(MessageType.CLIENT_VERSION);
    assertEquals(secondContractHash,new Sha256Hash(msg.getClientVersion().getPreviousChannelContractHash().toByteArray()));
    server.receiveMessage(msg);
  }
  client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.SERVER_VERSION));
  client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.CHANNEL_OPEN));
  pair.clientRecorder.checkOpened();
  assertEquals(2,clientStoredChannels.mapChannels.size());
  broadcastTxPause.release();
  client.close();
  server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.CLOSE));
  assertEquals(CloseReason.CLIENT_REQUESTED_CLOSE,pair.clientRecorder.q.take());
  server.connectionClosed();
  client.connectionClosed();
  assertFalse(clientStoredChannels.getChannel(Sha256Hash.create(new byte[]{}),secondContractHash).active);
  assertTrue(clientStoredChannels.getChannel(Sha256Hash.create(new byte[]{}),contractHash).active);
  openClient.connectionClosed();
  assertFalse(clientStoredChannels.getChannel(Sha256Hash.create(new byte[]{}),contractHash).active);
  Utils.rollMockClock(60 * 60 * 24 + 60 * 5);
  StoredPaymentChannelClientStates newClientStates=new StoredPaymentChannelClientStates(mockBroadcaster,wallet);
  newClientStates.deserializeWalletExtension(wallet,clientStoredChannels.serializeWalletExtension());
  for (int i=0; i < 2; i++) {
    broadcastTxPause.release();
    assertTrue(broadcasts.take().getOutput(0).getScriptPubKey().isSentToMultiSig());
    broadcastTxPause.release();
    assertEquals(TransactionConfidence.Source.SELF,broadcasts.take().getConfidence().getSource());
  }
  assertTrue(broadcasts.isEmpty());
  assertTrue(newClientStates.mapChannels.isEmpty());
  StoredPaymentChannelServerStates serverStoredChannels=new StoredPaymentChannelServerStates(serverWallet,mockBroadcaster);
  Thread.sleep(2000);
  assertTrue(serverStoredChannels.mapChannels.isEmpty());
}