From 4c2dd9b30683595364e617fc4ead969f8a5f2b55 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Thu, 27 Oct 2022 06:29:56 -0400 Subject: [PATCH] Partial work on correcting pallet calls --- Cargo.lock | 1 + substrate/consensus/Cargo.toml | 1 + substrate/consensus/src/block_import.rs | 4 ++ substrate/consensus/src/import_queue.rs | 7 ++- substrate/consensus/src/tendermint.rs | 40 ++++++++++++----- substrate/consensus/src/validators.rs | 59 ++++++++++++++++++------- substrate/consensus/src/verifier.rs | 4 ++ 7 files changed, 89 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 74572d58..26b922f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7419,6 +7419,7 @@ name = "serai-consensus" version = "0.1.0" dependencies = [ "async-trait", + "frame-support", "futures", "log", "pallet-session", diff --git a/substrate/consensus/Cargo.toml b/substrate/consensus/Cargo.toml index 06bde9f1..4102601b 100644 --- a/substrate/consensus/Cargo.toml +++ b/substrate/consensus/Cargo.toml @@ -38,6 +38,7 @@ sc-service = { 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" } +frame-support = { 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" } diff --git a/substrate/consensus/src/block_import.rs b/substrate/consensus/src/block_import.rs index c5a9a285..46dac4b1 100644 --- a/substrate/consensus/src/block_import.rs +++ b/substrate/consensus/src/block_import.rs @@ -2,6 +2,7 @@ use std::{sync::Arc, collections::HashMap}; use async_trait::async_trait; +use sp_core::sr25519::Public; use sp_inherents::CreateInherentDataProviders; use sp_runtime::traits::Block; use sp_api::TransactionFor; @@ -11,6 +12,8 @@ use sc_consensus::{BlockCheckParams, BlockImportParams, ImportResult, BlockImpor use sc_client_api::Backend; +use frame_support::traits::ValidatorSet; + use crate::{ tendermint::{TendermintClient, TendermintImport}, Announce, @@ -29,6 +32,7 @@ where TransactionFor: Send + Sync + 'static, Arc: BlockImport>, as BlockImport>::Error: Into, + C::Api: ValidatorSet, { type Error = Error; type Transaction = TransactionFor; diff --git a/substrate/consensus/src/import_queue.rs b/substrate/consensus/src/import_queue.rs index 4a5a3031..fb31d307 100644 --- a/substrate/consensus/src/import_queue.rs +++ b/substrate/consensus/src/import_queue.rs @@ -6,7 +6,7 @@ use std::{ time::{UNIX_EPOCH, SystemTime}, }; -use sp_core::Decode; +use sp_core::{Decode, sr25519::Public}; use sp_inherents::CreateInherentDataProviders; use sp_runtime::traits::{Header, Block}; use sp_api::{BlockId, TransactionFor}; @@ -19,6 +19,8 @@ use sc_client_api::Backend; use substrate_prometheus_endpoint::Registry; +use frame_support::traits::ValidatorSet; + use tendermint_machine::{ ext::{BlockNumber, Commit}, TendermintMachine, @@ -98,6 +100,7 @@ where TransactionFor: Send + Sync + 'static, Arc: BlockImport>, as BlockImport>::Error: Into, + C::Api: ValidatorSet, { let import = TendermintImport::new(client, announce, providers, env); @@ -116,7 +119,7 @@ where Ok(best) => BlockNumber(best), Err(_) => panic!("BlockNumber exceeded u64"), }, - Commit::::decode( + Commit::>::decode( &mut import_clone .client .justifications(&BlockId::Number(best)) diff --git a/substrate/consensus/src/tendermint.rs b/substrate/consensus/src/tendermint.rs index 2b92c004..089721c0 100644 --- a/substrate/consensus/src/tendermint.rs +++ b/substrate/consensus/src/tendermint.rs @@ -10,8 +10,10 @@ use log::warn; use tokio::sync::RwLock as AsyncRwLock; -use sp_core::{Encode, Decode}; -use sp_application_crypto::sr25519::Signature; +use sp_core::{ + Encode, Decode, + sr25519::{Public, Signature}, +}; use sp_inherents::{InherentData, InherentDataProvider, CreateInherentDataProviders}; use sp_runtime::{ traits::{Header, Block}, @@ -26,6 +28,8 @@ use sc_consensus::{ForkChoiceStrategy, BlockImportParams, BlockImport, import_qu use sc_service::ImportQueue; use sc_client_api::{BlockBackend, Backend, Finalizer}; +use frame_support::traits::ValidatorSet; + use tendermint_machine::{ ext::{BlockError, Commit, Network}, SignedMessage, TendermintHandle, @@ -47,6 +51,9 @@ pub trait TendermintClient + 'static>: + Finalizer + ProvideRuntimeApi + 'static +where + TransactionFor: Send + Sync + 'static, + Self::Api: ValidatorSet, { } impl< @@ -61,6 +68,9 @@ impl< + ProvideRuntimeApi + 'static, > TendermintClient for C +where + TransactionFor: Send + Sync + 'static, + C::Api: ValidatorSet, { } @@ -73,10 +83,13 @@ pub(crate) struct TendermintImport< A: Announce, > where TransactionFor: Send + Sync + 'static, + C::Api: ValidatorSet, { _block: PhantomData, _backend: PhantomData, + validators: Arc>, + importing_block: Arc>>, pub(crate) machine: Arc>>>, @@ -98,12 +111,15 @@ impl< > Clone for TendermintImport where TransactionFor: Send + Sync + 'static, + C::Api: ValidatorSet, { fn clone(&self) -> Self { TendermintImport { _block: PhantomData, _backend: PhantomData, + validators: self.validators.clone(), + importing_block: self.importing_block.clone(), machine: self.machine.clone(), @@ -127,6 +143,7 @@ impl< > TendermintImport where TransactionFor: Send + Sync + 'static, + C::Api: ValidatorSet, { pub(crate) fn new( client: Arc, @@ -138,6 +155,8 @@ where _block: PhantomData, _backend: PhantomData, + validators: TendermintValidators::new(client), + importing_block: Arc::new(RwLock::new(None)), machine: Arc::new(RwLock::new(None)), @@ -196,7 +215,7 @@ where Err(Error::InvalidJustification)?; } - let commit: Commit = + let commit: Commit> = Commit::decode(&mut justification.1.as_ref()).map_err(|_| Error::InvalidJustification)?; if !self.verify_commit(hash, &commit) { Err(Error::InvalidJustification)?; @@ -309,20 +328,21 @@ impl< > Network for TendermintImport where TransactionFor: Send + Sync + 'static, + C::Api: ValidatorSet, { type ValidatorId = u16; - type SignatureScheme = TendermintValidators; - type Weights = TendermintValidators; + type SignatureScheme = TendermintValidators; + type Weights = TendermintValidators; type Block = B; const BLOCK_TIME: u32 = { (serai_runtime::MILLISECS_PER_BLOCK / 1000) as u32 }; - fn signature_scheme(&self) -> Arc { - Arc::new(TendermintValidators::new()) + fn signature_scheme(&self) -> Arc> { + self.validators.clone() } - fn weights(&self) -> Arc { - Arc::new(TendermintValidators::new()) + fn weights(&self) -> Arc> { + self.validators.clone() } async fn broadcast(&mut self, msg: SignedMessage) { @@ -390,7 +410,7 @@ where Ok(()) } - async fn add_block(&mut self, block: B, commit: Commit) -> B { + async fn add_block(&mut self, block: B, commit: Commit>) -> B { let hash = block.hash(); let justification = (CONSENSUS_ID, commit.encode()); debug_assert!(self.verify_justification(hash, &justification).is_ok()); diff --git a/substrate/consensus/src/validators.rs b/substrate/consensus/src/validators.rs index 49b49811..8ebd31ed 100644 --- a/substrate/consensus/src/validators.rs +++ b/substrate/consensus/src/validators.rs @@ -1,4 +1,4 @@ -use core::ops::Deref; +use core::{marker::PhantomData, ops::Deref}; use std::sync::{Arc, RwLock}; use sp_application_crypto::{ @@ -6,8 +6,11 @@ use sp_application_crypto::{ sr25519::{Public, Pair, Signature}, }; +use sp_runtime::traits::Block; 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}; @@ -22,12 +25,17 @@ struct TendermintValidatorsStruct { } impl TendermintValidatorsStruct { - fn from_module() -> TendermintValidatorsStruct { - let validators = Session::::validators(); + fn from_module>( + client: C, + ) -> TendermintValidatorsStruct + where + C::Api: ValidatorSet, + { + let validators = client.runtime_api().validators(); assert_eq!(validators.len(), 1); let keys = Pair::from_string("//Alice", None).unwrap(); TendermintValidatorsStruct { - session: Session::::current_index(), + session: client.runtime_api().session_index(), // TODO 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 -struct Refresh { +struct Refresh> { + _block: PhantomData, + client: C, _refresh: Arc>, } -impl Refresh { +impl> Refresh +where + C::Api: ValidatorSet, +{ // If the session has changed, re-create the struct with the data on it fn refresh(&self) { let session = self._refresh.read().unwrap().session; - if session != Session::::current_index() { - *self._refresh.write().unwrap() = TendermintValidatorsStruct::from_module(); + if session != self.client.runtime_api().session_index() { + *self._refresh.write().unwrap() = TendermintValidatorsStruct::from_module(self.client); } } } -impl Deref for Refresh { +impl> Deref for Refresh +where + C::Api: ValidatorSet, +{ type Target = RwLock; fn deref(&self) -> &RwLock { self.refresh(); @@ -61,16 +77,26 @@ impl Deref for Refresh { } } -pub(crate) struct TendermintValidators(Refresh); -impl TendermintValidators { - pub(crate) fn new() -> TendermintValidators { +pub(crate) struct TendermintValidators>( + Refresh, +); +impl> TendermintValidators +where + C::Api: ValidatorSet, +{ + pub(crate) fn new(client: C) -> TendermintValidators { TendermintValidators(Refresh { + _block: PhantomData, + client, _refresh: Arc::new(RwLock::new(TendermintValidatorsStruct::from_module())), }) } } -impl SignatureScheme for TendermintValidators { +impl> SignatureScheme for TendermintValidators +where + C::Api: ValidatorSet, +{ type ValidatorId = u16; type Signature = Signature; type AggregateSignature = Vec; @@ -100,7 +126,10 @@ impl SignatureScheme for TendermintValidators { } } -impl Weights for TendermintValidators { +impl> Weights for TendermintValidators +where + C::Api: ValidatorSet, +{ type ValidatorId = u16; fn total_weight(&self) -> u64 { diff --git a/substrate/consensus/src/verifier.rs b/substrate/consensus/src/verifier.rs index d2379196..d7a2f8a4 100644 --- a/substrate/consensus/src/verifier.rs +++ b/substrate/consensus/src/verifier.rs @@ -2,6 +2,7 @@ use std::sync::Arc; use async_trait::async_trait; +use sp_core::sr25519::Public; use sp_inherents::CreateInherentDataProviders; use sp_runtime::traits::Block; use sp_api::TransactionFor; @@ -11,6 +12,8 @@ use sc_consensus::{BlockImportParams, BlockImport, Verifier}; use sc_client_api::Backend; +use frame_support::traits::ValidatorSet; + use crate::{ tendermint::{TendermintClient, TendermintImport}, Announce, @@ -29,6 +32,7 @@ where TransactionFor: Send + Sync + 'static, Arc: BlockImport>, as BlockImport>::Error: Into, + C::Api: ValidatorSet, { async fn verify( &mut self,