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 global_id: i32,
273    pub capabilities: u64,
274}
275
276#[derive(Debug, Serialize, Deserialize)]
277pub struct ElectionsPayloadResponse {
278    // TODO: Add `serde(with = "base64")`
279    pub data: Bytes,
280    pub public_key: HashBytes,
281    #[serde(with = "serde_helpers::signature")]
282    pub signature: Box<[u8; 64]>,
283}
284
285#[derive(Debug, Serialize, Deserialize)]
286pub struct NeighboursInfoResponse {
287    pub neighbours: Vec<NeighbourInfo>,
288}
289
290#[derive(Debug, Serialize, Deserialize)]
291pub struct NeighbourInfo {
292    pub id: HashBytes,
293    pub expires_at: u32,
294    pub score: u8,
295    pub failed_requests: u64,
296    pub total_requests: u64,
297    pub roundtrip_ms: u64,
298}
299
300#[derive(Debug, Serialize, Deserialize)]
301pub struct OverlayIdsResponse {
302    pub public_overlays: FastHashSet<HashBytes>,
303    pub private_overlays: FastHashSet<HashBytes>,
304}
305
306#[derive(Debug, Serialize, Deserialize)]
307pub struct OverlayPeersRequest {
308    pub overlay_id: HashBytes,
309}
310
311#[derive(Debug, Serialize, Deserialize)]
312pub struct OverlayPeersResponse {
313    pub overlay_type: OverlayType,
314    pub peers: Vec<OverlayPeer>,
315}
316
317#[derive(Debug, Serialize, Deserialize)]
318pub struct OverlayPeer {
319    pub peer_id: HashBytes,
320    pub entry_created_at: Option<u32>,
321    pub info: Option<PeerInfo>,
322}
323
324#[derive(Debug, Serialize, Deserialize)]
325pub enum OverlayType {
326    Private,
327    Public,
328}
329
330#[derive(Debug, Serialize, Deserialize)]
331pub struct DhtFindNodeRequest {
332    /// Remove peer id or `None` for local.
333    pub peer_id: Option<HashBytes>,
334    pub key: HashBytes,
335    pub k: u32,
336}
337
338#[derive(Debug, Serialize, Deserialize)]
339pub struct DhtFindNodeResponse {
340    pub nodes: Vec<DhtFindNodeResponseItem>,
341}
342
343#[derive(Debug, Serialize, Deserialize)]
344pub struct DhtFindNodeResponseItem {
345    pub peer_id: HashBytes,
346    pub info: PeerInfo,
347}
348
349#[derive(Debug, Serialize, Deserialize)]
350pub struct PeerInfo {
351    pub address_list: Vec<String>,
352    pub created_at: u32,
353    pub expires_at: u32,
354}