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.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@ -57,6 +58,9 @@ public class WalletAppKit extends AbstractIdleService {
|
|||||||
|
|
||||||
private boolean useAutoSave = true;
|
private boolean useAutoSave = true;
|
||||||
private PeerAddress[] peerAddresses;
|
private PeerAddress[] peerAddresses;
|
||||||
|
private PeerEventListener downloadListener;
|
||||||
|
private boolean autoStop = true;
|
||||||
|
private InputStream checkpoints;
|
||||||
|
|
||||||
public WalletAppKit(NetworkParameters params, File directory, String filePrefix) {
|
public WalletAppKit(NetworkParameters params, File directory, String filePrefix) {
|
||||||
this.params = checkNotNull(params);
|
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) {
|
public WalletAppKit setAutoSave(boolean value) {
|
||||||
checkState(state() == State.NEW, "Cannot call after startup");
|
checkState(state() == State.NEW, "Cannot call after startup");
|
||||||
useAutoSave = value;
|
useAutoSave = value;
|
||||||
return this;
|
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>
|
* <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;
|
FileInputStream walletStream = null;
|
||||||
try {
|
try {
|
||||||
File chainFile = new File(directory, filePrefix + ".spvchain");
|
File chainFile = new File(directory, filePrefix + ".spvchain");
|
||||||
|
boolean chainFileExists = chainFile.exists();
|
||||||
vWalletFile = new File(directory, filePrefix + ".wallet");
|
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);
|
vStore = new SPVBlockStore(params, chainFile);
|
||||||
|
if (!chainFileExists && checkpoints != null) {
|
||||||
|
CheckpointManager.checkpoint(params, checkpoints, vStore, vWallet.getEarliestKeyCreationTime());
|
||||||
|
}
|
||||||
vChain = new BlockChain(params, vStore);
|
vChain = new BlockChain(params, vStore);
|
||||||
vPeerGroup = new PeerGroup(params, vChain);
|
vPeerGroup = new PeerGroup(params, vChain);
|
||||||
// Set up peer addresses or discovery first, so if wallet extensions try to broadcast a transaction
|
// 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 {
|
} else {
|
||||||
vPeerGroup.addPeerDiscovery(new DnsDiscovery(params));
|
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);
|
vChain.addWallet(vWallet);
|
||||||
vPeerGroup.addWallet(vWallet);
|
vPeerGroup.addWallet(vWallet);
|
||||||
onSetupCompleted();
|
onSetupCompleted();
|
||||||
vPeerGroup.startAndWait();
|
vPeerGroup.startAndWait();
|
||||||
vPeerGroup.downloadBlockChain();
|
|
||||||
// Make sure we shut down cleanly.
|
// Make sure we shut down cleanly.
|
||||||
Runtime.getRuntime().addShutdownHook(new Thread() {
|
if (autoStop) Runtime.getRuntime().addShutdownHook(new Thread() {
|
||||||
@Override public void run() {
|
@Override public void run() {
|
||||||
try {
|
try {
|
||||||
WalletAppKit.this.stopAndWait();
|
WalletAppKit.this.stopAndWait();
|
||||||
@ -153,6 +186,7 @@ public class WalletAppKit extends AbstractIdleService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
vPeerGroup.startBlockChainDownload(downloadListener == null ? new DownloadListener() : downloadListener);
|
||||||
} catch (BlockStoreException e) {
|
} catch (BlockStoreException e) {
|
||||||
throw new IOException(e);
|
throw new IOException(e);
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -64,17 +64,8 @@ public class ForwardingService {
|
|||||||
// Parse the address given as the first parameter.
|
// Parse the address given as the first parameter.
|
||||||
forwardingAddress = new Address(params, args[0]);
|
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.
|
// Start up a basic app using a class that automates some boilerplate.
|
||||||
kit = new WalletAppKit(params, new File("."), filePrefix) {
|
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());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (params == RegTestParams.get()) {
|
if (params == RegTestParams.get()) {
|
||||||
// Regression test mode is designed for testing and development only, so there's no public network for it.
|
// 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