Skip to content
Merged
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
2 changes: 1 addition & 1 deletion packages/apps/faucet/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
},
"devDependencies": {
"@types/react": "^18.3.12",
"dotenv": "^16.3.2",
"dotenv": "^17.0.0",
"eslint": "^8.55.0",
"eslint-config-react-app": "^7.0.1",
"eslint-import-resolver-typescript": "^3.7.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/apps/faucet/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"web3": "^4.12.1"
},
"devDependencies": {
"@types/cors": "^2.8.17",
"@types/cors": "^2.8.19",
"@types/express": "^4.17.14",
"@types/node": "^22.15.16",
"concurrently": "^9.1.2",
Expand Down
2 changes: 1 addition & 1 deletion packages/apps/fortune/exchange-oracle/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"body-parser": "^1.20.3",
"class-transformer": "^0.5.1",
"class-validator": "0.14.1",
"dotenv": "^16.3.2",
"dotenv": "^17.0.0",
"ethers": "~6.13.5",
"joi": "^17.13.3",
"jsonwebtoken": "^9.0.2",
Expand Down
2 changes: 1 addition & 1 deletion packages/apps/fortune/recording-oracle/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"body-parser": "^1.20.2",
"class-transformer": "^0.5.1",
"class-validator": "0.14.1",
"dotenv": "^16.3.2",
"dotenv": "^17.0.0",
"helmet": "^7.1.0",
"joi": "^17.13.3",
"minio": "7.1.3",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ async function fetchActiveProposalFn() {
const logs = await contract.queryFilter(
filter,
env.VITE_NETWORK === 'mainnet'
? 68058296
? (await provider.getBlockNumber()) - 100000
: (await provider.getBlockNumber()) - 10000,
'latest'
);
Expand Down
5 changes: 5 additions & 0 deletions packages/apps/human-app/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,12 @@
"@nestjs/common": "^10.2.7",
"@nestjs/config": "^3.1.1",
"@nestjs/core": "^10.3.10",
"@nestjs/passport": "^10.0.0",
"@nestjs/platform-express": "^10.3.10",
"@nestjs/schedule": "^4.0.1",
"@nestjs/swagger": "^7.4.2",
"@nestjs/terminus": "^11.0.0",
"@types/passport-jwt": "^4.0.1",
"axios": "^1.7.2",
"cache-manager": "^5.4.0",
"cache-manager-redis-yet": "^5.1.5",
Expand All @@ -45,6 +47,8 @@
"jsonwebtoken": "^9.0.2",
"jwt-decode": "^4.0.0",
"lodash": "^4.17.21",
"passport": "^0.7.0",
"passport-jwt": "^4.0.1",
"reflect-metadata": "^0.2.2",
"rxjs": "^7.2.0"
},
Expand All @@ -57,6 +61,7 @@
"@types/jsonwebtoken": "^9.0.7",
"@types/lodash": "^4.17.14",
"@types/node": "22.10.5",
"@types/passport": "^0",
"@types/supertest": "^2.0.15",
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.0.0",
Expand Down
1 change: 1 addition & 0 deletions packages/apps/human-app/server/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ const JOI_BOOLEAN_STRING_SCHEMA = Joi.string().valid('true', 'false');
CACHE_TTL_DAILY_HMT_SPENT: Joi.number(),
CACHE_TTL_HCAPTCHA_USER_STATS: Joi.number(),
CACHE_TTL_ORACLE_DISCOVERY: Joi.number(),
CACHE_TTL_ORACLE_AVAILABLE_JOBS: Joi.number(),
JOB_ASSIGNMENTS_DATA_RETENTION_DAYS: Joi.number(),
CACHE_TTL_EXCHANGE_ORACLE_URL: Joi.number(),
CACHE_TTL_EXCHANGE_ORACLE_REGISTRATION_NEEDED: Joi.number(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const DEFAULT_CACHE_TTL_HCAPTCHA_USER_STATS = 12 * 60 * 60;
const DEFAULT_CACHE_TTL_ORACLE_STATS = 12 * 60 * 60;
const DEFAULT_CACHE_TTL_USER_STATS = 15 * 60;
const DEFAULT_CACHE_TTL_ORACLE_DISCOVERY = 24 * 60 * 60;
const DEFAULT_CACHE_TTL_ORACLE_AVAILABLE_JOBS = 2 * 60;
const DEFAULT_JOB_ASSIGNMENTS_DATA_RETENTION_DAYS = 45;
const DEFAULT_CACHE_TTL_DAILY_HMT_SPENT = 24 * 60 * 60;
const DEFAULT_CORS_ALLOWED_ORIGIN = 'http://localhost:5173';
Expand Down Expand Up @@ -164,6 +165,19 @@ export class EnvironmentConfigService {
);
}

/**
* The cache time-to-live (TTL) for oracle's available jobs.
* Default: 2 minutes
*/
get cacheTtlOracleAvailableJobs(): number {
return (
this.configService.get<number>(
'CACHE_TTL_ORACLE_AVAILABLE_JOBS',
DEFAULT_CACHE_TTL_ORACLE_AVAILABLE_JOBS,
) * 1000
);
}

/**
* Number of days without updates assignments data is retained.
* Default: 45 days
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ export class JwtHttpStrategy extends PassportStrategy(Strategy, 'jwt-http') {
);
done(null, pubKey);
} catch (error) {
console.error(error);
done(error);
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ export class KvStoreGateway {
if (cachedData) {
return cachedData;
}
let fetchedData: string;
let oracleUrl: string;
try {
const runner = new ethers.JsonRpcProvider(this.configService.rpcUrl);
const network = await runner.provider?.getNetwork();
const chainId: ChainId = Number(network?.chainId);

fetchedData = await KVStoreUtils.get(chainId, address, KVStoreKeys.url);
oracleUrl = await KVStoreUtils.get(chainId, address, KVStoreKeys.url);
} catch (e) {
if (e.toString().includes('Error: Invalid address')) {
throw new HttpException(
Expand All @@ -46,19 +46,23 @@ export class KvStoreGateway {
);
}
}
if (!fetchedData || fetchedData === '') {

if (!oracleUrl || oracleUrl === '') {
throw new HttpException(
`Unable to retrieve URL from address: ${address}`,
400,
);
} else {
await this.cacheManager.set(
key,
fetchedData,
this.configService.cacheTtlExchangeOracleUrl,
);
return fetchedData;
}

oracleUrl = oracleUrl.replace(/\/$/, '');

await this.cacheManager.set(
key,
oracleUrl,
this.configService.cacheTtlExchangeOracleUrl,
);

return oracleUrl;
}

async getJobTypesByAddress(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,12 @@
import { Test, TestingModule } from '@nestjs/testing';
import { KvStoreGateway } from '../kv-store.gateway';
import { ChainId, KVStoreKeys, KVStoreUtils } from '@human-protocol/sdk';
import { EnvironmentConfigService } from '../../../common/config/environment-config.service';
import { CACHE_MANAGER } from '@nestjs/cache-manager';
import { Cache } from 'cache-manager';
import { ORACLE_URL_CACHE_KEY } from '../../../common/constants/cache';

const EXPECTED_URL = 'https://example.com';
jest.mock('@human-protocol/sdk', () => {
const actualSdk = jest.requireActual('@human-protocol/sdk');
const mockedSdk = jest.createMockFromModule<
typeof import('@human-protocol/sdk')
>('@human-protocol/sdk');

return {
...actualSdk,
KVStoreUtils: {
get: jest.fn().mockResolvedValue('https://example.com'),
},
KVStoreUtils: mockedSdk.KVStoreUtils,
};
});

Expand All @@ -26,6 +19,7 @@ jest.mock('ethers', () => {
}),
},
};

return {
...actualEthers,
ethers: {
Expand All @@ -35,10 +29,23 @@ jest.mock('ethers', () => {
};
});

import { ChainId, KVStoreKeys, KVStoreUtils } from '@human-protocol/sdk';
import { CACHE_MANAGER } from '@nestjs/cache-manager';
import { Test, TestingModule } from '@nestjs/testing';

import { Cache } from 'cache-manager';

import { KvStoreGateway } from '../kv-store.gateway';
import { EnvironmentConfigService } from '../../../common/config/environment-config.service';
import { ORACLE_URL_CACHE_KEY } from '../../../common/constants/cache';

const EXPECTED_URL = 'https://example.com';

const mockedKvStoreUtils = jest.mocked(KVStoreUtils);

describe('KvStoreGateway', () => {
let service: KvStoreGateway;
let configService: EnvironmentConfigService;
let mockKVStoreUtils: any;
let cacheManager: Cache & { get: jest.Mock; set: jest.Mock };

beforeEach(async () => {
Expand All @@ -47,9 +54,6 @@ describe('KvStoreGateway', () => {
cacheTtlExchangeOracleUrl: 2137,
} as any;

mockKVStoreUtils = {
get: jest.fn(),
};
const cacheManagerMock = {
get: jest.fn(),
set: jest.fn(),
Expand All @@ -61,36 +65,36 @@ describe('KvStoreGateway', () => {
provide: EnvironmentConfigService,
useValue: configService,
},
{
provide: KVStoreUtils,
useValue: mockKVStoreUtils,
},
{
provide: CACHE_MANAGER,
useValue: cacheManagerMock,
},
],
}).compile();

cacheManager = module.get(CACHE_MANAGER);
configService = module.get(EnvironmentConfigService);
service = module.get<KvStoreGateway>(KvStoreGateway);
});

afterEach(async () => {
jest.restoreAllMocks();
jest.clearAllMocks();
});

it('should be defined', () => {
expect(service).toBeDefined();
});

describe('getExchangeOracleUrlByAddress', () => {
it('should get data from kvStoreUtils, if not cached', async () => {
const testAddress = 'testAddress';
const cacheKey = `${ORACLE_URL_CACHE_KEY}:${testAddress}`;
const expectedData = EXPECTED_URL;
mockKVStoreUtils.get.mockResolvedValue(expectedData);
const expectedUrl = EXPECTED_URL;
mockedKvStoreUtils.get.mockResolvedValue(expectedUrl + '/');
cacheManager.get.mockResolvedValue(undefined);

const result = await service.getExchangeOracleUrlByAddress(testAddress);

expect(KVStoreUtils.get).toHaveBeenCalledWith(
ChainId.LOCALHOST,
testAddress,
Expand All @@ -99,17 +103,19 @@ describe('KvStoreGateway', () => {

expect(cacheManager.set).toHaveBeenCalledWith(
cacheKey,
expectedData,
expectedUrl,
configService.cacheTtlExchangeOracleUrl,
);
expect(cacheManager.get).toHaveBeenCalledWith(cacheKey);
expect(result).toBe(expectedData);
expect(result).toBe(expectedUrl);
});

it('should get data from cache, if available', async () => {
const testAddress = 'testAddress';
const cacheKey = `${ORACLE_URL_CACHE_KEY}:${testAddress}`;
const expectedData = EXPECTED_URL;
cacheManager.get.mockResolvedValue(expectedData);

const result = await service.getExchangeOracleUrlByAddress(testAddress);

expect(KVStoreUtils.get).not.toHaveBeenCalled();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { AutoMap } from '@automapper/classes';
import { ApiProperty } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import { IsEthereumAddress, IsNumber } from 'class-validator';
import {
IsEthereumAddress,
IsNotEmpty,
IsNumber,
IsString,
} from 'class-validator';

export class ReportAbuseDto {
@AutoMap()
Expand All @@ -13,14 +18,22 @@ export class ReportAbuseDto {
@Type(() => Number)
@ApiProperty()
chain_id: number;
@AutoMap()
@IsString()
@IsNotEmpty()
@ApiProperty({ required: true, description: 'Reason for the abuse report' })
reason: string;
}

export class ReportAbuseParams {
@AutoMap()
chainId: number;
@AutoMap()
escrowAddress: string;
@AutoMap()
reason: string;
}

export class ReportAbuseCommand {
@AutoMap()
data: ReportAbuseParams;
Expand All @@ -33,13 +46,16 @@ export class ReportAbuseData {
escrow_address: string;
@AutoMap()
chain_id: number;
@AutoMap()
reason: string;
}

export class ReportedAbuseItem {
id: number;
escrowAddress: string;
chainId: number;
status: string;
reason: string;
}

export class ReportedAbuseResponse {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,19 @@ const ESCROW_ADDRESS = 'test_address';
const CHAIN_ID = 1;
const STATUS = 'reported';
const ABUSE_ID = 1;
const REASON = 'Test abuse reason';
export const TOKEN = 'test_user_token';

export const reportAbuseDtoFixture: ReportAbuseDto = {
chain_id: CHAIN_ID,
escrow_address: ESCROW_ADDRESS,
reason: REASON,
};

export const reportAbuseParamsFixture: ReportAbuseParams = {
chainId: CHAIN_ID,
escrowAddress: ESCROW_ADDRESS,
reason: REASON,
};

export const reportAbuseCommandFixture: ReportAbuseCommand = {
Expand All @@ -32,6 +35,7 @@ export const reportedAbuseItemFixture: ReportedAbuseItem = {
escrowAddress: ESCROW_ADDRESS,
chainId: CHAIN_ID,
status: STATUS,
reason: REASON,
};

export const reportedAbuseResponseFixture: ReportedAbuseResponse = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,11 @@ export class JobsDiscoveryService {
jobs: DiscoveredJob[],
): Promise<void> {
const cacheKey = JobsDiscoveryService.makeCacheKeyForOracle(oracleAddress);
await this.cacheManager.set(cacheKey, jobs);

await this.cacheManager.set(
cacheKey,
jobs,
this.configService.cacheTtlOracleAvailableJobs,
);
}
}
Loading
Loading