WalletAppKit: we need a stupid hack to make checkpointing and payment channels work together.

Apparently this simple utility class might start to need unit tests now!

To resolve the hack, we need to resolve some circularity in construction: to add the payment channels wallet extensions requires the peerGroup and wallet object to be constructed, but to construct the peerGroup requires the chain+store and to checkpoint a fresh store requires the wallet. Catch 22! We resolve by loading a temp wallet and then throwing it away, which is inefficient for a large wallet that's being replayed but normally shouldn't matter.

Once the payment channels stuff is more mature and tested, we might want to just fold it into the core wallet format.
This commit is contained in:
Mike Hearn 2013-09-21 21:03:36 +02:00
parent 324f603cbe
commit c587f2c442

View File

@ -168,14 +168,26 @@ public class WalletAppKit extends AbstractIdleService {
try {
File chainFile = new File(directory, filePrefix + ".spvchain");
boolean chainFileExists = chainFile.exists();
vWalletFile = new File(directory, filePrefix + ".wallet");
boolean shouldReplayWallet = vWalletFile.exists() && !chainFileExists;
vStore = new SPVBlockStore(params, chainFile);
if (!chainFileExists && checkpoints != null) {
CheckpointManager.checkpoint(params, checkpoints, vStore, vWallet.getEarliestKeyCreationTime());
// Ugly hack! We have to create the wallet once here to learn the earliest key time, and then throw it
// away. The reason is that wallet extensions might need access to peergroups/chains/etc so we have to
// create the wallet later, but we need to know the time early here before we create the BlockChain
// object.
long time = Long.MAX_VALUE;
if (vWalletFile.exists()) {
Wallet wallet = new Wallet(params);
FileInputStream stream = new FileInputStream(vWalletFile);
new WalletProtobufSerializer().readWallet(WalletProtobufSerializer.parseToProto(stream), wallet);
time = wallet.getEarliestKeyCreationTime();
}
CheckpointManager.checkpoint(params, checkpoints, vStore, time);
}
vChain = new BlockChain(params, vStore);
vPeerGroup = new PeerGroup(params, vChain);
vWalletFile = new File(directory, filePrefix + ".wallet");
boolean shouldReplayWallet = vWalletFile.exists() && !chainFileExists;
if (vWalletFile.exists()) {
walletStream = new FileInputStream(vWalletFile);
vWallet = new Wallet(params);