Partial work on correcting pallet calls

This commit is contained in:
Luke Parker
2022-10-27 06:29:56 -04:00
parent eb418448eb
commit 4c2dd9b306
7 changed files with 89 additions and 27 deletions

1
Cargo.lock generated
View File

@@ -7419,6 +7419,7 @@ name = "serai-consensus"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"frame-support",
"futures", "futures",
"log", "log",
"pallet-session", "pallet-session",

View File

@@ -38,6 +38,7 @@ sc-service = { git = "https://github.com/serai-dex/substrate" }
sc-client-api = { git = "https://github.com/serai-dex/substrate" } sc-client-api = { git = "https://github.com/serai-dex/substrate" }
sc-consensus = { git = "https://github.com/serai-dex/substrate" } sc-consensus = { git = "https://github.com/serai-dex/substrate" }
frame-support = { git = "https://github.com/serai-dex/substrate" }
pallet-session = { git = "https://github.com/serai-dex/substrate" } pallet-session = { git = "https://github.com/serai-dex/substrate" }
substrate-prometheus-endpoint = { git = "https://github.com/serai-dex/substrate" } substrate-prometheus-endpoint = { git = "https://github.com/serai-dex/substrate" }

View File

@@ -2,6 +2,7 @@ use std::{sync::Arc, collections::HashMap};
use async_trait::async_trait; use async_trait::async_trait;
use sp_core::sr25519::Public;
use sp_inherents::CreateInherentDataProviders; use sp_inherents::CreateInherentDataProviders;
use sp_runtime::traits::Block; use sp_runtime::traits::Block;
use sp_api::TransactionFor; use sp_api::TransactionFor;
@@ -11,6 +12,8 @@ use sc_consensus::{BlockCheckParams, BlockImportParams, ImportResult, BlockImpor
use sc_client_api::Backend; use sc_client_api::Backend;
use frame_support::traits::ValidatorSet;
use crate::{ use crate::{
tendermint::{TendermintClient, TendermintImport}, tendermint::{TendermintClient, TendermintImport},
Announce, Announce,
@@ -29,6 +32,7 @@ where
TransactionFor<C, B>: Send + Sync + 'static, TransactionFor<C, B>: Send + Sync + 'static,
Arc<C>: BlockImport<B, Transaction = TransactionFor<C, B>>, Arc<C>: BlockImport<B, Transaction = TransactionFor<C, B>>,
<Arc<C> as BlockImport<B>>::Error: Into<Error>, <Arc<C> as BlockImport<B>>::Error: Into<Error>,
C::Api: ValidatorSet<Public>,
{ {
type Error = Error; type Error = Error;
type Transaction = TransactionFor<C, B>; type Transaction = TransactionFor<C, B>;

View File

@@ -6,7 +6,7 @@ use std::{
time::{UNIX_EPOCH, SystemTime}, time::{UNIX_EPOCH, SystemTime},
}; };
use sp_core::Decode; use sp_core::{Decode, sr25519::Public};
use sp_inherents::CreateInherentDataProviders; use sp_inherents::CreateInherentDataProviders;
use sp_runtime::traits::{Header, Block}; use sp_runtime::traits::{Header, Block};
use sp_api::{BlockId, TransactionFor}; use sp_api::{BlockId, TransactionFor};
@@ -19,6 +19,8 @@ use sc_client_api::Backend;
use substrate_prometheus_endpoint::Registry; use substrate_prometheus_endpoint::Registry;
use frame_support::traits::ValidatorSet;
use tendermint_machine::{ use tendermint_machine::{
ext::{BlockNumber, Commit}, ext::{BlockNumber, Commit},
TendermintMachine, TendermintMachine,
@@ -98,6 +100,7 @@ where
TransactionFor<C, B>: Send + Sync + 'static, TransactionFor<C, B>: Send + Sync + 'static,
Arc<C>: BlockImport<B, Transaction = TransactionFor<C, B>>, Arc<C>: BlockImport<B, Transaction = TransactionFor<C, B>>,
<Arc<C> as BlockImport<B>>::Error: Into<Error>, <Arc<C> as BlockImport<B>>::Error: Into<Error>,
C::Api: ValidatorSet<Public>,
{ {
let import = TendermintImport::new(client, announce, providers, env); let import = TendermintImport::new(client, announce, providers, env);
@@ -116,7 +119,7 @@ where
Ok(best) => BlockNumber(best), Ok(best) => BlockNumber(best),
Err(_) => panic!("BlockNumber exceeded u64"), Err(_) => panic!("BlockNumber exceeded u64"),
}, },
Commit::<TendermintValidators>::decode( Commit::<TendermintValidators<B, C>>::decode(
&mut import_clone &mut import_clone
.client .client
.justifications(&BlockId::Number(best)) .justifications(&BlockId::Number(best))

View File

@@ -10,8 +10,10 @@ use log::warn;
use tokio::sync::RwLock as AsyncRwLock; use tokio::sync::RwLock as AsyncRwLock;
use sp_core::{Encode, Decode}; use sp_core::{
use sp_application_crypto::sr25519::Signature; Encode, Decode,
sr25519::{Public, Signature},
};
use sp_inherents::{InherentData, InherentDataProvider, CreateInherentDataProviders}; use sp_inherents::{InherentData, InherentDataProvider, CreateInherentDataProviders};
use sp_runtime::{ use sp_runtime::{
traits::{Header, Block}, traits::{Header, Block},
@@ -26,6 +28,8 @@ use sc_consensus::{ForkChoiceStrategy, BlockImportParams, BlockImport, import_qu
use sc_service::ImportQueue; use sc_service::ImportQueue;
use sc_client_api::{BlockBackend, Backend, Finalizer}; use sc_client_api::{BlockBackend, Backend, Finalizer};
use frame_support::traits::ValidatorSet;
use tendermint_machine::{ use tendermint_machine::{
ext::{BlockError, Commit, Network}, ext::{BlockError, Commit, Network},
SignedMessage, TendermintHandle, SignedMessage, TendermintHandle,
@@ -47,6 +51,9 @@ pub trait TendermintClient<B: Block, Be: Backend<B> + 'static>:
+ Finalizer<B, Be> + Finalizer<B, Be>
+ ProvideRuntimeApi<B> + ProvideRuntimeApi<B>
+ 'static + 'static
where
TransactionFor<Self, B>: Send + Sync + 'static,
Self::Api: ValidatorSet<Public>,
{ {
} }
impl< impl<
@@ -61,6 +68,9 @@ impl<
+ ProvideRuntimeApi<B> + ProvideRuntimeApi<B>
+ 'static, + 'static,
> TendermintClient<B, Be> for C > TendermintClient<B, Be> for C
where
TransactionFor<C, B>: Send + Sync + 'static,
C::Api: ValidatorSet<Public>,
{ {
} }
@@ -73,10 +83,13 @@ pub(crate) struct TendermintImport<
A: Announce<B>, A: Announce<B>,
> where > where
TransactionFor<C, B>: Send + Sync + 'static, TransactionFor<C, B>: Send + Sync + 'static,
C::Api: ValidatorSet<Public>,
{ {
_block: PhantomData<B>, _block: PhantomData<B>,
_backend: PhantomData<Be>, _backend: PhantomData<Be>,
validators: Arc<TendermintValidators<B, C>>,
importing_block: Arc<RwLock<Option<B::Hash>>>, importing_block: Arc<RwLock<Option<B::Hash>>>,
pub(crate) machine: Arc<RwLock<Option<TendermintHandle<Self>>>>, pub(crate) machine: Arc<RwLock<Option<TendermintHandle<Self>>>>,
@@ -98,12 +111,15 @@ impl<
> Clone for TendermintImport<B, Be, C, CIDP, E, A> > Clone for TendermintImport<B, Be, C, CIDP, E, A>
where where
TransactionFor<C, B>: Send + Sync + 'static, TransactionFor<C, B>: Send + Sync + 'static,
C::Api: ValidatorSet<Public>,
{ {
fn clone(&self) -> Self { fn clone(&self) -> Self {
TendermintImport { TendermintImport {
_block: PhantomData, _block: PhantomData,
_backend: PhantomData, _backend: PhantomData,
validators: self.validators.clone(),
importing_block: self.importing_block.clone(), importing_block: self.importing_block.clone(),
machine: self.machine.clone(), machine: self.machine.clone(),
@@ -127,6 +143,7 @@ impl<
> TendermintImport<B, Be, C, CIDP, E, A> > TendermintImport<B, Be, C, CIDP, E, A>
where where
TransactionFor<C, B>: Send + Sync + 'static, TransactionFor<C, B>: Send + Sync + 'static,
C::Api: ValidatorSet<Public>,
{ {
pub(crate) fn new( pub(crate) fn new(
client: Arc<C>, client: Arc<C>,
@@ -138,6 +155,8 @@ where
_block: PhantomData, _block: PhantomData,
_backend: PhantomData, _backend: PhantomData,
validators: TendermintValidators::new(client),
importing_block: Arc::new(RwLock::new(None)), importing_block: Arc::new(RwLock::new(None)),
machine: Arc::new(RwLock::new(None)), machine: Arc::new(RwLock::new(None)),
@@ -196,7 +215,7 @@ where
Err(Error::InvalidJustification)?; Err(Error::InvalidJustification)?;
} }
let commit: Commit<TendermintValidators> = let commit: Commit<TendermintValidators<B, C>> =
Commit::decode(&mut justification.1.as_ref()).map_err(|_| Error::InvalidJustification)?; Commit::decode(&mut justification.1.as_ref()).map_err(|_| Error::InvalidJustification)?;
if !self.verify_commit(hash, &commit) { if !self.verify_commit(hash, &commit) {
Err(Error::InvalidJustification)?; Err(Error::InvalidJustification)?;
@@ -309,20 +328,21 @@ impl<
> Network for TendermintImport<B, Be, C, CIDP, E, A> > Network for TendermintImport<B, Be, C, CIDP, E, A>
where where
TransactionFor<C, B>: Send + Sync + 'static, TransactionFor<C, B>: Send + Sync + 'static,
C::Api: ValidatorSet<Public>,
{ {
type ValidatorId = u16; type ValidatorId = u16;
type SignatureScheme = TendermintValidators; type SignatureScheme = TendermintValidators<B, C>;
type Weights = TendermintValidators; type Weights = TendermintValidators<B, C>;
type Block = B; type Block = B;
const BLOCK_TIME: u32 = { (serai_runtime::MILLISECS_PER_BLOCK / 1000) as u32 }; const BLOCK_TIME: u32 = { (serai_runtime::MILLISECS_PER_BLOCK / 1000) as u32 };
fn signature_scheme(&self) -> Arc<TendermintValidators> { fn signature_scheme(&self) -> Arc<TendermintValidators<B, C>> {
Arc::new(TendermintValidators::new()) self.validators.clone()
} }
fn weights(&self) -> Arc<TendermintValidators> { fn weights(&self) -> Arc<TendermintValidators<B, C>> {
Arc::new(TendermintValidators::new()) self.validators.clone()
} }
async fn broadcast(&mut self, msg: SignedMessage<u16, Self::Block, Signature>) { async fn broadcast(&mut self, msg: SignedMessage<u16, Self::Block, Signature>) {
@@ -390,7 +410,7 @@ where
Ok(()) Ok(())
} }
async fn add_block(&mut self, block: B, commit: Commit<TendermintValidators>) -> B { async fn add_block(&mut self, block: B, commit: Commit<TendermintValidators<B, C>>) -> B {
let hash = block.hash(); let hash = block.hash();
let justification = (CONSENSUS_ID, commit.encode()); let justification = (CONSENSUS_ID, commit.encode());
debug_assert!(self.verify_justification(hash, &justification).is_ok()); debug_assert!(self.verify_justification(hash, &justification).is_ok());

View File

@@ -1,4 +1,4 @@
use core::ops::Deref; use core::{marker::PhantomData, ops::Deref};
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
use sp_application_crypto::{ use sp_application_crypto::{
@@ -6,8 +6,11 @@ use sp_application_crypto::{
sr25519::{Public, Pair, Signature}, sr25519::{Public, Pair, Signature},
}; };
use sp_runtime::traits::Block;
use sp_staking::SessionIndex; use sp_staking::SessionIndex;
use pallet_session::Pallet as Session; use sp_api::ProvideRuntimeApi;
use frame_support::traits::ValidatorSet;
use tendermint_machine::ext::{BlockNumber, Round, Weights, SignatureScheme}; use tendermint_machine::ext::{BlockNumber, Round, Weights, SignatureScheme};
@@ -22,12 +25,17 @@ struct TendermintValidatorsStruct {
} }
impl TendermintValidatorsStruct { impl TendermintValidatorsStruct {
fn from_module() -> TendermintValidatorsStruct { fn from_module<B: Block, C: Send + Sync + ProvideRuntimeApi<B>>(
let validators = Session::<serai_runtime::Runtime>::validators(); client: C,
) -> TendermintValidatorsStruct
where
C::Api: ValidatorSet<Public>,
{
let validators = client.runtime_api().validators();
assert_eq!(validators.len(), 1); assert_eq!(validators.len(), 1);
let keys = Pair::from_string("//Alice", None).unwrap(); let keys = Pair::from_string("//Alice", None).unwrap();
TendermintValidatorsStruct { TendermintValidatorsStruct {
session: Session::<serai_runtime::Runtime>::current_index(), session: client.runtime_api().session_index(),
// TODO // TODO
total_weight: validators.len().try_into().unwrap(), total_weight: validators.len().try_into().unwrap(),
@@ -40,20 +48,28 @@ impl TendermintValidatorsStruct {
} }
// Wrap every access of the validators struct in something which forces calling refresh // Wrap every access of the validators struct in something which forces calling refresh
struct Refresh { struct Refresh<B: Block, C: Send + Sync + ProvideRuntimeApi<B>> {
_block: PhantomData<B>,
client: C,
_refresh: Arc<RwLock<TendermintValidatorsStruct>>, _refresh: Arc<RwLock<TendermintValidatorsStruct>>,
} }
impl Refresh { impl<B: Block, C: Send + Sync + ProvideRuntimeApi<B>> Refresh<B, C>
where
C::Api: ValidatorSet<Public>,
{
// If the session has changed, re-create the struct with the data on it // If the session has changed, re-create the struct with the data on it
fn refresh(&self) { fn refresh(&self) {
let session = self._refresh.read().unwrap().session; let session = self._refresh.read().unwrap().session;
if session != Session::<serai_runtime::Runtime>::current_index() { if session != self.client.runtime_api().session_index() {
*self._refresh.write().unwrap() = TendermintValidatorsStruct::from_module(); *self._refresh.write().unwrap() = TendermintValidatorsStruct::from_module(self.client);
} }
} }
} }
impl Deref for Refresh { impl<B: Block, C: Send + Sync + ProvideRuntimeApi<B>> Deref for Refresh<B, C>
where
C::Api: ValidatorSet<Public>,
{
type Target = RwLock<TendermintValidatorsStruct>; type Target = RwLock<TendermintValidatorsStruct>;
fn deref(&self) -> &RwLock<TendermintValidatorsStruct> { fn deref(&self) -> &RwLock<TendermintValidatorsStruct> {
self.refresh(); self.refresh();
@@ -61,16 +77,26 @@ impl Deref for Refresh {
} }
} }
pub(crate) struct TendermintValidators(Refresh); pub(crate) struct TendermintValidators<B: Block, C: Send + Sync + ProvideRuntimeApi<B>>(
impl TendermintValidators { Refresh<B, C>,
pub(crate) fn new() -> TendermintValidators { );
impl<B: Block, C: Send + Sync + ProvideRuntimeApi<B>> TendermintValidators<B, C>
where
C::Api: ValidatorSet<Public>,
{
pub(crate) fn new(client: C) -> TendermintValidators<B, C> {
TendermintValidators(Refresh { TendermintValidators(Refresh {
_block: PhantomData,
client,
_refresh: Arc::new(RwLock::new(TendermintValidatorsStruct::from_module())), _refresh: Arc::new(RwLock::new(TendermintValidatorsStruct::from_module())),
}) })
} }
} }
impl SignatureScheme for TendermintValidators { impl<B: Block, C: Send + Sync + ProvideRuntimeApi<B>> SignatureScheme for TendermintValidators<B, C>
where
C::Api: ValidatorSet<Public>,
{
type ValidatorId = u16; type ValidatorId = u16;
type Signature = Signature; type Signature = Signature;
type AggregateSignature = Vec<Signature>; type AggregateSignature = Vec<Signature>;
@@ -100,7 +126,10 @@ impl SignatureScheme for TendermintValidators {
} }
} }
impl Weights for TendermintValidators { impl<B: Block, C: Send + Sync + ProvideRuntimeApi<B>> Weights for TendermintValidators<B, C>
where
C::Api: ValidatorSet<Public>,
{
type ValidatorId = u16; type ValidatorId = u16;
fn total_weight(&self) -> u64 { fn total_weight(&self) -> u64 {

View File

@@ -2,6 +2,7 @@ use std::sync::Arc;
use async_trait::async_trait; use async_trait::async_trait;
use sp_core::sr25519::Public;
use sp_inherents::CreateInherentDataProviders; use sp_inherents::CreateInherentDataProviders;
use sp_runtime::traits::Block; use sp_runtime::traits::Block;
use sp_api::TransactionFor; use sp_api::TransactionFor;
@@ -11,6 +12,8 @@ use sc_consensus::{BlockImportParams, BlockImport, Verifier};
use sc_client_api::Backend; use sc_client_api::Backend;
use frame_support::traits::ValidatorSet;
use crate::{ use crate::{
tendermint::{TendermintClient, TendermintImport}, tendermint::{TendermintClient, TendermintImport},
Announce, Announce,
@@ -29,6 +32,7 @@ where
TransactionFor<C, B>: Send + Sync + 'static, TransactionFor<C, B>: Send + Sync + 'static,
Arc<C>: BlockImport<B, Transaction = TransactionFor<C, B>>, Arc<C>: BlockImport<B, Transaction = TransactionFor<C, B>>,
<Arc<C> as BlockImport<B>>::Error: Into<Error>, <Arc<C> as BlockImport<B>>::Error: Into<Error>,
C::Api: ValidatorSet<Public>,
{ {
async fn verify( async fn verify(
&mut self, &mut self,