ckb_jsonrpc_types/alert.rs
1use crate::{Timestamp, Uint32, bytes::JsonBytes};
2use ckb_types::{packed, prelude::*};
3use schemars::JsonSchema;
4use serde::{Deserialize, Serialize};
5
6/// The alert identifier that is used to filter duplicated alerts.
7///
8/// This is a 32-bit unsigned integer type encoded as the 0x-prefixed hex string in JSON. See examples of [Uint32](type.Uint32.html#examples).
9pub type AlertId = Uint32;
10
11/// Alerts are sorted by priority. Greater integers mean higher priorities.
12///
13/// This is a 32-bit unsigned integer type encoded as the 0x-prefixed hex string in JSON. See examples of [Uint32](type.Uint32.html#examples).
14pub type AlertPriority = Uint32;
15
16/// An alert is a message about critical problems to be broadcast to all nodes via the p2p network.
17///
18/// ## Examples
19///
20/// An example in JSON
21///
22/// ```
23/// # serde_json::from_str::<ckb_jsonrpc_types::Alert>(r#"
24/// {
25/// "id": "0x1",
26/// "cancel": "0x0",
27/// "min_version": "0.1.0",
28/// "max_version": "1.0.0",
29/// "priority": "0x1",
30/// "message": "An example alert message!",
31/// "notice_until": "0x24bcca57c00",
32/// "signatures": [
33/// "0xbd07059aa9a3d057da294c2c4d96fa1e67eeb089837c87b523f124239e18e9fc7d11bb95b720478f7f937d073517d0e4eb9a91d12da5c88a05f750362f4c214dd0",
34/// "0x0242ef40bb64fe3189284de91f981b17f4d740c5e24a3fc9b70059db6aa1d198a2e76da4f84ab37549880d116860976e0cf81cd039563c452412076ebffa2e4453"
35/// ]
36/// }
37/// # "#).unwrap();
38/// ```
39#[derive(Clone, Default, Serialize, Deserialize, PartialEq, Eq, Hash, Debug, JsonSchema)]
40pub struct Alert {
41 /// The identifier of the alert. Clients use id to filter duplicated alerts.
42 pub id: AlertId,
43 /// Cancel a previous sent alert.
44 pub cancel: AlertId,
45 /// Optionally set the minimal version of the target clients.
46 ///
47 /// See [Semantic Version](https://semver.org/) about how to specify a version.
48 pub min_version: Option<String>,
49 /// Optionally set the maximal version of the target clients.
50 ///
51 /// See [Semantic Version](https://semver.org/) about how to specify a version.
52 pub max_version: Option<String>,
53 /// Alerts are sorted by priority, highest first.
54 pub priority: AlertPriority,
55 /// The alert is expired after this timestamp.
56 pub notice_until: Timestamp,
57 /// Alert message.
58 pub message: String,
59 /// The list of required signatures.
60 pub signatures: Vec<JsonBytes>,
61}
62
63/// An alert sent by RPC `send_alert`.
64#[derive(Clone, Default, Serialize, Deserialize, PartialEq, Eq, Hash, Debug, JsonSchema)]
65pub struct AlertMessage {
66 /// The unique alert ID.
67 pub id: AlertId,
68 /// Alerts are sorted by priority, highest first.
69 pub priority: AlertPriority,
70 /// The alert is expired after this timestamp.
71 pub notice_until: Timestamp,
72 /// Alert message.
73 pub message: String,
74}
75
76impl From<Alert> for packed::Alert {
77 fn from(json: Alert) -> Self {
78 let Alert {
79 id,
80 cancel,
81 min_version,
82 max_version,
83 priority,
84 notice_until,
85 message,
86 signatures,
87 } = json;
88 let raw = packed::RawAlert::new_builder()
89 .id(id)
90 .cancel(cancel)
91 .min_version(min_version)
92 .max_version(max_version)
93 .priority(priority)
94 .notice_until(notice_until)
95 .message(message)
96 .build();
97 packed::Alert::new_builder()
98 .raw(raw)
99 .signatures(
100 signatures
101 .into_iter()
102 .map(Into::into)
103 .collect::<Vec<packed::Bytes>>(),
104 )
105 .build()
106 }
107}
108
109impl From<packed::Alert> for Alert {
110 fn from(input: packed::Alert) -> Self {
111 let raw = input.raw();
112 Alert {
113 id: raw.id().into(),
114 cancel: raw.cancel().into(),
115 min_version: raw
116 .as_reader()
117 .min_version()
118 .to_opt()
119 .map(|b| unsafe { b.as_utf8_unchecked() }.to_owned()),
120 max_version: raw
121 .as_reader()
122 .max_version()
123 .to_opt()
124 .map(|b| unsafe { b.as_utf8_unchecked() }.to_owned()),
125 priority: raw.priority().into(),
126 notice_until: raw.notice_until().into(),
127 message: unsafe { raw.as_reader().message().as_utf8_unchecked().to_string() },
128 signatures: input.signatures().into_iter().map(Into::into).collect(),
129 }
130 }
131}
132
133impl From<packed::Alert> for AlertMessage {
134 fn from(input: packed::Alert) -> Self {
135 let raw = input.raw();
136 AlertMessage {
137 id: raw.id().into(),
138 priority: raw.priority().into(),
139 notice_until: raw.notice_until().into(),
140 message: unsafe { raw.as_reader().message().as_utf8_unchecked().to_string() },
141 }
142 }
143}