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

tari-project / tari / 18399107786

10 Oct 2025 07:04AM UTC coverage: 58.589% (-1.0%) from 59.571%
18399107786

push

github

web-flow
feat: custom db timeout for grpc (#7544)

Description
---
Grpc create transaction calls have a timeout while waiting for a
database write. This timeout is 100ms, and should be sufficient, but can
be too long. This creates a custom config option to make this longer, or
shorter.

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

* **New Features**
* Added a configurable timeout for wallet gRPC database write operations
to control how long the system waits before reporting a timeout.
  * Default timeout set to 100 ms; adjustable via wallet configuration.
* Helps avoid premature timeouts on slower systems and permits tighter
responsiveness on faster setups.
* Preset configuration updated to include the new option for easier
setup.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

0 of 1 new or added line in 1 file covered. (0.0%)

1138 existing lines in 32 files now uncovered.

66489 of 113484 relevant lines covered (58.59%)

228871.69 hits per line

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

0.0
/base_layer/core/src/validation/error.rs
1
// Copyright 2019. 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
use tari_common_types::{epoch::VnEpoch, types::HashOutput};
23
use tari_node_components::blocks::{BlockHeaderValidationError, BlockValidationError};
24
use tari_sidechain::SidechainProofValidationError;
25
use tari_transaction_components::{
26
    tari_proof_of_work::{DifficultyError, PowError},
27
    transaction_components::{covenants::CovenantError, OutputType, TransactionError},
28
    validation::AggregatedBodyValidationError,
29
    BanPeriod,
30
    BanReason,
31
};
32
use tari_utilities::ByteArrayError;
33
use thiserror::Error;
34

35
use crate::{
36
    chain_storage::ChainStorageError,
37
    proof_of_work::{cuckaroo_pow::CuckarooVerificationError, monero_rx::MergeMineError},
38
};
39

40
#[derive(Debug, Error)]
41
pub enum ValidationError {
42
    #[error("Serialization failed: {0}")]
43
    SerializationError(String),
44
    #[error("Block header validation failed: {0}")]
45
    BlockHeaderError(#[from] BlockHeaderValidationError),
46
    #[error("Block validation error: {0}")]
47
    BlockError(#[from] BlockValidationError),
48
    #[error("Contains kernels or inputs that are not yet spendable")]
49
    MaturityError,
50
    #[error("The block weight ({actual_weight}) is above the maximum ({max_weight})")]
51
    BlockTooLarge { actual_weight: u64, max_weight: u64 },
52
    #[error("Contains {} unknown inputs", .0.len())]
53
    UnknownInputs(Vec<HashOutput>),
54
    #[error("Contains an unknown input")]
55
    UnknownInput,
56
    #[error("The transaction is invalid: {0}")]
57
    TransactionError(#[from] TransactionError),
58
    #[error("Fatal storage error during validation: {0}")]
59
    FatalStorageError(String),
60
    #[error(
61
        "The total expected supply plus the total accumulated (offset) excess does not equal the sum of all UTXO \
62
         commitments."
63
    )]
64
    InvalidAccountingBalance,
65
    #[error("Transaction contains already spent inputs")]
66
    ContainsSTxO,
67
    #[error("Transaction contains an output commitment that already exists")]
68
    ContainsDuplicateUtxoCommitment,
69
    #[error("Final state validation failed: The UTXO set did not balance with the expected emission at height {0}")]
70
    ChainBalanceValidationFailed(u64),
71
    #[error("The total value + fees of the block exceeds the maximum allowance on chain")]
72
    CoinbaseExceedsMaxLimit,
73
    #[error("Proof of work error: {0}")]
74
    ProofOfWorkError(#[from] PowError),
75
    #[error("Attempted to validate genesis block")]
76
    ValidatingGenesis,
77
    #[error("Duplicate or unsorted input found in block body")]
78
    UnsortedOrDuplicateInput,
79
    #[error("Duplicate or unsorted output found in block body")]
80
    UnsortedOrDuplicateOutput,
81
    #[error("Error in merge mine data:{0}")]
82
    MergeMineError(#[from] MergeMineError),
83
    #[error("Maximum transaction weight exceeded")]
84
    MaxTransactionWeightExceeded,
85
    #[error("Expected block height to be {expected}, but was {block_height}")]
86
    IncorrectHeight { expected: u64, block_height: u64 },
87
    #[error("Expected block previous hash to be {expected}, but was {block_hash}")]
88
    IncorrectPreviousHash { expected: String, block_hash: String },
89
    #[error("Bad block with hash '{hash}' and reason '{reason}' found")]
90
    BadBlockFound { hash: String, reason: String },
91
    #[error("Consensus Error: {0}")]
92
    ConsensusError(String),
93
    #[error("Duplicate kernel Error: {0}")]
94
    DuplicateKernelError(String),
95
    #[error("Covenant failed to validate: {0}")]
96
    CovenantError(#[from] CovenantError),
97
    #[error("Invalid or unsupported blockchain version {version}")]
98
    InvalidBlockchainVersion { version: u16 },
99
    #[error("Contains Invalid Burn: {0}")]
100
    InvalidBurnError(String),
101
    #[error("Validator node registration signature failed verification")]
102
    IncorrectNumberOfTimestampsProvided { expected: u64, actual: u64 },
103
    #[error("Invalid difficulty: {0}")]
104
    DifficultyError(#[from] DifficultyError),
105
    #[error("Invalid Serialized Public key: {0}")]
106
    InvalidSerializedPublicKey(String),
107
    #[error("Sidechain proof invalid: `{0}`")]
108
    SidechainProofInvalid(#[from] SidechainProofValidationError),
109
    #[error("Sidechain eviction proof submitted for unregistered validator {validator_pk}")]
110
    SidechainEvictionProofValidatorNotFound { validator_pk: String },
111
    #[error(
112
        "Sidechain eviction proof invalid: given epoch {epoch} is greater than the epoch at tip height {tip_height}"
113
    )]
114
    SidechainEvictionProofInvalidEpoch { epoch: VnEpoch, tip_height: u64 },
115
    #[error("Validator node already registered: {public_key}")]
116
    ValidatorNodeAlreadyRegistered { public_key: String },
117
    #[error("Validator node {public_key} not registered: {details}")]
118
    ValidatorNodeNotRegistered { public_key: String, details: String },
119
    #[error("Validator registration {public_key} invalid: max epoch {max_epoch} < current epoch {current_epoch}")]
120
    ValidatorNodeRegistrationMaxEpoch {
121
        public_key: String,
122
        current_epoch: VnEpoch,
123
        max_epoch: VnEpoch,
124
    },
125
    #[error("{output_type} output rule disallows the spend: {details}")]
126
    OutputSpendRuleDisallow { output_type: OutputType, details: String },
127
    #[error("Output type '{output_type}' does not match sidechain data")]
128
    OutputTypeNotMatchSidechainData { output_type: OutputType, details: String },
129
    #[error("Validation error: {0}")]
130
    AggregatedBodyValidationError(#[from] AggregatedBodyValidationError),
131
    #[error("Cuckaroo POW error: {0}")]
132
    CuckarooPowError(#[from] CuckarooVerificationError),
133
}
134

135
// ChainStorageError has a ValidationError variant, so to prevent a cyclic dependency we use a string representation in
136
// for storage errors that cause validation failures.
137
impl From<ChainStorageError> for ValidationError {
138
    fn from(err: ChainStorageError) -> Self {
×
139
        Self::FatalStorageError(err.to_string())
×
140
    }
×
141
}
142

143
impl From<ByteArrayError> for ValidationError {
144
    fn from(err: ByteArrayError) -> Self {
×
145
        Self::InvalidSerializedPublicKey(err.to_string())
×
146
    }
×
147
}
148

149
impl ValidationError {
UNCOV
150
    pub fn get_ban_reason(&self) -> Option<BanReason> {
×
UNCOV
151
        match self {
×
152
            ValidationError::ProofOfWorkError(e) => e.get_ban_reason(),
×
153
            err @ ValidationError::SerializationError(_) |
×
154
            err @ ValidationError::BlockHeaderError(_) |
×
155
            err @ ValidationError::BlockError(_) |
×
156
            err @ ValidationError::MaturityError |
×
157
            err @ ValidationError::BlockTooLarge { .. } |
×
158
            err @ ValidationError::UnknownInputs(_) |
×
159
            err @ ValidationError::UnknownInput |
×
160
            err @ ValidationError::TransactionError(_) |
×
161
            err @ ValidationError::InvalidAccountingBalance |
×
162
            err @ ValidationError::ContainsSTxO |
×
163
            err @ ValidationError::ContainsDuplicateUtxoCommitment |
×
164
            err @ ValidationError::ChainBalanceValidationFailed(_) |
×
165
            err @ ValidationError::ValidatingGenesis |
×
166
            err @ ValidationError::UnsortedOrDuplicateInput |
×
167
            err @ ValidationError::UnsortedOrDuplicateOutput |
×
168
            err @ ValidationError::MaxTransactionWeightExceeded |
×
169
            err @ ValidationError::IncorrectHeight { .. } |
×
170
            err @ ValidationError::IncorrectPreviousHash { .. } |
×
171
            err @ ValidationError::BadBlockFound { .. } |
×
UNCOV
172
            err @ ValidationError::ConsensusError(_) |
×
173
            err @ ValidationError::DuplicateKernelError(_) |
×
174
            err @ ValidationError::CovenantError(_) |
×
175
            err @ ValidationError::InvalidBlockchainVersion { .. } |
×
176
            err @ ValidationError::InvalidBurnError(_) |
×
177
            err @ ValidationError::DifficultyError(_) |
×
178
            err @ ValidationError::CoinbaseExceedsMaxLimit |
×
179
            err @ ValidationError::InvalidSerializedPublicKey(_) |
×
180
            err @ ValidationError::SidechainEvictionProofValidatorNotFound { .. } |
×
181
            err @ ValidationError::SidechainProofInvalid(_) |
×
182
            err @ ValidationError::SidechainEvictionProofInvalidEpoch { .. } |
×
183
            err @ ValidationError::ValidatorNodeAlreadyRegistered { .. } |
×
184
            err @ ValidationError::ValidatorNodeNotRegistered { .. } |
×
185
            err @ ValidationError::ValidatorNodeRegistrationMaxEpoch { .. } |
×
186
            err @ ValidationError::OutputTypeNotMatchSidechainData { .. } |
×
187
            err @ ValidationError::AggregatedBodyValidationError(_) |
×
188
            err @ ValidationError::CuckarooPowError(_) |
×
UNCOV
189
            err @ ValidationError::OutputSpendRuleDisallow { .. } => Some(BanReason {
×
UNCOV
190
                reason: err.to_string(),
×
UNCOV
191
                ban_duration: BanPeriod::Long,
×
UNCOV
192
            }),
×
193
            ValidationError::MergeMineError(e) => e.get_ban_reason(),
×
194
            ValidationError::FatalStorageError(_) | ValidationError::IncorrectNumberOfTimestampsProvided { .. } => None,
×
195
        }
UNCOV
196
    }
×
197
}
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