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 first_leader: Option<AccountOwner>,
163 pub multi_leader_rounds: i32,
164 pub open_multi_leader_rounds: bool,
165 pub timeout_config: TimeoutConfigMetadata,
166}
167
168#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, SimpleObject)]
170pub struct OwnerWithWeight {
171 pub owner: AccountOwner,
172 pub weight: String, }
174
175#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, SimpleObject)]
177pub struct ChangeApplicationPermissionsMetadata {
178 pub permissions: ApplicationPermissionsMetadata,
179}
180
181#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, SimpleObject)]
183pub struct AdminOperationMetadata {
184 pub admin_operation_type: String,
185 pub epoch: Option<i32>,
186 pub blob_hash: Option<CryptoHash>,
187}
188
189#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, SimpleObject)]
191pub struct CreateApplicationOperationMetadata {
192 pub module_id: String,
193 pub parameters_hex: String,
194 pub instantiation_argument_hex: String,
195 pub required_application_ids: Vec<ApplicationId>,
196}
197
198#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, SimpleObject)]
200pub struct PublishDataBlobMetadata {
201 pub blob_hash: CryptoHash,
202}
203
204#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, SimpleObject)]
206pub struct VerifyBlobMetadata {
207 pub blob_id: String,
208}
209
210#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, SimpleObject)]
212pub struct PublishModuleMetadata {
213 pub module_id: String,
214}
215
216#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, SimpleObject)]
218pub struct UpdateStreamMetadata {
219 pub chain_id: ChainId,
220 pub stream_id: String,
221 pub next_index: i32,
222}
223
224#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, SimpleObject)]
226pub struct SystemMessageMetadata {
227 pub system_message_type: String,
229 pub credit: Option<CreditMessageMetadata>,
231 pub withdraw: Option<WithdrawMessageMetadata>,
233}
234
235#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, SimpleObject)]
237pub struct CreditMessageMetadata {
238 pub target: AccountOwner,
239 pub amount: Amount,
240 pub source: AccountOwner,
241}
242
243#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, SimpleObject)]
245pub struct WithdrawMessageMetadata {
246 pub owner: AccountOwner,
247 pub amount: Amount,
248 pub recipient: Account,
249}
250
251#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, SimpleObject)]
253pub struct MessageMetadata {
254 pub message_type: String,
256 pub application_id: Option<ApplicationId>,
258 pub user_bytes_hex: Option<String>,
260 pub system_message: Option<SystemMessageMetadata>,
262}
263
264impl From<&SystemOperation> for SystemOperationMetadata {
265 fn from(sys_op: &SystemOperation) -> Self {
266 match sys_op {
267 SystemOperation::Transfer {
268 owner,
269 recipient,
270 amount,
271 } => SystemOperationMetadata {
272 transfer: Some(TransferOperationMetadata {
273 owner: *owner,
274 recipient: *recipient,
275 amount: *amount,
276 }),
277 ..SystemOperationMetadata::new("Transfer")
278 },
279 SystemOperation::Claim {
280 owner,
281 target_id,
282 recipient,
283 amount,
284 } => SystemOperationMetadata {
285 claim: Some(ClaimOperationMetadata {
286 owner: *owner,
287 target_id: *target_id,
288 recipient: *recipient,
289 amount: *amount,
290 }),
291 ..SystemOperationMetadata::new("Claim")
292 },
293 SystemOperation::OpenChain(config) => SystemOperationMetadata {
294 open_chain: Some(OpenChainOperationMetadata {
295 balance: config.balance,
296 ownership: ChainOwnershipMetadata::from(&config.ownership),
297 application_permissions: ApplicationPermissionsMetadata::from(
298 &config.application_permissions,
299 ),
300 }),
301 ..SystemOperationMetadata::new("OpenChain")
302 },
303 SystemOperation::CloseChain => SystemOperationMetadata::new("CloseChain"),
304 SystemOperation::ChangeOwnership {
305 super_owners,
306 owners,
307 first_leader,
308 multi_leader_rounds,
309 open_multi_leader_rounds,
310 timeout_config,
311 } => SystemOperationMetadata {
312 change_ownership: Some(ChangeOwnershipOperationMetadata {
313 super_owners: super_owners.clone(),
314 owners: owners
315 .iter()
316 .map(|(owner, weight)| OwnerWithWeight {
317 owner: *owner,
318 weight: weight.to_string(),
319 })
320 .collect(),
321 first_leader: *first_leader,
322 multi_leader_rounds: *multi_leader_rounds as i32,
323 open_multi_leader_rounds: *open_multi_leader_rounds,
324 timeout_config: TimeoutConfigMetadata::from(timeout_config),
325 }),
326 ..SystemOperationMetadata::new("ChangeOwnership")
327 },
328 SystemOperation::ChangeApplicationPermissions(permissions) => SystemOperationMetadata {
329 change_application_permissions: Some(ChangeApplicationPermissionsMetadata {
330 permissions: ApplicationPermissionsMetadata::from(permissions),
331 }),
332 ..SystemOperationMetadata::new("ChangeApplicationPermissions")
333 },
334 SystemOperation::Admin(admin_op) => SystemOperationMetadata {
335 admin: Some(AdminOperationMetadata::from(admin_op)),
336 ..SystemOperationMetadata::new("Admin")
337 },
338 SystemOperation::CreateApplication {
339 module_id,
340 parameters,
341 instantiation_argument,
342 required_application_ids,
343 } => SystemOperationMetadata {
344 create_application: Some(CreateApplicationOperationMetadata {
345 module_id: serde_json::to_string(module_id)
346 .unwrap_or_else(|_| format!("{:?}", module_id)),
347 parameters_hex: hex::encode(parameters),
348 instantiation_argument_hex: hex::encode(instantiation_argument),
349 required_application_ids: required_application_ids.clone(),
350 }),
351 ..SystemOperationMetadata::new("CreateApplication")
352 },
353 SystemOperation::PublishDataBlob { blob_hash } => SystemOperationMetadata {
354 publish_data_blob: Some(PublishDataBlobMetadata {
355 blob_hash: *blob_hash,
356 }),
357 ..SystemOperationMetadata::new("PublishDataBlob")
358 },
359 SystemOperation::VerifyBlob { blob_id } => SystemOperationMetadata {
360 verify_blob: Some(VerifyBlobMetadata {
361 blob_id: blob_id.to_string(),
362 }),
363 ..SystemOperationMetadata::new("VerifyBlob")
364 },
365 SystemOperation::PublishModule { module_id } => SystemOperationMetadata {
366 publish_module: Some(PublishModuleMetadata {
367 module_id: serde_json::to_string(module_id)
368 .unwrap_or_else(|_| format!("{:?}", module_id)),
369 }),
370 ..SystemOperationMetadata::new("PublishModule")
371 },
372 SystemOperation::ProcessNewEpoch(epoch) => SystemOperationMetadata {
373 epoch: Some(epoch.0 as i32),
374 ..SystemOperationMetadata::new("ProcessNewEpoch")
375 },
376 SystemOperation::ProcessRemovedEpoch(epoch) => SystemOperationMetadata {
377 epoch: Some(epoch.0 as i32),
378 ..SystemOperationMetadata::new("ProcessRemovedEpoch")
379 },
380 SystemOperation::UpdateStreams(streams) => SystemOperationMetadata {
381 update_streams: Some(
382 streams
383 .iter()
384 .map(|(chain_id, stream_id, next_index)| UpdateStreamMetadata {
385 chain_id: *chain_id,
386 stream_id: stream_id.to_string(),
387 next_index: *next_index as i32,
388 })
389 .collect(),
390 ),
391 ..SystemOperationMetadata::new("UpdateStreams")
392 },
393 }
394 }
395}
396
397impl From<&AdminOperation> for AdminOperationMetadata {
398 fn from(admin_op: &AdminOperation) -> Self {
399 match admin_op {
400 AdminOperation::PublishCommitteeBlob { blob_hash } => AdminOperationMetadata {
401 admin_operation_type: "PublishCommitteeBlob".to_string(),
402 epoch: None,
403 blob_hash: Some(*blob_hash),
404 },
405 AdminOperation::CreateCommittee { epoch, blob_hash } => AdminOperationMetadata {
406 admin_operation_type: "CreateCommittee".to_string(),
407 epoch: Some(epoch.0 as i32),
408 blob_hash: Some(*blob_hash),
409 },
410 AdminOperation::RemoveCommittee { epoch } => AdminOperationMetadata {
411 admin_operation_type: "RemoveCommittee".to_string(),
412 epoch: Some(epoch.0 as i32),
413 blob_hash: None,
414 },
415 }
416 }
417}
418
419impl From<&Message> for MessageMetadata {
420 fn from(message: &Message) -> Self {
421 match message {
422 Message::System(sys_msg) => MessageMetadata {
423 message_type: "System".to_string(),
424 application_id: None,
425 user_bytes_hex: None,
426 system_message: Some(SystemMessageMetadata::from(sys_msg)),
427 },
428 Message::User {
429 application_id,
430 bytes,
431 } => MessageMetadata {
432 message_type: "User".to_string(),
433 application_id: Some(*application_id),
434 user_bytes_hex: Some(hex::encode(bytes)),
435 system_message: None,
436 },
437 }
438 }
439}
440
441impl From<&SystemMessage> for SystemMessageMetadata {
442 fn from(sys_msg: &SystemMessage) -> Self {
443 match sys_msg {
444 SystemMessage::Credit {
445 target,
446 amount,
447 source,
448 } => SystemMessageMetadata {
449 system_message_type: "Credit".to_string(),
450 credit: Some(CreditMessageMetadata {
451 target: *target,
452 amount: *amount,
453 source: *source,
454 }),
455 withdraw: None,
456 },
457 SystemMessage::Withdraw {
458 owner,
459 amount,
460 recipient,
461 } => SystemMessageMetadata {
462 system_message_type: "Withdraw".to_string(),
463 credit: None,
464 withdraw: Some(WithdrawMessageMetadata {
465 owner: *owner,
466 amount: *amount,
467 recipient: *recipient,
468 }),
469 },
470 }
471 }
472}