Skip to content

Commit 982af55

Browse files
authored
Merge pull request #135 from OceanProtocolEnterprise/feat/double-decryption
Feat/double decryption
2 parents b9cbd6e + 0c2f3a4 commit 982af55

5 files changed

Lines changed: 76 additions & 20 deletions

File tree

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ocean-node",
3-
"version": "3.1.11",
3+
"version": "3.1.12",
44
"description": "Ocean Node is used to run all core services in the Ocean stack",
55
"author": "Ocean Protocol Foundation",
66
"license": "Apache-2.0",

src/components/Indexer/processors/BaseProcessor.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -210,9 +210,14 @@ export abstract class BaseEventProcessor {
210210
}
211211

212212
protected checkDdoHash(decryptedDocument: any, documentHashFromContract: any): boolean {
213-
const utf8Bytes = toUtf8Bytes(JSON.stringify(decryptedDocument))
213+
const documentString = JSON.stringify(decryptedDocument)
214+
const utf8Bytes = toUtf8Bytes(documentString)
214215
const expectedMetadata = hexlify(utf8Bytes)
215-
if (create256Hash(expectedMetadata.toString()) !== documentHashFromContract) {
216+
const validHashes = [
217+
create256Hash(expectedMetadata.toString()),
218+
create256Hash(documentString)
219+
]
220+
if (!validHashes.includes(documentHashFromContract)) {
216221
INDEXER_LOGGER.error(`DDO checksum does not match.`)
217222
return false
218223
}
@@ -317,6 +322,9 @@ export abstract class BaseEventProcessor {
317322
chainId,
318323
decrypterAddress: ethAddress,
319324
dataNftAddress: contractAddress,
325+
encryptedDocument: txId ? undefined : metadata,
326+
flags: parseInt(flag),
327+
documentHash: metadataHash || undefined,
320328
signature,
321329
nonce
322330
}
@@ -383,7 +391,7 @@ export abstract class BaseEventProcessor {
383391
ddo = JSON.parse(response.data)
384392
responseHash = create256Hash(ddo)
385393
}
386-
if (responseHash !== metadataHash) {
394+
if (metadataHash && responseHash !== metadataHash) {
387395
const msg = `Hash check failed: response=${ddo}, decrypted ddo hash=${responseHash}\n metadata hash=${metadataHash}`
388396
INDEXER_LOGGER.log(LOG_LEVELS_STR.LEVEL_ERROR, msg)
389397
throw new Error(msg)
@@ -429,6 +437,7 @@ export abstract class BaseEventProcessor {
429437
decrypterAddress: ethAddress,
430438
chainId,
431439
encryptedDocument: metadata,
440+
flags: parseInt(flag),
432441
documentHash: metadataHash,
433442
dataNftAddress: contractAddress,
434443
signature,
@@ -491,6 +500,7 @@ export abstract class BaseEventProcessor {
491500
decrypterAddress: ethAddress,
492501
chainId,
493502
encryptedDocument: metadata,
503+
flags: parseInt(flag),
494504
documentHash: metadataHash,
495505
dataNftAddress: contractAddress,
496506
signature,

src/components/Indexer/processors/MetadataEventProcessor.ts

Lines changed: 59 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,16 @@ import { getConfiguration } from '../../../utils/config.js'
2323
import { isRemoteDDO } from '../../core/utils/validateDdoHandler.js'
2424

2525
export class MetadataEventProcessor extends BaseEventProcessor {
26+
private isDDO(data: any): data is Record<string, any> {
27+
return (
28+
data &&
29+
typeof data === 'object' &&
30+
!Array.isArray(data) &&
31+
typeof data.id === 'string' &&
32+
typeof data.version === 'string'
33+
)
34+
}
35+
2636
async processEvent(
2737
event: ethers.Log,
2838
chainId: number,
@@ -122,25 +132,57 @@ export class MetadataEventProcessor extends BaseEventProcessor {
122132
metadataHash,
123133
metadata
124134
)
135+
const isRemoteMetadata = isRemoteDDO(decryptDDO)
136+
const isEncryptedMetadata = (parseInt(flag) & 2) !== 0
125137
let ddo = await this.processDDO(decryptDDO)
126-
if (
127-
!isRemoteDDO(decryptDDO) &&
128-
parseInt(flag) !== 2 &&
129-
!this.checkDdoHash(ddo, metadataHash)
130-
) {
138+
if (!isEncryptedMetadata && !this.checkDdoHash(ddo, metadataHash)) {
131139
return
132140
}
133141
if (ddo.encryptedData) {
142+
let { encryptedData } = ddo
143+
if ((parseInt(flag) & 2) !== 0) {
144+
try {
145+
const decryptedIpfsPayload = await this.decryptDDO(
146+
decodedEventData.args[2],
147+
flag,
148+
owner,
149+
event.address,
150+
chainId,
151+
'',
152+
'',
153+
ddo.encryptedData
154+
)
155+
encryptedData = decryptedIpfsPayload.encryptedData || encryptedData
156+
} catch (error) {
157+
INDEXER_LOGGER.log(
158+
LOG_LEVELS_STR.LEVEL_ERROR,
159+
`Unable to decrypt encrypted IPFS DDO payload, trying plaintext payload fallback: ${
160+
error instanceof Error ? error.message : String(error)
161+
}`
162+
)
163+
}
164+
}
165+
134166
const proof = await this.decryptDDOIPFS(
135167
decodedEventData.args[2],
136168
owner,
137-
ddo.encryptedData
169+
encryptedData
138170
)
139-
const data = this.getDataFromProof(proof)
140-
const ddoInstance = DDOManager.getDDOClass(data.ddoObj)
141-
ddo = ddoInstance.updateFields({
142-
proof: { signature: data.signature, header: data.header }
143-
})
171+
const data = typeof proof === 'string' ? this.getDataFromProof(proof) : null
172+
173+
const ddoObj = data?.ddoObj || (this.isDDO(proof) ? proof : null)
174+
if (!ddoObj) {
175+
throw new Error(
176+
'IPFS encryptedData payload is neither a DDO nor a supported DDO proof.'
177+
)
178+
}
179+
const ddoInstance = DDOManager.getDDOClass(ddoObj)
180+
ddo =
181+
data?.signature && data?.header
182+
? ddoInstance.updateFields({
183+
proof: { signature: data.signature, header: data.header }
184+
})
185+
: ddoInstance.getDDOData()
144186
}
145187
const clonedDdo = structuredClone(ddo)
146188
const updatedDdo = deleteIndexedMetadataIfExists(clonedDdo)
@@ -159,8 +201,12 @@ export class MetadataEventProcessor extends BaseEventProcessor {
159201
)
160202
return
161203
}
162-
// for unencrypted DDOs
163-
if ((parseInt(flag) & 2) === 0 && !this.checkDdoHash(updatedDdo, metadataHash)) {
204+
// for unencrypted inline DDOs
205+
if (
206+
!isRemoteMetadata &&
207+
!isEncryptedMetadata &&
208+
!this.checkDdoHash(updatedDdo, metadataHash)
209+
) {
164210
INDEXER_LOGGER.error('Unencrypted DDO hash does not match metadata hash.')
165211
await ddoState.update(
166212
this.networkId,

src/components/core/handler/ddoHandler.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ export class DecryptDdoHandler extends CommandHandler {
357357
} else {
358358
// checksum matches
359359
const decryptedDocumentHash = create256Hash(decryptedDocument.toString())
360-
if (decryptedDocumentHash !== documentHash) {
360+
if (documentHash && decryptedDocumentHash !== documentHash) {
361361
return {
362362
stream: null,
363363
status: {

0 commit comments

Comments
 (0)