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

tari-project / tari / 20773089691

07 Jan 2026 06:45AM UTC coverage: 60.457% (-0.3%) from 60.745%
20773089691

push

github

web-flow
chore(deps): bump rsa from 0.9.7 to 0.9.10 (#7649)

Bumps [rsa](https://github.com/RustCrypto/RSA) from 0.9.7 to 0.9.10.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/RustCrypto/RSA/blob/v0.9.10/CHANGELOG.md">rsa's
changelog</a>.</em></p>
<blockquote>
<h2>0.9.10 (2026-01-06)</h2>
<h3>Fixed</h3>
<ul>
<li>do not panic on a prime being 1 when loading a secret key (<a
href="https://redirect.github.com/RustCrypto/RSA/issues/624">#624</a>)</li>
</ul>
<p><a
href="https://redirect.github.com/RustCrypto/RSA/issues/624">#624</a>:
<a
href="https://redirect.github.com/RustCrypto/RSA/pull/624">RustCrypto/RSA#624</a></p>
<h2>0.9.9 (2025-11-13)</h2>
<h3>Fixed</h3>
<ul>
<li>Support for cryptographic operations with larger keys (<a
href="https://redirect.github.com/RustCrypto/RSA/issues/594">#594</a>)</li>
</ul>
<p><a
href="https://redirect.github.com/RustCrypto/RSA/issues/594">#594</a>:
<a
href="https://redirect.github.com/RustCrypto/RSA/pull/594">RustCrypto/RSA#594</a></p>
<h2>0.9.8 (2025-03-12)</h2>
<h3>Added</h3>
<ul>
<li>Doc comments to specify the <code>rand</code> version (<a
href="https://redirect.github.com/RustCrypto/RSA/issues/473">#473</a>)</li>
</ul>
<p><a
href="https://redirect.github.com/RustCrypto/RSA/issues/473">#473</a>:
<a
href="https://redirect.github.com/RustCrypto/RSA/pull/473">RustCrypto/RSA#473</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/RustCrypto/RSA/commit/da2af9a0f"><code>da2af9a</code></a>
chore: release v0.9.10</li>
<li><a
href="https://github.com/RustCrypto/RSA/commit/2926c91be"><code>2926c91</code></a>
fix: do not panic on a prime being 1 when loading a secret key (<a
href="https://redirect.github.com/RustCrypto/RSA/issues/624">#624</a>)</li>
<li><a
href="https://github.com/RustCrypto/RSA/commit/488d2ad60"><code>488d2ad</code></a>
chore: relea... (continued)

70166 of 116059 relevant lines covered (60.46%)

299924.04 hits per line

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

16.43
/base_layer/core/src/base_node/comms_interface/local_interface.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

23
use std::{ops::RangeInclusive, sync::Arc};
24

25
use tari_common_types::{
26
    chain_metadata::ChainMetadata,
27
    epoch::VnEpoch,
28
    types::{BlockHash, CompressedCommitment, CompressedPublicKey, CompressedSignature, FixedHash, HashOutput},
29
};
30
use tari_node_components::blocks::{Block, ChainHeader, HistoricalBlock, NewBlockTemplate};
31
use tari_service_framework::{reply_channel::SenderService, Service};
32
use tari_transaction_components::{
33
    tari_proof_of_work::{Difficulty, PowAlgorithm},
34
    transaction_components::{TransactionKernel, TransactionOutput},
35
};
36
use tokio::sync::broadcast;
37

38
use crate::{
39
    base_node::comms_interface::{
40
        comms_request::GetNewBlockTemplateRequest,
41
        comms_response::ValidatorNodeChange,
42
        error::CommsInterfaceError,
43
        BlockEvent,
44
        NodeCommsRequest,
45
        NodeCommsResponse,
46
    },
47
    chain_storage::{
48
        InputMinedInfo,
49
        MinedInfo,
50
        OutputMinedInfo,
51
        TemplateRegistrationEntry,
52
        ValidatorNodeRegistrationInfo,
53
    },
54
};
55
pub type BlockEventSender = broadcast::Sender<Arc<BlockEvent>>;
56
pub type BlockEventReceiver = broadcast::Receiver<Arc<BlockEvent>>;
57

58
/// The InboundNodeCommsInterface provides an interface to request information from the current local node by other
59
/// internal services.
60
#[derive(Clone)]
61
pub struct LocalNodeCommsInterface {
62
    request_sender: SenderService<NodeCommsRequest, Result<NodeCommsResponse, CommsInterfaceError>>,
63
    block_sender: SenderService<Block, Result<BlockHash, CommsInterfaceError>>,
64
    block_event_sender: BlockEventSender,
65
}
66

67
impl LocalNodeCommsInterface {
68
    /// Construct a new LocalNodeCommsInterface with the specified SenderService.
69
    pub fn new(
56✔
70
        request_sender: SenderService<NodeCommsRequest, Result<NodeCommsResponse, CommsInterfaceError>>,
56✔
71
        block_sender: SenderService<Block, Result<BlockHash, CommsInterfaceError>>,
56✔
72
        block_event_sender: BlockEventSender,
56✔
73
    ) -> Self {
56✔
74
        Self {
56✔
75
            request_sender,
56✔
76
            block_sender,
56✔
77
            block_event_sender,
56✔
78
        }
56✔
79
    }
56✔
80

81
    pub fn get_block_event_stream(&self) -> BlockEventReceiver {
101✔
82
        self.block_event_sender.subscribe()
101✔
83
    }
101✔
84

85
    /// Request metadata from the current local node.
86
    pub async fn get_metadata(&mut self) -> Result<ChainMetadata, CommsInterfaceError> {
74✔
87
        match self.request_sender.call(NodeCommsRequest::GetChainMetadata).await?? {
74✔
88
            NodeCommsResponse::ChainMetadata(metadata) => Ok(metadata),
74✔
89
            _ => Err(CommsInterfaceError::UnexpectedApiResponse),
×
90
        }
91
    }
74✔
92

93
    pub async fn get_target_difficulty_for_next_block(
×
94
        &mut self,
×
95
        algo: PowAlgorithm,
×
96
    ) -> Result<Difficulty, CommsInterfaceError> {
×
97
        match self
×
98
            .request_sender
×
99
            .call(NodeCommsRequest::GetTargetDifficultyNextBlock(algo))
×
100
            .await??
×
101
        {
102
            NodeCommsResponse::TargetDifficulty(target_difficulty) => Ok(target_difficulty),
×
103
            _ => Err(CommsInterfaceError::UnexpectedApiResponse),
×
104
        }
105
    }
×
106

107
    /// Request the block headers within the given range
108
    pub async fn get_blocks(
×
109
        &mut self,
×
110
        range: RangeInclusive<u64>,
×
111
        compact: bool,
×
112
    ) -> Result<Vec<HistoricalBlock>, CommsInterfaceError> {
×
113
        match self
×
114
            .request_sender
×
115
            .call(NodeCommsRequest::FetchMatchingBlocks { range, compact })
×
116
            .await??
×
117
        {
118
            NodeCommsResponse::HistoricalBlocks(blocks) => Ok(blocks),
×
119
            _ => Err(CommsInterfaceError::UnexpectedApiResponse),
×
120
        }
121
    }
×
122

123
    /// Request the block header at the given height
124
    pub async fn get_block(
×
125
        &mut self,
×
126
        height: u64,
×
127
        compact: bool,
×
128
    ) -> Result<Option<HistoricalBlock>, CommsInterfaceError> {
×
129
        match self
×
130
            .request_sender
×
131
            .call(NodeCommsRequest::FetchMatchingBlocks {
×
132
                range: height..=height,
×
133
                compact,
×
134
            })
×
135
            .await??
×
136
        {
137
            NodeCommsResponse::HistoricalBlocks(mut blocks) => Ok(blocks.pop()),
×
138
            _ => Err(CommsInterfaceError::UnexpectedApiResponse),
×
139
        }
140
    }
×
141

142
    /// Request the block headers with the given range of heights. The returned headers are ordered from lowest to
143
    /// highest block height
144
    pub async fn get_headers(&mut self, range: RangeInclusive<u64>) -> Result<Vec<ChainHeader>, CommsInterfaceError> {
×
145
        match self
×
146
            .request_sender
×
147
            .call(NodeCommsRequest::FetchHeaders(range))
×
148
            .await??
×
149
        {
150
            NodeCommsResponse::BlockHeaders(headers) => Ok(headers),
×
151
            _ => Err(CommsInterfaceError::UnexpectedApiResponse),
×
152
        }
153
    }
×
154

155
    /// Request the block header with the height.
156
    pub async fn get_header(&mut self, height: u64) -> Result<Option<ChainHeader>, CommsInterfaceError> {
×
157
        match self
×
158
            .request_sender
×
159
            .call(NodeCommsRequest::FetchHeaders(height..=height))
×
160
            .await??
×
161
        {
162
            NodeCommsResponse::BlockHeaders(mut headers) => Ok(headers.pop()),
×
163
            _ => Err(CommsInterfaceError::UnexpectedApiResponse),
×
164
        }
165
    }
×
166

167
    /// Request the construction of a new mineable block template from the base node service.
168
    pub async fn get_new_block_template(
3✔
169
        &mut self,
3✔
170
        pow_algorithm: PowAlgorithm,
3✔
171
        max_weight: u64,
3✔
172
    ) -> Result<NewBlockTemplate, CommsInterfaceError> {
3✔
173
        let request = GetNewBlockTemplateRequest {
3✔
174
            algo: pow_algorithm,
3✔
175
            max_weight,
3✔
176
        };
3✔
177
        match self
3✔
178
            .request_sender
3✔
179
            .call(NodeCommsRequest::GetNewBlockTemplate(request))
3✔
180
            .await??
3✔
181
        {
182
            NodeCommsResponse::NewBlockTemplate(new_block_template) => Ok(new_block_template),
3✔
183
            _ => Err(CommsInterfaceError::UnexpectedApiResponse),
×
184
        }
185
    }
3✔
186

187
    /// Request from base node service the construction of a block from a block template.
188
    pub async fn get_new_block(&mut self, block_template: NewBlockTemplate) -> Result<Block, CommsInterfaceError> {
3✔
189
        match self
3✔
190
            .request_sender
3✔
191
            .call(NodeCommsRequest::GetNewBlock(block_template))
3✔
192
            .await??
3✔
193
        {
194
            NodeCommsResponse::NewBlock { success, error, block } => {
3✔
195
                if success {
3✔
196
                    if let Some(block) = block {
3✔
197
                        Ok(block)
3✔
198
                    } else {
199
                        Err(CommsInterfaceError::UnexpectedApiResponse)
×
200
                    }
201
                } else {
202
                    Err(CommsInterfaceError::ApiError(
203
                        error.unwrap_or_else(|| "Unspecified error".to_string()),
×
204
                    ))
205
                }
206
            },
207
            _ => Err(CommsInterfaceError::UnexpectedApiResponse),
×
208
        }
209
    }
3✔
210

211
    /// Submit a block to the base node service.
212
    pub async fn submit_block(&mut self, block: Block) -> Result<BlockHash, CommsInterfaceError> {
7✔
213
        self.block_sender.call(block).await?
7✔
214
    }
7✔
215

216
    pub fn publish_block_event(&self, event: BlockEvent) -> usize {
×
217
        // If event send fails, that means that there are no receivers (i.e. it was sent to zero receivers)
218
        self.block_event_sender.send(Arc::new(event)).unwrap_or(0)
×
219
    }
×
220

221
    pub async fn fetch_matching_utxos(
×
222
        &mut self,
×
223
        hashes: Vec<HashOutput>,
×
224
    ) -> Result<Vec<TransactionOutput>, CommsInterfaceError> {
×
225
        match self
×
226
            .request_sender
×
227
            .call(NodeCommsRequest::FetchMatchingUtxos(hashes))
×
228
            .await??
×
229
        {
230
            NodeCommsResponse::TransactionOutputs(outputs) => Ok(outputs),
×
231
            _ => Err(CommsInterfaceError::UnexpectedApiResponse),
×
232
        }
233
    }
×
234

235
    /// Fetches the blocks with the specified utxo commitments
236
    pub async fn fetch_blocks_with_utxos(
×
237
        &mut self,
×
238
        commitments: Vec<CompressedCommitment>,
×
239
    ) -> Result<Vec<HistoricalBlock>, CommsInterfaceError> {
×
240
        match self
×
241
            .request_sender
×
242
            .call(NodeCommsRequest::FetchBlocksByUtxos(commitments))
×
243
            .await??
×
244
        {
245
            NodeCommsResponse::HistoricalBlocks(blocks) => Ok(blocks),
×
246
            _ => Err(CommsInterfaceError::UnexpectedApiResponse),
×
247
        }
248
    }
×
249

250
    /// Fetches the blocks with the specified kernel signatures commitments
251
    pub async fn get_blocks_with_kernels(
×
252
        &mut self,
×
253
        kernels: Vec<CompressedSignature>,
×
254
    ) -> Result<Vec<HistoricalBlock>, CommsInterfaceError> {
×
255
        match self
×
256
            .request_sender
×
257
            .call(NodeCommsRequest::FetchBlocksByKernelExcessSigs(kernels))
×
258
            .await??
×
259
        {
260
            NodeCommsResponse::HistoricalBlocks(blocks) => Ok(blocks),
×
261
            _ => Err(CommsInterfaceError::UnexpectedApiResponse),
×
262
        }
263
    }
×
264

265
    /// Return header matching the given hash. If the header cannot be found `Ok(None)` is returned.
266
    pub async fn get_header_by_hash(&mut self, hash: HashOutput) -> Result<Option<ChainHeader>, CommsInterfaceError> {
×
267
        match self
×
268
            .request_sender
×
269
            .call(NodeCommsRequest::GetHeaderByHash(hash))
×
270
            .await??
×
271
        {
272
            NodeCommsResponse::BlockHeader(header) => Ok(header),
×
273
            _ => Err(CommsInterfaceError::UnexpectedApiResponse),
×
274
        }
275
    }
×
276

277
    /// Return block matching the given hash. If the block cannot be found `Ok(None)` is returned.
278
    pub async fn get_block_by_hash(
×
279
        &mut self,
×
280
        hash: HashOutput,
×
281
    ) -> Result<Option<HistoricalBlock>, CommsInterfaceError> {
×
282
        match self
×
283
            .request_sender
×
284
            .call(NodeCommsRequest::GetBlockByHash(hash))
×
285
            .await??
×
286
        {
287
            NodeCommsResponse::HistoricalBlock(block) => Ok(*block),
×
288
            _ => Err(CommsInterfaceError::UnexpectedApiResponse),
×
289
        }
290
    }
×
291

292
    /// Searches for a kernel via the excess sig
293
    pub async fn get_kernel_by_excess_sig(
×
294
        &mut self,
×
295
        kernel: CompressedSignature,
×
296
    ) -> Result<Vec<TransactionKernel>, CommsInterfaceError> {
×
297
        match self
×
298
            .request_sender
×
299
            .call(NodeCommsRequest::FetchKernelByExcessSig(kernel))
×
300
            .await??
×
301
        {
302
            NodeCommsResponse::TransactionKernels(kernels) => Ok(kernels),
×
303
            _ => Err(CommsInterfaceError::UnexpectedApiResponse),
×
304
        }
305
    }
×
306

307
    pub async fn get_active_validator_nodes(
×
308
        &mut self,
×
309
        height: u64,
×
310
        validator_network: Option<CompressedPublicKey>,
×
311
    ) -> Result<Vec<ValidatorNodeRegistrationInfo>, CommsInterfaceError> {
×
312
        match self
×
313
            .request_sender
×
314
            .call(NodeCommsRequest::FetchValidatorNodesKeys {
×
315
                height,
×
316
                validator_network,
×
317
            })
×
318
            .await??
×
319
        {
320
            NodeCommsResponse::FetchValidatorNodesKeysResponse(validator_node) => Ok(validator_node),
×
321
            _ => Err(CommsInterfaceError::UnexpectedApiResponse),
×
322
        }
323
    }
×
324

325
    pub async fn get_validator_node_changes(
×
326
        &mut self,
×
327
        sidechain_id: Option<CompressedPublicKey>,
×
328
        epoch: VnEpoch,
×
329
    ) -> Result<Vec<ValidatorNodeChange>, CommsInterfaceError> {
×
330
        match self
×
331
            .request_sender
×
332
            .call(NodeCommsRequest::FetchValidatorNodeChanges { epoch, sidechain_id })
×
333
            .await??
×
334
        {
335
            NodeCommsResponse::FetchValidatorNodeChangesResponse(validator_node_change) => Ok(validator_node_change),
×
336
            _ => Err(CommsInterfaceError::UnexpectedApiResponse),
×
337
        }
338
    }
×
339

340
    pub async fn get_validator_node(
×
341
        &mut self,
×
342
        sidechain_id: Option<CompressedPublicKey>,
×
343
        public_key: CompressedPublicKey,
×
344
    ) -> Result<Option<ValidatorNodeRegistrationInfo>, CommsInterfaceError> {
×
345
        match self
×
346
            .request_sender
×
347
            .call(NodeCommsRequest::GetValidatorNode {
×
348
                sidechain_id,
×
349
                public_key,
×
350
            })
×
351
            .await??
×
352
        {
353
            NodeCommsResponse::GetValidatorNode(vn) => Ok(vn),
×
354
            _ => Err(CommsInterfaceError::UnexpectedApiResponse),
×
355
        }
356
    }
×
357

358
    pub async fn get_template_registrations(
×
359
        &mut self,
×
360
        start_height: u64,
×
361
        end_height: u64,
×
362
    ) -> Result<Vec<TemplateRegistrationEntry>, CommsInterfaceError> {
×
363
        match self
×
364
            .request_sender
×
365
            .call(NodeCommsRequest::FetchTemplateRegistrations {
×
366
                start_height,
×
367
                end_height,
×
368
            })
×
369
            .await??
×
370
        {
371
            NodeCommsResponse::FetchTemplateRegistrationsResponse(template_registrations) => Ok(template_registrations),
×
372
            _ => Err(CommsInterfaceError::UnexpectedApiResponse),
×
373
        }
374
    }
×
375

376
    /// Fetches UTXOs that are not spent for the given block hash up to the current chain tip.
377
    pub async fn fetch_unspent_utxos_in_block(
×
378
        &mut self,
×
379
        block_hash: BlockHash,
×
380
    ) -> Result<Vec<TransactionOutput>, CommsInterfaceError> {
×
381
        match self
×
382
            .request_sender
×
383
            .call(NodeCommsRequest::FetchUnspentUtxosInBlock { block_hash })
×
384
            .await??
×
385
        {
386
            NodeCommsResponse::TransactionOutputs(outputs) => Ok(outputs),
×
387
            _ => Err(CommsInterfaceError::UnexpectedApiResponse),
×
388
        }
389
    }
×
390

391
    /// Fetch mined info by PayRef (Payment Reference)
392
    pub async fn fetch_mined_info_by_payref(&mut self, payref: &FixedHash) -> Result<MinedInfo, CommsInterfaceError> {
×
393
        match self
×
394
            .request_sender
×
395
            .call(NodeCommsRequest::FetchMinedInfoByPayRef(*payref))
×
396
            .await??
×
397
        {
398
            NodeCommsResponse::MinedInfo(mined_info) => Ok(mined_info),
×
399
            _ => Err(CommsInterfaceError::UnexpectedApiResponse),
×
400
        }
401
    }
×
402

403
    /// Fetch mined info by output hash
404
    pub async fn fetch_mined_info_by_output_hash(
×
405
        &mut self,
×
406
        output_hash: &HashOutput,
×
407
    ) -> Result<MinedInfo, CommsInterfaceError> {
×
408
        match self
×
409
            .request_sender
×
410
            .call(NodeCommsRequest::FetchMinedInfoByOutputHash(*output_hash))
×
411
            .await??
×
412
        {
413
            NodeCommsResponse::MinedInfo(mined_info) => Ok(mined_info),
×
414
            _ => Err(CommsInterfaceError::UnexpectedApiResponse),
×
415
        }
416
    }
×
417

418
    /// Fetch output mined info by output hash
419
    pub async fn fetch_output_mined_info(
×
420
        &mut self,
×
421
        output_hash: &HashOutput,
×
422
    ) -> Result<Option<OutputMinedInfo>, CommsInterfaceError> {
×
423
        match self
×
424
            .request_sender
×
425
            .call(NodeCommsRequest::FetchOutputMinedInfo(*output_hash))
×
426
            .await??
×
427
        {
428
            NodeCommsResponse::OutputMinedInfo(output_info) => Ok(output_info),
×
429
            _ => Err(CommsInterfaceError::UnexpectedApiResponse),
×
430
        }
431
    }
×
432

433
    /// Check if an output is spent and return spent information
434
    pub async fn check_output_spent_status(
×
435
        &mut self,
×
436
        output_hash: HashOutput,
×
437
    ) -> Result<Option<InputMinedInfo>, CommsInterfaceError> {
×
438
        match self
×
439
            .request_sender
×
440
            .call(NodeCommsRequest::CheckOutputSpentStatus(output_hash))
×
441
            .await??
×
442
        {
443
            NodeCommsResponse::InputMinedInfo(input_info) => Ok(input_info),
×
444
            _ => Err(CommsInterfaceError::UnexpectedApiResponse),
×
445
        }
446
    }
×
447
}
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