From a051afe2247387ac1d950748a29514c1f03153b9 Mon Sep 17 00:00:00 2001 From: Mike Hearn Date: Thu, 10 Oct 2013 14:23:57 +0200 Subject: [PATCH] Payment channels: default server should not attempt to destroy the [TCP] connection after sending a CLOSE, let the client do that. This resolves some complicated state management issues in some kinds of client (like on Android). It's also just generally a part of the work to divorce the notion of settling a channel from closing underlying protocol connections. --- .../bitcoin/protocols/channels/PaymentChannelClient.java | 3 +++ .../bitcoin/protocols/channels/PaymentChannelServer.java | 4 +++- .../protocols/channels/ServerConnectionEventHandler.java | 3 ++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/google/bitcoin/protocols/channels/PaymentChannelClient.java b/core/src/main/java/com/google/bitcoin/protocols/channels/PaymentChannelClient.java index d73923d6..82d50787 100644 --- a/core/src/main/java/com/google/bitcoin/protocols/channels/PaymentChannelClient.java +++ b/core/src/main/java/com/google/bitcoin/protocols/channels/PaymentChannelClient.java @@ -298,6 +298,7 @@ public class PaymentChannelClient { checkState(lock.isHeldByCurrentThread()); if (msg.hasClose()) { Transaction closeTx = new Transaction(wallet.getParams(), msg.getClose().getTx().toByteArray()); + log.info("CLOSE message received with final contract {}", closeTx.getHash()); // TODO: set source if (state != null && state().isCloseTransaction(closeTx)) { // The wallet has a listener on it that the state object will use to do the right thing at this @@ -305,6 +306,8 @@ public class PaymentChannelClient { // and that it correctly spends the multisig contract. wallet.receivePending(closeTx, null); } + } else { + log.info("CLOSE message received without final contract"); } if (step == InitStep.WAITING_FOR_CHANNEL_CLOSE) conn.destroyConnection(CloseReason.CLIENT_REQUESTED_CLOSE); 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 6ec87ce9..7175a2b6 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 @@ -319,8 +319,10 @@ public class PaymentChannelServer { // properly and so on. msg.getCloseBuilder().setTx(ByteString.copyFrom(result.bitcoinSerialize())); } + log.info("Sending CLOSE back with finalized broadcast contract."); conn.sendToClient(msg.build()); - conn.destroyConnection(CloseReason.CLIENT_REQUESTED_CLOSE); + // The client is expected to hang up the TCP connection after we send back the + // CLOSE message. } @Override diff --git a/core/src/main/java/com/google/bitcoin/protocols/channels/ServerConnectionEventHandler.java b/core/src/main/java/com/google/bitcoin/protocols/channels/ServerConnectionEventHandler.java index bf6acf75..c53904a3 100644 --- a/core/src/main/java/com/google/bitcoin/protocols/channels/ServerConnectionEventHandler.java +++ b/core/src/main/java/com/google/bitcoin/protocols/channels/ServerConnectionEventHandler.java @@ -23,7 +23,8 @@ import com.google.bitcoin.protocols.niowrapper.ProtobufParser; import org.bitcoin.paymentchannel.Protos; /** -* A connection-specific event handler that handles events generated by client connections on a {@link PaymentChannelServerListener} +* A connection-specific event handler that handles events generated by client connections on a + * {@link PaymentChannelServerListener} */ public abstract class ServerConnectionEventHandler { private ProtobufParser connectionChannel;