pub use alloc::vec::Vec;
use super::{NoteId, RowIndex, TransactionMeasurements};
#[derive(Clone, Debug)]
pub struct TransactionProgress {
prologue: CycleInterval,
notes_processing: CycleInterval,
note_execution: Vec<(NoteId, CycleInterval)>,
tx_script_processing: CycleInterval,
epilogue: CycleInterval,
auth_procedure: CycleInterval,
epilogue_after_tx_cycles_obtained: Option<RowIndex>,
}
impl TransactionProgress {
pub fn new() -> Self {
Self {
prologue: CycleInterval::default(),
notes_processing: CycleInterval::default(),
note_execution: Vec::new(),
tx_script_processing: CycleInterval::default(),
epilogue: CycleInterval::default(),
auth_procedure: CycleInterval::default(),
epilogue_after_tx_cycles_obtained: None,
}
}
pub fn prologue(&self) -> &CycleInterval {
&self.prologue
}
pub fn notes_processing(&self) -> &CycleInterval {
&self.notes_processing
}
pub fn note_execution(&self) -> &Vec<(NoteId, CycleInterval)> {
&self.note_execution
}
pub fn tx_script_processing(&self) -> &CycleInterval {
&self.tx_script_processing
}
pub fn epilogue(&self) -> &CycleInterval {
&self.epilogue
}
pub fn auth_procedure(&self) -> &CycleInterval {
&self.auth_procedure
}
pub fn start_prologue(&mut self, cycle: RowIndex) {
self.prologue.set_start(cycle);
}
pub fn end_prologue(&mut self, cycle: RowIndex) {
self.prologue.set_end(cycle);
}
pub fn start_notes_processing(&mut self, cycle: RowIndex) {
self.notes_processing.set_start(cycle);
}
pub fn end_notes_processing(&mut self, cycle: RowIndex) {
self.notes_processing.set_end(cycle);
}
pub fn start_note_execution(&mut self, cycle: RowIndex, note_id: NoteId) {
self.note_execution.push((note_id, CycleInterval::new(cycle)));
}
pub fn end_note_execution(&mut self, cycle: RowIndex) {
if let Some((_, interval)) = self.note_execution.last_mut() {
interval.set_end(cycle)
}
}
pub fn start_tx_script_processing(&mut self, cycle: RowIndex) {
self.tx_script_processing.set_start(cycle);
}
pub fn end_tx_script_processing(&mut self, cycle: RowIndex) {
self.tx_script_processing.set_end(cycle);
}
pub fn start_epilogue(&mut self, cycle: RowIndex) {
self.epilogue.set_start(cycle);
}
pub fn start_auth_procedure(&mut self, cycle: RowIndex) {
self.auth_procedure.set_start(cycle);
}
pub fn end_auth_procedure(&mut self, cycle: RowIndex) {
self.auth_procedure.set_end(cycle);
}
pub fn epilogue_after_tx_cycles_obtained(&mut self, cycle: RowIndex) {
self.epilogue_after_tx_cycles_obtained = Some(cycle);
}
pub fn end_epilogue(&mut self, cycle: RowIndex) {
self.epilogue.set_end(cycle);
}
}
impl Default for TransactionProgress {
fn default() -> Self {
Self::new()
}
}
impl From<TransactionProgress> for TransactionMeasurements {
fn from(tx_progress: TransactionProgress) -> Self {
let prologue = tx_progress.prologue().len();
let notes_processing = tx_progress.notes_processing().len();
let note_execution = tx_progress
.note_execution()
.iter()
.map(|(note_id, interval)| (*note_id, interval.len()))
.collect();
let tx_script_processing = tx_progress.tx_script_processing().len();
let epilogue = tx_progress.epilogue().len();
let auth_procedure = tx_progress.auth_procedure().len();
let after_tx_cycles_obtained = if let Some(epilogue_after_tx_cycles_obtained) =
tx_progress.epilogue_after_tx_cycles_obtained
{
tx_progress.epilogue().end().expect("epilogue end should be set")
- epilogue_after_tx_cycles_obtained
} else {
0
};
Self {
prologue,
notes_processing,
note_execution,
tx_script_processing,
epilogue,
auth_procedure,
after_tx_cycles_obtained,
}
}
}
#[derive(Clone, Default, Debug)]
pub struct CycleInterval {
start: Option<RowIndex>,
end: Option<RowIndex>,
}
impl CycleInterval {
pub fn new(start: RowIndex) -> Self {
Self { start: Some(start), end: None }
}
pub fn set_start(&mut self, s: RowIndex) {
self.start = Some(s);
}
pub fn set_end(&mut self, e: RowIndex) {
self.end = Some(e);
}
pub fn start(&self) -> Option<RowIndex> {
self.start
}
pub fn end(&self) -> Option<RowIndex> {
self.end
}
pub fn len(&self) -> usize {
if let Some(start) = self.start
&& let Some(end) = self.end
&& end >= start
{
return end - start;
}
0
}
}