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

tari-project / tari / 15280118615

27 May 2025 04:01PM UTC coverage: 73.59% (+0.4%) from 73.233%
15280118615

push

github

web-flow
feat: add base node HTTP wallet service (#7061)

Description
---
Added a new HTTP server for base node that exposes some wallet related
query functionality.

Current new endpoints (examples on **esmeralda** network):
 - http://127.0.0.1:9005/get_tip_info
 - http://127.0.0.1:9005/get_header_by_height?height=6994
 - http://127.0.0.1:9005/get_height_at_time?time=1747739959

Default ports for http service (by network):
```
MainNet: 9000,
StageNet: 9001,
NextNet: 9002,
LocalNet: 9003,
Igor: 9004,
Esmeralda: 9005,
```

New configuration needs to be set in base node:
```toml
[base_node.http_wallet_query_service]
port = 9000
external_address = "http://127.0.0.1:9000" # this is optional, but if not set, when someone requests for the external address, just returns a None, so wallets can't contact base node
```

Motivation and Context
---


How Has This Been Tested?
---
### Manually

#### Basic test
1. Build new base node
2. Set base node configuration by adding the following:
```toml
[base_node.http_wallet_query_service]
port = 9000
external_address = "http://127.0.0.1:9000"
```
This way we set the port and external address (which is sent to wallet
client when requesting, so in real world it must be public)
3. Set logging level of base node logs to DEBUG
4. Start base node
5. Build and start console wallet
6. See that it is still able to synchronize
7. Check logs of base node (with `tail -f ...` command for instance) and
see that the HTTP endpoints are used

#### Use RPC fallback test
1. Build new base node
2. Set base node configuration by adding the following:
```toml
[base_node.http_wallet_query_service]
port = 9000
external_address = "http://127.0.0.1:9001"
```
This way we set the port and external address (which is sent to wallet
client when requesting, so in real world it must be public)
3. Set logging level of base node logs to DEBUG
4. Start base node
5. Build and start console wallet
6. See that it is still able to synchronize
7. Check logs of base nod... (continued)

9 of 114 new or added lines in 4 files covered. (7.89%)

1592 existing lines in 62 files now uncovered.

82227 of 111736 relevant lines covered (73.59%)

272070.7 hits per line

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

13.33
/base_layer/core/src/base_node/rpc/mod.rs
1
// Copyright 2025 The Tari Project
2
// SPDX-License-Identifier: BSD-3-Clause
3

4
#[cfg(feature = "base_node")]
5
mod service;
6
#[cfg(feature = "base_node")]
7
pub mod sync_utxos_by_block_task;
8

9
pub mod models;
10

11
#[cfg(feature = "base_node")]
12
pub mod query_service;
13

14
use std::{error::Error, fmt::Debug};
15

16
#[cfg(feature = "base_node")]
17
pub use service::BaseNodeWalletRpcService;
18
use tari_comms::protocol::rpc::{Request, Response, RpcStatus, Streaming};
19
use tari_comms_rpc_macros::tari_rpc;
20
#[cfg(feature = "base_node")]
21
use url::Url;
22

23
#[cfg(feature = "base_node")]
24
use crate::base_node::StateMachineHandle;
25
use crate::{
26
    blocks::BlockHeader,
27
    proto,
28
    proto::{
29
        base_node::{
30
            FetchMatchingUtxos,
31
            FetchUtxosResponse,
32
            GetMempoolFeePerGramStatsRequest,
33
            GetMempoolFeePerGramStatsResponse,
34
            GetWalletQueryHttpServiceAddressResponse,
35
            QueryDeletedRequest,
36
            QueryDeletedResponse,
37
            Signatures,
38
            SyncUtxosByBlockRequest,
39
            SyncUtxosByBlockResponse,
40
            TipInfoResponse,
41
            TxQueryBatchResponses,
42
            TxQueryResponse,
43
            TxSubmissionResponse,
44
            UtxoQueryRequest,
45
            UtxoQueryResponses,
46
        },
47
        types::{Signature, Transaction},
48
    },
49
};
50
#[cfg(feature = "base_node")]
51
use crate::{
52
    chain_storage::{async_db::AsyncBlockchainDb, BlockchainBackend},
53
    mempool::service::MempoolHandle,
54
};
55

56
/// Trait that a base node wallet query service must implement.
57
/// Please note that this service is to fetch data, so read-only queries.
58
#[async_trait::async_trait]
59
pub trait BaseNodeWalletQueryService: Send + Sync + 'static {
60
    type Error: Error + 'static;
61

62
    async fn get_tip_info(&self) -> Result<models::TipInfoResponse, Self::Error>;
63

64
    async fn get_header_by_height(&self, height: u64) -> Result<BlockHeader, Self::Error>;
65

66
    async fn get_height_at_time(&self, epoch_time: u64) -> Result<u64, Self::Error>;
67
}
68

69
#[tari_rpc(protocol_name = b"t/bnwallet/1", server_struct = BaseNodeWalletRpcServer, client_struct = BaseNodeWalletRpcClient
349✔
70
)]
349✔
71
pub trait BaseNodeWalletService: Send + Sync + 'static {
72
    #[rpc(method = 1)]
73
    async fn submit_transaction(
74
        &self,
75
        request: Request<Transaction>,
76
    ) -> Result<Response<TxSubmissionResponse>, RpcStatus>;
77

78
    #[rpc(method = 2)]
79
    async fn transaction_query(&self, request: Request<Signature>) -> Result<Response<TxQueryResponse>, RpcStatus>;
80

81
    #[rpc(method = 3)]
82
    async fn transaction_batch_query(
83
        &self,
84
        request: Request<Signatures>,
85
    ) -> Result<Response<TxQueryBatchResponses>, RpcStatus>;
86

87
    #[rpc(method = 4)]
88
    async fn fetch_matching_utxos(
89
        &self,
90
        request: Request<FetchMatchingUtxos>,
91
    ) -> Result<Response<FetchUtxosResponse>, RpcStatus>;
92

93
    #[rpc(method = 5)]
94
    async fn get_tip_info(&self, request: Request<()>) -> Result<Response<TipInfoResponse>, RpcStatus>;
95

96
    #[rpc(method = 6)]
97
    async fn get_header(&self, request: Request<u64>) -> Result<Response<proto::core::BlockHeader>, RpcStatus>;
98

99
    #[rpc(method = 7)]
100
    async fn utxo_query(&self, request: Request<UtxoQueryRequest>) -> Result<Response<UtxoQueryResponses>, RpcStatus>;
101

102
    #[rpc(method = 8)]
103
    async fn query_deleted(
104
        &self,
105
        request: Request<QueryDeletedRequest>,
106
    ) -> Result<Response<QueryDeletedResponse>, RpcStatus>;
107

108
    #[rpc(method = 9)]
109
    async fn get_header_by_height(
110
        &self,
111
        request: Request<u64>,
112
    ) -> Result<Response<proto::core::BlockHeader>, RpcStatus>;
113

114
    #[rpc(method = 10)]
115
    async fn get_height_at_time(&self, request: Request<u64>) -> Result<Response<u64>, RpcStatus>;
116

117
    #[rpc(method = 11)]
118
    async fn sync_utxos_by_block(
119
        &self,
120
        request: Request<SyncUtxosByBlockRequest>,
121
    ) -> Result<Streaming<SyncUtxosByBlockResponse>, RpcStatus>;
122

123
    #[rpc(method = 12)]
124
    async fn get_mempool_fee_per_gram_stats(
125
        &self,
126
        request: Request<GetMempoolFeePerGramStatsRequest>,
127
    ) -> Result<Response<GetMempoolFeePerGramStatsResponse>, RpcStatus>;
128

129
    #[rpc(method = 13)]
130
    async fn get_wallet_query_http_service_address(
131
        &self,
132
        request: Request<()>,
133
    ) -> Result<Response<GetWalletQueryHttpServiceAddressResponse>, RpcStatus>;
134
}
135

136
#[cfg(feature = "base_node")]
137
pub fn create_base_node_wallet_rpc_service<B: BlockchainBackend + 'static>(
×
138
    db: AsyncBlockchainDb<B>,
×
139
    mempool: MempoolHandle,
×
140
    state_machine: StateMachineHandle,
×
NEW
141
    wallet_query_service_address: Option<Url>,
×
142
) -> BaseNodeWalletRpcServer<BaseNodeWalletRpcService<B>> {
×
NEW
143
    BaseNodeWalletRpcServer::new(BaseNodeWalletRpcService::new(
×
NEW
144
        db,
×
NEW
145
        mempool,
×
NEW
146
        state_machine,
×
NEW
147
        wallet_query_service_address,
×
NEW
148
    ))
×
UNCOV
149
}
×
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