Skip to content

Commit

Permalink
Remove fs dependency in paima-sdk
Browse files Browse the repository at this point in the history
  • Loading branch information
SebastienGllmt committed Dec 8, 2023
1 parent 133d45e commit a7fa07f
Show file tree
Hide file tree
Showing 10 changed files with 82 additions and 49 deletions.
64 changes: 31 additions & 33 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions packages/batcher/runtime/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ import type { ErrorCode, ErrorMessageFxn, GameInputValidatorCore } from '@paima/

import { initializePool } from './pg/pgPool.js';
import type { BatcherRuntimeInitializer } from './types.js';
import { setLogger } from '@paima/utils';
import * as fs from 'fs';
import { parseSecurityYaml } from '@paima/utils-backend';

setLogger(s => {
try {
fs.appendFileSync('./logs.log', `${s}\n`);
} catch (e) {}
});

const MINIMUM_INTER_CATCH_PERIOD = 1000;
let batchedTransactionPosterReference: BatchedTransactionPoster | null = null;
Expand Down Expand Up @@ -127,6 +136,7 @@ async function main(): Promise<void> {
if (!checkConfig()) {
return;
}
await parseSecurityYaml();

const privateKey = ENV.BATCHER_PRIVATE_KEY;

Expand Down
2 changes: 2 additions & 0 deletions packages/batcher/runtime/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,7 @@
{ "path": "../utils" },
{ "path": "../batcher-transaction-poster" },
{ "path": "../../paima-sdk/paima-providers/tsconfig.build.json" },
{ "path": "../../paima-sdk/paima-utils/tsconfig.build.json" },
{ "path": "../../node-sdk/paima-utils-backend" },
]
}
2 changes: 2 additions & 0 deletions packages/engine/paima-standalone/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { argumentRouter } from './utils/input.js';

import * as fs from 'fs';
import { setLogger } from '@paima/utils';
import { parseSecurityYaml } from '@paima/utils-backend';

setLogger(s => {
try {
Expand All @@ -15,6 +16,7 @@ setLogger(s => {
config({ path: `${process.cwd()}/.env.${process.env.NODE_ENV || 'development'}` });

async function main(): Promise<void> {
await parseSecurityYaml();
await argumentRouter();
}

Expand Down
1 change: 1 addition & 0 deletions packages/engine/paima-standalone/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@
{ "path": "../../paima-sdk/paima-utils/tsconfig.build.json" },
{ "path": "../paima-funnel" },
{ "path": "../paima-rest/tsconfig.build.json" },
{ "path": "../../node-sdk/paima-utils-backend" },
]
}
1 change: 1 addition & 0 deletions packages/node-sdk/paima-utils-backend/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Crypto from 'crypto';

export { parseSecurityYaml } from './security.js';
export * from './cde-access.js';
export type * from './types.js';

Expand Down
10 changes: 10 additions & 0 deletions packages/node-sdk/paima-utils-backend/src/security.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { ENV, parseAndValidateYAML } from '@paima/utils';
import * as fs from 'fs/promises';

export async function parseSecurityYaml(): Promise<void> {
const namespace = ENV.SECURITY_NAMESPACE;
if (namespace.endsWith('.yml') || namespace.endsWith('.yaml')) {
const content = await fs.readFile(ENV.SECURITY_NAMESPACE, 'utf-8');
parseAndValidateYAML(content);
}
}
1 change: 1 addition & 0 deletions packages/node-sdk/paima-utils-backend/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
"include": ["src/**/*"],
"references": [
{ "path": "../paima-db" },
{ "path": "../../paima-sdk/paima-utils/tsconfig.build.json" }
]
}
29 changes: 14 additions & 15 deletions packages/paima-sdk/paima-utils/src/security/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import type { Static } from '@sinclair/typebox';
import { Type } from '@sinclair/typebox';
import { Value } from '@sinclair/typebox/value';
import YAML from 'yaml';
import * as fs from 'fs/promises';
import { ENV } from '../config.js';

const BlockSettings = Type.Object({
Expand All @@ -21,19 +20,22 @@ const Config = Type.Object({
/** Cache for file content so we don't have to re-read it from disk constantly */
let securityNamespaceConfig: undefined | Static<typeof Config>;

async function loadAndValidateYAML(filename: string): Promise<Static<typeof Config>> {
async function loadAndValidateYAML(): Promise<Static<typeof Config>> {
// try checking the cache first
// note the cache may be set externally by a direct call to parseAndValidateYAML
if (securityNamespaceConfig != null) return securityNamespaceConfig;

// this ENV var is used to help with compilation of Paima for browser environments
// since they can't access fs.readFile,
// we instead (at compile time) read the file
// and put the file content inside SECURITY_NAMESPACE_ROUTER
const fileContent = process.env.SECURITY_NAMESPACE_ROUTER
? (JSON.parse(process.env.SECURITY_NAMESPACE_ROUTER) as string)
: await fs.readFile(filename, 'utf-8');
return await parseAndValidateYAML(fileContent);
if (process.env.SECURITY_NAMESPACE_ROUTER != null) {
const fileContent = JSON.parse(process.env.SECURITY_NAMESPACE_ROUTER) as string;
return parseAndValidateYAML(fileContent);
}
throw new Error(`security namespace YAML specified, but wasn't initialized`);
}
async function parseAndValidateYAML(fileContent: string): Promise<Static<typeof Config>> {
export function parseAndValidateYAML(fileContent: string): Static<typeof Config> {
if (securityNamespaceConfig != null) return securityNamespaceConfig;
try {
// Parse the YAML content into an object
Expand All @@ -48,18 +50,15 @@ async function parseAndValidateYAML(fileContent: string): Promise<Static<typeof
}

// If validation passes, cache and return the validated object
let securityNamespaceConfig = yamlObject;
securityNamespaceConfig = yamlObject;
return securityNamespaceConfig;
} catch (error) {
throw new Error(`Error loading and validating YAML: ${error}`);
}
}

async function getEntryFromFile(
namespace: string,
blockHeight: number
): Promise<undefined | string[]> {
const config = await loadAndValidateYAML(namespace);
async function getEntryFromFile(blockHeight: number): Promise<undefined | string[]> {
const config = await loadAndValidateYAML();
let highestEntry: Static<typeof BlockSettings> | null = null;
for (const entry of config.namespace.read) {
if (
Expand All @@ -79,7 +78,7 @@ export async function getReadNamespaces(blockHeight: number): Promise<string[]>

const entry =
namespace.endsWith('.yml') || namespace.endsWith('.yaml')
? await getEntryFromFile(namespace, blockHeight)
? await getEntryFromFile(blockHeight)
: [namespace];

// default if no entry matches
Expand All @@ -102,7 +101,7 @@ export async function getWriteNamespace(): Promise<string> {
const entry =
namespace.endsWith('.yml') || namespace.endsWith('.yaml')
? await (async (): Promise<string> => {
const config = await loadAndValidateYAML(namespace);
const config = await loadAndValidateYAML();
return config.namespace.write;
})()
: namespace;
Expand Down
11 changes: 10 additions & 1 deletion packages/paima-sdk/paima-utils/test/security/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { describe, expect, test } from '@jest/globals';
import { getReadNamespaces, getWriteNamespace } from '../../src/security/parse.js';
import {
getReadNamespaces,
getWriteNamespace,
parseAndValidateYAML,
} from '../../src/security/parse.js';
import * as fs from 'fs/promises';

const CONTRACT_ADDRESS = '0x35390c41200DD56Ac3A679a0c1EeA369444f3b60';
process.env.CONTRACT_ADDRESS = CONTRACT_ADDRESS;
Expand All @@ -9,6 +14,10 @@ describe('Test if parsed', () => {
inputs.forEach(([namespace, blockHeight, expectedResult]: [string, number, string[]]) => {
test(`${namespace} at blockHeight=${blockHeight} to be ${expectedResult}`, async () => {
process.env.SECURITY_NAMESPACE = namespace;
if (namespace.endsWith('yml')) {
const content = await fs.readFile(process.env.SECURITY_NAMESPACE, 'utf-8');
parseAndValidateYAML(content);
}
const result = await getReadNamespaces(blockHeight);
expect(result).toEqual(expectedResult);
});
Expand Down

0 comments on commit a7fa07f

Please sign in to comment.