• 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

85.19
/base_layer/core/src/common/rolling_vec.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::ops::Deref;
24

25
/// A vector that contains up to a number of elements. As new elements are added to the end, the first elements are
26
/// removed.
27
#[derive(Debug)]
28
pub struct RollingVec<T>(Vec<T>);
29

30
impl<T> RollingVec<T> {
31
    pub fn new(capacity: usize) -> Self {
55✔
32
        Self(Vec::with_capacity(capacity))
55✔
33
    }
55✔
34

35
    /// Adds a new element to the RollingVec.
36
    /// If adding an element will cause the length to exceed the capacity, the first element is removed and the removed
37
    /// value is returned.
38
    pub fn push(&mut self, item: T) -> Option<T> {
95✔
39
        if self.capacity() == 0 {
95✔
40
            return None;
3✔
41
        }
92✔
42

43
        let mut removed = None;
92✔
44
        if self.is_full() {
92✔
45
            removed = Some(self.inner_mut().remove(0));
2✔
46
        }
90✔
47

48
        self.inner_mut().push(item);
92✔
49
        removed
92✔
50
    }
95✔
51

52
    pub fn insert(&mut self, index: usize, item: T) {
×
53
        assert!(index < self.capacity());
×
54
        assert!(index < self.len());
×
55

56
        if self.is_full() {
×
57
            self.inner_mut().remove(0);
×
58
        }
×
59

60
        self.inner_mut().insert(index, item);
×
61
    }
×
62

63
    pub fn pop(&mut self) -> Option<T> {
×
64
        self.inner_mut().pop()
×
65
    }
×
66

67
    #[inline]
68
    pub fn is_full(&self) -> bool {
98✔
69
        // len never exceeds capacity
70
        debug_assert!(self.inner().len() <= self.inner().capacity());
98✔
71
        self.len() == self.capacity()
98✔
72
    }
98✔
73

74
    #[inline]
75
    pub fn capacity(&self) -> usize {
201✔
76
        self.inner().capacity()
201✔
77
    }
201✔
78

79
    /// Sorts the slice, but might not preserve the order of equal elements.
80
    /// This sort is unstable (i.e., may reorder equal elements), in-place (i.e., does not allocate), and O(n * log(n))
81
    pub fn sort_unstable(&mut self)
23✔
82
    where T: Ord {
23✔
83
        self.inner_mut().sort_unstable();
23✔
84
    }
23✔
85

86
    #[inline]
87
    fn inner(&self) -> &Vec<T> {
563✔
88
        &self.0
563✔
89
    }
563✔
90

91
    #[inline]
92
    fn inner_mut(&mut self) -> &mut Vec<T> {
117✔
93
        &mut self.0
117✔
94
    }
117✔
95
}
96

97
impl<T> Extend<T> for RollingVec<T> {
98
    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
6✔
99
        let iter = iter.into_iter();
6✔
100
        let (lower, _) = iter.size_hint();
6✔
101

102
        let skip = if lower > self.capacity() {
6✔
103
            // If the iterator will emit more than the capacity, skip over the first elements that will be pushed out of
104
            // the rolling window
105
            lower - self.capacity()
2✔
106
        } else {
107
            0
4✔
108
        };
109

110
        for item in iter.skip(skip) {
26✔
111
            self.push(item);
26✔
112
        }
26✔
113
    }
6✔
114
}
115

116
impl<T> Deref for RollingVec<T> {
117
    type Target = [T];
118

119
    fn deref(&self) -> &Self::Target {
166✔
120
        self.inner()
166✔
121
    }
166✔
122
}
123

124
impl<T: Clone> Clone for RollingVec<T> {
UNCOV
125
    fn clone(&self) -> Self {
×
UNCOV
126
        let mut v = Vec::with_capacity(self.capacity());
×
UNCOV
127
        v.extend(self.0.clone());
×
UNCOV
128
        Self(v)
×
UNCOV
129
    }
×
130
}
131

132
#[cfg(test)]
133
mod test {
134
    #![allow(clippy::indexing_slicing)]
135
    use super::*;
136

137
    #[test]
138
    fn it_is_always_empty_for_zero_capacity() {
1✔
139
        let mut subject = RollingVec::new(0);
1✔
140
        assert!(subject.is_empty());
1✔
141
        subject.push(123);
1✔
142
        assert!(subject.is_empty());
1✔
143
        assert_eq!(subject.len(), 0);
1✔
144
    }
1✔
145

146
    #[test]
147
    fn it_is_always_full_for_zero_capacity() {
1✔
148
        let mut subject = RollingVec::new(0);
1✔
149
        assert!(subject.is_full());
1✔
150
        subject.push(123);
1✔
151
        assert!(subject.is_full());
1✔
152
    }
1✔
153

154
    #[test]
155
    fn it_is_full_if_n_elements_are_added() {
1✔
156
        let mut subject = RollingVec::new(1);
1✔
157
        assert!(!subject.is_full());
1✔
158
        subject.push(1);
1✔
159
        assert!(subject.is_full());
1✔
160
    }
1✔
161

162
    #[test]
163
    fn it_rolls_over_as_elements_are_added() {
1✔
164
        let mut subject = RollingVec::new(1);
1✔
165
        subject.push(1);
1✔
166
        assert_eq!(subject.len(), 1);
1✔
167
        subject.push(2);
1✔
168
        assert_eq!(subject.len(), 1);
1✔
169
        assert_eq!(subject[0], 2);
1✔
170
    }
1✔
171

172
    #[test]
173
    fn it_extends_with_less_items_than_capacity() {
1✔
174
        let mut subject = RollingVec::new(5);
1✔
175
        let vec = (0..2).collect::<Vec<_>>();
1✔
176
        subject.extend(vec);
1✔
177

178
        assert_eq!(subject.len(), 2);
1✔
179
        assert!(!subject.is_full());
1✔
180

181
        assert_eq!(subject[0], 0);
1✔
182
        assert_eq!(subject[1], 1);
1✔
183
    }
1✔
184

185
    #[test]
186
    fn it_extends_without_exceeding_capacity() {
1✔
187
        let mut subject = RollingVec::new(5);
1✔
188
        let vec = (0..10).collect::<Vec<_>>();
1✔
189
        subject.extend(vec);
1✔
190

191
        assert_eq!(subject.len(), 5);
1✔
192
        assert!(subject.is_full());
1✔
193

194
        assert_eq!(subject[0], 5);
1✔
195
        assert_eq!(subject[1], 6);
1✔
196
        assert_eq!(subject[2], 7);
1✔
197
        assert_eq!(subject[3], 8);
1✔
198
        assert_eq!(subject[4], 9);
1✔
199
    }
1✔
200
}
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