diff --git a/packages/chopsticks/src/plugins/follow-chain/cli.ts b/packages/chopsticks/src/plugins/follow-chain/cli.ts index 71986e97..77c71bc5 100644 --- a/packages/chopsticks/src/plugins/follow-chain/cli.ts +++ b/packages/chopsticks/src/plugins/follow-chain/cli.ts @@ -38,8 +38,8 @@ export const cli = (y: Argv) => { }) const context = await setupContext(config, true) - const { close, port: listenPort } = await createServer(handler(context), config.port) - logger.info(`${await context.chain.api.getSystemChain()} RPC listening on port ${listenPort}`) + const { close, port: listenPort } = await createServer(handler(context), config.addr, config.port) + logger.info(`${await context.chain.api.getSystemChain()} RPC listening on ${config.addr}:${listenPort}`) const chain = context.chain diff --git a/packages/chopsticks/src/plugins/try-runtime/index.ts b/packages/chopsticks/src/plugins/try-runtime/index.ts index a8815a5a..f5c8bc61 100644 --- a/packages/chopsticks/src/plugins/try-runtime/index.ts +++ b/packages/chopsticks/src/plugins/try-runtime/index.ts @@ -37,7 +37,12 @@ export const cli = (y: Argv) => { if (!config.db) { console.log('⚠️ Make sure to provide db, it will speed up the process') } - const context = await setupContext({ ...config, port: 8000, 'build-block-mode': BuildBlockMode.Manual }) + const context = await setupContext({ + ...config, + addr: 'localhost', + port: 8000, + 'build-block-mode': BuildBlockMode.Manual, + }) const block = context.chain.head const registry = await block.registry registry.register({ diff --git a/packages/chopsticks/src/schema/index.ts b/packages/chopsticks/src/schema/index.ts index 3f2602c7..f90e8ac6 100644 --- a/packages/chopsticks/src/schema/index.ts +++ b/packages/chopsticks/src/schema/index.ts @@ -12,7 +12,12 @@ export const zHex = z.custom((val: any) => /^0x\w+$/.test(val)) export const zHash = z.string().length(66).and(zHex) export const configSchema = z.object({ - port: z.number({ description: 'Port to listen on' }).default(8000), + addr: z + .union([z.literal('localhost'), z.string().ip()], { + description: 'Server listening interface', + }) + .default('localhost'), + port: z.number({ description: 'Server listening port' }).default(8000), endpoint: z.union([z.string(), z.array(z.string())], { description: 'Endpoint to connect to' }).optional(), block: z .union( diff --git a/packages/chopsticks/src/schema/options.test.ts b/packages/chopsticks/src/schema/options.test.ts index a62b600b..8156658a 100644 --- a/packages/chopsticks/src/schema/options.test.ts +++ b/packages/chopsticks/src/schema/options.test.ts @@ -4,6 +4,12 @@ import { expect, it } from 'vitest' it('get yargs options from zod schema', () => { expect(getYargsOptions(configSchema.shape)).toMatchInlineSnapshot(` { + "addr": { + "choices": undefined, + "demandOption": false, + "description": "Server listening interface", + "type": "string", + }, "allow-unresolved-imports": { "choices": undefined, "demandOption": false, @@ -77,7 +83,7 @@ it('get yargs options from zod schema', () => { "port": { "choices": undefined, "demandOption": false, - "description": "Port to listen on", + "description": "Server listening port", "type": "number", }, "prefetch-storages": { diff --git a/packages/chopsticks/src/schema/parse.test.ts b/packages/chopsticks/src/schema/parse.test.ts index 7d679f8c..fcb3ac97 100644 --- a/packages/chopsticks/src/schema/parse.test.ts +++ b/packages/chopsticks/src/schema/parse.test.ts @@ -28,6 +28,7 @@ describe('Existing configs', async () => { describe('Parsed options', () => { const defaults = { + addr: 'localhost', port: 8000, 'build-block-mode': 'Batch', } diff --git a/packages/chopsticks/src/server.ts b/packages/chopsticks/src/server.ts index 8dcda116..bbe4e579 100644 --- a/packages/chopsticks/src/server.ts +++ b/packages/chopsticks/src/server.ts @@ -78,7 +78,7 @@ const portInUse = async (port: number) => { return inUse } -export const createServer = async (handler: Handler, port: number) => { +export const createServer = async (handler: Handler, addr: string, port: number) => { let wss: WebSocketServer | undefined let listenPort: number | undefined @@ -162,7 +162,7 @@ export const createServer = async (handler: Handler, port: number) => { reject(e) } server.once('error', onError) - server.listen(preferPort, () => { + server.listen(preferPort, addr, () => { wss = new WebSocketServer({ server, maxPayload: 1024 * 1024 * 100 }) listenPort = (server.address() as AddressInfo).port server.removeListener('error', onError) diff --git a/packages/chopsticks/src/setup-with-server.ts b/packages/chopsticks/src/setup-with-server.ts index f35a6142..8ef8bcf5 100644 --- a/packages/chopsticks/src/setup-with-server.ts +++ b/packages/chopsticks/src/setup-with-server.ts @@ -7,12 +7,14 @@ import { setupContext } from './context.js' export const setupWithServer = async (argv: Config) => { const context = await setupContext(argv) - const { close, port: listenPort } = await createServer(handler(context), argv.port) + const addr = argv.addr ?? 'localhost' + const { close, port: listenPort } = await createServer(handler(context), addr, argv.port) - defaultLogger.info(`${await context.chain.api.getSystemChain()} RPC listening on port ${listenPort}`) + defaultLogger.info(`${await context.chain.api.getSystemChain()} RPC listening on ${addr}:${listenPort}`) return { ...context, + addr: argv.addr, listenPort, async close() { await context.chain.close() diff --git a/packages/e2e/src/genesis-provider.test.ts b/packages/e2e/src/genesis-provider.test.ts index 05656b5f..0fefd23b 100644 --- a/packages/e2e/src/genesis-provider.test.ts +++ b/packages/e2e/src/genesis-provider.test.ts @@ -13,6 +13,7 @@ describe.each([ ['Asset Hub Kusama', new URL('../blobs/asset-hub-kusama.json', import.meta.url).pathname], ])(`genesis provider works %s`, async (name, genesis) => { const { chain, dev, api, teardown } = await setupContextWithConfig({ + addr: 'localhost', port: 1234, genesis, 'build-block-mode': BuildBlockMode.Manual, diff --git a/packages/e2e/src/helper.ts b/packages/e2e/src/helper.ts index 3ddf8e4e..70485d30 100644 --- a/packages/e2e/src/helper.ts +++ b/packages/e2e/src/helper.ts @@ -102,7 +102,7 @@ export const setupAll = async ({ await chain.newBlock() } - const { port, close } = await createServer(handler({ chain }), 0) + const { port, close } = await createServer(handler({ chain }), 'localhost', 0) const ws = new WsProvider(`ws://localhost:${port}`, 3_000, undefined, 300_000) return { diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index e8c2c220..0afb7ae3 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -26,6 +26,7 @@ export type SetupOption = { wasmOverride?: string db?: string timeout?: number + addr?: string port?: number maxMemoryBlockCount?: number resume?: boolean | HexString | number @@ -45,6 +46,7 @@ export const createConfig = ({ wasmOverride, db, timeout, + addr, port, maxMemoryBlockCount, resume, @@ -52,10 +54,12 @@ export const createConfig = ({ allowUnresolvedImports, processQueuedMessages, }: SetupOption): SetupConfig => { + addr = addr ?? 'localhost' // random port if not specified port = port ?? Math.floor(Math.random() * 10000) + 10000 const config = { endpoint, + addr, port, block: blockNumber || blockHash, 'mock-signature-host': true, @@ -77,9 +81,9 @@ export const setupContext = async (option: SetupOption) => { } export const setupContextWithConfig = async ({ timeout, ...config }: SetupConfig) => { - const { chain, listenPort, close } = await setupWithServer(config) + const { chain, addr, listenPort, close } = await setupWithServer(config) - const url = `ws://localhost:${listenPort}` + const url = `ws://${addr}:${listenPort}` const ws = new WsProvider(url, 3_000, undefined, timeout) const api = await ApiPromise.create({ provider: ws,