mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-02-07 06:44:16 +00:00
Payment channels: rename "close" to "settle".
The previous overloading of the term "close" to mean both settlement of the channel (broadcast of the final payment tx) and terminating/cleaning up the underlying network connection was very confusing and made the code harder to work with. The notion of "closing" a protocol that is often embedded inside others isn't really well defined, so there's perhaps more work to do here, but this change makes the code easier to follow and is basically a big pile of no-ops.
This commit is contained in:
parent
edf37998ca
commit
0bc28781ae
@ -25,22 +25,21 @@ public interface IPaymentChannelClient {
|
||||
*
|
||||
* <p>Note that this <b>MUST</b> still be called even after either
|
||||
* {@link PaymentChannelClient.ClientConnection#destroyConnection(com.google.bitcoin.protocols.channels.PaymentChannelCloseException.CloseReason)} or
|
||||
* {@link IPaymentChannelClient#close()} is called to actually handle the connection close logic.</p>
|
||||
* {@link IPaymentChannelClient#settle()} is called, to actually handle the connection close logic.</p>
|
||||
*/
|
||||
void connectionClosed();
|
||||
|
||||
// TODO: Rename this to settle.
|
||||
/**
|
||||
* <p>Settles the channel, notifying the server it can broadcast the most recent payment transaction.</p>
|
||||
*
|
||||
* <p>Note that this only generates a CLOSE message for the server and calls
|
||||
* {@link PaymentChannelClient.ClientConnection#destroyConnection(com.google.bitcoin.protocols.channels.PaymentChannelCloseException.CloseReason)}
|
||||
* to close the connection, it does not actually handle connection close logic, and
|
||||
* to settle the connection, it does not actually handle connection close logic, and
|
||||
* {@link PaymentChannelClient#connectionClosed()} must still be called after the connection fully settles.</p>
|
||||
*
|
||||
* @throws IllegalStateException If the connection is not currently open (ie the CLOSE message cannot be sent)
|
||||
*/
|
||||
void close() throws IllegalStateException;
|
||||
void settle() throws IllegalStateException;
|
||||
|
||||
/**
|
||||
* <p>Called to indicate the connection has been opened and messages can now be generated for the server.</p>
|
||||
|
@ -277,18 +277,18 @@ public class PaymentChannelClient implements IPaymentChannelClient {
|
||||
@GuardedBy("lock")
|
||||
private void receiveClose(Protos.TwoWayChannelMessage msg) throws VerificationException {
|
||||
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());
|
||||
if (msg.hasSettlement()) {
|
||||
Transaction settleTx = new Transaction(wallet.getParams(), msg.getSettlement().getTx().toByteArray());
|
||||
log.info("CLOSE message received with settlement tx {}", settleTx.getHash());
|
||||
// TODO: set source
|
||||
if (state != null && state().isCloseTransaction(closeTx)) {
|
||||
if (state != null && state().isSettlementTransaction(settleTx)) {
|
||||
// The wallet has a listener on it that the state object will use to do the right thing at this
|
||||
// point (like watching it for confirmations). The tx has been checked by now for syntactical validity
|
||||
// and that it correctly spends the multisig contract.
|
||||
wallet.receivePending(closeTx, null);
|
||||
wallet.receivePending(settleTx, null);
|
||||
}
|
||||
} else {
|
||||
log.info("CLOSE message received without final contract");
|
||||
log.info("CLOSE message received without settlement tx");
|
||||
}
|
||||
if (step == InitStep.WAITING_FOR_CHANNEL_CLOSE)
|
||||
conn.destroyConnection(CloseReason.CLIENT_REQUESTED_CLOSE);
|
||||
@ -306,7 +306,7 @@ public class PaymentChannelClient implements IPaymentChannelClient {
|
||||
*
|
||||
* <p>Note that this <b>MUST</b> still be called even after either
|
||||
* {@link ClientConnection#destroyConnection(com.google.bitcoin.protocols.channels.PaymentChannelCloseException.CloseReason)} or
|
||||
* {@link PaymentChannelClient#close()} is called to actually handle the connection close logic.</p>
|
||||
* {@link PaymentChannelClient#settle()} is called, to actually handle the connection close logic.</p>
|
||||
*/
|
||||
@Override
|
||||
public void connectionClosed() {
|
||||
@ -321,23 +321,23 @@ public class PaymentChannelClient implements IPaymentChannelClient {
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Closes the connection, notifying the server it should close the channel by broadcasting the most recent payment
|
||||
* transaction.</p>
|
||||
* <p>Closes the connection, notifying the server it should settle the channel by broadcasting the most recent
|
||||
* payment transaction.</p>
|
||||
*
|
||||
* <p>Note that this only generates a CLOSE message for the server and calls
|
||||
* {@link ClientConnection#destroyConnection(CloseReason)} to close the connection, it does not
|
||||
* {@link ClientConnection#destroyConnection(CloseReason)} to settle the connection, it does not
|
||||
* actually handle connection close logic, and {@link PaymentChannelClient#connectionClosed()} must still be called
|
||||
* after the connection fully closes.</p>
|
||||
*
|
||||
* @throws IllegalStateException If the connection is not currently open (ie the CLOSE message cannot be sent)
|
||||
*/
|
||||
@Override
|
||||
public void close() throws IllegalStateException {
|
||||
public void settle() throws IllegalStateException {
|
||||
lock.lock();
|
||||
try {
|
||||
checkState(connectionOpen);
|
||||
step = InitStep.WAITING_FOR_CHANNEL_CLOSE;
|
||||
log.info("Sending a CLOSE message to the server and waiting for response indicating successful propagation.");
|
||||
log.info("Sending a CLOSE message to the server and waiting for response indicating successful settlement.");
|
||||
conn.sendToServer(Protos.TwoWayChannelMessage.newBuilder()
|
||||
.setType(Protos.TwoWayChannelMessage.MessageType.CLOSE)
|
||||
.build());
|
||||
|
@ -149,10 +149,10 @@ public class PaymentChannelClientConnection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the connection, notifying the server it should close the channel by broadcasting the most recent payment
|
||||
* Closes the connection, notifying the server it should settle the channel by broadcasting the most recent payment
|
||||
* transaction.
|
||||
*/
|
||||
public void close() {
|
||||
public void settle() {
|
||||
// Shutdown is a little complicated.
|
||||
//
|
||||
// This call will cause the CLOSE message to be written to the wire, and then the destroyConnection() method that
|
||||
@ -162,17 +162,17 @@ public class PaymentChannelClientConnection {
|
||||
// ProtobufParser.connectionClosed which invokes the connectionClosed method we defined above which in turn
|
||||
// then configures the open-future correctly and closes the state object. Phew!
|
||||
try {
|
||||
channelClient.close();
|
||||
channelClient.settle();
|
||||
} catch (IllegalStateException e) {
|
||||
// Already closed...oh well
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnects the network connection but doesn't request the server to close the channel first (literally just
|
||||
* Disconnects the network connection but doesn't request the server to settle the channel first (literally just
|
||||
* unplugs the network socket and marks the stored channel state as inactive).
|
||||
*/
|
||||
public void disconnectWithoutChannelClose() {
|
||||
public void disconnectWithoutSettlement() {
|
||||
wireParser.closeConnection();
|
||||
}
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ public class PaymentChannelClientState {
|
||||
private final ECKey myKey, serverMultisigKey;
|
||||
// How much value (in satoshis) is locked up into the channel.
|
||||
private final BigInteger totalValue;
|
||||
// When the channel will automatically close in favor of the client, if the server halts before protocol termination
|
||||
// When the channel will automatically settle in favor of the client, if the server halts before protocol termination
|
||||
// specified in terms of block timestamps (so it can off real time by a few hours).
|
||||
private final long expiryTime;
|
||||
|
||||
@ -124,9 +124,9 @@ public class PaymentChannelClientState {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the tx is a valid close transaction.
|
||||
* Returns true if the tx is a valid settlement transaction.
|
||||
*/
|
||||
public boolean isCloseTransaction(Transaction tx) {
|
||||
public boolean isSettlementTransaction(Transaction tx) {
|
||||
try {
|
||||
tx.verify();
|
||||
tx.getInput(0).verify(multisigContract.getOutput(0));
|
||||
@ -175,7 +175,7 @@ public class PaymentChannelClientState {
|
||||
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
||||
synchronized (PaymentChannelClientState.this) {
|
||||
if (multisigContract == null) return;
|
||||
if (isCloseTransaction(tx)) {
|
||||
if (isSettlementTransaction(tx)) {
|
||||
log.info("Close: transaction {} closed contract {}", tx.getHash(), multisigContract.getHash());
|
||||
// Record the fact that it was closed along with the transaction that closed it.
|
||||
state = State.CLOSED;
|
||||
@ -487,7 +487,7 @@ public class PaymentChannelClientState {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the fees that will be paid if the refund transaction has to be claimed because the server failed to close
|
||||
* Returns the fees that will be paid if the refund transaction has to be claimed because the server failed to settle
|
||||
* the channel properly. May only be called after {@link PaymentChannelClientState#initiate()}
|
||||
*/
|
||||
public synchronized BigInteger getRefundTxFees() {
|
||||
|
@ -18,9 +18,9 @@ public class PaymentChannelCloseException extends Exception {
|
||||
// Values after here indicate its probably possible to try reopening channel again
|
||||
|
||||
/**
|
||||
* <p>The {@link com.google.bitcoin.protocols.channels.PaymentChannelClient#close()} method was called or the
|
||||
* <p>The {@link com.google.bitcoin.protocols.channels.PaymentChannelClient#settle()} method was called or the
|
||||
* client sent a CLOSE message.</p>
|
||||
* <p>As long as the server received the CLOSE message, this means that the channel is closing and the payment
|
||||
* <p>As long as the server received the CLOSE message, this means that the channel is settling and the payment
|
||||
* transaction (if any) will be broadcast. If the client attempts to open a new connection, a new channel will
|
||||
* have to be opened.</p>
|
||||
*/
|
||||
|
@ -91,8 +91,8 @@ public class PaymentChannelServer {
|
||||
|
||||
// Used to keep track of whether or not the "socket" ie connection is open and we can generate messages
|
||||
@GuardedBy("lock") private boolean connectionOpen = false;
|
||||
// Indicates that no further messages should be sent and we intend to close the connection
|
||||
@GuardedBy("lock") private boolean connectionClosing = false;
|
||||
// Indicates that no further messages should be sent and we intend to settle the connection
|
||||
@GuardedBy("lock") private boolean channelSettling = false;
|
||||
|
||||
// The wallet and peergroup which are used to complete/broadcast transactions
|
||||
private final Wallet wallet;
|
||||
@ -127,7 +127,7 @@ public class PaymentChannelServer {
|
||||
* Unlike {@link PaymentChannelClient}, this does not have to already contain a StoredState manager
|
||||
* @param minAcceptedChannelSize The minimum value the client must lock into this channel. A value too large will be
|
||||
* rejected by clients, and a value too low will require excessive channel reopening
|
||||
* and may cause fees to be require to close the channel. A reasonable value depends
|
||||
* and may cause fees to be require to settle the channel. A reasonable value depends
|
||||
* entirely on the expected maximum for the channel, and should likely be somewhere
|
||||
* between a few bitcents and a bitcoin.
|
||||
* @param conn A callback listener which represents the connection to the client (forwards messages we generate to
|
||||
@ -224,7 +224,7 @@ public class PaymentChannelServer {
|
||||
private void multisigContractPropogated(Sha256Hash contractHash) {
|
||||
lock.lock();
|
||||
try {
|
||||
if (!connectionOpen || connectionClosing)
|
||||
if (!connectionOpen || channelSettling)
|
||||
return;
|
||||
state.storeChannelInWallet(PaymentChannelServer.this);
|
||||
conn.sendToClient(Protos.TwoWayChannelMessage.newBuilder()
|
||||
@ -287,7 +287,7 @@ public class PaymentChannelServer {
|
||||
lock.lock();
|
||||
try {
|
||||
checkState(connectionOpen);
|
||||
if (connectionClosing)
|
||||
if (channelSettling)
|
||||
return;
|
||||
// If we generate an error, we set errorBuilder and closeReason and break, otherwise we return
|
||||
Protos.Error.Builder errorBuilder;
|
||||
@ -370,10 +370,10 @@ public class PaymentChannelServer {
|
||||
|
||||
@GuardedBy("lock")
|
||||
private void settlePayment(final CloseReason clientRequestedClose) throws ValueOutOfRangeException {
|
||||
// Setting connectionClosing here prevents us from sending another CLOSE when state.close() calls
|
||||
// Setting channelSettling here prevents us from sending another CLOSE when state.close() calls
|
||||
// close() on us here below via the stored channel state.
|
||||
// TODO: Strongly separate the lifecycle of the payment channel from the TCP connection in these classes.
|
||||
connectionClosing = true;
|
||||
channelSettling = true;
|
||||
Futures.addCallback(state.close(), new FutureCallback<Transaction>() {
|
||||
@Override
|
||||
public void onSuccess(Transaction result) {
|
||||
@ -383,17 +383,17 @@ public class PaymentChannelServer {
|
||||
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.");
|
||||
msg.getSettlementBuilder().setTx(ByteString.copyFrom(result.bitcoinSerialize()));
|
||||
log.info("Sending CLOSE back with broadcast settlement tx.");
|
||||
} else {
|
||||
log.info("Sending CLOSE back without finalized broadcast contract.");
|
||||
log.info("Sending CLOSE back without broadcast settlement tx.");
|
||||
}
|
||||
conn.sendToClient(msg.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
log.error("Failed to broadcast close TX", t);
|
||||
log.error("Failed to broadcast settlement tx", t);
|
||||
conn.destroyConnection(clientRequestedClose);
|
||||
}
|
||||
});
|
||||
@ -446,7 +446,7 @@ public class PaymentChannelServer {
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Closes the connection by generating a close message for the client and calls
|
||||
* <p>Closes the connection by generating a settle message for the client and calls
|
||||
* {@link ServerConnection#destroyConnection(CloseReason)}. Note that this does not broadcast
|
||||
* the payment transaction and the client may still resume the same channel if they reconnect</p>
|
||||
*
|
||||
@ -456,7 +456,7 @@ public class PaymentChannelServer {
|
||||
public void close() {
|
||||
lock.lock();
|
||||
try {
|
||||
if (connectionOpen && !connectionClosing) {
|
||||
if (connectionOpen && !channelSettling) {
|
||||
final Protos.TwoWayChannelMessage.Builder msg = Protos.TwoWayChannelMessage.newBuilder();
|
||||
msg.setType(Protos.TwoWayChannelMessage.MessageType.CLOSE);
|
||||
conn.sendToClient(msg.build());
|
||||
|
@ -171,7 +171,7 @@ public class PaymentChannelServerListener {
|
||||
/**
|
||||
* <p>Closes all client connections currently connected gracefully.</p>
|
||||
*
|
||||
* <p>Note that this does <i>not</i> close the actual payment channels (and broadcast payment transactions), which
|
||||
* <p>Note that this does <i>not</i> settle the actual payment channels (and broadcast payment transactions), which
|
||||
* must be done using the {@link StoredPaymentChannelServerStates} which manages the states for the associated
|
||||
* wallet.</p>
|
||||
*/
|
||||
|
@ -374,14 +374,14 @@ public class PaymentChannelServerState {
|
||||
}
|
||||
|
||||
if (state.ordinal() < State.READY.ordinal()) {
|
||||
log.error("Attempt to close channel in state " + state);
|
||||
log.error("Attempt to settle channel in state " + state);
|
||||
state = State.CLOSED;
|
||||
closedFuture.set(null);
|
||||
return closedFuture;
|
||||
}
|
||||
if (state != State.READY) {
|
||||
// TODO: What is this codepath for?
|
||||
log.warn("Failed attempt to close a channel in state " + state);
|
||||
log.warn("Failed attempt to settle a channel in state " + state);
|
||||
return closedFuture;
|
||||
}
|
||||
|
||||
@ -435,7 +435,7 @@ public class PaymentChannelServerState {
|
||||
}
|
||||
|
||||
@Override public void onFailure(Throwable throwable) {
|
||||
log.error("Failed to close channel, could not broadcast: {}", throwable.toString());
|
||||
log.error("Failed to settle channel, could not broadcast: {}", throwable.toString());
|
||||
throwable.printStackTrace();
|
||||
state = State.ERROR;
|
||||
closedFuture.setException(throwable);
|
||||
@ -445,14 +445,14 @@ public class PaymentChannelServerState {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the highest payment to ourselves (which we will receive on close(), not including fees)
|
||||
* Gets the highest payment to ourselves (which we will receive on settle(), not including fees)
|
||||
*/
|
||||
public synchronized BigInteger getBestValueToMe() {
|
||||
return bestValueToMe;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the fee paid in the final payment transaction (only available if close() did not throw an exception)
|
||||
* Gets the fee paid in the final payment transaction (only available if settle() did not throw an exception)
|
||||
*/
|
||||
public synchronized BigInteger getFeePaid() {
|
||||
checkState(state == State.CLOSED || state == State.CLOSING);
|
||||
|
@ -25,7 +25,7 @@ import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
/**
|
||||
* Represents the state of a channel once it has been opened in such a way that it can be stored and used to resume a
|
||||
* channel which was interrupted (eg on connection failure) or close the channel automatically as the channel expire
|
||||
* channel which was interrupted (eg on connection failure) or settle the channel automatically as the channel expire
|
||||
* time approaches.
|
||||
*/
|
||||
public class StoredServerChannel {
|
||||
|
@ -143,19 +143,19 @@ public final class Protos {
|
||||
*/
|
||||
org.bitcoin.paymentchannel.Protos.UpdatePaymentOrBuilder getUpdatePaymentOrBuilder();
|
||||
|
||||
// optional .paymentchannels.Close close = 9;
|
||||
// optional .paymentchannels.Settlement settlement = 9;
|
||||
/**
|
||||
* <code>optional .paymentchannels.Close close = 9;</code>
|
||||
* <code>optional .paymentchannels.Settlement settlement = 9;</code>
|
||||
*/
|
||||
boolean hasClose();
|
||||
boolean hasSettlement();
|
||||
/**
|
||||
* <code>optional .paymentchannels.Close close = 9;</code>
|
||||
* <code>optional .paymentchannels.Settlement settlement = 9;</code>
|
||||
*/
|
||||
org.bitcoin.paymentchannel.Protos.Close getClose();
|
||||
org.bitcoin.paymentchannel.Protos.Settlement getSettlement();
|
||||
/**
|
||||
* <code>optional .paymentchannels.Close close = 9;</code>
|
||||
* <code>optional .paymentchannels.Settlement settlement = 9;</code>
|
||||
*/
|
||||
org.bitcoin.paymentchannel.Protos.CloseOrBuilder getCloseOrBuilder();
|
||||
org.bitcoin.paymentchannel.Protos.SettlementOrBuilder getSettlementOrBuilder();
|
||||
|
||||
// optional .paymentchannels.Error error = 10;
|
||||
/**
|
||||
@ -331,14 +331,14 @@ public final class Protos {
|
||||
break;
|
||||
}
|
||||
case 74: {
|
||||
org.bitcoin.paymentchannel.Protos.Close.Builder subBuilder = null;
|
||||
org.bitcoin.paymentchannel.Protos.Settlement.Builder subBuilder = null;
|
||||
if (((bitField0_ & 0x00000100) == 0x00000100)) {
|
||||
subBuilder = close_.toBuilder();
|
||||
subBuilder = settlement_.toBuilder();
|
||||
}
|
||||
close_ = input.readMessage(org.bitcoin.paymentchannel.Protos.Close.PARSER, extensionRegistry);
|
||||
settlement_ = input.readMessage(org.bitcoin.paymentchannel.Protos.Settlement.PARSER, extensionRegistry);
|
||||
if (subBuilder != null) {
|
||||
subBuilder.mergeFrom(close_);
|
||||
close_ = subBuilder.buildPartial();
|
||||
subBuilder.mergeFrom(settlement_);
|
||||
settlement_ = subBuilder.buildPartial();
|
||||
}
|
||||
bitField0_ |= 0x00000100;
|
||||
break;
|
||||
@ -458,11 +458,14 @@ public final class Protos {
|
||||
* takes the most recent signature it received in an UPDATE_PAYMENT and uses it to create a
|
||||
* valid transaction, which it then broadcasts on the network.
|
||||
*
|
||||
* If the server sends it to the client, then it can either be a simple "good bye" message or
|
||||
* it can include the fully signed close transaction and give it back so the client can
|
||||
* eventually broadcast it as well, in case the server fails to do so for some reason (and
|
||||
* more usefully so the client can build on it). In that case the server replies to a CLOSE
|
||||
* with another CLOSE and then disconnects.
|
||||
* Once broadcast is complete, it sends back another CLOSE message with the settlement field set, containing
|
||||
* the final state of the contract.
|
||||
*
|
||||
* The server is allowed to initiate settlement whenever it wants, in which case the client will
|
||||
* asynchronously receive a CLOSE message with the settlement field set. The server is also allowed
|
||||
* to send a CLOSE to mark the end of a connection without any settlement taking place, in which
|
||||
* case this is just an equivalent to a TCP FIN packet. An explicit end-of-protocol markers can be
|
||||
* useful when this protocol is embedded inside another.
|
||||
* </pre>
|
||||
*/
|
||||
CLOSE(9, 9),
|
||||
@ -537,11 +540,14 @@ public final class Protos {
|
||||
* takes the most recent signature it received in an UPDATE_PAYMENT and uses it to create a
|
||||
* valid transaction, which it then broadcasts on the network.
|
||||
*
|
||||
* If the server sends it to the client, then it can either be a simple "good bye" message or
|
||||
* it can include the fully signed close transaction and give it back so the client can
|
||||
* eventually broadcast it as well, in case the server fails to do so for some reason (and
|
||||
* more usefully so the client can build on it). In that case the server replies to a CLOSE
|
||||
* with another CLOSE and then disconnects.
|
||||
* Once broadcast is complete, it sends back another CLOSE message with the settlement field set, containing
|
||||
* the final state of the contract.
|
||||
*
|
||||
* The server is allowed to initiate settlement whenever it wants, in which case the client will
|
||||
* asynchronously receive a CLOSE message with the settlement field set. The server is also allowed
|
||||
* to send a CLOSE to mark the end of a connection without any settlement taking place, in which
|
||||
* case this is just an equivalent to a TCP FIN packet. An explicit end-of-protocol markers can be
|
||||
* useful when this protocol is embedded inside another.
|
||||
* </pre>
|
||||
*/
|
||||
public static final int CLOSE_VALUE = 9;
|
||||
@ -819,26 +825,26 @@ public final class Protos {
|
||||
return updatePayment_;
|
||||
}
|
||||
|
||||
// optional .paymentchannels.Close close = 9;
|
||||
public static final int CLOSE_FIELD_NUMBER = 9;
|
||||
private org.bitcoin.paymentchannel.Protos.Close close_;
|
||||
// optional .paymentchannels.Settlement settlement = 9;
|
||||
public static final int SETTLEMENT_FIELD_NUMBER = 9;
|
||||
private org.bitcoin.paymentchannel.Protos.Settlement settlement_;
|
||||
/**
|
||||
* <code>optional .paymentchannels.Close close = 9;</code>
|
||||
* <code>optional .paymentchannels.Settlement settlement = 9;</code>
|
||||
*/
|
||||
public boolean hasClose() {
|
||||
public boolean hasSettlement() {
|
||||
return ((bitField0_ & 0x00000100) == 0x00000100);
|
||||
}
|
||||
/**
|
||||
* <code>optional .paymentchannels.Close close = 9;</code>
|
||||
* <code>optional .paymentchannels.Settlement settlement = 9;</code>
|
||||
*/
|
||||
public org.bitcoin.paymentchannel.Protos.Close getClose() {
|
||||
return close_;
|
||||
public org.bitcoin.paymentchannel.Protos.Settlement getSettlement() {
|
||||
return settlement_;
|
||||
}
|
||||
/**
|
||||
* <code>optional .paymentchannels.Close close = 9;</code>
|
||||
* <code>optional .paymentchannels.Settlement settlement = 9;</code>
|
||||
*/
|
||||
public org.bitcoin.paymentchannel.Protos.CloseOrBuilder getCloseOrBuilder() {
|
||||
return close_;
|
||||
public org.bitcoin.paymentchannel.Protos.SettlementOrBuilder getSettlementOrBuilder() {
|
||||
return settlement_;
|
||||
}
|
||||
|
||||
// optional .paymentchannels.Error error = 10;
|
||||
@ -872,7 +878,7 @@ public final class Protos {
|
||||
returnRefund_ = org.bitcoin.paymentchannel.Protos.ReturnRefund.getDefaultInstance();
|
||||
provideContract_ = org.bitcoin.paymentchannel.Protos.ProvideContract.getDefaultInstance();
|
||||
updatePayment_ = org.bitcoin.paymentchannel.Protos.UpdatePayment.getDefaultInstance();
|
||||
close_ = org.bitcoin.paymentchannel.Protos.Close.getDefaultInstance();
|
||||
settlement_ = org.bitcoin.paymentchannel.Protos.Settlement.getDefaultInstance();
|
||||
error_ = org.bitcoin.paymentchannel.Protos.Error.getDefaultInstance();
|
||||
}
|
||||
private byte memoizedIsInitialized = -1;
|
||||
@ -926,8 +932,8 @@ public final class Protos {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (hasClose()) {
|
||||
if (!getClose().isInitialized()) {
|
||||
if (hasSettlement()) {
|
||||
if (!getSettlement().isInitialized()) {
|
||||
memoizedIsInitialized = 0;
|
||||
return false;
|
||||
}
|
||||
@ -964,7 +970,7 @@ public final class Protos {
|
||||
output.writeMessage(8, updatePayment_);
|
||||
}
|
||||
if (((bitField0_ & 0x00000100) == 0x00000100)) {
|
||||
output.writeMessage(9, close_);
|
||||
output.writeMessage(9, settlement_);
|
||||
}
|
||||
if (((bitField0_ & 0x00000200) == 0x00000200)) {
|
||||
output.writeMessage(10, error_);
|
||||
@ -1012,7 +1018,7 @@ public final class Protos {
|
||||
}
|
||||
if (((bitField0_ & 0x00000100) == 0x00000100)) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeMessageSize(9, close_);
|
||||
.computeMessageSize(9, settlement_);
|
||||
}
|
||||
if (((bitField0_ & 0x00000200) == 0x00000200)) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
@ -1139,7 +1145,7 @@ public final class Protos {
|
||||
getReturnRefundFieldBuilder();
|
||||
getProvideContractFieldBuilder();
|
||||
getUpdatePaymentFieldBuilder();
|
||||
getCloseFieldBuilder();
|
||||
getSettlementFieldBuilder();
|
||||
getErrorFieldBuilder();
|
||||
}
|
||||
}
|
||||
@ -1193,10 +1199,10 @@ public final class Protos {
|
||||
updatePaymentBuilder_.clear();
|
||||
}
|
||||
bitField0_ = (bitField0_ & ~0x00000080);
|
||||
if (closeBuilder_ == null) {
|
||||
close_ = org.bitcoin.paymentchannel.Protos.Close.getDefaultInstance();
|
||||
if (settlementBuilder_ == null) {
|
||||
settlement_ = org.bitcoin.paymentchannel.Protos.Settlement.getDefaultInstance();
|
||||
} else {
|
||||
closeBuilder_.clear();
|
||||
settlementBuilder_.clear();
|
||||
}
|
||||
bitField0_ = (bitField0_ & ~0x00000100);
|
||||
if (errorBuilder_ == null) {
|
||||
@ -1296,10 +1302,10 @@ public final class Protos {
|
||||
if (((from_bitField0_ & 0x00000100) == 0x00000100)) {
|
||||
to_bitField0_ |= 0x00000100;
|
||||
}
|
||||
if (closeBuilder_ == null) {
|
||||
result.close_ = close_;
|
||||
if (settlementBuilder_ == null) {
|
||||
result.settlement_ = settlement_;
|
||||
} else {
|
||||
result.close_ = closeBuilder_.build();
|
||||
result.settlement_ = settlementBuilder_.build();
|
||||
}
|
||||
if (((from_bitField0_ & 0x00000200) == 0x00000200)) {
|
||||
to_bitField0_ |= 0x00000200;
|
||||
@ -1349,8 +1355,8 @@ public final class Protos {
|
||||
if (other.hasUpdatePayment()) {
|
||||
mergeUpdatePayment(other.getUpdatePayment());
|
||||
}
|
||||
if (other.hasClose()) {
|
||||
mergeClose(other.getClose());
|
||||
if (other.hasSettlement()) {
|
||||
mergeSettlement(other.getSettlement());
|
||||
}
|
||||
if (other.hasError()) {
|
||||
mergeError(other.getError());
|
||||
@ -1406,8 +1412,8 @@ public final class Protos {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (hasClose()) {
|
||||
if (!getClose().isInitialized()) {
|
||||
if (hasSettlement()) {
|
||||
if (!getSettlement().isInitialized()) {
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -2349,121 +2355,121 @@ public final class Protos {
|
||||
return updatePaymentBuilder_;
|
||||
}
|
||||
|
||||
// optional .paymentchannels.Close close = 9;
|
||||
private org.bitcoin.paymentchannel.Protos.Close close_ = org.bitcoin.paymentchannel.Protos.Close.getDefaultInstance();
|
||||
// optional .paymentchannels.Settlement settlement = 9;
|
||||
private org.bitcoin.paymentchannel.Protos.Settlement settlement_ = org.bitcoin.paymentchannel.Protos.Settlement.getDefaultInstance();
|
||||
private com.google.protobuf.SingleFieldBuilder<
|
||||
org.bitcoin.paymentchannel.Protos.Close, org.bitcoin.paymentchannel.Protos.Close.Builder, org.bitcoin.paymentchannel.Protos.CloseOrBuilder> closeBuilder_;
|
||||
org.bitcoin.paymentchannel.Protos.Settlement, org.bitcoin.paymentchannel.Protos.Settlement.Builder, org.bitcoin.paymentchannel.Protos.SettlementOrBuilder> settlementBuilder_;
|
||||
/**
|
||||
* <code>optional .paymentchannels.Close close = 9;</code>
|
||||
* <code>optional .paymentchannels.Settlement settlement = 9;</code>
|
||||
*/
|
||||
public boolean hasClose() {
|
||||
public boolean hasSettlement() {
|
||||
return ((bitField0_ & 0x00000100) == 0x00000100);
|
||||
}
|
||||
/**
|
||||
* <code>optional .paymentchannels.Close close = 9;</code>
|
||||
* <code>optional .paymentchannels.Settlement settlement = 9;</code>
|
||||
*/
|
||||
public org.bitcoin.paymentchannel.Protos.Close getClose() {
|
||||
if (closeBuilder_ == null) {
|
||||
return close_;
|
||||
public org.bitcoin.paymentchannel.Protos.Settlement getSettlement() {
|
||||
if (settlementBuilder_ == null) {
|
||||
return settlement_;
|
||||
} else {
|
||||
return closeBuilder_.getMessage();
|
||||
return settlementBuilder_.getMessage();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* <code>optional .paymentchannels.Close close = 9;</code>
|
||||
* <code>optional .paymentchannels.Settlement settlement = 9;</code>
|
||||
*/
|
||||
public Builder setClose(org.bitcoin.paymentchannel.Protos.Close value) {
|
||||
if (closeBuilder_ == null) {
|
||||
public Builder setSettlement(org.bitcoin.paymentchannel.Protos.Settlement value) {
|
||||
if (settlementBuilder_ == null) {
|
||||
if (value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
close_ = value;
|
||||
settlement_ = value;
|
||||
onChanged();
|
||||
} else {
|
||||
closeBuilder_.setMessage(value);
|
||||
settlementBuilder_.setMessage(value);
|
||||
}
|
||||
bitField0_ |= 0x00000100;
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <code>optional .paymentchannels.Close close = 9;</code>
|
||||
* <code>optional .paymentchannels.Settlement settlement = 9;</code>
|
||||
*/
|
||||
public Builder setClose(
|
||||
org.bitcoin.paymentchannel.Protos.Close.Builder builderForValue) {
|
||||
if (closeBuilder_ == null) {
|
||||
close_ = builderForValue.build();
|
||||
public Builder setSettlement(
|
||||
org.bitcoin.paymentchannel.Protos.Settlement.Builder builderForValue) {
|
||||
if (settlementBuilder_ == null) {
|
||||
settlement_ = builderForValue.build();
|
||||
onChanged();
|
||||
} else {
|
||||
closeBuilder_.setMessage(builderForValue.build());
|
||||
settlementBuilder_.setMessage(builderForValue.build());
|
||||
}
|
||||
bitField0_ |= 0x00000100;
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <code>optional .paymentchannels.Close close = 9;</code>
|
||||
* <code>optional .paymentchannels.Settlement settlement = 9;</code>
|
||||
*/
|
||||
public Builder mergeClose(org.bitcoin.paymentchannel.Protos.Close value) {
|
||||
if (closeBuilder_ == null) {
|
||||
public Builder mergeSettlement(org.bitcoin.paymentchannel.Protos.Settlement value) {
|
||||
if (settlementBuilder_ == null) {
|
||||
if (((bitField0_ & 0x00000100) == 0x00000100) &&
|
||||
close_ != org.bitcoin.paymentchannel.Protos.Close.getDefaultInstance()) {
|
||||
close_ =
|
||||
org.bitcoin.paymentchannel.Protos.Close.newBuilder(close_).mergeFrom(value).buildPartial();
|
||||
settlement_ != org.bitcoin.paymentchannel.Protos.Settlement.getDefaultInstance()) {
|
||||
settlement_ =
|
||||
org.bitcoin.paymentchannel.Protos.Settlement.newBuilder(settlement_).mergeFrom(value).buildPartial();
|
||||
} else {
|
||||
close_ = value;
|
||||
settlement_ = value;
|
||||
}
|
||||
onChanged();
|
||||
} else {
|
||||
closeBuilder_.mergeFrom(value);
|
||||
settlementBuilder_.mergeFrom(value);
|
||||
}
|
||||
bitField0_ |= 0x00000100;
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <code>optional .paymentchannels.Close close = 9;</code>
|
||||
* <code>optional .paymentchannels.Settlement settlement = 9;</code>
|
||||
*/
|
||||
public Builder clearClose() {
|
||||
if (closeBuilder_ == null) {
|
||||
close_ = org.bitcoin.paymentchannel.Protos.Close.getDefaultInstance();
|
||||
public Builder clearSettlement() {
|
||||
if (settlementBuilder_ == null) {
|
||||
settlement_ = org.bitcoin.paymentchannel.Protos.Settlement.getDefaultInstance();
|
||||
onChanged();
|
||||
} else {
|
||||
closeBuilder_.clear();
|
||||
settlementBuilder_.clear();
|
||||
}
|
||||
bitField0_ = (bitField0_ & ~0x00000100);
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <code>optional .paymentchannels.Close close = 9;</code>
|
||||
* <code>optional .paymentchannels.Settlement settlement = 9;</code>
|
||||
*/
|
||||
public org.bitcoin.paymentchannel.Protos.Close.Builder getCloseBuilder() {
|
||||
public org.bitcoin.paymentchannel.Protos.Settlement.Builder getSettlementBuilder() {
|
||||
bitField0_ |= 0x00000100;
|
||||
onChanged();
|
||||
return getCloseFieldBuilder().getBuilder();
|
||||
return getSettlementFieldBuilder().getBuilder();
|
||||
}
|
||||
/**
|
||||
* <code>optional .paymentchannels.Close close = 9;</code>
|
||||
* <code>optional .paymentchannels.Settlement settlement = 9;</code>
|
||||
*/
|
||||
public org.bitcoin.paymentchannel.Protos.CloseOrBuilder getCloseOrBuilder() {
|
||||
if (closeBuilder_ != null) {
|
||||
return closeBuilder_.getMessageOrBuilder();
|
||||
public org.bitcoin.paymentchannel.Protos.SettlementOrBuilder getSettlementOrBuilder() {
|
||||
if (settlementBuilder_ != null) {
|
||||
return settlementBuilder_.getMessageOrBuilder();
|
||||
} else {
|
||||
return close_;
|
||||
return settlement_;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* <code>optional .paymentchannels.Close close = 9;</code>
|
||||
* <code>optional .paymentchannels.Settlement settlement = 9;</code>
|
||||
*/
|
||||
private com.google.protobuf.SingleFieldBuilder<
|
||||
org.bitcoin.paymentchannel.Protos.Close, org.bitcoin.paymentchannel.Protos.Close.Builder, org.bitcoin.paymentchannel.Protos.CloseOrBuilder>
|
||||
getCloseFieldBuilder() {
|
||||
if (closeBuilder_ == null) {
|
||||
closeBuilder_ = new com.google.protobuf.SingleFieldBuilder<
|
||||
org.bitcoin.paymentchannel.Protos.Close, org.bitcoin.paymentchannel.Protos.Close.Builder, org.bitcoin.paymentchannel.Protos.CloseOrBuilder>(
|
||||
close_,
|
||||
org.bitcoin.paymentchannel.Protos.Settlement, org.bitcoin.paymentchannel.Protos.Settlement.Builder, org.bitcoin.paymentchannel.Protos.SettlementOrBuilder>
|
||||
getSettlementFieldBuilder() {
|
||||
if (settlementBuilder_ == null) {
|
||||
settlementBuilder_ = new com.google.protobuf.SingleFieldBuilder<
|
||||
org.bitcoin.paymentchannel.Protos.Settlement, org.bitcoin.paymentchannel.Protos.Settlement.Builder, org.bitcoin.paymentchannel.Protos.SettlementOrBuilder>(
|
||||
settlement_,
|
||||
getParentForChildren(),
|
||||
isClean());
|
||||
close_ = null;
|
||||
settlement_ = null;
|
||||
}
|
||||
return closeBuilder_;
|
||||
return settlementBuilder_;
|
||||
}
|
||||
|
||||
// optional .paymentchannels.Error error = 10;
|
||||
@ -3817,7 +3823,7 @@ public final class Protos {
|
||||
* Protobuf type {@code paymentchannels.Initiate}
|
||||
*
|
||||
* <pre>
|
||||
* Sent from secondary to primary once version nego is done.
|
||||
* Sent from server to client once version nego is done.
|
||||
* </pre>
|
||||
*/
|
||||
public static final class Initiate extends
|
||||
@ -4158,7 +4164,7 @@ public final class Protos {
|
||||
* Protobuf type {@code paymentchannels.Initiate}
|
||||
*
|
||||
* <pre>
|
||||
* Sent from secondary to primary once version nego is done.
|
||||
* Sent from server to client once version nego is done.
|
||||
* </pre>
|
||||
*/
|
||||
public static final class Builder extends
|
||||
@ -6680,7 +6686,7 @@ public final class Protos {
|
||||
// @@protoc_insertion_point(class_scope:paymentchannels.UpdatePayment)
|
||||
}
|
||||
|
||||
public interface CloseOrBuilder
|
||||
public interface SettlementOrBuilder
|
||||
extends com.google.protobuf.MessageOrBuilder {
|
||||
|
||||
// required bytes tx = 3;
|
||||
@ -6688,7 +6694,7 @@ public final class Protos {
|
||||
* <code>required bytes tx = 3;</code>
|
||||
*
|
||||
* <pre>
|
||||
* A copy of the fully signed final contract that closes the channel. The client can verify
|
||||
* A copy of the fully signed final contract that settles the channel. The client can verify
|
||||
* the transaction is correct and then commit it to their wallet.
|
||||
* </pre>
|
||||
*/
|
||||
@ -6697,31 +6703,31 @@ public final class Protos {
|
||||
* <code>required bytes tx = 3;</code>
|
||||
*
|
||||
* <pre>
|
||||
* A copy of the fully signed final contract that closes the channel. The client can verify
|
||||
* A copy of the fully signed final contract that settles the channel. The client can verify
|
||||
* the transaction is correct and then commit it to their wallet.
|
||||
* </pre>
|
||||
*/
|
||||
com.google.protobuf.ByteString getTx();
|
||||
}
|
||||
/**
|
||||
* Protobuf type {@code paymentchannels.Close}
|
||||
* Protobuf type {@code paymentchannels.Settlement}
|
||||
*/
|
||||
public static final class Close extends
|
||||
public static final class Settlement extends
|
||||
com.google.protobuf.GeneratedMessage
|
||||
implements CloseOrBuilder {
|
||||
// Use Close.newBuilder() to construct.
|
||||
private Close(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
|
||||
implements SettlementOrBuilder {
|
||||
// Use Settlement.newBuilder() to construct.
|
||||
private Settlement(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
|
||||
super(builder);
|
||||
this.unknownFields = builder.getUnknownFields();
|
||||
}
|
||||
private Close(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
|
||||
private Settlement(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
|
||||
|
||||
private static final Close defaultInstance;
|
||||
public static Close getDefaultInstance() {
|
||||
private static final Settlement defaultInstance;
|
||||
public static Settlement getDefaultInstance() {
|
||||
return defaultInstance;
|
||||
}
|
||||
|
||||
public Close getDefaultInstanceForType() {
|
||||
public Settlement getDefaultInstanceForType() {
|
||||
return defaultInstance;
|
||||
}
|
||||
|
||||
@ -6731,7 +6737,7 @@ public final class Protos {
|
||||
getUnknownFields() {
|
||||
return this.unknownFields;
|
||||
}
|
||||
private Close(
|
||||
private Settlement(
|
||||
com.google.protobuf.CodedInputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
@ -6773,28 +6779,28 @@ public final class Protos {
|
||||
}
|
||||
public static final com.google.protobuf.Descriptors.Descriptor
|
||||
getDescriptor() {
|
||||
return org.bitcoin.paymentchannel.Protos.internal_static_paymentchannels_Close_descriptor;
|
||||
return org.bitcoin.paymentchannel.Protos.internal_static_paymentchannels_Settlement_descriptor;
|
||||
}
|
||||
|
||||
protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
|
||||
internalGetFieldAccessorTable() {
|
||||
return org.bitcoin.paymentchannel.Protos.internal_static_paymentchannels_Close_fieldAccessorTable
|
||||
return org.bitcoin.paymentchannel.Protos.internal_static_paymentchannels_Settlement_fieldAccessorTable
|
||||
.ensureFieldAccessorsInitialized(
|
||||
org.bitcoin.paymentchannel.Protos.Close.class, org.bitcoin.paymentchannel.Protos.Close.Builder.class);
|
||||
org.bitcoin.paymentchannel.Protos.Settlement.class, org.bitcoin.paymentchannel.Protos.Settlement.Builder.class);
|
||||
}
|
||||
|
||||
public static com.google.protobuf.Parser<Close> PARSER =
|
||||
new com.google.protobuf.AbstractParser<Close>() {
|
||||
public Close parsePartialFrom(
|
||||
public static com.google.protobuf.Parser<Settlement> PARSER =
|
||||
new com.google.protobuf.AbstractParser<Settlement>() {
|
||||
public Settlement parsePartialFrom(
|
||||
com.google.protobuf.CodedInputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return new Close(input, extensionRegistry);
|
||||
return new Settlement(input, extensionRegistry);
|
||||
}
|
||||
};
|
||||
|
||||
@java.lang.Override
|
||||
public com.google.protobuf.Parser<Close> getParserForType() {
|
||||
public com.google.protobuf.Parser<Settlement> getParserForType() {
|
||||
return PARSER;
|
||||
}
|
||||
|
||||
@ -6806,7 +6812,7 @@ public final class Protos {
|
||||
* <code>required bytes tx = 3;</code>
|
||||
*
|
||||
* <pre>
|
||||
* A copy of the fully signed final contract that closes the channel. The client can verify
|
||||
* A copy of the fully signed final contract that settles the channel. The client can verify
|
||||
* the transaction is correct and then commit it to their wallet.
|
||||
* </pre>
|
||||
*/
|
||||
@ -6817,7 +6823,7 @@ public final class Protos {
|
||||
* <code>required bytes tx = 3;</code>
|
||||
*
|
||||
* <pre>
|
||||
* A copy of the fully signed final contract that closes the channel. The client can verify
|
||||
* A copy of the fully signed final contract that settles the channel. The client can verify
|
||||
* the transaction is correct and then commit it to their wallet.
|
||||
* </pre>
|
||||
*/
|
||||
@ -6872,53 +6878,53 @@ public final class Protos {
|
||||
return super.writeReplace();
|
||||
}
|
||||
|
||||
public static org.bitcoin.paymentchannel.Protos.Close parseFrom(
|
||||
public static org.bitcoin.paymentchannel.Protos.Settlement parseFrom(
|
||||
com.google.protobuf.ByteString data)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data);
|
||||
}
|
||||
public static org.bitcoin.paymentchannel.Protos.Close parseFrom(
|
||||
public static org.bitcoin.paymentchannel.Protos.Settlement parseFrom(
|
||||
com.google.protobuf.ByteString data,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data, extensionRegistry);
|
||||
}
|
||||
public static org.bitcoin.paymentchannel.Protos.Close parseFrom(byte[] data)
|
||||
public static org.bitcoin.paymentchannel.Protos.Settlement parseFrom(byte[] data)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data);
|
||||
}
|
||||
public static org.bitcoin.paymentchannel.Protos.Close parseFrom(
|
||||
public static org.bitcoin.paymentchannel.Protos.Settlement parseFrom(
|
||||
byte[] data,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data, extensionRegistry);
|
||||
}
|
||||
public static org.bitcoin.paymentchannel.Protos.Close parseFrom(java.io.InputStream input)
|
||||
public static org.bitcoin.paymentchannel.Protos.Settlement parseFrom(java.io.InputStream input)
|
||||
throws java.io.IOException {
|
||||
return PARSER.parseFrom(input);
|
||||
}
|
||||
public static org.bitcoin.paymentchannel.Protos.Close parseFrom(
|
||||
public static org.bitcoin.paymentchannel.Protos.Settlement parseFrom(
|
||||
java.io.InputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
return PARSER.parseFrom(input, extensionRegistry);
|
||||
}
|
||||
public static org.bitcoin.paymentchannel.Protos.Close parseDelimitedFrom(java.io.InputStream input)
|
||||
public static org.bitcoin.paymentchannel.Protos.Settlement parseDelimitedFrom(java.io.InputStream input)
|
||||
throws java.io.IOException {
|
||||
return PARSER.parseDelimitedFrom(input);
|
||||
}
|
||||
public static org.bitcoin.paymentchannel.Protos.Close parseDelimitedFrom(
|
||||
public static org.bitcoin.paymentchannel.Protos.Settlement parseDelimitedFrom(
|
||||
java.io.InputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
return PARSER.parseDelimitedFrom(input, extensionRegistry);
|
||||
}
|
||||
public static org.bitcoin.paymentchannel.Protos.Close parseFrom(
|
||||
public static org.bitcoin.paymentchannel.Protos.Settlement parseFrom(
|
||||
com.google.protobuf.CodedInputStream input)
|
||||
throws java.io.IOException {
|
||||
return PARSER.parseFrom(input);
|
||||
}
|
||||
public static org.bitcoin.paymentchannel.Protos.Close parseFrom(
|
||||
public static org.bitcoin.paymentchannel.Protos.Settlement parseFrom(
|
||||
com.google.protobuf.CodedInputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
@ -6927,7 +6933,7 @@ public final class Protos {
|
||||
|
||||
public static Builder newBuilder() { return Builder.create(); }
|
||||
public Builder newBuilderForType() { return newBuilder(); }
|
||||
public static Builder newBuilder(org.bitcoin.paymentchannel.Protos.Close prototype) {
|
||||
public static Builder newBuilder(org.bitcoin.paymentchannel.Protos.Settlement prototype) {
|
||||
return newBuilder().mergeFrom(prototype);
|
||||
}
|
||||
public Builder toBuilder() { return newBuilder(this); }
|
||||
@ -6939,24 +6945,24 @@ public final class Protos {
|
||||
return builder;
|
||||
}
|
||||
/**
|
||||
* Protobuf type {@code paymentchannels.Close}
|
||||
* Protobuf type {@code paymentchannels.Settlement}
|
||||
*/
|
||||
public static final class Builder extends
|
||||
com.google.protobuf.GeneratedMessage.Builder<Builder>
|
||||
implements org.bitcoin.paymentchannel.Protos.CloseOrBuilder {
|
||||
implements org.bitcoin.paymentchannel.Protos.SettlementOrBuilder {
|
||||
public static final com.google.protobuf.Descriptors.Descriptor
|
||||
getDescriptor() {
|
||||
return org.bitcoin.paymentchannel.Protos.internal_static_paymentchannels_Close_descriptor;
|
||||
return org.bitcoin.paymentchannel.Protos.internal_static_paymentchannels_Settlement_descriptor;
|
||||
}
|
||||
|
||||
protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
|
||||
internalGetFieldAccessorTable() {
|
||||
return org.bitcoin.paymentchannel.Protos.internal_static_paymentchannels_Close_fieldAccessorTable
|
||||
return org.bitcoin.paymentchannel.Protos.internal_static_paymentchannels_Settlement_fieldAccessorTable
|
||||
.ensureFieldAccessorsInitialized(
|
||||
org.bitcoin.paymentchannel.Protos.Close.class, org.bitcoin.paymentchannel.Protos.Close.Builder.class);
|
||||
org.bitcoin.paymentchannel.Protos.Settlement.class, org.bitcoin.paymentchannel.Protos.Settlement.Builder.class);
|
||||
}
|
||||
|
||||
// Construct using org.bitcoin.paymentchannel.Protos.Close.newBuilder()
|
||||
// Construct using org.bitcoin.paymentchannel.Protos.Settlement.newBuilder()
|
||||
private Builder() {
|
||||
maybeForceBuilderInitialization();
|
||||
}
|
||||
@ -6987,23 +6993,23 @@ public final class Protos {
|
||||
|
||||
public com.google.protobuf.Descriptors.Descriptor
|
||||
getDescriptorForType() {
|
||||
return org.bitcoin.paymentchannel.Protos.internal_static_paymentchannels_Close_descriptor;
|
||||
return org.bitcoin.paymentchannel.Protos.internal_static_paymentchannels_Settlement_descriptor;
|
||||
}
|
||||
|
||||
public org.bitcoin.paymentchannel.Protos.Close getDefaultInstanceForType() {
|
||||
return org.bitcoin.paymentchannel.Protos.Close.getDefaultInstance();
|
||||
public org.bitcoin.paymentchannel.Protos.Settlement getDefaultInstanceForType() {
|
||||
return org.bitcoin.paymentchannel.Protos.Settlement.getDefaultInstance();
|
||||
}
|
||||
|
||||
public org.bitcoin.paymentchannel.Protos.Close build() {
|
||||
org.bitcoin.paymentchannel.Protos.Close result = buildPartial();
|
||||
public org.bitcoin.paymentchannel.Protos.Settlement build() {
|
||||
org.bitcoin.paymentchannel.Protos.Settlement result = buildPartial();
|
||||
if (!result.isInitialized()) {
|
||||
throw newUninitializedMessageException(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public org.bitcoin.paymentchannel.Protos.Close buildPartial() {
|
||||
org.bitcoin.paymentchannel.Protos.Close result = new org.bitcoin.paymentchannel.Protos.Close(this);
|
||||
public org.bitcoin.paymentchannel.Protos.Settlement buildPartial() {
|
||||
org.bitcoin.paymentchannel.Protos.Settlement result = new org.bitcoin.paymentchannel.Protos.Settlement(this);
|
||||
int from_bitField0_ = bitField0_;
|
||||
int to_bitField0_ = 0;
|
||||
if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
|
||||
@ -7016,16 +7022,16 @@ public final class Protos {
|
||||
}
|
||||
|
||||
public Builder mergeFrom(com.google.protobuf.Message other) {
|
||||
if (other instanceof org.bitcoin.paymentchannel.Protos.Close) {
|
||||
return mergeFrom((org.bitcoin.paymentchannel.Protos.Close)other);
|
||||
if (other instanceof org.bitcoin.paymentchannel.Protos.Settlement) {
|
||||
return mergeFrom((org.bitcoin.paymentchannel.Protos.Settlement)other);
|
||||
} else {
|
||||
super.mergeFrom(other);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public Builder mergeFrom(org.bitcoin.paymentchannel.Protos.Close other) {
|
||||
if (other == org.bitcoin.paymentchannel.Protos.Close.getDefaultInstance()) return this;
|
||||
public Builder mergeFrom(org.bitcoin.paymentchannel.Protos.Settlement other) {
|
||||
if (other == org.bitcoin.paymentchannel.Protos.Settlement.getDefaultInstance()) return this;
|
||||
if (other.hasTx()) {
|
||||
setTx(other.getTx());
|
||||
}
|
||||
@ -7045,11 +7051,11 @@ public final class Protos {
|
||||
com.google.protobuf.CodedInputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
org.bitcoin.paymentchannel.Protos.Close parsedMessage = null;
|
||||
org.bitcoin.paymentchannel.Protos.Settlement parsedMessage = null;
|
||||
try {
|
||||
parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
|
||||
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
|
||||
parsedMessage = (org.bitcoin.paymentchannel.Protos.Close) e.getUnfinishedMessage();
|
||||
parsedMessage = (org.bitcoin.paymentchannel.Protos.Settlement) e.getUnfinishedMessage();
|
||||
throw e;
|
||||
} finally {
|
||||
if (parsedMessage != null) {
|
||||
@ -7066,7 +7072,7 @@ public final class Protos {
|
||||
* <code>required bytes tx = 3;</code>
|
||||
*
|
||||
* <pre>
|
||||
* A copy of the fully signed final contract that closes the channel. The client can verify
|
||||
* A copy of the fully signed final contract that settles the channel. The client can verify
|
||||
* the transaction is correct and then commit it to their wallet.
|
||||
* </pre>
|
||||
*/
|
||||
@ -7077,7 +7083,7 @@ public final class Protos {
|
||||
* <code>required bytes tx = 3;</code>
|
||||
*
|
||||
* <pre>
|
||||
* A copy of the fully signed final contract that closes the channel. The client can verify
|
||||
* A copy of the fully signed final contract that settles the channel. The client can verify
|
||||
* the transaction is correct and then commit it to their wallet.
|
||||
* </pre>
|
||||
*/
|
||||
@ -7088,7 +7094,7 @@ public final class Protos {
|
||||
* <code>required bytes tx = 3;</code>
|
||||
*
|
||||
* <pre>
|
||||
* A copy of the fully signed final contract that closes the channel. The client can verify
|
||||
* A copy of the fully signed final contract that settles the channel. The client can verify
|
||||
* the transaction is correct and then commit it to their wallet.
|
||||
* </pre>
|
||||
*/
|
||||
@ -7105,7 +7111,7 @@ public final class Protos {
|
||||
* <code>required bytes tx = 3;</code>
|
||||
*
|
||||
* <pre>
|
||||
* A copy of the fully signed final contract that closes the channel. The client can verify
|
||||
* A copy of the fully signed final contract that settles the channel. The client can verify
|
||||
* the transaction is correct and then commit it to their wallet.
|
||||
* </pre>
|
||||
*/
|
||||
@ -7116,15 +7122,15 @@ public final class Protos {
|
||||
return this;
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(builder_scope:paymentchannels.Close)
|
||||
// @@protoc_insertion_point(builder_scope:paymentchannels.Settlement)
|
||||
}
|
||||
|
||||
static {
|
||||
defaultInstance = new Close(true);
|
||||
defaultInstance = new Settlement(true);
|
||||
defaultInstance.initFields();
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(class_scope:paymentchannels.Close)
|
||||
// @@protoc_insertion_point(class_scope:paymentchannels.Settlement)
|
||||
}
|
||||
|
||||
public interface ErrorOrBuilder
|
||||
@ -7966,10 +7972,10 @@ public final class Protos {
|
||||
com.google.protobuf.GeneratedMessage.FieldAccessorTable
|
||||
internal_static_paymentchannels_UpdatePayment_fieldAccessorTable;
|
||||
private static com.google.protobuf.Descriptors.Descriptor
|
||||
internal_static_paymentchannels_Close_descriptor;
|
||||
internal_static_paymentchannels_Settlement_descriptor;
|
||||
private static
|
||||
com.google.protobuf.GeneratedMessage.FieldAccessorTable
|
||||
internal_static_paymentchannels_Close_fieldAccessorTable;
|
||||
internal_static_paymentchannels_Settlement_fieldAccessorTable;
|
||||
private static com.google.protobuf.Descriptors.Descriptor
|
||||
internal_static_paymentchannels_Error_descriptor;
|
||||
private static
|
||||
@ -7985,7 +7991,7 @@ public final class Protos {
|
||||
static {
|
||||
java.lang.String[] descriptorData = {
|
||||
"\n\024paymentchannel.proto\022\017paymentchannels\"" +
|
||||
"\364\005\n\024TwoWayChannelMessage\022?\n\004type\030\001 \002(\01621" +
|
||||
"\376\005\n\024TwoWayChannelMessage\022?\n\004type\030\001 \002(\01621" +
|
||||
".paymentchannels.TwoWayChannelMessage.Me" +
|
||||
"ssageType\0226\n\016client_version\030\002 \001(\0132\036.paym" +
|
||||
"entchannels.ClientVersion\0226\n\016server_vers" +
|
||||
@ -7996,32 +8002,33 @@ public final class Protos {
|
||||
"\006 \001(\0132\035.paymentchannels.ReturnRefund\022:\n\020",
|
||||
"provide_contract\030\007 \001(\0132 .paymentchannels" +
|
||||
".ProvideContract\0226\n\016update_payment\030\010 \001(\013" +
|
||||
"2\036.paymentchannels.UpdatePayment\022%\n\005clos" +
|
||||
"e\030\t \001(\0132\026.paymentchannels.Close\022%\n\005error" +
|
||||
"\030\n \001(\0132\026.paymentchannels.Error\"\315\001\n\013Messa" +
|
||||
"geType\022\022\n\016CLIENT_VERSION\020\001\022\022\n\016SERVER_VER" +
|
||||
"SION\020\002\022\014\n\010INITIATE\020\003\022\022\n\016PROVIDE_REFUND\020\004" +
|
||||
"\022\021\n\rRETURN_REFUND\020\005\022\024\n\020PROVIDE_CONTRACT\020" +
|
||||
"\006\022\020\n\014CHANNEL_OPEN\020\007\022\022\n\016UPDATE_PAYMENT\020\010\022" +
|
||||
"\017\n\013PAYMENT_ACK\020\013\022\t\n\005CLOSE\020\t\022\t\n\005ERROR\020\n\"X",
|
||||
"\n\rClientVersion\022\r\n\005major\030\001 \002(\005\022\020\n\005minor\030" +
|
||||
"\002 \001(\005:\0010\022&\n\036previous_channel_contract_ha" +
|
||||
"sh\030\003 \001(\014\"0\n\rServerVersion\022\r\n\005major\030\001 \002(\005" +
|
||||
"\022\020\n\005minor\030\002 \001(\005:\0010\"]\n\010Initiate\022\024\n\014multis" +
|
||||
"ig_key\030\001 \002(\014\022!\n\031min_accepted_channel_siz" +
|
||||
"e\030\002 \002(\004\022\030\n\020expire_time_secs\030\003 \002(\004\"1\n\rPro" +
|
||||
"videRefund\022\024\n\014multisig_key\030\001 \002(\014\022\n\n\002tx\030\002" +
|
||||
" \002(\014\"!\n\014ReturnRefund\022\021\n\tsignature\030\001 \002(\014\"" +
|
||||
"\035\n\017ProvideContract\022\n\n\002tx\030\001 \002(\014\"?\n\rUpdate" +
|
||||
"Payment\022\033\n\023client_change_value\030\001 \002(\004\022\021\n\t",
|
||||
"signature\030\002 \002(\014\"\023\n\005Close\022\n\n\002tx\030\003 \002(\014\"\363\001\n" +
|
||||
"\005Error\0225\n\004code\030\001 \001(\0162 .paymentchannels.E" +
|
||||
"rror.ErrorCode:\005OTHER\022\023\n\013explanation\030\002 \001" +
|
||||
"(\t\"\235\001\n\tErrorCode\022\013\n\007TIMEOUT\020\001\022\020\n\014SYNTAX_" +
|
||||
"ERROR\020\002\022\031\n\025NO_ACCEPTABLE_VERSION\020\003\022\023\n\017BA" +
|
||||
"D_TRANSACTION\020\004\022\031\n\025TIME_WINDOW_TOO_LARGE" +
|
||||
"\020\005\022\033\n\027CHANNEL_VALUE_TOO_LARGE\020\006\022\t\n\005OTHER" +
|
||||
"\020\007B$\n\032org.bitcoin.paymentchannelB\006Protos"
|
||||
"2\036.paymentchannels.UpdatePayment\022/\n\nsett" +
|
||||
"lement\030\t \001(\0132\033.paymentchannels.Settlemen" +
|
||||
"t\022%\n\005error\030\n \001(\0132\026.paymentchannels.Error" +
|
||||
"\"\315\001\n\013MessageType\022\022\n\016CLIENT_VERSION\020\001\022\022\n\016" +
|
||||
"SERVER_VERSION\020\002\022\014\n\010INITIATE\020\003\022\022\n\016PROVID" +
|
||||
"E_REFUND\020\004\022\021\n\rRETURN_REFUND\020\005\022\024\n\020PROVIDE" +
|
||||
"_CONTRACT\020\006\022\020\n\014CHANNEL_OPEN\020\007\022\022\n\016UPDATE_" +
|
||||
"PAYMENT\020\010\022\017\n\013PAYMENT_ACK\020\013\022\t\n\005CLOSE\020\t\022\t\n",
|
||||
"\005ERROR\020\n\"X\n\rClientVersion\022\r\n\005major\030\001 \002(\005" +
|
||||
"\022\020\n\005minor\030\002 \001(\005:\0010\022&\n\036previous_channel_c" +
|
||||
"ontract_hash\030\003 \001(\014\"0\n\rServerVersion\022\r\n\005m" +
|
||||
"ajor\030\001 \002(\005\022\020\n\005minor\030\002 \001(\005:\0010\"]\n\010Initiate" +
|
||||
"\022\024\n\014multisig_key\030\001 \002(\014\022!\n\031min_accepted_c" +
|
||||
"hannel_size\030\002 \002(\004\022\030\n\020expire_time_secs\030\003 " +
|
||||
"\002(\004\"1\n\rProvideRefund\022\024\n\014multisig_key\030\001 \002" +
|
||||
"(\014\022\n\n\002tx\030\002 \002(\014\"!\n\014ReturnRefund\022\021\n\tsignat" +
|
||||
"ure\030\001 \002(\014\"\035\n\017ProvideContract\022\n\n\002tx\030\001 \002(\014" +
|
||||
"\"?\n\rUpdatePayment\022\033\n\023client_change_value",
|
||||
"\030\001 \002(\004\022\021\n\tsignature\030\002 \002(\014\"\030\n\nSettlement\022" +
|
||||
"\n\n\002tx\030\003 \002(\014\"\363\001\n\005Error\0225\n\004code\030\001 \001(\0162 .pa" +
|
||||
"ymentchannels.Error.ErrorCode:\005OTHER\022\023\n\013" +
|
||||
"explanation\030\002 \001(\t\"\235\001\n\tErrorCode\022\013\n\007TIMEO" +
|
||||
"UT\020\001\022\020\n\014SYNTAX_ERROR\020\002\022\031\n\025NO_ACCEPTABLE_" +
|
||||
"VERSION\020\003\022\023\n\017BAD_TRANSACTION\020\004\022\031\n\025TIME_W" +
|
||||
"INDOW_TOO_LARGE\020\005\022\033\n\027CHANNEL_VALUE_TOO_L" +
|
||||
"ARGE\020\006\022\t\n\005OTHER\020\007B$\n\032org.bitcoin.payment" +
|
||||
"channelB\006Protos"
|
||||
};
|
||||
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
|
||||
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
|
||||
@ -8033,7 +8040,7 @@ public final class Protos {
|
||||
internal_static_paymentchannels_TwoWayChannelMessage_fieldAccessorTable = new
|
||||
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
|
||||
internal_static_paymentchannels_TwoWayChannelMessage_descriptor,
|
||||
new java.lang.String[] { "Type", "ClientVersion", "ServerVersion", "Initiate", "ProvideRefund", "ReturnRefund", "ProvideContract", "UpdatePayment", "Close", "Error", });
|
||||
new java.lang.String[] { "Type", "ClientVersion", "ServerVersion", "Initiate", "ProvideRefund", "ReturnRefund", "ProvideContract", "UpdatePayment", "Settlement", "Error", });
|
||||
internal_static_paymentchannels_ClientVersion_descriptor =
|
||||
getDescriptor().getMessageTypes().get(1);
|
||||
internal_static_paymentchannels_ClientVersion_fieldAccessorTable = new
|
||||
@ -8076,11 +8083,11 @@ public final class Protos {
|
||||
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
|
||||
internal_static_paymentchannels_UpdatePayment_descriptor,
|
||||
new java.lang.String[] { "ClientChangeValue", "Signature", });
|
||||
internal_static_paymentchannels_Close_descriptor =
|
||||
internal_static_paymentchannels_Settlement_descriptor =
|
||||
getDescriptor().getMessageTypes().get(8);
|
||||
internal_static_paymentchannels_Close_fieldAccessorTable = new
|
||||
internal_static_paymentchannels_Settlement_fieldAccessorTable = new
|
||||
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
|
||||
internal_static_paymentchannels_Close_descriptor,
|
||||
internal_static_paymentchannels_Settlement_descriptor,
|
||||
new java.lang.String[] { "Tx", });
|
||||
internal_static_paymentchannels_Error_descriptor =
|
||||
getDescriptor().getMessageTypes().get(9);
|
||||
|
@ -53,11 +53,14 @@ message TwoWayChannelMessage {
|
||||
// takes the most recent signature it received in an UPDATE_PAYMENT and uses it to create a
|
||||
// valid transaction, which it then broadcasts on the network.
|
||||
//
|
||||
// If the server sends it to the client, then it can either be a simple "good bye" message or
|
||||
// it can include the fully signed close transaction and give it back so the client can
|
||||
// eventually broadcast it as well, in case the server fails to do so for some reason (and
|
||||
// more usefully so the client can build on it). In that case the server replies to a CLOSE
|
||||
// with another CLOSE and then disconnects.
|
||||
// Once broadcast is complete, it sends back another CLOSE message with the settlement field set, containing
|
||||
// the final state of the contract.
|
||||
//
|
||||
// The server is allowed to initiate settlement whenever it wants, in which case the client will
|
||||
// asynchronously receive a CLOSE message with the settlement field set. The server is also allowed
|
||||
// to send a CLOSE to mark the end of a connection without any settlement taking place, in which
|
||||
// case this is just an equivalent to a TCP FIN packet. An explicit end-of-protocol markers can be
|
||||
// useful when this protocol is embedded inside another.
|
||||
CLOSE = 9;
|
||||
|
||||
// Used to indicate an error condition.
|
||||
@ -80,7 +83,7 @@ message TwoWayChannelMessage {
|
||||
optional ReturnRefund return_refund = 6;
|
||||
optional ProvideContract provide_contract = 7;
|
||||
optional UpdatePayment update_payment = 8;
|
||||
optional Close close = 9;
|
||||
optional Settlement settlement = 9;
|
||||
|
||||
optional Error error = 10;
|
||||
}
|
||||
@ -110,7 +113,7 @@ message ServerVersion {
|
||||
optional int32 minor = 2 [default = 0];
|
||||
}
|
||||
|
||||
// Sent from secondary to primary once version nego is done.
|
||||
// Sent from server to client once version nego is done.
|
||||
message Initiate {
|
||||
// This must be a raw pubkey in regular ECDSA form. Both compressed and non-compressed forms
|
||||
// are accepted. It is used only in the creation of the multisig contract, as outputs are
|
||||
@ -194,8 +197,8 @@ message UpdatePayment {
|
||||
required bytes signature = 2;
|
||||
}
|
||||
|
||||
message Close {
|
||||
// A copy of the fully signed final contract that closes the channel. The client can verify
|
||||
message Settlement {
|
||||
// A copy of the fully signed final contract that settles the channel. The client can verify
|
||||
// the transaction is correct and then commit it to their wallet.
|
||||
required bytes tx = 3;
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ public class ChannelConnectionTest extends TestWithWallet {
|
||||
|
||||
@Test
|
||||
public void testSimpleChannel() throws Exception {
|
||||
// Test with network code and without any issues. We'll broadcast two txns: multisig contract and close transaction.
|
||||
// Test with network code and without any issues. We'll broadcast two txns: multisig contract and settle transaction.
|
||||
final SettableFuture<ListenableFuture<PaymentChannelServerState>> serverCloseFuture = SettableFuture.create();
|
||||
final SettableFuture<Sha256Hash> channelOpenFuture = SettableFuture.create();
|
||||
final BlockingQueue<BigInteger> q = new LinkedBlockingQueue<BigInteger>();
|
||||
@ -177,25 +177,25 @@ public class ChannelConnectionTest extends TestWithWallet {
|
||||
StoredServerChannel storedServerChannel = channels.getChannel(broadcastMultiSig.getHash());
|
||||
PaymentChannelServerState serverState = storedServerChannel.getOrCreateState(serverWallet, mockBroadcaster);
|
||||
|
||||
// Check that you can call close multiple times with no exceptions.
|
||||
client.close();
|
||||
client.close();
|
||||
// Check that you can call settle multiple times with no exceptions.
|
||||
client.settle();
|
||||
client.settle();
|
||||
|
||||
broadcastTxPause.release();
|
||||
Transaction closeTx = broadcasts.take();
|
||||
Transaction settleTx = broadcasts.take();
|
||||
assertEquals(PaymentChannelServerState.State.CLOSED, serverState.getState());
|
||||
if (!serverState.getBestValueToMe().equals(Utils.CENT.multiply(BigInteger.valueOf(3))) || !serverState.getFeePaid().equals(BigInteger.ZERO))
|
||||
fail();
|
||||
assertTrue(channels.mapChannels.isEmpty());
|
||||
|
||||
// Send the close TX to the client wallet.
|
||||
sendMoneyToWallet(closeTx, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||
// Send the settle TX to the client wallet.
|
||||
sendMoneyToWallet(settleTx, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||
assertEquals(PaymentChannelClientState.State.CLOSED, client.state().getState());
|
||||
|
||||
server.close();
|
||||
server.close();
|
||||
|
||||
// Now confirm the close TX and see if the channel deletes itself from the wallet.
|
||||
// Now confirm the settle TX and see if the channel deletes itself from the wallet.
|
||||
assertEquals(1, StoredPaymentChannelClientStates.getFromWallet(wallet).mapChannels.size());
|
||||
wallet.notifyNewBestBlock(createFakeBlock(blockStore).storedBlock);
|
||||
assertEquals(1, StoredPaymentChannelClientStates.getFromWallet(wallet).mapChannels.size());
|
||||
@ -237,7 +237,7 @@ public class ChannelConnectionTest extends TestWithWallet {
|
||||
client.connectionOpen();
|
||||
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.CLIENT_VERSION));
|
||||
client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.SERVER_VERSION));
|
||||
client.close();
|
||||
client.settle();
|
||||
client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.INITIATE));
|
||||
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.CLOSE));
|
||||
assertEquals(CloseReason.CLIENT_REQUESTED_CLOSE, pair.serverRecorder.q.take());
|
||||
@ -604,7 +604,7 @@ public class ChannelConnectionTest extends TestWithWallet {
|
||||
pair.clientRecorder.checkOpened();
|
||||
assertNull(pair.serverRecorder.q.poll());
|
||||
assertNull(pair.clientRecorder.q.poll());
|
||||
// Send the whole channel at once. The server will broadcast the final contract and close the channel for us.
|
||||
// Send the whole channel at once. The server will broadcast the final contract and settle the channel for us.
|
||||
client.incrementPayment(Utils.COIN);
|
||||
broadcastTxPause.release();
|
||||
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.UPDATE_PAYMENT));
|
||||
@ -628,7 +628,7 @@ public class ChannelConnectionTest extends TestWithWallet {
|
||||
public void repeatedChannels() throws Exception {
|
||||
// Ensures we're selecting channels correctly. Covers a bug in which we'd always try and fail to resume
|
||||
// the first channel due to lack of proper closing behaviour.
|
||||
// Open up a normal channel, but don't spend all of it, then close it.
|
||||
// Open up a normal channel, but don't spend all of it, then settle it.
|
||||
{
|
||||
Sha256Hash someServerId = Sha256Hash.ZERO_HASH;
|
||||
ChannelTestUtils.RecordingPair pair = ChannelTestUtils.makeRecorders(serverWallet, mockBroadcaster);
|
||||
@ -664,22 +664,22 @@ public class ChannelConnectionTest extends TestWithWallet {
|
||||
pair.serverRecorder.q.take();
|
||||
client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.PAYMENT_ACK));
|
||||
|
||||
// Close it and verify it's considered to be closed.
|
||||
// Settle it and verify it's considered to be settled.
|
||||
broadcastTxPause.release();
|
||||
client.close();
|
||||
client.settle();
|
||||
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.CLOSE));
|
||||
Transaction close = broadcasts.take();
|
||||
// Server sends back the close TX it just broadcast.
|
||||
Transaction settlement1 = broadcasts.take();
|
||||
// Server sends back the settle TX it just broadcast.
|
||||
final Protos.TwoWayChannelMessage closeMsg = pair.serverRecorder.checkNextMsg(MessageType.CLOSE);
|
||||
final Transaction closeTx = new Transaction(params, closeMsg.getClose().getTx().toByteArray());
|
||||
assertEquals(close, closeTx);
|
||||
final Transaction settlement2 = new Transaction(params, closeMsg.getSettlement().getTx().toByteArray());
|
||||
assertEquals(settlement1, settlement2);
|
||||
client.receiveMessage(closeMsg);
|
||||
assertNotNull(wallet.getTransaction(closeTx.getHash())); // Close TX entered the wallet.
|
||||
sendMoneyToWallet(close, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||
assertNotNull(wallet.getTransaction(settlement2.getHash())); // Close TX entered the wallet.
|
||||
sendMoneyToWallet(settlement1, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||
client.connectionClosed();
|
||||
server.connectionClosed();
|
||||
}
|
||||
// Now open a second channel and don't spend all of it/don't close it.
|
||||
// Now open a second channel and don't spend all of it/don't settle it.
|
||||
{
|
||||
Sha256Hash someServerId = Sha256Hash.ZERO_HASH;
|
||||
ChannelTestUtils.RecordingPair pair = ChannelTestUtils.makeRecorders(serverWallet, mockBroadcaster);
|
||||
|
@ -182,7 +182,7 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
||||
totalPayment = totalPayment.add(size);
|
||||
serverState.incrementPayment(halfCoin.subtract(totalPayment), signature);
|
||||
|
||||
// And close the channel.
|
||||
// And settle the channel.
|
||||
serverState.close();
|
||||
assertEquals(PaymentChannelServerState.State.CLOSING, serverState.getState());
|
||||
final TxFuturePair pair2 = broadcasts.take();
|
||||
@ -631,10 +631,10 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
||||
|
||||
serverState.incrementPayment(Utils.CENT.subtract(totalPayment), payment.signature.encodeToBitcoin());
|
||||
|
||||
// And close the channel.
|
||||
// And settle the channel.
|
||||
serverState.close();
|
||||
assertEquals(PaymentChannelServerState.State.CLOSING, serverState.getState());
|
||||
pair = broadcasts.take(); // close
|
||||
pair = broadcasts.take(); // settle
|
||||
pair.future.set(pair.tx);
|
||||
assertEquals(PaymentChannelServerState.State.CLOSED, serverState.getState());
|
||||
serverState.close();
|
||||
@ -719,7 +719,7 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
||||
totalRefund = totalRefund.subtract(BigInteger.ONE.shiftLeft(1));
|
||||
serverState.incrementPayment(totalRefund, signature);
|
||||
|
||||
// And close the channel.
|
||||
// And settle the channel.
|
||||
serverState.close();
|
||||
assertEquals(PaymentChannelServerState.State.CLOSING, serverState.getState());
|
||||
pair = broadcasts.take();
|
||||
|
@ -129,11 +129,11 @@ public class ExamplePaymentChannelClient {
|
||||
// left. If we never do this then eventually the server will time out and do it anyway and if the
|
||||
// server goes away for longer, then eventually WE will time out and the refund tx will get broadcast
|
||||
// by ourselves.
|
||||
log.info("Closing channel for good");
|
||||
client.close();
|
||||
log.info("Settling channel for good");
|
||||
client.settle();
|
||||
} else {
|
||||
// Just unplug from the server but leave the channel open so it can resume later.
|
||||
client.disconnectWithoutChannelClose();
|
||||
client.disconnectWithoutSettlement();
|
||||
}
|
||||
latch.countDown();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user