• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

tari-project / tari / 17860174736

19 Sep 2025 01:46PM UTC coverage: 60.677% (+0.03%) from 60.651%
17860174736

push

github

SWvheerden
chore: new release v5.10-pre.2

74238 of 122350 relevant lines covered (60.68%)

222750.63 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/base_layer/core/src/base_node/sync/header_sync/error.rs
1
//  Copyright 2020, The Tari Project
2
//
3
//  Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
4
//  following conditions are met:
5
//
6
//  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
7
//  disclaimer.
8
//
9
//  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
10
//  following disclaimer in the documentation and/or other materials provided with the distribution.
11
//
12
//  3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
13
//  products derived from this software without specific prior written permission.
14
//
15
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
16
//  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17
//  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
18
//  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19
//  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
20
//  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
21
//  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22

23
use std::time::Duration;
24

25
use primitive_types::U512;
26
use tari_comms::{
27
    connectivity::ConnectivityError,
28
    peer_manager::NodeId,
29
    protocol::rpc::{RpcError, RpcStatus},
30
};
31
use tari_node_components::blocks::BlockError;
32
use tari_transaction_components::{BanPeriod, BanReason};
33

34
use crate::{chain_storage::ChainStorageError, validation::ValidationError};
35

36
#[derive(Debug, thiserror::Error)]
37
pub enum BlockHeaderSyncError {
38
    #[error("No more sync peers available: {0}")]
39
    NoMoreSyncPeers(String),
40
    #[error("Could not find peer info")]
41
    PeerNotFound,
42
    #[error("RPC error: {0}")]
43
    RpcError(#[from] RpcError),
44
    #[error("RPC request failed: {0}")]
45
    RpcRequestError(#[from] RpcStatus),
46
    #[error("Peer sent invalid header: {0}")]
47
    ReceivedInvalidHeader(String),
48
    #[error("Chain storage error: {0}")]
49
    ChainStorageError(#[from] ChainStorageError),
50
    #[error("Validation failed: {0}")]
51
    ValidationFailed(#[from] ValidationError),
52
    #[error("Sync failed for all peers")]
53
    SyncFailedAllPeers,
54
    #[error("Peer sent a found hash index that was out of range (Expected less than {0}, Found: {1})")]
55
    FoundHashIndexOutOfRange(u64, u64),
56
    #[error("Failed to ban peer: {0}")]
57
    FailedToBan(ConnectivityError),
58
    #[error("Connectivity Error: {0}")]
59
    ConnectivityError(#[from] ConnectivityError),
60
    #[error("Node is still not in sync. Sync will be retried with another peer if possible.")]
61
    NotInSync,
62
    #[error("Unable to locate start hash `{0}`")]
63
    StartHashNotFound(String),
64
    #[error("Expected header height {expected} got {actual}")]
65
    InvalidBlockHeight { expected: u64, actual: u64 },
66
    #[error("Unable to find chain split from peer `{0}`")]
67
    ChainSplitNotFound(NodeId),
68
    #[error("Invalid protocol response: {0}")]
69
    InvalidProtocolResponse(String),
70
    #[error("Header at height {height} did not form a chain. Expected {actual} to equal the previous hash {expected}")]
71
    ChainLinkBroken {
72
        height: u64,
73
        actual: String,
74
        expected: String,
75
    },
76
    #[error("Block error: {0}")]
77
    BlockError(#[from] BlockError),
78
    #[error(
79
        "Peer claimed a stronger chain than they were able to provide. Claimed {claimed}, Actual: {actual:?}, local: \
80
         {local}"
81
    )]
82
    PeerSentInaccurateChainMetadata {
83
        claimed: U512,
84
        actual: Option<U512>,
85
        local: U512,
86
    },
87
    #[error("This peer sent too many headers ({0}) in response to a chain split request")]
88
    PeerSentTooManyHeaders(usize),
89
    #[error("Peer {peer} exceeded maximum permitted sync latency. latency: {latency:.2?}s, max: {max_latency:.2?}s")]
90
    MaxLatencyExceeded {
91
        peer: NodeId,
92
        latency: Duration,
93
        max_latency: Duration,
94
    },
95
    #[error("All sync peers exceeded max allowed latency")]
96
    AllSyncPeersExceedLatency,
97
    #[error("Unable to get TargetDifficulties: ({0})")]
98
    TargetDifficultiesError(String),
99
}
100

101
impl BlockHeaderSyncError {
102
    pub fn get_ban_reason(&self) -> Option<BanReason> {
×
103
        match self {
×
104
            // no ban
105
            BlockHeaderSyncError::NoMoreSyncPeers(_) |
106
            BlockHeaderSyncError::SyncFailedAllPeers |
107
            BlockHeaderSyncError::FailedToBan(_) |
108
            BlockHeaderSyncError::AllSyncPeersExceedLatency |
109
            BlockHeaderSyncError::ConnectivityError(_) |
110
            BlockHeaderSyncError::NotInSync |
111
            BlockHeaderSyncError::TargetDifficultiesError(_) |
112
            BlockHeaderSyncError::PeerSentInaccurateChainMetadata { .. } |
113
            BlockHeaderSyncError::PeerNotFound => None,
×
114
            BlockHeaderSyncError::ChainStorageError(e) => e.get_ban_reason(),
×
115

116
            // short ban
117
            err @ BlockHeaderSyncError::MaxLatencyExceeded { .. } |
×
118
            err @ BlockHeaderSyncError::RpcError { .. } |
×
119
            err @ BlockHeaderSyncError::RpcRequestError { .. } => Some(BanReason {
×
120
                reason: format!("{err}"),
×
121
                ban_duration: BanPeriod::Short,
×
122
            }),
×
123

124
            // long ban
125
            err @ BlockHeaderSyncError::ReceivedInvalidHeader(_) |
×
126
            err @ BlockHeaderSyncError::FoundHashIndexOutOfRange(_, _) |
×
127
            err @ BlockHeaderSyncError::StartHashNotFound(_) |
×
128
            err @ BlockHeaderSyncError::InvalidBlockHeight { .. } |
×
129
            err @ BlockHeaderSyncError::ChainSplitNotFound(_) |
×
130
            err @ BlockHeaderSyncError::InvalidProtocolResponse(_) |
×
131
            err @ BlockHeaderSyncError::ChainLinkBroken { .. } |
×
132
            err @ BlockHeaderSyncError::BlockError(_) |
×
133
            err @ BlockHeaderSyncError::PeerSentTooManyHeaders(_) => Some(BanReason {
×
134
                reason: format!("{err}"),
×
135
                ban_duration: BanPeriod::Long,
×
136
            }),
×
137

138
            BlockHeaderSyncError::ValidationFailed(err) => ValidationError::get_ban_reason(err),
×
139
        }
140
    }
×
141
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc