mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-02-12 02:05:53 +00:00
Support for bundling an optional info Protobuf ByteString with an UpdatePayment message.
This commit is contained in:
parent
9e56093353
commit
1153192be8
@ -3,6 +3,7 @@ package com.google.bitcoin.jni;
|
||||
import com.google.bitcoin.core.*;
|
||||
import com.google.bitcoin.protocols.channels.PaymentChannelCloseException;
|
||||
import com.google.bitcoin.protocols.channels.ServerConnectionEventHandler;
|
||||
import com.google.protobuf.ByteString;
|
||||
|
||||
/**
|
||||
* An event listener that relays events to a native C++ object. A pointer to that object is stored in
|
||||
@ -16,7 +17,7 @@ public class NativePaymentChannelServerConnectionEventHandler extends ServerConn
|
||||
public native void channelOpen(Sha256Hash channelId);
|
||||
|
||||
@Override
|
||||
public native void paymentIncrease(Coin by, Coin to);
|
||||
public native void paymentIncrease(Coin by, Coin to, ByteString info);
|
||||
|
||||
@Override
|
||||
public native void channelClosed(PaymentChannelCloseException.CloseReason reason);
|
||||
|
@ -20,8 +20,11 @@ import com.google.bitcoin.core.Coin;
|
||||
import com.google.bitcoin.core.InsufficientMoneyException;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
import com.google.protobuf.ByteString;
|
||||
import org.bitcoin.paymentchannel.Protos;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* A class implementing this interface supports the basic operations of a payment channel. An implementation is provided
|
||||
* in {@link PaymentChannelClient}, but alternative implementations are possible. For example, an implementor might
|
||||
@ -74,13 +77,14 @@ public interface IPaymentChannelClient {
|
||||
* you wait for the previous increase payment future to complete before incrementing the payment again.
|
||||
*
|
||||
* @param size How many satoshis to increment the payment by (note: not the new total).
|
||||
* @param info Information about this update, used to extend this protocol.
|
||||
* @throws ValueOutOfRangeException If the size is negative or would pay more than this channel's total value
|
||||
* ({@link PaymentChannelClientConnection#state()}.getTotalValue())
|
||||
* @throws IllegalStateException If the channel has been closed or is not yet open
|
||||
* (see {@link PaymentChannelClientConnection#getChannelOpenFuture()} for the second)
|
||||
* @return a future that completes when the server acknowledges receipt and acceptance of the payment.
|
||||
*/
|
||||
ListenableFuture<Coin> incrementPayment(Coin size) throws ValueOutOfRangeException, IllegalStateException;
|
||||
ListenableFuture<Coin> incrementPayment(Coin size, @Nullable ByteString info) throws ValueOutOfRangeException, IllegalStateException;
|
||||
|
||||
/**
|
||||
* Implements the connection between this client and the server, providing an interface which allows messages to be
|
||||
|
@ -468,8 +468,27 @@ public class PaymentChannelClient implements IPaymentChannelClient {
|
||||
* (see {@link PaymentChannelClientConnection#getChannelOpenFuture()} for the second)
|
||||
* @return a future that completes when the server acknowledges receipt and acceptance of the payment.
|
||||
*/
|
||||
@Override
|
||||
public ListenableFuture<Coin> incrementPayment(Coin size) throws ValueOutOfRangeException, IllegalStateException {
|
||||
return incrementPayment(size, ByteString.EMPTY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments the total value which we pay the server. Note that the amount of money sent may not be the same as the
|
||||
* amount of money actually requested. It can be larger if the amount left over in the channel would be too small to
|
||||
* be accepted by the Bitcoin network. ValueOutOfRangeException will be thrown, however, if there's not enough money
|
||||
* left in the channel to make the payment at all. Only one payment can be in-flight at once. You have to ensure
|
||||
* you wait for the previous increase payment future to complete before incrementing the payment again.
|
||||
*
|
||||
* @param size How many satoshis to increment the payment by (note: not the new total).
|
||||
* @param info Information about this update, used to extend this protocol.
|
||||
* @throws ValueOutOfRangeException If the size is negative or would pay more than this channel's total value
|
||||
* ({@link PaymentChannelClientConnection#state()}.getTotalValue())
|
||||
* @throws IllegalStateException If the channel has been closed or is not yet open
|
||||
* (see {@link PaymentChannelClientConnection#getChannelOpenFuture()} for the second)
|
||||
* @return a future that completes when the server acknowledges receipt and acceptance of the payment.
|
||||
*/
|
||||
@Override
|
||||
public ListenableFuture<Coin> incrementPayment(Coin size, @Nullable ByteString info) throws ValueOutOfRangeException, IllegalStateException {
|
||||
lock.lock();
|
||||
try {
|
||||
if (state() == null || !connectionOpen || step != InitStep.CHANNEL_OPEN)
|
||||
@ -481,6 +500,7 @@ public class PaymentChannelClient implements IPaymentChannelClient {
|
||||
Protos.UpdatePayment.Builder updatePaymentBuilder = Protos.UpdatePayment.newBuilder()
|
||||
.setSignature(ByteString.copyFrom(payment.signature.encodeToBitcoin()))
|
||||
.setClientChangeValue(state.getValueRefunded().value);
|
||||
if (info != null) updatePaymentBuilder.setInfo(info);
|
||||
|
||||
increasePaymentFuture = SettableFuture.create();
|
||||
increasePaymentFuture.addListener(new Runnable() {
|
||||
|
@ -26,6 +26,7 @@ import com.google.bitcoin.net.ProtobufParser;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.common.util.concurrent.SettableFuture;
|
||||
|
||||
import com.google.protobuf.ByteString;
|
||||
import org.bitcoin.paymentchannel.Protos;
|
||||
|
||||
import java.io.IOException;
|
||||
@ -120,7 +121,7 @@ public class PaymentChannelClientConnection {
|
||||
* an error before the channel has reached the open state.</p>
|
||||
*
|
||||
* <p>After this future completes successfully, you may call
|
||||
* {@link PaymentChannelClientConnection#incrementPayment(Coin)} to begin paying the server.</p>
|
||||
* {@link PaymentChannelClientConnection#incrementPayment(Coin)} or {@link PaymentChannelClientConnection#incrementPayment(Coin, com.google.protobuf.ByteString)} to begin paying the server.</p>
|
||||
*/
|
||||
public ListenableFuture<PaymentChannelClientConnection> getChannelOpenFuture() {
|
||||
return channelOpenFuture;
|
||||
@ -136,7 +137,20 @@ public class PaymentChannelClientConnection {
|
||||
* (see {@link PaymentChannelClientConnection#getChannelOpenFuture()} for the second)
|
||||
*/
|
||||
public ListenableFuture<Coin> incrementPayment(Coin size) throws ValueOutOfRangeException, IllegalStateException {
|
||||
return channelClient.incrementPayment(size);
|
||||
return channelClient.incrementPayment(size, ByteString.EMPTY);
|
||||
}
|
||||
/**
|
||||
* Increments the total value which we pay the server.
|
||||
*
|
||||
* @param size How many satoshis to increment the payment by (note: not the new total).
|
||||
* @param info Information about this payment increment, used to extend this protocol.
|
||||
* @throws ValueOutOfRangeException If the size is negative or would pay more than this channel's total value
|
||||
* ({@link PaymentChannelClientConnection#state()}.getTotalValue())
|
||||
* @throws IllegalStateException If the channel has been closed or is not yet open
|
||||
* (see {@link PaymentChannelClientConnection#getChannelOpenFuture()} for the second)
|
||||
*/
|
||||
public ListenableFuture<Coin> incrementPayment(Coin size, ByteString info) throws ValueOutOfRangeException, IllegalStateException {
|
||||
return channelClient.incrementPayment(size, info);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -100,8 +100,9 @@ public class PaymentChannelServer {
|
||||
*
|
||||
* @param by The increase in total payment
|
||||
* @param to The new total payment to us (not including fees which may be required to claim the payment)
|
||||
* @param info Information about this payment increase, used to extend this protocol.
|
||||
*/
|
||||
public void paymentIncrease(Coin by, Coin to);
|
||||
public void paymentIncrease(Coin by, Coin to, @Nullable ByteString info);
|
||||
}
|
||||
private final ServerConnection conn;
|
||||
|
||||
@ -314,8 +315,10 @@ public class PaymentChannelServer {
|
||||
boolean stillUsable = state.incrementPayment(refundSize, msg.getSignature().toByteArray());
|
||||
Coin bestPaymentChange = state.getBestValueToMe().subtract(lastBestPayment);
|
||||
|
||||
if (bestPaymentChange.signum() > 0)
|
||||
conn.paymentIncrease(bestPaymentChange, state.getBestValueToMe());
|
||||
if (bestPaymentChange.signum() > 0) {
|
||||
ByteString info = (msg.hasInfo()) ? msg.getInfo() : null;
|
||||
conn.paymentIncrease(bestPaymentChange, state.getBestValueToMe(), info);
|
||||
}
|
||||
|
||||
if (sendAck) {
|
||||
Protos.TwoWayChannelMessage.Builder ack = Protos.TwoWayChannelMessage.newBuilder();
|
||||
|
@ -25,6 +25,7 @@ import com.google.bitcoin.net.NioServer;
|
||||
import com.google.bitcoin.net.ProtobufParser;
|
||||
import com.google.bitcoin.net.StreamParserFactory;
|
||||
|
||||
import com.google.protobuf.ByteString;
|
||||
import org.bitcoin.paymentchannel.Protos;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
@ -82,8 +83,8 @@ public class PaymentChannelServerListener {
|
||||
eventHandler.channelOpen(contractHash);
|
||||
}
|
||||
|
||||
@Override public void paymentIncrease(Coin by, Coin to) {
|
||||
eventHandler.paymentIncrease(by, to);
|
||||
@Override public void paymentIncrease(Coin by, Coin to, @Nullable ByteString info) {
|
||||
eventHandler.paymentIncrease(by, to, info);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -20,6 +20,7 @@ import com.google.bitcoin.core.Coin;
|
||||
import com.google.bitcoin.core.Sha256Hash;
|
||||
import com.google.bitcoin.net.ProtobufParser;
|
||||
|
||||
import com.google.protobuf.ByteString;
|
||||
import org.bitcoin.paymentchannel.Protos;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
@ -69,8 +70,9 @@ public abstract class ServerConnectionEventHandler {
|
||||
*
|
||||
* @param by The increase in total payment
|
||||
* @param to The new total payment to us (not including fees which may be required to claim the payment)
|
||||
* @param info Information about this payment increase, used to extend this protocol.
|
||||
*/
|
||||
public abstract void paymentIncrease(Coin by, Coin to);
|
||||
public abstract void paymentIncrease(Coin by, Coin to, ByteString info);
|
||||
|
||||
/**
|
||||
* <p>Called when the channel was closed for some reason. May be called without a call to
|
||||
|
@ -6582,6 +6582,24 @@ public final class Protos {
|
||||
* </pre>
|
||||
*/
|
||||
com.google.protobuf.ByteString getSignature();
|
||||
|
||||
// optional bytes info = 3;
|
||||
/**
|
||||
* <code>optional bytes info = 3;</code>
|
||||
*
|
||||
* <pre>
|
||||
* Information about the this update. Used to extend this protocol.
|
||||
* </pre>
|
||||
*/
|
||||
boolean hasInfo();
|
||||
/**
|
||||
* <code>optional bytes info = 3;</code>
|
||||
*
|
||||
* <pre>
|
||||
* Information about the this update. Used to extend this protocol.
|
||||
* </pre>
|
||||
*/
|
||||
com.google.protobuf.ByteString getInfo();
|
||||
}
|
||||
/**
|
||||
* Protobuf type {@code paymentchannels.UpdatePayment}
|
||||
@ -6660,6 +6678,11 @@ public final class Protos {
|
||||
signature_ = input.readBytes();
|
||||
break;
|
||||
}
|
||||
case 26: {
|
||||
bitField0_ |= 0x00000004;
|
||||
info_ = input.readBytes();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
|
||||
@ -6756,9 +6779,34 @@ public final class Protos {
|
||||
return signature_;
|
||||
}
|
||||
|
||||
// optional bytes info = 3;
|
||||
public static final int INFO_FIELD_NUMBER = 3;
|
||||
private com.google.protobuf.ByteString info_;
|
||||
/**
|
||||
* <code>optional bytes info = 3;</code>
|
||||
*
|
||||
* <pre>
|
||||
* Information about the this update. Used to extend this protocol.
|
||||
* </pre>
|
||||
*/
|
||||
public boolean hasInfo() {
|
||||
return ((bitField0_ & 0x00000004) == 0x00000004);
|
||||
}
|
||||
/**
|
||||
* <code>optional bytes info = 3;</code>
|
||||
*
|
||||
* <pre>
|
||||
* Information about the this update. Used to extend this protocol.
|
||||
* </pre>
|
||||
*/
|
||||
public com.google.protobuf.ByteString getInfo() {
|
||||
return info_;
|
||||
}
|
||||
|
||||
private void initFields() {
|
||||
clientChangeValue_ = 0L;
|
||||
signature_ = com.google.protobuf.ByteString.EMPTY;
|
||||
info_ = com.google.protobuf.ByteString.EMPTY;
|
||||
}
|
||||
private byte memoizedIsInitialized = -1;
|
||||
public final boolean isInitialized() {
|
||||
@ -6786,6 +6834,9 @@ public final class Protos {
|
||||
if (((bitField0_ & 0x00000002) == 0x00000002)) {
|
||||
output.writeBytes(2, signature_);
|
||||
}
|
||||
if (((bitField0_ & 0x00000004) == 0x00000004)) {
|
||||
output.writeBytes(3, info_);
|
||||
}
|
||||
getUnknownFields().writeTo(output);
|
||||
}
|
||||
|
||||
@ -6803,6 +6854,10 @@ public final class Protos {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeBytesSize(2, signature_);
|
||||
}
|
||||
if (((bitField0_ & 0x00000004) == 0x00000004)) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeBytesSize(3, info_);
|
||||
}
|
||||
size += getUnknownFields().getSerializedSize();
|
||||
memoizedSerializedSize = size;
|
||||
return size;
|
||||
@ -6939,6 +6994,8 @@ public final class Protos {
|
||||
bitField0_ = (bitField0_ & ~0x00000001);
|
||||
signature_ = com.google.protobuf.ByteString.EMPTY;
|
||||
bitField0_ = (bitField0_ & ~0x00000002);
|
||||
info_ = com.google.protobuf.ByteString.EMPTY;
|
||||
bitField0_ = (bitField0_ & ~0x00000004);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -6975,6 +7032,10 @@ public final class Protos {
|
||||
to_bitField0_ |= 0x00000002;
|
||||
}
|
||||
result.signature_ = signature_;
|
||||
if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
|
||||
to_bitField0_ |= 0x00000004;
|
||||
}
|
||||
result.info_ = info_;
|
||||
result.bitField0_ = to_bitField0_;
|
||||
onBuilt();
|
||||
return result;
|
||||
@ -6997,6 +7058,9 @@ public final class Protos {
|
||||
if (other.hasSignature()) {
|
||||
setSignature(other.getSignature());
|
||||
}
|
||||
if (other.hasInfo()) {
|
||||
setInfo(other.getInfo());
|
||||
}
|
||||
this.mergeUnknownFields(other.getUnknownFields());
|
||||
return this;
|
||||
}
|
||||
@ -7149,6 +7213,58 @@ public final class Protos {
|
||||
return this;
|
||||
}
|
||||
|
||||
// optional bytes info = 3;
|
||||
private com.google.protobuf.ByteString info_ = com.google.protobuf.ByteString.EMPTY;
|
||||
/**
|
||||
* <code>optional bytes info = 3;</code>
|
||||
*
|
||||
* <pre>
|
||||
* Information about the this update. Used to extend this protocol.
|
||||
* </pre>
|
||||
*/
|
||||
public boolean hasInfo() {
|
||||
return ((bitField0_ & 0x00000004) == 0x00000004);
|
||||
}
|
||||
/**
|
||||
* <code>optional bytes info = 3;</code>
|
||||
*
|
||||
* <pre>
|
||||
* Information about the this update. Used to extend this protocol.
|
||||
* </pre>
|
||||
*/
|
||||
public com.google.protobuf.ByteString getInfo() {
|
||||
return info_;
|
||||
}
|
||||
/**
|
||||
* <code>optional bytes info = 3;</code>
|
||||
*
|
||||
* <pre>
|
||||
* Information about the this update. Used to extend this protocol.
|
||||
* </pre>
|
||||
*/
|
||||
public Builder setInfo(com.google.protobuf.ByteString value) {
|
||||
if (value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
bitField0_ |= 0x00000004;
|
||||
info_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <code>optional bytes info = 3;</code>
|
||||
*
|
||||
* <pre>
|
||||
* Information about the this update. Used to extend this protocol.
|
||||
* </pre>
|
||||
*/
|
||||
public Builder clearInfo() {
|
||||
bitField0_ = (bitField0_ & ~0x00000004);
|
||||
info_ = getDefaultInstance().getInfo();
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(builder_scope:paymentchannels.UpdatePayment)
|
||||
}
|
||||
|
||||
@ -8624,18 +8740,18 @@ public final class Protos {
|
||||
"d\022\024\n\014multisig_key\030\001 \002(\014\022\n\n\002tx\030\002 \002(\014\"!\n\014R" +
|
||||
"eturnRefund\022\021\n\tsignature\030\001 \002(\014\"V\n\017Provid" +
|
||||
"eContract\022\n\n\002tx\030\001 \002(\014\0227\n\017initial_payment",
|
||||
"\030\002 \002(\0132\036.paymentchannels.UpdatePayment\"?" +
|
||||
"\030\002 \002(\0132\036.paymentchannels.UpdatePayment\"M" +
|
||||
"\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\"\246\002\n\005Error\0225\n\004code\030\001 \001(\0162 .paym" +
|
||||
"entchannels.Error.ErrorCode:\005OTHER\022\023\n\013ex" +
|
||||
"planation\030\002 \001(\t\022\026\n\016expected_value\030\003 \001(\004\"" +
|
||||
"\270\001\n\tErrorCode\022\013\n\007TIMEOUT\020\001\022\020\n\014SYNTAX_ERR" +
|
||||
"OR\020\002\022\031\n\025NO_ACCEPTABLE_VERSION\020\003\022\023\n\017BAD_T" +
|
||||
"RANSACTION\020\004\022\031\n\025TIME_WINDOW_TOO_LARGE\020\005\022" +
|
||||
"\033\n\027CHANNEL_VALUE_TOO_LARGE\020\006\022\031\n\025MIN_PAYM",
|
||||
"ENT_TOO_LARGE\020\007\022\t\n\005OTHER\020\010B$\n\032org.bitcoi" +
|
||||
"n.paymentchannelB\006Protos"
|
||||
" \002(\004\022\021\n\tsignature\030\002 \002(\014\022\014\n\004info\030\003 \001(\014\"\030\n" +
|
||||
"\nSettlement\022\n\n\002tx\030\003 \002(\014\"\246\002\n\005Error\0225\n\004cod" +
|
||||
"e\030\001 \001(\0162 .paymentchannels.Error.ErrorCod" +
|
||||
"e:\005OTHER\022\023\n\013explanation\030\002 \001(\t\022\026\n\016expecte" +
|
||||
"d_value\030\003 \001(\004\"\270\001\n\tErrorCode\022\013\n\007TIMEOUT\020\001" +
|
||||
"\022\020\n\014SYNTAX_ERROR\020\002\022\031\n\025NO_ACCEPTABLE_VERS" +
|
||||
"ION\020\003\022\023\n\017BAD_TRANSACTION\020\004\022\031\n\025TIME_WINDO" +
|
||||
"W_TOO_LARGE\020\005\022\033\n\027CHANNEL_VALUE_TOO_LARGE",
|
||||
"\020\006\022\031\n\025MIN_PAYMENT_TOO_LARGE\020\007\022\t\n\005OTHER\020\010" +
|
||||
"B$\n\032org.bitcoin.paymentchannelB\006Protos"
|
||||
};
|
||||
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
|
||||
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
|
||||
@ -8689,7 +8805,7 @@ public final class Protos {
|
||||
internal_static_paymentchannels_UpdatePayment_fieldAccessorTable = new
|
||||
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
|
||||
internal_static_paymentchannels_UpdatePayment_descriptor,
|
||||
new java.lang.String[] { "ClientChangeValue", "Signature", });
|
||||
new java.lang.String[] { "ClientChangeValue", "Signature", "Info", });
|
||||
internal_static_paymentchannels_Settlement_descriptor =
|
||||
getDescriptor().getMessageTypes().get(8);
|
||||
internal_static_paymentchannels_Settlement_fieldAccessorTable = new
|
||||
|
@ -209,6 +209,9 @@ message UpdatePayment {
|
||||
// the primary's refund output and thus the secondary is free to do what they wish with their
|
||||
// part of the multisig output.
|
||||
required bytes signature = 2;
|
||||
// Information about this update. Used to extend this protocol.
|
||||
optional bytes info = 3;
|
||||
|
||||
}
|
||||
|
||||
message Settlement {
|
||||
|
@ -117,7 +117,7 @@ public class ChannelConnectionTest extends TestWithWallet {
|
||||
// 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<Coin> q = new LinkedBlockingQueue<Coin>();
|
||||
final BlockingQueue<ChannelTestUtils.UpdatePair> q = new LinkedBlockingQueue<ChannelTestUtils.UpdatePair>();
|
||||
final PaymentChannelServerListener server = new PaymentChannelServerListener(mockBroadcaster, serverWallet, 30, COIN,
|
||||
new PaymentChannelServerListener.HandlerFactory() {
|
||||
@Nullable
|
||||
@ -130,8 +130,8 @@ public class ChannelConnectionTest extends TestWithWallet {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paymentIncrease(Coin by, Coin to) {
|
||||
q.add(to);
|
||||
public void paymentIncrease(Coin by, Coin to, ByteString info) {
|
||||
q.add(new ChannelTestUtils.UpdatePair(to, info));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -171,16 +171,13 @@ public class ChannelConnectionTest extends TestWithWallet {
|
||||
|
||||
Thread.sleep(1250); // No timeouts once the channel is open
|
||||
Coin amount = client.state().getValueSpent();
|
||||
assertEquals(amount, q.take());
|
||||
client.incrementPayment(CENT).get();
|
||||
amount = amount.add(CENT);
|
||||
assertEquals(amount, q.take());
|
||||
client.incrementPayment(CENT).get();
|
||||
amount = amount.add(CENT);
|
||||
assertEquals(amount, q.take());
|
||||
client.incrementPayment(CENT).get();
|
||||
amount = amount.add(CENT);
|
||||
assertEquals(amount, q.take());
|
||||
q.take().assertPair(amount, ByteString.EMPTY);
|
||||
ByteString[] infos = new ByteString[]{ByteString.EMPTY, ByteString.copyFromUtf8("one"),ByteString.copyFromUtf8("two")};
|
||||
for (ByteString info : infos) {
|
||||
client.incrementPayment(CENT, info).get();
|
||||
amount = amount.add(CENT);
|
||||
q.take().assertPair(amount, info);
|
||||
}
|
||||
latch.await();
|
||||
|
||||
StoredPaymentChannelServerStates channels = (StoredPaymentChannelServerStates)serverWallet.getExtensions().get(StoredPaymentChannelServerStates.EXTENSION_ID);
|
||||
@ -301,7 +298,7 @@ public class ChannelConnectionTest extends TestWithWallet {
|
||||
Coin amount = minPayment.add(CENT);
|
||||
client.incrementPayment(CENT);
|
||||
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.UPDATE_PAYMENT));
|
||||
assertEquals(amount, pair.serverRecorder.q.take());
|
||||
assertEquals(amount, ((ChannelTestUtils.UpdatePair)pair.serverRecorder.q.take()).amount);
|
||||
server.close();
|
||||
server.connectionClosed();
|
||||
client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.PAYMENT_ACK));
|
||||
|
@ -5,8 +5,10 @@ import com.google.bitcoin.core.Sha256Hash;
|
||||
import com.google.bitcoin.core.TransactionBroadcaster;
|
||||
import com.google.bitcoin.core.Wallet;
|
||||
|
||||
import com.google.protobuf.ByteString;
|
||||
import org.bitcoin.paymentchannel.Protos;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
@ -35,8 +37,8 @@ public class ChannelTestUtils {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paymentIncrease(Coin by, Coin to) {
|
||||
q.add(to);
|
||||
public void paymentIncrease(Coin by, Coin to, @Nullable ByteString info) {
|
||||
q.add(new UpdatePair(to, info));
|
||||
}
|
||||
|
||||
public Protos.TwoWayChannelMessage getNextMsg() throws InterruptedException {
|
||||
@ -50,7 +52,7 @@ public class ChannelTestUtils {
|
||||
}
|
||||
|
||||
public void checkTotalPayment(Coin valueSoFar) throws InterruptedException {
|
||||
Coin lastSeen = (Coin) q.take();
|
||||
Coin lastSeen = ((UpdatePair) q.take()).amount;
|
||||
assertEquals(lastSeen, valueSoFar);
|
||||
}
|
||||
}
|
||||
@ -112,4 +114,40 @@ public class ChannelTestUtils {
|
||||
pair.clientRecorder = new RecordingClientConnection();
|
||||
return pair;
|
||||
}
|
||||
|
||||
public static class UpdatePair {
|
||||
public Coin amount;
|
||||
public ByteString info;
|
||||
|
||||
public UpdatePair(Coin amount, ByteString info) {
|
||||
this.amount = amount;
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
UpdatePair that = (UpdatePair) o;
|
||||
|
||||
if (amount != null ? !amount.equals(that.amount) : that.amount != null) return false;
|
||||
if (info != null ? !info.equals(that.info) : that.info != null) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = amount != null ? amount.hashCode() : 0;
|
||||
result = 31 * result + (info != null ? info.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
public void assertPair(Coin amount, ByteString info) {
|
||||
assertEquals(amount, this.amount);
|
||||
assertEquals(info, this.info);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ import com.google.bitcoin.protocols.channels.*;
|
||||
import com.google.bitcoin.utils.BriefLogFormatter;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import com.google.protobuf.ByteString;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
@ -101,7 +102,7 @@ public class ExamplePaymentChannelServer implements PaymentChannelServerListener
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paymentIncrease(Coin by, Coin to) {
|
||||
public void paymentIncrease(Coin by, Coin to, ByteString info) {
|
||||
log.info("Client {} paid increased payment by {} for a total of " + to.toString(), clientAddress, by);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user