3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-02-07 14:54:15 +00:00

Payment channels: expose whether a channel was initiated or resumed in the ClientConnection interface.

This commit is contained in:
Mike Hearn 2013-11-13 15:29:16 +01:00
parent d41814ced2
commit 6c40363c3d
5 changed files with 27 additions and 11 deletions

View File

@ -117,11 +117,15 @@ public interface IPaymentChannelClient {
/** /**
* <p>Indicates the channel has been successfully opened and * <p>Indicates the channel has been successfully opened and
* {@link com.google.bitcoin.protocols.channels.PaymentChannelClient#incrementPayment(java.math.BigInteger)} may be called at will.</p> * {@link com.google.bitcoin.protocols.channels.PaymentChannelClient#incrementPayment(java.math.BigInteger)}
* may be called at will.</p>
* *
* <p>Called while holding a lock on the {@link com.google.bitcoin.protocols.channels.PaymentChannelClient} object - be careful about reentrancy</p> * <p>Called while holding a lock on the {@link com.google.bitcoin.protocols.channels.PaymentChannelClient}
* object - be careful about reentrancy</p>
*
* @param wasInitiated If true, the channel is newly opened. If false, it was resumed.
*/ */
void channelOpen(); void channelOpen(boolean wasInitiated);
} }
/** /**

View File

@ -169,12 +169,16 @@ public class PaymentChannelClient implements IPaymentChannelClient {
checkState(step == InitStep.WAITING_FOR_CHANNEL_OPEN || (step == InitStep.WAITING_FOR_INITIATE && storedChannel != null), step); checkState(step == InitStep.WAITING_FOR_CHANNEL_OPEN || (step == InitStep.WAITING_FOR_INITIATE && storedChannel != null), step);
log.info("Got CHANNEL_OPEN message, ready to pay"); log.info("Got CHANNEL_OPEN message, ready to pay");
if (step == InitStep.WAITING_FOR_INITIATE) boolean wasInitiated = true;
if (step == InitStep.WAITING_FOR_INITIATE) {
// We skipped the initiate step, because a previous channel that's still valid was resumed.
wasInitiated = false;
state = new PaymentChannelClientState(storedChannel, wallet); state = new PaymentChannelClientState(storedChannel, wallet);
}
step = InitStep.CHANNEL_OPEN; step = InitStep.CHANNEL_OPEN;
// channelOpen should disable timeouts, but // channelOpen should disable timeouts, but
// TODO accomodate high latency between PROVIDE_CONTRACT and here // TODO accomodate high latency between PROVIDE_CONTRACT and here
conn.channelOpen(); conn.channelOpen(wasInitiated);
} }
/** /**

View File

@ -76,7 +76,7 @@ public class PaymentChannelClientConnection {
} }
@Override @Override
public void channelOpen() { public void channelOpen(boolean wasInitiated) {
wireParser.setSocketTimeout(0); wireParser.setSocketTimeout(0);
// Inform the API user that we're done and ready to roll. // Inform the API user that we're done and ready to roll.
channelOpenFuture.set(PaymentChannelClientConnection.this); channelOpenFuture.set(PaymentChannelClientConnection.this);

View File

@ -282,7 +282,7 @@ public class ChannelConnectionTest extends TestWithWallet {
broadcasts.take(); broadcasts.take();
client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.CHANNEL_OPEN)); client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.CHANNEL_OPEN));
Sha256Hash contractHash = (Sha256Hash) pair.serverRecorder.q.take(); Sha256Hash contractHash = (Sha256Hash) pair.serverRecorder.q.take();
pair.clientRecorder.checkOpened(); pair.clientRecorder.checkInitiated();
assertNull(pair.serverRecorder.q.poll()); assertNull(pair.serverRecorder.q.poll());
assertNull(pair.clientRecorder.q.poll()); assertNull(pair.clientRecorder.q.poll());
// Send a bitcent. // Send a bitcent.
@ -601,7 +601,7 @@ public class ChannelConnectionTest extends TestWithWallet {
broadcasts.take(); broadcasts.take();
client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.CHANNEL_OPEN)); client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.CHANNEL_OPEN));
Sha256Hash contractHash = (Sha256Hash) pair.serverRecorder.q.take(); Sha256Hash contractHash = (Sha256Hash) pair.serverRecorder.q.take();
pair.clientRecorder.checkOpened(); pair.clientRecorder.checkInitiated();
assertNull(pair.serverRecorder.q.poll()); assertNull(pair.serverRecorder.q.poll());
assertNull(pair.clientRecorder.q.poll()); assertNull(pair.clientRecorder.q.poll());
// Send the whole channel at once. The server will broadcast the final contract and settle the channel for us. // Send the whole channel at once. The server will broadcast the final contract and settle the channel for us.
@ -646,7 +646,7 @@ public class ChannelConnectionTest extends TestWithWallet {
broadcasts.take(); broadcasts.take();
client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.CHANNEL_OPEN)); client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.CHANNEL_OPEN));
Sha256Hash contractHash = (Sha256Hash) pair.serverRecorder.q.take(); Sha256Hash contractHash = (Sha256Hash) pair.serverRecorder.q.take();
pair.clientRecorder.checkOpened(); pair.clientRecorder.checkInitiated();
assertNull(pair.serverRecorder.q.poll()); assertNull(pair.serverRecorder.q.poll());
assertNull(pair.clientRecorder.q.poll()); assertNull(pair.clientRecorder.q.poll());
ListenableFuture<BigInteger> future = client.incrementPayment(Utils.CENT); ListenableFuture<BigInteger> future = client.incrementPayment(Utils.CENT);
@ -699,7 +699,7 @@ public class ChannelConnectionTest extends TestWithWallet {
broadcasts.take(); broadcasts.take();
client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.CHANNEL_OPEN)); client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.CHANNEL_OPEN));
Sha256Hash contractHash = (Sha256Hash) pair.serverRecorder.q.take(); Sha256Hash contractHash = (Sha256Hash) pair.serverRecorder.q.take();
pair.clientRecorder.checkOpened(); pair.clientRecorder.checkInitiated();
assertNull(pair.serverRecorder.q.poll()); assertNull(pair.serverRecorder.q.poll());
assertNull(pair.clientRecorder.q.poll()); assertNull(pair.clientRecorder.q.poll());
client.incrementPayment(Utils.CENT); client.incrementPayment(Utils.CENT);

View File

@ -59,6 +59,7 @@ public class ChannelTestUtils {
public BlockingQueue<Object> q = new LinkedBlockingQueue<Object>(); public BlockingQueue<Object> q = new LinkedBlockingQueue<Object>();
// An arbitrary sentinel object for equality testing. // An arbitrary sentinel object for equality testing.
public static final Object CHANNEL_INITIATED = new Object();
public static final Object CHANNEL_OPEN = new Object(); public static final Object CHANNEL_OPEN = new Object();
@Override @Override
@ -72,7 +73,9 @@ public class ChannelTestUtils {
} }
@Override @Override
public void channelOpen() { public void channelOpen(boolean wasInitiated) {
if (wasInitiated)
q.add(CHANNEL_INITIATED);
q.add(CHANNEL_OPEN); q.add(CHANNEL_OPEN);
} }
@ -89,6 +92,11 @@ public class ChannelTestUtils {
public void checkOpened() throws InterruptedException { public void checkOpened() throws InterruptedException {
assertEquals(CHANNEL_OPEN, q.take()); assertEquals(CHANNEL_OPEN, q.take());
} }
public void checkInitiated() throws InterruptedException {
assertEquals(CHANNEL_INITIATED, q.take());
checkOpened();
}
} }
public static class RecordingPair { public static class RecordingPair {