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 metrics = KeyValueStoreMetrics::new_for_tests();
48 let http_kv = Arc::new(HttpKVStore::new(&options.base_url, 100, metrics).unwrap());
49 let kv =
50 TransactionKeyValueStore::new("http_kv", KeyValueStoreMetrics::new_for_tests(), http_kv);
51
52 let seqs: Vec<_> = options
53 .seq
54 .into_iter()
55 .map(|s| {
56 CheckpointSequenceNumber::from_str(&s).expect("invalid checkpoint sequence number")
57 })
58 .collect();
59
60 match options.type_.as_str() {
62 "tx" | "fx" => {
63 let digests: Vec<_> = options
64 .digest
65 .into_iter()
66 .map(|digest| {
67 TransactionDigest::from_str(&digest).expect("invalid transaction digest")
68 })
69 .collect();
70
71 if options.type_ == "tx" {
72 let tx = kv.multi_get_tx(&digests).await.unwrap();
73 for (digest, tx) in digests.iter().zip(tx.iter()) {
74 println!("fetched tx: {digest:?} {tx:?}");
75 }
76 } else {
77 let fx = kv.multi_get_fx_by_tx_digest(&digests).await.unwrap();
78 for (digest, fx) in digests.iter().zip(fx.iter()) {
79 println!("fetched fx: {digest:?} {fx:?}");
80 }
81 }
82 }
83
84 "ckpt_contents" => {
85 let ckpts = kv.multi_get_checkpoints(&[], &seqs, &[]).await.unwrap();
86
87 for (seq, ckpt) in seqs.iter().zip(ckpts.1.iter()) {
88 ckpt.as_ref().map(|c| c.digest());
90 println!("fetched ckpt contents: {seq:?} {ckpt:?}");
91 }
92 }
93
94 "ckpt_summary" => {
95 let digests: Vec<_> = options
96 .digest
97 .into_iter()
98 .map(|s| CheckpointDigest::from_str(&s).expect("invalid checkpoint digest"))
99 .collect();
100
101 let ckpts = kv
102 .multi_get_checkpoints(&seqs, &[], &digests)
103 .await
104 .unwrap();
105
106 for (seq, ckpt) in seqs.iter().zip(ckpts.0.iter()) {
107 ckpt.as_ref().map(|c| c.digest());
109 println!("fetched ckpt summary: {seq:?} {ckpt:?}");
110 }
111 for (digest, ckpt) in digests.iter().zip(ckpts.2.iter()) {
112 ckpt.as_ref().map(|c| c.digest());
114 println!("fetched ckpt summary: {digest:?} {ckpt:?}");
115 }
116 }
117
118 "ob" => {
119 let object_id = ObjectID::from_str(&options.digest[0]).expect("invalid object id");
120 let object = kv.get_object(object_id, seqs[0].into()).await.unwrap();
121 println!("fetched object {object:?}");
122 }
123
124 _ => {
125 println!(
126 "Invalid key type: {}. Must be one of 'tx', 'fx', or 'ev'.",
127 options.type_
128 );
129 std::process::exit(1);
130 }
131 }
132}