conflux/
cli.rs

1use crate::command::dump::DumpCommand;
2use clap::{Args, Parser, Subcommand, ValueEnum};
3
4/// Conflux client
5#[derive(Parser, Debug)]
6#[clap(
7    name = "conflux",
8    about = "Conflux client",
9    author = "The Conflux Team",
10    version
11)]
12pub struct Cli {
13    /// Use the preset testing configurations. dev or test.
14    #[arg(long, value_name = "MODE", value_enum)]
15    pub mode: Option<String>,
16
17    /// Specify the port for P2P connections.
18    #[arg(long, short = 'p', value_name = "PORT")]
19    pub port: Option<String>,
20
21    /// Specify the UDP port for peer discovery.
22    #[arg(id = "udp-port", long = "udp-port", value_name = "PORT")]
23    pub udp_port: Option<String>,
24
25    /// Specify the port for the WebSocket JSON-RPC API server.
26    #[arg(
27        id = "jsonrpc-ws-port",
28        long = "jsonrpc-ws-port",
29        value_name = "PORT"
30    )]
31    pub jsonrpc_ws_port: Option<String>,
32
33    /// Specify the port for the TCP JSON-RPC API server.
34    #[arg(
35        id = "jsonrpc-tcp-port",
36        long = "jsonrpc-tcp-port",
37        value_name = "PORT"
38    )]
39    pub jsonrpc_tcp_port: Option<String>,
40
41    /// Specify the port for the HTTP JSON-RPC API server.
42    #[arg(
43        id = "jsonrpc-http-port",
44        long = "jsonrpc-http-port",
45        value_name = "PORT"
46    )]
47    pub jsonrpc_http_port: Option<String>,
48
49    /// Specify CORS header for HTTP JSON-RPC API responses.
50    #[arg(id = "jsonrpc-cors", long = "jsonrpc-cors", value_name = "URL")]
51    pub jsonrpc_cors: Option<String>,
52
53    /// Enable HTTP/1.1 keep alive header.
54    #[arg(
55        id = "jsonrpc-http-keep-alive",
56        long = "jsonrpc-http-keep-alive",
57        value_name = "BOOL"
58    )]
59    pub jsonrpc_http_keep_alive: Option<String>,
60
61    /// Specify the filename for the log. Stdout will be used by default if
62    /// omitted.
63    #[arg(id = "log-file", long = "log-file", value_name = "FILE")]
64    pub log_file: Option<String>,
65
66    /// Can be error/warn/info/debug/trace. Default is the info level.
67    #[arg(id = "log-level", long = "log-level", value_name = "LEVEL")]
68    pub log_level: Option<String>,
69
70    /// Sets a custom log config file.
71    #[arg(id = "log-conf", long = "log-conf", value_name = "FILE")]
72    pub log_conf: Option<String>,
73
74    /// Sets a custom config file.
75    #[arg(short = 'c', long, value_name = "FILE")]
76    pub config: Option<String>,
77
78    /// Sets a custom list of bootnodes.
79    #[arg(long, value_name = "NODES")]
80    // "bootnodes" does not contain a hyphen
81    pub bootnodes: Option<String>,
82
83    /// Sets a custom directory for network configurations.
84    #[arg(id = "netconf-dir", long = "netconf-dir", value_name = "DIR")]
85    pub netconf_dir: Option<String>,
86
87    /// Sets a custom public address to be connected by others.
88    #[arg(
89        id = "public-address",
90        long = "public-address",
91        value_name = "IP ADDRESS"
92    )]
93    pub public_address: Option<String>,
94
95    /// Sets a custom secret key to generate unique node ID.
96    #[arg(id = "net-key", long = "net-key", value_name = "KEY")]
97    pub net_key: Option<String>,
98
99    /// Start mining if set to true. Ensure that mining-author is set.
100    #[arg(id = "start-mining", long = "start-mining", value_name = "BOOL")]
101    pub start_mining: Option<String>,
102
103    /// Set the address to receive mining rewards.
104    #[arg(
105        id = "mining-author",
106        long = "mining-author",
107        value_name = "ADDRESS"
108    )]
109    pub mining_author: Option<String>,
110
111    /// Sets the ledger cache size.
112    #[arg(
113        id = "ledger-cache-size",
114        long = "ledger-cache-size",
115        value_name = "SIZE"
116    )]
117    pub ledger_cache_size: Option<String>,
118
119    /// Sets the db cache size.
120    #[arg(id = "db-cache-size", long = "db-cache-size", value_name = "SIZE")]
121    pub db_cache_size: Option<String>,
122
123    /// Enable discovery protocol.
124    #[arg(
125        id = "enable-discovery",
126        long = "enable-discovery",
127        value_name = "BOOL"
128    )]
129    pub enable_discovery: Option<String>,
130
131    /// How often Conflux updates its peer table (default 300).
132    #[arg(
133        id = "node-table-timeout-s",
134        long = "node-table-timeout-s",
135        value_name = "SEC"
136    )]
137    pub node_table_timeout_s: Option<String>,
138
139    /// How long Conflux waits for promoting a peer to trustworthy (default 3 *
140    /// 24 * 3600).
141    #[arg(
142        id = "node-table-promotion-timeout-s",
143        long = "node-table-promotion-timeout-s",
144        value_name = "SEC"
145    )]
146    pub node_table_promotion_timeout_s: Option<String>,
147
148    /// Sets test mode for adding latency
149    #[arg(id = "test-mode", long = "test-mode", value_name = "BOOL")]
150    pub test_mode: Option<String>,
151
152    /// Sets the compaction profile of RocksDB.
153    #[arg(
154        id = "db-compact-profile",
155        long = "db-compact-profile",
156        value_name = "ENUM"
157    )]
158    pub db_compact_profile: Option<String>,
159
160    /// Sets the root path of db.
161    #[arg(id = "block-db-dir", long = "block-db-dir", value_name = "DIR")]
162    pub block_db_dir: Option<String>,
163
164    /// Sets the test chain json file.
165    #[arg(
166        id = "load-test-chain",
167        long = "load-test-chain",
168        value_name = "FILE"
169    )]
170    pub load_test_chain: Option<String>,
171
172    /// Sets egress queue capacity of P2P network.
173    #[arg(
174        id = "egress-queue-capacity",
175        long = "egress-queue-capacity",
176        value_name = "MB"
177    )]
178    pub egress_queue_capacity: Option<String>,
179
180    /// Sets minimum throttling queue size of egress.
181    #[arg(
182        id = "egress-min-throttle",
183        long = "egress-min-throttle",
184        value_name = "MB"
185    )]
186    pub egress_min_throttle: Option<String>,
187
188    /// Sets maximum throttling queue size of egress.
189    #[arg(
190        id = "egress-max-throttle",
191        long = "egress-max-throttle",
192        value_name = "MB"
193    )]
194    pub egress_max_throttle: Option<String>,
195
196    /// Sets the size of the epoch batches used during log filtering.
197    #[arg(
198        id = "get-logs-epoch-batch-size",
199        long = "get-logs-epoch-batch-size",
200        value_name = "SIZE"
201    )]
202    pub get_logs_epoch_batch_size: Option<String>,
203
204    /// Sets the maximum number of allowed epochs during log filtering.
205    #[arg(
206        id = "get-logs-filter-max-epoch-range",
207        long = "get-logs-filter-max-epoch-range",
208        value_name = "SIZE"
209    )]
210    pub get_logs_filter_max_epoch_range: Option<String>,
211
212    /// Sets the maximum number of log entries returned during log filtering.
213    #[arg(
214        id = "get-logs-filter-max-limit",
215        long = "get-logs-filter-max-limit",
216        value_name = "SIZE"
217    )]
218    pub get_logs_filter_max_limit: Option<String>,
219
220    /// Sets the maximum number of allowed blocks during log filtering.
221    #[arg(
222        id = "get-logs-filter-max-block-number-range",
223        long = "get-logs-filter-max-block-number-range",
224        value_name = "SIZE"
225    )]
226    pub get_logs_filter_max_block_number_range: Option<String>,
227
228    /// Sets the time after which accounts are re-read from disk.
229    #[arg(
230        id = "account-provider-refresh-time-ms",
231        long = "account-provider-refresh-time-ms",
232        value_name = "MS"
233    )]
234    pub account_provider_refresh_time_ms: Option<String>,
235
236    ///  Sets the encryption password for the pos private key file. It's used
237    /// to encrypt a new generated key or to decrypt an existing key file.
238    #[arg(
239        id = "dev-pos-private-key-encryption-password",
240        long = "dev-pos-private-key-encryption-password",
241        value_name = "PASSWD"
242    )]
243    pub dev_pos_private_key_encryption_password: Option<String>,
244
245    /// If true, the node will start PoS election and voting if it's available.
246    #[arg(
247        id = "pos-started-as-voter",
248        long = "pos-started-as-voter",
249        value_name = "BOOL"
250    )]
251    pub pos_started_as_voter: Option<String>,
252
253    #[arg(long)]
254    pub light: bool,
255    #[arg(long)]
256    pub archive: bool,
257    #[arg(long)]
258    pub tg_archive: bool,
259    #[arg(long)]
260    pub full: bool,
261
262    #[command(subcommand)]
263    pub command: Option<Commands>,
264}
265
266#[derive(Subcommand, Debug)]
267pub enum Commands {
268    /// Manage accounts
269    #[command(subcommand_required = true, arg_required_else_help = true)]
270    Account(AccountSubcommands),
271    /// Dump eSpace account state at a given block number
272    #[command(subcommand_required = false, arg_required_else_help = false)]
273    Dump(DumpCommand),
274    /// RPC based subcommands to query blockchain information and send
275    /// transactions
276    #[command(subcommand_required = true, arg_required_else_help = true)]
277    Rpc(RpcCommand),
278}
279
280/**
281 * --------------- Account Subcommands ---------------
282 */
283
284/// Account Subcommands
285#[derive(Args, Debug)]
286pub struct AccountSubcommands {
287    #[command(subcommand)]
288    pub command: AccountCommand,
289}
290
291#[derive(Subcommand, Debug)]
292pub enum AccountCommand {
293    /// Create a new account (and its associated key) for the given --chain
294    /// (default conflux).
295    New(AccountNewArgs),
296    /// List existing accounts of the given --chain (default conflux).
297    List,
298    /// Import accounts from JSON UTC keystore files
299    Import(AccountImportArgs),
300}
301
302#[derive(Args, Debug)]
303pub struct AccountNewArgs {
304    /// Specify the number of iterations to use when deriving key from the
305    /// password (bigger is more secure).
306    #[arg(
307        id = "keys-iterations",
308        long = "keys-iterations",
309        value_name = "NUM",
310        default_value = "10240"
311    )]
312    pub keys_iterations: Option<u32>,
313    /// Provide a file containing a password for unlocking an account.
314    #[arg(long, value_name = "FILE")]
315    pub password: Option<String>,
316}
317
318#[derive(Args, Debug)]
319pub struct AccountImportArgs {
320    /// A list of file paths to import.
321    #[arg(id = "import-path", long = "import-path", value_name = "PATH", required = true, num_args = 1..)]
322    pub import_path: Vec<String>,
323}
324
325/**
326 * --------------- RPC Subcommands ---------------
327 */
328
329// RPC Subcommands
330#[derive(Args, Debug)]
331pub struct RpcCommand {
332    /// URL of RPC server
333    #[arg(
334        long,
335        value_name = "URL",
336        default_value = "http://localhost:12539",
337        global = true
338    )]
339    pub url: String,
340    #[command(subcommand)]
341    pub command: RpcSubcommands,
342}
343
344#[derive(Subcommand, Debug)]
345pub enum RpcSubcommands {
346    /// Get recent mean gas price
347    Price(RpcPriceArgs),
348    /// Get epoch number
349    Epoch(RpcEpochArgs),
350    /// Get balance of specified account
351    Balance(RpcBalanceArgs),
352    /// Get bytecode of specified contract
353    Code(RpcCodeArgs),
354    /// Get block by hash
355    #[command(name = "block-by-hash")]
356    BlockByHash(RpcBlockByHashArgs),
357    /// Get block by hash with pivot chain assumption
358    #[command(name = "block-with-assumption")]
359    BlockWithAssumption(RpcBlockWithAssumptionArgs),
360    /// Get block by epoch
361    #[command(name = "block-by-epoch")]
362    BlockByEpoch(RpcBlockByEpochArgs),
363    /// Get the best block hash
364    #[command(name = "best-block-hash")]
365    BestBlockHash(RpcBestBlockHashArgs),
366    /// Get nonce of specified account
367    Nonce(RpcNonceArgs),
368    /// Send a signed transaction and return its hash
369    Send(RpcSendArgs),
370    /// Get transaction by hash
371    Tx(RpcTxArgs),
372    /// Get blocks of specified epoch
373    Blocks(RpcBlocksArgs),
374    /// Get skipped blocks of specified epoch
375    #[command(name = "skipped-blocks")]
376    SkippedBlocks(RpcSkippedBlocksArgs),
377    /// Get receipt by transaction hash
378    Receipt(RpcReceiptArgs),
379    /// Executes a new message call immediately without creating a transaction
380    Call(RpcCallArgs),
381    /// Executes a call request and returns the gas used
382    #[command(name = "estimate-gas")]
383    EstimateGas(RpcEstimateGasArgs),
384    /// Local subcommands (requires jsonrpc_local_http_port configured)
385    #[command(subcommand_required = true, arg_required_else_help = true)]
386    Local(RpcLocalSubcommands),
387}
388
389#[derive(Args, Debug)]
390pub struct RpcPriceArgs {
391    #[arg(
392        id = "rpc-method",
393        long = "rpc-method",
394        default_value = "cfx_gasPrice",
395        hide = true
396    )]
397    pub rpc_method: String,
398}
399
400#[derive(Args, Debug)]
401pub struct RpcEpochArgs {
402    #[arg(
403        id = "rpc-method",
404        long = "rpc-method",
405        default_value = "cfx_epochNumber",
406        hide = true
407    )]
408    pub rpc_method: String,
409    #[arg(
410        id = "rpc-args",
411        long = "rpc-args",
412        hide = true,
413        default_value = "epoch",
414        value_delimiter = ','
415    )]
416    pub rpc_args: Vec<String>,
417    /// Epoch (latest_mined, latest_state, earliest or epoch number in HEX
418    /// format)
419    #[arg(long, value_name = "EPOCH")]
420    pub epoch: Option<String>,
421}
422
423#[derive(Args, Debug)]
424pub struct RpcBalanceArgs {
425    #[arg(
426        id = "rpc-method",
427        long = "rpc-method",
428        default_value = "cfx_getBalance",
429        hide = true
430    )]
431    pub rpc_method: String,
432    #[arg(
433        id = "rpc-args",
434        long = "rpc-args",
435        hide = true,
436        default_value = "address,epoch",
437        value_delimiter = ','
438    )]
439    pub rpc_args: Vec<String>,
440    /// Account address / Contract address
441    #[arg(long, required = true, value_name = "ADDRESS")]
442    pub address: String,
443    /// Epoch (latest_mined, latest_state, earliest or epoch number in HEX
444    /// format)
445    #[arg(long, value_name = "EPOCH")]
446    pub epoch: Option<String>,
447}
448
449#[derive(Args, Debug)]
450pub struct RpcCodeArgs {
451    #[arg(
452        id = "rpc-method",
453        long = "rpc-method",
454        default_value = "cfx_getCode",
455        hide = true
456    )]
457    pub rpc_method: String,
458    #[arg(
459        id = "rpc-args",
460        long = "rpc-args",
461        hide = true,
462        default_value = "address,epoch",
463        value_delimiter = ','
464    )]
465    pub rpc_args: Vec<String>,
466    #[arg(long = "address", required = true, value_name = "ADDRESS")]
467    pub address: String,
468    /// Epoch (latest_mined, latest_state, earliest or epoch number in HEX
469    /// format)
470    #[arg(long, required = true, value_name = "EPOCH")]
471    pub epoch: String,
472}
473
474#[derive(Args, Debug)]
475pub struct RpcBlockByHashArgs {
476    #[arg(
477        id = "rpc-method",
478        long = "rpc-method",
479        default_value = "cfx_getBlockByHash",
480        hide = true
481    )]
482    pub rpc_method: String,
483    #[arg(
484        id = "rpc-args",
485        long = "rpc-args",
486        hide = true,
487        default_value = "hash,include-txs:bool",
488        value_delimiter = ','
489    )]
490    pub rpc_args: Vec<String>,
491    /// Block hash / Transaction hash
492    #[arg(long, required = true, value_name = "HASH")]
493    pub hash: String,
494    /// Whether to return detailed transactions in block
495    #[arg(id = "include-txs", long = "include-txs")]
496    pub include_txs: bool,
497}
498
499#[derive(Args, Debug)]
500pub struct RpcBlockWithAssumptionArgs {
501    #[arg(
502        id = "rpc-method",
503        long = "rpc-method",
504        default_value = "cfx_getBlockByHashWithPivotAssumption",
505        hide = true
506    )]
507    pub rpc_method: String,
508    #[arg(
509        id = "rpc-args",
510        long = "rpc-args",
511        hide = true,
512        default_value = "block-hash,pivot-hash,epoch-number:u64",
513        value_delimiter = ','
514    )]
515    pub rpc_args: Vec<String>,
516    /// Block hash
517    #[arg(
518        id = "block-hash",
519        long = "block-hash",
520        required = true,
521        value_name = "HASH"
522    )]
523    pub block_hash: String,
524    /// Pivot block hash
525    #[arg(
526        id = "pivot-hash",
527        long = "pivot-hash",
528        required = true,
529        value_name = "HASH"
530    )]
531    pub pivot_hash: String,
532    /// Epoch number
533    #[arg(
534        id = "epoch-number",
535        long = "epoch-number",
536        required = true,
537        value_name = "NUMBER"
538    )]
539    pub epoch_number: u64,
540}
541
542#[derive(Args, Debug)]
543pub struct RpcBlockByEpochArgs {
544    #[arg(
545        id = "rpc-method",
546        long = "rpc-method",
547        default_value = "cfx_getBlockByEpochNumber",
548        hide = true
549    )]
550    pub rpc_method: String,
551    #[arg(
552        id = "rpc-args",
553        long = "rpc-args",
554        hide = true,
555        default_value = "epoch,include-txs:bool",
556        value_delimiter = ','
557    )]
558    pub rpc_args: Vec<String>,
559    /// Epoch (latest_mined, latest_state, earliest or epoch number in HEX
560    /// format)
561    #[arg(long, required = true, value_name = "EPOCH")]
562    pub epoch: String,
563    /// Whether to return detailed transactions in block
564    #[arg(id = "include-txs", long = "include-txs")]
565    pub include_txs: bool,
566}
567
568#[derive(Args, Debug)]
569pub struct RpcBestBlockHashArgs {
570    #[arg(
571        id = "rpc-method",
572        long = "rpc-method",
573        default_value = "cfx_getBestBlockHash",
574        hide = true
575    )]
576    pub rpc_method: String,
577}
578
579#[derive(Args, Debug)]
580pub struct RpcNonceArgs {
581    #[arg(
582        id = "rpc-method",
583        long = "rpc-method",
584        default_value = "cfx_getNextNonce",
585        hide = true
586    )]
587    pub rpc_method: String,
588    #[arg(
589        id = "rpc-args",
590        long = "rpc-args",
591        hide = true,
592        default_value = "address,epoch",
593        value_delimiter = ','
594    )]
595    pub rpc_args: Vec<String>,
596    /// Account address / Contract address
597    #[arg(long, required = true, value_name = "ADDRESS")]
598    pub address: String,
599    /// Epoch (latest_mined, latest_state, earliest or epoch number in HEX
600    /// format)
601    #[arg(long, value_name = "EPOCH")]
602    pub epoch: Option<String>,
603}
604
605#[derive(Args, Debug)]
606pub struct RpcSendArgs {
607    #[arg(
608        id = "rpc-method",
609        long = "rpc-method",
610        default_value = "cfx_sendRawTransaction",
611        hide = true
612    )]
613    pub rpc_method: String,
614    #[arg(
615        id = "rpc-args",
616        long = "rpc-args",
617        hide = true,
618        default_value = "raw-bytes",
619        value_delimiter = ','
620    )]
621    pub rpc_args: Vec<String>,
622    /// Signed transaction data
623    #[arg(
624        id = "raw-bytes",
625        long = "raw-bytes",
626        required = true,
627        value_name = "HEX"
628    )]
629    pub raw_bytes: String,
630}
631
632#[derive(Args, Debug)]
633pub struct RpcTxArgs {
634    #[arg(
635        id = "rpc-method",
636        long = "rpc-method",
637        default_value = "cfx_getTransactionByHash",
638        hide = true
639    )]
640    pub rpc_method: String,
641    #[arg(
642        id = "rpc-args",
643        long = "rpc-args",
644        hide = true,
645        default_value = "hash",
646        value_delimiter = ','
647    )]
648    pub rpc_args: Vec<String>,
649    /// Block hash / Transaction hash
650    #[arg(long, required = true, value_name = "HASH")]
651    pub hash: String,
652}
653
654#[derive(Args, Debug)]
655pub struct RpcBlocksArgs {
656    #[arg(
657        id = "rpc-method",
658        long = "rpc-method",
659        default_value = "cfx_getBlocksByEpoch",
660        hide = true
661    )]
662    pub rpc_method: String,
663    #[arg(
664        id = "rpc-args",
665        long = "rpc-args",
666        hide = true,
667        default_value = "epoch",
668        value_delimiter = ','
669    )]
670    pub rpc_args: Vec<String>,
671    /// Epoch (latest_mined, latest_state, earliest or epoch number in HEX
672    /// format)
673    #[arg(long, required = true, value_name = "EPOCH")]
674    pub epoch: String,
675}
676
677#[derive(Args, Debug)]
678pub struct RpcSkippedBlocksArgs {
679    #[arg(
680        id = "rpc-method",
681        long = "rpc-method",
682        default_value = "cfx_getSkippedBlocksByEpoch",
683        hide = true
684    )]
685    pub rpc_method: String,
686    #[arg(
687        id = "rpc-args",
688        long = "rpc-args",
689        hide = true,
690        default_value = "epoch",
691        value_delimiter = ','
692    )]
693    pub rpc_args: Vec<String>,
694    /// Epoch (latest_mined, latest_state, earliest or epoch number in HEX
695    /// format)
696    #[arg(long, required = true, value_name = "EPOCH")]
697    pub epoch: String,
698}
699
700#[derive(Args, Debug)]
701pub struct RpcReceiptArgs {
702    #[arg(
703        id = "rpc-method",
704        long = "rpc-method",
705        default_value = "cfx_getTransactionReceipt",
706        hide = true
707    )]
708    pub rpc_method: String,
709    #[arg(
710        id = "rpc-args",
711        long = "rpc-args",
712        hide = true,
713        default_value = "hash",
714        value_delimiter = ','
715    )]
716    pub rpc_args: Vec<String>,
717    /// Block hash / Transaction hash
718    #[arg(long, required = true, value_name = "HASH")]
719    pub hash: String,
720}
721
722#[derive(Args, Debug)]
723pub struct RpcCallArgs {
724    #[arg(
725        id = "rpc-method",
726        long = "rpc-method",
727        default_value = "cfx_call",
728        hide = true
729    )]
730    pub rpc_method: String,
731    #[arg(
732        id = "rpc-args",
733        long = "rpc-args",
734        hide = true,
735        default_value = "tx:map(from;to;gas-price;type;max-fee-per-gas;max-priority-fee-per-gas;gas;value;data;nonce),epoch",
736        value_delimiter = ','
737    )]
738    pub rpc_args: Vec<String>,
739    /// Transaction from address
740    #[arg(long, value_name = "ADDRESS")]
741    pub from: Option<String>,
742    /// Transaction to address
743    #[arg(long, value_name = "ADDRESS")]
744    pub to: Option<String>,
745    /// Transaction gas price
746    #[arg(id = "gas-price", long = "gas-price", value_name = "HEX")]
747    pub gas_price: Option<String>,
748    /// Transaction type
749    #[arg(id = "type", long = "type", value_name = "HEX")]
750    // "type" does not contain a hyphen
751    pub tx_type: Option<String>,
752    /// Transaction max fee per gas
753    #[arg(
754        id = "max-fee-per-gas",
755        long = "max-fee-per-gas",
756        value_name = "HEX"
757    )]
758    pub max_fee_per_gas: Option<String>,
759    /// Transaction max priority fee per gas
760    #[arg(
761        id = "max-priority-fee-per-gas",
762        long = "max-priority-fee-per-gas",
763        value_name = "HEX"
764    )]
765    pub max_priority_fee_per_gas: Option<String>,
766    /// Gas provided for transaction execution
767    #[arg(long, value_name = "HEX")]
768    pub gas: Option<String>,
769    /// value sent with this transaction
770    #[arg(long, value_name = "HEX")]
771    pub value: Option<String>,
772    /// Hash of the method signature and encoded parameters
773    #[arg(long, value_name = "HEX")]
774    pub data: Option<String>,
775    /// Transaction nonce
776    #[arg(long, value_name = "HEX")]
777    pub nonce: Option<String>,
778    /// Epoch
779    #[arg(long, value_name = "EPOCH")]
780    pub epoch: Option<String>,
781}
782
783#[derive(Args, Debug)]
784pub struct RpcEstimateGasArgs {
785    #[arg(
786        id = "rpc-method",
787        long = "rpc-method",
788        default_value = "cfx_estimateGas",
789        hide = true
790    )]
791    pub rpc_method: String,
792    #[arg(
793        id = "rpc-args",
794        long = "rpc-args",
795        hide = true,
796        default_value = "tx:map(from;to;gas-price;type;max-fee-per-gas;max-priority-fee-per-gas;gas;value;data;nonce),epoch",
797        value_delimiter = ','
798    )]
799    pub rpc_args: Vec<String>,
800    /// Transaction from address
801    #[arg(long, value_name = "ADDRESS")]
802    pub from: Option<String>,
803    /// Transaction to address
804    #[arg(long, value_name = "ADDRESS")]
805    pub to: Option<String>,
806    /// Transaction gas price
807    #[arg(id = "gas-price", long = "gas-price", value_name = "HEX")]
808    pub gas_price: Option<String>,
809    /// Transaction type
810    #[arg(id = "type", long = "type", value_name = "HEX")]
811    // "type" does not contain a hyphen
812    pub tx_type: Option<String>,
813    /// Transaction max fee per gas
814    #[arg(
815        id = "max-fee-per-gas",
816        long = "max-fee-per-gas",
817        value_name = "HEX"
818    )]
819    pub max_fee_per_gas: Option<String>,
820    /// Transaction max priority fee per gas
821    #[arg(
822        id = "max-priority-fee-per-gas",
823        long = "max-priority-fee-per-gas",
824        value_name = "HEX"
825    )]
826    pub max_priority_fee_per_gas: Option<String>,
827    /// Gas provided for transaction execution
828    #[arg(long, value_name = "HEX")]
829    pub gas: Option<String>,
830    /// value sent with this transaction
831    #[arg(long, value_name = "HEX")]
832    pub value: Option<String>,
833    /// Hash of the method signature and encoded parameters
834    #[arg(long, value_name = "HEX")]
835    pub data: Option<String>,
836    /// Transaction nonce
837    #[arg(long, value_name = "HEX")]
838    pub nonce: Option<String>,
839    /// Epoch
840    #[arg(long, value_name = "EPOCH")]
841    pub epoch: Option<String>,
842}
843
844/**
845 * --------------- RPC Local Subcommands ---------------
846 */
847
848// RPC Local Subcommands
849#[derive(Args, Debug)]
850pub struct RpcLocalSubcommands {
851    #[command(subcommand)]
852    pub command: RpcLocalCommand,
853}
854
855#[derive(Subcommand, Debug)]
856pub enum RpcLocalCommand {
857    /// Send a transaction and return its hash
858    Send(RpcLocalSendArgs),
859    /// Account related subcommands
860    #[command(subcommand_required = true, arg_required_else_help = true)]
861    Account(RpcLocalAccountSubcommands),
862    /// Transaction pool subcommands
863    #[command(subcommand_required = true, arg_required_else_help = true)]
864    Txpool(RpcLocalTxpoolSubcommands),
865    /// Network subcommands
866    #[command(subcommand_required = true, arg_required_else_help = true)]
867    Net(RpcLocalNetSubcommands),
868    /// Get the current synchronization phase
869    #[command(name = "sync-phase")]
870    SyncPhase(RpcLocalSyncPhaseArgs),
871    /// Get the consensus graph state
872    #[command(name = "consensus-graph-state")]
873    ConsensusGraphState(RpcLocalConsensusGraphStateArgs),
874    /// Test subcommands (used for test purpose only)
875    #[command(subcommand_required = true, arg_required_else_help = true)]
876    Test(RpcLocalTestSubcommands),
877    /// PoS subcommands
878    #[command(subcommand_required = true, arg_required_else_help = true)]
879    Pos(RpcLocalPosSubcommands),
880}
881
882#[derive(Args, Debug)]
883pub struct RpcLocalSendArgs {
884    #[arg(
885        id = "rpc-method",
886        long = "rpc-method",
887        default_value = "cfx_sendTransaction",
888        hide = true
889    )]
890    pub rpc_method: String,
891    #[arg(
892        id = "rpc-args",
893        long = "rpc-args",
894        hide = true,
895        default_value = "tx:map(from;to;gas-price;type;max-fee-per-gas;max-priority-fee-per-gas;gas;value;data;nonce;storageLimit),password:password",
896        value_delimiter = ','
897    )]
898    pub rpc_args: Vec<String>,
899    /// Transaction from address
900    #[arg(long, required = true, value_name = "ADDRESS")]
901    pub from: String,
902    /// Transaction to address (empty to create contract)
903    #[arg(long, value_name = "ADDRESS")]
904    pub to: Option<String>,
905    /// Transaction gas price
906    #[arg(
907        id = "gas-price",
908        long = "gas-price",
909        value_name = "HEX",
910        default_value = "0x2540BE400"
911    )]
912    pub gas_price: Option<String>,
913    /// Transaction type
914    #[arg(id = "type", long = "type", value_name = "HEX")]
915    // "type" does not contain a hyphen
916    pub tx_type: Option<String>,
917    /// Transaction max fee per gas
918    #[arg(
919        id = "max-fee-per-gas",
920        long = "max-fee-per-gas",
921        value_name = "HEX"
922    )]
923    pub max_fee_per_gas: Option<String>,
924    /// Transaction max priority fee per gas
925    #[arg(
926        id = "max-priority-fee-per-gas",
927        long = "max-priority-fee-per-gas",
928        value_name = "HEX"
929    )]
930    pub max_priority_fee_per_gas: Option<String>,
931    /// Gas provided for transaction execution
932    #[arg(long, value_name = "HEX", default_value = "0x5208")]
933    pub gas: Option<String>,
934    /// value sent with this transaction
935    #[arg(long, required = true, value_name = "HEX")]
936    pub value: String,
937    /// Hash of the method signature and encoded parameters
938    #[arg(long, value_name = "HEX")]
939    pub data: Option<String>,
940    /// Transaction nonce
941    #[arg(long, value_name = "HEX")]
942    pub nonce: Option<String>,
943    /// Storage limit for the transaction
944    #[arg(
945        id = "storage-limit",
946        long = "storage-limit",
947        value_name = "HEX",
948        default_value = "0x0"
949    )]
950    pub storage_limit: Option<String>,
951}
952
953#[derive(Args, Debug)]
954pub struct RpcLocalAccountSubcommands {
955    #[command(subcommand)]
956    pub command: RpcLocalAccountCommand,
957}
958
959#[derive(Subcommand, Debug)]
960pub enum RpcLocalAccountCommand {
961    /// List all accounts
962    List(RpcLocalAccountListArgs),
963    /// Create a new account
964    New(RpcLocalAccountNewArgs),
965    /// Unlock an account
966    Unlock(RpcLocalAccountUnlockArgs),
967    /// Lock an unlocked account
968    Lock(RpcLocalAccountLockArgs),
969}
970
971#[derive(Args, Debug)]
972pub struct RpcLocalAccountListArgs {
973    #[arg(
974        id = "rpc-method",
975        long = "rpc-method",
976        default_value = "cfx_accounts",
977        hide = true
978    )]
979    pub rpc_method: String,
980}
981
982#[derive(Args, Debug)]
983pub struct RpcLocalAccountNewArgs {
984    #[arg(
985        id = "rpc-method",
986        long = "rpc-method",
987        default_value = "cfx_newAccount",
988        hide = true
989    )]
990    pub rpc_method: String,
991    #[arg(
992        id = "rpc-args",
993        long = "rpc-args",
994        hide = true,
995        default_value = "password:password2",
996        value_delimiter = ','
997    )]
998    pub rpc_args: Vec<String>,
999}
1000
1001#[derive(Args, Debug)]
1002pub struct RpcLocalAccountUnlockArgs {
1003    #[arg(
1004        id = "rpc-method",
1005        long = "rpc-method",
1006        default_value = "cfx_unlockAccount",
1007        hide = true
1008    )]
1009    pub rpc_method: String,
1010    #[arg(
1011        id = "rpc-args",
1012        long = "rpc-args",
1013        hide = true,
1014        default_value = "address,password:password,duration",
1015        value_delimiter = ','
1016    )]
1017    pub rpc_args: Vec<String>,
1018    /// Address of the account
1019    #[arg(long, required = true, value_name = "ADDRESS")]
1020    pub address: String,
1021    /// Duration to unlock the account, use 0x0 to unlock permanently (strongly
1022    /// not recommended!).
1023    #[arg(long, value_name = "DURATION", default_value = "0x3c")]
1024    pub duration: Option<String>,
1025}
1026
1027#[derive(Args, Debug)]
1028pub struct RpcLocalAccountLockArgs {
1029    #[arg(
1030        id = "rpc-method",
1031        long = "rpc-method",
1032        default_value = "cfx_lockAccount",
1033        hide = true
1034    )]
1035    pub rpc_method: String,
1036    #[arg(
1037        id = "rpc-args",
1038        long = "rpc-args",
1039        hide = true,
1040        default_value = "address",
1041        value_delimiter = ','
1042    )]
1043    pub rpc_args: Vec<String>,
1044    /// Address of the account
1045    #[arg(long, required = true, value_name = "ADDRESS")]
1046    pub address: String,
1047}
1048
1049#[derive(Args, Debug)]
1050pub struct RpcLocalTxpoolSubcommands {
1051    #[command(subcommand)]
1052    pub command: RpcLocalTxpoolCommand,
1053}
1054
1055#[derive(Subcommand, Debug)]
1056pub enum RpcLocalTxpoolCommand {
1057    /// Get the number of transactions for different status
1058    Status(RpcLocalTxpoolStatusArgs),
1059    /// Get the detailed status of specified transaction
1060    #[command(name = "inspect-one")]
1061    InspectOne(RpcLocalTxpoolInspectOneArgs),
1062    /// List textual summary of all transactions
1063    Inspect(RpcLocalTxpoolInspectArgs),
1064    /// List exact details of all transactions
1065    Content(RpcLocalTxpoolContentArgs),
1066    /// Remove all transactions
1067    Clear(RpcLocalTxpoolClearArgs),
1068}
1069
1070#[derive(Args, Debug)]
1071pub struct RpcLocalTxpoolStatusArgs {
1072    #[arg(
1073        id = "rpc-method",
1074        long = "rpc-method",
1075        default_value = "txpool_status",
1076        hide = true
1077    )]
1078    pub rpc_method: String,
1079}
1080
1081#[derive(Args, Debug)]
1082pub struct RpcLocalTxpoolInspectOneArgs {
1083    #[arg(
1084        id = "rpc-method",
1085        long = "rpc-method",
1086        default_value = "txpool_txWithPoolInfo",
1087        hide = true
1088    )]
1089    pub rpc_method: String,
1090    #[arg(
1091        id = "rpc-args",
1092        long = "rpc-args",
1093        hide = true,
1094        default_value = "hash",
1095        value_delimiter = ','
1096    )]
1097    pub rpc_args: Vec<String>,
1098    /// Block hash / Transaction hash
1099    #[arg(long, required = true, value_name = "HASH")]
1100    pub hash: String,
1101}
1102
1103#[derive(Args, Debug)]
1104pub struct RpcLocalTxpoolInspectArgs {
1105    #[arg(
1106        id = "rpc-method",
1107        long = "rpc-method",
1108        default_value = "debug_inspectTxPool",
1109        hide = true
1110    )]
1111    pub rpc_method: String,
1112    #[arg(
1113        id = "rpc-args",
1114        long = "rpc-args",
1115        hide = true,
1116        default_value = "address",
1117        value_delimiter = ','
1118    )]
1119    pub rpc_args: Vec<String>,
1120    /// Account address
1121    #[arg(long, value_name = "ADDRESS")]
1122    pub address: Option<String>,
1123}
1124
1125#[derive(Args, Debug)]
1126pub struct RpcLocalTxpoolContentArgs {
1127    #[arg(
1128        id = "rpc-method",
1129        long = "rpc-method",
1130        default_value = "debug_txPoolContent",
1131        hide = true
1132    )]
1133    pub rpc_method: String,
1134    #[arg(
1135        id = "rpc-args",
1136        long = "rpc-args",
1137        hide = true,
1138        default_value = "address",
1139        value_delimiter = ','
1140    )]
1141    pub rpc_args: Vec<String>,
1142    /// Account address
1143    #[arg(long, value_name = "ADDRESS")]
1144    pub address: Option<String>,
1145}
1146
1147#[derive(Args, Debug)]
1148pub struct RpcLocalTxpoolClearArgs {
1149    #[arg(
1150        id = "rpc-method",
1151        long = "rpc-method",
1152        default_value = "debug_clearTxPool",
1153        hide = true
1154    )]
1155    pub rpc_method: String,
1156}
1157
1158#[derive(Args, Debug)]
1159pub struct RpcLocalNetSubcommands {
1160    #[command(subcommand)]
1161    pub command: RpcLocalNetCommand,
1162}
1163
1164#[derive(Subcommand, Debug)]
1165pub enum RpcLocalNetCommand {
1166    /// Get the current throttling information
1167    Throttling(RpcLocalNetThrottlingArgs),
1168    /// Get node information by ID
1169    Node(RpcLocalNetNodeArgs),
1170    /// Disconnect a node
1171    Disconnect(RpcLocalNetDisconnectArgs),
1172    /// Get active session(s)
1173    Session(RpcLocalNetSessionArgs),
1174}
1175
1176#[derive(Args, Debug)]
1177pub struct RpcLocalNetThrottlingArgs {
1178    #[arg(
1179        id = "rpc-method",
1180        long = "rpc-method",
1181        default_value = "debug_getNetThrottling",
1182        hide = true
1183    )]
1184    pub rpc_method: String,
1185}
1186
1187#[derive(Args, Debug)]
1188pub struct RpcLocalNetNodeArgs {
1189    #[arg(
1190        id = "rpc-method",
1191        long = "rpc-method",
1192        default_value = "debug_getNetNode",
1193        hide = true
1194    )]
1195    pub rpc_method: String,
1196    #[arg(
1197        id = "rpc-args",
1198        long = "rpc-args",
1199        hide = true,
1200        default_value = "id",
1201        value_delimiter = ','
1202    )]
1203    pub rpc_args: Vec<String>,
1204    /// Node ID
1205    #[arg(long, required = true, value_name = "ID")]
1206    pub id: String,
1207}
1208
1209#[derive(ValueEnum, Clone, Debug)]
1210pub enum NodeDisconnectOperation {
1211    Failure,
1212    Demotion,
1213    Remove,
1214}
1215
1216#[derive(Args, Debug)]
1217pub struct RpcLocalNetDisconnectArgs {
1218    #[arg(
1219        id = "rpc-method",
1220        long = "rpc-method",
1221        default_value = "debug_disconnectNetNode",
1222        hide = true
1223    )]
1224    pub rpc_method: String,
1225    #[arg(
1226        id = "rpc-args",
1227        long = "rpc-args",
1228        hide = true,
1229        default_value = "id,operation",
1230        value_delimiter = ','
1231    )]
1232    pub rpc_args: Vec<String>,
1233    /// Node ID
1234    #[arg(long, required = true, value_name = "ID")]
1235    pub id: String,
1236    /// Operation to update node database
1237    #[arg(long, value_name = "OPERATION", value_enum)]
1238    pub operation: Option<NodeDisconnectOperation>,
1239}
1240
1241#[derive(Args, Debug)]
1242pub struct RpcLocalNetSessionArgs {
1243    #[arg(
1244        id = "rpc-method",
1245        long = "rpc-method",
1246        default_value = "debug_getNetSessions",
1247        hide = true
1248    )]
1249    pub rpc_method: String,
1250    #[arg(
1251        id = "rpc-args",
1252        long = "rpc-args",
1253        hide = true,
1254        default_value = "id",
1255        value_delimiter = ','
1256    )]
1257    pub rpc_args: Vec<String>,
1258    /// Node ID
1259    #[arg(long, value_name = "ID")]
1260    pub id: Option<String>,
1261}
1262
1263#[derive(Args, Debug)]
1264pub struct RpcLocalSyncPhaseArgs {
1265    #[arg(
1266        id = "rpc-method",
1267        long = "rpc-method",
1268        default_value = "debug_currentSyncPhase",
1269        hide = true
1270    )]
1271    pub rpc_method: String,
1272}
1273
1274#[derive(Args, Debug)]
1275pub struct RpcLocalConsensusGraphStateArgs {
1276    #[arg(
1277        id = "rpc-method",
1278        long = "rpc-method",
1279        default_value = "debug_consensusGraphState",
1280        hide = true
1281    )]
1282    pub rpc_method: String,
1283}
1284
1285#[derive(Args, Debug)]
1286pub struct RpcLocalTestSubcommands {
1287    #[command(subcommand)]
1288    pub command: RpcLocalTestCommand,
1289}
1290
1291#[derive(Subcommand, Debug)]
1292pub enum RpcLocalTestCommand {
1293    /// Get the total block count
1294    #[command(name = "block-count")]
1295    BlockCount(RpcLocalTestBlockCountArgs),
1296    /// Get the recent transaction good TPS
1297    Goodput(RpcLocalTestGoodputArgs),
1298    /// List "ALL" blocks in topological order
1299    Chain(RpcLocalTestChainArgs),
1300    /// Stop the conflux program
1301    Stop(RpcLocalTestStopArgs),
1302    /// Get the current status of Conflux
1303    Status(RpcLocalTestStatusArgs),
1304}
1305
1306#[derive(Args, Debug)]
1307pub struct RpcLocalTestBlockCountArgs {
1308    #[arg(
1309        id = "rpc-method",
1310        long = "rpc-method",
1311        default_value = "test_getBlockCount",
1312        hide = true
1313    )]
1314    pub rpc_method: String,
1315}
1316#[derive(Args, Debug)]
1317pub struct RpcLocalTestGoodputArgs {
1318    #[arg(
1319        id = "rpc-method",
1320        long = "rpc-method",
1321        default_value = "test_getGoodPut",
1322        hide = true
1323    )]
1324    pub rpc_method: String,
1325}
1326#[derive(Args, Debug)]
1327pub struct RpcLocalTestChainArgs {
1328    #[arg(
1329        id = "rpc-method",
1330        long = "rpc-method",
1331        default_value = "test_getChain",
1332        hide = true
1333    )]
1334    pub rpc_method: String,
1335}
1336#[derive(Args, Debug)]
1337pub struct RpcLocalTestStopArgs {
1338    #[arg(
1339        id = "rpc-method",
1340        long = "rpc-method",
1341        default_value = "test_stop",
1342        hide = true
1343    )]
1344    pub rpc_method: String,
1345}
1346#[derive(Args, Debug)]
1347pub struct RpcLocalTestStatusArgs {
1348    #[arg(
1349        id = "rpc-method",
1350        long = "rpc-method",
1351        default_value = "cfx_getStatus",
1352        hide = true
1353    )]
1354    pub rpc_method: String,
1355}
1356#[derive(Args, Debug)]
1357pub struct RpcLocalPosSubcommands {
1358    #[command(subcommand)]
1359    pub command: RpcLocalPosCommand,
1360}
1361
1362#[derive(Subcommand, Debug)]
1363pub enum RpcLocalPosCommand {
1364    /// Return the transaction data needed to register the PoS keys
1365    Register(RpcLocalPosRegisterArgs),
1366    /// Stop sending PoS election transactions.
1367    #[command(name = "stop_election")]
1368    StopElection(RpcLocalPosStopElectionArgs),
1369    /// Start PoS voting.
1370    #[command(name = "start_voting")]
1371    StartVoting(RpcLocalPosStartVotingArgs),
1372    /// Stop PoS voting.
1373    #[command(name = "stop_voting")]
1374    StopVoting(RpcLocalPosStopVotingArgs),
1375    /// Show if the node is voting.
1376    #[command(name = "voting_status")]
1377    VotingStatus(RpcLocalPosVotingStatusArgs),
1378}
1379
1380#[derive(Args, Debug)]
1381pub struct RpcLocalPosRegisterArgs {
1382    #[arg(
1383        id = "rpc-method",
1384        long = "rpc-method",
1385        default_value = "test_posRegister",
1386        hide = true
1387    )]
1388    pub rpc_method: String,
1389    #[arg(
1390        id = "rpc-args",
1391        long = "rpc-args",
1392        hide = true,
1393        default_value = "power:u64",
1394        value_delimiter = ','
1395    )]
1396    pub rpc_args: Vec<String>,
1397    /// The voting power to register (one voting power is 100 staked CFX)
1398    #[arg(long, required = true, value_name = "POWER")]
1399    pub power: u64,
1400}
1401
1402#[derive(Args, Debug)]
1403pub struct RpcLocalPosStopElectionArgs {
1404    #[arg(
1405        id = "rpc-method",
1406        long = "rpc-method",
1407        default_value = "test_posStopElection",
1408        hide = true
1409    )]
1410    pub rpc_method: String,
1411}
1412
1413#[derive(Args, Debug)]
1414pub struct RpcLocalPosStartVotingArgs {
1415    #[arg(
1416        id = "rpc-method",
1417        long = "rpc-method",
1418        default_value = "test_posStartVoting",
1419        hide = true
1420    )]
1421    pub rpc_method: String,
1422    #[arg(
1423        id = "rpc-args",
1424        long = "rpc-args",
1425        hide = true,
1426        default_value = "initialize:bool",
1427        value_delimiter = ','
1428    )]
1429    pub rpc_args: Vec<String>,
1430    /// set this means the node uses its local safety data instead of a saved
1431    /// data file from another primary node
1432    #[arg(long)]
1433    pub initialize: bool,
1434}
1435
1436#[derive(Args, Debug)]
1437pub struct RpcLocalPosStopVotingArgs {
1438    #[arg(
1439        id = "rpc-method",
1440        long = "rpc-method",
1441        default_value = "test_posStopVoting",
1442        hide = true
1443    )]
1444    pub rpc_method: String,
1445}
1446#[derive(Args, Debug)]
1447pub struct RpcLocalPosVotingStatusArgs {
1448    #[arg(
1449        id = "rpc-method",
1450        long = "rpc-method",
1451        default_value = "test_posVotingStatus",
1452        hide = true
1453    )]
1454    pub rpc_method: String,
1455}