Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
4 changes: 4 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ jobs:

test-content:
runs-on: ubuntu-latest
env:
NODE_OPTIONS: "--max-old-space-size=8192"
services:
postgres:
image: postgres
Expand Down Expand Up @@ -55,6 +57,8 @@ jobs:

test-lambdas:
runs-on: ubuntu-latest
env:
NODE_OPTIONS: "--max-old-space-size=8192"
steps:
- uses: actions/checkout@v4
- name: Use Node.js 24.x
Expand Down
16 changes: 6 additions & 10 deletions content/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"@dcl/content-validator": "^7.0.3",
"@dcl/crypto": "^3.4.5",
"@dcl/hashing": "^3.0.4",
"@dcl/job-component": "^0.2.7",
"@dcl/job-component": "^0.2.8",
"@dcl/schemas": "^20.1.1",
"@dcl/snapshots-fetcher": "^9.1.0",
"@dcl/urn-resolver": "^3.6.0",
Expand Down Expand Up @@ -64,7 +64,7 @@
"@types/faker": "5.5.9",
"@types/jest": "27.4.1",
"@types/lru-cache": "7.6.1",
"@types/node": "17.0.45",
"@types/node": "^24",
"@types/pg": "^8",
"@types/uuid": "^8",
"@typescript-eslint/eslint-plugin": "5.33.0",
Expand All @@ -76,19 +76,15 @@
"eslint-config-prettier": "8.5.0",
"eslint-plugin-prettier": "4.2.1",
"faker": "5.5.3",
"jest": "27.4.7",
"jest": "^30.2.0",
"jest-extra-utils": "^0.1.0",
"jest-junit": "^13.0.0",
"jest-leak-detector": "^29.3.1",
"lint-staged": "13.0.3",
"nyc": "^15.1.0",
"prettier": "2.7.1",
"testcontainers": "8.9.0",
"ts-jest": "27.1.5",
"ts-mockito": "2.6.1",
"ts-node": "10.7.0",
"tsc": "2.0.4",
"typescript": "^4.7.4"
"ts-jest": "^29.4.6",
"ts-node": "^10.9.2",
"typescript": "^5.9.3"
},
"resolutions": {
"@well-known-components/http-server/path-to-regexp": "^6.2.1",
Expand Down
24 changes: 12 additions & 12 deletions content/src/Environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,22 @@ export const DEFAULT_ETH_NETWORK = 'sepolia'
export const DEFAULT_ENS_OWNER_PROVIDER_URL_TESTNET =
'https://api.studio.thegraph.com/query/49472/marketplace-sepolia/version/latest'
const DEFAULT_ENS_OWNER_PROVIDER_URL_MAINNET = 'https://subgraph.decentraland.org/marketplace'
export const DEFAULT_LAND_MANAGER_SUBGRAPH_TESTNET =
const DEFAULT_LAND_MANAGER_SUBGRAPH_TESTNET =
'https://api.studio.thegraph.com/query/49472/land-manager-sepolia/version/latest'
export const DEFAULT_LAND_MANAGER_SUBGRAPH_MAINNET = 'https://subgraph.decentraland.org/land-manager'
export const DEFAULT_COLLECTIONS_SUBGRAPH_TESTNET =
const DEFAULT_LAND_MANAGER_SUBGRAPH_MAINNET = 'https://subgraph.decentraland.org/land-manager'
const DEFAULT_COLLECTIONS_SUBGRAPH_TESTNET =
'https://api.studio.thegraph.com/query/49472/collections-ethereum-sepolia/version/latest'
export const DEFAULT_COLLECTIONS_SUBGRAPH_MAINNET = 'https://subgraph.decentraland.org/collections-ethereum-mainnet'
export const DEFAULT_COLLECTIONS_SUBGRAPH_MATIC_MAINNET = 'https://subgraph.decentraland.org/collections-matic-mainnet'
export const DEFAULT_COLLECTIONS_SUBGRAPH_MATIC_AMOY = 'https://subgraph.decentraland.org/collections-matic-amoy'
export const DEFAULT_THIRD_PARTY_REGISTRY_SUBGRAPH_MATIC_AMOY = 'https://subgraph.decentraland.org/tpr-matic-amoy'
export const DEFAULT_THIRD_PARTY_REGISTRY_SUBGRAPH_MATIC_MAINNET = 'https://subgraph.decentraland.org/tpr-matic-mainnet'
export const DEFAULT_BLOCKS_SUBGRAPH_TESTNET =
const DEFAULT_COLLECTIONS_SUBGRAPH_MAINNET = 'https://subgraph.decentraland.org/collections-ethereum-mainnet'
const DEFAULT_COLLECTIONS_SUBGRAPH_MATIC_MAINNET = 'https://subgraph.decentraland.org/collections-matic-mainnet'
const DEFAULT_COLLECTIONS_SUBGRAPH_MATIC_AMOY = 'https://subgraph.decentraland.org/collections-matic-amoy'
const DEFAULT_THIRD_PARTY_REGISTRY_SUBGRAPH_MATIC_AMOY = 'https://subgraph.decentraland.org/tpr-matic-amoy'
const DEFAULT_THIRD_PARTY_REGISTRY_SUBGRAPH_MATIC_MAINNET = 'https://subgraph.decentraland.org/tpr-matic-mainnet'
const DEFAULT_BLOCKS_SUBGRAPH_TESTNET =
'https://api.studio.thegraph.com/query/49472/blocks-ethereum-sepolia/version/latest'
export const DEFAULT_BLOCKS_SUBGRAPH_MAINNET = 'https://subgraph.decentraland.org/blocks-ethereum-mainnet'
export const DEFAULT_BLOCKS_SUBGRAPH_MATIC_AMOY =
const DEFAULT_BLOCKS_SUBGRAPH_MAINNET = 'https://subgraph.decentraland.org/blocks-ethereum-mainnet'
const DEFAULT_BLOCKS_SUBGRAPH_MATIC_AMOY =
'https://api.studio.thegraph.com/query/49472/blocks-matic-amoy/version/latest'
export const DEFAULT_BLOCKS_SUBGRAPH_MATIC_MAINNET = 'https://subgraph.decentraland.org/blocks-matic-mainnet'
const DEFAULT_BLOCKS_SUBGRAPH_MATIC_MAINNET = 'https://subgraph.decentraland.org/blocks-matic-mainnet'

export const CURRENT_COMMIT_HASH = process.env.COMMIT_HASH ?? 'Unknown'
export const CURRENT_VERSION = process.env.CURRENT_VERSION ?? 'Unknown'
Expand Down
4 changes: 2 additions & 2 deletions content/src/logic/formatters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import * as utils from 'eth-connect'
*
* @param blockNumber - The given blocknumber
*/
export function isPredefinedBlockNumber(blockNumber: utils.Quantity | utils.Tag): blockNumber is utils.Tag {
function isPredefinedBlockNumber(blockNumber: utils.Quantity | utils.Tag): blockNumber is utils.Tag {
return blockNumber === 'latest' || blockNumber === 'pending' || blockNumber === 'earliest'
}

Expand Down Expand Up @@ -62,7 +62,7 @@ export function inputCallFormatter(options: utils.TransactionOptions) {
return options
}

export function inputAddressFormatter(address: string) {
function inputAddressFormatter(address: string) {
if (utils.isStrictAddress(address)) {
return address
} else if (utils.isAddress(address)) {
Expand Down
2 changes: 1 addition & 1 deletion content/src/logic/time-range.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { TimeRange } from '@dcl/snapshots-fetcher/dist/types'

export type TimeRangeDivision = {
type TimeRangeDivision = {
intervals: TimeRange[]
remainder: TimeRange
}
Expand Down
7 changes: 3 additions & 4 deletions content/src/ports/activeEntities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,12 @@ import { IBaseComponent } from '@well-known-components/interfaces'
import { parseUrn } from '@dcl/urn-resolver'

export const BASE_AVATARS_COLLECTION_ID = 'urn:decentraland:off-chain:base-avatars'
export const BASE_EMOTES_COLLECTION_ID = 'urn:decentraland:off-chain:base-emotes'

export type NotActiveEntity = 'NOT_ACTIVE_ENTITY'
type NotActiveEntity = 'NOT_ACTIVE_ENTITY'

export const isEntityPresent = (result: Entity | NotActiveEntity | undefined): result is Entity =>
const isEntityPresent = (result: Entity | NotActiveEntity | undefined): result is Entity =>
result !== undefined && result !== 'NOT_ACTIVE_ENTITY'
export const isPointingToEntity = (result: string | NotActiveEntity | undefined): result is string =>
const isPointingToEntity = (result: string | NotActiveEntity | undefined): result is string =>
result !== undefined && result !== 'NOT_ACTIVE_ENTITY'

export type ActiveEntities = IBaseComponent & {
Expand Down
2 changes: 1 addition & 1 deletion content/src/ports/denylist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export async function createDenylist(
logger.error(err)
}
}
let reloadTimer: NodeJS.Timer | undefined = undefined
let reloadTimer: ReturnType<typeof setInterval> | undefined = undefined
return {
isDenylisted: (id: string): boolean => {
const denied = deniedContentIdentifiers.has(id)
Expand Down
2 changes: 1 addition & 1 deletion content/src/ports/deployer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { happenedBefore } from '../service/time/TimeSorting'
import { AppComponents, EntityVersion } from '../types'
import { DatabaseClient } from './postgres'

export function isIPFSHash(hash: string): boolean {
function isIPFSHash(hash: string): boolean {
return IPFSv2.validate(hash)
}

Expand Down
12 changes: 9 additions & 3 deletions content/src/ports/postgres.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ export type DatabaseTransactionalClient = DatabaseClient & {
}

export interface IDatabaseComponent extends IDatabase, IBaseComponent {
queryWithValues<T>(sql: SQLStatement, durationQueryNameLabel?: string): Promise<IDatabase.IQueryResult<T>>
queryWithValues<T extends Record<string, any>>(
sql: SQLStatement,
durationQueryNameLabel?: string
): Promise<IDatabase.IQueryResult<T>>
streamQuery<T = any>(
sql: SQLStatement,
config?: { batchSize?: number },
Expand Down Expand Up @@ -92,14 +95,17 @@ export async function createDatabase(
const queryClient = initializedClient ? initializedClient : pool

return {
async query<T>(sql: string): Promise<IDatabase.IQueryResult<T>> {
async query<T extends Record<string, any>>(sql: string): Promise<IDatabase.IQueryResult<T>> {
const rows = await queryClient.query<T[]>(sql)
return {
rows: rows.rows as any[],
rowCount: rows.rowCount
}
},
async queryWithValues<T>(sql: SQLStatement, durationQueryNameLabel?: string): Promise<IDatabase.IQueryResult<T>> {
async queryWithValues<T extends Record<string, any>>(
sql: SQLStatement,
durationQueryNameLabel?: string
): Promise<IDatabase.IQueryResult<T>> {
const endTimer = startTimer(durationQueryNameLabel)
try {
const rows = await queryClient.query<T[]>(sql)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import SQL from 'sql-template-strings'

const PROFILE_CLEANUP_LIMIT = 10000

export type GCStaleProfilesResult = {
type GCStaleProfilesResult = {
deletedHashes: Set<string>
deletedDeployments: Set<string>
}
Expand Down
2 changes: 1 addition & 1 deletion content/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ export enum EntityVersion {

export type CannonicalEntityDeployment = { entity: SyncDeployment; servers: string[] }

export type StatusProbeResult = {
type StatusProbeResult = {
/** name is used as unique key for the status map */
name: string
data: Record<string, any>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { instance, mock, when } from 'ts-mockito'
import { ContentCluster } from '../../../../src/service/synchronization/ContentCluster'

export class MockedContentCluster {
static withAddress(ethAddress: string): ContentCluster {
const mockedCluster: ContentCluster = mock(ContentCluster)
when(mockedCluster.getIdentity()).thenResolve({ owner: ethAddress, address: '', id: '0' })
return instance(mockedCluster)
static withAddress(ethAddress: string): jest.Mocked<ContentCluster> {
return {
getIdentity: jest.fn().mockResolvedValue({ owner: ethAddress, address: '', id: '0' })
} as unknown as jest.Mocked<ContentCluster>
}
}
6 changes: 4 additions & 2 deletions content/test/integration/E2EAssertions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ export async function assertEntitiesAreDeployedButNotActive(server: TestProgram,
assert.equal(
unexpectedEntities.length,
0,
`Expected not to find entity with id ${entity.id} when checking for pointer ${entity.pointers
`Expected not to find entity with id ${entity.id} when checking for pointer ${
entity.pointers
} on server '${server.getUrl()}.'`
)
await assertEntityIsOnServer(server, entity)
Expand Down Expand Up @@ -83,7 +84,8 @@ export async function assertDeploymentsAreReported(server: TestProgram, ...expec
assert.equal(
deployments.length,
expectedDeployments.length,
`Expected to find ${expectedDeployments.length} deployments on server ${server.getUrl()}. Instead, found ${deployments.length
`Expected to find ${expectedDeployments.length} deployments on server ${server.getUrl()}. Instead, found ${
deployments.length
}.`
)

Expand Down
20 changes: 10 additions & 10 deletions content/test/integration/logic/snapshots.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ describe('snapshot generator - ', () => {
const timeRange = timeRangeOfDaysFromInitialTimestamp(1)

const snapshots = await generateSnapshotsInMultipleTimeRanges(components, timeRange)
expect(divideTimeSpy).toBeCalledWith(timeRange)
expect(divideTimeSpy).toHaveBeenCalledWith(timeRange)
expect(snapshots).toEqual(expect.arrayContaining([expect.objectContaining(emptySnapshot)]))
if (snapshots) {
const exist = await components.storage.existMultiple(snapshots.map((s) => s.hash))
expect(Array.from(exist.values()).every((e) => e)).toBeTruthy()
}
expect(clockSpy).toBeCalledTimes(1)
expect(clockSpy).toHaveBeenCalledTimes(1)
})

testCaseWithComponents(
Expand All @@ -49,7 +49,7 @@ describe('snapshot generator - ', () => {
expect(snapshots).toEqual(
expect.arrayContaining([expect.objectContaining(emptySnapshot), expect.objectContaining(emptySnapshot)])
)
expect(clockSpy).toBeCalledTimes(2)
expect(clockSpy).toHaveBeenCalledTimes(2)
}
)

Expand Down Expand Up @@ -79,7 +79,7 @@ describe('snapshot generator - ', () => {
])
)
// It's called one time every time a snapshot is created
expect(clockSpy).toBeCalledTimes(7)
expect(clockSpy).toHaveBeenCalledTimes(7)
}
)

Expand All @@ -100,7 +100,7 @@ describe('snapshot generator - ', () => {

// It's called one time every time a snapshot is created
// 7 daily + (1 weekly + 1 daily)
expect(clockSpy).toBeCalledTimes(9)
expect(clockSpy).toHaveBeenCalledTimes(9)

const weeklySnapshot = snapshots[0]
expect(weeklySnapshot).toEqual({
Expand Down Expand Up @@ -131,7 +131,7 @@ describe('snapshot generator - ', () => {
})
// It's called one time every time a snapshot is created
// 7 daily + (1 weekly + 1 daily)
expect(clockSpy).toBeCalledTimes(9)
expect(clockSpy).toHaveBeenCalledTimes(9)
}
)

Expand All @@ -151,7 +151,7 @@ describe('snapshot generator - ', () => {

// It's called one time every time a snapshot is created
// 5 daily + (1 weekly + 1 daily)
expect(clockSpy).toBeCalledTimes(7)
expect(clockSpy).toHaveBeenCalledTimes(7)

const weeklySnapshot = snapshots[0]
expect(weeklySnapshot).toEqual({
Expand Down Expand Up @@ -267,7 +267,7 @@ describe('snapshot generator - ', () => {
const snapshots = await generateSnapshotsInMultipleTimeRanges(components, timeRangeOfDaysFromInitialTimestamp(1))

expect(snapshots).toEqual(expect.arrayContaining([expect.objectContaining({ numberOfEntities: 1 })]))
expect(storeSpy).toBeCalledWith(snapshots[0].hash, expect.anything())
expect(storeSpy).toHaveBeenCalledWith(snapshots[0].hash, expect.anything())
expect(await components.storage.exist(snapshots[0].hash)).toBeTruthy()

// now the snapshot is deleted from storage so it needs to be re-generated
Expand All @@ -278,7 +278,7 @@ describe('snapshot generator - ', () => {
// now the snapshot is re-generated and stored again
const snapshots2 = await generateSnapshotsInMultipleTimeRanges(components, timeRangeOfDaysFromInitialTimestamp(1))
expect(snapshots2).toEqual(expect.arrayContaining([expect.objectContaining({ numberOfEntities: 1 })]))
expect(storeSpy).toBeCalledWith(snapshots2[0].hash, expect.anything())
expect(storeSpy).toHaveBeenCalledWith(snapshots2[0].hash, expect.anything())
expect(await components.storage.exist(snapshots2[0].hash)).toBeTruthy()
})

Expand Down Expand Up @@ -313,7 +313,7 @@ describe('snapshot generator - ', () => {

expect(snapshots).toEqual(expect.arrayContaining([expect.objectContaining({ numberOfEntities: 1 })]))
expect(await components.storage.exist(snapshots[0].hash)).toBeTruthy()
expect(snapshotsNotInTimeRangeSpy).toBeCalledWith(
expect(snapshotsNotInTimeRangeSpy).toHaveBeenCalledWith(
expect.anything(),
expect.arrayContaining(['h1']),
expect.anything()
Expand Down
12 changes: 6 additions & 6 deletions content/test/integration/ports/processedSnapshotStorage.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ describe('precessed snapshot storage', () => {
await saveProcessedSnapshot(components.database, processedSnapshot, Date.now())

await components.processedSnapshotStorage.filterProcessedSnapshotsFrom([processedSnapshot])
expect(dbQuerySpy).toBeCalledTimes(1)
expect(dbQuerySpy).toHaveBeenCalledTimes(1)
// now the result should be cached
dbQuerySpy.mockClear()
await components.processedSnapshotStorage.filterProcessedSnapshotsFrom([processedSnapshot])
expect(dbQuerySpy).toBeCalledTimes(0)
expect(dbQuerySpy).toHaveBeenCalledTimes(0)
})

it('should query the db if not ALL the snapshots are in the cache', async () => {
Expand All @@ -60,7 +60,7 @@ describe('precessed snapshot storage', () => {
// now the snapshot 'processedSnapshot' is cached
const anotherHashNotInCache = 'anotherHashNotInCache'
await components.processedSnapshotStorage.filterProcessedSnapshotsFrom([processedSnapshot, anotherHashNotInCache])
expect(dbQuerySpy).toBeCalledWith(
expect(dbQuerySpy).toHaveBeenCalledWith(
expect.anything(),
expect.arrayContaining([processedSnapshot, anotherHashNotInCache])
)
Expand Down Expand Up @@ -89,7 +89,7 @@ describe('precessed snapshot storage', () => {
otherProcessedSnapshot,
anotherProcessedSnapshot
])
expect(dbQuerySpy).toBeCalledTimes(0)
expect(dbQuerySpy).toHaveBeenCalledTimes(0)
})
})

Expand All @@ -103,7 +103,7 @@ describe('precessed snapshot storage', () => {

await components.processedSnapshotStorage.markSnapshotAsProcessed(processedSnapshot)

expect(saveProcessedSnapshotSpy).toBeCalledWith(expect.anything(), processedSnapshot, expectedProcessTime)
expect(saveProcessedSnapshotSpy).toHaveBeenCalledWith(expect.anything(), processedSnapshot, expectedProcessTime)
})

it('should cache the processed snapshot when saving a snapshot', async () => {
Expand All @@ -114,7 +114,7 @@ describe('precessed snapshot storage', () => {
const processedSnapshots = await components.processedSnapshotStorage.filterProcessedSnapshotsFrom([
processedSnapshot
])
expect(dbQuerySpy).toBeCalledTimes(0)
expect(dbQuerySpy).toHaveBeenCalledTimes(0)
expect(processedSnapshots).toEqual(new Set([processedSnapshot]))
})
})
Expand Down
Loading
Loading