1
1
//! Traces progress of protocol execution
2
+ //!
3
+ //! Provides [`Tracer`] trait that can be used to trace progress of ongoing MPC protocol execution.
4
+ //! For instance, it can be implemented to report progress to the end user.
5
+ //!
6
+ //! Out of box, there's [`PerfProfiler`] which can be used to bechmark a protocol.
7
+ //!
8
+ //! ## Usage example
9
+ //! Provide tracer to the protocol builder and obtain results after protocol is completed:
10
+ //!
11
+ //! ```rust,no_run
12
+ //! # use cggmp21::key_share::{Valid, KeyShare};
13
+ //! # type E = cggmp21::supported_curves::Secp256r1;
14
+ //! # type L = cggmp21::security_level::ReasonablySecure;
15
+ //! # fn load_key_share() -> Result<Valid<KeyShare<E, L>>, std::convert::Infallible> { unimplemented!() }
16
+ //! # async fn connect_to_network<M>() -> Result<round_based::MpcParty<M, round_based::simulation::MockedDelivery<M>>, std::convert::Infallible> { unimplemented!() }
17
+ //! # async fn doc() -> Result<(), Box<dyn std::error::Error>> {
18
+ //! use cggmp21::progress::PerfProfiler;
19
+ //!
20
+ //! let mut tracer = PerfProfiler::new();
21
+ //!
22
+ //! let party = connect_to_network().await?;
23
+ //! let key_share = load_key_share()?;
24
+ //! cggmp21::signing(&key_share)
25
+ //! .set_progress_tracer(&mut tracer)
26
+ //! .generate_presignature(&mut rand::rngs::OsRng, party)
27
+ //! .await?;
28
+ //! # Ok(()) }
29
+ //!```
2
30
3
31
use std:: fmt;
4
32
use std:: time:: { Duration , Instant } ;
5
33
6
34
use thiserror:: Error ;
7
35
36
+ /// Traces progress of protocol execution
37
+ ///
38
+ /// See [module level documentation](self) for more details
8
39
pub trait Tracer : Send + Sync {
40
+ /// Traces occurred event
9
41
fn trace_event ( & mut self , event : Event ) ;
10
42
43
+ /// Traces [`Event::ProtocolBegins`] event
11
44
fn protocol_begins ( & mut self ) {
12
45
self . trace_event ( Event :: ProtocolBegins )
13
46
}
47
+ /// Traces [`Event::RoundBegins`] event
14
48
fn round_begins ( & mut self ) {
15
49
self . trace_event ( Event :: RoundBegins { name : None } )
16
50
}
51
+ /// Traces [`Event::RoundBegins`] event
17
52
fn named_round_begins ( & mut self , round_name : & ' static str ) {
18
53
self . trace_event ( Event :: RoundBegins {
19
54
name : Some ( round_name) ,
20
55
} )
21
56
}
57
+ /// Traces [`Event::Stage`] event
22
58
fn stage ( & mut self , stage : & ' static str ) {
23
59
self . trace_event ( Event :: Stage { name : stage } )
24
60
}
61
+ /// Traces [`Event::ReceiveMsgs`] event
25
62
fn receive_msgs ( & mut self ) {
26
63
self . trace_event ( Event :: ReceiveMsgs )
27
64
}
65
+ /// Traces [`Event::MsgsReceived`] event
28
66
fn msgs_received ( & mut self ) {
29
67
self . trace_event ( Event :: MsgsReceived )
30
68
}
69
+ /// Traces [`Event::SendMsg`] event
31
70
fn send_msg ( & mut self ) {
32
71
self . trace_event ( Event :: SendMsg )
33
72
}
73
+ /// Traces [`Event::MsgSent`] event
34
74
fn msg_sent ( & mut self ) {
35
75
self . trace_event ( Event :: MsgSent )
36
76
}
77
+ /// Traces [`Event::ProtocolEnds`] event
37
78
fn protocol_ends ( & mut self ) {
38
79
self . trace_event ( Event :: ProtocolEnds )
39
80
}
40
81
}
41
82
83
+ /// Event occurred during the protocol execution
42
84
#[ derive( Debug , PartialEq , Eq , Copy , Clone ) ]
43
85
pub enum Event {
86
+ /// Protocol begins
87
+ ///
88
+ /// This event is always emitted before any other events
44
89
ProtocolBegins ,
45
90
46
- RoundBegins { name : Option < & ' static str > } ,
47
- Stage { name : & ' static str } ,
48
-
91
+ /// Round begins
92
+ RoundBegins {
93
+ /// Optional name of the round
94
+ name : Option < & ' static str > ,
95
+ } ,
96
+ /// Stage begins
97
+ Stage {
98
+ /// Name of the stage
99
+ name : & ' static str ,
100
+ } ,
101
+
102
+ /// Protocol waits for some messages to be received
49
103
ReceiveMsgs ,
104
+ /// Protocol received messages, round continues
50
105
MsgsReceived ,
51
106
107
+ /// Protocol starts sending a message
52
108
SendMsg ,
109
+ /// Protocol sent a message, round continues
53
110
MsgSent ,
54
111
112
+ /// Protocol completed
55
113
ProtocolEnds ,
56
114
}
57
115
@@ -78,6 +136,11 @@ impl<T: Tracer> Tracer for Option<T> {
78
136
}
79
137
}
80
138
139
+ /// Profiles performance of the protocol
140
+ ///
141
+ /// Implements [`Tracer`] trait so it can be embedded into protocol execution. `PerfProfiler` keeps track of time
142
+ /// passed between each step of protocol. After protocol is completed, you can obtain a [`PerfReport`] via
143
+ /// [`.get_report()`](PerfProfiler::get_report) method that contains all the measurements.
81
144
pub struct PerfProfiler {
82
145
last_timestamp : Option < Instant > ,
83
146
ongoing_stage : Option < usize > ,
@@ -86,29 +149,43 @@ pub struct PerfProfiler {
86
149
error : Option < ProfileError > ,
87
150
}
88
151
152
+ /// Performance report generated by [`PerfProfiler`]
89
153
#[ derive( Debug , Clone ) ]
90
154
pub struct PerfReport {
155
+ /// Duration of setup phase (time after protocol began and before first round started)
91
156
pub setup : Duration ,
157
+ /// Stages of setup phase
92
158
pub setup_stages : Vec < StageDuration > ,
159
+ /// Performance report for each round
93
160
pub rounds : Vec < RoundDuration > ,
94
161
display_io : bool ,
95
162
}
96
163
164
+ /// Performance of specific round (part of [`PerfReport`])
97
165
#[ derive( Debug , Clone ) ]
98
166
pub struct RoundDuration {
167
+ /// Round name (if provided)
99
168
pub round_name : Option < & ' static str > ,
169
+ /// Stages of the round
100
170
pub stages : Vec < StageDuration > ,
171
+ /// Total duration of pure computation performed during the round
101
172
pub computation : Duration ,
173
+ /// Total time we spent during this round on sending messages
102
174
pub sending : Duration ,
175
+ /// Total time we spent during this round on receiving messages
103
176
pub receiving : Duration ,
104
177
}
105
178
179
+ /// Performance of specific stage (part of [`PerfReport`])
106
180
#[ derive( Debug , Clone ) ]
107
181
pub struct StageDuration {
182
+ /// Stage name
108
183
pub name : & ' static str ,
184
+ /// Duration of the stage
109
185
pub duration : Duration ,
110
186
}
111
187
188
+ /// Protocol profiling resulted into error
112
189
#[ derive( Debug , Error , Clone ) ]
113
190
#[ error( "profiler failed to trace protocol: it behaved unexpectedly" ) ]
114
191
pub struct ProfileError (
@@ -118,13 +195,11 @@ pub struct ProfileError(
118
195
) ;
119
196
120
197
#[ derive( Debug , Error , Clone ) ]
121
- pub enum ErrorReason {
198
+ enum ErrorReason {
122
199
#[ error( "protocol has never began" ) ]
123
200
ProtocolNeverBegan ,
124
201
#[ error( "tracing stage or sending/receiving message but round never began" ) ]
125
202
RoundNeverBegan ,
126
- #[ error( "bug: unreachable condition happened" ) ]
127
- Unreachable ,
128
203
#[ error( "stage is ongoing, but it can't be finished with that event: {event:?}" ) ]
129
204
CantFinishStage { event : Event } ,
130
205
}
@@ -140,6 +215,7 @@ impl Tracer for PerfProfiler {
140
215
}
141
216
142
217
impl PerfProfiler {
218
+ /// Constructs new [`PerfProfiler`]
143
219
pub fn new ( ) -> Self {
144
220
Self {
145
221
last_timestamp : None ,
@@ -155,6 +231,9 @@ impl PerfProfiler {
155
231
}
156
232
}
157
233
234
+ /// Obtains a report
235
+ ///
236
+ /// Returns error if protocol behaved unexpectedly
158
237
pub fn get_report ( & self ) -> Result < PerfReport , ProfileError > {
159
238
if let Some ( err) = self . error . clone ( ) {
160
239
Err ( err)
0 commit comments