diff --git a/schedule-update/Cargo.toml b/schedule-update/Cargo.toml
index 40523d6f4506cb09203320e3bd0a806886d56c9b..3d9814a6fd8c5381c20be4da75597e3db89fb0f6 100644
--- a/schedule-update/Cargo.toml
+++ b/schedule-update/Cargo.toml
@@ -20,6 +20,8 @@ sp-io = { version = "2.0.0-alpha.6", default-features = false }
 sp-core = { version = "2.0.0-alpha.6", default-features = false }
 pallet-balances = { version = "2.0.0-alpha.6" }
 
+clear_on_drop = { version = "0.2.3", features = ["no_cc"] }	# https://github.com/paritytech/substrate/issues/4179
+
 [features]
 default = ["std"]
 std = [
diff --git a/utilities/src/lib.rs b/utilities/src/lib.rs
index a99a48489f8d92b83d0efc0432ad9a775cdcd10f..910f9884980bd95e50dada77a56b19baca5d5f65 100644
--- a/utilities/src/lib.rs
+++ b/utilities/src/lib.rs
@@ -2,6 +2,7 @@
 
 pub mod fixed_u128;
 pub mod linked_item;
+pub mod ordered_set;
 
 pub use fixed_u128::FixedU128;
 pub use linked_item::{LinkedItem, LinkedList};
diff --git a/utilities/src/ordered_set.rs b/utilities/src/ordered_set.rs
new file mode 100644
index 0000000000000000000000000000000000000000..56ec86616f8337a10573b17c5aa686a45b52fd13
--- /dev/null
+++ b/utilities/src/ordered_set.rs
@@ -0,0 +1,131 @@
+use codec::{Decode, Encode};
+use sp_runtime::RuntimeDebug;
+use sp_std::prelude::*;
+
+#[derive(RuntimeDebug, PartialEq, Eq, Encode, Decode, Default)]
+pub struct OrderedSet<T>(Vec<T>);
+
+impl<T: Ord> OrderedSet<T> {
+	pub fn new() -> Self {
+		Self(Vec::new())
+	}
+
+	pub fn from(mut v: Vec<T>) -> Self {
+		v.sort();
+		v.dedup();
+		Self::from_sorted_set(v)
+	}
+
+	/// Assume v is sorted and contain unique elements
+	pub fn from_sorted_set(v: Vec<T>) -> Self {
+		Self(v)
+	}
+
+	pub fn insert(&mut self, value: T) -> bool {
+		match self.0.binary_search(&value) {
+			Ok(_) => false,
+			Err(loc) => {
+				self.0.insert(loc, value);
+				true
+			}
+		}
+	}
+
+	pub fn remove(&mut self, value: &T) -> bool {
+		match self.0.binary_search(&value) {
+			Ok(loc) => {
+				self.0.remove(loc);
+				true
+			}
+			Err(_) => false,
+		}
+	}
+
+	pub fn contains(&self, value: &T) -> bool {
+		self.0.binary_search(&value).is_ok()
+	}
+
+	pub fn clear(&mut self) {
+		self.0.clear();
+	}
+}
+
+impl<T: Ord> From<Vec<T>> for OrderedSet<T> {
+	fn from(v: Vec<T>) -> Self {
+		Self::from(v)
+	}
+}
+
+#[cfg(test)]
+mod tests {
+	use super::*;
+
+	#[test]
+	fn from() {
+		let v = vec![4, 2, 3, 4, 3, 1];
+		let set: OrderedSet<i32> = v.into();
+		assert_eq!(set, OrderedSet::from(vec![1, 2, 3, 4]));
+	}
+
+	#[test]
+	fn insert() {
+		let mut set: OrderedSet<i32> = OrderedSet::new();
+		assert_eq!(set, OrderedSet::from(vec![]));
+
+		assert_eq!(set.insert(1), true);
+		assert_eq!(set, OrderedSet::from(vec![1]));
+
+		assert_eq!(set.insert(5), true);
+		assert_eq!(set, OrderedSet::from(vec![1, 5]));
+
+		assert_eq!(set.insert(3), true);
+		assert_eq!(set, OrderedSet::from(vec![1, 3, 5]));
+
+		assert_eq!(set.insert(3), false);
+		assert_eq!(set, OrderedSet::from(vec![1, 3, 5]));
+	}
+
+	#[test]
+	fn remove() {
+		let mut set: OrderedSet<i32> = OrderedSet::from(vec![1, 2, 3, 4]);
+
+		assert_eq!(set.remove(&5), false);
+		assert_eq!(set, OrderedSet::from(vec![1, 2, 3, 4]));
+
+		assert_eq!(set.remove(&1), true);
+		assert_eq!(set, OrderedSet::from(vec![2, 3, 4]));
+
+		assert_eq!(set.remove(&3), true);
+		assert_eq!(set, OrderedSet::from(vec![2, 4]));
+
+		assert_eq!(set.remove(&3), false);
+		assert_eq!(set, OrderedSet::from(vec![2, 4]));
+
+		assert_eq!(set.remove(&4), true);
+		assert_eq!(set, OrderedSet::from(vec![2]));
+
+		assert_eq!(set.remove(&2), true);
+		assert_eq!(set, OrderedSet::from(vec![]));
+
+		assert_eq!(set.remove(&2), false);
+		assert_eq!(set, OrderedSet::from(vec![]));
+	}
+
+	#[test]
+	fn contains() {
+		let set: OrderedSet<i32> = OrderedSet::from(vec![1, 2, 3, 4]);
+
+		assert_eq!(set.contains(&5), false);
+
+		assert_eq!(set.contains(&1), true);
+
+		assert_eq!(set.contains(&3), true);
+	}
+
+	#[test]
+	fn clear() {
+		let mut set: OrderedSet<i32> = OrderedSet::from(vec![1, 2, 3, 4]);
+		set.clear();
+		assert_eq!(set, OrderedSet::new());
+	}
+}