diff --git a/substrate/node/src/service.rs b/substrate/node/src/service.rs
index fcf863ff..c3d570db 100644
--- a/substrate/node/src/service.rs
+++ b/substrate/node/src/service.rs
@@ -1,11 +1,9 @@
 use std::{boxed::Box, sync::Arc, error::Error};
 
-use sp_keystore::SyncCryptoStore;
 use sp_runtime::traits::{Block as BlockTrait};
 use sp_inherents::CreateInherentDataProviders;
 use sp_consensus::DisableProofRecording;
-use sp_api::{BlockId, ProvideRuntimeApi};
-use sp_tendermint::TendermintApi;
+use sp_api::ProvideRuntimeApi;
 
 use sc_executor::{NativeVersion, NativeExecutionDispatch, NativeElseWasmExecutor};
 use sc_transaction_pool::FullPool;
@@ -231,44 +229,23 @@ pub async fn new_full(mut config: Configuration) -> Result<TaskManager, ServiceE
   })?;
 
   if is_authority {
-    let keys = keystore_container.sync_keystore();
-    let key = SyncCryptoStore::sr25519_public_keys(&*keys, sc_tendermint::KEY_TYPE_ID)
-      .get(0)
-      .cloned()
-      .unwrap_or_else(|| {
-        SyncCryptoStore::sr25519_generate_new(&*keys, sc_tendermint::KEY_TYPE_ID, None).unwrap()
-      });
-
-    let mut spawned = false;
-    let mut validators =
-      client.runtime_api().validators(&BlockId::Hash(client.chain_info().finalized_hash)).unwrap();
-    for (i, validator) in validators.drain(..).enumerate() {
-      if validator == key {
-        task_manager.spawn_essential_handle().spawn(
-          "tendermint",
-          None,
-          TendermintAuthority::new(authority).authority(
-            (u16::try_from(i).unwrap(), keystore_container.keystore()),
-            Cidp,
-            sc_basic_authorship::ProposerFactory::new(
-              task_manager.spawn_handle(),
-              client,
-              transaction_pool,
-              registry.as_ref(),
-              telemetry.map(|telemtry| telemtry.handle()),
-            ),
-            network,
-            None,
-          ),
-        );
-        spawned = true;
-        break;
-      }
-    }
-
-    if !spawned {
-      log::warn!("authority role yet not a validator");
-    }
+    task_manager.spawn_essential_handle().spawn(
+      "tendermint",
+      None,
+      TendermintAuthority::new(authority).authority(
+        keystore_container.keystore(),
+        Cidp,
+        sc_basic_authorship::ProposerFactory::new(
+          task_manager.spawn_handle(),
+          client,
+          transaction_pool,
+          registry.as_ref(),
+          telemetry.map(|telemtry| telemtry.handle()),
+        ),
+        network,
+        None,
+      ),
+    );
   }
 
   network_starter.start_network();
diff --git a/substrate/tendermint/client/src/authority/gossip.rs b/substrate/tendermint/client/src/authority/gossip.rs
index 9e1b54ef..fec5c8be 100644
--- a/substrate/tendermint/client/src/authority/gossip.rs
+++ b/substrate/tendermint/client/src/authority/gossip.rs
@@ -13,14 +13,11 @@ use crate::{TendermintValidator, validators::TendermintValidators};
 #[derive(Clone)]
 pub(crate) struct TendermintGossip<T: TendermintValidator> {
   number: Arc<RwLock<u64>>,
-  signature_scheme: Arc<TendermintValidators<T>>,
+  signature_scheme: TendermintValidators<T>,
 }
 
 impl<T: TendermintValidator> TendermintGossip<T> {
-  pub(crate) fn new(
-    number: Arc<RwLock<u64>>,
-    signature_scheme: Arc<TendermintValidators<T>>,
-  ) -> Self {
+  pub(crate) fn new(number: Arc<RwLock<u64>>, signature_scheme: TendermintValidators<T>) -> Self {
     TendermintGossip { number, signature_scheme }
   }
 
diff --git a/substrate/tendermint/client/src/authority/mod.rs b/substrate/tendermint/client/src/authority/mod.rs
index c87c8394..7d910158 100644
--- a/substrate/tendermint/client/src/authority/mod.rs
+++ b/substrate/tendermint/client/src/authority/mod.rs
@@ -34,7 +34,8 @@ use tendermint_machine::{
 };
 
 use crate::{
-  CONSENSUS_ID, PROTOCOL_NAME, TendermintValidator, validators::TendermintValidators,
+  CONSENSUS_ID, PROTOCOL_NAME, TendermintValidator,
+  validators::{TendermintSigner, TendermintValidators},
   tendermint::TendermintImport,
 };
 
@@ -49,6 +50,8 @@ use import_future::ImportFuture;
 // as it's only Authority which implements tendermint_machine::ext::Network. Network has
 // verify_commit provided, and even non-authorities have to verify commits
 struct ActiveAuthority<T: TendermintValidator> {
+  signer: TendermintSigner<T>,
+
   // Block whose gossip is being tracked
   number: Arc<RwLock<u64>>,
   // Outgoing message queue, placed here as the GossipEngine itself can't be
@@ -138,7 +141,7 @@ impl<T: TendermintValidator> TendermintAuthority<T> {
   /// as it will not return until the P2P stack shuts down.
   pub async fn authority(
     mut self,
-    validator: (u16, Arc<dyn CryptoStore>),
+    keys: Arc<dyn CryptoStore>,
     providers: T::CIDP,
     env: T::Environment,
     network: T::Network,
@@ -165,21 +168,21 @@ impl<T: TendermintValidator> TendermintAuthority<T> {
       // Set this struct as active
       *self.import.providers.write().await = Some(providers);
       self.active = Some(ActiveAuthority {
+        signer: TendermintSigner(keys, self.import.validators.clone()),
+
         number: number.clone(),
         gossip_queue: gossip_queue.clone(),
 
         env,
         announce: network,
       });
-      let (validator, keys) = validator;
-      self.import.validators.set_keys(keys).await;
 
       let proposal = self
         .get_proposal(&self.import.client.header(BlockId::Hash(best_hash)).unwrap().unwrap())
         .await;
 
       // We no longer need self, so let TendermintMachine become its owner
-      TendermintMachine::new(self, validator, last, proposal)
+      TendermintMachine::new(self, last, proposal)
     };
 
     // Start receiving messages about the Tendermint process for this block
@@ -248,11 +251,15 @@ impl<T: TendermintValidator> Network for TendermintAuthority<T> {
 
   const BLOCK_TIME: u32 = T::BLOCK_TIME_IN_SECONDS;
 
-  fn signature_scheme(&self) -> Arc<TendermintValidators<T>> {
+  fn signer(&self) -> TendermintSigner<T> {
+    self.active.as_ref().unwrap().signer.clone()
+  }
+
+  fn signature_scheme(&self) -> TendermintValidators<T> {
     self.import.validators.clone()
   }
 
-  fn weights(&self) -> Arc<TendermintValidators<T>> {
+  fn weights(&self) -> TendermintValidators<T> {
     self.import.validators.clone()
   }
 
diff --git a/substrate/tendermint/client/src/tendermint.rs b/substrate/tendermint/client/src/tendermint.rs
index 901c591e..042a6902 100644
--- a/substrate/tendermint/client/src/tendermint.rs
+++ b/substrate/tendermint/client/src/tendermint.rs
@@ -27,7 +27,7 @@ use crate::{
 
 /// Tendermint import handler.
 pub struct TendermintImport<T: TendermintValidator> {
-  pub(crate) validators: Arc<TendermintValidators<T>>,
+  pub(crate) validators: TendermintValidators<T>,
 
   pub(crate) providers: Arc<AsyncRwLock<Option<T::CIDP>>>,
   pub(crate) importing_block: Arc<RwLock<Option<<T::Block as Block>::Hash>>>,
@@ -54,7 +54,7 @@ impl<T: TendermintValidator> Clone for TendermintImport<T> {
 impl<T: TendermintValidator> TendermintImport<T> {
   pub(crate) fn new(client: Arc<T::Client>) -> TendermintImport<T> {
     TendermintImport {
-      validators: Arc::new(TendermintValidators::new(client.clone())),
+      validators: TendermintValidators::new(client.clone()),
 
       providers: Arc::new(AsyncRwLock::new(None)),
       importing_block: Arc::new(RwLock::new(None)),
diff --git a/substrate/tendermint/client/src/validators.rs b/substrate/tendermint/client/src/validators.rs
index c3299506..409733c7 100644
--- a/substrate/tendermint/client/src/validators.rs
+++ b/substrate/tendermint/client/src/validators.rs
@@ -3,8 +3,6 @@ use std::sync::{Arc, RwLock};
 
 use async_trait::async_trait;
 
-use tokio::sync::RwLock as AsyncRwLock;
-
 use sp_core::Decode;
 use sp_application_crypto::{
   RuntimePublic as PublicTrait,
@@ -17,7 +15,7 @@ use sp_api::{BlockId, ProvideRuntimeApi};
 
 use sc_client_api::HeaderBackend;
 
-use tendermint_machine::ext::{BlockNumber, Round, Weights, SignatureScheme};
+use tendermint_machine::ext::{BlockNumber, Round, Weights, Signer, SignatureScheme};
 
 use sp_tendermint::TendermintApi;
 
@@ -82,49 +80,81 @@ impl<T: TendermintClient> Deref for Refresh<T> {
 }
 
 /// Tendermint validators observer, providing data on the active validators.
-pub struct TendermintValidators<T: TendermintClient>(
-  Refresh<T>,
-  Arc<AsyncRwLock<Option<Arc<dyn CryptoStore>>>>,
-);
+pub struct TendermintValidators<T: TendermintClient>(Refresh<T>);
+impl<T: TendermintClient> Clone for TendermintValidators<T> {
+  fn clone(&self) -> Self {
+    Self(Refresh { _refresh: self.0._refresh.clone(), client: self.0.client.clone() })
+  }
+}
 
 impl<T: TendermintClient> TendermintValidators<T> {
   pub(crate) fn new(client: Arc<T::Client>) -> TendermintValidators<T> {
-    TendermintValidators(
-      Refresh {
-        _refresh: Arc::new(RwLock::new(TendermintValidatorsStruct::from_module::<T>(&client))),
-        client,
-      },
-      Arc::new(AsyncRwLock::new(None)),
-    )
+    TendermintValidators(Refresh {
+      _refresh: Arc::new(RwLock::new(TendermintValidatorsStruct::from_module::<T>(&client))),
+      client,
+    })
   }
+}
 
-  pub(crate) async fn set_keys(&self, keys: Arc<dyn CryptoStore>) {
-    *self.1.write().await = Some(keys);
+pub struct TendermintSigner<T: TendermintClient>(
+  pub(crate) Arc<dyn CryptoStore>,
+  pub(crate) TendermintValidators<T>,
+);
+
+impl<T: TendermintClient> Clone for TendermintSigner<T> {
+  fn clone(&self) -> Self {
+    Self(self.0.clone(), self.1.clone())
+  }
+}
+
+impl<T: TendermintClient> TendermintSigner<T> {
+  async fn get_public_key(&self) -> Public {
+    let pubs = self.0.sr25519_public_keys(KEY_TYPE_ID).await;
+    if pubs.is_empty() {
+      self.0.sr25519_generate_new(KEY_TYPE_ID, None).await.unwrap()
+    } else {
+      pubs[0]
+    }
   }
 }
 
 #[async_trait]
+impl<T: TendermintClient> Signer for TendermintSigner<T> {
+  type ValidatorId = u16;
+  type Signature = Signature;
+
+  async fn validator_id(&self) -> u16 {
+    let key = self.get_public_key().await;
+    for (i, k) in (*self.1 .0).read().unwrap().lookup.iter().enumerate() {
+      if k == &key {
+        return u16::try_from(i).unwrap();
+      }
+    }
+    // TODO: Enable switching between being a validator and not being one, likely be returning
+    // Option<u16> here. Non-validators should be able to simply not broadcast when they think
+    // they have messages.
+    panic!("not a validator");
+  }
+
+  async fn sign(&self, msg: &[u8]) -> Signature {
+    Signature::decode(
+      &mut self
+        .0
+        .sign_with(KEY_TYPE_ID, &self.get_public_key().await.into(), msg)
+        .await
+        .unwrap()
+        .unwrap()
+        .as_ref(),
+    )
+    .unwrap()
+  }
+}
+
 impl<T: TendermintClient> SignatureScheme for TendermintValidators<T> {
   type ValidatorId = u16;
   type Signature = Signature;
   type AggregateSignature = Vec<Signature>;
-
-  async fn sign(&self, msg: &[u8]) -> Signature {
-    let read = self.1.read().await;
-    let keys = read.as_ref().unwrap();
-    let key = {
-      let pubs = keys.sr25519_public_keys(KEY_TYPE_ID).await;
-      if pubs.is_empty() {
-        keys.sr25519_generate_new(KEY_TYPE_ID, None).await.unwrap()
-      } else {
-        pubs[0]
-      }
-    };
-    Signature::decode(
-      &mut keys.sign_with(KEY_TYPE_ID, &key.into(), msg).await.unwrap().unwrap().as_ref(),
-    )
-    .unwrap()
-  }
+  type Signer = TendermintSigner<T>;
 
   fn verify(&self, validator: u16, msg: &[u8], sig: &Signature) -> bool {
     self.0.read().unwrap().lookup[usize::try_from(validator).unwrap()].verify(&msg, sig)