Skip to main content

tycho_control/
proto.rs

1use std::net::SocketAddr;
2use std::num::{NonZeroU32, NonZeroU64};
3
4use bytes::Bytes;
5use serde::{Deserialize, Serialize};
6use tycho_types::models::{
7    BlockId, BlockIdShort, BlockchainConfig, GlobalVersion, ShardAccount, StdAddr,
8};
9use tycho_types::prelude::*;
10use tycho_util::{FastHashSet, serde_helpers};
11
12use crate::error::ServerResult;
13
14#[tarpc::service]
15pub trait ControlServer {
16    /// Ping a node. Returns node timestamp in milliseconds.
17    async fn ping() -> u64;
18
19    /// Get node status.
20    async fn get_status() -> ServerResult<NodeStatusResponse>;
21
22    /// Trigger manual GC for archives.
23    async fn trigger_archives_gc(req: TriggerGcRequest);
24
25    /// Trigger manual GC for blocks.
26    async fn trigger_blocks_gc(req: TriggerGcRequest);
27
28    /// Trigger manual GC for states.
29    async fn trigger_states_gc(req: TriggerGcRequest);
30
31    /// Trigger manual compaction.
32    async fn trigger_compaction(req: TriggerCompactionRequest);
33
34    /// Sets memory profiler state. Returns whether the state was changed.
35    async fn set_memory_profiler_enabled(enabled: bool) -> bool;
36
37    /// Returns memory profiler dump.
38    async fn dump_memory_profiler() -> ServerResult<Vec<u8>>;
39
40    /// Get node neighbours info
41    async fn get_neighbours_info() -> ServerResult<NeighboursInfoResponse>;
42
43    /// Broadcast a message to validators.
44    async fn broadcast_external_message(req: BroadcastExtMsgRequest) -> ServerResult<()>;
45
46    /// Get account state.
47    async fn get_account_state(req: AccountStateRequest) -> ServerResult<AccountStateResponse>;
48
49    /// Get blockchain config.
50    async fn get_blockchain_config() -> ServerResult<BlockchainConfigResponse>;
51
52    /// Get block bytes
53    async fn get_block(req: BlockRequest) -> ServerResult<BlockResponse>;
54
55    /// Get proof bytes.
56    async fn get_block_proof(req: BlockRequest) -> ServerResult<BlockResponse>;
57
58    /// Get queue bytes.
59    async fn get_queue_diff(req: BlockRequest) -> ServerResult<BlockResponse>;
60
61    /// Get archive id
62    async fn get_archive_info(req: ArchiveInfoRequest) -> ServerResult<ArchiveInfoResponse>;
63
64    /// Download archive slice.
65    async fn get_archive_chunk(req: ArchiveSliceRequest) -> ServerResult<ArchiveSliceResponse>;
66
67    /// Returns list of all archive ids.
68    async fn get_archive_ids() -> ServerResult<Vec<ArchiveInfo>>;
69
70    /// Returns list of all block ids.
71    async fn get_block_ids(req: BlockListRequest) -> ServerResult<BlockListResponse>;
72
73    /// Returns list of all overlays.
74    async fn get_overlay_ids() -> ServerResult<OverlayIdsResponse>;
75
76    /// Get overlay peers.
77    async fn get_overlay_peers(req: OverlayPeersRequest) -> ServerResult<OverlayPeersResponse>;
78
79    /// Search for `k` closest nodes known to `peer_id` that store `key`.
80    async fn dht_find_node(req: DhtFindNodeRequest) -> ServerResult<DhtFindNodeResponse>;
81
82    /// Signs an elections payload.
83    async fn sign_elections_payload(
84        req: ElectionsPayloadRequest,
85    ) -> ServerResult<ElectionsPayloadResponse>;
86}
87
88#[derive(Debug, Clone, Serialize, Deserialize)]
89pub struct NodeStatusResponse {
90    pub status_at: u32,
91    pub node_info: NodeInfo,
92    pub init_block_id: Option<BlockId>,
93    pub last_applied_block: Option<LastAppliedBlock>,
94    pub validator_status: Option<ValidatorStatus>,
95}
96
97#[derive(Debug, Clone, Serialize, Deserialize)]
98pub struct NodeInfo {
99    pub version: String,
100    pub build: String,
101
102    // TODO: Somehow expose tycho_network::Address?
103    pub public_addr: String,
104    pub local_addr: SocketAddr,
105    pub adnl_id: HashBytes,
106    pub collator: Option<CollatorInfo>,
107}
108
109#[derive(Debug, Clone, Serialize, Deserialize)]
110pub struct LastAppliedBlock {
111    pub block_id: BlockId,
112    pub gen_utime: u32,
113}
114
115#[derive(Debug, Clone, Serialize, Deserialize)]
116pub struct ValidatorStatus {
117    pub public_key: HashBytes,
118    pub in_current_vset: bool,
119    pub in_next_vset: bool,
120    pub is_elected: bool,
121}
122
123#[derive(Debug, Clone, Serialize, Deserialize)]
124pub struct CollatorInfo {
125    pub global_version: GlobalVersion,
126}
127
128#[derive(Debug, Clone, Serialize, Deserialize)]
129pub enum TriggerGcRequest {
130    Exact(u32),
131    Distance(u32),
132}
133
134#[derive(Debug, Clone, Serialize, Deserialize)]
135pub struct TriggerCompactionRequest {
136    pub database: String,
137}
138
139#[derive(Debug, Clone, Serialize, Deserialize)]
140pub struct BroadcastExtMsgRequest {
141    /// A BOC with a [`Message`].
142    ///
143    /// [`Message`]: tycho_types::models::Message
144    pub message: Bytes,
145}
146
147#[derive(Debug, Clone, Serialize, Deserialize)]
148pub struct AccountStateRequest {
149    pub address: StdAddr,
150}
151
152#[derive(Debug, Clone, Serialize, Deserialize)]
153pub struct AccountStateResponse {
154    pub mc_seqno: u32,
155    pub gen_utime: u32,
156
157    /// A BOC with a [`ShardAccount`].
158    ///
159    /// NOTE: [`BocRepr`] cannot be safely used here because
160    /// we must hold a state tracker handle to delay the GC,
161    /// and it is very inconvenient to pass it around here.
162    pub state: Bytes,
163}
164
165impl AccountStateResponse {
166    pub fn parse(&self) -> Result<ParsedAccountState, tycho_types::boc::BocReprError> {
167        Ok(ParsedAccountState {
168            mc_seqno: self.mc_seqno,
169            gen_utime: self.gen_utime,
170            state: BocRepr::decode(&self.state)?,
171        })
172    }
173}
174
175#[derive(Debug, Clone, Serialize)]
176pub struct ParsedAccountState {
177    pub mc_seqno: u32,
178    pub gen_utime: u32,
179    #[serde(flatten)]
180    pub state: ShardAccount,
181}
182
183#[derive(Debug, Clone, Serialize, Deserialize)]
184pub struct BlockchainConfigResponse {
185    pub global_id: i32,
186    pub mc_seqno: u32,
187    pub gen_utime: u32,
188
189    /// A BOC with a [`BlockchainConfig`].
190    pub config: Bytes,
191}
192
193impl BlockchainConfigResponse {
194    pub fn parse(&self) -> Result<ParsedBlockchainConfigResponse, tycho_types::boc::BocReprError> {
195        Ok(ParsedBlockchainConfigResponse {
196            global_id: self.global_id,
197            mc_seqno: self.mc_seqno,
198            gen_utime: self.gen_utime,
199            config: BocRepr::decode(&self.config)?,
200        })
201    }
202}
203
204#[derive(Debug, Clone, Serialize)]
205pub struct ParsedBlockchainConfigResponse {
206    pub global_id: i32,
207    pub mc_seqno: u32,
208    pub gen_utime: u32,
209    #[serde(flatten)]
210    pub config: BlockchainConfig,
211}
212
213#[derive(Debug, Clone, Serialize, Deserialize)]
214pub struct BlockRequest {
215    pub block_id: BlockId,
216}
217
218#[derive(Debug, Serialize, Deserialize)]
219pub enum BlockResponse {
220    Found { data: Bytes },
221    NotFound,
222}
223
224#[derive(Debug, Clone, Serialize, Deserialize)]
225pub struct ArchiveInfoRequest {
226    pub mc_seqno: u32,
227}
228
229#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
230pub struct ArchiveInfo {
231    pub id: u32,
232    pub size: NonZeroU64,
233    pub chunk_size: NonZeroU32,
234}
235
236#[derive(Debug, Serialize, Deserialize)]
237pub enum ArchiveInfoResponse {
238    Found(ArchiveInfo),
239    TooNew,
240    NotFound,
241}
242
243#[derive(Debug, Clone, Serialize, Deserialize)]
244pub struct ArchiveSliceRequest {
245    pub archive_id: u32,
246    pub offset: u64,
247}
248
249#[derive(Debug, Serialize, Deserialize)]
250pub struct ArchiveSliceResponse {
251    pub data: Bytes,
252}
253
254#[derive(Debug, Serialize, Deserialize)]
255pub struct BlockListRequest {
256    pub continuation: Option<BlockIdShort>,
257}
258
259#[derive(Debug, Serialize, Deserialize)]
260pub struct BlockListResponse {
261    pub blocks: Vec<BlockId>,
262    pub continuation: Option<BlockIdShort>,
263}
264
265#[derive(Debug, Serialize, Deserialize)]
266pub struct ElectionsPayloadRequest {
267    pub election_id: u32,
268    pub address: HashBytes,
269    pub stake_factor: u32,
270    pub public_key: HashBytes,
271    pub adnl_addr: HashBytes,
272    pub signature_id: Option<i32>,
273}
274
275#[derive(Debug, Serialize, Deserialize)]
276pub struct ElectionsPayloadResponse {
277    // TODO: Add `serde(with = "base64")`
278    pub data: Bytes,
279    pub public_key: HashBytes,
280    #[serde(with = "serde_helpers::signature")]
281    pub signature: Box<[u8; 64]>,
282}
283
284#[derive(Debug, Serialize, Deserialize)]
285pub struct NeighboursInfoResponse {
286    pub neighbours: Vec<NeighbourInfo>,
287}
288
289#[derive(Debug, Serialize, Deserialize)]
290pub struct NeighbourInfo {
291    pub id: HashBytes,
292    pub expires_at: u32,
293    pub score: u8,
294    pub failed_requests: u64,
295    pub total_requests: u64,
296    pub roundtrip_ms: u64,
297}
298
299#[derive(Debug, Serialize, Deserialize)]
300pub struct OverlayIdsResponse {
301    pub public_overlays: FastHashSet<HashBytes>,
302    pub private_overlays: FastHashSet<HashBytes>,
303}
304
305#[derive(Debug, Serialize, Deserialize)]
306pub struct OverlayPeersRequest {
307    pub overlay_id: HashBytes,
308}
309
310#[derive(Debug, Serialize, Deserialize)]
311pub struct OverlayPeersResponse {
312    pub overlay_type: OverlayType,
313    pub peers: Vec<OverlayPeer>,
314}
315
316#[derive(Debug, Serialize, Deserialize)]
317pub struct OverlayPeer {
318    pub peer_id: HashBytes,
319    pub entry_created_at: Option<u32>,
320    pub info: Option<PeerInfo>,
321}
322
323#[derive(Debug, Serialize, Deserialize)]
324pub enum OverlayType {
325    Private,
326    Public,
327}
328
329#[derive(Debug, Serialize, Deserialize)]
330pub struct DhtFindNodeRequest {
331    /// Remove peer id or `None` for local.
332    pub peer_id: Option<HashBytes>,
333    pub key: HashBytes,
334    pub k: u32,
335}
336
337#[derive(Debug, Serialize, Deserialize)]
338pub struct DhtFindNodeResponse {
339    pub nodes: Vec<DhtFindNodeResponseItem>,
340}
341
342#[derive(Debug, Serialize, Deserialize)]
343pub struct DhtFindNodeResponseItem {
344    pub peer_id: HashBytes,
345    pub info: PeerInfo,
346}
347
348#[derive(Debug, Serialize, Deserialize)]
349pub struct PeerInfo {
350    pub address_list: Vec<String>,
351    pub created_at: u32,
352    pub expires_at: u32,
353}