diff --git a/.changeset/new-penguins-end.md b/.changeset/new-penguins-end.md new file mode 100644 index 0000000000..96439d7211 --- /dev/null +++ b/.changeset/new-penguins-end.md @@ -0,0 +1,5 @@ +--- +"@farcaster/hubble": minor +--- + +feat: Make l2 rpc url required to start hubble ahead of mainnet migration diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 52f021b5e9..f1f068de16 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,7 +36,7 @@ jobs: - name: Run Hubble shell: bash - run: docker run --name hub --detach -p2282:2282 -p2283:2283 farcasterxyz/hubble:test sh -c 'node build/cli.js identity create && node build/cli.js start --rpc-port 2283 --ip 0.0.0.0 --gossip-port 2282 --eth-rpc-url "https://eth-goerli.g.alchemy.com/v2/IvjMoCKt1hT66f9OJoL_dMXypnvQYUdd" --eth-mainnet-rpc-url "https://eth-mainnet.g.alchemy.com/v2/8cz__IXnQ5FK_GNYDlfooLzYhBAW7ta0" --network 3 --allowed-peers none' + run: docker run --name hub --detach -p2282:2282 -p2283:2283 farcasterxyz/hubble:test sh -c 'node build/cli.js identity create && node build/cli.js start --rpc-port 2283 --ip 0.0.0.0 --gossip-port 2282 --eth-rpc-url "https://eth-goerli.g.alchemy.com/v2/IvjMoCKt1hT66f9OJoL_dMXypnvQYUdd" --eth-mainnet-rpc-url "https://eth-mainnet.g.alchemy.com/v2/8cz__IXnQ5FK_GNYDlfooLzYhBAW7ta0" --l2-rpc-url "https://opt-mainnet.g.alchemy.com/v2/3xWX-cWV-an3IPXmVCRXX51PpQzc-8iJ" --network 3 --allowed-peers none' - name: Download grpcurl shell: bash diff --git a/apps/hubble/src/cli.ts b/apps/hubble/src/cli.ts index b310747d70..a337b9bea4 100644 --- a/apps/hubble/src/cli.ts +++ b/apps/hubble/src/cli.ts @@ -513,7 +513,13 @@ app await startupCheck.rpcCheck(options.ethRpcUrl, goerli, "L1"); await startupCheck.rpcCheck(options.ethMainnetRpcUrl, mainnet, "L1"); - await startupCheck.rpcCheck(options.l2RpcUrl, optimism, "L2"); + await startupCheck.rpcCheck(options.l2RpcUrl, optimism, "L2", options.l2ChainId); + + if (startupCheck.anyFailedChecks()) { + logger.fatal({ reason: "Startup checks failed" }, "shutting down hub"); + logger.flush(); + process.exit(1); + } const hubResult = Result.fromThrowable( () => new Hub(options), diff --git a/apps/hubble/src/hubble.ts b/apps/hubble/src/hubble.ts index 1bdd377425..460d384e37 100644 --- a/apps/hubble/src/hubble.ts +++ b/apps/hubble/src/hubble.ts @@ -332,7 +332,8 @@ export class Hub implements HubInterface { options.l2RentExpiryOverride, ); } else { - log.warn("No L2 RPC URL provided, not syncing with L2 contract events"); + log.warn("No L2 RPC URL provided, unable to sync L2 contract events"); + throw new HubError("bad_request.invalid_param", "Invalid l2 rpc url"); } if (options.fnameServerUrl && options.fnameServerUrl !== "") { diff --git a/apps/hubble/src/utils/startupCheck.ts b/apps/hubble/src/utils/startupCheck.ts index d2947b45f3..cde9da9387 100644 --- a/apps/hubble/src/utils/startupCheck.ts +++ b/apps/hubble/src/utils/startupCheck.ts @@ -60,7 +60,13 @@ class StartupCheck { } } - async rpcCheck(rpcUrl: string | undefined, chain: Chain, prefix = "", status = StartupCheckStatus.ERROR) { + async rpcCheck( + rpcUrl: string | undefined, + chain: Chain, + prefix = "", + chainId?: number, + status = StartupCheckStatus.ERROR, + ) { const type = chain.name; if (!rpcUrl) { this.printStartupCheckStatus( @@ -82,7 +88,7 @@ class StartupCheck { // Check that the publicClient is reachable and returns the goerli chainId const chainIdResult = await ResultAsync.fromPromise(publicClient.getChainId(), (err) => err); - if (chainIdResult.isErr() || chainIdResult.value !== chain.id) { + if (chainIdResult.isErr() || chainIdResult.value !== (chainId ?? chain.id)) { console.log(chainIdResult); this.printStartupCheckStatus( status,