1use async_graphql::SimpleObject;
7use linera_base::{
8 crypto::CryptoHash,
9 data_types::{Amount, ApplicationPermissions},
10 hex,
11 identifiers::{Account, AccountOwner, ApplicationId, ChainId},
12 ownership::{ChainOwnership, TimeoutConfig},
13};
14use linera_execution::{system::AdminOperation, Message, SystemMessage, SystemOperation};
15use serde::{Deserialize, Serialize};
16
17#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, SimpleObject)]
19pub struct TimeoutConfigMetadata {
20 pub fast_round_ms: Option<String>,
22 pub base_timeout_ms: String,
24 pub timeout_increment_ms: String,
26 pub fallback_duration_ms: String,
29}
30
31impl From<&TimeoutConfig> for TimeoutConfigMetadata {
32 fn from(config: &TimeoutConfig) -> Self {
33 TimeoutConfigMetadata {
34 fast_round_ms: config
35 .fast_round_duration
36 .map(|d| (d.as_micros() / 1000).to_string()),
37 base_timeout_ms: (config.base_timeout.as_micros() / 1000).to_string(),
38 timeout_increment_ms: (config.timeout_increment.as_micros() / 1000).to_string(),
39 fallback_duration_ms: (config.fallback_duration.as_micros() / 1000).to_string(),
40 }
41 }
42}
43
44#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, SimpleObject)]
46pub struct ChainOwnershipMetadata {
47 pub ownership_json: String,
49}
50
51impl From<&ChainOwnership> for ChainOwnershipMetadata {
52 fn from(ownership: &ChainOwnership) -> Self {
53 ChainOwnershipMetadata {
54 ownership_json: serde_json::to_string(ownership)
57 .unwrap_or_else(|_| format!("{:?}", ownership)),
58 }
59 }
60}
61
62#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, SimpleObject)]
64pub struct ApplicationPermissionsMetadata {
65 pub permissions_json: String,
67}
68
69impl From<&ApplicationPermissions> for ApplicationPermissionsMetadata {
70 fn from(permissions: &ApplicationPermissions) -> Self {
71 ApplicationPermissionsMetadata {
72 permissions_json: serde_json::to_string(permissions)
75 .unwrap_or_else(|_| format!("{:?}", permissions)),
76 }
77 }
78}
79
80#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, SimpleObject)]
82pub struct SystemOperationMetadata {
83 pub system_operation_type: String,
85 pub transfer: Option<TransferOperationMetadata>,
87 pub claim: Option<ClaimOperationMetadata>,
89 pub open_chain: Option<OpenChainOperationMetadata>,
91 pub change_ownership: Option<ChangeOwnershipOperationMetadata>,
93 pub change_application_permissions: Option<ChangeApplicationPermissionsMetadata>,
95 pub admin: Option<AdminOperationMetadata>,
97 pub create_application: Option<CreateApplicationOperationMetadata>,
99 pub publish_data_blob: Option<PublishDataBlobMetadata>,
101 pub verify_blob: Option<VerifyBlobMetadata>,
103 pub publish_module: Option<PublishModuleMetadata>,
105 pub epoch: Option<i32>,
107 pub update_streams: Option<Vec<UpdateStreamMetadata>>,
109}
110
111impl SystemOperationMetadata {
112 fn new(system_operation_type: &str) -> Self {
114 SystemOperationMetadata {
115 system_operation_type: system_operation_type.to_string(),
116 transfer: None,
117 claim: None,
118 open_chain: None,
119 change_ownership: None,
120 change_application_permissions: None,
121 admin: None,
122 create_application: None,
123 publish_data_blob: None,
124 verify_blob: None,
125 publish_module: None,
126 epoch: None,
127 update_streams: None,
128 }
129 }
130}
131
132#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, SimpleObject)]
134pub struct TransferOperationMetadata {
135 pub owner: AccountOwner,
136 pub recipient: Account,
137 pub amount: Amount,
138}
139
140#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, SimpleObject)]
142pub struct ClaimOperationMetadata {
143 pub owner: AccountOwner,
144 pub target_id: ChainId,
145 pub recipient: Account,
146 pub amount: Amount,
147}
148
149#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, SimpleObject)]
151pub struct OpenChainOperationMetadata {
152 pub balance: Amount,
153 pub ownership: ChainOwnershipMetadata,
154 pub application_permissions: ApplicationPermissionsMetadata,
155}
156
157#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, SimpleObject)]
159pub struct ChangeOwnershipOperationMetadata {
160 pub super_owners: Vec<AccountOwner>,
161 pub owners: Vec<OwnerWithWeight>,
162 pub multi_leader_rounds: i32,
163 pub open_multi_leader_rounds: bool,
164 pub timeout_config: TimeoutConfigMetadata,
165}
166
167#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, SimpleObject)]
169pub struct OwnerWithWeight {
170 pub owner: AccountOwner,
171 pub weight: String, }
173
174#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, SimpleObject)]
176pub struct ChangeApplicationPermissionsMetadata {
177 pub permissions: ApplicationPermissionsMetadata,
178}
179
180#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, SimpleObject)]
182pub struct AdminOperationMetadata {
183 pub admin_operation_type: String,
184 pub epoch: Option<i32>,
185 pub blob_hash: Option<CryptoHash>,
186}
187
188#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, SimpleObject)]
190pub struct CreateApplicationOperationMetadata {
191 pub module_id: String,
192 pub parameters_hex: String,
193 pub instantiation_argument_hex: String,
194 pub required_application_ids: Vec<ApplicationId>,
195}
196
197#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, SimpleObject)]
199pub struct PublishDataBlobMetadata {
200 pub blob_hash: CryptoHash,
201}
202
203#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, SimpleObject)]
205pub struct VerifyBlobMetadata {
206 pub blob_id: String,
207}
208
209#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, SimpleObject)]
211pub struct PublishModuleMetadata {
212 pub module_id: String,
213}
214
215#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, SimpleObject)]
217pub struct UpdateStreamMetadata {
218 pub chain_id: ChainId,
219 pub stream_id: String,
220 pub next_index: i32,
221}
222
223#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, SimpleObject)]
225pub struct SystemMessageMetadata {
226 pub system_message_type: String,
228 pub credit: Option<CreditMessageMetadata>,
230 pub withdraw: Option<WithdrawMessageMetadata>,
232}
233
234#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, SimpleObject)]
236pub struct CreditMessageMetadata {
237 pub target: AccountOwner,
238 pub amount: Amount,
239 pub source: AccountOwner,
240}
241
242#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, SimpleObject)]
244pub struct WithdrawMessageMetadata {
245 pub owner: AccountOwner,
246 pub amount: Amount,
247 pub recipient: Account,
248}
249
250#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, SimpleObject)]
252pub struct MessageMetadata {
253 pub message_type: String,
255 pub application_id: Option<ApplicationId>,
257 pub user_bytes_hex: Option<String>,
259 pub system_message: Option<SystemMessageMetadata>,
261}
262
263impl From<&SystemOperation> for SystemOperationMetadata {
264 fn from(sys_op: &SystemOperation) -> Self {
265 match sys_op {
266 SystemOperation::Transfer {
267 owner,
268 recipient,
269 amount,
270 } => SystemOperationMetadata {
271 transfer: Some(TransferOperationMetadata {
272 owner: *owner,
273 recipient: *recipient,
274 amount: *amount,
275 }),
276 ..SystemOperationMetadata::new("Transfer")
277 },
278 SystemOperation::Claim {
279 owner,
280 target_id,
281 recipient,
282 amount,
283 } => SystemOperationMetadata {
284 claim: Some(ClaimOperationMetadata {
285 owner: *owner,
286 target_id: *target_id,
287 recipient: *recipient,
288 amount: *amount,
289 }),
290 ..SystemOperationMetadata::new("Claim")
291 },
292 SystemOperation::OpenChain(config) => SystemOperationMetadata {
293 open_chain: Some(OpenChainOperationMetadata {
294 balance: config.balance,
295 ownership: ChainOwnershipMetadata::from(&config.ownership),
296 application_permissions: ApplicationPermissionsMetadata::from(
297 &config.application_permissions,
298 ),
299 }),
300 ..SystemOperationMetadata::new("OpenChain")
301 },
302 SystemOperation::CloseChain => SystemOperationMetadata::new("CloseChain"),
303 SystemOperation::ChangeOwnership {
304 super_owners,
305 owners,
306 multi_leader_rounds,
307 open_multi_leader_rounds,
308 timeout_config,
309 } => SystemOperationMetadata {
310 change_ownership: Some(ChangeOwnershipOperationMetadata {
311 super_owners: super_owners.clone(),
312 owners: owners
313 .iter()
314 .map(|(owner, weight)| OwnerWithWeight {
315 owner: *owner,
316 weight: weight.to_string(),
317 })
318 .collect(),
319 multi_leader_rounds: *multi_leader_rounds as i32,
320 open_multi_leader_rounds: *open_multi_leader_rounds,
321 timeout_config: TimeoutConfigMetadata::from(timeout_config),
322 }),
323 ..SystemOperationMetadata::new("ChangeOwnership")
324 },
325 SystemOperation::ChangeApplicationPermissions(permissions) => SystemOperationMetadata {
326 change_application_permissions: Some(ChangeApplicationPermissionsMetadata {
327 permissions: ApplicationPermissionsMetadata::from(permissions),
328 }),
329 ..SystemOperationMetadata::new("ChangeApplicationPermissions")
330 },
331 SystemOperation::Admin(admin_op) => SystemOperationMetadata {
332 admin: Some(AdminOperationMetadata::from(admin_op)),
333 ..SystemOperationMetadata::new("Admin")
334 },
335 SystemOperation::CreateApplication {
336 module_id,
337 parameters,
338 instantiation_argument,
339 required_application_ids,
340 } => SystemOperationMetadata {
341 create_application: Some(CreateApplicationOperationMetadata {
342 module_id: serde_json::to_string(module_id)
343 .unwrap_or_else(|_| format!("{:?}", module_id)),
344 parameters_hex: hex::encode(parameters),
345 instantiation_argument_hex: hex::encode(instantiation_argument),
346 required_application_ids: required_application_ids.clone(),
347 }),
348 ..SystemOperationMetadata::new("CreateApplication")
349 },
350 SystemOperation::PublishDataBlob { blob_hash } => SystemOperationMetadata {
351 publish_data_blob: Some(PublishDataBlobMetadata {
352 blob_hash: *blob_hash,
353 }),
354 ..SystemOperationMetadata::new("PublishDataBlob")
355 },
356 SystemOperation::VerifyBlob { blob_id } => SystemOperationMetadata {
357 verify_blob: Some(VerifyBlobMetadata {
358 blob_id: blob_id.to_string(),
359 }),
360 ..SystemOperationMetadata::new("VerifyBlob")
361 },
362 SystemOperation::PublishModule { module_id } => SystemOperationMetadata {
363 publish_module: Some(PublishModuleMetadata {
364 module_id: serde_json::to_string(module_id)
365 .unwrap_or_else(|_| format!("{:?}", module_id)),
366 }),
367 ..SystemOperationMetadata::new("PublishModule")
368 },
369 SystemOperation::ProcessNewEpoch(epoch) => SystemOperationMetadata {
370 epoch: Some(epoch.0 as i32),
371 ..SystemOperationMetadata::new("ProcessNewEpoch")
372 },
373 SystemOperation::ProcessRemovedEpoch(epoch) => SystemOperationMetadata {
374 epoch: Some(epoch.0 as i32),
375 ..SystemOperationMetadata::new("ProcessRemovedEpoch")
376 },
377 SystemOperation::UpdateStreams(streams) => SystemOperationMetadata {
378 update_streams: Some(
379 streams
380 .iter()
381 .map(|(chain_id, stream_id, next_index)| UpdateStreamMetadata {
382 chain_id: *chain_id,
383 stream_id: stream_id.to_string(),
384 next_index: *next_index as i32,
385 })
386 .collect(),
387 ),
388 ..SystemOperationMetadata::new("UpdateStreams")
389 },
390 }
391 }
392}
393
394impl From<&AdminOperation> for AdminOperationMetadata {
395 fn from(admin_op: &AdminOperation) -> Self {
396 match admin_op {
397 AdminOperation::PublishCommitteeBlob { blob_hash } => AdminOperationMetadata {
398 admin_operation_type: "PublishCommitteeBlob".to_string(),
399 epoch: None,
400 blob_hash: Some(*blob_hash),
401 },
402 AdminOperation::CreateCommittee { epoch, blob_hash } => AdminOperationMetadata {
403 admin_operation_type: "CreateCommittee".to_string(),
404 epoch: Some(epoch.0 as i32),
405 blob_hash: Some(*blob_hash),
406 },
407 AdminOperation::RemoveCommittee { epoch } => AdminOperationMetadata {
408 admin_operation_type: "RemoveCommittee".to_string(),
409 epoch: Some(epoch.0 as i32),
410 blob_hash: None,
411 },
412 }
413 }
414}
415
416impl From<&Message> for MessageMetadata {
417 fn from(message: &Message) -> Self {
418 match message {
419 Message::System(sys_msg) => MessageMetadata {
420 message_type: "System".to_string(),
421 application_id: None,
422 user_bytes_hex: None,
423 system_message: Some(SystemMessageMetadata::from(sys_msg)),
424 },
425 Message::User {
426 application_id,
427 bytes,
428 } => MessageMetadata {
429 message_type: "User".to_string(),
430 application_id: Some(*application_id),
431 user_bytes_hex: Some(hex::encode(bytes)),
432 system_message: None,
433 },
434 }
435 }
436}
437
438impl From<&SystemMessage> for SystemMessageMetadata {
439 fn from(sys_msg: &SystemMessage) -> Self {
440 match sys_msg {
441 SystemMessage::Credit {
442 target,
443 amount,
444 source,
445 } => SystemMessageMetadata {
446 system_message_type: "Credit".to_string(),
447 credit: Some(CreditMessageMetadata {
448 target: *target,
449 amount: *amount,
450 source: *source,
451 }),
452 withdraw: None,
453 },
454 SystemMessage::Withdraw {
455 owner,
456 amount,
457 recipient,
458 } => SystemMessageMetadata {
459 system_message_type: "Withdraw".to_string(),
460 credit: None,
461 withdraw: Some(WithdrawMessageMetadata {
462 owner: *owner,
463 amount: *amount,
464 recipient: *recipient,
465 }),
466 },
467 }
468 }
469}