Skip to content

Instantly share code, notes, and snippets.

@jeremyorme
jeremyorme / validate-syntax.txt
Created June 20, 2022 14:49
Syntax validations and null checks
check_exists(IStoreManifest)
check_manifest_syntax(IStoreManifest)
check_exists(IStore)
check_store_syntax(IStore)
check_exists(IEntryBlock)
check_entry_block_syntax(IEntryBlock)
@jeremyorme
jeremyorme / db.ts
Created June 20, 2022 14:45
DbStoreUpdater._isStoreValid method
_isStoreValid(store: IStore|null) {
// check_store_exists(IStore)
if (!store) {
console.log('[Db] ERROR: Store structure not found (address = ' + this._address + ')');
return false;
}
// check_store_syntax(IStore)
if (!validateStore(store)) {
console.log('[Db] ERROR: Store structure invalid (address = ' + this._address + ')');
@jeremyorme
jeremyorme / db.ts
Created June 20, 2022 14:44
DbStoreUpdater._isStoreManifestValid
_isStoreManifestValid(manifest: IStoreManifest|null) {
// check_manifest_exists(IStoreManifest)
if (!manifest) {
console.log('[Db] ERROR: Manifest not found (address = ' + this._address + ')');
return false;
}
// check_manifest_syntax(IStoreManifest)
if (!validateStoreManifest(manifest)) {
console.log('[Db] ERROR: Manifest invalid (address = ' + this._address + ')');
@jeremyorme
jeremyorme / db.ts
Created June 20, 2022 14:41
DbStoreUpdater.init method delegate validation to helpers
async init(name: string) {
var manifest;
if (this._options.address) {
this._address = this._options.address;
manifest = await ipfsGet<IStoreManifest>(this._ipfs, this._address);
if (!this._isStoreManifestValid(manifest))
return;
this._ownerIdentity = manifest.ownerIdentity;
}
@jeremyorme
jeremyorme / db.ts
Created June 20, 2022 14:39
DbStoreUpdater._areEntriesValid method
_areEntriesValid(entries: (IEntry|null)[], entryBlockList: IEntryBlockList) {
// check_strictly_increasing(IEntry.clock, IEntry.clock)
if (!entries.reduce((p, c) => !p || !c ? null : p.clock < c.clock ? c : null)) {
console.log('[Db] WARNING: Update containing non-increasing clocks was ignored (address = ' + this._address + ')');
return false;
}
// check_max(IEntryBlockList.clock, IEntry.clock)
const lastEntry = entries.slice(-1)[0];
if (lastEntry && lastEntry.clock != entryBlockList.clock) {
@jeremyorme
jeremyorme / db.ts
Created June 20, 2022 14:37
DbStoreUpdater._isEntryBlockValid method
_isEntryBlockValid(entryBlock: IEntryBlock|null, entryBlockList: IEntryBlockList, isLast: boolean) {
// check_entry_block_exists(IEntryBlock)
if (!entryBlock) {
console.log('[Db] WARNING: Update referencing missing block was ignored (address = ' + this._address + ')');
return false;
}
// check_entry_block_syntax(IEntryBlock)
if (!validateEntryBlock(entryBlock)) {
console.log('[Db] WARNING: Update containing invalid block was ignore (address = ' + this._address + ')');
@jeremyorme
jeremyorme / db.ts
Created June 20, 2022 14:34
DbStoreUpdater._areEntryBlocksValid method
_areEntryBlocksValid(entryBlockList: IEntryBlockList, entryBlocks: (IEntryBlock|null)[]) {
if (!entryBlocks.every((entryBlock, i) => this._isEntryBlockValid(entryBlock, entryBlockList, i == entryBlockList.entryBlockCids.length - 1)))
return false;
if (!this._areEntriesValid(mergeArrays(entryBlocks.map(entryBlock => entryBlock ? entryBlock.entries : [])), entryBlockList))
return false;
// success!
return true;
}
@jeremyorme
jeremyorme / db.ts
Created June 20, 2022 14:31
DbStoreUpdater._isEntryBlockListNew method
_isEntryBlockListNew(entryBlockList: IEntryBlockList) {
const existingEntryBlockList = this._entryBlockLists.get(entryBlockList.ownerIdentity);
return !existingEntryBlockList || entryBlockList.clock > existingEntryBlockList.clock;
}
@jeremyorme
jeremyorme / db.ts
Created June 20, 2022 14:27
DbStoreUpdater.merge updated to discard whole update if validation fails
async merge(entryBlockLists: IEntryBlockList[]) {
// Clone the entry block list map and set any received entry block lists that are new
const newEntryBlockLists = new Map(this._entryBlockLists);
entryBlockLists.filter(entryBlockList => this._isEntryBlockListNew(entryBlockList)).forEach(entryBlockList => {
newEntryBlockLists.set(entryBlockList.ownerIdentity, entryBlockList);
});
// Fetch the entry blocks
const listsAndBlocks = await Promise.all(Array.from(newEntryBlockLists.values())
@jeremyorme
jeremyorme / validate-interfaces.txt
Last active June 12, 2022 07:45
Add clock validations
check_signature(IEntryBlockList.publicKey, IEntryBlockList.signature, IEntryBlock)
check_not_empty(IEntryBlockList.entryBlockCids);
check_not_empty(IEntryBlock[last].entries)
check_size(IEntryBlock[!last].entries, IStoreOptions.entryBlockSize)
check_has_write_access(IEntryBlockList.ownerIdentity, IStoreManifest.ownerIdentity)
check_max_clock(IEntry.clock, IEntryBlockList.clock)
check_greater than(IEntry[N].clock, IEntry[N-1].clock)