@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
JavaScript
;
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;