diff --git a/core/src/main/java/org/bitcoinj/kits/WalletAppKit.java b/core/src/main/java/org/bitcoinj/kits/WalletAppKit.java index a7d6169f8..903e97a71 100644 --- a/core/src/main/java/org/bitcoinj/kits/WalletAppKit.java +++ b/core/src/main/java/org/bitcoinj/kits/WalletAppKit.java @@ -238,7 +238,7 @@ public class WalletAppKit extends AbstractIdleService { /** * Tests to see if the spvchain file has an operating system file lock on it. Useful for checking if your app * is already running. If another copy of your app is running and you start the appkit anyway, an exception will - * be thrown during the startup process. Returns false if the chain file does not exist. + * be thrown during the startup process. Returns false if the chain file does not exist or is a directory. */ public boolean isChainFileLocked() throws IOException { RandomAccessFile file2 = null; @@ -246,6 +246,8 @@ public class WalletAppKit extends AbstractIdleService { File file = new File(directory, filePrefix + ".spvchain"); if (!file.exists()) return false; + if (file.isDirectory()) + return false; file2 = new RandomAccessFile(file, "rw"); FileLock lock = file2.getChannel().tryLock(); if (lock == null) diff --git a/core/src/main/java/org/bitcoinj/store/LevelDBBlockStore.java b/core/src/main/java/org/bitcoinj/store/LevelDBBlockStore.java index e8dfba184..d21d4d146 100644 --- a/core/src/main/java/org/bitcoinj/store/LevelDBBlockStore.java +++ b/core/src/main/java/org/bitcoinj/store/LevelDBBlockStore.java @@ -18,7 +18,7 @@ public class LevelDBBlockStore implements BlockStore { private static final byte[] CHAIN_HEAD_KEY = "chainhead".getBytes(); private final Context context; - private final DB db; + private DB db; private final ByteBuffer buffer = ByteBuffer.allocate(StoredBlock.COMPACT_SERIALIZED_SIZE); private final File path; @@ -35,14 +35,23 @@ public class LevelDBBlockStore implements BlockStore { options.createIfMissing(); try { - db = dbFactory.open(directory, options); - initStoreIfNeeded(); + tryOpen(directory, dbFactory, options); } catch (IOException e) { - throw new BlockStoreException(e); + try { + dbFactory.repair(directory, options); + tryOpen(directory, dbFactory, options); + } catch (IOException e1) { + throw new BlockStoreException(e1); + } } } - private void initStoreIfNeeded() throws BlockStoreException { + private synchronized void tryOpen(File directory, DBFactory dbFactory, Options options) throws IOException, BlockStoreException { + db = dbFactory.open(directory, options); + initStoreIfNeeded(); + } + + private synchronized void initStoreIfNeeded() throws BlockStoreException { if (db.get(CHAIN_HEAD_KEY) != null) return; // Already initialised. Block genesis = context.getParams().getGenesisBlock().cloneAsHeader();