mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-02-19 05:35:49 +00:00
Payment channels: update example client to reflect API changes.
This commit is contained in:
parent
9fe8e8ee2b
commit
8ff52f5217
@ -17,16 +17,21 @@
|
|||||||
|
|
||||||
package com.google.bitcoin.examples;
|
package com.google.bitcoin.examples;
|
||||||
|
|
||||||
import com.google.bitcoin.core.*;
|
import com.google.bitcoin.core.ECKey;
|
||||||
|
import com.google.bitcoin.core.NetworkParameters;
|
||||||
|
import com.google.bitcoin.core.Utils;
|
||||||
|
import com.google.bitcoin.core.Wallet;
|
||||||
import com.google.bitcoin.kits.WalletAppKit;
|
import com.google.bitcoin.kits.WalletAppKit;
|
||||||
import com.google.bitcoin.params.TestNet3Params;
|
import com.google.bitcoin.params.RegTestParams;
|
||||||
import com.google.bitcoin.protocols.channels.PaymentChannelClientConnection;
|
import com.google.bitcoin.protocols.channels.PaymentChannelClientConnection;
|
||||||
import com.google.bitcoin.protocols.channels.StoredPaymentChannelClientStates;
|
import com.google.bitcoin.protocols.channels.StoredPaymentChannelClientStates;
|
||||||
import com.google.bitcoin.protocols.channels.ValueOutOfRangeException;
|
import com.google.bitcoin.protocols.channels.ValueOutOfRangeException;
|
||||||
import com.google.bitcoin.utils.BriefLogFormatter;
|
import com.google.bitcoin.utils.BriefLogFormatter;
|
||||||
|
import com.google.bitcoin.utils.Threading;
|
||||||
import com.google.common.util.concurrent.FutureCallback;
|
import com.google.common.util.concurrent.FutureCallback;
|
||||||
import com.google.common.util.concurrent.Futures;
|
import com.google.common.util.concurrent.Futures;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
import com.google.common.util.concurrent.Uninterruptibles;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@ -34,10 +39,10 @@ import java.io.IOException;
|
|||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
import static com.google.bitcoin.core.Utils.CENT;
|
import static com.google.bitcoin.core.Utils.CENT;
|
||||||
import static java.math.BigInteger.TEN;
|
import static java.math.BigInteger.TEN;
|
||||||
import static java.math.BigInteger.ZERO;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple client that connects to the given host, opens a channel, and pays one cent.
|
* Simple client that connects to the given host, opens a channel, and pays one cent.
|
||||||
@ -58,7 +63,7 @@ public class ExamplePaymentChannelClient {
|
|||||||
public ExamplePaymentChannelClient() {
|
public ExamplePaymentChannelClient() {
|
||||||
channelSize = CENT;
|
channelSize = CENT;
|
||||||
myKey = new ECKey();
|
myKey = new ECKey();
|
||||||
params = TestNet3Params.get();
|
params = RegTestParams.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run(final String host) throws Exception {
|
public void run(final String host) throws Exception {
|
||||||
@ -74,6 +79,7 @@ public class ExamplePaymentChannelClient {
|
|||||||
wallet().addExtension(new StoredPaymentChannelClientStates(wallet(), peerGroup()));
|
wallet().addExtension(new StoredPaymentChannelClientStates(wallet(), peerGroup()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
appKit.connectToLocalHost();
|
||||||
appKit.startAsync();
|
appKit.startAsync();
|
||||||
appKit.awaitRunning();
|
appKit.awaitRunning();
|
||||||
// We now have active network connections and a fully synced wallet.
|
// We now have active network connections and a fully synced wallet.
|
||||||
@ -98,18 +104,16 @@ public class ExamplePaymentChannelClient {
|
|||||||
// demonstrates resuming a channel that wasn't closed yet. It should close automatically once we run out
|
// demonstrates resuming a channel that wasn't closed yet. It should close automatically once we run out
|
||||||
// of money on the channel.
|
// of money on the channel.
|
||||||
log.info("Round one ...");
|
log.info("Round one ...");
|
||||||
openAndSend(timeoutSecs, server, channelID);
|
openAndSend(timeoutSecs, server, channelID, 5);
|
||||||
log.info("Round two ...");
|
log.info("Round two ...");
|
||||||
log.info(appKit.wallet().toString());
|
log.info(appKit.wallet().toString());
|
||||||
openAndSend(timeoutSecs, server, channelID);
|
openAndSend(timeoutSecs, server, channelID, 4); // 4 times because the opening of the channel made a payment.
|
||||||
log.info("Waiting ...");
|
|
||||||
Thread.sleep(60 * 60 * 1000); // 1 hour.
|
|
||||||
log.info("Stopping ...");
|
log.info("Stopping ...");
|
||||||
appKit.stopAsync();
|
appKit.stopAsync();
|
||||||
appKit.awaitTerminated();
|
appKit.awaitTerminated();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void openAndSend(int timeoutSecs, InetSocketAddress server, String channelID) throws IOException, ValueOutOfRangeException, InterruptedException {
|
private void openAndSend(int timeoutSecs, InetSocketAddress server, String channelID, final int times) throws IOException, ValueOutOfRangeException, InterruptedException {
|
||||||
PaymentChannelClientConnection client = new PaymentChannelClientConnection(
|
PaymentChannelClientConnection client = new PaymentChannelClientConnection(
|
||||||
server, timeoutSecs, appKit.wallet(), myKey, channelSize, channelID);
|
server, timeoutSecs, appKit.wallet(), myKey, channelSize, channelID);
|
||||||
// Opening the channel requires talking to the server, so it's asynchronous.
|
// Opening the channel requires talking to the server, so it's asynchronous.
|
||||||
@ -117,17 +121,28 @@ public class ExamplePaymentChannelClient {
|
|||||||
Futures.addCallback(client.getChannelOpenFuture(), new FutureCallback<PaymentChannelClientConnection>() {
|
Futures.addCallback(client.getChannelOpenFuture(), new FutureCallback<PaymentChannelClientConnection>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(PaymentChannelClientConnection client) {
|
public void onSuccess(PaymentChannelClientConnection client) {
|
||||||
// Success! We should be able to try making micropayments now. Try doing it 5 times.
|
// By the time we get here, if the channel is new then we already made a micropayment! The reason is,
|
||||||
for (int i = 0; i < 5; i++) {
|
// we are not allowed to have payment channels that pay nothing at all.
|
||||||
|
log.info("Success! Trying to make {} micropayments. Already paid {} satoshis on this channel",
|
||||||
|
times, client.state().getValueSpent());
|
||||||
|
final BigInteger MICROPAYMENT_SIZE = CENT.divide(TEN);
|
||||||
|
for (int i = 0; i < times; i++) {
|
||||||
try {
|
try {
|
||||||
client.incrementPayment(CENT.divide(TEN));
|
// Wait because the act of making a micropayment is async, and we're not allowed to overlap.
|
||||||
|
// This callback is running on the user thread (see the last lines in openAndSend) so it's safe
|
||||||
|
// for us to block here: if we didn't select the right thread, we'd end up blocking the payment
|
||||||
|
// channels thread and would deadlock.
|
||||||
|
Uninterruptibles.getUninterruptibly(client.incrementPayment(MICROPAYMENT_SIZE));
|
||||||
} catch (ValueOutOfRangeException e) {
|
} catch (ValueOutOfRangeException e) {
|
||||||
log.error("Failed to increment payment by a CENT, remaining value is {}", client.state().getValueRefunded());
|
log.error("Failed to increment payment by a CENT, remaining value is {}", client.state().getValueRefunded());
|
||||||
System.exit(-3);
|
throw new RuntimeException(e);
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
log.error("Failed to increment payment", e);
|
||||||
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
log.info("Successfully sent payment of one CENT, total remaining on channel is now {}", client.state().getValueRefunded());
|
log.info("Successfully sent payment of one CENT, total remaining on channel is now {}", client.state().getValueRefunded());
|
||||||
}
|
}
|
||||||
if (client.state().getValueRefunded().equals(ZERO)) {
|
if (client.state().getValueRefunded().compareTo(MICROPAYMENT_SIZE) < 0) {
|
||||||
// Now tell the server we're done so they should broadcast the final transaction and refund us what's
|
// Now tell the server we're done so they should broadcast the final transaction and refund us what's
|
||||||
// left. If we never do this then eventually the server will time out and do it anyway and if the
|
// left. If we never do this then eventually the server will time out and do it anyway and if the
|
||||||
// server goes away for longer, then eventually WE will time out and the refund tx will get broadcast
|
// server goes away for longer, then eventually WE will time out and the refund tx will get broadcast
|
||||||
@ -146,7 +161,7 @@ public class ExamplePaymentChannelClient {
|
|||||||
log.error("Failed to open connection", throwable);
|
log.error("Failed to open connection", throwable);
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
}
|
}
|
||||||
});
|
}, Threading.USER_THREAD);
|
||||||
latch.await();
|
latch.await();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,9 +17,11 @@
|
|||||||
|
|
||||||
package com.google.bitcoin.examples;
|
package com.google.bitcoin.examples;
|
||||||
|
|
||||||
import com.google.bitcoin.core.*;
|
import com.google.bitcoin.core.NetworkParameters;
|
||||||
|
import com.google.bitcoin.core.Sha256Hash;
|
||||||
|
import com.google.bitcoin.core.VerificationException;
|
||||||
import com.google.bitcoin.kits.WalletAppKit;
|
import com.google.bitcoin.kits.WalletAppKit;
|
||||||
import com.google.bitcoin.params.TestNet3Params;
|
import com.google.bitcoin.params.RegTestParams;
|
||||||
import com.google.bitcoin.protocols.channels.*;
|
import com.google.bitcoin.protocols.channels.*;
|
||||||
import com.google.bitcoin.utils.BriefLogFormatter;
|
import com.google.bitcoin.utils.BriefLogFormatter;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -43,7 +45,7 @@ public class ExamplePaymentChannelServer implements PaymentChannelServerListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void run() throws Exception {
|
public void run() throws Exception {
|
||||||
NetworkParameters params = TestNet3Params.get();
|
NetworkParameters params = RegTestParams.get();
|
||||||
|
|
||||||
// Bring up all the objects we need, create/load a wallet, sync the chain, etc. We override WalletAppKit so we
|
// Bring up all the objects we need, create/load a wallet, sync the chain, etc. We override WalletAppKit so we
|
||||||
// can customize it by adding the extension objects - we have to do this before the wallet file is loaded so
|
// can customize it by adding the extension objects - we have to do this before the wallet file is loaded so
|
||||||
@ -58,6 +60,7 @@ public class ExamplePaymentChannelServer implements PaymentChannelServerListener
|
|||||||
wallet().addExtension(storedStates);
|
wallet().addExtension(storedStates);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
appKit.connectToLocalHost();
|
||||||
appKit.startAsync();
|
appKit.startAsync();
|
||||||
appKit.awaitRunning();
|
appKit.awaitRunning();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user