From 0f6c2e181fa77e6be0283a687c825353eafc4923 Mon Sep 17 00:00:00 2001 From: Liran Cohen Date: Tue, 22 Oct 2024 11:15:17 -0400 Subject: [PATCH 1/3] fix issue whre dwn-store records were not actually being updated --- packages/agent/src/store-data.ts | 36 +++++++++++++++++++++---- packages/agent/tests/store-data.spec.ts | 8 ++++++ 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/packages/agent/src/store-data.ts b/packages/agent/src/store-data.ts index c4fbea41e..6e396fd50 100644 --- a/packages/agent/src/store-data.ts +++ b/packages/agent/src/store-data.ts @@ -8,7 +8,7 @@ import type { Web5PlatformAgent } from './types/agent.js'; 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; @@ -151,13 +151,15 @@ export class DwnDataStore = Jwk> implem 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 }); @@ -175,7 +177,7 @@ export class DwnDataStore = Jwk> implem author : tenantDid, target : tenantDid, messageType : DwnInterface.RecordsWrite, - messageParams : { ...this._recordProperties }, + messageParams : { ...this._recordProperties, ...messageParams }, dataStream : new Blob([dataBytes], { type: 'application/json' }) }); @@ -307,6 +309,30 @@ export class DwnDataStore = Jwk> implem return recordId; } + + private async getExistingRecordEntry({ id, tenantDid, agent }: { + id: string; + tenantDid: string; + agent: Web5PlatformAgent; + }): Promise { + // 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}`); + } + + return readReply.entry; + } + } } export class InMemoryDataStore = Jwk> implements AgentDataStore { diff --git a/packages/agent/tests/store-data.spec.ts b/packages/agent/tests/store-data.spec.ts index ac562dac3..5b638efee 100644 --- a/packages/agent/tests/store-data.spec.ts +++ b/packages/agent/tests/store-data.spec.ts @@ -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({ @@ -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, @@ -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 () => { From 242990c85cb5882296556e21e052926c61a73a45 Mon Sep 17 00:00:00 2001 From: Liran Cohen Date: Tue, 22 Oct 2024 11:17:04 -0400 Subject: [PATCH 2/3] add changesets --- .changeset/curvy-fireants-dress.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .changeset/curvy-fireants-dress.md diff --git a/.changeset/curvy-fireants-dress.md b/.changeset/curvy-fireants-dress.md new file mode 100644 index 000000000..37a597312 --- /dev/null +++ b/.changeset/curvy-fireants-dress.md @@ -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. From 0f899a58dfcc438d56d37e21e6eb18abe4683dd6 Mon Sep 17 00:00:00 2001 From: Liran Cohen Date: Tue, 22 Oct 2024 12:07:11 -0400 Subject: [PATCH 3/3] remove optionality complexity --- packages/agent/src/store-data.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/agent/src/store-data.ts b/packages/agent/src/store-data.ts index 6e396fd50..11a1b95fa 100644 --- a/packages/agent/src/store-data.ts +++ b/packages/agent/src/store-data.ts @@ -158,8 +158,8 @@ export class DwnDataStore = Jwk> implem // set the recordId in the messageParams to update the existing record // set the dateCreated to the existing dateCreated as this is an immutable property - messageParams.recordId = matchingRecordEntry.recordsWrite?.recordId; - messageParams.dateCreated = matchingRecordEntry.recordsWrite?.descriptor.dateCreated; + 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 }); @@ -326,10 +326,6 @@ export class DwnDataStore = Jwk> implem messageParams : { filter: { recordId } } }); - if (readReply.status.code !== 200 || !readReply.entry) { - throw new Error(`${this.name}: Failed to read data from DWN for: ${recordId}`); - } - return readReply.entry; } }