diff --git a/CONFIGURATION.md b/CONFIGURATION.md index 5fa3f96..4ed4867 100644 --- a/CONFIGURATION.md +++ b/CONFIGURATION.md @@ -13,6 +13,7 @@ | TREE_UPDATE_PARAMS_PATH | Local path to tree update circuit parameters | string | | TRANSFER_PARAMS_PATH | Local path to transfer circuit parameters | string | | TX_VK_PATH | Local path to transaction circuit verification key | string | +| RELAYER_REQUEST_LOG_PATH | Path to a file where all HTTP request logs will be saved. Default `./zp.log`. | string | | STATE_DIR_PATH | Path to persistent state files related to tree and transactions storage. Default: `./POOL_STATE` | string | | GAS_PRICE_FALLBACK | Default fallback gas price | integer | | GAS_PRICE_ESTIMATION_TYPE | Gas price estimation type | `web3` / `gas-price-oracle` / `eip1559-gas-estimation` / `polygon-gasstation-v2` | @@ -37,5 +38,7 @@ | PERMIT_DEADLINE_THRESHOLD_RESEND | Minimum time threshold in seconds for permit signature deadline to be valid (for re-send attempts) | integer | | RELAYER_REQUIRE_TRACE_ID | If set to `true`, then requests to relayer (except `/info`, `/version`, `/params/hash/tree`, `/params/hash/tx`) without `zkbob-support-id` header will be rejected. | boolean | | RELAYER_REQUIRE_HTTPS | If set to `true`, then RPC URL(s) must be in HTTPS format. HTTP RPC URL(s) should be used in test environment only. | boolean | +| RELAYER_LOG_IGNORE_ROUTES | List of space separated relayer endpoints for which request logging will be suppressed. E.g. `/fee /version` | string(s) | +| RELAYER_LOG_HEADER_BLACKLIST | List of space separated HTTP headers which will be suppressed in request logs. E.g. `content-length content-type` | string(s) | | RELAYER_SCREENER_URL | Screener service URL | URL | | RELAYER_SCREENER_TOKEN | Authorization token for screener service | string | diff --git a/README.md b/README.md index 5265470..98faaa6 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,11 @@ You can use a pre-built [image](https://github.com/zkBob/zeropool-relayer/pkgs/c cd zp-relayer && yarn test:unit ``` +**Worker tests** +To run worker tests you need Docker and docker-compose installed locally. +```bash +cd zp-relayer && yarn test:worker +``` ## Workflow diff --git a/zp-relayer/config.ts b/zp-relayer/config.ts index 28e3626..b8aace2 100644 --- a/zp-relayer/config.ts +++ b/zp-relayer/config.ts @@ -7,6 +7,9 @@ const relayerAddress = new Web3().eth.accounts.privateKeyToAccount( process.env.RELAYER_ADDRESS_PRIVATE_KEY as string ).address +const defaultHeaderBlacklist = + 'accept accept-language accept-encoding connection content-length content-type postman-token referer upgrade-insecure-requests' + const config = { relayerRef: process.env.RELAYER_REF || null, relayerSHA: process.env.RELAYER_SHA || null, @@ -21,6 +24,7 @@ const config = { treeUpdateParamsPath: process.env.TREE_UPDATE_PARAMS_PATH || './params/tree_params.bin', transferParamsPath: process.env.TRANSFER_PARAMS_PATH || './params/transfer_params.bin', txVKPath: process.env.TX_VK_PATH || './params/transfer_verification_key.json', + requestLogPath: process.env.RELAYER_REQUEST_LOG_PATH || './zp.log', stateDirPath: process.env.STATE_DIR_PATH || './POOL_STATE', gasPriceFallback: process.env.GAS_PRICE_FALLBACK as string, gasPriceEstimationType: (process.env.GAS_PRICE_ESTIMATION_TYPE as EstimationType) || 'web3', @@ -43,11 +47,16 @@ const config = { insufficientBalanceCheckTimeout: parseInt(process.env.INSUFFICIENT_BALANCE_CHECK_TIMEOUT || '60000'), rpcSyncCheckInterval: parseInt(process.env.RELAYER_RPC_SYNC_STATE_CHECK_INTERVAL || '0'), permitDeadlineThresholdInitial: parseInt(process.env.PERMIT_DEADLINE_THRESHOLD_INITIAL || '300'), - relayerJsonRpcErrorCodes: (process.env.RELAYER_JSONRPC_ERROR_CODES || '-32603,-32002,-32005') - .split(',') + relayerJsonRpcErrorCodes: (process.env.RELAYER_JSONRPC_ERROR_CODES || '-32603 -32002 -32005') + .split(' ') + .filter(s => s.length > 0) .map(s => parseInt(s, 10)), requireTraceId: process.env.RELAYER_REQUIRE_TRACE_ID === 'true', requireHTTPS: process.env.RELAYER_REQUIRE_HTTPS === 'true', + logIgnoreRoutes: (process.env.RELAYER_LOG_IGNORE_ROUTES || '').split(' ').filter(r => r.length > 0), + logHeaderBlacklist: (process.env.RELAYER_LOG_HEADER_BLACKLIST || defaultHeaderBlacklist) + .split(' ') + .filter(r => r.length > 0), screenerUrl: process.env.RELAYER_SCREENER_URL || null, screenerToken: process.env.RELAYER_SCREENER_TOKEN || null, } diff --git a/zp-relayer/index.ts b/zp-relayer/index.ts index 3cffa0b..4f3ef5e 100644 --- a/zp-relayer/index.ts +++ b/zp-relayer/index.ts @@ -2,13 +2,14 @@ import './env' import express from 'express' import router from './router' import { logger } from './services/appLogger' -import { createLoggerMiddleware } from './services/loggerMiddleware' +import { createConsoleLoggerMiddleware, createPersistentLoggerMiddleware } from './services/loggerMiddleware' import config from './config' import { init } from './init' const app = express() -app.use(createLoggerMiddleware('zp.log')) +app.use(createPersistentLoggerMiddleware(config.requestLogPath)) +app.use(createConsoleLoggerMiddleware()) app.use(router) diff --git a/zp-relayer/services/loggerMiddleware.ts b/zp-relayer/services/loggerMiddleware.ts index 3969fb9..de268ef 100644 --- a/zp-relayer/services/loggerMiddleware.ts +++ b/zp-relayer/services/loggerMiddleware.ts @@ -1,9 +1,21 @@ -import winston from 'winston' +import { format, transports } from 'winston' import expressWinston from 'express-winston' +import config from '@/config' +import { logger } from './appLogger' -export function createLoggerMiddleware(filename: string = 'zp.log') { +export function createPersistentLoggerMiddleware(filename: string = 'zp.log') { return expressWinston.logger({ - transports: [new winston.transports.File({ filename })], - format: winston.format.combine(winston.format.json()), + transports: [new transports.File({ filename })], + format: format.combine(format.json()), + }) +} + +export function createConsoleLoggerMiddleware() { + return expressWinston.logger({ + winstonInstance: logger, + level: 'debug', + ignoredRoutes: config.logIgnoreRoutes, + headerBlacklist: config.logHeaderBlacklist, + requestWhitelist: ['headers', 'httpVersion'], }) }