Skip to content

Commit

Permalink
Ord for execution indices (#262)
Browse files Browse the repository at this point in the history
Ord for execution indices
  • Loading branch information
asonnino committed May 19, 2022
1 parent ca1a8a3 commit 6288ba4
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 2 deletions.
29 changes: 27 additions & 2 deletions narwhal/executor/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@
use consensus::SequenceNumber;
use serde::{Deserialize, Serialize};

#[cfg(test)]
#[path = "tests/state_tests.rs"]
pub mod state_tests;

/// The state of the subscriber keeping track of the transactions that have already been
/// executed. It ensures we do not process twice the same transaction despite crash-recovery.
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
#[cfg_attr(test, derive(PartialEq, Eq))]
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, Eq)]
pub struct ExecutionIndices {
/// The index of the latest consensus message we processed (used for crash-recovery).
pub next_certificate_index: SequenceNumber,
Expand Down Expand Up @@ -59,3 +62,25 @@ impl ExecutionIndices {
transaction_index == self.next_transaction_index
}
}

impl Ord for ExecutionIndices {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
if self.next_certificate_index == other.next_certificate_index {
if self.next_batch_index == other.next_batch_index {
self.next_transaction_index
.cmp(&other.next_transaction_index)
} else {
self.next_batch_index.cmp(&other.next_batch_index)
}
} else {
self.next_certificate_index
.cmp(&other.next_certificate_index)
}
}
}

impl PartialOrd for ExecutionIndices {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
106 changes: 106 additions & 0 deletions narwhal/executor/src/tests/state_tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// Copyright (c) 2022, Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0
use super::*;

#[test]
fn next_transaction() {
let mut state = ExecutionIndices::default();
state.next(
/* total_batches */ 10, /* total_transactions */ 100,
);
assert_eq!(state.next_certificate_index, 0);
assert_eq!(state.next_batch_index, 0);
assert_eq!(state.next_transaction_index, 1);
}

#[test]
fn next_batch() {
let mut state = ExecutionIndices::default();
state.next(/* total_batches */ 10, /* total_transactions */ 1);
assert_eq!(state.next_certificate_index, 0);
assert_eq!(state.next_batch_index, 1);
assert_eq!(state.next_transaction_index, 0);
}

#[test]
fn next_certificate() {
let mut state = ExecutionIndices::default();
state.next(/* total_batches */ 1, /* total_transactions */ 1);
assert_eq!(state.next_certificate_index, 1);
assert_eq!(state.next_batch_index, 0);
assert_eq!(state.next_transaction_index, 0);
}

#[test]
fn skip_batch() {
let mut state = ExecutionIndices {
next_certificate_index: 1,
next_batch_index: 1,
next_transaction_index: 1,
};
state.skip_batch(/* total_batches */ 10);
assert_eq!(state.next_certificate_index, 1);
assert_eq!(state.next_batch_index, 2);
assert_eq!(state.next_transaction_index, 0);
}

#[test]
fn skip_certificate() {
let mut state = ExecutionIndices {
next_certificate_index: 1,
next_batch_index: 1,
next_transaction_index: 1,
};
state.skip_certificate();
assert_eq!(state.next_certificate_index, 2);
assert_eq!(state.next_batch_index, 0);
assert_eq!(state.next_transaction_index, 0);
}

#[test]
fn order_certificate_index() {
let state_1 = ExecutionIndices {
next_certificate_index: 0,
next_batch_index: 1,
next_transaction_index: 1,
};
let state_2 = ExecutionIndices {
next_certificate_index: 1,
next_batch_index: 0,
next_transaction_index: 0,
};

assert!(state_2 > state_1);
}

#[test]
fn order_batch_index() {
let state_1 = ExecutionIndices {
next_certificate_index: 1,
next_batch_index: 0,
next_transaction_index: 1,
};
let state_2 = ExecutionIndices {
next_certificate_index: 1,
next_batch_index: 1,
next_transaction_index: 0,
};

assert!(state_2 > state_1);
}

#[test]
fn order_transaction_index() {
let state_1 = ExecutionIndices {
next_certificate_index: 1,
next_batch_index: 1,
next_transaction_index: 0,
};
let state_2 = ExecutionIndices {
next_certificate_index: 1,
next_batch_index: 1,
next_transaction_index: 1,
};

assert!(state_2 > state_1);
}

0 comments on commit 6288ba4

Please sign in to comment.