diff --git a/core/src/blocktree_processor.rs b/core/src/blocktree_processor.rs index 8d4543928d..d1073f149a 100644 --- a/core/src/blocktree_processor.rs +++ b/core/src/blocktree_processor.rs @@ -9,7 +9,7 @@ use solana_runtime::locked_accounts_results::LockedAccountsResults; use solana_sdk::genesis_block::GenesisBlock; use solana_sdk::timing::duration_as_ms; use solana_sdk::timing::MAX_RECENT_BLOCKHASHES; -use solana_sdk::transaction::Result; +use solana_sdk::transaction::{Result, TransactionError}; use std::result; use std::sync::Arc; use std::time::Instant; @@ -21,6 +21,13 @@ fn first_err(results: &[Result<()>]) -> Result<()> { Ok(()) } +fn is_unexpected_validator_error(r: &Result<()>) -> bool { + match r { + Err(TransactionError::DuplicateSignature) => true, + _ => false, + } +} + fn par_execute_entries(bank: &Bank, entries: &[(&Entry, LockedAccountsResults)]) -> Result<()> { inc_new_counter_info!("bank-par_execute_entries-count", entries.len()); let results: Vec> = entries @@ -31,7 +38,26 @@ fn par_execute_entries(bank: &Bank, entries: &[(&Entry, LockedAccountsResults)]) locked_accounts, MAX_RECENT_BLOCKHASHES, ); - first_err(&results) + let mut first_err = None; + for r in results { + if let Err(ref e) = r { + if first_err.is_none() { + first_err = Some(r.clone()); + } + if is_unexpected_validator_error(&r) { + warn!("Unexpected validator error: {:?}", e); + solana_metrics::submit( + solana_metrics::influxdb::Point::new("validator_process_entry_error") + .add_field( + "error", + solana_metrics::influxdb::Value::String(format!("{:?}", e)), + ) + .to_owned(), + ) + } + } + } + first_err.unwrap_or(Ok(())) }) .collect();