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: module_id.to_string(),
343 parameters_hex: hex::encode(parameters),
344 instantiation_argument_hex: hex::encode(instantiation_argument),
345 required_application_ids: required_application_ids.clone(),
346 }),
347 ..SystemOperationMetadata::new("CreateApplication")
348 },
349 SystemOperation::PublishDataBlob { blob_hash } => SystemOperationMetadata {
350 publish_data_blob: Some(PublishDataBlobMetadata {
351 blob_hash: *blob_hash,
352 }),
353 ..SystemOperationMetadata::new("PublishDataBlob")
354 },
355 SystemOperation::VerifyBlob { blob_id } => SystemOperationMetadata {
356 verify_blob: Some(VerifyBlobMetadata {
357 blob_id: blob_id.to_string(),
358 }),
359 ..SystemOperationMetadata::new("VerifyBlob")
360 },
361 SystemOperation::PublishModule { module_id } => SystemOperationMetadata {
362 publish_module: Some(PublishModuleMetadata {
363 module_id: module_id.to_string(),
364 }),
365 ..SystemOperationMetadata::new("PublishModule")
366 },
367 SystemOperation::ProcessNewEpoch(epoch) => SystemOperationMetadata {
368 epoch: Some(epoch.0 as i32),
369 ..SystemOperationMetadata::new("ProcessNewEpoch")
370 },
371 SystemOperation::ProcessRemovedEpoch(epoch) => SystemOperationMetadata {
372 epoch: Some(epoch.0 as i32),
373 ..SystemOperationMetadata::new("ProcessRemovedEpoch")
374 },
375 SystemOperation::UpdateStreams(streams) => SystemOperationMetadata {
376 update_streams: Some(
377 streams
378 .iter()
379 .map(|(chain_id, stream_id, next_index)| UpdateStreamMetadata {
380 chain_id: *chain_id,
381 stream_id: stream_id.to_string(),
382 next_index: *next_index as i32,
383 })
384 .collect(),
385 ),
386 ..SystemOperationMetadata::new("UpdateStreams")
387 },
388 }
389 }
390}
391
392impl From<&AdminOperation> for AdminOperationMetadata {
393 fn from(admin_op: &AdminOperation) -> Self {
394 match admin_op {
395 AdminOperation::PublishCommitteeBlob { blob_hash } => AdminOperationMetadata {
396 admin_operation_type: "PublishCommitteeBlob".to_string(),
397 epoch: None,
398 blob_hash: Some(*blob_hash),
399 },
400 AdminOperation::CreateCommittee { epoch, blob_hash } => AdminOperationMetadata {
401 admin_operation_type: "CreateCommittee".to_string(),
402 epoch: Some(epoch.0 as i32),
403 blob_hash: Some(*blob_hash),
404 },
405 AdminOperation::RemoveCommittee { epoch } => AdminOperationMetadata {
406 admin_operation_type: "RemoveCommittee".to_string(),
407 epoch: Some(epoch.0 as i32),
408 blob_hash: None,
409 },
410 }
411 }
412}
413
414impl From<&Message> for MessageMetadata {
415 fn from(message: &Message) -> Self {
416 match message {
417 Message::System(sys_msg) => MessageMetadata {
418 message_type: "System".to_string(),
419 application_id: None,
420 user_bytes_hex: None,
421 system_message: Some(SystemMessageMetadata::from(sys_msg)),
422 },
423 Message::User {
424 application_id,
425 bytes,
426 } => MessageMetadata {
427 message_type: "User".to_string(),
428 application_id: Some(*application_id),
429 user_bytes_hex: Some(hex::encode(bytes)),
430 system_message: None,
431 },
432 }
433 }
434}
435
436impl From<&SystemMessage> for SystemMessageMetadata {
437 fn from(sys_msg: &SystemMessage) -> Self {
438 match sys_msg {
439 SystemMessage::Credit {
440 target,
441 amount,
442 source,
443 } => SystemMessageMetadata {
444 system_message_type: "Credit".to_string(),
445 credit: Some(CreditMessageMetadata {
446 target: *target,
447 amount: *amount,
448 source: *source,
449 }),
450 withdraw: None,
451 },
452 SystemMessage::Withdraw {
453 owner,
454 amount,
455 recipient,
456 } => SystemMessageMetadata {
457 system_message_type: "Withdraw".to_string(),
458 credit: None,
459 withdraw: Some(WithdrawMessageMetadata {
460 owner: *owner,
461 amount: *amount,
462 recipient: *recipient,
463 }),
464 },
465 }
466 }
467}