1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
//! Signals which can be emitted from within Holochain, out across an interface.
//! There are two main kinds of Signal: system-defined, and app-defined:
//! - App-defined signals are produced via the `emit_signal` host function.
//! - System-defined signals are produced in various places in the system
use crate::app::{InstalledAppId, UnrecoverableCellReason};
use crate::impl_from;
use holochain_serialized_bytes::prelude::*;
use holochain_zome_types::prelude::*;
/// A Signal is some information emitted from within Holochain out through
/// an Interface
#[derive(Clone, Debug, Serialize, Deserialize, SerializedBytes, PartialEq, Eq)]
#[serde(tag = "type", content = "value", rename_all = "snake_case")]
pub enum Signal {
/// Signal from a Cell, generated by `emit_signal`
App {
/// The Cell from which the signal was emitted
cell_id: CellId,
/// The Zome from which the signal was emitted
zome_name: ZomeName,
/// The actual signal that was emitted
signal: AppSignal,
},
/// A direct signal, sent with an app call to `SendDirectSignal`.
AppDirect {
/// The receiving `CellId`.
cell_id: CellId,
/// The payload sent by the remote agent.
signal: Vec<u8>,
},
/// System-defined signals
System(SystemSignal),
}
impl Signal {
/// Parse from vec.
pub fn try_from_vec(v: Vec<u8>) -> Result<Self, SerializedBytesError> {
Self::try_from(SerializedBytes::from(UnsafeBytes::from(v)))
}
}
/// A Signal which originates from within the Holochain system, as opposed to
/// from within a Cell
#[derive(Clone, Debug, Serialize, Deserialize, SerializedBytes, PartialEq, Eq)]
#[serde(tag = "type", content = "value", rename_all = "snake_case")]
pub enum SystemSignal {
/// A countersigning session has successfully completed.
SuccessfulCountersigning(EntryHash),
/// A countersigning session has been abandoned.
AbandonedCountersigning(EntryHash),
/// A single cell within an app has finished restoring its source chain from the DHT.
RestoreComplete {
/// The cell that finished restoring.
cell_id: CellId,
},
/// All cells of an app have finished restoring; the app is now Disabled(NeverStarted).
AppRestoreComplete {
/// The app that finished restoring.
installed_app_id: InstalledAppId,
},
/// A cell's restore hit a permanent failure (e.g. validated ChainIntegrityWarrant). The whole
/// app transitions to [`crate::app::AppStatus::Unrecoverable`] at the same moment.
RestoreFailed {
/// The cell that failed to restore.
cell_id: CellId,
/// Why the restore is unrecoverable.
reason: UnrecoverableCellReason,
},
}
impl_from! {
SystemSignal => Signal, |s| { Self::System(s) },
}
/// The maximum size that Holochain will permit sending or receiving in a single direct signal.
pub const DIRECT_SIGNAL_MAX_SIZE: usize = 1024 * 1024;
/// Wrapper type for transmitting a signed direct signal over the network.
#[derive(Debug, Clone, Serialize, Deserialize, SerializedBytes)]
pub struct DirectSignal(pub Vec<u8>);
#[cfg(test)]
mod tests {
use super::*;
use crate::app::{UnrecoverableCellReason, WarrantSummary};
use ::fixt::prelude::*;
use holo_hash::fixt::*;
#[test]
fn restore_system_signals_serde_round_trip() {
let cell_id = CellId::new(fixt!(DnaHash), fixt!(AgentPubKey));
let summary = WarrantSummary {
author: fixt!(AgentPubKey),
warrantee: fixt!(AgentPubKey),
timestamp: Timestamp::from_micros(1_000_000),
};
let reason = UnrecoverableCellReason::ChainForkWarrant(Box::new(summary));
let signals: Vec<SystemSignal> = vec![
SystemSignal::RestoreComplete {
cell_id: cell_id.clone(),
},
SystemSignal::AppRestoreComplete {
installed_app_id: "my_app".to_string(),
},
SystemSignal::RestoreFailed {
cell_id: cell_id.clone(),
reason: reason.clone(),
},
];
for signal in &signals {
let json = serde_json::to_string(signal).unwrap();
let recovered: SystemSignal = serde_json::from_str(&json).unwrap();
assert_eq!(signal, &recovered);
}
}
}