mirror of
https://github.com/farcasterxyz/hub-monorepo.git
synced 2026-02-18 00:41:27 -05:00
refactor(hubble): order and comment cli options for clarity (#1154)
This commit is contained in:
@@ -51,58 +51,67 @@ const parseNumber = (string: string) => {
|
||||
const app = new Command();
|
||||
app.name("hub").description("Farcaster Hub").version(APP_VERSION);
|
||||
|
||||
/*//////////////////////////////////////////////////////////////
|
||||
START COMMAND
|
||||
//////////////////////////////////////////////////////////////*/
|
||||
|
||||
app
|
||||
.command("start")
|
||||
.description("Start a Hub")
|
||||
.option("-e, --eth-rpc-url <url>", "RPC URL of a Goerli Ethereum Node (or comma separated list of URLs)")
|
||||
.option("-l, --l2-rpc-url <url>", "RPC URL of a Goerli Optimism Node (or comma separated list of URLs)")
|
||||
.option("-m, --eth-mainnet-rpc-url <url>", "RPC URL of a mainnet Ethereum Node (or comma separated list of URLs)")
|
||||
.option("--rank-rpcs", "Rank the RPCs by latency/stability and use the fastest one (default: disabled)")
|
||||
.option("-c, --config <filepath>", "Path to a config file with options")
|
||||
.option("--fir-address <address>", "The address of the Farcaster ID Registry contract")
|
||||
.option("--fnr-address <address>", "The address of the Farcaster Name Registry contract")
|
||||
.option("--first-block <number>", "The block number to begin syncing events from Farcaster contracts", parseNumber)
|
||||
.option("--fname-server-url <url>", "The URL for the FName registry server")
|
||||
.option(
|
||||
"--chunk-size <number>",
|
||||
"The number of blocks to batch when syncing historical events from Farcaster contracts. (default: 10000)",
|
||||
parseNumber,
|
||||
)
|
||||
.option("-b, --bootstrap <peer-multiaddrs...>", "A list of peer multiaddrs to bootstrap libp2p")
|
||||
.option("-a, --allowed-peers <peerIds...>", "An allow-list of peer ids permitted to connect to the hub")
|
||||
.option("--ip <ip-address>", 'The IP address libp2p should listen on. (default: "127.0.0.1")')
|
||||
.option(
|
||||
"--announce-ip <ip-address>",
|
||||
"The IP address libp2p should announce to other peers. If not provided, the IP address will be fetched from an external service",
|
||||
)
|
||||
.option(
|
||||
"--announce-server-name <name>",
|
||||
'The name of the server to announce to peers. This is useful if you have SSL/TLS enabled. (default: "none")',
|
||||
)
|
||||
.option("-g, --gossip-port <port>", "The tcp port libp2p should gossip over. (default: 2282)")
|
||||
.option("-r, --rpc-port <port>", "The tcp port that the rpc server should listen on. (default: 2283)")
|
||||
.option(
|
||||
"--rpc-auth <username:password,...>",
|
||||
"Enable Auth for RPC submit methods with the username and password. (default: disabled)",
|
||||
)
|
||||
.option(
|
||||
"--rpc-rate-limit <number>",
|
||||
"Impose a Per IP rate limit per minute. Set to -1 for no rate limits (default: 20k/min)",
|
||||
)
|
||||
|
||||
// Hubble Options
|
||||
.option("-n --network <network>", "ID of the Farcaster Network (default: 3 (devnet))", parseNetwork)
|
||||
.option("-i, --id <filepath>", "Path to the PeerId file.")
|
||||
.option("-c, --config <filepath>", "Path to the config file.")
|
||||
.option("--db-name <name>", "The name of the RocksDB instance. (default: rocks.hub._default)")
|
||||
.option("--admin-server-enabled", "Enable the admin server. (default: disabled)")
|
||||
.option("--admin-server-host <host>", "The host the admin server should listen on. (default: '127.0.0.1')")
|
||||
.option("--db-name <name>", "The name of the RocksDB instance")
|
||||
.option("--profile-sync", "Profile the sync. Will sync the node and exit. (default: disabled)")
|
||||
.option("--rebuild-sync-trie", "Rebuilds the sync trie before starting")
|
||||
.option("--resync-eth-events", "Resyncs events from the Farcaster contracts before starting")
|
||||
.option("--resync-name-events", "Resyncs events from the FName registry server before starting")
|
||||
.option("--commit-lock-timeout <number>", "Commit lock timeout in milliseconds (default: 500)", parseNumber)
|
||||
.option("--commit-lock-max-pending <number>", "Commit lock max pending jobs (default: 1000)", parseNumber)
|
||||
.option("-i, --id <filepath>", "Path to the PeerId file")
|
||||
.option("-n --network <network>", "Farcaster network ID", parseNetwork)
|
||||
.option("--gossip-metrics-enabled", "Enable gossip network tracing and metrics. (default: disabled)")
|
||||
.option("--process-file-prefix <prefix>", 'Prefix for file to which hub process number is written. (default: "")')
|
||||
|
||||
// Ethereum Options
|
||||
.option("-m, --eth-mainnet-rpc-url <url>", "RPC URL of a Mainnet ETH Node (or comma separated list of URLs)")
|
||||
.option("-e, --eth-rpc-url <url>", "RPC URL of a Goerli ETH Node (or comma separated list of URLs)")
|
||||
.option("-l, --l2-rpc-url <url>", "RPC URL of a Goerli Optimism Node (or comma separated list of URLs)")
|
||||
.option("--rank-rpcs", "Rank the RPCs by latency/stability and use the fastest one (default: disabled)")
|
||||
.option("--fname-server-url <url>", `The URL for the FName registry server (default: ${DEFAULT_FNAME_SERVER_URL}`)
|
||||
.option("--fir-address <address>", "The address of the Farcaster ID Registry contract")
|
||||
.option("--first-block <number>", "The block number to begin syncing events from Farcaster contracts", parseNumber)
|
||||
|
||||
// Networking Options
|
||||
.option("-a, --allowed-peers <peerIds...>", "Only peer with specific peer ids. (default: all peers allowed)")
|
||||
.option("-b, --bootstrap <peer-multiaddrs...>", "Peers to bootstrap gossip and sync from. (default: none)")
|
||||
.option("-g, --gossip-port <port>", `Port to use for gossip (default: ${DEFAULT_GOSSIP_PORT})`)
|
||||
.option("-r, --rpc-port <port>", `Port to use for gRPC (default: ${DEFAULT_RPC_PORT})`)
|
||||
.option("--ip <ip-address>", 'IP address to listen on (default: "127.0.0.1")')
|
||||
.option("--announce-ip <ip-address>", "Public IP address announced to peers (default: fetched with external service)")
|
||||
.option(
|
||||
"--announce-server-name <name>",
|
||||
'Server name announced to peers, useful if SSL/TLS enabled. (default: "none")',
|
||||
)
|
||||
.option("--direct-peers <peer-multiaddrs...>", "A list of peers for libp2p to directly peer with (default: [])")
|
||||
.option(
|
||||
"--rpc-rate-limit <number>",
|
||||
"RPC rate limit for peers specified in rpm. Set to -1 for none. (default: 20k/min)",
|
||||
)
|
||||
|
||||
// Debugging options
|
||||
.option("--gossip-metrics-enabled", "Generate tracing and metrics for the gossip network. (default: disabled)")
|
||||
.option("--profile-sync", "Profile a full hub sync and exit. (default: disabled)")
|
||||
.option("--rebuild-sync-trie", "Rebuild the sync trie before starting (default: disabled)")
|
||||
.option("--resync-eth-events", "Resync events from the Farcaster contracts before starting (default: disabled)")
|
||||
.option("--resync-name-events", "Resync events from the Fname server before starting (default: disabled)")
|
||||
.option(
|
||||
"--chunk-size <number>",
|
||||
`The number of blocks to batch when syncing historical events from Farcaster contracts. (default: ${DEFAULT_CHUNK_SIZE})`,
|
||||
parseNumber,
|
||||
)
|
||||
.option("--commit-lock-timeout <number>", "Rocks DB commit lock timeout in milliseconds (default: 500)", parseNumber)
|
||||
.option("--commit-lock-max-pending <number>", "Rocks DB commit lock max pending jobs (default: 1000)", parseNumber)
|
||||
.option("--rpc-auth <username:password,...>", "Require username-password auth for RPC submit. (default: disabled)")
|
||||
|
||||
// To be deprecated
|
||||
.option("--fnr-address <address>", "The address of the Farcaster Name Registry contract")
|
||||
|
||||
.action(async (cliOptions) => {
|
||||
const teardown = async (hub: Hub) => {
|
||||
await hub.stop();
|
||||
@@ -424,6 +433,10 @@ app
|
||||
});
|
||||
});
|
||||
|
||||
/*//////////////////////////////////////////////////////////////
|
||||
IDENTITY COMMAND
|
||||
//////////////////////////////////////////////////////////////*/
|
||||
|
||||
/** Write a given PeerId to a file */
|
||||
const writePeerId = async (peerId: PeerId, filepath: string) => {
|
||||
const directory = dirname(filepath);
|
||||
@@ -447,7 +460,7 @@ const createIdCommand = new Command("create")
|
||||
.description(
|
||||
"Create a new peerId and write it to a file.\n\nNote: This command will always overwrite the default PeerId file.",
|
||||
)
|
||||
.option("-O, --output <directory>", "Path to where the generated PeerId/s should be stored", DEFAULT_PEER_ID_DIR)
|
||||
.option("-O, --output <directory>", "Path to where the generated PeerIds should be stored", DEFAULT_PEER_ID_DIR)
|
||||
.option("-N, --count <number>", "Number of PeerIds to generate", parseNumber, 1)
|
||||
.action(async (options) => {
|
||||
for (let i = 0; i < options.count; i++) {
|
||||
@@ -465,40 +478,6 @@ const createIdCommand = new Command("create")
|
||||
exit(0);
|
||||
});
|
||||
|
||||
app
|
||||
.command("dbreset")
|
||||
.description("Completely remove the database")
|
||||
.option("--db-name <name>", "The name of the RocksDB instance")
|
||||
.option("-c, --config <filepath>", "Path to a config file with options")
|
||||
.action(async (cliOptions) => {
|
||||
const hubConfig = cliOptions.config ? (await import(resolve(cliOptions.config))).Config : DefaultConfig;
|
||||
const rocksDBName = cliOptions.dbName ?? hubConfig.dbName ?? "";
|
||||
|
||||
if (!rocksDBName) throw new Error("No RocksDB name provided.");
|
||||
|
||||
const rocksDB = new RocksDB(rocksDBName);
|
||||
const fallback = () => {
|
||||
fs.rmSync(rocksDB.location, { recursive: true, force: true });
|
||||
};
|
||||
|
||||
const dbResult = await ResultAsync.fromPromise(rocksDB.open(), (e) => e as Error);
|
||||
if (dbResult.isErr()) {
|
||||
logger.warn({ rocksDBName }, "Failed to open RocksDB, falling back to rm");
|
||||
fallback();
|
||||
} else {
|
||||
const clearResult = await ResultAsync.fromPromise(rocksDB.clear(), (e) => e as Error);
|
||||
if (clearResult.isErr()) {
|
||||
logger.warn({ rocksDBName }, "Failed to open RocksDB, falling back to rm");
|
||||
fallback();
|
||||
}
|
||||
|
||||
await rocksDB.close();
|
||||
}
|
||||
|
||||
logger.info({ rocksDBName }, "Database cleared.");
|
||||
exit(0);
|
||||
});
|
||||
|
||||
const verifyIdCommand = new Command("verify")
|
||||
.description("Verify a peerId file")
|
||||
.option("-I, --id <filepath>", "Path to the PeerId file", DEFAULT_PEER_ID_LOCATION)
|
||||
@@ -514,28 +493,9 @@ app
|
||||
.addCommand(createIdCommand)
|
||||
.addCommand(verifyIdCommand);
|
||||
|
||||
const storageProfileCommand = new Command("storage")
|
||||
.description("Profile the storage layout of the hub, accounting for all the storage")
|
||||
.option("--db-name <name>", "The name of the RocksDB instance")
|
||||
.option("-c, --config <filepath>", "Path to a config file with options")
|
||||
.action(async (cliOptions) => {
|
||||
const hubConfig = cliOptions.config ? (await import(resolve(cliOptions.config))).Config : DefaultConfig;
|
||||
const rocksDBName = cliOptions.dbName ?? hubConfig.dbName ?? "";
|
||||
const rocksDB = new RocksDB(rocksDBName);
|
||||
|
||||
if (!rocksDBName) throw new Error("No RocksDB name provided.");
|
||||
const dbResult = await ResultAsync.fromPromise(rocksDB.open(), (e) => e as Error);
|
||||
if (dbResult.isErr()) {
|
||||
logger.warn({ rocksDBName }, "Failed to open RocksDB. The Hub needs to be stopped to run this command.");
|
||||
} else {
|
||||
await profileStorageUsed(rocksDB);
|
||||
}
|
||||
|
||||
await rocksDB.close();
|
||||
exit(0);
|
||||
});
|
||||
|
||||
app.command("profile").description("Profile various resources used by the hub").addCommand(storageProfileCommand);
|
||||
/*//////////////////////////////////////////////////////////////
|
||||
STATUS COMMAND
|
||||
//////////////////////////////////////////////////////////////*/
|
||||
|
||||
app
|
||||
.command("status")
|
||||
@@ -612,6 +572,75 @@ app
|
||||
exit(0);
|
||||
});
|
||||
|
||||
/*//////////////////////////////////////////////////////////////
|
||||
PROFILE COMMAND
|
||||
//////////////////////////////////////////////////////////////*/
|
||||
|
||||
const storageProfileCommand = new Command("storage")
|
||||
.description("Profile the storage layout of the hub, accounting for all the storage")
|
||||
.option("--db-name <name>", "The name of the RocksDB instance")
|
||||
.option("-c, --config <filepath>", "Path to a config file with options")
|
||||
.action(async (cliOptions) => {
|
||||
const hubConfig = cliOptions.config ? (await import(resolve(cliOptions.config))).Config : DefaultConfig;
|
||||
const rocksDBName = cliOptions.dbName ?? hubConfig.dbName ?? "";
|
||||
const rocksDB = new RocksDB(rocksDBName);
|
||||
|
||||
if (!rocksDBName) throw new Error("No RocksDB name provided.");
|
||||
const dbResult = await ResultAsync.fromPromise(rocksDB.open(), (e) => e as Error);
|
||||
if (dbResult.isErr()) {
|
||||
logger.warn({ rocksDBName }, "Failed to open RocksDB. The Hub needs to be stopped to run this command.");
|
||||
} else {
|
||||
await profileStorageUsed(rocksDB);
|
||||
}
|
||||
|
||||
await rocksDB.close();
|
||||
exit(0);
|
||||
});
|
||||
|
||||
app.command("profile").description("Profile various resources used by the hub").addCommand(storageProfileCommand);
|
||||
|
||||
/*//////////////////////////////////////////////////////////////
|
||||
DBRESET COMMAND
|
||||
//////////////////////////////////////////////////////////////*/
|
||||
|
||||
app
|
||||
.command("dbreset")
|
||||
.description("Completely remove the database")
|
||||
.option("--db-name <name>", "The name of the RocksDB instance")
|
||||
.option("-c, --config <filepath>", "Path to a config file with options")
|
||||
.action(async (cliOptions) => {
|
||||
const hubConfig = cliOptions.config ? (await import(resolve(cliOptions.config))).Config : DefaultConfig;
|
||||
const rocksDBName = cliOptions.dbName ?? hubConfig.dbName ?? "";
|
||||
|
||||
if (!rocksDBName) throw new Error("No RocksDB name provided.");
|
||||
|
||||
const rocksDB = new RocksDB(rocksDBName);
|
||||
const fallback = () => {
|
||||
fs.rmSync(rocksDB.location, { recursive: true, force: true });
|
||||
};
|
||||
|
||||
const dbResult = await ResultAsync.fromPromise(rocksDB.open(), (e) => e as Error);
|
||||
if (dbResult.isErr()) {
|
||||
logger.warn({ rocksDBName }, "Failed to open RocksDB, falling back to rm");
|
||||
fallback();
|
||||
} else {
|
||||
const clearResult = await ResultAsync.fromPromise(rocksDB.clear(), (e) => e as Error);
|
||||
if (clearResult.isErr()) {
|
||||
logger.warn({ rocksDBName }, "Failed to open RocksDB, falling back to rm");
|
||||
fallback();
|
||||
}
|
||||
|
||||
await rocksDB.close();
|
||||
}
|
||||
|
||||
logger.info({ rocksDBName }, "Database cleared.");
|
||||
exit(0);
|
||||
});
|
||||
|
||||
/*//////////////////////////////////////////////////////////////
|
||||
CONSOLE COMMAND
|
||||
//////////////////////////////////////////////////////////////*/
|
||||
|
||||
app
|
||||
.command("console")
|
||||
.description("Start a REPL console")
|
||||
|
||||
@@ -25,34 +25,47 @@ Usage: yarn start [options]
|
||||
|
||||
Start a Hub
|
||||
|
||||
Options:
|
||||
-e, --eth-rpc-url <url> RPC URL of a Goerli Ethereum Node
|
||||
-c, --config <filepath> Path to a config file with options
|
||||
--fir-address <address> The address of the Farcaster ID Registry contract
|
||||
--fnr-address <address> The address of the Farcaster Name Registry contract
|
||||
--first-block <number> The block number to begin syncing events from Farcaster contracts
|
||||
--fname-server-url <url> The URL for the FName registry server
|
||||
--chunk-size <number> The number of blocks to batch when syncing historical events from Farcaster contracts. (default: 10000)
|
||||
-b, --bootstrap <peer-multiaddrs...> A list of peer multiaddrs to bootstrap libp2p
|
||||
-a, --allowed-peers <peerIds...> An allow-list of peer ids permitted to connect to the hub
|
||||
--ip <ip-address> The IP address libp2p should listen on. (default: "127.0.0.1")
|
||||
--announce-ip <ip-address> The IP address libp2p should announce to other peers. If not provided, the IP address will be fetched from an external service
|
||||
--announce-server-name <name> The name of the server to announce to peers. This is useful if you have SSL/TLS enabled. (default: "none")
|
||||
-g, --gossip-port <port> The tcp port libp2p should gossip over. (default: 2282)
|
||||
-r, --rpc-port <port> The tcp port that the rpc server should listen on. (default: 2283)
|
||||
--rpc-auth <username:password,...> Enable Auth for RPC submit methods with the username and password. (default: disabled)
|
||||
--rpc-rate-limit <number> Impose a Per IP rate limit per minute. Set to -1 for no rate limits (default: 20k/min)
|
||||
Hubble Options:
|
||||
-n --network <network> ID of the Farcaster Network (default: 3 (devnet))
|
||||
-i, --id <filepath> Path to the PeerId file.
|
||||
-c, --config <filepath> Path to the config file.
|
||||
--db-name <name> The name of the RocksDB instance. (default: rocks.hub._default)
|
||||
--admin-server-enabled Enable the admin server. (default: disabled)
|
||||
--admin-server-host <host> The host the admin server should listen on. (default: '127.0.0.1')
|
||||
--db-name <name> The name of the RocksDB instance
|
||||
--rebuild-sync-trie Rebuilds the sync trie before starting
|
||||
--resync-eth-events Resyncs events from the Farcaster contracts before starting
|
||||
--resync-name-events Resyncs events from the FName registry server before starting
|
||||
--commit-lock-timeout <number> Commit lock timeout in milliseconds (default: 500)
|
||||
--commit-lock-max-pending <number> Commit lock max pending jobs (default: 1000)
|
||||
-i, --id <filepath> Path to the PeerId file
|
||||
-n --network <network> Farcaster network ID
|
||||
--process-file-prefix <prefix> Prefix for file to which hub process number is written. (default: "")
|
||||
|
||||
Ethereum Options:
|
||||
-m, --eth-mainnet-rpc-url <url> RPC URL of a Mainnet ETH Node (or comma separated list of URLs)
|
||||
-e, --eth-rpc-url <url> RPC URL of a Goerli ETH Node (or comma separated list of URLs)
|
||||
-l, --l2-rpc-url <url> RPC URL of a Goerli Optimism Node (or comma separated list of URLs)
|
||||
--rank-rpcs Rank the RPCs by latency/stability and use the fastest one (default: disabled)
|
||||
--fname-server-url <url> The URL for the FName registry server (default: https://fnames.farcaster.xyz
|
||||
--fir-address <address> The address of the Farcaster ID Registry contract
|
||||
--first-block <number> The block number to begin syncing events from Farcaster contracts
|
||||
|
||||
Networking Options:
|
||||
-a, --allowed-peers <peerIds...> Only peer with specific peer ids. (default: all peers allowed)
|
||||
-b, --bootstrap <peer-multiaddrs...> Peers to bootstrap gossip and sync from. (default: none)
|
||||
-g, --gossip-port <port> Port to use for gossip (default: 2282)
|
||||
-r, --rpc-port <port> Port to use for gRPC (default: 2283)
|
||||
--ip <ip-address> IP address to listen on (default: "127.0.0.1")
|
||||
--announce-ip <ip-address> Public IP address announced to peers (default: fetched with external service)
|
||||
--announce-server-name <name> Server name announced to peers, useful if SSL/TLS enabled. (default: "none")
|
||||
--direct-peers <peer-multiaddrs...> A list of peers for libp2p to directly peer with (default: [])
|
||||
--rpc-rate-limit <number> RPC rate limit for peers specified in rpm. Set to -1 for none. (default: 20k/min)
|
||||
|
||||
Debugging Options:
|
||||
--gossip-metrics-enabled Generate tracing and metrics for the gossip network. (default: disabled)
|
||||
--profile-sync Profile a full hub sync and exit. (default: disabled)
|
||||
--rebuild-sync-trie Rebuild the sync trie before starting (default: disabled)
|
||||
--resync-eth-events Resync events from the Farcaster contracts before starting (default: disabled)
|
||||
--resync-name-events Resync events from the Fname server before starting (default: disabled)
|
||||
--chunk-size <number> The number of blocks to batch when syncing historical events from Farcaster contracts. (default: 10000)
|
||||
--commit-lock-timeout <number> Rocks DB commit lock timeout in milliseconds (default: 500)
|
||||
--commit-lock-max-pending <number> Rocks DB commit lock max pending jobs (default: 1000)
|
||||
--rpc-auth <username:password,...> Require username-password auth for RPC submit. (default: disabled)
|
||||
|
||||
--fnr-address <address> The address of the Farcaster Name Registry contract
|
||||
-h, --help display help for command
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user