Skip to content

Commit

Permalink
add todos
Browse files Browse the repository at this point in the history
  • Loading branch information
Mariano Goldman committed Aug 28, 2024
1 parent fcef9c4 commit d2f74ee
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 56 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"@types/bcrypt": "^5.0.2",
"@types/node": "^20.11.10",
"@well-known-components/test-helpers": "^1.5.6",
"dcl-catalyst-client": "https://sdk-team-cdn.decentraland.org/@dcl/catalyst-client/branch/deploy-v2/dcl-catalyst-client-21.7.1-9521698381.commit-b45e84a.tgz",
"dcl-catalyst-client": "https://sdk-team-cdn.decentraland.org/@dcl/catalyst-client/branch/deploy-v2/dcl-catalyst-client-21.7.1-10599703790.commit-1aa8621.tgz",
"typescript": "^5.3.3"
},
"prettier": {
Expand Down
114 changes: 64 additions & 50 deletions src/adapters/deployment-v2-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,19 @@ export function createDeploymentV2Manager(
// Check what files are already in storage and temporary storage and return the result
const results = Array.from((await storage.existMultiple(Object.keys(files))).entries())

// TODO we could check the local temp folder to avoid the client uploading the same file multiple times

const ongoingDeploymentMetadata = {
authChain,
files,
availableFiles: results.filter(([_, available]) => !!available).map(([cid, _]) => cid),
missingFiles: results.filter(([_, available]) => !available).map(([cid, _]) => cid)
}

// TODO we could store this in local file system of the ECS
ongoingDeploymentsRecord[entityId] = ongoingDeploymentMetadata

// TODO same
tempFiles[entityId] = entityRaw

return ongoingDeploymentMetadata
Expand All @@ -55,6 +59,9 @@ export function createDeploymentV2Manager(
if (!ongoingDeploymentsRecordElement) {
throw new InvalidRequestError(`Deployment for entity ${entityId} not found`)
}

// TODO we could check if the ongoing deployment is too old, and reject the file

const computedFileHash = await hashV1(file)
if (computedFileHash === entityId || fileHash === computedFileHash) {
if (!ongoingDeploymentsRecordElement.missingFiles.includes(fileHash)) {
Expand All @@ -69,71 +76,78 @@ export function createDeploymentV2Manager(
}
}

// TODO store in temp files folder
tempFiles[fileHash] = file
logger.info(`Received file ${fileHash} for entity ${entityId}`)
}

async function completeDeployment(baseUrl: string, entityId: string): Promise<DeploymentResult> {
const ongoingDeploymentsRecordElement = ongoingDeploymentsRecord[entityId]
if (!ongoingDeploymentsRecordElement) {
throw new Error(`Deployment for entity ${entityId} not found`)
}
try {
const ongoingDeploymentsRecordElement = ongoingDeploymentsRecord[entityId]
if (!ongoingDeploymentsRecordElement) {
throw new Error(`Deployment for entity ${entityId} not found`)
}

logger.info(`Completing deployment for entity ${entityId}`)
// TODO we could check if the ongoing deployment is too old, and reject the file (deployment TTL)

const authChain = ongoingDeploymentsRecordElement.authChain
const entityRaw = tempFiles[entityId].toString()
if (!entityRaw) {
throw new Error(`Entity file not found in deployment for entity ${entityId}.`)
}
logger.info(`Completing deployment for entity ${entityId}`)

const entityMetadataJson = JSON.parse(entityRaw.toString())
const authChain = ongoingDeploymentsRecordElement.authChain
const entityRaw = tempFiles[entityId].toString()
if (!entityRaw) {
throw new Error(`Entity file not found in deployment for entity ${entityId}.`)
}

const entity: Entity = {
id: entityId, // this is not part of the published entity
timestamp: Date.now(), // this is not part of the published entity
...entityMetadataJson
}
const entityMetadataJson = JSON.parse(entityRaw.toString())

const uploadedFiles: Map<string, Uint8Array> = new Map()
for (const fileHash of Object.keys(ongoingDeploymentsRecordElement.files)) {
if (tempFiles[fileHash]) {
uploadedFiles.set(fileHash, tempFiles[fileHash])
const entity: Entity = {
id: entityId, // this is not part of the published entity
timestamp: Date.now(), // this is not part of the published entity
...entityMetadataJson
}
}

const contentHashesInStorage = await storage.existMultiple(Array.from(new Set(entity.content!.map(($) => $.hash))))

// run all validations about the deployment
const validationResult = await validator.validate({
entity,
files: uploadedFiles,
authChain,
contentHashesInStorage
})
if (!validationResult.ok()) {
throw new InvalidRequestError(`Deployment failed: ${validationResult.errors.join(', ')}`)
}
const uploadedFiles: Map<string, Uint8Array> = new Map()
for (const fileHash of Object.keys(ongoingDeploymentsRecordElement.files)) {
if (tempFiles[fileHash]) {
uploadedFiles.set(fileHash, tempFiles[fileHash])
}
}

// Store the entity
const deploymentResult = await entityDeployer.deployEntity(
baseUrl,
entity,
contentHashesInStorage,
uploadedFiles,
entityRaw,
authChain
)

// Clean up temporary files
for (const fileHash in ongoingDeploymentsRecordElement.files) {
delete tempFiles[fileHash]
}
const contentHashesInStorage = await storage.existMultiple(
Array.from(new Set(entity.content!.map(($) => $.hash)))
)

// run all validations about the deployment
const validationResult = await validator.validate({
entity,
files: uploadedFiles,
authChain,
contentHashesInStorage
})
if (!validationResult.ok()) {
throw new InvalidRequestError(`Deployment failed: ${validationResult.errors.join(', ')}`)
}

// Clean up ongoing deployments
delete ongoingDeploymentsRecord[entityId]
// Store the entity
return await entityDeployer.deployEntity(
baseUrl,
entity,
contentHashesInStorage,
uploadedFiles,
entityRaw,
authChain
)
} finally {
// Clean up temporary files
const ongoingDeploymentsRecordElement = ongoingDeploymentsRecord[entityId]

for (const fileHash in ongoingDeploymentsRecordElement.files) {
delete tempFiles[fileHash]
}

return deploymentResult
// Clean up ongoing deployments
delete ongoingDeploymentsRecord[entityId]
}
}

return {
Expand Down
4 changes: 2 additions & 2 deletions src/controllers/handlers/deploy-v2-handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ export async function startDeployEntity(
export async function deployFile(
ctx: HandlerContextWithPath<'deploymentV2Manager', '/v2/entities/:entityId/files/:fileHash'>
): Promise<IHttpServerComponent.IResponse> {
const entityId = await ctx.params.entityId
const fileHash = await ctx.params.fileHash
const entityId = ctx.params.entityId
const fileHash = ctx.params.fileHash
const buffer = await ctx.request.buffer()

await ctx.components.deploymentV2Manager.addFileToDeployment(entityId, fileHash, buffer)
Expand Down
6 changes: 3 additions & 3 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2558,9 +2558,9 @@ cross-spawn@^7.0.2, cross-spawn@^7.0.3:
shebang-command "^2.0.0"
which "^2.0.1"

"dcl-catalyst-client@https://sdk-team-cdn.decentraland.org/@dcl/catalyst-client/branch/deploy-v2/dcl-catalyst-client-21.7.1-9517693754.commit-34d6bdc.tgz":
version "21.7.1-9517693754.commit-34d6bdc"
resolved "https://sdk-team-cdn.decentraland.org/@dcl/catalyst-client/branch/deploy-v2/dcl-catalyst-client-21.7.1-9517693754.commit-34d6bdc.tgz#86be52bf40ba11b714217caee2c4ddfab288a1ed"
"dcl-catalyst-client@https://sdk-team-cdn.decentraland.org/@dcl/catalyst-client/branch/deploy-v2/dcl-catalyst-client-21.7.1-10599703790.commit-1aa8621.tgz":
version "21.7.1-10599703790.commit-1aa8621"
resolved "https://sdk-team-cdn.decentraland.org/@dcl/catalyst-client/branch/deploy-v2/dcl-catalyst-client-21.7.1-10599703790.commit-1aa8621.tgz#3715021ce107e198aa6d718042a53e105206338c"
dependencies:
"@dcl/catalyst-contracts" "^4.4.0"
"@dcl/crypto" "^3.4.0"
Expand Down

0 comments on commit d2f74ee

Please sign in to comment.