diff --git a/substrate/demo/runtime/src/dispatch.rs b/substrate/demo/runtime/src/dispatch.rs
index 980025e3ee7ad739aae7d731ba26a9d61b1e1488..bc5a501705dbd3706ca0aced3cc1bc626dca720b 100644
--- a/substrate/demo/runtime/src/dispatch.rs
+++ b/substrate/demo/runtime/src/dispatch.rs
@@ -43,7 +43,7 @@ pub fn enact_proposal(proposal: Proposal) {
 			staking::privileged::force_new_era()
 		}
 		Proposal::DemocracyCancelReferendum(ref_index) => {
-			democracy::privileged::clear_referendum(ref_index)
+			democracy::privileged::cancel_referendum(ref_index)
 		}
 	}
 }
diff --git a/substrate/demo/runtime/src/runtime/council_vote.rs b/substrate/demo/runtime/src/runtime/council_vote.rs
index 86f9ecb612cdfa107de5d2837fded238e67074da..1b568c65808cd8643bf896c74f9e9dcdd03bdf87 100644
--- a/substrate/demo/runtime/src/runtime/council_vote.rs
+++ b/substrate/demo/runtime/src/runtime/council_vote.rs
@@ -190,8 +190,11 @@ pub mod internal {
 	pub fn end_block(now: BlockNumber) {
 		while let Some((proposal, proposal_hash)) = take_proposal_if_expiring_at(now) {
 			let tally = take_tally(&proposal_hash);
-			if let (&Proposal::DemocracyCancelReferendum(ref_index), (_, 0 ,0)) = (&proposal, tally) {
-				democracy::privileged::clear_referendum(ref_index);
+			println!("Executing proposal {:?} {:?}", proposal, tally);
+			if let &Proposal::DemocracyCancelReferendum(ref_index) = &proposal {
+				if let (_, 0, 0) = tally {
+					democracy::privileged::cancel_referendum(ref_index);
+				}
 			} else {
 				if tally.0 > tally.1 + tally.2 {
 					kill_veto_of(&proposal_hash);
@@ -211,7 +214,7 @@ pub mod testing {
 	use runtime_io::{twox_128, TestExternalities};
 	use keyring::Keyring::{Alice, Bob, Charlie};
 	use codec::Joiner;
-	use runtime::council;
+	use runtime::{council, democracy};
 
 	pub fn externalities() -> TestExternalities {
 		let expiry: BlockNumber = 10;
@@ -222,7 +225,8 @@ pub mod testing {
 				(Charlie.into(), expiry)
 			]),
 			twox_128(COOLOFF_PERIOD).to_vec() => vec![].and(&2u64),
-			twox_128(VOTING_PERIOD).to_vec() => vec![].and(&1u64)
+			twox_128(VOTING_PERIOD).to_vec() => vec![].and(&1u64),
+			twox_128(democracy::VOTING_PERIOD).to_vec() => vec![].and(&3u64)
 		];
 		council::testing::externalities()
 			.into_iter().chain(extras.into_iter()).collect()
@@ -264,6 +268,68 @@ mod tests {
 		});
 	}
 
+	#[test]
+	fn referendum_cancellation_should_work_when_unanimous() {
+		with_externalities(&mut new_test_ext(), || {
+			with_env(|e| e.block_number = 1);
+			let proposal = Proposal::StakingSetBondingDuration(42);
+			democracy::privileged::start_referendum(proposal.clone(), VoteThreshold::SuperMajorityApprove);
+			assert_eq!(democracy::active_referendums(), vec![(0, 4, proposal, VoteThreshold::SuperMajorityApprove)]);
+
+			let cancellation = Proposal::DemocracyCancelReferendum(0);
+			let hash = cancellation.blake2_256();
+			public::propose(Alice, &cancellation);
+			public::vote(Bob, &hash, true);
+			public::vote(Charlie, &hash, true);
+			assert_eq!(proposals(), vec![(2, hash)]);
+			internal::end_block(1);
+
+			with_env(|e| e.block_number = 2);
+			internal::end_block(2);
+			assert_eq!(democracy::active_referendums(), vec![]);
+			assert_eq!(staking::bonding_duration(), 0);
+		});
+	}
+
+	#[test]
+	fn referendum_cancellation_should_fail_when_not_unanimous() {
+		with_externalities(&mut new_test_ext(), || {
+			with_env(|e| e.block_number = 1);
+			let proposal = Proposal::StakingSetBondingDuration(42);
+			democracy::privileged::start_referendum(proposal.clone(), VoteThreshold::SuperMajorityApprove);
+
+			let cancellation = Proposal::DemocracyCancelReferendum(0);
+			let hash = cancellation.blake2_256();
+			public::propose(Alice, &cancellation);
+			public::vote(Bob, &hash, true);
+			public::vote(Charlie, &hash, false);
+			internal::end_block(1);
+
+			with_env(|e| e.block_number = 2);
+			internal::end_block(2);
+			assert_eq!(democracy::active_referendums(), vec![(0, 4, proposal, VoteThreshold::SuperMajorityApprove)]);
+		});
+	}
+
+	#[test]
+	fn referendum_cancellation_should_fail_when_abstentions() {
+		with_externalities(&mut new_test_ext(), || {
+			with_env(|e| e.block_number = 1);
+			let proposal = Proposal::StakingSetBondingDuration(42);
+			democracy::privileged::start_referendum(proposal.clone(), VoteThreshold::SuperMajorityApprove);
+
+			let cancellation = Proposal::DemocracyCancelReferendum(0);
+			let hash = cancellation.blake2_256();
+			public::propose(Alice, &cancellation);
+			public::vote(Bob, &hash, true);
+			internal::end_block(1);
+
+			with_env(|e| e.block_number = 2);
+			internal::end_block(2);
+			assert_eq!(democracy::active_referendums(), vec![(0, 4, proposal, VoteThreshold::SuperMajorityApprove)]);
+		});
+	}
+
 	#[test]
 	fn veto_should_work() {
 		with_externalities(&mut new_test_ext(), || {
@@ -326,8 +392,7 @@ mod tests {
 			with_env(|e| e.block_number = 4);
 			internal::end_block(4);
 			assert_eq!(proposals().len(), 0);
-			assert_eq!(democracy::active_referendums(), vec![(0, 5, Proposal::StakingSetBondingDuration(42), VoteThreshold::SimpleMajority)]);
-
+			assert_eq!(democracy::active_referendums(), vec![(0, 7, Proposal::StakingSetBondingDuration(42), VoteThreshold::SimpleMajority)]);
 		});
 	}
 
@@ -390,7 +455,7 @@ mod tests {
 			with_env(|e| e.block_number = 2);
 			internal::end_block(2);
 			assert_eq!(proposals().len(), 0);
-			assert_eq!(democracy::active_referendums(), vec![(0, 3, Proposal::StakingSetBondingDuration(42), VoteThreshold::SuperMajorityAgainst)]);
+			assert_eq!(democracy::active_referendums(), vec![(0, 5, Proposal::StakingSetBondingDuration(42), VoteThreshold::SuperMajorityAgainst)]);
 		});
 	}
 
@@ -407,7 +472,7 @@ mod tests {
 			with_env(|e| e.block_number = 2);
 			internal::end_block(2);
 			assert_eq!(proposals().len(), 0);
-			assert_eq!(democracy::active_referendums(), vec![(0, 3, Proposal::StakingSetBondingDuration(42), VoteThreshold::SimpleMajority)]);
+			assert_eq!(democracy::active_referendums(), vec![(0, 5, Proposal::StakingSetBondingDuration(42), VoteThreshold::SimpleMajority)]);
 		});
 	}
 
diff --git a/substrate/demo/runtime/src/runtime/democracy.rs b/substrate/demo/runtime/src/runtime/democracy.rs
index 31486149996a3ca3054e840c9824442a6654a469..c7cd152f61b48410cf1c7eb63c836470ff9b542d 100644
--- a/substrate/demo/runtime/src/runtime/democracy.rs
+++ b/substrate/demo/runtime/src/runtime/democracy.rs
@@ -233,11 +233,8 @@ pub mod privileged {
 	}
 
 	/// Remove a referendum.
-	pub fn clear_referendum(ref_index: ReferendumIndex) {
-		for v in voters_for(ref_index) {
-			storage::kill(&(v, ref_index).to_keyed_vec(VOTE_OF));
-		}
-		storage::kill(&ref_index.to_keyed_vec(VOTERS_FOR));
+	pub fn cancel_referendum(ref_index: ReferendumIndex) {
+		clear_referendum(ref_index);
 	}
 }
 
@@ -247,9 +244,7 @@ pub mod internal {
 	use dispatch::enact_proposal;
 
 	/// Current era is ending; we should finish up any proposals.
-	pub fn end_block() {
-		let now = system::block_number();
-
+	pub fn end_block(now: BlockNumber) {
 		// pick out another public referendum if it's time.
 		if now % launch_period() == 0 {
 			let mut public_props = public_props();
@@ -274,7 +269,7 @@ pub mod internal {
 		for (index, _, proposal, vote_threshold) in maturing_referendums_at(now) {
 			let (approve, against) = tally(index);
 			let total_stake = staking::total_stake();
-			privileged::clear_referendum(index);
+			clear_referendum(index);
 			if vote_threshold.approved(approve, against, total_stake) {
 				enact_proposal(proposal);
 			}
@@ -299,6 +294,15 @@ fn inject_referendum(
 	ref_index
 }
 
+/// Remove all info on a referendum.
+fn clear_referendum(ref_index: ReferendumIndex) {
+	storage::kill(&ref_index.to_keyed_vec(REFERENDUM_INFO_OF));
+	storage::kill(&ref_index.to_keyed_vec(VOTERS_FOR));
+	for v in voters_for(ref_index) {
+		storage::kill(&(v, ref_index).to_keyed_vec(VOTE_OF));
+	}
+}
+
 #[cfg(test)]
 pub mod testing {
 	use super::*;
@@ -399,7 +403,7 @@ mod tests {
 		with_externalities(&mut t, || {
 			with_env(|e| e.block_number = 1);
 			public::propose(&alice, &Proposal::StakingSetSessionsPerEra(2), 1u64);
-			democracy::internal::end_block();
+			democracy::internal::end_block(system::block_number());
 
 			with_env(|e| e.block_number = 2);
 			let r = 0;
@@ -410,7 +414,7 @@ mod tests {
 			assert_eq!(vote_of(&alice, r), Some(true));
 			assert_eq!(tally(r), (10, 0));
 
-			democracy::internal::end_block();
+			democracy::internal::end_block(system::block_number());
 			staking::internal::check_new_era();
 
 			assert_eq!(staking::era_length(), 2u64);
@@ -451,7 +455,7 @@ mod tests {
 			public::second(&eve, 0);
 			public::second(&eve, 0);
 			public::second(&eve, 0);
-			democracy::internal::end_block();
+			democracy::internal::end_block(system::block_number());
 			assert_eq!(staking::balance(&alice), 10u64);
 			assert_eq!(staking::balance(&bob), 20u64);
 			assert_eq!(staking::balance(&eve), 50u64);
@@ -506,23 +510,23 @@ mod tests {
 			public::propose(&alice, &Proposal::StakingSetBondingDuration(2), 2u64);
 			public::propose(&alice, &Proposal::StakingSetBondingDuration(4), 4u64);
 			public::propose(&alice, &Proposal::StakingSetBondingDuration(3), 3u64);
-			democracy::internal::end_block();
+			democracy::internal::end_block(system::block_number());
 
 			with_env(|e| e.block_number = 1);
 			public::vote(&alice, 0, true);
-			democracy::internal::end_block();
+			democracy::internal::end_block(system::block_number());
 			staking::internal::check_new_era();
 			assert_eq!(staking::bonding_duration(), 4u64);
 
 			with_env(|e| e.block_number = 2);
 			public::vote(&alice, 1, true);
-			democracy::internal::end_block();
+			democracy::internal::end_block(system::block_number());
 			staking::internal::check_new_era();
 			assert_eq!(staking::bonding_duration(), 3u64);
 
 			with_env(|e| e.block_number = 3);
 			public::vote(&alice, 2, true);
-			democracy::internal::end_block();
+			democracy::internal::end_block(system::block_number());
 			staking::internal::check_new_era();
 			assert_eq!(staking::bonding_duration(), 2u64);
 		});
@@ -542,13 +546,31 @@ mod tests {
 			assert_eq!(vote_of(&alice, r), Some(true));
 			assert_eq!(tally(r), (10, 0));
 
-			democracy::internal::end_block();
+			democracy::internal::end_block(system::block_number());
 			staking::internal::check_new_era();
 
 			assert_eq!(staking::era_length(), 2u64);
 		});
 	}
 
+	#[test]
+	fn cancel_referendum_should_work() {
+		let alice = Keyring::Alice.to_raw_public();
+		let mut t = new_test_ext();
+
+		with_externalities(&mut t, || {
+			with_env(|e| e.block_number = 1);
+			let r = inject_referendum(1, Proposal::StakingSetSessionsPerEra(2), VoteThreshold::SuperMajorityApprove);
+			public::vote(&alice, r, true);
+			privileged::cancel_referendum(r);
+
+			democracy::internal::end_block(system::block_number());
+			staking::internal::check_new_era();
+
+			assert_eq!(staking::era_length(), 1u64);
+		});
+	}
+
 	#[test]
 	fn simple_failing_should_work() {
 		let alice = Keyring::Alice.to_raw_public();
@@ -563,7 +585,7 @@ mod tests {
 			assert_eq!(vote_of(&alice, r), Some(false));
 			assert_eq!(tally(r), (0, 10));
 
-			democracy::internal::end_block();
+			democracy::internal::end_block(system::block_number());
 			staking::internal::check_new_era();
 
 			assert_eq!(staking::era_length(), 1u64);
@@ -593,7 +615,7 @@ mod tests {
 
 			assert_eq!(tally(r), (110, 100));
 
-			democracy::internal::end_block();
+			democracy::internal::end_block(system::block_number());
 			staking::internal::check_new_era();
 
 			assert_eq!(staking::era_length(), 2u64);
@@ -619,7 +641,7 @@ mod tests {
 
 			assert_eq!(tally(r), (60, 50));
 
-			democracy::internal::end_block();
+			democracy::internal::end_block(system::block_number());
 			staking::internal::check_new_era();
 
 			assert_eq!(staking::era_length(), 1u64);
@@ -649,7 +671,7 @@ mod tests {
 
 			assert_eq!(tally(r), (100, 50));
 
-			democracy::internal::end_block();
+			democracy::internal::end_block(system::block_number());
 			staking::internal::check_new_era();
 
 			assert_eq!(staking::era_length(), 2u64);