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

tari-project / tari / 18003082473

25 Sep 2025 09:26AM UTC coverage: 60.969% (+0.3%) from 60.677%
18003082473

push

github

web-flow
chore: revert accumulated difficulty fix and let orphans clean at startup (#7513)

Description
---
- Revert "fix: accumulated data in c29 (#7507)" This reverts commit
840c6d24e.
- Revert "fix: remove ban for wrong accumulated difficulty" This reverts
commit ccb41e6c5.
- Set `cleanup_orphans_at_startup` config option to true to combat the
base node being fixated on bad orphan blocks - this stops the node from
syncing when it happens.

Motivation and Context
---
Network forks and base nodes cannot sync anymore

How Has This Been Tested?
---
System-level testing.

What process can a PR reviewer use to test or verify this change?
---

<!-- Checklist -->
<!-- 1. Is the title of your PR in the form that would make nice release
notes? The title, excluding the conventional commit
tag, will be included exactly as is in the CHANGELOG, so please think
about it carefully. -->


Breaking Changes
---

- [ ] None
- [ ] Requires data directory on base node to be deleted
- [ ] Requires hard fork
- [x] Other - Please specify

<!-- Does this include a breaking change? If so, include this line as a
footer -->
BREAKING CHANGE: This changes back the accumulated difficulty
calculation to that which is currently the official release.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- Refactor
- Updated accumulated difficulty calculation; reported totals may
change.
- Chores
  - Base node now cleans up orphan blocks on startup by default.
- Tightened peer ban policy: inaccurate chain metadata now triggers a
short ban.
- Documentation
- Config preset comments updated to reflect the new orphan-cleanup
default.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

2 of 4 new or added lines in 3 files covered. (50.0%)

64 existing lines in 9 files now uncovered.

74565 of 122299 relevant lines covered (60.97%)

222853.45 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(_) |
UNCOV
112
            BlockHeaderSyncError::PeerNotFound => None,
×
113
            BlockHeaderSyncError::ChainStorageError(e) => e.get_ban_reason(),
×
114

115
            // short ban
116
            err @ BlockHeaderSyncError::MaxLatencyExceeded { .. } |
×
117
            err @ BlockHeaderSyncError::RpcError { .. } |
×
NEW
118
            err @ BlockHeaderSyncError::RpcRequestError { .. } |
×
NEW
119
            err @ BlockHeaderSyncError::PeerSentInaccurateChainMetadata { .. } => 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