Skip to content

Commit

Permalink
Enable testing listCount and improve list assignment code.
Browse files Browse the repository at this point in the history
  • Loading branch information
dlongley committed Feb 18, 2024
1 parent 97cf426 commit 33cac98
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 21 deletions.
47 changes: 28 additions & 19 deletions lib/ListManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ export class ListManager {
// (without writing to the database) with a new set of SLC IDs for next time
async _createNextStatusLists() {
// get next status lists metadata
const {nextStatusLists} = this.lmDoc.content;
const {nextStatusLists, listAssignment} = this.lmDoc.content;
console.log('nextStatusLists', nextStatusLists);

// throw if no more status lists can be created
Expand All @@ -460,18 +460,21 @@ export class ListManager {
e => this.listSource.createStatusList(e)));

// create next status lists metadata
this.lmDoc.content.nextStatusLists = await this._createStatusListMeta();
this.lmDoc.content.nextStatusLists = await this._createStatusListMeta({
listAssignment
});
}

async _createStatusListMeta() {
async _createStatusListMeta({listAssignment} = {}) {
// generate new SLC IDs for each ID and set them in LM doc;
// determine how many SLC IDs to generate how they should look (terse / not)
const {baseUrl, statusPurpose, terse, options} = this.statusListConfig;
// determine how many SLC IDs to generate how they should look (total list
// count is limited, aka, "terse", or not)
const {baseUrl, statusPurpose, options} = this.statusListConfig;
const purposes = Array.isArray(statusPurpose) ?
statusPurpose : [statusPurpose];
const length = options.blockCount * options.blockSize;
if(!terse) {
// not overall index limit; generate random local ID for each SLC
if(options.listCount === undefined) {
// not overall list limit; generate random local ID for each SLC
return Promise.all(purposes.map(async statusPurpose => {
return {
id: `${baseUrl}/${await generateLocalId()}`,
Expand All @@ -481,7 +484,7 @@ export class ListManager {
}));
}

/* Note: In the case of a terse list, there is some total amount of
/* Note: In the case of a limited list count, there is some total amount of
"list index space" for which N-many lists (bounded) can be created (e.g.,
32768 lists with a list size of 131072 is 2^32 total list index space). The
next list-sized chunk of total "list index space" is selected at random
Expand All @@ -493,12 +496,11 @@ export class ListManager {
N-many lists in the LDM. */

// if all lists are already assigned, return `[]` for next SLC IDs
const {content: {listAssignment}} = this.lmDoc;
if(listAssignment.assignedListCount === options.listCount) {
return [];
}
// choose next list at random from available lists
const {listIndex} = _chooseRandom({listAssignment});
const {listIndex} = await _chooseRandom({listAssignment});
return purposes.map(statusPurpose => {
const encodedStatusPurpose = encodeURIComponent(statusPurpose);
return {
Expand All @@ -524,6 +526,17 @@ export class ListManager {
return;
}

// track list assignment when using a limited total list count
let listAssignment;
if(options.listCount !== undefined) {
const bs = new Bitstring({length: options.listCount});
listAssignment = {
assignedLists: await bs.encodeBits(),
assignedListCount: 0,
listCount: options.listCount
};
}

// no LMD found, upsert it
const type = 'StatusListManagementDocument';
const lmDoc = {
Expand All @@ -533,22 +546,16 @@ export class ListManager {
type,
// each element has an `id` and other meta data for the next status
// lists to be created
nextStatusLists: await this._createStatusListMeta(),
nextStatusLists: await this._createStatusListMeta({listAssignment}),
blockAssignment: {
active: [],
inactive: []
}
},
meta: {type}
};
// track list assignment when using a limited total list count
if(options.listCount !== undefined) {
const bs = new Bitstring({length: options.listCount});
lmDoc.content.listAssignment = {
assignedLists: await bs.encodeBits(),
assignedListCount: 0,
listCount: options.listCount
};
if(listAssignment) {
lmDoc.content.listAssignment = listAssignment;
}
try {
this.lmDoc = await edvClient.update({doc: lmDoc});
Expand All @@ -573,6 +580,8 @@ export class ListManager {
async function _chooseRandom({listAssignment}) {
const {assignedLists, assignedListCount, listCount} = listAssignment;

// FIXME: reuse some code from `IndexAllocationCache.js` here

// choose one of the unassigned lists
let choice = Math.floor(Math.random() * assignedListCount);
// map the choice to a specific list index
Expand Down
1 change: 1 addition & 0 deletions lib/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ cfg.routes = {
credentialsIssue: '/credentials/issue',
credentialsStatus: '/credentials/status',
// `slcs` route must be a prefix for `publishSlc` and `slc`
// FIXME: remove `publish` and auto-publish on demand instead
publishSlc: '/slcs/:slcId/publish',
slc: '/slcs/:slcId',
slcs: '/slcs'
Expand Down
5 changes: 3 additions & 2 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,11 @@ async function validateConfigFn({config, op, existingConfig} = {}) {
}
// `listCount` checks...
if(options.listCount !== undefined) {
if(type !== 'TerseBitstringStatusList') {
// FIXME: re-enable this check
/*if(type !== 'TerseBitstringStatusList') {
throw new Error(
'"listCount" can only be used with "TerseBitstringStatusList".');
}
}*/
}
if(type === 'TerseBitstringStatusList') {
// must be a list count for `TerseBitstringStatusList`
Expand Down

0 comments on commit 33cac98

Please sign in to comment.