From 576650142c498f54f935770e7fdaf38b6b6f3de2 Mon Sep 17 00:00:00 2001 From: Miron Cuperman Date: Fri, 23 Mar 2012 12:53:54 -0700 Subject: [PATCH] Lock in BOBS on creation, do not swallow non-IO exceptions --- .../store/BoundedOverheadBlockStore.java | 35 +++++++++++-------- .../store/BoundedOverheadBlockStoreTest.java | 19 ++++++++++ 2 files changed, 39 insertions(+), 15 deletions(-) diff --git a/core/src/main/java/com/google/bitcoin/store/BoundedOverheadBlockStore.java b/core/src/main/java/com/google/bitcoin/store/BoundedOverheadBlockStore.java index 28f9acf3..7669ecb6 100644 --- a/core/src/main/java/com/google/bitcoin/store/BoundedOverheadBlockStore.java +++ b/core/src/main/java/com/google/bitcoin/store/BoundedOverheadBlockStore.java @@ -152,7 +152,7 @@ public class BoundedOverheadBlockStore implements BlockStore { try { load(file); return; - } catch (Exception e) { + } catch (IOException e) { log.error("Failed to load block chain from " + file, e); // Fall through and try to create a new one. } @@ -172,6 +172,7 @@ public class BoundedOverheadBlockStore implements BlockStore { // Create fresh. The d makes writes synchronous. this.file = new RandomAccessFile(file, "rwd"); this.channel = this.file.getChannel(); + lock(); this.file.write(FILE_FORMAT_VERSION); } catch (IOException e1) { // We could not load a block store nor could we create a new one! @@ -195,21 +196,9 @@ public class BoundedOverheadBlockStore implements BlockStore { log.info("Reading block store from {}", file); // Open in synchronous mode. See above. this.file = new RandomAccessFile(file, "rwd"); + channel = this.file.getChannel(); + lock(); try { - lock = this.file.getChannel().tryLock(); - } catch (OverlappingFileLockException e) { - lock = null; - } - if (lock == null) { - try { - this.file.close(); - } finally { - this.file = null; - } - throw new BlockStoreException("Could not lock file"); - } - try { - channel = this.file.getChannel(); // Read a version byte. int version = this.file.read(); if (version == -1) { @@ -235,6 +224,22 @@ public class BoundedOverheadBlockStore implements BlockStore { } } + private void lock() throws IOException, BlockStoreException { + try { + lock = channel.tryLock(); + } catch (OverlappingFileLockException e) { + lock = null; + } + if (lock == null) { + try { + this.file.close(); + } finally { + this.file = null; + } + throw new BlockStoreException("Could not lock file"); + } + } + private void ensureOpen() throws BlockStoreException { if (file == null) { throw new BlockStoreException("BlockStore was closed"); diff --git a/core/src/test/java/com/google/bitcoin/store/BoundedOverheadBlockStoreTest.java b/core/src/test/java/com/google/bitcoin/store/BoundedOverheadBlockStoreTest.java index b56fcc3f..15e19065 100644 --- a/core/src/test/java/com/google/bitcoin/store/BoundedOverheadBlockStoreTest.java +++ b/core/src/test/java/com/google/bitcoin/store/BoundedOverheadBlockStoreTest.java @@ -24,6 +24,7 @@ import org.junit.Test; import java.io.File; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; public class BoundedOverheadBlockStoreTest { @Test @@ -43,6 +44,8 @@ public class BoundedOverheadBlockStoreTest { StoredBlock b1 = genesis.build(genesis.getHeader().createNextBlock(to).cloneAsHeader()); store.put(b1); store.setChainHead(b1); + store.close(); + // Check we can get it back out again if we rebuild the store object. store = new BoundedOverheadBlockStore(params, temp); StoredBlock b2 = store.get(b1.getHeader().getHash()); @@ -50,4 +53,20 @@ public class BoundedOverheadBlockStoreTest { // Check the chain head was stored correctly also. assertEquals(b1, store.getChainHead()); } + + @Test + public void testLocking() throws Exception { + File temp = File.createTempFile("bitcoinj-test", null, null); + System.out.println(temp.getAbsolutePath()); + temp.deleteOnExit(); + + NetworkParameters params = NetworkParameters.unitTests(); + BoundedOverheadBlockStore store = new BoundedOverheadBlockStore(params, temp); + try { + BoundedOverheadBlockStore store1 = new BoundedOverheadBlockStore(params, temp); + fail(); + } catch (BlockStoreException e) { + // Expected + } + } }