Advance Blender WebEngine N-015 through N-022 parity
This commit is contained in:
@@ -2,6 +2,11 @@ import type { ErrorCode } from "./error";
|
||||
|
||||
export const SIMULATION_CACHE_SCHEMA = 1 as const;
|
||||
export const SIMULATION_CACHE_BLENDER_VERSION_PREFIX = "5.2." as const;
|
||||
export const SIMULATION_CACHE_BUDGET = {
|
||||
maxCacheBytes: 16 * 1024 * 1024 * 1024,
|
||||
maxFrameBytes: 512 * 1024 * 1024,
|
||||
maxFrames: 100_000,
|
||||
} as const;
|
||||
|
||||
export interface SimulationCacheFrameIR {
|
||||
frame: number;
|
||||
@@ -69,7 +74,10 @@ export function parseSimulationCacheManifest(value: unknown): SimulationCacheMan
|
||||
const frameStart = integer(value.frameStart, "frameStart", -1_000_000);
|
||||
const frameEnd = integer(value.frameEnd, "frameEnd", -1_000_000);
|
||||
const byteLength = integer(value.byteLength, "byteLength", 1);
|
||||
if (frameEnd < frameStart || frameEnd - frameStart > 100_000 || !Array.isArray(value.frames)) {
|
||||
if (byteLength > SIMULATION_CACHE_BUDGET.maxCacheBytes) {
|
||||
throw new SimulationCacheValidationError("SIMULATION_CACHE_INVALID", "Simulation cache exceeds the byte budget");
|
||||
}
|
||||
if (frameEnd < frameStart || frameEnd - frameStart + 1 > SIMULATION_CACHE_BUDGET.maxFrames || !Array.isArray(value.frames)) {
|
||||
throw new SimulationCacheValidationError("SIMULATION_CACHE_INVALID", "Simulation frame range is invalid");
|
||||
}
|
||||
if (value.frames.length !== frameEnd - frameStart + 1) {
|
||||
@@ -81,7 +89,10 @@ export function parseSimulationCacheManifest(value: unknown): SimulationCacheMan
|
||||
const frame = integer(item.frame, `frames[${index}].frame`, -1_000_000);
|
||||
const byteOffset = integer(item.byteOffset, `frames[${index}].byteOffset`);
|
||||
const frameByteLength = integer(item.byteLength, `frames[${index}].byteLength`, 1);
|
||||
if (frame !== frameStart + index || byteOffset !== nextOffset || byteOffset + frameByteLength > byteLength) {
|
||||
if (frameByteLength > SIMULATION_CACHE_BUDGET.maxFrameBytes) {
|
||||
throw new SimulationCacheValidationError("SIMULATION_CACHE_INVALID", `frames[${index}] exceeds the byte budget`);
|
||||
}
|
||||
if (frame !== frameStart + index || byteOffset !== nextOffset || byteOffset > byteLength - frameByteLength) {
|
||||
throw new SimulationCacheValidationError("SIMULATION_CACHE_INVALID", `frames[${index}] is not contiguous or ordered`);
|
||||
}
|
||||
nextOffset += frameByteLength;
|
||||
@@ -122,6 +133,30 @@ export async function verifySimulationCache(manifestValue: unknown, data: ArrayB
|
||||
return manifest;
|
||||
}
|
||||
|
||||
export function selectSimulationCacheFrame(manifestValue: unknown, frame: number): SimulationCacheFrameIR {
|
||||
const manifest = parseSimulationCacheManifest(manifestValue);
|
||||
if (!Number.isSafeInteger(frame) || frame < manifest.frameStart || frame > manifest.frameEnd) {
|
||||
throw new SimulationCacheValidationError("SIMULATION_CACHE_MISSING", `Simulation cache has no frame ${frame}`);
|
||||
}
|
||||
const selected = manifest.frames[frame - manifest.frameStart];
|
||||
if (!selected || selected.frame !== frame) {
|
||||
throw new SimulationCacheValidationError("SIMULATION_CACHE_MISSING", `Simulation cache has no frame ${frame}`);
|
||||
}
|
||||
return selected;
|
||||
}
|
||||
|
||||
export async function verifySimulationCacheFrame(
|
||||
manifestValue: unknown,
|
||||
frame: number,
|
||||
data: ArrayBuffer,
|
||||
): Promise<SimulationCacheFrameIR> {
|
||||
const selected = selectSimulationCacheFrame(manifestValue, frame);
|
||||
if (data.byteLength !== selected.byteLength || await sha256(data) !== selected.sha256) {
|
||||
throw new SimulationCacheValidationError("SIMULATION_CACHE_HASH_MISMATCH", `Simulation frame ${frame} failed SHA-256 verification`);
|
||||
}
|
||||
return selected;
|
||||
}
|
||||
|
||||
export function simulationCacheKey(manifest: SimulationCacheManifestIR): string {
|
||||
return `${manifest.graphHash.slice(0, 16)}-${manifest.sourceBlendSha256.slice(0, 16)}-${manifest.inputHash.slice(0, 16)}-${manifest.frameStart}-${manifest.frameEnd}`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user