error handling fixes
This commit is contained in:
parent
88b043cf41
commit
7cd421e142
|
|
@ -67,8 +67,47 @@ async fn main() {
|
|||
};
|
||||
let receiver = match normalize_short_address_input(&receiver_input) {
|
||||
Ok(address) => address,
|
||||
Err(_) => {
|
||||
println!("reciver wallet is not valid");
|
||||
Err(err) => {
|
||||
let trimmed_receiver = receiver_input.trim();
|
||||
let escaped_receiver = receiver_input
|
||||
.chars()
|
||||
.flat_map(char::escape_default)
|
||||
.collect::<String>();
|
||||
let escaped_trimmed_receiver = trimmed_receiver
|
||||
.chars()
|
||||
.flat_map(char::escape_default)
|
||||
.collect::<String>();
|
||||
let dot_count = trimmed_receiver.matches('.').count();
|
||||
let (payload_chars, payload_bytes, suffix, payload_is_hex, payload_is_ascii) =
|
||||
match trimmed_receiver.rsplit_once('.') {
|
||||
Some((payload, suffix)) => (
|
||||
payload.chars().count(),
|
||||
payload.len(),
|
||||
suffix,
|
||||
payload.chars().all(|ch| ch.is_ascii_hexdigit()),
|
||||
payload.is_ascii(),
|
||||
),
|
||||
None => (0, 0, "<missing>", false, trimmed_receiver.is_ascii()),
|
||||
};
|
||||
|
||||
println!("receiver wallet is not valid: {err}");
|
||||
println!(
|
||||
"receiver diagnostics: raw_chars={} raw_bytes={} trimmed_chars={} trimmed_bytes={} dot_count={} suffix={} payload_chars={} payload_bytes={} payload_hex={} payload_ascii={} raw_ascii={} raw_control_chars={}",
|
||||
receiver_input.chars().count(),
|
||||
receiver_input.len(),
|
||||
trimmed_receiver.chars().count(),
|
||||
trimmed_receiver.len(),
|
||||
dot_count,
|
||||
suffix,
|
||||
payload_chars,
|
||||
payload_bytes,
|
||||
payload_is_hex,
|
||||
payload_is_ascii,
|
||||
receiver_input.is_ascii(),
|
||||
receiver_input.chars().any(char::is_control)
|
||||
);
|
||||
println!("receiver escaped raw: {escaped_receiver}");
|
||||
println!("receiver escaped trimmed: {escaped_trimmed_receiver}");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use crate::common::binary_conversions::binary_to_string;
|
||||
use crate::log::{error, info, warn};
|
||||
use crate::miner::flag::begin_reorg_lock;
|
||||
use crate::miner::flag::{begin_reorg_lock, is_syncing_mode};
|
||||
use crate::orphans::structs::UndoTransactions;
|
||||
use crate::orphans::undo_block_transactions::undo_transactions;
|
||||
use crate::records::memory::connections::live_miner_peer_streams;
|
||||
|
|
@ -35,22 +35,24 @@ fn required_snapshot_votes(total_voters: usize) -> usize {
|
|||
(total_voters * 2).div_ceil(3).max(2)
|
||||
}
|
||||
|
||||
fn peer_is_syncing_vote_error(error: &str) -> bool {
|
||||
error.trim() == "error: Node is syncing"
|
||||
}
|
||||
|
||||
async fn snapshot_has_peer_quorum(
|
||||
snapshot_height: u32,
|
||||
local_hash: &str,
|
||||
map: Arc<Mutex<Command>>,
|
||||
) -> bool {
|
||||
let peers = live_miner_peer_streams().await;
|
||||
let total_voters = peers.len() + 1;
|
||||
|
||||
if total_voters < 2 {
|
||||
if peers.is_empty() {
|
||||
warn!(
|
||||
"[snapshot] not advancing snapshot at height {snapshot_height}: no connected miner peers"
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
let required_votes = required_snapshot_votes(total_voters);
|
||||
let mut handles = Vec::with_capacity(peers.len());
|
||||
|
||||
for (connections_key, stream) in peers {
|
||||
|
|
@ -68,10 +70,12 @@ async fn snapshot_has_peer_quorum(
|
|||
}
|
||||
|
||||
let mut matching_votes = 1usize;
|
||||
let mut eligible_peer_votes = 0usize;
|
||||
|
||||
for handle in handles {
|
||||
match handle.await {
|
||||
Ok((connections_key, Ok(peer_hash))) => {
|
||||
eligible_peer_votes += 1;
|
||||
if peer_hash == local_hash {
|
||||
matching_votes += 1;
|
||||
} else {
|
||||
|
|
@ -81,9 +85,15 @@ async fn snapshot_has_peer_quorum(
|
|||
}
|
||||
}
|
||||
Ok((connections_key, Err(err))) => {
|
||||
warn!(
|
||||
"[snapshot] peer vote failed: height={snapshot_height} peer={connections_key} err={err}"
|
||||
);
|
||||
if peer_is_syncing_vote_error(&err) {
|
||||
info!(
|
||||
"[snapshot] skipping syncing peer vote: height={snapshot_height} peer={connections_key}"
|
||||
);
|
||||
} else {
|
||||
warn!(
|
||||
"[snapshot] peer vote failed: height={snapshot_height} peer={connections_key} err={err}"
|
||||
);
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
warn!("[snapshot] peer vote task failed at height {snapshot_height}: {err}");
|
||||
|
|
@ -91,6 +101,15 @@ async fn snapshot_has_peer_quorum(
|
|||
}
|
||||
}
|
||||
|
||||
let total_voters = eligible_peer_votes + 1;
|
||||
if total_voters < 2 {
|
||||
warn!(
|
||||
"[snapshot] not advancing snapshot at height {snapshot_height}: no eligible non-syncing miner peers"
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
let required_votes = required_snapshot_votes(total_voters);
|
||||
if matching_votes >= required_votes {
|
||||
info!(
|
||||
"[snapshot] consensus reached: height={snapshot_height} hash={local_hash} votes={matching_votes}/{total_voters} required={required_votes}"
|
||||
|
|
@ -117,6 +136,10 @@ pub async fn update_snapshot(
|
|||
current_height: u32,
|
||||
map: Arc<Mutex<Command>>,
|
||||
) -> Result<(), String> {
|
||||
if is_syncing_mode() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Genesis is always a valid snapshot, then later snapshots lag the tip
|
||||
// so normal orphan correction still has room to operate.
|
||||
let snapshot_height = if current_height == 0 {
|
||||
|
|
|
|||
|
|
@ -70,9 +70,7 @@ pub async fn load_block(block_number: u32) -> Result<Block, String> {
|
|||
let binary_data = match fs::read(&file_name) {
|
||||
Ok(data) => data,
|
||||
Err(err) => {
|
||||
println!("{}", &file_name);
|
||||
eprintln!("Error reading file load_block: {err:?}");
|
||||
return Err(format!("Unable to read binary file: {err:?}"));
|
||||
return Err(format!("Unable to read block {block_number}: {err:?}"));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,9 @@ pub async fn load_block_header(block_number: u32) -> Result<VrfBlock, String> {
|
|||
let file = match File::open(&file_name).await {
|
||||
Ok(file) => file,
|
||||
Err(err) => {
|
||||
return Err(format!("Error opening file {}: {:?}", &file_name, err));
|
||||
return Err(format!(
|
||||
"Error opening block file for height {block_number}: {err:?}"
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -37,8 +39,7 @@ pub async fn load_block_header(block_number: u32) -> Result<VrfBlock, String> {
|
|||
.await
|
||||
{
|
||||
return Err(format!(
|
||||
"Error reading file load_block_head {}: {:?}",
|
||||
&file_name, err
|
||||
"Error reading block header for height {block_number}: {err:?}"
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,10 +51,8 @@ pub async fn request_block(db: &Db, hash: &str) -> RpcResponse {
|
|||
match load_block(block_number).await {
|
||||
Ok(block) => match block.to_bytes().await {
|
||||
Ok(block_bytes) => RpcResponse::Binary(block_bytes),
|
||||
Err(err) => RpcResponse::Binary(
|
||||
format!("error: Failed to convert block to bytes: {err}").into_bytes(),
|
||||
),
|
||||
Err(_) => RpcResponse::Binary(b"error: Unable to serialize block".to_vec()),
|
||||
},
|
||||
Err(err) => RpcResponse::Binary(format!("error: Failed to load block: {err}").into_bytes()),
|
||||
Err(_) => RpcResponse::Binary(b"error: Block not found".to_vec()),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,15 +9,9 @@ pub async fn request_block(height: u32) -> RpcResponse {
|
|||
let block_bytes = block.to_bytes().await;
|
||||
match block_bytes {
|
||||
Ok(result) => RpcResponse::Binary(result),
|
||||
Err(err) => {
|
||||
let msg = format!("error: {err}").to_string().as_bytes().to_vec();
|
||||
RpcResponse::Binary(msg)
|
||||
}
|
||||
Err(_) => RpcResponse::Binary(b"error: Unable to serialize block".to_vec()),
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
let msg = format!("error: {err}").to_string().as_bytes().to_vec();
|
||||
RpcResponse::Binary(msg)
|
||||
}
|
||||
Err(_) => RpcResponse::Binary(format!("error: Block {height} not found").into_bytes()),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,13 @@
|
|||
use crate::decode;
|
||||
use crate::miner::flag::is_syncing_mode;
|
||||
use crate::records::unpack_block::unpack_header::load_block_header;
|
||||
use crate::rpc::responses::RpcResponse;
|
||||
|
||||
pub async fn request_block_hash_at_height(block_number: u32) -> RpcResponse {
|
||||
if is_syncing_mode() {
|
||||
return RpcResponse::Binary(b"error: Node is syncing".to_vec());
|
||||
}
|
||||
|
||||
match load_block_header(block_number).await {
|
||||
Ok(header) => {
|
||||
let hash = header.hash().await;
|
||||
|
|
@ -15,10 +20,8 @@ pub async fn request_block_hash_at_height(block_number: u32) -> RpcResponse {
|
|||
),
|
||||
}
|
||||
}
|
||||
Err(err) => RpcResponse::Binary(
|
||||
format!("error: Failed to load block header at height {block_number}: {err}")
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
),
|
||||
Err(_) => {
|
||||
RpcResponse::Binary(format!("error: Block {block_number} not found").into_bytes())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,15 +13,9 @@ pub async fn request_latest_block(db: &Db) -> RpcResponse {
|
|||
let block_bytes = block.to_bytes().await;
|
||||
match block_bytes {
|
||||
Ok(block_bytes) => RpcResponse::Binary(block_bytes),
|
||||
Err(err) => {
|
||||
let msg = format!("error: {err}").to_string().as_bytes().to_vec();
|
||||
RpcResponse::Binary(msg)
|
||||
}
|
||||
Err(_) => RpcResponse::Binary(b"error: Unable to serialize block".to_vec()),
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
let msg = format!("error: {err}").to_string().as_bytes().to_vec();
|
||||
RpcResponse::Binary(msg)
|
||||
}
|
||||
Err(_) => RpcResponse::Binary(format!("error: Block {height} not found").into_bytes()),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ pub fn should_trigger_orphan_check(error: &str) -> bool {
|
|||
|| error.contains("Candidate parent is not current chain parent.")
|
||||
|| error.contains("Difficulty mismatch with the blockchain data.")
|
||||
|| error.contains("Incoming block is no longer the next expected height.")
|
||||
|| error.contains("Error opening file ./testnet_blocks/")
|
||||
|| error.contains("Unable to read block")
|
||||
}
|
||||
|
||||
async fn next_expected_height(db: &Db) -> u32 {
|
||||
|
|
|
|||
Loading…
Reference in New Issue