Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issue where dwn-store records are not actually being updated #961

Merged
merged 3 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changeset/curvy-fireants-dress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@web5/agent": patch
"@web5/identity-agent": patch
"@web5/proxy-agent": patch
"@web5/user-agent": patch
---

Fix error where `dwn-store` records were not being updated when marked as such.
36 changes: 31 additions & 5 deletions packages/agent/src/store-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import { TENANT_SEPARATOR } from './utils-internal.js';
import { getDataStoreTenant } from './utils-internal.js';
import { DwnInterface, DwnMessageParams } from './types/dwn.js';
import { ProtocolDefinition } from '@tbd54566975/dwn-sdk-js';
import { ProtocolDefinition, RecordsReadReplyEntry } from '@tbd54566975/dwn-sdk-js';

export type DataStoreTenantParams = {
agent: Web5PlatformAgent;
Expand Down Expand Up @@ -151,13 +151,15 @@

if (updateExisting) {
// Look up the DWN record ID of the object in the store with the given `id`.
const matchingRecordId = await this.lookupRecordId({ id, tenantDid, agent });
if (!matchingRecordId) {
const matchingRecordEntry = await this.getExistingRecordEntry({ id, tenantDid, agent });
if (!matchingRecordEntry) {
throw new Error(`${this.name}: Update failed due to missing entry for: ${id}`);
}

// set the recordId in the messageParams to update the existing record
messageParams.recordId = matchingRecordId;
// set the dateCreated to the existing dateCreated as this is an immutable property
messageParams.recordId = matchingRecordEntry.recordsWrite?.recordId;
messageParams.dateCreated = matchingRecordEntry.recordsWrite?.descriptor.dateCreated;
} else if (preventDuplicates) {
// Look up the DWN record ID of the object in the store with the given `id`.
const matchingRecordId = await this.lookupRecordId({ id, tenantDid, agent });
Expand All @@ -175,7 +177,7 @@
author : tenantDid,
target : tenantDid,
messageType : DwnInterface.RecordsWrite,
messageParams : { ...this._recordProperties },
messageParams : { ...this._recordProperties, ...messageParams },
dataStream : new Blob([dataBytes], { type: 'application/json' })
});

Expand Down Expand Up @@ -307,6 +309,30 @@

return recordId;
}

private async getExistingRecordEntry({ id, tenantDid, agent }: {
id: string;
tenantDid: string;
agent: Web5PlatformAgent;
}): Promise<RecordsReadReplyEntry | undefined> {
// Look up the DWN record ID of the object in the store with the given `id`.
const recordId = await this.lookupRecordId({ id, tenantDid, agent });
if (recordId) {
// Read the record from the store.
const { reply: readReply } = await agent.dwn.processRequest({
author : tenantDid,
target : tenantDid,
messageType : DwnInterface.RecordsRead,
messageParams : { filter: { recordId } }
});

if (readReply.status.code !== 200 || !readReply.entry) {
throw new Error(`${this.name}: Failed to read data from DWN for: ${recordId}`);
}

Check warning on line 331 in packages/agent/src/store-data.ts

View check run for this annotation

Codecov / codecov/patch

packages/agent/src/store-data.ts#L330-L331

Added lines #L330 - L331 were not covered by tests

return readReply.entry;
}
}
}

export class InMemoryDataStore<TStoreObject extends Record<string, any> = Jwk> implements AgentDataStore<TStoreObject> {
Expand Down
8 changes: 8 additions & 0 deletions packages/agent/tests/store-data.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,7 @@ describe('AgentDataStore', () => {

describe('updateExisting', () => {
it('updates an existing record', async () => {

// Create and import a DID.
let bearerDid = await DidJwk.create();
const importedDid = await testHarness.agent.did.import({
Expand All @@ -723,6 +724,9 @@ describe('AgentDataStore', () => {
}
};

// get the length of the list before updating to confirm that no additional records are added
const listLength = (await testStore.list({ agent: testHarness.agent })).length;

// Update the DID in the store.
await testStore.set({
id : importedDid.uri,
Expand All @@ -736,6 +740,10 @@ describe('AgentDataStore', () => {
const storedDid = await testStore.get({ id: importedDid.uri, agent: testHarness.agent, tenant: testHarness.agent.agentDid.uri });
expect(storedDid!.uri).to.equal(updatedDid.uri);
expect(storedDid!.document).to.deep.equal(updatedDid.document);

// verify that no additional records were added
const updatedListLength = (await testStore.list({ agent: testHarness.agent })).length;
expect(updatedListLength).to.equal(listLength);
});

it('throws an error if the record does not exist', async () => {
Expand Down
Loading