From abd2ae4b5d8128ed7aae5b697ea14242512d20f4 Mon Sep 17 00:00:00 2001 From: Braydon Fuller Date: Thu, 28 Feb 2019 11:04:46 -0800 Subject: [PATCH] blockstore: prevent blocks writes at the same position --- lib/blockstore/file.js | 9 +++++++++ test/blockstore-test.js | 25 +++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/lib/blockstore/file.js b/lib/blockstore/file.js index 231dc573..e735b442 100644 --- a/lib/blockstore/file.js +++ b/lib/blockstore/file.js @@ -45,6 +45,8 @@ class FileBlockStore extends AbstractBlockStore { if (options.network != null) this.network = Network.get(options.network); + + this.writing = false; } /** @@ -231,6 +233,11 @@ class FileBlockStore extends AbstractBlockStore { */ async write(hash, data) { + if (this.writing) + throw new Error('Already writing.'); + + this.writing = true; + const mlength = 8; const blength = data.length; const length = data.length + mlength; @@ -280,6 +287,8 @@ class FileBlockStore extends AbstractBlockStore { b.put(layout.R.encode(), bw.writeU32(fileno).render()); await b.write(); + + this.writing = false; } /** diff --git a/test/blockstore-test.js b/test/blockstore-test.js index 53043516..a7bea129 100644 --- a/test/blockstore-test.js +++ b/test/blockstore-test.js @@ -477,6 +477,31 @@ describe('BlockStore', function() { } }); + it('will not write blocks at the same position', (done) => { + let err = null; + let finished = 0; + + for (let i = 0; i < 16; i++) { + const block = random.randomBytes(128); + const hash = random.randomBytes(32); + + // Accidently don't use `await` and attempt to + // write multiple blocks in parallel and at the + // same file position. + const promise = store.write(hash, block); + promise.catch((e) => { + err = e; + }).finally(() => { + finished += 1; + if (finished >= 16) { + assert(err); + assert(err.message, 'Already writing.'); + done(); + } + }); + } + }); + it('will return null if block not found', async () => { const hash = random.randomBytes(32); const block = await store.read(hash);