TendermintApi, compilation fixes

This commit is contained in:
Luke Parker
2022-10-27 08:44:53 -04:00
parent 66f7663cb2
commit 5c08fa9701
14 changed files with 202 additions and 110 deletions

View File

@@ -2,7 +2,6 @@ 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;
@@ -12,7 +11,7 @@ use sc_consensus::{BlockCheckParams, BlockImportParams, ImportResult, BlockImpor
use sc_client_api::Backend;
use frame_support::traits::ValidatorSet;
use sp_tendermint::TendermintApi;
use crate::{
tendermint::{TendermintClient, TendermintImport},
@@ -32,7 +31,7 @@ where
TransactionFor<C, B>: Send + Sync + 'static,
Arc<C>: BlockImport<B, Transaction = TransactionFor<C, B>>,
<Arc<C> as BlockImport<B>>::Error: Into<Error>,
C::Api: ValidatorSet<Public>,
C::Api: TendermintApi<B>,
{
type Error = Error;
type Transaction = TransactionFor<C, B>;

View File

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

View File

@@ -10,10 +10,7 @@ use log::warn;
use tokio::sync::RwLock as AsyncRwLock;
use sp_core::{
Encode, Decode,
sr25519::{Public, Signature},
};
use sp_core::{Encode, Decode, sr25519::Signature};
use sp_inherents::{InherentData, InherentDataProvider, CreateInherentDataProviders};
use sp_runtime::{
traits::{Header, Block},
@@ -28,13 +25,13 @@ 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,
};
use sp_tendermint::TendermintApi;
use crate::{
CONSENSUS_ID,
validators::TendermintValidators,
@@ -53,7 +50,7 @@ pub trait TendermintClient<B: Block, Be: Backend<B> + 'static>:
+ 'static
where
TransactionFor<Self, B>: Send + Sync + 'static,
Self::Api: ValidatorSet<Public>,
Self::Api: TendermintApi<B>,
{
}
impl<
@@ -70,7 +67,7 @@ impl<
> TendermintClient<B, Be> for C
where
TransactionFor<C, B>: Send + Sync + 'static,
C::Api: ValidatorSet<Public>,
C::Api: TendermintApi<B>,
{
}
@@ -83,12 +80,12 @@ pub(crate) struct TendermintImport<
A: Announce<B>,
> where
TransactionFor<C, B>: Send + Sync + 'static,
C::Api: ValidatorSet<Public>,
C::Api: TendermintApi<B>,
{
_block: PhantomData<B>,
_backend: PhantomData<Be>,
validators: Arc<TendermintValidators<B, C>>,
validators: Arc<TendermintValidators<B, Be, C>>,
importing_block: Arc<RwLock<Option<B::Hash>>>,
pub(crate) machine: Arc<RwLock<Option<TendermintHandle<Self>>>>,
@@ -111,7 +108,7 @@ impl<
> Clone for TendermintImport<B, Be, C, CIDP, E, A>
where
TransactionFor<C, B>: Send + Sync + 'static,
C::Api: ValidatorSet<Public>,
C::Api: TendermintApi<B>,
{
fn clone(&self) -> Self {
TendermintImport {
@@ -143,7 +140,7 @@ impl<
> TendermintImport<B, Be, C, CIDP, E, A>
where
TransactionFor<C, B>: Send + Sync + 'static,
C::Api: ValidatorSet<Public>,
C::Api: TendermintApi<B>,
{
pub(crate) fn new(
client: Arc<C>,
@@ -155,7 +152,7 @@ where
_block: PhantomData,
_backend: PhantomData,
validators: TendermintValidators::new(client),
validators: Arc::new(TendermintValidators::new(client.clone())),
importing_block: Arc::new(RwLock::new(None)),
machine: Arc::new(RwLock::new(None)),
@@ -215,7 +212,7 @@ where
Err(Error::InvalidJustification)?;
}
let commit: Commit<TendermintValidators<B, C>> =
let commit: Commit<TendermintValidators<B, Be, C>> =
Commit::decode(&mut justification.1.as_ref()).map_err(|_| Error::InvalidJustification)?;
if !self.verify_commit(hash, &commit) {
Err(Error::InvalidJustification)?;
@@ -328,20 +325,20 @@ impl<
> Network for TendermintImport<B, Be, C, CIDP, E, A>
where
TransactionFor<C, B>: Send + Sync + 'static,
C::Api: ValidatorSet<Public>,
C::Api: TendermintApi<B>,
{
type ValidatorId = u16;
type SignatureScheme = TendermintValidators<B, C>;
type Weights = TendermintValidators<B, C>;
type SignatureScheme = TendermintValidators<B, Be, C>;
type Weights = TendermintValidators<B, Be, C>;
type Block = B;
const BLOCK_TIME: u32 = { (serai_runtime::MILLISECS_PER_BLOCK / 1000) as u32 };
fn signature_scheme(&self) -> Arc<TendermintValidators<B, C>> {
fn signature_scheme(&self) -> Arc<TendermintValidators<B, Be, C>> {
self.validators.clone()
}
fn weights(&self) -> Arc<TendermintValidators<B, C>> {
fn weights(&self) -> Arc<TendermintValidators<B, Be, C>> {
self.validators.clone()
}
@@ -410,7 +407,7 @@ where
Ok(())
}
async fn add_block(&mut self, block: B, commit: Commit<TendermintValidators<B, C>>) -> B {
async fn add_block(&mut self, block: B, commit: Commit<TendermintValidators<B, Be, C>>) -> B {
let hash = block.hash();
let justification = (CONSENSUS_ID, commit.encode());
debug_assert!(self.verify_justification(hash, &justification).is_ok());

View File

@@ -8,12 +8,16 @@ use sp_application_crypto::{
use sp_runtime::traits::Block;
use sp_staking::SessionIndex;
use sp_api::ProvideRuntimeApi;
use sp_api::{BlockId, TransactionFor};
use frame_support::traits::ValidatorSet;
use sc_client_api::Backend;
use tendermint_machine::ext::{BlockNumber, Round, Weights, SignatureScheme};
use sp_tendermint::TendermintApi;
use crate::tendermint::TendermintClient;
struct TendermintValidatorsStruct {
session: SessionIndex,
@@ -25,17 +29,21 @@ struct TendermintValidatorsStruct {
}
impl TendermintValidatorsStruct {
fn from_module<B: Block, C: Send + Sync + ProvideRuntimeApi<B>>(
client: C,
fn from_module<B: Block, Be: Backend<B> + 'static, C: TendermintClient<B, Be>>(
client: &Arc<C>,
) -> TendermintValidatorsStruct
where
C::Api: ValidatorSet<Public>,
TransactionFor<C, B>: Send + Sync + 'static,
C::Api: TendermintApi<B>,
{
let validators = client.runtime_api().validators();
let last = client.info().best_hash;
let api = client.runtime_api();
let session = api.current_session(&BlockId::Hash(last)).unwrap();
let validators = api.validators(&BlockId::Hash(last)).unwrap();
assert_eq!(validators.len(), 1);
let keys = Pair::from_string("//Alice", None).unwrap();
TendermintValidatorsStruct {
session: client.runtime_api().session_index(),
session,
// TODO
total_weight: validators.len().try_into().unwrap(),
@@ -48,27 +56,42 @@ impl TendermintValidatorsStruct {
}
// Wrap every access of the validators struct in something which forces calling refresh
struct Refresh<B: Block, C: Send + Sync + ProvideRuntimeApi<B>> {
struct Refresh<B: Block, Be: Backend<B> + 'static, C: TendermintClient<B, Be>>
where
TransactionFor<C, B>: Send + Sync + 'static,
C::Api: TendermintApi<B>,
{
_block: PhantomData<B>,
client: C,
_backend: PhantomData<Be>,
client: Arc<C>,
_refresh: Arc<RwLock<TendermintValidatorsStruct>>,
}
impl<B: Block, C: Send + Sync + ProvideRuntimeApi<B>> Refresh<B, C>
impl<B: Block, Be: Backend<B> + 'static, C: TendermintClient<B, Be>> Refresh<B, Be, C>
where
C::Api: ValidatorSet<Public>,
TransactionFor<C, B>: Send + Sync + 'static,
C::Api: TendermintApi<B>,
{
// 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 != self.client.runtime_api().session_index() {
*self._refresh.write().unwrap() = TendermintValidatorsStruct::from_module(self.client);
if session !=
self
.client
.runtime_api()
.current_session(&BlockId::Hash(self.client.info().best_hash))
.unwrap()
{
*self._refresh.write().unwrap() = TendermintValidatorsStruct::from_module(&self.client);
}
}
}
impl<B: Block, C: Send + Sync + ProvideRuntimeApi<B>> Deref for Refresh<B, C>
impl<B: Block, Be: Backend<B> + 'static, C: TendermintClient<B, Be>> Deref for Refresh<B, Be, C>
where
C::Api: ValidatorSet<Public>,
TransactionFor<C, B>: Send + Sync + 'static,
C::Api: TendermintApi<B>,
{
type Target = RwLock<TendermintValidatorsStruct>;
fn deref(&self) -> &RwLock<TendermintValidatorsStruct> {
@@ -77,25 +100,36 @@ where
}
}
pub(crate) struct TendermintValidators<B: Block, C: Send + Sync + ProvideRuntimeApi<B>>(
Refresh<B, C>,
);
impl<B: Block, C: Send + Sync + ProvideRuntimeApi<B>> TendermintValidators<B, C>
pub(crate) struct TendermintValidators<
B: Block,
Be: Backend<B> + 'static,
C: TendermintClient<B, Be>,
>(Refresh<B, Be, C>)
where
C::Api: ValidatorSet<Public>,
TransactionFor<C, B>: Send + Sync + 'static,
C::Api: TendermintApi<B>;
impl<B: Block, Be: Backend<B> + 'static, C: TendermintClient<B, Be>> TendermintValidators<B, Be, C>
where
TransactionFor<C, B>: Send + Sync + 'static,
C::Api: TendermintApi<B>,
{
pub(crate) fn new(client: C) -> TendermintValidators<B, C> {
pub(crate) fn new(client: Arc<C>) -> TendermintValidators<B, Be, C> {
TendermintValidators(Refresh {
_block: PhantomData,
_backend: PhantomData,
_refresh: Arc::new(RwLock::new(TendermintValidatorsStruct::from_module(&client))),
client,
_refresh: Arc::new(RwLock::new(TendermintValidatorsStruct::from_module())),
})
}
}
impl<B: Block, C: Send + Sync + ProvideRuntimeApi<B>> SignatureScheme for TendermintValidators<B, C>
impl<B: Block, Be: Backend<B> + 'static, C: TendermintClient<B, Be>> SignatureScheme
for TendermintValidators<B, Be, C>
where
C::Api: ValidatorSet<Public>,
TransactionFor<C, B>: Send + Sync + 'static,
C::Api: TendermintApi<B>,
{
type ValidatorId = u16;
type Signature = Signature;
@@ -126,9 +160,11 @@ where
}
}
impl<B: Block, C: Send + Sync + ProvideRuntimeApi<B>> Weights for TendermintValidators<B, C>
impl<B: Block, Be: Backend<B> + 'static, C: TendermintClient<B, Be>> Weights
for TendermintValidators<B, Be, C>
where
C::Api: ValidatorSet<Public>,
TransactionFor<C, B>: Send + Sync + 'static,
C::Api: TendermintApi<B>,
{
type ValidatorId = u16;

View File

@@ -2,7 +2,6 @@ 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;
@@ -12,7 +11,7 @@ use sc_consensus::{BlockImportParams, BlockImport, Verifier};
use sc_client_api::Backend;
use frame_support::traits::ValidatorSet;
use sp_tendermint::TendermintApi;
use crate::{
tendermint::{TendermintClient, TendermintImport},
@@ -32,7 +31,7 @@ where
TransactionFor<C, B>: Send + Sync + 'static,
Arc<C>: BlockImport<B, Transaction = TransactionFor<C, B>>,
<Arc<C> as BlockImport<B>>::Error: Into<Error>,
C::Api: ValidatorSet<Public>,
C::Api: TendermintApi<B>,
{
async fn verify(
&mut self,