From a7a7516717144c55b1c55eb1e780594293b23b72 Mon Sep 17 00:00:00 2001 From: Irakli Gozalishvili Date: Wed, 19 Jul 2023 11:16:59 -0700 Subject: [PATCH] chore: consolidate constants --- src/constant.js | 46 +++++++++++++++++++++++++++++++++++ src/fr32.js | 49 +++++++------------------------------- src/lib.js | 1 + src/multihash.js | 9 ++----- src/node.js | 3 ++- src/piece.js | 13 +++++----- src/piece/padded-size.js | 15 +++++++----- src/piece/unpadded-size.js | 19 ++++++++------- 8 files changed, 86 insertions(+), 69 deletions(-) create mode 100644 src/constant.js diff --git a/src/constant.js b/src/constant.js new file mode 100644 index 0000000..94d1786 --- /dev/null +++ b/src/constant.js @@ -0,0 +1,46 @@ +/** + * Number of bits per byte + */ +const BITS_PER_BYTE = 8 + +/** + * The number of Frs per Block. + */ +export const FRS_PER_QUAD = 4 + +/** + * The amount of bits in an Fr when not padded. + */ +export const IN_BITS_FR = 254 +/** + * The amount of bits in an Fr when padded. + */ +export const OUT_BITS_FR = 256 + +export const IN_BYTES_PER_QUAD = + /** @type {127} */ + ((FRS_PER_QUAD * IN_BITS_FR) / BITS_PER_BYTE) + +export const OUT_BYTES_PER_QUAD = + /** @type {128} */ + ((FRS_PER_QUAD * OUT_BITS_FR) / BITS_PER_BYTE) + +export const BYTES_PER_FR = + /** @type {32} */ + OUT_BYTES_PER_QUAD / FRS_PER_QUAD + +export const FR_RATIO = IN_BITS_FR / OUT_BITS_FR + +/** + * Size of a node in the merkle tree. + */ +export const NODE_SIZE = + /** @type {32} */ + (OUT_BYTES_PER_QUAD / FRS_PER_QUAD) + +/** + * The smallest amount of data for which FR32 padding has a defined result. + * Silently upgrading 2 leaves to 4 would break the symmetry so we require + * an extra byte and the rest can be 0 padded to expand to 4 leaves. + */ +export const MIN_PAYLOAD_SIZE = 2 * NODE_SIZE + 1 diff --git a/src/fr32.js b/src/fr32.js index b9a9d1d..c454505 100644 --- a/src/fr32.js +++ b/src/fr32.js @@ -1,52 +1,21 @@ import * as API from './api.js' - -/** - * The smallest amount of data for which FR32 padding has a defined result. - */ -export const MIN_PIECE_SIZE = 65 - -/** - * Number of bits per byte - */ -const BITS_PER_BYTE = 8 - -/** - * The number of Frs per Block. - */ -const FRS_PER_QUAD = 4 -/** - * The amount of bits in an Fr when not padded. - */ -const IN_BITS_FR = 254 -/** - * The amount of bits in an Fr when padded. - */ -const OUT_BITS_FR = 256 - -export const IN_BYTES_PER_QUAD = - /** @type {127} */ - ((FRS_PER_QUAD * IN_BITS_FR) / BITS_PER_BYTE) - -export const OUT_BYTES_PER_QUAD = - /** @type {128} */ - ((FRS_PER_QUAD * OUT_BITS_FR) / BITS_PER_BYTE) - -export const BYTES_PER_FR = - /** @type {32} */ - OUT_BYTES_PER_QUAD / FRS_PER_QUAD - -export const FR_RATIO = IN_BITS_FR / OUT_BITS_FR +import { + OUT_BYTES_PER_QUAD, + FR_RATIO, + IN_BYTES_PER_QUAD, + MIN_PAYLOAD_SIZE, +} from './constant.js' /** * Determine the additional bytes of zeroed padding to append to the * end of a resource of `size` length in order to fit within a pow2 piece while * leaving enough room for Fr32 padding (2 bits per 254). * - * @param {number} sourceSize - The size of the original resource + * @param {number} payloadSize - The size of the payload. * @returns {number} */ -export function toZeroPaddedSize(sourceSize) { - const size = Math.max(sourceSize, MIN_PIECE_SIZE) +export function toZeroPaddedSize(payloadSize) { + const size = Math.max(payloadSize, MIN_PAYLOAD_SIZE) const highestBit = Math.floor(Math.log2(size)) const bound = Math.ceil(FR_RATIO * 2 ** (highestBit + 1)) diff --git a/src/lib.js b/src/lib.js index e67033f..89f81b8 100644 --- a/src/lib.js +++ b/src/lib.js @@ -1,4 +1,5 @@ export * from './api.js' +export * from './constant.js' export * as API from './api.js' export * as Node from './node.js' export * as Proof from './proof.js' diff --git a/src/multihash.js b/src/multihash.js index 5aa04d7..06cfd77 100644 --- a/src/multihash.js +++ b/src/multihash.js @@ -1,14 +1,9 @@ import * as API from './api.js' -import { - IN_BYTES_PER_QUAD, - OUT_BYTES_PER_QUAD, - FR_RATIO, - pad, - MIN_PIECE_SIZE, -} from './fr32.js' +import { IN_BYTES_PER_QUAD, FR_RATIO, MIN_PAYLOAD_SIZE } from './constant.js' import * as ZeroPad from './zero-comm.js' import * as Proof from './proof.js' import { split } from './piece/tree.js' +import { pad } from './fr32.js' export const name = /** @type {const} */ ( 'fr32-sha2-256-trunc254-padded-binary-tree' diff --git a/src/node.js b/src/node.js index f0ea980..5c3edf8 100644 --- a/src/node.js +++ b/src/node.js @@ -1,6 +1,7 @@ import * as API from './api.js' +import { NODE_SIZE as Size } from './constant.js' -export const Size = 32 +export { Size } /** * @param {number[]} bytes diff --git a/src/piece.js b/src/piece.js index 58943e2..6860f33 100644 --- a/src/piece.js +++ b/src/piece.js @@ -1,12 +1,11 @@ import * as API from './api.js' import * as Fr32 from './fr32.js' -import { Size as NodeSize } from './node.js' import * as Digest from 'multiformats/hashes/digest' import * as Link from 'multiformats/link' import * as Tree from './piece/tree.js' import * as UnpaddedSize from './piece/unpadded-size.js' import * as PaddedSize from './piece/padded-size.js' -import { log2Ceil } from './uint64.js' +import { FR_RATIO, NODE_SIZE, MIN_PAYLOAD_SIZE } from './constant.js' export { Tree } @@ -24,12 +23,12 @@ export const FilCommitmentUnsealed = 0xf101 * Current maximum piece size is limited by the maximum number of leaves in the * tree, which is limited by max size of the JS array, which is 128GiB. */ -export const MAX_PIECE_SIZE = Tree.MAX_LEAF_COUNT * NodeSize +export const MAX_PIECE_SIZE = Tree.MAX_LEAF_COUNT * NODE_SIZE /** * The maximum amount of data that one can compute for the piece. */ -export const MAX_PAYLOAD_SIZE = (MAX_PIECE_SIZE / 128) * 127 +export const MAX_PAYLOAD_SIZE = MAX_PIECE_SIZE * FR_RATIO export { UnpaddedSize, PaddedSize } @@ -47,7 +46,7 @@ class PieceInfo { this.height = height } get size() { - return 2n ** BigInt(this.height) * BigInt(NodeSize) + return 2n ** BigInt(this.height) * BigInt(NODE_SIZE) } toJSON() { return toJSON(this) @@ -123,9 +122,9 @@ export const createLink = (root) => * @returns {API.Piece} */ export const build = (source) => { - if (source.length < Fr32.MIN_PIECE_SIZE) { + if (source.length < MIN_PAYLOAD_SIZE) { throw new RangeError( - `Piece is not defined for payloads smaller than ${Fr32.MIN_PIECE_SIZE} bytes` + `Piece is not defined for payloads smaller than ${MIN_PAYLOAD_SIZE} bytes` ) } diff --git a/src/piece/padded-size.js b/src/piece/padded-size.js index 5a1d5ee..b7e8efd 100644 --- a/src/piece/padded-size.js +++ b/src/piece/padded-size.js @@ -1,8 +1,9 @@ import * as API from '../api.js' import { onesCount64, log2Ceil } from '../uint64.js' -import * as Node from '../node.js' +import { OUT_BYTES_PER_QUAD, NODE_SIZE } from '../constant.js' -const NODE_SIZE = BigInt(Node.Size) +const BYTES_PER_NODE = BigInt(NODE_SIZE) +const BYTES_PER_QUAD = BigInt(OUT_BYTES_PER_QUAD) /** * Validates that given `size` is a valid {@link API.PaddedPieceSize} and @@ -34,8 +35,10 @@ export const from = (size) => { * @returns {API.Result} */ export const validate = (size) => { - if (size < 128) { - return { error: RangeError('minimum padded piece size is 128 bytes') } + if (size < BYTES_PER_QUAD) { + return { + error: RangeError(`minimum padded piece size is ${BYTES_PER_QUAD} bytes`), + } } if (onesCount64(size) !== 1) { @@ -50,11 +53,11 @@ export const validate = (size) => { * @param {API.PaddedPieceSize} size * @returns {API.UnpaddedPieceSize} */ -export const toUnpaddedSize = (size) => size - size / 128n +export const toUnpaddedSize = (size) => size - size / BYTES_PER_QUAD /** * Calculates the height of the piece tree from unpadded size. * * @param {API.PaddedPieceSize} size */ -export const toHeight = (size) => log2Ceil(size / NODE_SIZE) +export const toHeight = (size) => log2Ceil(size / BYTES_PER_NODE) diff --git a/src/piece/unpadded-size.js b/src/piece/unpadded-size.js index dce3c6f..2bcf97c 100644 --- a/src/piece/unpadded-size.js +++ b/src/piece/unpadded-size.js @@ -1,8 +1,9 @@ import * as API from '../api.js' import { trailingZeros64, log2Ceil } from '../uint64.js' -import * as Node from '../node.js' +import { IN_BYTES_PER_QUAD, NODE_SIZE } from '../constant.js' -const NODE_SIZE = BigInt(Node.Size) +const BYTES_PER_NODE = BigInt(NODE_SIZE) +const BYTES_PER_QUAD = BigInt(IN_BYTES_PER_QUAD) /** * Validates that given `size` is a valid {@link API.UnpaddedPieceSize} and @@ -33,14 +34,16 @@ export const from = (size) => { * @returns {API.Result} */ export const validate = (size) => { - if (size < 127) { - return { error: new Error('Minimum piece size is 127 bytes') } + if (size < BYTES_PER_QUAD) { + return { + error: new Error(`Minimum piece size is ${BYTES_PER_QUAD} bytes`), + } } - if (size >> BigInt(trailingZeros64(size)) !== 127n) { + if (size >> BigInt(trailingZeros64(size)) !== BYTES_PER_QUAD) { return { error: new Error( - `Unpadded piece size must be a power of 2 multiple of 127, got ${size} instead` + `Unpadded piece size must be a power of 2 multiple of ${BYTES_PER_QUAD}, got ${size} instead` ), } } @@ -62,11 +65,11 @@ export const validate = (size) => { * @param {API.UnpaddedPieceSize} size * @returns {API.PaddedPieceSize} */ -export const toPaddedSize = (size) => size + size / 127n +export const toPaddedSize = (size) => size + size / BYTES_PER_QUAD /** * Calculates the height of the piece tree from unpadded size. * * @param {API.UnpaddedPieceSize} size */ -export const toHeight = (size) => log2Ceil(toPaddedSize(size) / NODE_SIZE) +export const toHeight = (size) => log2Ceil(toPaddedSize(size) / BYTES_PER_NODE)