http_kv_tool/
http_kv_tool.rs1use std::{str::FromStr, sync::Arc};
6
7use clap::*;
8use iota_storage::{
9 http_key_value_store::*, key_value_store::TransactionKeyValueStore,
10 key_value_store_metrics::KeyValueStoreMetrics,
11};
12use iota_types::{
13 base_types::ObjectID,
14 digests::{CheckpointDigest, TransactionDigest},
15 messages_checkpoint::CheckpointSequenceNumber,
16};
17
18#[derive(Parser)]
23struct Options {
24 #[arg(short, long)]
25 base_url: String,
26
27 #[arg(short, long)]
28 digest: Vec<String>,
29
30 #[arg(short, long)]
31 seq: Vec<String>,
32
33 #[arg(short, long, default_value = "tx")]
36 type_: String,
37}
38
39#[tokio::main]
40async fn main() {
41 let _guard = telemetry_subscribers::TelemetryConfig::new()
42 .with_env()
43 .init();
44
45 let options = Options::parse();
46
47 let http_kv = Arc::new(HttpKVStore::new(&options.base_url).unwrap());
48 let kv =
49 TransactionKeyValueStore::new("http_kv", KeyValueStoreMetrics::new_for_tests(), http_kv);
50
51 let seqs: Vec<_> = options
52 .seq
53 .into_iter()
54 .map(|s| {
55 CheckpointSequenceNumber::from_str(&s).expect("invalid checkpoint sequence number")
56 })
57 .collect();
58
59 match options.type_.as_str() {
61 "tx" | "fx" => {
62 let digests: Vec<_> = options
63 .digest
64 .into_iter()
65 .map(|digest| {
66 TransactionDigest::from_str(&digest).expect("invalid transaction digest")
67 })
68 .collect();
69
70 if options.type_ == "tx" {
71 let tx = kv.multi_get_tx(&digests).await.unwrap();
72 for (digest, tx) in digests.iter().zip(tx.iter()) {
73 println!("fetched tx: {:?} {:?}", digest, tx);
74 }
75 } else {
76 let fx = kv.multi_get_fx_by_tx_digest(&digests).await.unwrap();
77 for (digest, fx) in digests.iter().zip(fx.iter()) {
78 println!("fetched fx: {:?} {:?}", digest, fx);
79 }
80 }
81 }
82
83 "ckpt_contents" => {
84 let ckpts = kv.multi_get_checkpoints(&[], &seqs, &[]).await.unwrap();
85
86 for (seq, ckpt) in seqs.iter().zip(ckpts.1.iter()) {
87 ckpt.as_ref().map(|c| c.digest());
89 println!("fetched ckpt contents: {:?} {:?}", seq, ckpt);
90 }
91 }
92
93 "ckpt_summary" => {
94 let digests: Vec<_> = options
95 .digest
96 .into_iter()
97 .map(|s| CheckpointDigest::from_str(&s).expect("invalid checkpoint digest"))
98 .collect();
99
100 let ckpts = kv
101 .multi_get_checkpoints(&seqs, &[], &digests)
102 .await
103 .unwrap();
104
105 for (seq, ckpt) in seqs.iter().zip(ckpts.0.iter()) {
106 ckpt.as_ref().map(|c| c.digest());
108 println!("fetched ckpt summary: {:?} {:?}", seq, ckpt);
109 }
110 for (digest, ckpt) in digests.iter().zip(ckpts.2.iter()) {
111 ckpt.as_ref().map(|c| c.digest());
113 println!("fetched ckpt summary: {:?} {:?}", digest, ckpt);
114 }
115 }
116
117 "ob" => {
118 let object_id = ObjectID::from_str(&options.digest[0]).expect("invalid object id");
119 let object = kv.get_object(object_id, seqs[0].into()).await.unwrap();
120 println!("fetched object {:?}", object);
121 }
122
123 _ => {
124 println!(
125 "Invalid key type: {}. Must be one of 'tx', 'fx', or 'ev'.",
126 options.type_
127 );
128 std::process::exit(1);
129 }
130 }
131}