Skip to content

Commit 71c5f6b

Browse files
authored
feat: add offline option to blockstore get (#145)
Adds an `offline` option to blockstore get methods to only go to the local blockstore and not the network.
1 parent 671ec87 commit 71c5f6b

File tree

4 files changed

+32
-9
lines changed

4 files changed

+32
-9
lines changed

packages/helia/src/storage.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import createMortice from 'mortice'
2-
import type { Blocks, Pair, DeleteManyBlocksProgressEvents, DeleteBlockProgressEvents, GetBlockProgressEvents, GetManyBlocksProgressEvents, PutManyBlocksProgressEvents, PutBlockProgressEvents, GetAllBlocksProgressEvents } from '@helia/interface/blocks'
2+
import type { Blocks, Pair, DeleteManyBlocksProgressEvents, DeleteBlockProgressEvents, GetBlockProgressEvents, GetManyBlocksProgressEvents, PutManyBlocksProgressEvents, PutBlockProgressEvents, GetAllBlocksProgressEvents, GetOfflineOptions } from '@helia/interface/blocks'
33
import type { Pins } from '@helia/interface/pins'
44
import type { AbortOptions } from '@libp2p/interfaces'
55
import type { Blockstore } from 'interface-blockstore'
@@ -70,7 +70,7 @@ export class BlockStorage implements Blocks {
7070
/**
7171
* Get a block by cid
7272
*/
73-
async get (cid: CID, options: AbortOptions & ProgressOptions<GetBlockProgressEvents> = {}): Promise<Uint8Array> {
73+
async get (cid: CID, options: GetOfflineOptions & AbortOptions & ProgressOptions<GetBlockProgressEvents> = {}): Promise<Uint8Array> {
7474
const releaseLock = await this.lock.readLock()
7575

7676
try {
@@ -83,7 +83,7 @@ export class BlockStorage implements Blocks {
8383
/**
8484
* Get multiple blocks back from an (async) iterable of cids
8585
*/
86-
async * getMany (cids: AwaitIterable<CID>, options: AbortOptions & ProgressOptions<GetManyBlocksProgressEvents> = {}): AsyncIterable<Pair> {
86+
async * getMany (cids: AwaitIterable<CID>, options: GetOfflineOptions & AbortOptions & ProgressOptions<GetManyBlocksProgressEvents> = {}): AsyncIterable<Pair> {
8787
const releaseLock = await this.lock.readLock()
8888

8989
try {

packages/helia/src/utils/networked-storage.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import filter from 'it-filter'
22
import forEach from 'it-foreach'
33
import { CustomProgressEvent, type ProgressOptions } from 'progress-events'
4-
import type { Blocks, Pair, DeleteManyBlocksProgressEvents, DeleteBlockProgressEvents, GetBlockProgressEvents, GetManyBlocksProgressEvents, PutManyBlocksProgressEvents, PutBlockProgressEvents, GetAllBlocksProgressEvents } from '@helia/interface/blocks'
4+
import type { Blocks, Pair, DeleteManyBlocksProgressEvents, DeleteBlockProgressEvents, GetBlockProgressEvents, GetManyBlocksProgressEvents, PutManyBlocksProgressEvents, PutBlockProgressEvents, GetAllBlocksProgressEvents, GetOfflineOptions } from '@helia/interface/blocks'
55
import type { AbortOptions } from '@libp2p/interfaces'
66
import type { Blockstore } from 'interface-blockstore'
77
import type { AwaitIterable } from 'interface-store'
@@ -82,8 +82,8 @@ export class NetworkedStorage implements Blocks {
8282
/**
8383
* Get a block by cid
8484
*/
85-
async get (cid: CID, options: AbortOptions & ProgressOptions<GetBlockProgressEvents> = {}): Promise<Uint8Array> {
86-
if (this.bitswap?.isStarted() != null && !(await this.child.has(cid))) {
85+
async get (cid: CID, options: GetOfflineOptions & AbortOptions & ProgressOptions<GetBlockProgressEvents> = {}): Promise<Uint8Array> {
86+
if (options.offline !== true && this.bitswap?.isStarted() != null && !(await this.child.has(cid))) {
8787
options.onProgress?.(new CustomProgressEvent<CID>('blocks:get:bitswap:get', cid))
8888
const block = await this.bitswap.want(cid, options)
8989

@@ -101,11 +101,11 @@ export class NetworkedStorage implements Blocks {
101101
/**
102102
* Get multiple blocks back from an (async) iterable of cids
103103
*/
104-
async * getMany (cids: AwaitIterable<CID>, options: AbortOptions & ProgressOptions<GetManyBlocksProgressEvents> = {}): AsyncIterable<Pair> {
104+
async * getMany (cids: AwaitIterable<CID>, options: GetOfflineOptions & AbortOptions & ProgressOptions<GetManyBlocksProgressEvents> = {}): AsyncIterable<Pair> {
105105
options.onProgress?.(new CustomProgressEvent('blocks:get-many:blockstore:get-many'))
106106

107107
yield * this.child.getMany(forEach(cids, async (cid): Promise<void> => {
108-
if (this.bitswap?.isStarted() === true && !(await this.child.has(cid))) {
108+
if (options.offline !== true && this.bitswap?.isStarted() === true && !(await this.child.has(cid))) {
109109
options.onProgress?.(new CustomProgressEvent<CID>('blocks:get-many:bitswap:get', cid))
110110
const block = await this.bitswap.want(cid, options)
111111
options.onProgress?.(new CustomProgressEvent<CID>('blocks:get-many:blockstore:put', cid))

packages/helia/test/utils/networked-storage.spec.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@ describe('storage', () => {
4242
expect(retrieved).to.equalBytes(block)
4343
})
4444

45+
it('gets a block from the blockstore offline', async () => {
46+
const { cid } = blocks[0]
47+
48+
await expect(storage.get(cid, {
49+
offline: true
50+
})).to.eventually.be.rejected.with.property('code', 'ERR_NOT_FOUND')
51+
})
52+
4553
it('gets a block from the blockstore with progress', async () => {
4654
const { cid, block } = blocks[0]
4755
await blockstore.put(cid, block)
@@ -72,6 +80,14 @@ describe('storage', () => {
7280
expect(retrieved).to.deep.equal(new Array(count).fill(0).map((_, i) => blocks[i]))
7381
})
7482

83+
it('gets many blocks from the blockstore offline', async () => {
84+
const { cid } = blocks[0]
85+
86+
await expect(drain(storage.getMany([cid], {
87+
offline: true
88+
}))).to.eventually.be.rejected.with.property('code', 'ERR_NOT_FOUND')
89+
})
90+
7591
it('puts a block into the blockstore', async () => {
7692
const { cid, block } = blocks[0]
7793
await storage.put(cid, block)

packages/interface/src/blocks.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,16 @@ export type DeleteBlockProgressEvents =
4747
export type DeleteManyBlocksProgressEvents =
4848
ProgressEvent<'blocks:delete-many:blockstore:delete-many'>
4949

50+
export interface GetOfflineOptions {
51+
/**
52+
* If true, do not attempt to fetch any missing blocks from the network (default: false)
53+
*/
54+
offline?: boolean
55+
}
56+
5057
export interface Blocks extends Blockstore<ProgressOptions<HasBlockProgressEvents>,
5158
ProgressOptions<PutBlockProgressEvents>, ProgressOptions<PutManyBlocksProgressEvents>,
52-
ProgressOptions<GetBlockProgressEvents>, ProgressOptions<GetManyBlocksProgressEvents>, ProgressOptions<GetAllBlocksProgressEvents>,
59+
GetOfflineOptions & ProgressOptions<GetBlockProgressEvents>, GetOfflineOptions & ProgressOptions<GetManyBlocksProgressEvents>, ProgressOptions<GetAllBlocksProgressEvents>,
5360
ProgressOptions<DeleteBlockProgressEvents>, ProgressOptions<DeleteManyBlocksProgressEvents>
5461
> {
5562

0 commit comments

Comments
 (0)