mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-02-07 23:03:04 +00:00
Payment channels: protocol tweak - when the client sends a CLOSE, the server sends a CLOSE back that contains the final negotiated contract, so it can be inserted into the wallet without needing to wait for a network broadcast (this is useful if the client does not have internet connectivity at that point).
This commit is contained in:
parent
b9aa1e4d1e
commit
6342af0913
@ -91,7 +91,9 @@ public class PaymentChannelClient {
|
|||||||
WAITING_FOR_INITIATE,
|
WAITING_FOR_INITIATE,
|
||||||
WAITING_FOR_REFUND_RETURN,
|
WAITING_FOR_REFUND_RETURN,
|
||||||
WAITING_FOR_CHANNEL_OPEN,
|
WAITING_FOR_CHANNEL_OPEN,
|
||||||
CHANNEL_OPEN
|
CHANNEL_OPEN,
|
||||||
|
WAITING_FOR_CHANNEL_CLOSE,
|
||||||
|
CHANNEL_CLOSED,
|
||||||
}
|
}
|
||||||
@GuardedBy("lock") private InitStep step = InitStep.WAITING_FOR_CONNECTION_OPEN;
|
@GuardedBy("lock") private InitStep step = InitStep.WAITING_FOR_CONNECTION_OPEN;
|
||||||
|
|
||||||
@ -253,7 +255,7 @@ public class PaymentChannelClient {
|
|||||||
receiveChannelOpen();
|
receiveChannelOpen();
|
||||||
return;
|
return;
|
||||||
case CLOSE:
|
case CLOSE:
|
||||||
conn.destroyConnection(CloseReason.SERVER_REQUESTED_CLOSE);
|
receiveClose(msg);
|
||||||
return;
|
return;
|
||||||
case ERROR:
|
case ERROR:
|
||||||
checkState(msg.hasError());
|
checkState(msg.hasError());
|
||||||
@ -290,6 +292,26 @@ public class PaymentChannelClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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());
|
||||||
|
// 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
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (step == InitStep.WAITING_FOR_CHANNEL_CLOSE)
|
||||||
|
conn.destroyConnection(CloseReason.CLIENT_REQUESTED_CLOSE);
|
||||||
|
else
|
||||||
|
conn.destroyConnection(CloseReason.SERVER_REQUESTED_CLOSE);
|
||||||
|
step = InitStep.CHANNEL_CLOSED;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Called when the connection terminates. Notifies the {@link StoredClientChannel} object that we can attempt to
|
* <p>Called when the connection terminates. Notifies the {@link StoredClientChannel} object that we can attempt to
|
||||||
* resume this channel in the future and stops generating messages for the server.</p>
|
* resume this channel in the future and stops generating messages for the server.</p>
|
||||||
@ -327,10 +349,11 @@ public class PaymentChannelClient {
|
|||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
checkState(connectionOpen);
|
checkState(connectionOpen);
|
||||||
|
step = InitStep.WAITING_FOR_CHANNEL_CLOSE;
|
||||||
|
log.info("Sending a CLOSE message to the server and waiting for response indicating successful propagation.");
|
||||||
conn.sendToServer(Protos.TwoWayChannelMessage.newBuilder()
|
conn.sendToServer(Protos.TwoWayChannelMessage.newBuilder()
|
||||||
.setType(Protos.TwoWayChannelMessage.MessageType.CLOSE)
|
.setType(Protos.TwoWayChannelMessage.MessageType.CLOSE)
|
||||||
.build());
|
.build());
|
||||||
conn.destroyConnection(CloseReason.CLIENT_REQUESTED_CLOSE);
|
|
||||||
} finally {
|
} finally {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
|
@ -123,8 +123,12 @@ public class PaymentChannelClientState {
|
|||||||
initWalletListeners();
|
initWalletListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isCloseTransaction(Transaction tx) {
|
/**
|
||||||
|
* Returns true if the tx is a valid close transaction.
|
||||||
|
*/
|
||||||
|
public boolean isCloseTransaction(Transaction tx) {
|
||||||
try {
|
try {
|
||||||
|
tx.verify();
|
||||||
tx.getInput(0).verify(multisigContract.getOutput(0));
|
tx.getInput(0).verify(multisigContract.getOutput(0));
|
||||||
return true;
|
return true;
|
||||||
} catch (VerificationException e) {
|
} catch (VerificationException e) {
|
||||||
|
@ -3,6 +3,8 @@ package com.google.bitcoin.protocols.channels;
|
|||||||
import com.google.bitcoin.core.*;
|
import com.google.bitcoin.core.*;
|
||||||
import com.google.bitcoin.protocols.channels.PaymentChannelCloseException.CloseReason;
|
import com.google.bitcoin.protocols.channels.PaymentChannelCloseException.CloseReason;
|
||||||
import com.google.bitcoin.utils.Threading;
|
import com.google.bitcoin.utils.Threading;
|
||||||
|
import com.google.common.util.concurrent.FutureCallback;
|
||||||
|
import com.google.common.util.concurrent.Futures;
|
||||||
import com.google.protobuf.ByteString;
|
import com.google.protobuf.ByteString;
|
||||||
import net.jcip.annotations.GuardedBy;
|
import net.jcip.annotations.GuardedBy;
|
||||||
import org.bitcoin.paymentchannel.Protos;
|
import org.bitcoin.paymentchannel.Protos;
|
||||||
@ -304,9 +306,31 @@ public class PaymentChannelServer {
|
|||||||
case CLOSE:
|
case CLOSE:
|
||||||
log.info("Got CLOSE message, closing channel");
|
log.info("Got CLOSE message, closing channel");
|
||||||
connectionClosing = true;
|
connectionClosing = true;
|
||||||
if (state != null)
|
if (state != null) {
|
||||||
state.close();
|
Futures.addCallback(state.close(), new FutureCallback<Transaction>() {
|
||||||
conn.destroyConnection(CloseReason.CLIENT_REQUESTED_CLOSE);
|
@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()));
|
||||||
|
}
|
||||||
|
conn.sendToClient(msg.build());
|
||||||
|
conn.destroyConnection(CloseReason.CLIENT_REQUESTED_CLOSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@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);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
case ERROR:
|
case ERROR:
|
||||||
checkState(msg.hasError());
|
checkState(msg.hasError());
|
||||||
@ -407,9 +431,9 @@ public class PaymentChannelServer {
|
|||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
if (connectionOpen && !connectionClosing) {
|
if (connectionOpen && !connectionClosing) {
|
||||||
conn.sendToClient(Protos.TwoWayChannelMessage.newBuilder()
|
final Protos.TwoWayChannelMessage.Builder msg = Protos.TwoWayChannelMessage.newBuilder();
|
||||||
.setType(Protos.TwoWayChannelMessage.MessageType.CLOSE)
|
msg.setType(Protos.TwoWayChannelMessage.MessageType.CLOSE);
|
||||||
.build());
|
conn.sendToClient(msg.build());
|
||||||
conn.destroyConnection(CloseReason.SERVER_REQUESTED_CLOSE);
|
conn.destroyConnection(CloseReason.SERVER_REQUESTED_CLOSE);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -344,7 +344,7 @@ public class PaymentChannelServerState {
|
|||||||
tx.getInput(0).setScriptSig(scriptSig);
|
tx.getInput(0).setScriptSig(scriptSig);
|
||||||
}
|
}
|
||||||
|
|
||||||
final SettableFuture<PaymentChannelServerState> closedFuture = SettableFuture.create();
|
final SettableFuture<Transaction> closedFuture = SettableFuture.create();
|
||||||
/**
|
/**
|
||||||
* <p>Closes this channel and broadcasts the highest value payment transaction on the network.</p>
|
* <p>Closes this channel and broadcasts the highest value payment transaction on the network.</p>
|
||||||
*
|
*
|
||||||
@ -355,11 +355,12 @@ public class PaymentChannelServerState {
|
|||||||
* simply set the state to {@link State#CLOSED} and let the client handle getting its refund transaction confirmed.
|
* simply set the state to {@link State#CLOSED} and let the client handle getting its refund transaction confirmed.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @return a future which completes when the provided multisig contract successfully broadcasts, or throws if the broadcast fails for some reason
|
* @return a future which completes when the provided multisig contract successfully broadcasts, or throws if the
|
||||||
* Note that if the network simply rejects the transaction, this future will never complete, a timeout should be used.
|
* broadcast fails for some reason. Note that if the network simply rejects the transaction, this future
|
||||||
* @throws ValueOutOfRangeException If the payment transaction would have cost more in fees to spend than it was worth
|
* will never complete, a timeout should be used.
|
||||||
|
* @throws ValueOutOfRangeException If the payment tx would have cost more in fees to spend than it is worth.
|
||||||
*/
|
*/
|
||||||
public synchronized ListenableFuture<PaymentChannelServerState> close() throws ValueOutOfRangeException {
|
public synchronized ListenableFuture<Transaction> close() throws ValueOutOfRangeException {
|
||||||
if (storedServerChannel != null) {
|
if (storedServerChannel != null) {
|
||||||
StoredServerChannel temp = storedServerChannel;
|
StoredServerChannel temp = storedServerChannel;
|
||||||
storedServerChannel = null;
|
storedServerChannel = null;
|
||||||
@ -371,11 +372,13 @@ public class PaymentChannelServerState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (state.ordinal() < State.READY.ordinal()) {
|
if (state.ordinal() < State.READY.ordinal()) {
|
||||||
|
log.error("Attempt to close channel in state " + state);
|
||||||
state = State.CLOSED;
|
state = State.CLOSED;
|
||||||
closedFuture.set(this);
|
closedFuture.set(null);
|
||||||
return closedFuture;
|
return closedFuture;
|
||||||
}
|
}
|
||||||
if (state != State.READY) {
|
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 close a channel in state " + state);
|
||||||
return closedFuture;
|
return closedFuture;
|
||||||
}
|
}
|
||||||
@ -386,7 +389,7 @@ public class PaymentChannelServerState {
|
|||||||
// the submission of an initial zero-valued payment during the open phase.
|
// the submission of an initial zero-valued payment during the open phase.
|
||||||
log.warn("Closing channel that never received any payments.");
|
log.warn("Closing channel that never received any payments.");
|
||||||
state = State.CLOSED;
|
state = State.CLOSED;
|
||||||
closedFuture.set(this);
|
closedFuture.set(null);
|
||||||
return closedFuture;
|
return closedFuture;
|
||||||
}
|
}
|
||||||
Transaction tx = null;
|
Transaction tx = null;
|
||||||
@ -426,7 +429,7 @@ public class PaymentChannelServerState {
|
|||||||
@Override public void onSuccess(Transaction transaction) {
|
@Override public void onSuccess(Transaction transaction) {
|
||||||
log.info("TX {} propagated, channel successfully closed.", transaction.getHash());
|
log.info("TX {} propagated, channel successfully closed.", transaction.getHash());
|
||||||
state = State.CLOSED;
|
state = State.CLOSED;
|
||||||
closedFuture.set(PaymentChannelServerState.this);
|
closedFuture.set(transaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void onFailure(Throwable throwable) {
|
@Override public void onFailure(Throwable throwable) {
|
||||||
|
@ -83,7 +83,6 @@ public class StoredPaymentChannelServerStates implements WalletExtension {
|
|||||||
synchronized (channel) {
|
synchronized (channel) {
|
||||||
channel.closeConnectedHandler();
|
channel.closeConnectedHandler();
|
||||||
try {
|
try {
|
||||||
//TODO add event listener to PaymentChannelServerStateManager
|
|
||||||
channel.getOrCreateState(wallet, broadcaster).close();
|
channel.getOrCreateState(wallet, broadcaster).close();
|
||||||
} catch (ValueOutOfRangeException e) {
|
} catch (ValueOutOfRangeException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -143,6 +143,20 @@ public final class Protos {
|
|||||||
*/
|
*/
|
||||||
org.bitcoin.paymentchannel.Protos.UpdatePaymentOrBuilder getUpdatePaymentOrBuilder();
|
org.bitcoin.paymentchannel.Protos.UpdatePaymentOrBuilder getUpdatePaymentOrBuilder();
|
||||||
|
|
||||||
|
// optional .paymentchannels.Close close = 9;
|
||||||
|
/**
|
||||||
|
* <code>optional .paymentchannels.Close close = 9;</code>
|
||||||
|
*/
|
||||||
|
boolean hasClose();
|
||||||
|
/**
|
||||||
|
* <code>optional .paymentchannels.Close close = 9;</code>
|
||||||
|
*/
|
||||||
|
org.bitcoin.paymentchannel.Protos.Close getClose();
|
||||||
|
/**
|
||||||
|
* <code>optional .paymentchannels.Close close = 9;</code>
|
||||||
|
*/
|
||||||
|
org.bitcoin.paymentchannel.Protos.CloseOrBuilder getCloseOrBuilder();
|
||||||
|
|
||||||
// optional .paymentchannels.Error error = 10;
|
// optional .paymentchannels.Error error = 10;
|
||||||
/**
|
/**
|
||||||
* <code>optional .paymentchannels.Error error = 10;</code>
|
* <code>optional .paymentchannels.Error error = 10;</code>
|
||||||
@ -316,9 +330,22 @@ public final class Protos {
|
|||||||
bitField0_ |= 0x00000080;
|
bitField0_ |= 0x00000080;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 74: {
|
||||||
|
org.bitcoin.paymentchannel.Protos.Close.Builder subBuilder = null;
|
||||||
|
if (((bitField0_ & 0x00000100) == 0x00000100)) {
|
||||||
|
subBuilder = close_.toBuilder();
|
||||||
|
}
|
||||||
|
close_ = input.readMessage(org.bitcoin.paymentchannel.Protos.Close.PARSER, extensionRegistry);
|
||||||
|
if (subBuilder != null) {
|
||||||
|
subBuilder.mergeFrom(close_);
|
||||||
|
close_ = subBuilder.buildPartial();
|
||||||
|
}
|
||||||
|
bitField0_ |= 0x00000100;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 82: {
|
case 82: {
|
||||||
org.bitcoin.paymentchannel.Protos.Error.Builder subBuilder = null;
|
org.bitcoin.paymentchannel.Protos.Error.Builder subBuilder = null;
|
||||||
if (((bitField0_ & 0x00000100) == 0x00000100)) {
|
if (((bitField0_ & 0x00000200) == 0x00000200)) {
|
||||||
subBuilder = error_.toBuilder();
|
subBuilder = error_.toBuilder();
|
||||||
}
|
}
|
||||||
error_ = input.readMessage(org.bitcoin.paymentchannel.Protos.Error.PARSER, extensionRegistry);
|
error_ = input.readMessage(org.bitcoin.paymentchannel.Protos.Error.PARSER, extensionRegistry);
|
||||||
@ -326,7 +353,7 @@ public final class Protos {
|
|||||||
subBuilder.mergeFrom(error_);
|
subBuilder.mergeFrom(error_);
|
||||||
error_ = subBuilder.buildPartial();
|
error_ = subBuilder.buildPartial();
|
||||||
}
|
}
|
||||||
bitField0_ |= 0x00000100;
|
bitField0_ |= 0x00000200;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -419,10 +446,15 @@ public final class Protos {
|
|||||||
* <code>CLOSE = 9;</code>
|
* <code>CLOSE = 9;</code>
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* Note that there are no optional fields set for CLOSE, it is sent by either party to
|
* Either side can send this message. If the client sends it to the server, then the server
|
||||||
* indicate that the channel is now closed and no further updates can happen. After this,
|
* takes the most recent signature it received in an UPDATE_PAYMENT and uses it to create a
|
||||||
* the secondary takes the most recent signature it received in an UPDATE_PAYMENT and
|
* valid transaction, which it then broadcasts on the network.
|
||||||
* 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.
|
||||||
* </pre>
|
* </pre>
|
||||||
*/
|
*/
|
||||||
CLOSE(8, 9),
|
CLOSE(8, 9),
|
||||||
@ -432,7 +464,8 @@ public final class Protos {
|
|||||||
* <pre>
|
* <pre>
|
||||||
* Used to indicate an error condition.
|
* Used to indicate an error condition.
|
||||||
* Both parties should make an effort to send either an ERROR or a CLOSE immediately
|
* Both parties should make an effort to send either an ERROR or a CLOSE immediately
|
||||||
* before closing the socket (unless they just received an ERROR or a CLOSE)
|
* before closing the socket (unless they just received an ERROR or a CLOSE). This is important
|
||||||
|
* because the protocol may not run over TCP.
|
||||||
* </pre>
|
* </pre>
|
||||||
*/
|
*/
|
||||||
ERROR(9, 10),
|
ERROR(9, 10),
|
||||||
@ -484,10 +517,15 @@ public final class Protos {
|
|||||||
* <code>CLOSE = 9;</code>
|
* <code>CLOSE = 9;</code>
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* Note that there are no optional fields set for CLOSE, it is sent by either party to
|
* Either side can send this message. If the client sends it to the server, then the server
|
||||||
* indicate that the channel is now closed and no further updates can happen. After this,
|
* takes the most recent signature it received in an UPDATE_PAYMENT and uses it to create a
|
||||||
* the secondary takes the most recent signature it received in an UPDATE_PAYMENT and
|
* valid transaction, which it then broadcasts on the network.
|
||||||
* 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.
|
||||||
* </pre>
|
* </pre>
|
||||||
*/
|
*/
|
||||||
public static final int CLOSE_VALUE = 9;
|
public static final int CLOSE_VALUE = 9;
|
||||||
@ -497,7 +535,8 @@ public final class Protos {
|
|||||||
* <pre>
|
* <pre>
|
||||||
* Used to indicate an error condition.
|
* Used to indicate an error condition.
|
||||||
* Both parties should make an effort to send either an ERROR or a CLOSE immediately
|
* Both parties should make an effort to send either an ERROR or a CLOSE immediately
|
||||||
* before closing the socket (unless they just received an ERROR or a CLOSE)
|
* before closing the socket (unless they just received an ERROR or a CLOSE). This is important
|
||||||
|
* because the protocol may not run over TCP.
|
||||||
* </pre>
|
* </pre>
|
||||||
*/
|
*/
|
||||||
public static final int ERROR_VALUE = 10;
|
public static final int ERROR_VALUE = 10;
|
||||||
@ -763,6 +802,28 @@ public final class Protos {
|
|||||||
return updatePayment_;
|
return updatePayment_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// optional .paymentchannels.Close close = 9;
|
||||||
|
public static final int CLOSE_FIELD_NUMBER = 9;
|
||||||
|
private org.bitcoin.paymentchannel.Protos.Close close_;
|
||||||
|
/**
|
||||||
|
* <code>optional .paymentchannels.Close close = 9;</code>
|
||||||
|
*/
|
||||||
|
public boolean hasClose() {
|
||||||
|
return ((bitField0_ & 0x00000100) == 0x00000100);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>optional .paymentchannels.Close close = 9;</code>
|
||||||
|
*/
|
||||||
|
public org.bitcoin.paymentchannel.Protos.Close getClose() {
|
||||||
|
return close_;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>optional .paymentchannels.Close close = 9;</code>
|
||||||
|
*/
|
||||||
|
public org.bitcoin.paymentchannel.Protos.CloseOrBuilder getCloseOrBuilder() {
|
||||||
|
return close_;
|
||||||
|
}
|
||||||
|
|
||||||
// optional .paymentchannels.Error error = 10;
|
// optional .paymentchannels.Error error = 10;
|
||||||
public static final int ERROR_FIELD_NUMBER = 10;
|
public static final int ERROR_FIELD_NUMBER = 10;
|
||||||
private org.bitcoin.paymentchannel.Protos.Error error_;
|
private org.bitcoin.paymentchannel.Protos.Error error_;
|
||||||
@ -770,7 +831,7 @@ public final class Protos {
|
|||||||
* <code>optional .paymentchannels.Error error = 10;</code>
|
* <code>optional .paymentchannels.Error error = 10;</code>
|
||||||
*/
|
*/
|
||||||
public boolean hasError() {
|
public boolean hasError() {
|
||||||
return ((bitField0_ & 0x00000100) == 0x00000100);
|
return ((bitField0_ & 0x00000200) == 0x00000200);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* <code>optional .paymentchannels.Error error = 10;</code>
|
* <code>optional .paymentchannels.Error error = 10;</code>
|
||||||
@ -794,6 +855,7 @@ public final class Protos {
|
|||||||
returnRefund_ = org.bitcoin.paymentchannel.Protos.ReturnRefund.getDefaultInstance();
|
returnRefund_ = org.bitcoin.paymentchannel.Protos.ReturnRefund.getDefaultInstance();
|
||||||
provideContract_ = org.bitcoin.paymentchannel.Protos.ProvideContract.getDefaultInstance();
|
provideContract_ = org.bitcoin.paymentchannel.Protos.ProvideContract.getDefaultInstance();
|
||||||
updatePayment_ = org.bitcoin.paymentchannel.Protos.UpdatePayment.getDefaultInstance();
|
updatePayment_ = org.bitcoin.paymentchannel.Protos.UpdatePayment.getDefaultInstance();
|
||||||
|
close_ = org.bitcoin.paymentchannel.Protos.Close.getDefaultInstance();
|
||||||
error_ = org.bitcoin.paymentchannel.Protos.Error.getDefaultInstance();
|
error_ = org.bitcoin.paymentchannel.Protos.Error.getDefaultInstance();
|
||||||
}
|
}
|
||||||
private byte memoizedIsInitialized = -1;
|
private byte memoizedIsInitialized = -1;
|
||||||
@ -847,6 +909,12 @@ public final class Protos {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (hasClose()) {
|
||||||
|
if (!getClose().isInitialized()) {
|
||||||
|
memoizedIsInitialized = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
memoizedIsInitialized = 1;
|
memoizedIsInitialized = 1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -879,6 +947,9 @@ public final class Protos {
|
|||||||
output.writeMessage(8, updatePayment_);
|
output.writeMessage(8, updatePayment_);
|
||||||
}
|
}
|
||||||
if (((bitField0_ & 0x00000100) == 0x00000100)) {
|
if (((bitField0_ & 0x00000100) == 0x00000100)) {
|
||||||
|
output.writeMessage(9, close_);
|
||||||
|
}
|
||||||
|
if (((bitField0_ & 0x00000200) == 0x00000200)) {
|
||||||
output.writeMessage(10, error_);
|
output.writeMessage(10, error_);
|
||||||
}
|
}
|
||||||
getUnknownFields().writeTo(output);
|
getUnknownFields().writeTo(output);
|
||||||
@ -923,6 +994,10 @@ public final class Protos {
|
|||||||
.computeMessageSize(8, updatePayment_);
|
.computeMessageSize(8, updatePayment_);
|
||||||
}
|
}
|
||||||
if (((bitField0_ & 0x00000100) == 0x00000100)) {
|
if (((bitField0_ & 0x00000100) == 0x00000100)) {
|
||||||
|
size += com.google.protobuf.CodedOutputStream
|
||||||
|
.computeMessageSize(9, close_);
|
||||||
|
}
|
||||||
|
if (((bitField0_ & 0x00000200) == 0x00000200)) {
|
||||||
size += com.google.protobuf.CodedOutputStream
|
size += com.google.protobuf.CodedOutputStream
|
||||||
.computeMessageSize(10, error_);
|
.computeMessageSize(10, error_);
|
||||||
}
|
}
|
||||||
@ -1047,6 +1122,7 @@ public final class Protos {
|
|||||||
getReturnRefundFieldBuilder();
|
getReturnRefundFieldBuilder();
|
||||||
getProvideContractFieldBuilder();
|
getProvideContractFieldBuilder();
|
||||||
getUpdatePaymentFieldBuilder();
|
getUpdatePaymentFieldBuilder();
|
||||||
|
getCloseFieldBuilder();
|
||||||
getErrorFieldBuilder();
|
getErrorFieldBuilder();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1100,12 +1176,18 @@ public final class Protos {
|
|||||||
updatePaymentBuilder_.clear();
|
updatePaymentBuilder_.clear();
|
||||||
}
|
}
|
||||||
bitField0_ = (bitField0_ & ~0x00000080);
|
bitField0_ = (bitField0_ & ~0x00000080);
|
||||||
|
if (closeBuilder_ == null) {
|
||||||
|
close_ = org.bitcoin.paymentchannel.Protos.Close.getDefaultInstance();
|
||||||
|
} else {
|
||||||
|
closeBuilder_.clear();
|
||||||
|
}
|
||||||
|
bitField0_ = (bitField0_ & ~0x00000100);
|
||||||
if (errorBuilder_ == null) {
|
if (errorBuilder_ == null) {
|
||||||
error_ = org.bitcoin.paymentchannel.Protos.Error.getDefaultInstance();
|
error_ = org.bitcoin.paymentchannel.Protos.Error.getDefaultInstance();
|
||||||
} else {
|
} else {
|
||||||
errorBuilder_.clear();
|
errorBuilder_.clear();
|
||||||
}
|
}
|
||||||
bitField0_ = (bitField0_ & ~0x00000100);
|
bitField0_ = (bitField0_ & ~0x00000200);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1197,6 +1279,14 @@ public final class Protos {
|
|||||||
if (((from_bitField0_ & 0x00000100) == 0x00000100)) {
|
if (((from_bitField0_ & 0x00000100) == 0x00000100)) {
|
||||||
to_bitField0_ |= 0x00000100;
|
to_bitField0_ |= 0x00000100;
|
||||||
}
|
}
|
||||||
|
if (closeBuilder_ == null) {
|
||||||
|
result.close_ = close_;
|
||||||
|
} else {
|
||||||
|
result.close_ = closeBuilder_.build();
|
||||||
|
}
|
||||||
|
if (((from_bitField0_ & 0x00000200) == 0x00000200)) {
|
||||||
|
to_bitField0_ |= 0x00000200;
|
||||||
|
}
|
||||||
if (errorBuilder_ == null) {
|
if (errorBuilder_ == null) {
|
||||||
result.error_ = error_;
|
result.error_ = error_;
|
||||||
} else {
|
} else {
|
||||||
@ -1242,6 +1332,9 @@ public final class Protos {
|
|||||||
if (other.hasUpdatePayment()) {
|
if (other.hasUpdatePayment()) {
|
||||||
mergeUpdatePayment(other.getUpdatePayment());
|
mergeUpdatePayment(other.getUpdatePayment());
|
||||||
}
|
}
|
||||||
|
if (other.hasClose()) {
|
||||||
|
mergeClose(other.getClose());
|
||||||
|
}
|
||||||
if (other.hasError()) {
|
if (other.hasError()) {
|
||||||
mergeError(other.getError());
|
mergeError(other.getError());
|
||||||
}
|
}
|
||||||
@ -1296,6 +1389,12 @@ public final class Protos {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (hasClose()) {
|
||||||
|
if (!getClose().isInitialized()) {
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2233,6 +2332,123 @@ public final class Protos {
|
|||||||
return updatePaymentBuilder_;
|
return updatePaymentBuilder_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// optional .paymentchannels.Close close = 9;
|
||||||
|
private org.bitcoin.paymentchannel.Protos.Close close_ = org.bitcoin.paymentchannel.Protos.Close.getDefaultInstance();
|
||||||
|
private com.google.protobuf.SingleFieldBuilder<
|
||||||
|
org.bitcoin.paymentchannel.Protos.Close, org.bitcoin.paymentchannel.Protos.Close.Builder, org.bitcoin.paymentchannel.Protos.CloseOrBuilder> closeBuilder_;
|
||||||
|
/**
|
||||||
|
* <code>optional .paymentchannels.Close close = 9;</code>
|
||||||
|
*/
|
||||||
|
public boolean hasClose() {
|
||||||
|
return ((bitField0_ & 0x00000100) == 0x00000100);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>optional .paymentchannels.Close close = 9;</code>
|
||||||
|
*/
|
||||||
|
public org.bitcoin.paymentchannel.Protos.Close getClose() {
|
||||||
|
if (closeBuilder_ == null) {
|
||||||
|
return close_;
|
||||||
|
} else {
|
||||||
|
return closeBuilder_.getMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>optional .paymentchannels.Close close = 9;</code>
|
||||||
|
*/
|
||||||
|
public Builder setClose(org.bitcoin.paymentchannel.Protos.Close value) {
|
||||||
|
if (closeBuilder_ == null) {
|
||||||
|
if (value == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
close_ = value;
|
||||||
|
onChanged();
|
||||||
|
} else {
|
||||||
|
closeBuilder_.setMessage(value);
|
||||||
|
}
|
||||||
|
bitField0_ |= 0x00000100;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>optional .paymentchannels.Close close = 9;</code>
|
||||||
|
*/
|
||||||
|
public Builder setClose(
|
||||||
|
org.bitcoin.paymentchannel.Protos.Close.Builder builderForValue) {
|
||||||
|
if (closeBuilder_ == null) {
|
||||||
|
close_ = builderForValue.build();
|
||||||
|
onChanged();
|
||||||
|
} else {
|
||||||
|
closeBuilder_.setMessage(builderForValue.build());
|
||||||
|
}
|
||||||
|
bitField0_ |= 0x00000100;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>optional .paymentchannels.Close close = 9;</code>
|
||||||
|
*/
|
||||||
|
public Builder mergeClose(org.bitcoin.paymentchannel.Protos.Close value) {
|
||||||
|
if (closeBuilder_ == null) {
|
||||||
|
if (((bitField0_ & 0x00000100) == 0x00000100) &&
|
||||||
|
close_ != org.bitcoin.paymentchannel.Protos.Close.getDefaultInstance()) {
|
||||||
|
close_ =
|
||||||
|
org.bitcoin.paymentchannel.Protos.Close.newBuilder(close_).mergeFrom(value).buildPartial();
|
||||||
|
} else {
|
||||||
|
close_ = value;
|
||||||
|
}
|
||||||
|
onChanged();
|
||||||
|
} else {
|
||||||
|
closeBuilder_.mergeFrom(value);
|
||||||
|
}
|
||||||
|
bitField0_ |= 0x00000100;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>optional .paymentchannels.Close close = 9;</code>
|
||||||
|
*/
|
||||||
|
public Builder clearClose() {
|
||||||
|
if (closeBuilder_ == null) {
|
||||||
|
close_ = org.bitcoin.paymentchannel.Protos.Close.getDefaultInstance();
|
||||||
|
onChanged();
|
||||||
|
} else {
|
||||||
|
closeBuilder_.clear();
|
||||||
|
}
|
||||||
|
bitField0_ = (bitField0_ & ~0x00000100);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>optional .paymentchannels.Close close = 9;</code>
|
||||||
|
*/
|
||||||
|
public org.bitcoin.paymentchannel.Protos.Close.Builder getCloseBuilder() {
|
||||||
|
bitField0_ |= 0x00000100;
|
||||||
|
onChanged();
|
||||||
|
return getCloseFieldBuilder().getBuilder();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>optional .paymentchannels.Close close = 9;</code>
|
||||||
|
*/
|
||||||
|
public org.bitcoin.paymentchannel.Protos.CloseOrBuilder getCloseOrBuilder() {
|
||||||
|
if (closeBuilder_ != null) {
|
||||||
|
return closeBuilder_.getMessageOrBuilder();
|
||||||
|
} else {
|
||||||
|
return close_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>optional .paymentchannels.Close close = 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_,
|
||||||
|
getParentForChildren(),
|
||||||
|
isClean());
|
||||||
|
close_ = null;
|
||||||
|
}
|
||||||
|
return closeBuilder_;
|
||||||
|
}
|
||||||
|
|
||||||
// optional .paymentchannels.Error error = 10;
|
// optional .paymentchannels.Error error = 10;
|
||||||
private org.bitcoin.paymentchannel.Protos.Error error_ = org.bitcoin.paymentchannel.Protos.Error.getDefaultInstance();
|
private org.bitcoin.paymentchannel.Protos.Error error_ = org.bitcoin.paymentchannel.Protos.Error.getDefaultInstance();
|
||||||
private com.google.protobuf.SingleFieldBuilder<
|
private com.google.protobuf.SingleFieldBuilder<
|
||||||
@ -2241,7 +2457,7 @@ public final class Protos {
|
|||||||
* <code>optional .paymentchannels.Error error = 10;</code>
|
* <code>optional .paymentchannels.Error error = 10;</code>
|
||||||
*/
|
*/
|
||||||
public boolean hasError() {
|
public boolean hasError() {
|
||||||
return ((bitField0_ & 0x00000100) == 0x00000100);
|
return ((bitField0_ & 0x00000200) == 0x00000200);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* <code>optional .paymentchannels.Error error = 10;</code>
|
* <code>optional .paymentchannels.Error error = 10;</code>
|
||||||
@ -2266,7 +2482,7 @@ public final class Protos {
|
|||||||
} else {
|
} else {
|
||||||
errorBuilder_.setMessage(value);
|
errorBuilder_.setMessage(value);
|
||||||
}
|
}
|
||||||
bitField0_ |= 0x00000100;
|
bitField0_ |= 0x00000200;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -2280,7 +2496,7 @@ public final class Protos {
|
|||||||
} else {
|
} else {
|
||||||
errorBuilder_.setMessage(builderForValue.build());
|
errorBuilder_.setMessage(builderForValue.build());
|
||||||
}
|
}
|
||||||
bitField0_ |= 0x00000100;
|
bitField0_ |= 0x00000200;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -2288,7 +2504,7 @@ public final class Protos {
|
|||||||
*/
|
*/
|
||||||
public Builder mergeError(org.bitcoin.paymentchannel.Protos.Error value) {
|
public Builder mergeError(org.bitcoin.paymentchannel.Protos.Error value) {
|
||||||
if (errorBuilder_ == null) {
|
if (errorBuilder_ == null) {
|
||||||
if (((bitField0_ & 0x00000100) == 0x00000100) &&
|
if (((bitField0_ & 0x00000200) == 0x00000200) &&
|
||||||
error_ != org.bitcoin.paymentchannel.Protos.Error.getDefaultInstance()) {
|
error_ != org.bitcoin.paymentchannel.Protos.Error.getDefaultInstance()) {
|
||||||
error_ =
|
error_ =
|
||||||
org.bitcoin.paymentchannel.Protos.Error.newBuilder(error_).mergeFrom(value).buildPartial();
|
org.bitcoin.paymentchannel.Protos.Error.newBuilder(error_).mergeFrom(value).buildPartial();
|
||||||
@ -2299,7 +2515,7 @@ public final class Protos {
|
|||||||
} else {
|
} else {
|
||||||
errorBuilder_.mergeFrom(value);
|
errorBuilder_.mergeFrom(value);
|
||||||
}
|
}
|
||||||
bitField0_ |= 0x00000100;
|
bitField0_ |= 0x00000200;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -2312,14 +2528,14 @@ public final class Protos {
|
|||||||
} else {
|
} else {
|
||||||
errorBuilder_.clear();
|
errorBuilder_.clear();
|
||||||
}
|
}
|
||||||
bitField0_ = (bitField0_ & ~0x00000100);
|
bitField0_ = (bitField0_ & ~0x00000200);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* <code>optional .paymentchannels.Error error = 10;</code>
|
* <code>optional .paymentchannels.Error error = 10;</code>
|
||||||
*/
|
*/
|
||||||
public org.bitcoin.paymentchannel.Protos.Error.Builder getErrorBuilder() {
|
public org.bitcoin.paymentchannel.Protos.Error.Builder getErrorBuilder() {
|
||||||
bitField0_ |= 0x00000100;
|
bitField0_ |= 0x00000200;
|
||||||
onChanged();
|
onChanged();
|
||||||
return getErrorFieldBuilder().getBuilder();
|
return getErrorFieldBuilder().getBuilder();
|
||||||
}
|
}
|
||||||
@ -6447,6 +6663,453 @@ public final class Protos {
|
|||||||
// @@protoc_insertion_point(class_scope:paymentchannels.UpdatePayment)
|
// @@protoc_insertion_point(class_scope:paymentchannels.UpdatePayment)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface CloseOrBuilder
|
||||||
|
extends com.google.protobuf.MessageOrBuilder {
|
||||||
|
|
||||||
|
// required bytes tx = 3;
|
||||||
|
/**
|
||||||
|
* <code>required bytes tx = 3;</code>
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* A copy of the fully signed final contract that closes the channel. The client can verify
|
||||||
|
* the transaction is correct and then commit it to their wallet.
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
boolean hasTx();
|
||||||
|
/**
|
||||||
|
* <code>required bytes tx = 3;</code>
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* A copy of the fully signed final contract that closes 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}
|
||||||
|
*/
|
||||||
|
public static final class Close extends
|
||||||
|
com.google.protobuf.GeneratedMessage
|
||||||
|
implements CloseOrBuilder {
|
||||||
|
// Use Close.newBuilder() to construct.
|
||||||
|
private Close(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
|
||||||
|
super(builder);
|
||||||
|
this.unknownFields = builder.getUnknownFields();
|
||||||
|
}
|
||||||
|
private Close(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
|
||||||
|
|
||||||
|
private static final Close defaultInstance;
|
||||||
|
public static Close getDefaultInstance() {
|
||||||
|
return defaultInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Close getDefaultInstanceForType() {
|
||||||
|
return defaultInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final com.google.protobuf.UnknownFieldSet unknownFields;
|
||||||
|
@java.lang.Override
|
||||||
|
public final com.google.protobuf.UnknownFieldSet
|
||||||
|
getUnknownFields() {
|
||||||
|
return this.unknownFields;
|
||||||
|
}
|
||||||
|
private Close(
|
||||||
|
com.google.protobuf.CodedInputStream input,
|
||||||
|
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||||
|
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||||
|
initFields();
|
||||||
|
int mutable_bitField0_ = 0;
|
||||||
|
com.google.protobuf.UnknownFieldSet.Builder unknownFields =
|
||||||
|
com.google.protobuf.UnknownFieldSet.newBuilder();
|
||||||
|
try {
|
||||||
|
boolean done = false;
|
||||||
|
while (!done) {
|
||||||
|
int tag = input.readTag();
|
||||||
|
switch (tag) {
|
||||||
|
case 0:
|
||||||
|
done = true;
|
||||||
|
break;
|
||||||
|
default: {
|
||||||
|
if (!parseUnknownField(input, unknownFields,
|
||||||
|
extensionRegistry, tag)) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 26: {
|
||||||
|
bitField0_ |= 0x00000001;
|
||||||
|
tx_ = input.readBytes();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
|
||||||
|
throw e.setUnfinishedMessage(this);
|
||||||
|
} catch (java.io.IOException e) {
|
||||||
|
throw new com.google.protobuf.InvalidProtocolBufferException(
|
||||||
|
e.getMessage()).setUnfinishedMessage(this);
|
||||||
|
} finally {
|
||||||
|
this.unknownFields = unknownFields.build();
|
||||||
|
makeExtensionsImmutable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static final com.google.protobuf.Descriptors.Descriptor
|
||||||
|
getDescriptor() {
|
||||||
|
return org.bitcoin.paymentchannel.Protos.internal_static_paymentchannels_Close_descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
|
||||||
|
internalGetFieldAccessorTable() {
|
||||||
|
return org.bitcoin.paymentchannel.Protos.internal_static_paymentchannels_Close_fieldAccessorTable
|
||||||
|
.ensureFieldAccessorsInitialized(
|
||||||
|
org.bitcoin.paymentchannel.Protos.Close.class, org.bitcoin.paymentchannel.Protos.Close.Builder.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.google.protobuf.Parser<Close> PARSER =
|
||||||
|
new com.google.protobuf.AbstractParser<Close>() {
|
||||||
|
public Close parsePartialFrom(
|
||||||
|
com.google.protobuf.CodedInputStream input,
|
||||||
|
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||||
|
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||||
|
return new Close(input, extensionRegistry);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
public com.google.protobuf.Parser<Close> getParserForType() {
|
||||||
|
return PARSER;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int bitField0_;
|
||||||
|
// required bytes tx = 3;
|
||||||
|
public static final int TX_FIELD_NUMBER = 3;
|
||||||
|
private com.google.protobuf.ByteString tx_;
|
||||||
|
/**
|
||||||
|
* <code>required bytes tx = 3;</code>
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* A copy of the fully signed final contract that closes the channel. The client can verify
|
||||||
|
* the transaction is correct and then commit it to their wallet.
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
public boolean hasTx() {
|
||||||
|
return ((bitField0_ & 0x00000001) == 0x00000001);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>required bytes tx = 3;</code>
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* A copy of the fully signed final contract that closes the channel. The client can verify
|
||||||
|
* the transaction is correct and then commit it to their wallet.
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
public com.google.protobuf.ByteString getTx() {
|
||||||
|
return tx_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initFields() {
|
||||||
|
tx_ = com.google.protobuf.ByteString.EMPTY;
|
||||||
|
}
|
||||||
|
private byte memoizedIsInitialized = -1;
|
||||||
|
public final boolean isInitialized() {
|
||||||
|
byte isInitialized = memoizedIsInitialized;
|
||||||
|
if (isInitialized != -1) return isInitialized == 1;
|
||||||
|
|
||||||
|
if (!hasTx()) {
|
||||||
|
memoizedIsInitialized = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
memoizedIsInitialized = 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeTo(com.google.protobuf.CodedOutputStream output)
|
||||||
|
throws java.io.IOException {
|
||||||
|
getSerializedSize();
|
||||||
|
if (((bitField0_ & 0x00000001) == 0x00000001)) {
|
||||||
|
output.writeBytes(3, tx_);
|
||||||
|
}
|
||||||
|
getUnknownFields().writeTo(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int memoizedSerializedSize = -1;
|
||||||
|
public int getSerializedSize() {
|
||||||
|
int size = memoizedSerializedSize;
|
||||||
|
if (size != -1) return size;
|
||||||
|
|
||||||
|
size = 0;
|
||||||
|
if (((bitField0_ & 0x00000001) == 0x00000001)) {
|
||||||
|
size += com.google.protobuf.CodedOutputStream
|
||||||
|
.computeBytesSize(3, tx_);
|
||||||
|
}
|
||||||
|
size += getUnknownFields().getSerializedSize();
|
||||||
|
memoizedSerializedSize = size;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 0L;
|
||||||
|
@java.lang.Override
|
||||||
|
protected java.lang.Object writeReplace()
|
||||||
|
throws java.io.ObjectStreamException {
|
||||||
|
return super.writeReplace();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static org.bitcoin.paymentchannel.Protos.Close parseFrom(
|
||||||
|
com.google.protobuf.ByteString data)
|
||||||
|
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||||
|
return PARSER.parseFrom(data);
|
||||||
|
}
|
||||||
|
public static org.bitcoin.paymentchannel.Protos.Close 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)
|
||||||
|
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||||
|
return PARSER.parseFrom(data);
|
||||||
|
}
|
||||||
|
public static org.bitcoin.paymentchannel.Protos.Close 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)
|
||||||
|
throws java.io.IOException {
|
||||||
|
return PARSER.parseFrom(input);
|
||||||
|
}
|
||||||
|
public static org.bitcoin.paymentchannel.Protos.Close 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)
|
||||||
|
throws java.io.IOException {
|
||||||
|
return PARSER.parseDelimitedFrom(input);
|
||||||
|
}
|
||||||
|
public static org.bitcoin.paymentchannel.Protos.Close 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(
|
||||||
|
com.google.protobuf.CodedInputStream input)
|
||||||
|
throws java.io.IOException {
|
||||||
|
return PARSER.parseFrom(input);
|
||||||
|
}
|
||||||
|
public static org.bitcoin.paymentchannel.Protos.Close parseFrom(
|
||||||
|
com.google.protobuf.CodedInputStream input,
|
||||||
|
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||||
|
throws java.io.IOException {
|
||||||
|
return PARSER.parseFrom(input, extensionRegistry);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Builder newBuilder() { return Builder.create(); }
|
||||||
|
public Builder newBuilderForType() { return newBuilder(); }
|
||||||
|
public static Builder newBuilder(org.bitcoin.paymentchannel.Protos.Close prototype) {
|
||||||
|
return newBuilder().mergeFrom(prototype);
|
||||||
|
}
|
||||||
|
public Builder toBuilder() { return newBuilder(this); }
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
protected Builder newBuilderForType(
|
||||||
|
com.google.protobuf.GeneratedMessage.BuilderParent parent) {
|
||||||
|
Builder builder = new Builder(parent);
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Protobuf type {@code paymentchannels.Close}
|
||||||
|
*/
|
||||||
|
public static final class Builder extends
|
||||||
|
com.google.protobuf.GeneratedMessage.Builder<Builder>
|
||||||
|
implements org.bitcoin.paymentchannel.Protos.CloseOrBuilder {
|
||||||
|
public static final com.google.protobuf.Descriptors.Descriptor
|
||||||
|
getDescriptor() {
|
||||||
|
return org.bitcoin.paymentchannel.Protos.internal_static_paymentchannels_Close_descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
|
||||||
|
internalGetFieldAccessorTable() {
|
||||||
|
return org.bitcoin.paymentchannel.Protos.internal_static_paymentchannels_Close_fieldAccessorTable
|
||||||
|
.ensureFieldAccessorsInitialized(
|
||||||
|
org.bitcoin.paymentchannel.Protos.Close.class, org.bitcoin.paymentchannel.Protos.Close.Builder.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct using org.bitcoin.paymentchannel.Protos.Close.newBuilder()
|
||||||
|
private Builder() {
|
||||||
|
maybeForceBuilderInitialization();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Builder(
|
||||||
|
com.google.protobuf.GeneratedMessage.BuilderParent parent) {
|
||||||
|
super(parent);
|
||||||
|
maybeForceBuilderInitialization();
|
||||||
|
}
|
||||||
|
private void maybeForceBuilderInitialization() {
|
||||||
|
if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static Builder create() {
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder clear() {
|
||||||
|
super.clear();
|
||||||
|
tx_ = com.google.protobuf.ByteString.EMPTY;
|
||||||
|
bitField0_ = (bitField0_ & ~0x00000001);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder clone() {
|
||||||
|
return create().mergeFrom(buildPartial());
|
||||||
|
}
|
||||||
|
|
||||||
|
public com.google.protobuf.Descriptors.Descriptor
|
||||||
|
getDescriptorForType() {
|
||||||
|
return org.bitcoin.paymentchannel.Protos.internal_static_paymentchannels_Close_descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public org.bitcoin.paymentchannel.Protos.Close getDefaultInstanceForType() {
|
||||||
|
return org.bitcoin.paymentchannel.Protos.Close.getDefaultInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
public org.bitcoin.paymentchannel.Protos.Close build() {
|
||||||
|
org.bitcoin.paymentchannel.Protos.Close 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);
|
||||||
|
int from_bitField0_ = bitField0_;
|
||||||
|
int to_bitField0_ = 0;
|
||||||
|
if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
|
||||||
|
to_bitField0_ |= 0x00000001;
|
||||||
|
}
|
||||||
|
result.tx_ = tx_;
|
||||||
|
result.bitField0_ = to_bitField0_;
|
||||||
|
onBuilt();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder mergeFrom(com.google.protobuf.Message other) {
|
||||||
|
if (other instanceof org.bitcoin.paymentchannel.Protos.Close) {
|
||||||
|
return mergeFrom((org.bitcoin.paymentchannel.Protos.Close)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;
|
||||||
|
if (other.hasTx()) {
|
||||||
|
setTx(other.getTx());
|
||||||
|
}
|
||||||
|
this.mergeUnknownFields(other.getUnknownFields());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final boolean isInitialized() {
|
||||||
|
if (!hasTx()) {
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder mergeFrom(
|
||||||
|
com.google.protobuf.CodedInputStream input,
|
||||||
|
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||||
|
throws java.io.IOException {
|
||||||
|
org.bitcoin.paymentchannel.Protos.Close parsedMessage = null;
|
||||||
|
try {
|
||||||
|
parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
|
||||||
|
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
|
||||||
|
parsedMessage = (org.bitcoin.paymentchannel.Protos.Close) e.getUnfinishedMessage();
|
||||||
|
throw e;
|
||||||
|
} finally {
|
||||||
|
if (parsedMessage != null) {
|
||||||
|
mergeFrom(parsedMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
private int bitField0_;
|
||||||
|
|
||||||
|
// required bytes tx = 3;
|
||||||
|
private com.google.protobuf.ByteString tx_ = com.google.protobuf.ByteString.EMPTY;
|
||||||
|
/**
|
||||||
|
* <code>required bytes tx = 3;</code>
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* A copy of the fully signed final contract that closes the channel. The client can verify
|
||||||
|
* the transaction is correct and then commit it to their wallet.
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
public boolean hasTx() {
|
||||||
|
return ((bitField0_ & 0x00000001) == 0x00000001);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>required bytes tx = 3;</code>
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* A copy of the fully signed final contract that closes the channel. The client can verify
|
||||||
|
* the transaction is correct and then commit it to their wallet.
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
public com.google.protobuf.ByteString getTx() {
|
||||||
|
return tx_;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>required bytes tx = 3;</code>
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* A copy of the fully signed final contract that closes the channel. The client can verify
|
||||||
|
* the transaction is correct and then commit it to their wallet.
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
public Builder setTx(com.google.protobuf.ByteString value) {
|
||||||
|
if (value == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
bitField0_ |= 0x00000001;
|
||||||
|
tx_ = value;
|
||||||
|
onChanged();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>required bytes tx = 3;</code>
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* A copy of the fully signed final contract that closes the channel. The client can verify
|
||||||
|
* the transaction is correct and then commit it to their wallet.
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
public Builder clearTx() {
|
||||||
|
bitField0_ = (bitField0_ & ~0x00000001);
|
||||||
|
tx_ = getDefaultInstance().getTx();
|
||||||
|
onChanged();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @@protoc_insertion_point(builder_scope:paymentchannels.Close)
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
defaultInstance = new Close(true);
|
||||||
|
defaultInstance.initFields();
|
||||||
|
}
|
||||||
|
|
||||||
|
// @@protoc_insertion_point(class_scope:paymentchannels.Close)
|
||||||
|
}
|
||||||
|
|
||||||
public interface ErrorOrBuilder
|
public interface ErrorOrBuilder
|
||||||
extends com.google.protobuf.MessageOrBuilder {
|
extends com.google.protobuf.MessageOrBuilder {
|
||||||
|
|
||||||
@ -7285,6 +7948,11 @@ public final class Protos {
|
|||||||
private static
|
private static
|
||||||
com.google.protobuf.GeneratedMessage.FieldAccessorTable
|
com.google.protobuf.GeneratedMessage.FieldAccessorTable
|
||||||
internal_static_paymentchannels_UpdatePayment_fieldAccessorTable;
|
internal_static_paymentchannels_UpdatePayment_fieldAccessorTable;
|
||||||
|
private static com.google.protobuf.Descriptors.Descriptor
|
||||||
|
internal_static_paymentchannels_Close_descriptor;
|
||||||
|
private static
|
||||||
|
com.google.protobuf.GeneratedMessage.FieldAccessorTable
|
||||||
|
internal_static_paymentchannels_Close_fieldAccessorTable;
|
||||||
private static com.google.protobuf.Descriptors.Descriptor
|
private static com.google.protobuf.Descriptors.Descriptor
|
||||||
internal_static_paymentchannels_Error_descriptor;
|
internal_static_paymentchannels_Error_descriptor;
|
||||||
private static
|
private static
|
||||||
@ -7300,7 +7968,7 @@ public final class Protos {
|
|||||||
static {
|
static {
|
||||||
java.lang.String[] descriptorData = {
|
java.lang.String[] descriptorData = {
|
||||||
"\n\024paymentchannel.proto\022\017paymentchannels\"" +
|
"\n\024paymentchannel.proto\022\017paymentchannels\"" +
|
||||||
"\274\005\n\024TwoWayChannelMessage\022?\n\004type\030\001 \002(\01621" +
|
"\343\005\n\024TwoWayChannelMessage\022?\n\004type\030\001 \002(\01621" +
|
||||||
".paymentchannels.TwoWayChannelMessage.Me" +
|
".paymentchannels.TwoWayChannelMessage.Me" +
|
||||||
"ssageType\0226\n\016client_version\030\002 \001(\0132\036.paym" +
|
"ssageType\0226\n\016client_version\030\002 \001(\0132\036.paym" +
|
||||||
"entchannels.ClientVersion\0226\n\016server_vers" +
|
"entchannels.ClientVersion\0226\n\016server_vers" +
|
||||||
@ -7311,31 +7979,32 @@ public final class Protos {
|
|||||||
"\006 \001(\0132\035.paymentchannels.ReturnRefund\022:\n\020",
|
"\006 \001(\0132\035.paymentchannels.ReturnRefund\022:\n\020",
|
||||||
"provide_contract\030\007 \001(\0132 .paymentchannels" +
|
"provide_contract\030\007 \001(\0132 .paymentchannels" +
|
||||||
".ProvideContract\0226\n\016update_payment\030\010 \001(\013" +
|
".ProvideContract\0226\n\016update_payment\030\010 \001(\013" +
|
||||||
"2\036.paymentchannels.UpdatePayment\022%\n\005erro" +
|
"2\036.paymentchannels.UpdatePayment\022%\n\005clos" +
|
||||||
"r\030\n \001(\0132\026.paymentchannels.Error\"\274\001\n\013Mess" +
|
"e\030\t \001(\0132\026.paymentchannels.Close\022%\n\005error" +
|
||||||
"ageType\022\022\n\016CLIENT_VERSION\020\001\022\022\n\016SERVER_VE" +
|
"\030\n \001(\0132\026.paymentchannels.Error\"\274\001\n\013Messa" +
|
||||||
"RSION\020\002\022\014\n\010INITIATE\020\003\022\022\n\016PROVIDE_REFUND\020" +
|
"geType\022\022\n\016CLIENT_VERSION\020\001\022\022\n\016SERVER_VER" +
|
||||||
"\004\022\021\n\rRETURN_REFUND\020\005\022\024\n\020PROVIDE_CONTRACT" +
|
"SION\020\002\022\014\n\010INITIATE\020\003\022\022\n\016PROVIDE_REFUND\020\004" +
|
||||||
"\020\006\022\020\n\014CHANNEL_OPEN\020\007\022\022\n\016UPDATE_PAYMENT\020\010" +
|
"\022\021\n\rRETURN_REFUND\020\005\022\024\n\020PROVIDE_CONTRACT\020" +
|
||||||
"\022\t\n\005CLOSE\020\t\022\t\n\005ERROR\020\n\"X\n\rClientVersion\022" +
|
"\006\022\020\n\014CHANNEL_OPEN\020\007\022\022\n\016UPDATE_PAYMENT\020\010\022" +
|
||||||
"\r\n\005major\030\001 \002(\005\022\020\n\005minor\030\002 \001(\005:\0010\022&\n\036prev",
|
"\t\n\005CLOSE\020\t\022\t\n\005ERROR\020\n\"X\n\rClientVersion\022\r",
|
||||||
"ious_channel_contract_hash\030\003 \001(\014\"0\n\rServ" +
|
"\n\005major\030\001 \002(\005\022\020\n\005minor\030\002 \001(\005:\0010\022&\n\036previ" +
|
||||||
"erVersion\022\r\n\005major\030\001 \002(\005\022\020\n\005minor\030\002 \001(\005:" +
|
"ous_channel_contract_hash\030\003 \001(\014\"0\n\rServe" +
|
||||||
"\0010\"]\n\010Initiate\022\024\n\014multisig_key\030\001 \002(\014\022!\n\031" +
|
"rVersion\022\r\n\005major\030\001 \002(\005\022\020\n\005minor\030\002 \001(\005:\001" +
|
||||||
"min_accepted_channel_size\030\002 \002(\004\022\030\n\020expir" +
|
"0\"]\n\010Initiate\022\024\n\014multisig_key\030\001 \002(\014\022!\n\031m" +
|
||||||
"e_time_secs\030\003 \002(\004\"1\n\rProvideRefund\022\024\n\014mu" +
|
"in_accepted_channel_size\030\002 \002(\004\022\030\n\020expire" +
|
||||||
"ltisig_key\030\001 \002(\014\022\n\n\002tx\030\002 \002(\014\"!\n\014ReturnRe" +
|
"_time_secs\030\003 \002(\004\"1\n\rProvideRefund\022\024\n\014mul" +
|
||||||
"fund\022\021\n\tsignature\030\001 \002(\014\"\035\n\017ProvideContra" +
|
"tisig_key\030\001 \002(\014\022\n\n\002tx\030\002 \002(\014\"!\n\014ReturnRef" +
|
||||||
"ct\022\n\n\002tx\030\001 \002(\014\"?\n\rUpdatePayment\022\033\n\023clien" +
|
"und\022\021\n\tsignature\030\001 \002(\014\"\035\n\017ProvideContrac" +
|
||||||
"t_change_value\030\001 \002(\004\022\021\n\tsignature\030\002 \002(\014\"" +
|
"t\022\n\n\002tx\030\001 \002(\014\"?\n\rUpdatePayment\022\033\n\023client" +
|
||||||
"\363\001\n\005Error\0225\n\004code\030\001 \001(\0162 .paymentchannel",
|
"_change_value\030\001 \002(\004\022\021\n\tsignature\030\002 \002(\014\"\023",
|
||||||
"s.Error.ErrorCode:\005OTHER\022\023\n\013explanation\030" +
|
"\n\005Close\022\n\n\002tx\030\003 \002(\014\"\363\001\n\005Error\0225\n\004code\030\001 " +
|
||||||
"\002 \001(\t\"\235\001\n\tErrorCode\022\013\n\007TIMEOUT\020\001\022\020\n\014SYNT" +
|
"\001(\0162 .paymentchannels.Error.ErrorCode:\005O" +
|
||||||
"AX_ERROR\020\002\022\031\n\025NO_ACCEPTABLE_VERSION\020\003\022\023\n" +
|
"THER\022\023\n\013explanation\030\002 \001(\t\"\235\001\n\tErrorCode\022" +
|
||||||
"\017BAD_TRANSACTION\020\004\022\031\n\025TIME_WINDOW_TOO_LA" +
|
"\013\n\007TIMEOUT\020\001\022\020\n\014SYNTAX_ERROR\020\002\022\031\n\025NO_ACC" +
|
||||||
"RGE\020\005\022\033\n\027CHANNEL_VALUE_TOO_LARGE\020\006\022\t\n\005OT" +
|
"EPTABLE_VERSION\020\003\022\023\n\017BAD_TRANSACTION\020\004\022\031" +
|
||||||
"HER\020\007B$\n\032org.bitcoin.paymentchannelB\006Pro" +
|
"\n\025TIME_WINDOW_TOO_LARGE\020\005\022\033\n\027CHANNEL_VAL" +
|
||||||
"tos"
|
"UE_TOO_LARGE\020\006\022\t\n\005OTHER\020\007B$\n\032org.bitcoin" +
|
||||||
|
".paymentchannelB\006Protos"
|
||||||
};
|
};
|
||||||
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
|
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
|
||||||
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
|
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
|
||||||
@ -7347,7 +8016,7 @@ public final class Protos {
|
|||||||
internal_static_paymentchannels_TwoWayChannelMessage_fieldAccessorTable = new
|
internal_static_paymentchannels_TwoWayChannelMessage_fieldAccessorTable = new
|
||||||
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
|
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
|
||||||
internal_static_paymentchannels_TwoWayChannelMessage_descriptor,
|
internal_static_paymentchannels_TwoWayChannelMessage_descriptor,
|
||||||
new java.lang.String[] { "Type", "ClientVersion", "ServerVersion", "Initiate", "ProvideRefund", "ReturnRefund", "ProvideContract", "UpdatePayment", "Error", });
|
new java.lang.String[] { "Type", "ClientVersion", "ServerVersion", "Initiate", "ProvideRefund", "ReturnRefund", "ProvideContract", "UpdatePayment", "Close", "Error", });
|
||||||
internal_static_paymentchannels_ClientVersion_descriptor =
|
internal_static_paymentchannels_ClientVersion_descriptor =
|
||||||
getDescriptor().getMessageTypes().get(1);
|
getDescriptor().getMessageTypes().get(1);
|
||||||
internal_static_paymentchannels_ClientVersion_fieldAccessorTable = new
|
internal_static_paymentchannels_ClientVersion_fieldAccessorTable = new
|
||||||
@ -7390,8 +8059,14 @@ public final class Protos {
|
|||||||
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
|
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
|
||||||
internal_static_paymentchannels_UpdatePayment_descriptor,
|
internal_static_paymentchannels_UpdatePayment_descriptor,
|
||||||
new java.lang.String[] { "ClientChangeValue", "Signature", });
|
new java.lang.String[] { "ClientChangeValue", "Signature", });
|
||||||
internal_static_paymentchannels_Error_descriptor =
|
internal_static_paymentchannels_Close_descriptor =
|
||||||
getDescriptor().getMessageTypes().get(8);
|
getDescriptor().getMessageTypes().get(8);
|
||||||
|
internal_static_paymentchannels_Close_fieldAccessorTable = new
|
||||||
|
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
|
||||||
|
internal_static_paymentchannels_Close_descriptor,
|
||||||
|
new java.lang.String[] { "Tx", });
|
||||||
|
internal_static_paymentchannels_Error_descriptor =
|
||||||
|
getDescriptor().getMessageTypes().get(9);
|
||||||
internal_static_paymentchannels_Error_fieldAccessorTable = new
|
internal_static_paymentchannels_Error_fieldAccessorTable = new
|
||||||
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
|
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
|
||||||
internal_static_paymentchannels_Error_descriptor,
|
internal_static_paymentchannels_Error_descriptor,
|
||||||
|
@ -47,15 +47,21 @@ message TwoWayChannelMessage {
|
|||||||
// message.
|
// message.
|
||||||
CHANNEL_OPEN = 7;
|
CHANNEL_OPEN = 7;
|
||||||
UPDATE_PAYMENT = 8;
|
UPDATE_PAYMENT = 8;
|
||||||
// Note that there are no optional fields set for CLOSE, it is sent by either party to
|
// Either side can send this message. If the client sends it to the server, then the server
|
||||||
// indicate that the channel is now closed and no further updates can happen. After this,
|
// takes the most recent signature it received in an UPDATE_PAYMENT and uses it to create a
|
||||||
// the secondary takes the most recent signature it received in an UPDATE_PAYMENT and
|
// valid transaction, which it then broadcasts on the network.
|
||||||
// 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.
|
||||||
CLOSE = 9;
|
CLOSE = 9;
|
||||||
|
|
||||||
// Used to indicate an error condition.
|
// Used to indicate an error condition.
|
||||||
// Both parties should make an effort to send either an ERROR or a CLOSE immediately
|
// Both parties should make an effort to send either an ERROR or a CLOSE immediately
|
||||||
// before closing the socket (unless they just received an ERROR or a CLOSE)
|
// before closing the socket (unless they just received an ERROR or a CLOSE). This is important
|
||||||
|
// because the protocol may not run over TCP.
|
||||||
ERROR = 10;
|
ERROR = 10;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -72,6 +78,7 @@ message TwoWayChannelMessage {
|
|||||||
optional ReturnRefund return_refund = 6;
|
optional ReturnRefund return_refund = 6;
|
||||||
optional ProvideContract provide_contract = 7;
|
optional ProvideContract provide_contract = 7;
|
||||||
optional UpdatePayment update_payment = 8;
|
optional UpdatePayment update_payment = 8;
|
||||||
|
optional Close close = 9;
|
||||||
|
|
||||||
optional Error error = 10;
|
optional Error error = 10;
|
||||||
}
|
}
|
||||||
@ -185,6 +192,11 @@ message UpdatePayment {
|
|||||||
required bytes signature = 2;
|
required bytes signature = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message Close {
|
||||||
|
// A copy of the fully signed final contract that closes the channel. The client can verify
|
||||||
|
// the transaction is correct and then commit it to their wallet.
|
||||||
|
required bytes tx = 3;
|
||||||
|
}
|
||||||
|
|
||||||
// An Error can be sent by either party at any time
|
// An Error can be sent by either party at any time
|
||||||
// Both parties should make an effort to send either an ERROR or a CLOSE immediately before
|
// Both parties should make an effort to send either an ERROR or a CLOSE immediately before
|
||||||
|
@ -644,13 +644,23 @@ public class ChannelConnectionTest extends TestWithWallet {
|
|||||||
client.incrementPayment(Utils.CENT);
|
client.incrementPayment(Utils.CENT);
|
||||||
client.incrementPayment(Utils.CENT);
|
client.incrementPayment(Utils.CENT);
|
||||||
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.UPDATE_PAYMENT));
|
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.UPDATE_PAYMENT));
|
||||||
|
pair.serverRecorder.q.take();
|
||||||
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.UPDATE_PAYMENT));
|
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.UPDATE_PAYMENT));
|
||||||
|
pair.serverRecorder.q.take();
|
||||||
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.UPDATE_PAYMENT));
|
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.UPDATE_PAYMENT));
|
||||||
|
pair.serverRecorder.q.take();
|
||||||
|
|
||||||
// Close it and verify it's considered to be closed.
|
// Close it and verify it's considered to be closed.
|
||||||
broadcastTxPause.release();
|
broadcastTxPause.release();
|
||||||
client.close();
|
client.close();
|
||||||
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.CLOSE));
|
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.CLOSE));
|
||||||
Transaction close = broadcasts.take();
|
Transaction close = broadcasts.take();
|
||||||
|
// Server sends back the close 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);
|
||||||
|
client.receiveMessage(closeMsg);
|
||||||
|
assertNotNull(wallet.getTransaction(closeTx.getHash())); // Close TX entered the wallet.
|
||||||
sendMoneyToWallet(close, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
sendMoneyToWallet(close, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||||
client.connectionClosed();
|
client.connectionClosed();
|
||||||
server.connectionClosed();
|
server.connectionClosed();
|
||||||
|
@ -20,7 +20,6 @@ import com.google.bitcoin.core.*;
|
|||||||
import com.google.bitcoin.script.Script;
|
import com.google.bitcoin.script.Script;
|
||||||
import com.google.bitcoin.script.ScriptBuilder;
|
import com.google.bitcoin.script.ScriptBuilder;
|
||||||
import com.google.bitcoin.utils.TestWithWallet;
|
import com.google.bitcoin.utils.TestWithWallet;
|
||||||
import com.google.bitcoin.wallet.DefaultCoinSelector;
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import com.google.common.util.concurrent.SettableFuture;
|
import com.google.common.util.concurrent.SettableFuture;
|
||||||
@ -189,29 +188,19 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
final TxFuturePair pair2 = broadcasts.take();
|
final TxFuturePair pair2 = broadcasts.take();
|
||||||
Transaction closeTx = pair2.tx;
|
Transaction closeTx = pair2.tx;
|
||||||
pair2.future.set(closeTx);
|
pair2.future.set(closeTx);
|
||||||
|
final Transaction reserializedCloseTx = new Transaction(params, closeTx.bitcoinSerialize());
|
||||||
assertEquals(PaymentChannelServerState.State.CLOSED, serverState.getState());
|
assertEquals(PaymentChannelServerState.State.CLOSED, serverState.getState());
|
||||||
|
// ... and on the client side.
|
||||||
|
wallet.receivePending(reserializedCloseTx, null);
|
||||||
|
assertEquals(PaymentChannelClientState.State.CLOSED, clientState.getState());
|
||||||
|
|
||||||
// Create a block with the payment transaction in it and give it to both wallets
|
// Create a block with the payment transaction in it and give it to both wallets
|
||||||
chain.add(makeSolvedTestBlock(blockStore.getChainHead().getHeader(), new Transaction(params, closeTx.bitcoinSerialize())));
|
chain.add(makeSolvedTestBlock(blockStore.getChainHead().getHeader(), reserializedCloseTx));
|
||||||
|
|
||||||
assertEquals(size.multiply(BigInteger.valueOf(5)), serverWallet.getBalance(new DefaultCoinSelector() {
|
assertEquals(size.multiply(BigInteger.valueOf(5)), serverWallet.getBalance());
|
||||||
@Override
|
|
||||||
protected boolean shouldSelect(Transaction tx) {
|
|
||||||
if (tx.getConfidence().getConfidenceType() == TransactionConfidence.ConfidenceType.BUILDING)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
assertEquals(0, serverWallet.getPendingTransactions().size());
|
assertEquals(0, serverWallet.getPendingTransactions().size());
|
||||||
|
|
||||||
assertEquals(Utils.COIN.subtract(size.multiply(BigInteger.valueOf(5))), wallet.getBalance(new DefaultCoinSelector() {
|
assertEquals(Utils.COIN.subtract(size.multiply(BigInteger.valueOf(5))), wallet.getBalance());
|
||||||
@Override
|
|
||||||
protected boolean shouldSelect(Transaction tx) {
|
|
||||||
if (tx.getConfidence().getConfidenceType() == TransactionConfidence.ConfidenceType.BUILDING)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
assertEquals(0, wallet.getPendingTransactions().size());
|
assertEquals(0, wallet.getPendingTransactions().size());
|
||||||
assertEquals(3, wallet.getTransactions(false).size());
|
assertEquals(3, wallet.getTransactions(false).size());
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user