3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-02-13 10:45:51 +00:00

Added capability to run example payment channels on regtest, test or main nets

This commit is contained in:
Will Shackleton 2016-02-08 11:21:00 +00:00 committed by Andreas Schildbach
parent ef3acab8d5
commit 7bb7ab60e1
4 changed files with 110 additions and 14 deletions

View File

@ -36,6 +36,11 @@
<artifactId>bitcoinj-core</artifactId> <artifactId>bitcoinj-core</artifactId>
<version>${project.parent.version}</version> <version>${project.parent.version}</version>
</dependency> </dependency>
<dependency>
<groupId>net.sf.jopt-simple</groupId>
<artifactId>jopt-simple</artifactId>
<version>4.3</version>
</dependency>
<dependency> <dependency>
<groupId>org.slf4j</groupId> <groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId> <artifactId>slf4j-jdk14</artifactId>

View File

@ -17,6 +17,9 @@
package org.bitcoinj.examples; package org.bitcoinj.examples;
import joptsimple.OptionParser;
import joptsimple.OptionSet;
import joptsimple.OptionSpec;
import org.bitcoinj.core.*; import org.bitcoinj.core.*;
import org.bitcoinj.kits.WalletAppKit; import org.bitcoinj.kits.WalletAppKit;
import org.bitcoinj.params.RegTestParams; import org.bitcoinj.params.RegTestParams;
@ -54,8 +57,32 @@ public class ExamplePaymentChannelClient {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
BriefLogFormatter.init(); BriefLogFormatter.init();
System.out.println("USAGE: host"); OptionParser parser = new OptionParser();
new ExamplePaymentChannelClient().run(args[0]); OptionSpec<NetworkEnum> net = parser.accepts("net", "The network to run the examples on").withRequiredArg().ofType(NetworkEnum.class).defaultsTo(NetworkEnum.TEST);
OptionSpec<Integer> version = parser.accepts("version", "The payment channel protocol to use").withRequiredArg().ofType(Integer.class);
parser.accepts("help", "Displays program options");
OptionSet opts = parser.parse(args);
if (opts.has("help") || !opts.has(net) || opts.nonOptionArguments().size() != 1) {
System.err.println("usage: ExamplePaymentChannelClient --net=MAIN/TEST/REGTEST --version=1/2 host");
parser.printHelpOn(System.err);
return;
}
PaymentChannelClient.VersionSelector versionSelector = PaymentChannelClient.VersionSelector.VERSION_1;
if (opts.has("version")) {
switch (version.value(opts)) {
case 1:
versionSelector = PaymentChannelClient.VersionSelector.VERSION_1;
break;
case 2:
versionSelector = PaymentChannelClient.VersionSelector.VERSION_2;
break;
default:
System.err.println("Invalid version - valid versions are 1, 2");
return;
}
}
NetworkParameters params = net.value(opts).get();
new ExamplePaymentChannelClient().run(opts.nonOptionArguments().get(0), versionSelector, params);
} }
public ExamplePaymentChannelClient() { public ExamplePaymentChannelClient() {
@ -64,7 +91,7 @@ public class ExamplePaymentChannelClient {
params = RegTestParams.get(); params = RegTestParams.get();
} }
public void run(final String host) throws Exception { public void run(final String host, PaymentChannelClient.VersionSelector versionSelector, final NetworkParameters params) throws Exception {
// 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
// the plugin that knows how to parse all the additional data is present during the load. // the plugin that knows how to parse all the additional data is present during the load.
@ -79,7 +106,11 @@ public class ExamplePaymentChannelClient {
return ImmutableList.<WalletExtension>of(new StoredPaymentChannelClientStates(null)); return ImmutableList.<WalletExtension>of(new StoredPaymentChannelClientStates(null));
} }
}; };
appKit.connectToLocalHost(); // Broadcasting can take a bit of time so we up the timeout for "real" networks
final int timeoutSeconds = params.getId().equals(NetworkParameters.ID_REGTEST) ? 15 : 150;
if (params == RegTestParams.get()) {
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.
@ -95,7 +126,6 @@ public class ExamplePaymentChannelClient {
// //
// Note that this may or may not actually construct a new channel. If an existing unclosed channel is found in // Note that this may or may not actually construct a new channel. If an existing unclosed channel is found in
// the wallet, then it'll re-use that one instead. // the wallet, then it'll re-use that one instead.
final int timeoutSecs = 15;
final InetSocketAddress server = new InetSocketAddress(host, 4242); final InetSocketAddress server = new InetSocketAddress(host, 4242);
waitForSufficientBalance(channelSize); waitForSufficientBalance(channelSize);
@ -104,19 +134,19 @@ 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, 5); openAndSend(timeoutSeconds, server, channelID, 5, versionSelector);
log.info("Round two ..."); log.info("Round two ...");
log.info(appKit.wallet().toString()); log.info(appKit.wallet().toString());
openAndSend(timeoutSecs, server, channelID, 4); // 4 times because the opening of the channel made a payment. openAndSend(timeoutSeconds, server, channelID, 4, versionSelector); // 4 times because the opening of the channel made a payment.
log.info("Stopping ..."); log.info("Stopping ...");
appKit.stopAsync(); appKit.stopAsync();
appKit.awaitTerminated(); appKit.awaitTerminated();
} }
private void openAndSend(int timeoutSecs, InetSocketAddress server, String channelID, final int times) throws IOException, ValueOutOfRangeException, InterruptedException { private void openAndSend(int timeoutSecs, InetSocketAddress server, String channelID, final int times, PaymentChannelClient.VersionSelector versionSelector) throws IOException, ValueOutOfRangeException, InterruptedException {
// Use protocol version 1 for simplicity // Use protocol version 1 for simplicity
PaymentChannelClientConnection client = new PaymentChannelClientConnection( PaymentChannelClientConnection client = new PaymentChannelClientConnection(
server, timeoutSecs, appKit.wallet(), myKey, channelSize, channelID, PaymentChannelClient.VersionSelector.VERSION_1); server, timeoutSecs, appKit.wallet(), myKey, channelSize, channelID, versionSelector);
// Opening the channel requires talking to the server, so it's asynchronous. // Opening the channel requires talking to the server, so it's asynchronous.
final CountDownLatch latch = new CountDownLatch(1); final CountDownLatch latch = new CountDownLatch(1);
Futures.addCallback(client.getChannelOpenFuture(), new FutureCallback<PaymentChannelClientConnection>() { Futures.addCallback(client.getChannelOpenFuture(), new FutureCallback<PaymentChannelClientConnection>() {

View File

@ -17,13 +17,18 @@
package org.bitcoinj.examples; package org.bitcoinj.examples;
import joptsimple.OptionParser;
import joptsimple.OptionSet;
import joptsimple.OptionSpec;
import org.bitcoinj.core.Coin; import org.bitcoinj.core.Coin;
import org.bitcoinj.core.NetworkParameters; import org.bitcoinj.core.NetworkParameters;
import org.bitcoinj.core.Sha256Hash; import org.bitcoinj.core.Sha256Hash;
import org.bitcoinj.core.VerificationException; import org.bitcoinj.core.VerificationException;
import org.bitcoinj.core.WalletExtension; import org.bitcoinj.core.WalletExtension;
import org.bitcoinj.kits.WalletAppKit; import org.bitcoinj.kits.WalletAppKit;
import org.bitcoinj.params.MainNetParams;
import org.bitcoinj.params.RegTestParams; import org.bitcoinj.params.RegTestParams;
import org.bitcoinj.params.TestNet3Params;
import org.bitcoinj.protocols.channels.*; import org.bitcoinj.protocols.channels.*;
import org.bitcoinj.utils.BriefLogFormatter; import org.bitcoinj.utils.BriefLogFormatter;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
@ -46,11 +51,20 @@ public class ExamplePaymentChannelServer implements PaymentChannelServerListener
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
BriefLogFormatter.init(); BriefLogFormatter.init();
new ExamplePaymentChannelServer().run(); OptionParser parser = new OptionParser();
OptionSpec<NetworkEnum> net = parser.accepts("net", "The network to run the examples on").withRequiredArg().ofType(NetworkEnum.class).defaultsTo(NetworkEnum.TEST);
parser.accepts("help", "Displays program options");
OptionSet opts = parser.parse(args);
if (opts.has("help") || !opts.has(net)) {
System.err.println("usage: ExamplePaymentChannelServer --net=MAIN/TEST/REGTEST");
parser.printHelpOn(System.err);
return;
}
NetworkParameters params = net.value(opts).get();
new ExamplePaymentChannelServer().run(params);
} }
public void run() throws Exception { public void run(NetworkParameters params) throws Exception {
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
@ -64,7 +78,11 @@ public class ExamplePaymentChannelServer implements PaymentChannelServerListener
return ImmutableList.<WalletExtension>of(new StoredPaymentChannelServerStates(null)); return ImmutableList.<WalletExtension>of(new StoredPaymentChannelServerStates(null));
} }
}; };
appKit.connectToLocalHost(); // Broadcasting can take a bit of time so we up the timeout for "real" networks
final int timeoutSeconds = params.getId().equals(NetworkParameters.ID_REGTEST) ? 15 : 150;
if (params == RegTestParams.get()) {
appKit.connectToLocalHost();
}
appKit.startAsync(); appKit.startAsync();
appKit.awaitRunning(); appKit.awaitRunning();
@ -72,7 +90,7 @@ public class ExamplePaymentChannelServer implements PaymentChannelServerListener
// We provide a peer group, a wallet, a timeout in seconds, the amount we require to start a channel and // We provide a peer group, a wallet, a timeout in seconds, the amount we require to start a channel and
// an implementation of HandlerFactory, which we just implement ourselves. // an implementation of HandlerFactory, which we just implement ourselves.
new PaymentChannelServerListener(appKit.peerGroup(), appKit.wallet(), 15, Coin.valueOf(100000), this).bindAndStart(4242); new PaymentChannelServerListener(appKit.peerGroup(), appKit.wallet(), timeoutSeconds, Coin.valueOf(100000), this).bindAndStart(4242);
} }
@Override @Override

View File

@ -0,0 +1,43 @@
/*
* Copyright 2013 Google Inc.
* Copyright 2014 Andreas Schildbach
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.bitcoinj.examples;
import org.bitcoinj.core.NetworkParameters;
import org.bitcoinj.params.MainNetParams;
import org.bitcoinj.params.RegTestParams;
import org.bitcoinj.params.TestNet3Params;
public enum NetworkEnum {
MAIN,
PROD, // alias for MAIN
TEST,
REGTEST;
public NetworkParameters get() {
switch(this) {
case MAIN:
case PROD:
return MainNetParams.get();
case TEST:
return TestNet3Params.get();
case REGTEST:
default:
return RegTestParams.get();
}
}
}