Skip to content

Commit 0f49ddf

Browse files
refactor: improve status output for v2 trees (#1879)
1 parent 2371981 commit 0f49ddf

File tree

4 files changed

+273
-130
lines changed

4 files changed

+273
-130
lines changed

forester/src/forester_status.rs

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -179,22 +179,28 @@ pub async fn fetch_forester_status(args: &StatusArgs) -> crate::Result<()> {
179179
fetch_active_tree: false,
180180
})
181181
.await?;
182-
let trees = fetch_trees(&rpc).await?;
182+
let trees = fetch_trees(&rpc)
183+
.await?
184+
.iter()
185+
.sorted_by_key(|t| t.merkle_tree.to_string())
186+
.cloned()
187+
.collect::<Vec<_>>();
188+
183189
if trees.is_empty() {
184190
warn!("No trees found. Exiting.");
185191
}
186-
run_queue_info(config.clone(), trees.clone(), TreeType::StateV1).await?;
187-
run_queue_info(config.clone(), trees.clone(), TreeType::AddressV1).await?;
192+
run_queue_info(config.clone(), &trees, TreeType::StateV1).await?;
193+
run_queue_info(config.clone(), &trees, TreeType::AddressV1).await?;
188194

189-
run_queue_info(config.clone(), trees.clone(), TreeType::StateV2).await?;
190-
run_queue_info(config.clone(), trees.clone(), TreeType::AddressV2).await?;
195+
run_queue_info(config.clone(), &trees, TreeType::StateV2).await?;
196+
run_queue_info(config.clone(), &trees, TreeType::AddressV2).await?;
191197

192198
for tree in &trees {
193-
let tree_type = format!("[{}]", tree.tree_type);
199+
let tree_type = format!("{}", tree.tree_type);
194200
let tree_info = get_tree_fullness(&mut rpc, tree.merkle_tree, tree.tree_type).await?;
195201
let fullness_percentage = tree_info.fullness * 100.0;
196202
println!(
197-
"{} Tree {}: Fullness: {:.4}% | Next Index: {} | Threshold: {}",
203+
"{} {}: Fullness: {:.4}% | Next Index: {} | Threshold: {}",
198204
tree_type,
199205
&tree.merkle_tree,
200206
format!("{:.2}%", fullness_percentage),
@@ -323,9 +329,7 @@ fn print_current_forester_assignments(
323329
);
324330

325331
println!("Queue processors for the current light slot:");
326-
println!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
327-
println!("│ Tree Type │ Tree Address │ Forester │");
328-
println!("┼───────────┼──────────────────────────────────────────┼──────────────────────────────────────────┤");
332+
println!("Tree Type\t\tTree Address\tForester");
329333

330334
for tree in trees {
331335
let eligible_forester_slot_index = match ForesterEpochPda::get_eligible_forester_index(
@@ -337,7 +341,7 @@ fn print_current_forester_assignments(
337341
Ok(idx) => idx,
338342
Err(e) => {
339343
println!(
340-
"│ {:9} │ {} │ ERROR: {:?}",
344+
"{:12}\t\t{}\tERROR: {:?}",
341345
tree.tree_type, tree.merkle_tree, e
342346
);
343347
continue;
@@ -350,17 +354,16 @@ fn print_current_forester_assignments(
350354

351355
if let Some(forester_pda) = assigned_forester {
352356
println!(
353-
"│ {:9} │ {} │ {} │",
357+
"{:12}\t\t{}\t{}",
354358
tree.tree_type, tree.merkle_tree, forester_pda.authority
355359
);
356360
} else {
357361
println!(
358-
"│ {:9} │ {} │ UNASSIGNED (Eligible Index: {})",
362+
"{:12}\t\t{}\tUNASSIGNED (Eligible Index: {})",
359363
tree.tree_type, tree.merkle_tree, eligible_forester_slot_index
360364
);
361365
}
362366
}
363-
println!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
364367
} else {
365368
println!(
366369
"ERROR: Could not find EpochPda for active epoch {}. Cannot determine forester assignments.",

forester/src/lib.rs

Lines changed: 77 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ pub use config::{ForesterConfig, ForesterEpochInfo};
2626
use forester_utils::{
2727
forester_epoch::TreeAccounts, rate_limiter::RateLimiter, rpc_pool::SolanaRpcPoolBuilder,
2828
};
29+
use itertools::Itertools;
2930
use light_client::rpc::{LightClient, LightClientConfig, Rpc};
3031
use light_compressed_account::TreeType;
3132
use solana_sdk::commitment_config::CommitmentConfig;
@@ -37,15 +38,16 @@ use crate::{
3738
metrics::QUEUE_LENGTH,
3839
processor::tx_cache::ProcessedHashCache,
3940
queue_helpers::{
40-
fetch_address_v2_queue_length, fetch_queue_item_data, fetch_state_v2_queue_length,
41+
fetch_queue_item_data, print_address_v2_queue_info, print_state_v2_input_queue_info,
42+
print_state_v2_output_queue_info,
4143
},
4244
slot_tracker::SlotTracker,
4345
utils::get_protocol_config,
4446
};
4547

4648
pub async fn run_queue_info(
4749
config: Arc<ForesterConfig>,
48-
trees: Vec<TreeAccounts>,
50+
trees: &[TreeAccounts],
4951
queue_type: TreeType,
5052
) -> Result<()> {
5153
let mut rpc = LightClient::new(LightClientConfig {
@@ -60,49 +62,87 @@ pub async fn run_queue_info(
6062
let trees: Vec<_> = trees
6163
.iter()
6264
.filter(|t| t.tree_type == queue_type)
65+
.sorted_by_key(|t| t.merkle_tree.to_string())
6366
.cloned()
6467
.collect();
6568

6669
for tree_data in trees {
67-
let queue_length = match tree_data.tree_type {
68-
TreeType::StateV1 => fetch_queue_item_data(
69-
&mut rpc,
70-
&tree_data.queue,
71-
0,
72-
STATE_NULLIFIER_QUEUE_VALUES,
73-
STATE_NULLIFIER_QUEUE_VALUES,
74-
)
75-
.await?
76-
.len(),
77-
TreeType::AddressV1 => fetch_queue_item_data(
78-
&mut rpc,
79-
&tree_data.queue,
80-
0,
81-
ADDRESS_QUEUE_VALUES,
82-
ADDRESS_QUEUE_VALUES,
83-
)
84-
.await?
85-
.len(),
86-
TreeType::StateV2 => fetch_state_v2_queue_length(&mut rpc, &tree_data.queue).await?,
87-
TreeType::AddressV2 => {
88-
fetch_address_v2_queue_length(&mut rpc, &tree_data.merkle_tree).await?
70+
match tree_data.tree_type {
71+
TreeType::StateV1 => {
72+
let queue_length = fetch_queue_item_data(
73+
&mut rpc,
74+
&tree_data.queue,
75+
0,
76+
STATE_NULLIFIER_QUEUE_VALUES,
77+
STATE_NULLIFIER_QUEUE_VALUES,
78+
)
79+
.await?
80+
.len();
81+
QUEUE_LENGTH
82+
.with_label_values(&[
83+
&*queue_type.to_string(),
84+
&tree_data.merkle_tree.to_string(),
85+
])
86+
.set(queue_length as i64);
87+
88+
println!(
89+
"{:?} queue {} length: {}",
90+
queue_type, tree_data.queue, queue_length
91+
);
8992
}
90-
};
93+
TreeType::AddressV1 => {
94+
let queue_length = fetch_queue_item_data(
95+
&mut rpc,
96+
&tree_data.queue,
97+
0,
98+
ADDRESS_QUEUE_VALUES,
99+
ADDRESS_QUEUE_VALUES,
100+
)
101+
.await?
102+
.len();
103+
QUEUE_LENGTH
104+
.with_label_values(&[
105+
&*queue_type.to_string(),
106+
&tree_data.merkle_tree.to_string(),
107+
])
108+
.set(queue_length as i64);
109+
110+
println!(
111+
"{:?} queue {} length: {}",
112+
queue_type, tree_data.queue, queue_length
113+
);
114+
}
115+
TreeType::StateV2 => {
116+
println!("\n=== StateV2 {} ===", tree_data.merkle_tree);
91117

92-
QUEUE_LENGTH
93-
.with_label_values(&[&*queue_type.to_string(), &tree_data.merkle_tree.to_string()])
94-
.set(queue_length as i64);
118+
println!("\n1. APPEND OPERATIONS:");
119+
let append_unprocessed =
120+
print_state_v2_output_queue_info(&mut rpc, &tree_data.queue).await?;
95121

96-
let queue_identifier = if tree_data.tree_type == TreeType::AddressV2 {
97-
tree_data.merkle_tree.to_string()
98-
} else {
99-
tree_data.queue.to_string()
100-
};
122+
println!("\n2. NULLIFY OPERATIONS:");
123+
let nullify_unprocessed =
124+
print_state_v2_input_queue_info(&mut rpc, &tree_data.merkle_tree).await?;
125+
126+
println!("===========================================\n");
101127

102-
println!(
103-
"{:?} queue {} length: {}",
104-
queue_type, queue_identifier, queue_length
105-
);
128+
QUEUE_LENGTH
129+
.with_label_values(&["StateV2.Append", &tree_data.queue.to_string()])
130+
.set(append_unprocessed as i64);
131+
132+
QUEUE_LENGTH
133+
.with_label_values(&["StateV2.Nullify", &tree_data.merkle_tree.to_string()])
134+
.set(nullify_unprocessed as i64);
135+
}
136+
TreeType::AddressV2 => {
137+
println!("\n=== AddressV2 {} ===", tree_data.merkle_tree);
138+
let queue_length =
139+
print_address_v2_queue_info(&mut rpc, &tree_data.merkle_tree).await?;
140+
println!("===========================================\n");
141+
QUEUE_LENGTH
142+
.with_label_values(&["AddressV2", &tree_data.merkle_tree.to_string()])
143+
.set(queue_length as i64);
144+
}
145+
};
106146
}
107147
Ok(())
108148
}

0 commit comments

Comments
 (0)