{"version":3,"file":"index.mjs","names":[],"sources":["../../src/utils/index.ts"],"sourcesContent":["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { fromBase64, toBase64 } from '@mysten/bcs';\nimport type { InferBcsType } from '@mysten/bcs';\nimport type { SuiMoveNormalizedType } from '@mysten/sui/jsonRpc';\n\nimport type { Committee } from '../contracts/walrus/committee.js';\nimport type { EncodingType } from '../types.js';\nimport { BlobId } from './bcs.js';\n\nconst DIGEST_LEN = 32;\nconst BLOB_ID_LEN = 32;\n\nexport const REQUIRED_ALIGNMENT_BY_ENCODING_TYPE = {\n\tRS2: 2,\n\tRedStuff: 2,\n};\n\nexport const MAX_SYMBOL_SIZE_BY_ENCODING_TYPE = {\n\tRS2: 2 ** 16 - 1,\n\tRedStuff: 2 ** 16 - 1,\n};\n\nexport function encodedBlobLength(\n\tunencodedLength: number,\n\tnShards: number,\n\tencodingType: EncodingType = 'RS2',\n): number {\n\tconst sliverSize = encodedSliverSize(unencodedLength, nShards, encodingType);\n\tconst metadata = nShards * DIGEST_LEN * 2 + BLOB_ID_LEN;\n\treturn nShards * metadata + sliverSize;\n}\n\nexport function encodedSliverSize(\n\tunencodedLength: number,\n\tnShards: number,\n\tencodingType: EncodingType = 'RS2',\n): number {\n\tconst { primarySymbols, secondarySymbols } = getSourceSymbols(nShards, encodingType);\n\n\tlet symbolSize =\n\t\tMath.floor((Math.max(unencodedLength, 1) - 1) / (primarySymbols * secondarySymbols)) + 1;\n\n\tif (encodingType === 'RS2' && symbolSize % 2 === 1) {\n\t\tsymbolSize = symbolSize + 1;\n\t}\n\n\tconst singleShardSize = (primarySymbols + secondarySymbols) * symbolSize;\n\n\treturn singleShardSize * nShards;\n}\n\nexport function getSourceSymbols(nShards: number, encodingType: EncodingType = 'RS2') {\n\tconst safetyLimit = decodingSafetyLimit(nShards, encodingType);\n\tconst maxFaulty = getMaxFaultyNodes(nShards);\n\tconst minCorrect = nShards - maxFaulty;\n\n\treturn {\n\t\tprimarySymbols: minCorrect - maxFaulty - safetyLimit,\n\t\tsecondarySymbols: minCorrect - safetyLimit,\n\t};\n}\n\nexport function isQuorum(size: number, nShards: number): boolean {\n\tconst maxFaulty = getMaxFaultyNodes(nShards);\n\treturn size > 2 * maxFaulty;\n}\n\nexport function isAboveValidity(size: number, nShards: number): boolean {\n\tconst maxFaulty = getMaxFaultyNodes(nShards);\n\treturn size > maxFaulty;\n}\n\nexport function getMaxFaultyNodes(nShards: number): number {\n\treturn Math.floor((nShards - 1) / 3);\n}\n\nfunction decodingSafetyLimit(nShards: number, encodingType: EncodingType): number {\n\tswitch (encodingType) {\n\t\tcase 'RedStuff':\n\t\t\treturn Math.min(5, Math.floor(getMaxFaultyNodes(nShards) / 5));\n\t\tcase 'RS2':\n\t\t\treturn 0;\n\t\tdefault:\n\t\t\tthrow new Error(`Encountered unknown encoding type of ${encodingType}`);\n\t}\n}\n\nconst BYTES_PER_UNIT_SIZE = 1024 * 1024;\n\nexport function storageUnitsFromSize(size: number): number {\n\treturn Math.ceil(size / BYTES_PER_UNIT_SIZE);\n}\n\nfunction rotationOffset(bytes: Uint8Array, modulus: number): number {\n\treturn bytes.reduce((acc, byte) => (acc * 256 + byte) % modulus, 0);\n}\n\nexport function toShardIndex(sliverPairIndex: number, blobId: string, numShards: number): number {\n\tconst offset = rotationOffset(BlobId.serialize(blobId).toBytes(), numShards);\n\treturn (sliverPairIndex + offset) % numShards;\n}\n\nexport function sliverPairIndexFromSecondarySliverIndex(\n\tsliverIndex: number,\n\tnumShards: number,\n): number {\n\treturn numShards - sliverIndex - 1;\n}\n\nexport function shardIndexFromSecondarySliverIndex(\n\tsliverIndex: number,\n\tblobId: string,\n\tnumShards: number,\n): number {\n\tconst sliverPairIndex = sliverPairIndexFromSecondarySliverIndex(sliverIndex, numShards);\n\treturn toShardIndex(sliverPairIndex, blobId, numShards);\n}\n\nexport function toPairIndex(shardIndex: number, blobId: string, numShards: number): number {\n\tconst offset = rotationOffset(BlobId.serialize(blobId).toBytes(), numShards);\n\treturn (numShards + shardIndex - offset) % numShards;\n}\n\nexport function signersToBitmap(signers: number[], committeeSize: number): Uint8Array {\n\tconst bitmapSize = Math.ceil(committeeSize / 8);\n\tconst bitmap = new Uint8Array(bitmapSize);\n\n\tfor (const signer of signers) {\n\t\tconst byteIndex = Math.floor(signer / 8);\n\t\tconst bitIndex = signer % 8;\n\t\tbitmap[byteIndex] |= 1 << bitIndex;\n\t}\n\n\treturn bitmap;\n}\n\nexport function getShardIndicesByNodeId(committee: InferBcsType<typeof Committee>) {\n\tconst shardIndicesByNodeId = new Map<string, number[]>();\n\n\tfor (const node of committee[0].contents) {\n\t\tif (!shardIndicesByNodeId.has(node.key)) {\n\t\t\tshardIndicesByNodeId.set(node.key, []);\n\t\t}\n\t\tshardIndicesByNodeId.get(node.key)!.push(...node.value);\n\t}\n\n\treturn shardIndicesByNodeId;\n}\n\nexport function nodesByShardIndex(committee: InferBcsType<typeof Committee>) {\n\tconst nodesByShardIndex = new Map<number, string>();\n\n\tfor (const node of committee[0].contents) {\n\t\tfor (const shardIndex of node.value) {\n\t\t\tnodesByShardIndex.set(shardIndex, node.key);\n\t\t}\n\t}\n\n\treturn nodesByShardIndex;\n}\n\nexport function toTypeString(type: SuiMoveNormalizedType): string {\n\tif (typeof type === 'string') {\n\t\tswitch (type) {\n\t\t\tcase 'Address':\n\t\t\t\treturn 'address';\n\t\t\tcase 'Bool':\n\t\t\t\treturn 'bool';\n\t\t\tcase 'U8':\n\t\t\t\treturn 'u8';\n\t\t\tcase 'U16':\n\t\t\t\treturn 'u16';\n\t\t\tcase 'U32':\n\t\t\t\treturn 'u32';\n\t\t\tcase 'U64':\n\t\t\t\treturn 'u64';\n\t\t\tcase 'U128':\n\t\t\t\treturn 'u128';\n\t\t\tcase 'U256':\n\t\t\t\treturn 'u256';\n\t\t\tdefault:\n\t\t\t\tthrow new Error(`Unexpected type ${type}`);\n\t\t}\n\t}\n\n\tif ('Vector' in type) {\n\t\treturn `vector<${toTypeString(type.Vector)}>`;\n\t}\n\n\tif ('Struct' in type) {\n\t\tif (type.Struct.typeArguments.length > 0) {\n\t\t\treturn `${type.Struct.address}::${type.Struct.module}::${type.Struct.name}<${type.Struct.typeArguments.map(toTypeString).join(',')}>`;\n\t\t} else {\n\t\t\treturn `${type.Struct.address}::${type.Struct.module}::${type.Struct.name}`;\n\t\t}\n\t}\n\n\tif ('TypeParameter' in type) {\n\t\tthrow new Error(`Type parameters can't be converted to type strings`);\n\t}\n\n\tif ('Reference' in type) {\n\t\treturn toTypeString(type.Reference);\n\t}\n\n\tif ('MutableReference' in type) {\n\t\treturn toTypeString(type.MutableReference);\n\t}\n\n\tthrow new Error(`Unexpected type ${JSON.stringify(type)}`);\n}\n\nexport function urlSafeBase64(bytes: Uint8Array): string {\n\treturn toBase64(bytes).replace(/=*$/, '').replaceAll('+', '-').replaceAll('/', '_');\n}\n\nexport function fromUrlSafeBase64(base64: string): Uint8Array {\n\treturn fromBase64(base64.replaceAll('-', '+').replaceAll('_', '/'));\n}\n\nexport function getSizes(blobSize: number, numShards: number) {\n\tconst encodedBlobSize = encodedSliverSize(blobSize, numShards);\n\tconst { primarySymbols, secondarySymbols } = getSourceSymbols(numShards);\n\tconst totalSymbols = (primarySymbols + secondarySymbols) * numShards;\n\n\tif (encodedBlobSize % totalSymbols !== 0) {\n\t\tthrow new Error('encoded blob size should be divisible by total symbols');\n\t}\n\n\tconst symbolSize = encodedBlobSize / totalSymbols;\n\n\tif (encodedBlobSize % totalSymbols !== 0) {\n\t\tthrow new Error('blob length should be divisible by total symbols');\n\t}\n\n\tconst rowSize = symbolSize * secondarySymbols;\n\tconst columnSize = symbolSize * primarySymbols;\n\n\treturn {\n\t\tsymbolSize,\n\t\trowSize,\n\t\tcolumnSize,\n\t\tblobSize,\n\t};\n}\n"],"mappings":"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"}