diff --git a/core/src/main/java/org/bitcoinj/kits/WalletAppKit.java b/core/src/main/java/org/bitcoinj/kits/WalletAppKit.java index ac5c21aa6..15818437d 100644 --- a/core/src/main/java/org/bitcoinj/kits/WalletAppKit.java +++ b/core/src/main/java/org/bitcoinj/kits/WalletAppKit.java @@ -69,7 +69,7 @@ public class WalletAppKit extends AbstractIdleService { protected final KeyChainGroupStructure structure; protected final String filePrefix; protected volatile BlockChain vChain; - protected volatile BlockStore vStore; + protected volatile SPVBlockStore vStore; protected volatile Wallet vWallet; protected volatile PeerGroup vPeerGroup; @@ -245,13 +245,6 @@ public class WalletAppKit extends AbstractIdleService { return ImmutableList.of(); } - /** - * Override this to use a {@link BlockStore} that isn't the default of {@link SPVBlockStore}. - */ - protected BlockStore provideBlockStore(File file) throws BlockStoreException { - return new SPVBlockStore(params, file); - } - /** * This method is invoked on a background thread after all objects are initialised, but before the peer group * or block chain download is started. You can tweak the objects configuration here. @@ -301,7 +294,7 @@ public class WalletAppKit extends AbstractIdleService { vWallet = createOrLoadWallet(shouldReplayWallet); // Initiate Bitcoin network objects (block store, blockchain and peer group) - vStore = provideBlockStore(chainFile); + vStore = new SPVBlockStore(params, chainFile); if (!chainFileExists || restoreFromSeed != null || restoreFromKey != null) { if (checkpoints == null && !Utils.isAndroidRuntime()) { checkpoints = CheckpointManager.openStream(params); @@ -313,20 +306,14 @@ public class WalletAppKit extends AbstractIdleService { if (restoreFromSeed != null) { time = restoreFromSeed.getCreationTimeSeconds(); if (chainFileExists) { - log.info("Deleting the chain file in preparation from restore."); - vStore.close(); - if (!chainFile.delete()) - throw new IOException("Failed to delete chain file in preparation for restore."); - vStore = provideBlockStore(chainFile); + log.info("Clearing the chain file in preparation for restore."); + vStore.clear(); } } else if (restoreFromKey != null) { time = restoreFromKey.getCreationTimeSeconds(); if (chainFileExists) { - log.info("Deleting the chain file in preparation from restore."); - vStore.close(); - if (!chainFile.delete()) - throw new IOException("Failed to delete chain file in preparation for restore."); - vStore = provideBlockStore(chainFile); + log.info("Clearing the chain file in preparation for restore."); + vStore.clear(); } } else @@ -338,11 +325,8 @@ public class WalletAppKit extends AbstractIdleService { else log.warn("Creating a new uncheckpointed block store due to a wallet with a creation time of zero: this will result in a very slow chain sync"); } else if (chainFileExists) { - log.info("Deleting the chain file in preparation from restore."); - vStore.close(); - if (!chainFile.delete()) - throw new IOException("Failed to delete chain file in preparation for restore."); - vStore = provideBlockStore(chainFile); + log.info("Clearing the chain file in preparation for restore."); + vStore.clear(); } } vChain = new BlockChain(params, vStore); diff --git a/core/src/main/java/org/bitcoinj/store/SPVBlockStore.java b/core/src/main/java/org/bitcoinj/store/SPVBlockStore.java index f53ddc244..1dab81743 100644 --- a/core/src/main/java/org/bitcoinj/store/SPVBlockStore.java +++ b/core/src/main/java/org/bitcoinj/store/SPVBlockStore.java @@ -326,4 +326,22 @@ public class SPVBlockStore implements BlockStore { checkArgument(newCursor >= 0); buffer.putInt(4, newCursor); } + + public void clear() throws Exception { + lock.lock(); + try { + // Clear caches + blockCache.clear(); + notFoundCache.clear(); + // Clear file content + buffer.position(0); + long fileLength = randomAccessFile.length(); + for (int i = 0; i < fileLength; i++) { + buffer.put((byte)0); + } + // Initialize store again + buffer.position(0); + initNewStore(params); + } finally { lock.unlock(); } + } } diff --git a/core/src/test/java/org/bitcoinj/store/SPVBlockStoreTest.java b/core/src/test/java/org/bitcoinj/store/SPVBlockStoreTest.java index d38846c5d..70f51db20 100644 --- a/core/src/test/java/org/bitcoinj/store/SPVBlockStoreTest.java +++ b/core/src/test/java/org/bitcoinj/store/SPVBlockStoreTest.java @@ -19,6 +19,7 @@ package org.bitcoinj.store; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertNull; import java.io.File; import java.math.BigInteger; @@ -146,4 +147,21 @@ public class SPVBlockStoreTest { watch.elapsed(TimeUnit.MILLISECONDS) < THRESHOLD_MS); store.close(); } + + @Test + public void clear() throws Exception { + SPVBlockStore store = new SPVBlockStore(UNITTEST, blockStoreFile); + + // Build a new block. + Address to = LegacyAddress.fromKey(UNITTEST, new ECKey()); + StoredBlock genesis = store.getChainHead(); + StoredBlock b1 = genesis.build(genesis.getHeader().createNextBlock(to).cloneAsHeader()); + store.put(b1); + store.setChainHead(b1); + assertEquals(b1.getHeader().getHash(), store.getChainHead().getHeader().getHash()); + store.clear(); + assertNull(store.get(b1.getHeader().getHash())); + assertEquals(UNITTEST.getGenesisBlock().getHash(), store.getChainHead().getHeader().getHash()); + store.close(); + } }