mirror of
https://github.com/bitcoinj/bitcoinj.git
synced 2024-11-19 09:50:32 +01:00
Add more features to WalletAppKit, and ensure wallets it creates always have at least one key.
This commit is contained in:
parent
2ccfd3fd48
commit
95f528a340
@ -26,6 +26,7 @@ import com.google.common.util.concurrent.AbstractIdleService;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -57,6 +58,9 @@ public class WalletAppKit extends AbstractIdleService {
|
||||
|
||||
private boolean useAutoSave = true;
|
||||
private PeerAddress[] peerAddresses;
|
||||
private PeerEventListener downloadListener;
|
||||
private boolean autoStop = true;
|
||||
private InputStream checkpoints;
|
||||
|
||||
public WalletAppKit(NetworkParameters params, File directory, String filePrefix) {
|
||||
this.params = checkNotNull(params);
|
||||
@ -82,12 +86,37 @@ public class WalletAppKit extends AbstractIdleService {
|
||||
}
|
||||
}
|
||||
|
||||
/** If true, the wallet will save itself to disk automatically whenever it changes. */
|
||||
public WalletAppKit setAutoSave(boolean value) {
|
||||
checkState(state() == State.NEW, "Cannot call after startup");
|
||||
useAutoSave = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If you want to learn about the sync process, you can provide a listener here. For instance, a
|
||||
* {@link DownloadListener} is a good choice.
|
||||
*/
|
||||
public WalletAppKit setDownloadListener(PeerEventListener listener) {
|
||||
this.downloadListener = listener;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** If true, will register a shutdown hook to stop the library. Defaults to true. */
|
||||
public WalletAppKit setAutoStop(boolean autoStop) {
|
||||
this.autoStop = autoStop;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If set, the file is expected to contain a checkpoints file calculated with BuildCheckpoints. It makes initial
|
||||
* block sync faster for new users - please refer to the documentation on the bitcoinj website for further details.
|
||||
*/
|
||||
public WalletAppKit setCheckpoints(InputStream checkpoints) {
|
||||
this.checkpoints = checkpoints;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Override this to load all wallet extensions if any are necessary.</p>
|
||||
*
|
||||
@ -113,9 +142,26 @@ public class WalletAppKit extends AbstractIdleService {
|
||||
FileInputStream walletStream = null;
|
||||
try {
|
||||
File chainFile = new File(directory, filePrefix + ".spvchain");
|
||||
boolean chainFileExists = chainFile.exists();
|
||||
vWalletFile = new File(directory, filePrefix + ".wallet");
|
||||
boolean shouldReplayWallet = vWalletFile.exists() && !chainFile.exists();
|
||||
boolean shouldReplayWallet = vWalletFile.exists() && !chainFileExists;
|
||||
if (vWalletFile.exists()) {
|
||||
walletStream = new FileInputStream(vWalletFile);
|
||||
vWallet = new Wallet(params);
|
||||
addWalletExtensions(); // All extensions must be present before we deserialize
|
||||
new WalletProtobufSerializer().readWallet(WalletProtobufSerializer.parseToProto(walletStream), vWallet);
|
||||
if (shouldReplayWallet)
|
||||
vWallet.clearTransactions(0);
|
||||
} else {
|
||||
vWallet = new Wallet(params);
|
||||
vWallet.addKey(new ECKey());
|
||||
addWalletExtensions();
|
||||
}
|
||||
if (useAutoSave) vWallet.autosaveToFile(vWalletFile, 1, TimeUnit.SECONDS, null);
|
||||
vStore = new SPVBlockStore(params, chainFile);
|
||||
if (!chainFileExists && checkpoints != null) {
|
||||
CheckpointManager.checkpoint(params, checkpoints, vStore, vWallet.getEarliestKeyCreationTime());
|
||||
}
|
||||
vChain = new BlockChain(params, vStore);
|
||||
vPeerGroup = new PeerGroup(params, vChain);
|
||||
// Set up peer addresses or discovery first, so if wallet extensions try to broadcast a transaction
|
||||
@ -126,25 +172,12 @@ public class WalletAppKit extends AbstractIdleService {
|
||||
} else {
|
||||
vPeerGroup.addPeerDiscovery(new DnsDiscovery(params));
|
||||
}
|
||||
if (vWalletFile.exists()) {
|
||||
walletStream = new FileInputStream(vWalletFile);
|
||||
vWallet = new Wallet(params);
|
||||
addWalletExtensions(); // All extensions must be present before we deserialize
|
||||
new WalletProtobufSerializer().readWallet(WalletProtobufSerializer.parseToProto(walletStream), vWallet);
|
||||
if (shouldReplayWallet)
|
||||
vWallet.clearTransactions(0);
|
||||
} else {
|
||||
vWallet = new Wallet(params);
|
||||
addWalletExtensions();
|
||||
}
|
||||
if (useAutoSave) vWallet.autosaveToFile(vWalletFile, 1, TimeUnit.SECONDS, null);
|
||||
vChain.addWallet(vWallet);
|
||||
vPeerGroup.addWallet(vWallet);
|
||||
onSetupCompleted();
|
||||
vPeerGroup.startAndWait();
|
||||
vPeerGroup.downloadBlockChain();
|
||||
// Make sure we shut down cleanly.
|
||||
Runtime.getRuntime().addShutdownHook(new Thread() {
|
||||
if (autoStop) Runtime.getRuntime().addShutdownHook(new Thread() {
|
||||
@Override public void run() {
|
||||
try {
|
||||
WalletAppKit.this.stopAndWait();
|
||||
@ -153,6 +186,7 @@ public class WalletAppKit extends AbstractIdleService {
|
||||
}
|
||||
}
|
||||
});
|
||||
vPeerGroup.startBlockChainDownload(downloadListener == null ? new DownloadListener() : downloadListener);
|
||||
} catch (BlockStoreException e) {
|
||||
throw new IOException(e);
|
||||
} finally {
|
||||
|
@ -64,17 +64,8 @@ public class ForwardingService {
|
||||
// Parse the address given as the first parameter.
|
||||
forwardingAddress = new Address(params, args[0]);
|
||||
|
||||
// Start up a basic app using a class that automates some boilerplate. Ensure we always have at least one key.
|
||||
kit = new WalletAppKit(params, new File("."), filePrefix) {
|
||||
@Override
|
||||
protected void onSetupCompleted() {
|
||||
// This is called in a background thread after startAndWait is called, as setting up various objects
|
||||
// can do disk and network IO that may cause UI jank/stuttering in wallet apps if it were to be done
|
||||
// on the main thread.
|
||||
if (wallet().getKeychainSize() < 1)
|
||||
wallet().addKey(new ECKey());
|
||||
}
|
||||
};
|
||||
// Start up a basic app using a class that automates some boilerplate.
|
||||
kit = new WalletAppKit(params, new File("."), filePrefix);
|
||||
|
||||
if (params == RegTestParams.get()) {
|
||||
// Regression test mode is designed for testing and development only, so there's no public network for it.
|
||||
|
Loading…
Reference in New Issue
Block a user