From c913c680e50644de62c9f1454f2c86038e3e4d4d Mon Sep 17 00:00:00 2001 From: Dave Longley Date: Sat, 17 Feb 2024 17:03:37 -0500 Subject: [PATCH] Clean up status list config options and support for terse lists. --- lib/CredentialStatusWriter.js | 7 ++++++- lib/ListManager.js | 14 +++----------- lib/constants.js | 11 ++++++++--- lib/index.js | 31 +++++++++++++++++++++++++------ schemas/bedrock-vc-issuer.js | 6 +++--- 5 files changed, 45 insertions(+), 24 deletions(-) diff --git a/lib/CredentialStatusWriter.js b/lib/CredentialStatusWriter.js index f5ef855e..06266624 100644 --- a/lib/CredentialStatusWriter.js +++ b/lib/CredentialStatusWriter.js @@ -341,7 +341,7 @@ export class CredentialStatusWriter { credentialStatus.statusPurpose = statusPurpose; } else { // assume `TerseBitstringStatusList` - credentialStatus.type = 'TerseBitstringStatusList'; + credentialStatus.type = 'TerseBitstringStatusListEntry'; // this type of status list uses `terseStatusListIndex` in VCs instead, // which is expressed as an offset into total list index space instead of // into the individual status list @@ -350,6 +350,11 @@ export class CredentialStatusWriter { // the property value is an integer not a string credentialStatus.terseStatusListIndex = offset; meta.credentialStatus.terseStatusListIndex = offset; + + // FIXME: remove once `TerseBitstringStatusList` context is installed + credentialStatus.type = 'StatusList2021Entry'; + credentialStatus.statusListIndex = `${statusListIndex}`; + delete credentialStatus.terseStatusListIndex; } // add credential status if it did not already exist diff --git a/lib/ListManager.js b/lib/ListManager.js index 44abe0c2..83c912bb 100644 --- a/lib/ListManager.js +++ b/lib/ListManager.js @@ -463,10 +463,6 @@ export class ListManager { // creates the next SLs on demand and updates the current LM doc content // (without writing to the database) with a new set of SLC IDs for next time async _createNextStatusLists() { - // FIXME: may need to store more than just status list IDs... must store - // enough information to enable every `credentialStatus` entry to be - // created (but might be able to leverage `statusListConfig` for this) - // get next status lists metadata const {nextStatusLists} = this.lmDoc.content; console.log('nextStatusLists', nextStatusLists); @@ -535,9 +531,7 @@ export class ListManager { const {edvClient} = this; // try to find existing LMD using `indexAllocator` as ID - const {statusListConfig: {indexAllocator, terse, options}} = this; - // FIXME: get needed appropriate status list config options - //const {statusPurpose, terse, options} = this.statusListConfig; + const {statusListConfig: {indexAllocator, type: listType, options}} = this; const equals = {'content.id': indexAllocator}; while(true) { // find existing LMD @@ -564,10 +558,8 @@ export class ListManager { }, meta: {type} }; - // FIXME: add `terse` options - // FIXME: ensure that `listCount` default is set when the status list - // config was created - if(terse) { + // track list assignment when using `TerseBitstringStatusList` + if(listType === 'TerseBitstringStatusList') { const bs = new Bitstring({length: options.listCount}); lmDoc.content.listAssignment = { assignedLists: await bs.encodeBits(), diff --git a/lib/constants.js b/lib/constants.js index bddbd75f..80e30dcb 100644 --- a/lib/constants.js +++ b/lib/constants.js @@ -1,9 +1,14 @@ /*! * Copyright (c) 2024 Digital Bazaar, Inc. All rights reserved. */ -// max list size is MAX_BLOCK_COUNT * MAX_BLOCK_SIZE = 131072 -export const MAX_BLOCK_COUNT = 4096; -export const MAX_BLOCK_SIZE = 32; +export const DEFAULT_BLOCK_COUNT = 4096; +export const DEFAULT_BLOCK_SIZE = 32; + +// default `TerseBitstringStatusList` list count is 32-bit integer size +export const DEFAULT_TERSE_LIST_COUNT = 0x100000000; + +// max list size is DEFAULT_BLOCK_COUNT * DEFAULT_BLOCK_SIZE = 131072 +export const MAX_LIST_SIZE = DEFAULT_BLOCK_COUNT * DEFAULT_BLOCK_SIZE; // maximum number of lists this software can keep track of (applies only to // status list configurations where the number of lists is limited) diff --git a/lib/index.js b/lib/index.js index 143d4b25..ff47e39e 100644 --- a/lib/index.js +++ b/lib/index.js @@ -4,10 +4,13 @@ import * as bedrock from '@bedrock/core'; import * as issuer from './issuer.js'; import {createService, schemas} from '@bedrock/service-core'; +import { + DEFAULT_BLOCK_COUNT, DEFAULT_BLOCK_SIZE, DEFAULT_TERSE_LIST_COUNT, + MAX_LIST_SIZE, serviceType +} from './constants.js'; import { issueOptions, statusListOptions } from '../schemas/bedrock-vc-issuer.js'; -import {MAX_BLOCK_COUNT, MAX_BLOCK_SIZE} from './constants.js'; import { addRoutes as addContextStoreRoutes } from '@bedrock/service-context-store'; @@ -22,8 +25,6 @@ import './config.js'; export {issuer}; -const serviceType = 'vc-issuer'; - bedrock.events.on('bedrock.init', async () => { // add customizations to config validators... const createConfigBody = klona(schemas.createConfigBody); @@ -141,16 +142,34 @@ async function validateConfigFn({config, op, existingConfig} = {}) { // set default options const options = { - blockCount: MAX_BLOCK_COUNT, - blockSize: MAX_BLOCK_SIZE, + blockCount: DEFAULT_BLOCK_COUNT, + blockSize: DEFAULT_BLOCK_SIZE, ...statusConfig.options }; - // ensure list size is a multiple of 8 + // ensure list size is a multiple of 8 and less than the max list size const listSize = options.blockCount * options.blockSize; if(listSize % 8 !== 0) { throw new Error( `Total status list size (${listSize}) must be a multiple of 8.`); } + if(listSize > MAX_LIST_SIZE) { + throw new Error( + `Total status list size (${listSize}) must be less than ` + + `${MAX_LIST_SIZE}.`); + } + // `listCount` checks... + if(options.listCount !== undefined) { + if(type !== 'TerseBitstringStatusList') { + throw new Error( + '"listCount" can only be used with "TerseBitstringStatusList".'); + } + } + if(type === 'TerseBitstringStatusList') { + // must be a list count for `TerseBitstringStatusList` + if(options.listCount === undefined) { + options.listCount = DEFAULT_TERSE_LIST_COUNT; + } + } statusConfig.options = options; getSuiteParams({config, suiteName}); diff --git a/schemas/bedrock-vc-issuer.js b/schemas/bedrock-vc-issuer.js index 68c970b3..3c483bb1 100644 --- a/schemas/bedrock-vc-issuer.js +++ b/schemas/bedrock-vc-issuer.js @@ -2,7 +2,7 @@ * Copyright (c) 2022-2024 Digital Bazaar, Inc. All rights reserved. */ import { - MAX_BLOCK_COUNT, MAX_BLOCK_SIZE, MAX_LIST_COUNT + DEFAULT_BLOCK_COUNT, DEFAULT_BLOCK_SIZE, MAX_LIST_COUNT } from '../lib/constants.js'; const context = { @@ -88,12 +88,12 @@ export const statusListConfig = { blockCount: { type: 'integer', minimum: 1, - maximum: MAX_BLOCK_COUNT + maximum: DEFAULT_BLOCK_COUNT }, blockSize: { type: 'integer', minimum: 1, - maximum: MAX_BLOCK_SIZE + maximum: DEFAULT_BLOCK_SIZE }, // note: some list types will require a `listCount`, each having their // own different list count limits and defaults applied elsewhere; the