From 5b28091c9a3ccd72751a4fa95ddebb92d5e223b5 Mon Sep 17 00:00:00 2001 From: Mike Hearn Date: Wed, 16 Oct 2013 16:14:12 +0200 Subject: [PATCH] Payment channels: split CLOSE message processing on the server side into a separate method. --- .../channels/PaymentChannelServer.java | 63 ++++++++++--------- 1 file changed, 34 insertions(+), 29 deletions(-) diff --git a/core/src/main/java/com/google/bitcoin/protocols/channels/PaymentChannelServer.java b/core/src/main/java/com/google/bitcoin/protocols/channels/PaymentChannelServer.java index 7175a2b6..fecfe2c7 100644 --- a/core/src/main/java/com/google/bitcoin/protocols/channels/PaymentChannelServer.java +++ b/core/src/main/java/com/google/bitcoin/protocols/channels/PaymentChannelServer.java @@ -305,35 +305,7 @@ public class PaymentChannelServer { receiveUpdatePaymentMessage(msg); return; case CLOSE: - log.info("Got CLOSE message, closing channel"); - connectionClosing = true; - if (state != null) { - Futures.addCallback(state.close(), new FutureCallback() { - @Override - public void onSuccess(Transaction result) { - // Send the successfully accepted transaction back to the client. - final Protos.TwoWayChannelMessage.Builder msg = Protos.TwoWayChannelMessage.newBuilder(); - msg.setType(Protos.TwoWayChannelMessage.MessageType.CLOSE); - if (result != null) { - // Result can be null on various error paths, like if we never actually opened - // properly and so on. - msg.getCloseBuilder().setTx(ByteString.copyFrom(result.bitcoinSerialize())); - } - log.info("Sending CLOSE back with finalized broadcast contract."); - conn.sendToClient(msg.build()); - // The client is expected to hang up the TCP connection after we send back the - // CLOSE message. - } - - @Override - public void onFailure(Throwable t) { - log.error("Failed to broadcast close TX", t); - conn.destroyConnection(CloseReason.CLIENT_REQUESTED_CLOSE); - } - }); - } else { - conn.destroyConnection(CloseReason.CLIENT_REQUESTED_CLOSE); - } + receiveCloseMessage(); return; case ERROR: checkState(msg.hasError()); @@ -376,6 +348,39 @@ public class PaymentChannelServer { } } + @GuardedBy("lock") + private void receiveCloseMessage() throws ValueOutOfRangeException { + log.info("Got CLOSE message, closing channel"); + connectionClosing = true; + if (state != null) { + Futures.addCallback(state.close(), new FutureCallback() { + @Override + public void onSuccess(Transaction result) { + // Send the successfully accepted transaction back to the client. + final Protos.TwoWayChannelMessage.Builder msg = Protos.TwoWayChannelMessage.newBuilder(); + msg.setType(Protos.TwoWayChannelMessage.MessageType.CLOSE); + if (result != null) { + // Result can be null on various error paths, like if we never actually opened + // properly and so on. + msg.getCloseBuilder().setTx(ByteString.copyFrom(result.bitcoinSerialize())); + } + log.info("Sending CLOSE back with finalized broadcast contract."); + conn.sendToClient(msg.build()); + // The client is expected to hang up the TCP connection after we send back the + // CLOSE message. + } + + @Override + public void onFailure(Throwable t) { + log.error("Failed to broadcast close TX", t); + conn.destroyConnection(CloseReason.CLIENT_REQUESTED_CLOSE); + } + }); + } else { + conn.destroyConnection(CloseReason.CLIENT_REQUESTED_CLOSE); + } + } + /** *

Called when the connection terminates. Notifies the {@link StoredServerChannel} object that we can attempt to * resume this channel in the future and stops generating messages for the client.