From 91c28cb08b5b569f52eb33f8b22cf21b02778bdb Mon Sep 17 00:00:00 2001 From: Igor Shadurin Date: Fri, 20 Oct 2023 14:08:50 +0300 Subject: [PATCH] feat: enforce minimum block size for data upload --- src/content-items/handler.ts | 7 ++++++- src/file/handler.ts | 5 +++-- src/utils/bytes.ts | 12 ++++++++++++ test/integration/node/upload-by-index.spec.ts | 6 ++++++ 4 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/content-items/handler.ts b/src/content-items/handler.ts index 62e0bffe..4cc4776c 100644 --- a/src/content-items/handler.ts +++ b/src/content-items/handler.ts @@ -14,8 +14,13 @@ import { PodPasswordBytes } from '../utils/encryption' import { DataUploadOptions } from '../file/types' import { getNextEpoch } from '../feed/lookup/utils' +/** + * Minimum block size for uploading data + */ +export const MINIMUM_BLOCK_SIZE = 1000000 + export const DEFAULT_UPLOAD_OPTIONS: DataUploadOptions = { - blockSize: 1000000, + blockSize: MINIMUM_BLOCK_SIZE, contentType: '', } diff --git a/src/file/handler.ts b/src/file/handler.ts index 1ef23be6..eb55d6d3 100644 --- a/src/file/handler.ts +++ b/src/file/handler.ts @@ -1,4 +1,4 @@ -import { stringToBytes, wrapBytesWithHelpers } from '../utils/bytes' +import { assertMinLength, stringToBytes, wrapBytesWithHelpers } from '../utils/bytes' import { Bee, Data, BeeRequestOptions } from '@ethersphere/bee-js' import { EthAddress } from '@ethersphere/bee-js/dist/types/utils/eth' import { @@ -33,7 +33,7 @@ import { } from './types' import { assertPodName, getExtendedPodsListByAccountData, META_VERSION } from '../pod/utils' import { getUnixTimestamp } from '../utils/time' -import { addEntryToDirectory, DEFAULT_UPLOAD_OPTIONS } from '../content-items/handler' +import { addEntryToDirectory, DEFAULT_UPLOAD_OPTIONS, MINIMUM_BLOCK_SIZE } from '../content-items/handler' import { writeFeedData } from '../feed/api' import { AccountData } from '../account/account-data' import { prepareEthAddress } from '../utils/wallet' @@ -191,6 +191,7 @@ export async function uploadData( assertWallet(accountData.wallet) const blockSize = options.blockSize ?? Number(DEFAULT_UPLOAD_OPTIONS!.blockSize) + assertMinLength(blockSize, MINIMUM_BLOCK_SIZE, `Block size is too small. Minimum is ${MINIMUM_BLOCK_SIZE} bytes.`) const contentType = options.contentType ?? String(DEFAULT_UPLOAD_OPTIONS!.contentType) const connection = accountData.connection updateUploadProgress(options, UploadProgressType.GetPodInfo) diff --git a/src/utils/bytes.ts b/src/utils/bytes.ts index e18aa3b4..f7b90297 100644 --- a/src/utils/bytes.ts +++ b/src/utils/bytes.ts @@ -124,6 +124,18 @@ export function wordArrayToBytes(data: CryptoJS.lib.WordArray): Uint8Array { return Utils.hexToBytes(CryptoJS.enc.Hex.stringify(data)) } +/** + * Asserts that length is greater than or equal to min length + * @param currentLength current length + * @param minLength min length + * @param customMessage custom error message + */ +export function assertMinLength(currentLength: number, minLength: number, customMessage?: string): void { + if (currentLength < minLength) { + throw new Error(customMessage ? customMessage : `length ${currentLength} is less than min length ${minLength}`) + } +} + /** * Asserts that length is less than or equal to max length * @param currentLength currentLength diff --git a/test/integration/node/upload-by-index.spec.ts b/test/integration/node/upload-by-index.spec.ts index cefdb8b3..6e5c3f14 100644 --- a/test/integration/node/upload-by-index.spec.ts +++ b/test/integration/node/upload-by-index.spec.ts @@ -1,6 +1,7 @@ import { createFdp, generateRandomHexString, generateUser, makeFileContent } from '../../utils' import { wrapBytesWithHelpers } from '../../../src/utils/bytes' import { getDataBlock } from '../../../src' +import { MINIMUM_BLOCK_SIZE } from '../../../src/content-items/handler' jest.setTimeout(400000) it('Upload by index', async () => { @@ -24,6 +25,11 @@ it('Upload by index', async () => { await expect(fdp.file.uploadData(pod, fullPath, mixedBlocks)).rejects.toThrow( 'The sequence of `ExternalDataBlock` is not correctly indexed.', ) + await expect( + fdp.file.uploadData(pod, fullPath, mixedBlocks, { + blockSize: 100, + }), + ).rejects.toThrow(`Block size is too small. Minimum is ${MINIMUM_BLOCK_SIZE} bytes.`) const fileMeta = await fdp.file.uploadData(pod, fullPath, blocks) expect(fileMeta.fileName).toEqual(filename)