@metamask/ocap-kernel
Version:
OCap kernel core components
1 lines • 13.8 kB
Source Map (JSON)
{"version":3,"file":"index.cjs","sourceRoot":"","sources":["../../src/store/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;;AAuCH,0CA0IC;AA9KD,6CAA0C;AAG1C,gDAAmD;AACnD,kDAAqD;AACrD,kDAAqD;AACrD,4CAA+C;AAC/C,4CAA+C;AAC/C,oDAAuD;AACvD,oDAAoD;AACpD,sDAAyD;AACzD,kDAAqD;AACrD,0DAA6D;AAC7D,wDAA2D;AAC3D,4DAA+D;AAC/D,8DAAgE;AAChE,8DAA0D;AAC1D,8CAAiD;AAGjD;;;;;;;;;;;;;;GAcG;AACH,4EAA4E;AAC5E,SAAgB,eAAe,CAAC,GAAmB,EAAE,MAAe;IAClE,wBAAwB;IAExB,4DAA4D;IAC5D,MAAM,EAAE,GAAY,GAAG,CAAC,aAAa,CAAC;IAEtC,MAAM,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,GAAG,IAAA,wBAAc,EAAC,EAAE,CAAC,CAAC;IAE5E,MAAM,OAAO,GAAiB;QAC5B,EAAE;QACF,8BAA8B;QAC9B,QAAQ,EAAE,kBAAkB,CAAC,KAAK,EAAE,IAAI,CAAC;QACzC,8CAA8C;QAC9C,mBAAmB,EAAE,CAAC,CAAC;QACvB,+CAA+C;QAC/C,YAAY,EAAE,wBAAwB,CAAC,cAAc,EAAE,GAAG,CAAC;QAC3D,gDAAgD;QAChD,aAAa,EAAE,wBAAwB,CAAC,eAAe,EAAE,GAAG,CAAC;QAC7D,oCAAoC;QACpC,SAAS,EAAE,wBAAwB,CAAC,WAAW,EAAE,GAAG,CAAC;QACrD,uCAAuC;QACvC,YAAY,EAAE,wBAAwB,CAAC,cAAc,EAAE,GAAG,CAAC;QAC3D,uEAAuE;QACvE,iCAAiC;QACjC,sEAAsE;QACtE,mEAAmE;QACnE,sEAAsE;QACtE,2EAA2E;QAC3E,+EAA+E;QAC/E,2EAA2E;QAC3E,yEAAyE;QACzE,WAAW;QACX,cAAc,EAAE,IAAI,GAAG,EAAQ;QAC/B,qBAAqB;QACrB,SAAS,EAAE,wBAAwB,CAAC,WAAW,EAAE,IAAI,CAAC;QACtD,SAAS,EAAE,wBAAwB,CAAC,WAAW,EAAE,IAAI,CAAC;QACtD,cAAc,EAAE,wBAAwB,CAAC,iBAAiB,EAAE,IAAI,CAAC;QACjE,OAAO,EAAE,KAAK;QACd,UAAU,EAAE,EAAE;QACd,cAAc;QACd,WAAW,EAAE,wBAAwB,CAAC,aAAa,EAAE,IAAI,CAAC;QAC1D,gBAAgB,EAAE,wBAAwB,CAAC,kBAAkB,EAAE,GAAG,CAAC;QACnE,kBAAkB,EAAE,wBAAwB,CAAC,oBAAoB,EAAE,IAAI,CAAC;QACxE,UAAU;QACV,MAAM,EAAE,MAAM,IAAI,IAAI,eAAM,CAAC,EAAE,IAAI,EAAE,CAAC,cAAc,CAAC,EAAE,CAAC;KACzD,CAAC;IAEF,MAAM,EAAE,GAAG,IAAA,oBAAY,EAAC,OAAO,CAAC,CAAC;IACjC,MAAM,QAAQ,GAAG,IAAA,gCAAkB,EAAC,OAAO,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,IAAA,4BAAgB,EAAC,OAAO,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,IAAA,8BAAiB,EAAC,OAAO,CAAC,CAAC;IAC3C,MAAM,UAAU,GAAG,IAAA,oCAAoB,EAAC,OAAO,CAAC,CAAC;IACjD,MAAM,EAAE,GAAG,IAAA,oBAAY,EAAC,OAAO,CAAC,CAAC;IACjC,MAAM,KAAK,GAAG,IAAA,0BAAe,EAAC,OAAO,CAAC,CAAC;IACvC,MAAM,KAAK,GAAG,IAAA,0BAAe,EAAC,OAAO,CAAC,CAAC;IACvC,MAAM,GAAG,GAAG,IAAA,sBAAa,EAAC,OAAO,CAAC,CAAC;IACnC,MAAM,SAAS,GAAG,IAAA,kCAAmB,EAAC,OAAO,CAAC,CAAC;IAC/C,MAAM,WAAW,GAAG,IAAA,+BAAc,EAAC,OAAO,CAAC,CAAC;IAC5C,MAAM,MAAM,GAAG,IAAA,yBAAa,EAAC,OAAO,CAAC,CAAC;IACtC,MAAM,KAAK,GAAG,IAAA,0BAAe,EAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAC5C,MAAM,WAAW,GAAG,IAAA,qCAAoB,EAAC,OAAO,CAAC,CAAC;IAElD;;;;;;OAMG;IACH,SAAS,YAAY,CAAC,KAAa;QACjC,OAAO,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;IAED;;;;OAIG;IACH,SAAS,SAAS,CAAC,KAAY;QAC7B,GAAG,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QAC3B,GAAG,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QAC1B,WAAW,CAAC,uBAAuB,CAAC,KAAK,CAAC,CAAC;IAC7C,CAAC;IAED;;OAEG;IACH,SAAS,KAAK;QACZ,GAAG,CAAC,KAAK,EAAE,CAAC;QACZ,OAAO,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;QAC/B,OAAO,CAAC,QAAQ,GAAG,kBAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACnD,OAAO,CAAC,SAAS,GAAG,wBAAwB,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QAChE,OAAO,CAAC,SAAS,GAAG,wBAAwB,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QAChE,OAAO,CAAC,cAAc,GAAG,wBAAwB,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAAC;QAC3E,OAAO,CAAC,YAAY,GAAG,wBAAwB,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;QACrE,OAAO,CAAC,aAAa,GAAG,wBAAwB,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC;QACvE,OAAO,CAAC,SAAS,GAAG,wBAAwB,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;QAC/D,OAAO,CAAC,YAAY,GAAG,wBAAwB,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;QACrE,OAAO,CAAC,WAAW,GAAG,wBAAwB,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;QACpE,OAAO,CAAC,gBAAgB,GAAG,wBAAwB,CACjD,kBAAkB,EAClB,GAAG,CACJ,CAAC;QACF,OAAO,CAAC,kBAAkB,GAAG,wBAAwB,CACnD,oBAAoB,EACpB,IAAI,CACL,CAAC;QACF,KAAK,CAAC,oBAAoB,EAAE,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,SAAS,KAAK;QACZ,GAAG,CAAC,KAAK,EAAE,CAAC;IACd,CAAC;IAED,OAAO,MAAM,CAAC;QACZ,GAAG,EAAE;QACL,GAAG,KAAK;QACR,GAAG,QAAQ;QACX,GAAG,MAAM;QACT,GAAG,OAAO;QACV,GAAG,UAAU;QACb,GAAG,EAAE;QACL,GAAG,SAAS;QACZ,GAAG,KAAK;QACR,GAAG,GAAG;QACN,GAAG,WAAW;QACd,GAAG,MAAM;QACT,GAAG,KAAK;QACR,GAAG,WAAW;QACd,YAAY;QACZ,SAAS;QACT,KAAK;QACL,KAAK;QACL,EAAE;KACH,CAAC,CAAC;AACL,CAAC","sourcesContent":["/*\n * Organization of keys in the key value store:\n *\n * Definitions\n * NN ::= some decimal integer\n * CAPDATA ::= capdata encoded structure value\n * JSON(${xx}) ::= JSON encoding of ${xx}\n *\n * ${koid} ::= ko${NN} // kernel object ID\n * ${kpid} ::= kp${NN} // kernel promise ID\n * ${kref} ::= ${koid} | ${kpid} // kernel reference\n * ${dir} ::= + | - // direction (for remote and vat references)\n * ${roid} ::= ro${dir}${NN} // remote object ID\n * ${rpid} ::= rp${dir}${NN} // remote promise ID\n * ${rref} ::= ${roid} | ${rpid} // remote reference\n * ${void} ::= o${dir}${NN} // vat object ID\n * ${vpid} ::= p${dir}${NN} // vat promise ID\n * ${vref} ::= ${void} | ${vpid} // vat reference\n * ${eref} ::= ${vref} | ${rref} // external reference\n * ${vatid} ::= v${NN} // vat ID\n * ${remid} ::= r${NN} // remote ID\n * ${endid} ::= ${vatid} | ${remid} // endpoint ID\n * ${queueName} ::= run | ${kpid}\n *\n * Queues\n * queue.${queueName}.head = NN // queue head index\n * queue.${queueName}.tail = NN // queue tail index\n * queue.${queueName}.${NN} = JSON(CAPDATA) // queue entry #NN\n *\n * Kernel objects\n * ${koid}.refCount = NN // reference count\n * ${koid}.owner = ${vatid} // owner (where the object is)\n *\n * Kernel promises\n * ${kpid}.refCount = NN // reference count\n * ${kpid}.state = unresolved | fulfilled | rejected // current state of settlement\n * ${kpid}.subscribers = JSON([${endid}]) // array of who is waiting for settlement\n * ${kpid}.decider = ${endid} // who decides on settlement\n * ${kpid}.value = JSON(CAPDATA) // value settled to, if settled\n *\n * C-lists\n * cle.${endid}.${eref} = ${kref} // ERef->KRef mapping\n * clk.${endid}.${kref} = ${eref} // KRef->ERef mapping\n *\n * Vat bookkeeping\n * e.nextObjectId.${endid} = NN // allocation counter for imported object ERefs\n * e.nextPromiseId.${endid} = NN // allocation counter for imported promise ERefs\n * vatConfig.${vatid} = JSON(CONFIG) // vat's configuration object\n *\n * Kernel bookkeeping\n * initialized = true // if set, indicates the store has been initialized\n * nextVatId = NN // allocation counter for vat IDs\n * nextRemoteId = NN // allocation counter for remote IDs\n * k.nextObjectId = NN // allocation counter for object KRefs\n * k.nextPromiseId = NN // allocation counter for promise KRefs\n */\n\nimport type { KernelDatabase, KVStore, VatStore } from '@metamask/kernel-store';\nimport { Logger } from '@metamask/logger';\n\nimport type { KRef, VatId } from '../types.ts';\nimport { getBaseMethods } from './methods/base.ts';\nimport { getCListMethods } from './methods/clist.ts';\nimport { getCrankMethods } from './methods/crank.ts';\nimport { getGCMethods } from './methods/gc.ts';\nimport { getIdMethods } from './methods/id.ts';\nimport { getObjectMethods } from './methods/object.ts';\nimport { getPinMethods } from './methods/pinned.ts';\nimport { getPromiseMethods } from './methods/promise.ts';\nimport { getQueueMethods } from './methods/queue.ts';\nimport { getReachableMethods } from './methods/reachable.ts';\nimport { getRefCountMethods } from './methods/refcount.ts';\nimport { getRevocationMethods } from './methods/revocation.ts';\nimport { getSubclusterMethods } from './methods/subclusters.ts';\nimport { getTranslators } from './methods/translators.ts';\nimport { getVatMethods } from './methods/vat.ts';\nimport type { StoreContext } from './types.ts';\n\n/**\n * Create a new KernelStore object wrapped around a raw kernel database. The\n * resulting object provides a variety of operations for accessing various\n * kernel-relevent persistent data structure abstractions on their own terms,\n * without burdening the kernel with the particular details of how they are\n * represented in storage. It is our hope that these operations may be later\n * reimplemented on top of a more sophisticated database layer that can realize\n * them more directly (and thus, one hopes, more efficiently) without requiring\n * the kernel itself to be any the wiser.\n *\n * @param kdb - The kernel database this store is based on.\n * @param logger - The logger to use.\n * @returns A KernelStore object that maps various persistent kernel data\n * structures onto `kdb`.\n */\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nexport function makeKernelStore(kdb: KernelDatabase, logger?: Logger) {\n // Initialize core state\n\n /** KV store in which all the kernel's own state is kept. */\n const kv: KVStore = kdb.kernelKVStore;\n\n const { provideCachedStoredValue, provideStoredQueue } = getBaseMethods(kv);\n\n const context: StoreContext = {\n kv,\n /** The kernel's run queue. */\n runQueue: provideStoredQueue('run', true),\n /** Cache of the run queue's current length */\n runQueueLengthCache: -1,\n /** Counter for allocating kernel object IDs */\n nextObjectId: provideCachedStoredValue('nextObjectId', '1'),\n /** Counter for allocating kernel promise IDs */\n nextPromiseId: provideCachedStoredValue('nextPromiseId', '1'),\n /** Counter for allocating VatIDs */\n nextVatId: provideCachedStoredValue('nextVatId', '1'),\n /** Counter for allocating RemoteIDs */\n nextRemoteId: provideCachedStoredValue('nextRemoteId', '1'),\n // As refcounts are decremented, we accumulate a set of krefs for which\n // action might need to be taken:\n // * promises which are now resolved and unreferenced can be deleted\n // * objects which are no longer reachable: export can be dropped\n // * objects which are no longer recognizable: export can be retired\n // This set is ephemeral: it lives in RAM, grows as deliveries and syscalls\n // cause decrefs, and will be harvested by processRefcounts(). This needs to be\n // called in the same transaction window as the syscalls/etc which prompted\n // the change, else removals might be lost (not performed during the next\n // replay).\n maybeFreeKrefs: new Set<KRef>(),\n // Garbage collection\n gcActions: provideCachedStoredValue('gcActions', '[]'),\n reapQueue: provideCachedStoredValue('reapQueue', '[]'),\n terminatedVats: provideCachedStoredValue('vats.terminated', '[]'),\n inCrank: false,\n savepoints: [],\n // Subclusters\n subclusters: provideCachedStoredValue('subclusters', '[]'),\n nextSubclusterId: provideCachedStoredValue('nextSubclusterId', '1'),\n vatToSubclusterMap: provideCachedStoredValue('vatToSubclusterMap', '{}'),\n // Logging\n logger: logger ?? new Logger({ tags: ['kernel-store'] }),\n };\n\n const id = getIdMethods(context);\n const refCount = getRefCountMethods(context);\n const object = getObjectMethods(context);\n const promise = getPromiseMethods(context);\n const revocation = getRevocationMethods(context);\n const gc = getGCMethods(context);\n const cList = getCListMethods(context);\n const queue = getQueueMethods(context);\n const vat = getVatMethods(context);\n const reachable = getReachableMethods(context);\n const translators = getTranslators(context);\n const pinned = getPinMethods(context);\n const crank = getCrankMethods(context, kdb);\n const subclusters = getSubclusterMethods(context);\n\n /**\n * Create a new VatStore for a vat.\n *\n * @param vatID - The vat for which this is being done.\n *\n * @returns a a VatStore object for the given vat.\n */\n function makeVatStore(vatID: string): VatStore {\n return kdb.makeVatStore(vatID);\n }\n\n /**\n * Delete all persistent state associated with a vat.\n *\n * @param vatId - The vat whose state is to be deleted.\n */\n function deleteVat(vatId: VatId): void {\n vat.deleteVatConfig(vatId);\n kdb.deleteVatStore(vatId);\n subclusters.removeVatFromSubcluster(vatId);\n }\n\n /**\n * Reset the kernel's persistent state and reset all counters.\n */\n function reset(): void {\n kdb.clear();\n context.maybeFreeKrefs.clear();\n context.runQueue = provideStoredQueue('run', true);\n context.gcActions = provideCachedStoredValue('gcActions', '[]');\n context.reapQueue = provideCachedStoredValue('reapQueue', '[]');\n context.terminatedVats = provideCachedStoredValue('vats.terminated', '[]');\n context.nextObjectId = provideCachedStoredValue('nextObjectId', '1');\n context.nextPromiseId = provideCachedStoredValue('nextPromiseId', '1');\n context.nextVatId = provideCachedStoredValue('nextVatId', '1');\n context.nextRemoteId = provideCachedStoredValue('nextRemoteId', '1');\n context.subclusters = provideCachedStoredValue('subclusters', '[]');\n context.nextSubclusterId = provideCachedStoredValue(\n 'nextSubclusterId',\n '1',\n );\n context.vatToSubclusterMap = provideCachedStoredValue(\n 'vatToSubclusterMap',\n '{}',\n );\n crank.releaseAllSavepoints();\n }\n\n /**\n * Delete everything from the database.\n */\n function clear(): void {\n kdb.clear();\n }\n\n return harden({\n ...id,\n ...queue,\n ...refCount,\n ...object,\n ...promise,\n ...revocation,\n ...gc,\n ...reachable,\n ...cList,\n ...vat,\n ...translators,\n ...pinned,\n ...crank,\n ...subclusters,\n makeVatStore,\n deleteVat,\n clear,\n reset,\n kv,\n });\n}\n\nexport type KernelStore = ReturnType<typeof makeKernelStore>;\n"]}