Skip to content

Commit

Permalink
collision logic + fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Mariano Goldman committed Apr 9, 2024
1 parent eb4f333 commit 881001b
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 37 deletions.
45 changes: 40 additions & 5 deletions src/adapters/worlds-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,19 @@ export async function createWorldsManagerComponent({
const fileInfos = await storage.fileInfoMultiple(scene.content?.map((c) => c.hash) || [])
const size = scene.content?.reduce((acc, c) => acc + (fileInfos.get(c.hash)?.size || 0), 0) || 0

const sqlWorld = SQL`
const existingScenes = await getDeployedScenesForWorld(worldName)
const collidingScenes = await findCollisions(scene, existingScenes)

try {
await database.query(SQL`BEGIN`)
await database.query(
SQL`DELETE
FROM scenes
WHERE world_name = ${worldName.toLowerCase()}
AND entity_id = ANY (${collidingScenes.map((s) => s.entity_id)})`
)

const sqlWorld = SQL`
INSERT INTO worlds (name, owner, permissions, created_at, updated_at)
VALUES (${worldName.toLowerCase()},
${owner?.toLowerCase()},
Expand All @@ -97,9 +109,9 @@ export async function createWorldsManagerComponent({
DO UPDATE SET owner = ${owner?.toLowerCase()},
updated_at = ${new Date()}
`
await database.query(sqlWorld)
await database.query(sqlWorld)

const sqlScene = SQL`
const sqlScene = SQL`
INSERT INTO scenes (world_name, entity_id, deployer, deployment_auth_chain, entity, size, created_at, updated_at)
VALUES (${worldName.toLowerCase()},
${scene.id},
Expand All @@ -117,7 +129,13 @@ export async function createWorldsManagerComponent({
size = ${size},
updated_at = ${new Date()}
`
await database.query(sqlScene)
await database.query(sqlScene)
await database.query(SQL`COMMIT`)
} catch (error: any) {
logger.warn(`Error deploying scene: ${error.message}`)
await database.query(SQL`ROLLBACK`)
throw error
}
}

async function storePermissions(worldName: string, permissions: Permissions): Promise<void> {
Expand Down Expand Up @@ -174,7 +192,7 @@ export async function createWorldsManagerComponent({
}

const result = await database.query<Pick<SceneRecord, 'entity_id' | 'entity'>>(
SQL`SELECT entity_id, entity FROM scenes WHERE world_name = ${worldName.toLowerCase()} ORDER BY name`
SQL`SELECT entity_id, entity FROM scenes WHERE world_name = ${worldName.toLowerCase()} ORDER BY world_name`
)

if (result.rowCount === 0) {
Expand All @@ -193,6 +211,23 @@ export async function createWorldsManagerComponent({
await database.query(SQL`DELETE FROM scenes WHERE world_name = ${worldName.toLowerCase()}`)
}

async function getDeployedScenesForWorld(worldName: string): Promise<SceneRecord[]> {
const result = await database.query<SceneRecord>(
SQL`SELECT * FROM scenes WHERE world_name = ${worldName.toLowerCase()} ORDER BY created_at DESC`
)

return result.rows
}

async function findCollisions(entity: Entity, previousScenes: SceneRecord[]): Promise<SceneRecord[]> {
const newParcels = new Set(entity.pointers)
return previousScenes.filter(
(row) =>
newParcels.has(row.entity.metadata.scene.base) ||
row.entity.metadata.scene.parcels.some((parcel: string) => newParcels.has(parcel))
)
}

return {
getRawSceneRecords,
getDeployedWorldCount,
Expand Down
1 change: 0 additions & 1 deletion src/logic/world-runtime-metadata-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ export function extractWorldRuntimeMetadata(worldName: string, entities: Entity[
name: worldName,
entityIds: entities.map(({ id }) => id)
} as WorldRuntimeMetadata
// migrateConfiguration(worldName, entity.metadata?.worldConfiguration)

function resolveFilename(entity: Entity, filename: string | undefined): string | undefined {
if (filename) {
Expand Down
3 changes: 0 additions & 3 deletions test/integration/deploy.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ test('deployment works', function ({ components, stubComponents }) {

const stored = await worldsManager.getMetadataForWorld(worldName)
expect(stored).toMatchObject({
entityId,
runtimeMetadata: {
name: worldName,
entityIds: [entityId],
Expand Down Expand Up @@ -170,7 +169,6 @@ test('deployment works', function ({ components, stubComponents }) {

const stored = await worldsManager.getMetadataForWorld(worldName)
expect(stored).toMatchObject({
entityId,
runtimeMetadata: {
entityIds: [entityId],
minimapVisible: false,
Expand Down Expand Up @@ -228,7 +226,6 @@ test('deployment works', function ({ components, stubComponents }) {

const stored = await worldsManager.getMetadataForWorld(worldName)
expect(stored).toMatchObject({
entityId,
runtimeMetadata: {
name: worldName,
entityIds: [entityId],
Expand Down
61 changes: 35 additions & 26 deletions test/mocks/worlds-manager-mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import {
IPermissionChecker,
IWorldsManager,
Permissions,
WorldMetadata,
WorldRecord
SceneRecord,
WorldMetadata
} from '../../src/types'
import { bufferToStream, streamToBuffer } from '@dcl/catalyst-storage'
import { Entity } from '@dcl/schemas'
Expand All @@ -15,38 +15,48 @@ import { createPermissionChecker, defaultPermissions } from '../../src/logic/per
export async function createWorldsManagerMockComponent({
storage
}: Pick<AppComponents, 'storage'>): Promise<IWorldsManager> {
async function getRawWorldRecords(): Promise<WorldRecord[]> {
const worlds: WorldRecord[] = []
async function getRawSceneRecords(): Promise<SceneRecord[]> {
const scenes: SceneRecord[] = []
for await (const key of storage.allFileIds('name-')) {
const entity = await getEntityForWorld(key.substring(5))
if (entity) {
const content = await storage.retrieve(`${entity.id}.auth`)
const authChain = JSON.parse((await streamToBuffer(await content?.asStream())).toString())
worlds.push({
name: entity.metadata.worldConfiguration.name,
deployer: authChain[0].payload,
entity_id: entity.id,
const metadata = await getMetadataForWorld(key)
if (!metadata || metadata.runtimeMetadata.entityIds.length === 0) {
continue
}
for (const entityId of metadata.runtimeMetadata.entityIds) {
const content = await storage.retrieve(entityId)
if (!content) {
continue
}

const json = JSON.parse((await streamToBuffer(await content.asStream())).toString())
const authChainText = await storage.retrieve(`${entityId}.auth`)
const authChain = JSON.parse((await streamToBuffer(await authChainText?.asStream())).toString())

scenes.push({
world_name: key,
entity_id: entityId,
entity: json,
deployment_auth_chain: authChain,
entity: entity.metadata,
created_at: new Date(1706019701900),
updated_at: new Date(1706019701900),
permissions: { ...defaultPermissions() },
size: 0n,
owner: authChain[0].payload,
blocked_since: null
deployer: authChain[0].payload,
size: 0n
})
}
}
return worlds
return scenes
}

async function getEntityForWorld(worldName: string): Promise<Entity | undefined> {
const metadata = await getMetadataForWorld(worldName)
if (!metadata || !metadata.entityId) {
if (
!metadata ||
!metadata.runtimeMetadata ||
!metadata.runtimeMetadata.entityIds ||
metadata.runtimeMetadata.entityIds.length === 0
) {
return undefined
}

const content = await storage.retrieve(metadata.entityId)
const content = await storage.retrieve(metadata.runtimeMetadata.entityIds[0])
if (!content) {
return undefined
}
Expand All @@ -55,7 +65,7 @@ export async function createWorldsManagerMockComponent({

return {
...json,
id: metadata.entityId
id: metadata.runtimeMetadata.entityIds[0]
}
}

Expand All @@ -80,8 +90,7 @@ export async function createWorldsManagerMockComponent({

async function deployScene(worldName: string, scene: Entity): Promise<void> {
await storeWorldMetadata(worldName, {
entityId: scene.id,
runtimeMetadata: extractWorldRuntimeMetadata(worldName, scene)
runtimeMetadata: extractWorldRuntimeMetadata(worldName, [scene])
})
}

Expand Down Expand Up @@ -122,7 +131,7 @@ export async function createWorldsManagerMockComponent({
}

return {
getRawWorldRecords,
getRawSceneRecords,
getDeployedWorldCount,
getDeployedWorldEntities,
getMetadataForWorld,
Expand Down
12 changes: 10 additions & 2 deletions test/unit/world-indexer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,23 @@ describe('All data from worlds', function () {
'name-world-name.dcl.eth',
bufferToStream(
Buffer.from(
stringToUtf8Bytes(JSON.stringify({ entityId: 'bafkreielwj3ki46munydwn4ayazdvmjln76khmz2xyaf5v6dkmo6yoebbi' }))
stringToUtf8Bytes(
JSON.stringify({
runtimeMetadata: { entityIds: ['bafkreielwj3ki46munydwn4ayazdvmjln76khmz2xyaf5v6dkmo6yoebbi'] }
})
)
)
)
)
await storage.storeStream(
'name-another-world-name.dcl.eth',
bufferToStream(
Buffer.from(
stringToUtf8Bytes(JSON.stringify({ entityId: 'bafkreic6ix3pdwf7g24reg4ktlyjpmtbqbc2nq4zocupkmul37am4vlt6y' }))
stringToUtf8Bytes(
JSON.stringify({
runtimeMetadata: { entityIds: ['bafkreic6ix3pdwf7g24reg4ktlyjpmtbqbc2nq4zocupkmul37am4vlt6y'] }
})
)
)
)
)
Expand Down

0 comments on commit 881001b

Please sign in to comment.