diff --git a/canister/src/api/metrics.rs b/canister/src/api/metrics.rs index 164abd86..a7288714 100644 --- a/canister/src/api/metrics.rs +++ b/canister/src/api/metrics.rs @@ -169,6 +169,36 @@ fn encode_metrics(w: &mut MetricsEncoder>) -> std::io::Result<()> { .value(&[("flag", "enabled")], enabled)? .value(&[("flag", "disabled")], disabled)?; + if let Some(stats) = &state.syncing_state.get_successors_request_stats { + encode_labeled_gauge( + w, + "get_successors_tx_count", + "The number of get_successors requests.", + &stats.get_count_metrics(), + )?; + } + + if let Some(stats) = &state.syncing_state.get_successors_response_stats { + encode_labeled_gauge( + w, + "get_successors_rx_count", + "The number of get_successors responses.", + &stats.get_count_metrics(), + )?; + encode_labeled_gauge( + w, + "get_successors_rx_block_count", + "The number of blocks in get_successors responses.", + &stats.get_block_count_metrics(), + )?; + encode_labeled_gauge( + w, + "get_successors_rx_block_size", + "The total size of the blocks in get_successors responses.", + &stats.get_block_size_metrics(), + )?; + } + Ok(()) }) } diff --git a/canister/src/heartbeat.rs b/canister/src/heartbeat.rs index d9d8c4de..18808ede 100644 --- a/canister/src/heartbeat.rs +++ b/canister/src/heartbeat.rs @@ -1,7 +1,7 @@ use crate::{ api::get_current_fee_percentiles_impl, runtime::{call_get_successors, cycles_burn, print}, - state::{self, ResponseToProcess}, + state::{self, ResponseToProcess, SuccessorsRequestStats, SuccessorsResponseStats}, types::{ GetSuccessorsCompleteResponse, GetSuccessorsRequest, GetSuccessorsRequestInitial, GetSuccessorsResponse, @@ -63,6 +63,18 @@ async fn maybe_fetch_blocks() -> bool { } }; + with_state_mut(|s| { + let tx_stats = s + .syncing_state + .get_successors_request_stats + .get_or_insert_with(SuccessorsRequestStats::default); + tx_stats.total_count += 1; + match request { + GetSuccessorsRequest::Initial(_) => tx_stats.initial_count += 1, + GetSuccessorsRequest::FollowUp(_) => tx_stats.follow_up_count += 1, + } + }); + print(&format!("Sending request: {:?}", request)); let response: Result<(GetSuccessorsResponse,), _> = @@ -80,6 +92,10 @@ async fn maybe_fetch_blocks() -> bool { } }; + s.syncing_state + .get_successors_response_stats + .get_or_insert_with(SuccessorsResponseStats::default); + match response { GetSuccessorsResponse::Complete(response) => { // Received complete response. @@ -93,6 +109,14 @@ async fn maybe_fetch_blocks() -> bool { "Received complete response: {} blocks, total {} bytes.", count, bytes, )); + if let Some(rx_stats) = s.syncing_state.get_successors_response_stats.as_mut() { + rx_stats.complete_count += 1; + rx_stats.complete_block_count += count; + rx_stats.complete_block_size += bytes; + rx_stats.total_count += 1; + rx_stats.total_block_count += count; + rx_stats.total_block_size += bytes; + } s.syncing_state.response_to_process = Some(ResponseToProcess::Complete(response)); } GetSuccessorsResponse::Partial(partial_response) => { @@ -107,6 +131,14 @@ async fn maybe_fetch_blocks() -> bool { "Received partial response: {} bytes, {} follow-ups remaining.", bytes, remaining, )); + if let Some(rx_stats) = s.syncing_state.get_successors_response_stats.as_mut() { + rx_stats.partial_count += 1; + rx_stats.partial_block_count += 1; + rx_stats.partial_block_size += bytes; + rx_stats.total_count += 1; + rx_stats.total_block_count += 1; + rx_stats.total_block_size += bytes; + } s.syncing_state.response_to_process = Some(ResponseToProcess::Partial(partial_response, 0)); } @@ -116,6 +148,14 @@ async fn maybe_fetch_blocks() -> bool { // a partial response to process. let bytes = block_bytes.len() as u64; print(&format!("Received follow-up response: {} bytes.", bytes)); + if let Some(rx_stats) = s.syncing_state.get_successors_response_stats.as_mut() { + rx_stats.follow_up_count += 1; + rx_stats.follow_up_block_count += 1; + rx_stats.follow_up_block_size += bytes; + rx_stats.total_count += 1; + rx_stats.total_block_count += 1; + rx_stats.total_block_size += bytes; + } let (mut partial_response, mut follow_up_index) = match s.syncing_state.response_to_process.take() { Some(ResponseToProcess::Partial(res, pages)) => (res, pages), other => unreachable!("Cannot receive follow-up response without a previous partial response. Previous response found: {:?}", other) diff --git a/canister/src/state.rs b/canister/src/state.rs index be72d3a0..30ef51aa 100644 --- a/canister/src/state.rs +++ b/canister/src/state.rs @@ -325,6 +325,14 @@ pub struct SyncingState { /// The number of errors occurred when inserting a block. pub num_insert_block_errors: u64, + + /// Stats about the request sent to GetSuccessors. + #[serde(default)] // Ensures backward compatibility during deserialization + pub get_successors_request_stats: Option, + + /// Stats about the responses received from GetSuccessors. + #[serde(default)] // Ensures backward compatibility during deserialization + pub get_successors_response_stats: Option, } impl Default for SyncingState { @@ -336,10 +344,77 @@ impl Default for SyncingState { num_get_successors_rejects: 0, num_block_deserialize_errors: 0, num_insert_block_errors: 0, + get_successors_request_stats: None, + get_successors_response_stats: None, } } } +#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Default)] +pub struct SuccessorsRequestStats { + pub total_count: u64, + pub initial_count: u64, + pub follow_up_count: u64, +} + +impl SuccessorsRequestStats { + pub fn get_count_metrics(&self) -> Vec<((&str, &str), u64)> { + vec![ + (("type", "total"), self.total_count), + (("type", "initial"), self.initial_count), + (("type", "follow_up"), self.follow_up_count), + ] + } +} + +#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Default)] +pub struct SuccessorsResponseStats { + pub total_count: u64, + pub total_block_count: u64, + pub total_block_size: u64, + + pub complete_count: u64, + pub complete_block_count: u64, + pub complete_block_size: u64, + + pub partial_count: u64, + pub partial_block_count: u64, + pub partial_block_size: u64, + + pub follow_up_count: u64, + pub follow_up_block_count: u64, + pub follow_up_block_size: u64, +} + +impl SuccessorsResponseStats { + pub fn get_count_metrics(&self) -> Vec<((&str, &str), u64)> { + vec![ + (("type", "total"), self.total_count), + (("type", "complete"), self.complete_count), + (("type", "partial"), self.partial_count), + (("type", "follow_up"), self.follow_up_count), + ] + } + + pub fn get_block_count_metrics(&self) -> Vec<((&str, &str), u64)> { + vec![ + (("type", "total"), self.total_block_count), + (("type", "complete"), self.complete_block_count), + (("type", "partial"), self.partial_block_count), + (("type", "follow_up"), self.follow_up_block_count), + ] + } + + pub fn get_block_size_metrics(&self) -> Vec<((&str, &str), u64)> { + vec![ + (("type", "total"), self.total_block_size), + (("type", "complete"), self.complete_block_size), + (("type", "partial"), self.partial_block_size), + (("type", "follow_up"), self.follow_up_block_size), + ] + } +} + /// Cache for storing last calculated fee percentiles /// /// Stores last tip block hash and fee percentiles associated with it. diff --git a/canister/src/unstable_blocks.rs b/canister/src/unstable_blocks.rs index b5c15c1c..58649053 100644 --- a/canister/src/unstable_blocks.rs +++ b/canister/src/unstable_blocks.rs @@ -17,7 +17,7 @@ use self::next_block_headers::NextBlockHeaders; // The maximum number of blocks that a chain on testnet can exceed other chains before its // anchor block is marked as stable. -const TESTNET_CHAIN_MAX_DEPTH: u128 = 1000; +const TESTNET_CHAIN_MAX_DEPTH: u128 = 200; // TODO: DO NOT SUBMIT! this is only for testing. /// A data structure for maintaining all unstable blocks. /// diff --git a/dfx.json b/dfx.json index bf31daa7..1155066d 100644 --- a/dfx.json +++ b/dfx.json @@ -1,7 +1,13 @@ { "dfx": "0.21.0", "canisters": { - "bitcoin": { + "bitcoin_t": { + "type": "custom", + "candid": "./canister/candid.did", + "wasm": "target/wasm32-unknown-unknown/release/ic-btc-canister.wasm.gz", + "build": "./scripts/build-canister.sh ic-btc-canister" + }, + "bitcoin_m": { "type": "custom", "candid": "./canister/candid.did", "wasm": "target/wasm32-unknown-unknown/release/ic-btc-canister.wasm.gz", @@ -79,10 +85,10 @@ }, "testnet": { "providers": [ - "http://[2a00:fb01:400:42:5000:aaff:fea4:ae46]:8080" + "http://[2600:c00:2:100:505e:86ff:fed7:a12]:8080" ], "type": "persistent" } }, "version": 1 -} +} \ No newline at end of file diff --git a/poll_logs.sh b/poll_logs.sh new file mode 100755 index 00000000..8e3b6a00 --- /dev/null +++ b/poll_logs.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +CANISTER_ID="g4xu7-jiaaa-aaaan-aaaaq-cai" + +# Function to fetch logs and filter out new lines +fetch_and_filter_logs() { + # Fetch logs + new_logs=$(dfx canister logs --network testnet $CANISTER_ID) + + # Compare with previous logs to find new ones + while IFS= read -r line; do + if [[ ! "${previous_logs[*]}" =~ "$line" ]]; then + echo "$line" + fi + done <<< "$new_logs" + + # Update previous logs + previous_logs=("$new_logs") +} + +# Initial fetch and filter +fetch_and_filter_logs + +# Infinite loop to continuously fetch and filter logs +while true; do + fetch_and_filter_logs + sleep 0.1 +done