UNPKG

@sebastianp265/safe-server-side-storage-client

Version:

Library for Confidential Server-Side Message Storage Using the Labyrinth Protocol

141 lines (140 loc) 6.17 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.EpochStorage = exports.NegativeEpochSequenceIdError = exports.NoEpochExistsInEpochStorageError = exports.OmittedEpochError = exports.EpochAlreadyExistError = exports.EpochDoesNotExistError = exports.EpochStorageError = void 0; const BytesSerializer_1 = require("./BytesSerializer"); class EpochStorageError extends Error { constructor(message) { super(message); Object.setPrototypeOf(this, EpochStorageError.prototype); } } exports.EpochStorageError = EpochStorageError; class EpochDoesNotExistError extends EpochStorageError { constructor(epochSequenceId) { super(`Epoch with sequenceId = ${epochSequenceId} doesn't exist`); Object.setPrototypeOf(this, EpochDoesNotExistError.prototype); } } exports.EpochDoesNotExistError = EpochDoesNotExistError; class EpochAlreadyExistError extends EpochStorageError { constructor(epochSequenceId) { super(`Epoch with sequenceId = ${epochSequenceId} already exists`); Object.setPrototypeOf(this, EpochAlreadyExistError.prototype); } } exports.EpochAlreadyExistError = EpochAlreadyExistError; class OmittedEpochError extends EpochStorageError { constructor(expectedOlderEpochSequenceId, expectedNewerEpochSequenceId, actualEpochSequenceId) { super(`Expected to add older epoch with sequenceId = ${expectedOlderEpochSequenceId} or to add newer epoch with sequenceId = ${expectedNewerEpochSequenceId}, got epoch with sequenceId = ${actualEpochSequenceId}`); Object.setPrototypeOf(this, OmittedEpochError.prototype); } } exports.OmittedEpochError = OmittedEpochError; class NoEpochExistsInEpochStorageError extends EpochStorageError { constructor() { super("No epoch exists"); Object.setPrototypeOf(this, NoEpochExistsInEpochStorageError.prototype); } } exports.NoEpochExistsInEpochStorageError = NoEpochExistsInEpochStorageError; class NegativeEpochSequenceIdError extends EpochStorageError { constructor() { super("There cannot be an epoch with negative sequenceId"); Object.setPrototypeOf(this, NegativeEpochSequenceIdError.prototype); } } exports.NegativeEpochSequenceIdError = NegativeEpochSequenceIdError; class EpochStorage { newestEpochSequenceId; oldestEpochSequenceId; sequenceIdToEpoch; constructor(newestEpochSequenceId, oldestEpochSequenceId, sequenceIdToEpoch) { this.newestEpochSequenceId = newestEpochSequenceId; this.oldestEpochSequenceId = oldestEpochSequenceId; this.sequenceIdToEpoch = sequenceIdToEpoch; } static deserialize(epochStorageSerialized) { return new EpochStorage(epochStorageSerialized.oldestEpochSequenceId, epochStorageSerialized.newestEpochSequenceId, Object.fromEntries(Object.entries(epochStorageSerialized.sequenceIdToEpoch).map((e) => { const [k, v] = e; return [ k, { id: v.id, rootKey: BytesSerializer_1.bytesSerializerProvider.bytesSerializer.deserialize(v.rootKey), sequenceId: v.sequenceId, }, ]; }))); } serialize() { return { newestEpochSequenceId: this.newestEpochSequenceId, oldestEpochSequenceId: this.oldestEpochSequenceId, sequenceIdToEpoch: Object.fromEntries(Object.entries(this.sequenceIdToEpoch).map((e) => { const [k, v] = e; return [ k, { id: v.id, rootKey: BytesSerializer_1.bytesSerializerProvider.bytesSerializer.serialize(v.rootKey), sequenceId: v.sequenceId, }, ]; })), }; } static createEmpty() { return new EpochStorage(null, null, {}); } getEpoch(sequenceId) { const epoch = this.sequenceIdToEpoch[sequenceId]; if (epoch === undefined) { throw new EpochDoesNotExistError(sequenceId); } return epoch; } isEpochPresent(sequenceId) { return this.sequenceIdToEpoch[sequenceId] != undefined; } getOldestEpoch() { if (this.oldestEpochSequenceId === null) { throw new NoEpochExistsInEpochStorageError(); } return this.sequenceIdToEpoch[this.oldestEpochSequenceId]; } getNewestEpoch() { if (this.newestEpochSequenceId === null) { throw new NoEpochExistsInEpochStorageError(); } return this.sequenceIdToEpoch[this.newestEpochSequenceId]; } add(epochToAdd) { if (this.isEpochPresent(epochToAdd.sequenceId)) { throw new EpochAlreadyExistError(epochToAdd.sequenceId); } const epochToAddSequenceIdInt = BigInt(epochToAdd.sequenceId); if (epochToAddSequenceIdInt < 0) { throw new NegativeEpochSequenceIdError(); } if (Object.keys(this.sequenceIdToEpoch).length === 0) { this.sequenceIdToEpoch[epochToAdd.sequenceId] = epochToAdd; this.oldestEpochSequenceId = epochToAdd.sequenceId; this.newestEpochSequenceId = epochToAdd.sequenceId; } else { const possibleOlderEpochSequenceIdInt = BigInt(this.oldestEpochSequenceId) - BigInt(1); const possibleNewerEpochSequenceIdInt = BigInt(this.newestEpochSequenceId) + BigInt(1); if (possibleOlderEpochSequenceIdInt === epochToAddSequenceIdInt) { this.oldestEpochSequenceId = epochToAdd.sequenceId; } else if (possibleNewerEpochSequenceIdInt === epochToAddSequenceIdInt) { this.newestEpochSequenceId = epochToAdd.sequenceId; } else { throw new OmittedEpochError(possibleOlderEpochSequenceIdInt.toString(), possibleNewerEpochSequenceIdInt.toString(), epochToAdd.sequenceId); } this.sequenceIdToEpoch[epochToAdd.sequenceId] = epochToAdd; } } } exports.EpochStorage = EpochStorage;