TendermintApi, compilation fixes

This commit is contained in:
Luke Parker 2022-10-27 08:44:53 -04:00
parent 66f7663cb2
commit 5c08fa9701
No known key found for this signature in database
GPG key ID: F9F1386DB1E119B6
14 changed files with 202 additions and 110 deletions

13
Cargo.lock generated
View file

@ -5115,6 +5115,8 @@ dependencies = [
"parity-scale-codec", "parity-scale-codec",
"scale-info", "scale-info",
"sp-application-crypto", "sp-application-crypto",
"sp-core",
"sp-std",
] ]
[[package]] [[package]]
@ -7439,6 +7441,7 @@ dependencies = [
"sp-inherents", "sp-inherents",
"sp-runtime", "sp-runtime",
"sp-staking", "sp-staking",
"sp-tendermint",
"sp-timestamp", "sp-timestamp",
"substrate-prometheus-endpoint", "substrate-prometheus-endpoint",
"tendermint-machine", "tendermint-machine",
@ -7558,6 +7561,7 @@ dependencies = [
"sp-runtime", "sp-runtime",
"sp-session", "sp-session",
"sp-std", "sp-std",
"sp-tendermint",
"sp-transaction-pool", "sp-transaction-pool",
"sp-version", "sp-version",
"substrate-wasm-builder", "substrate-wasm-builder",
@ -8318,6 +8322,15 @@ dependencies = [
"sp-std", "sp-std",
] ]
[[package]]
name = "sp-tendermint"
version = "0.1.0"
dependencies = [
"sp-api",
"sp-core",
"sp-std",
]
[[package]] [[package]]
name = "sp-timestamp" name = "sp-timestamp"
version = "4.0.0-dev" version = "4.0.0-dev"

View file

@ -47,9 +47,9 @@ sc-rpc-api = { git = "https://github.com/serai-dex/substrate" }
substrate-frame-rpc-system = { git = "https://github.com/serai-dex/substrate" } substrate-frame-rpc-system = { git = "https://github.com/serai-dex/substrate" }
pallet-transaction-payment-rpc = { git = "https://github.com/serai-dex/substrate" } pallet-transaction-payment-rpc = { git = "https://github.com/serai-dex/substrate" }
pallet-tendermint = { path = "../pallet-tendermint", default-features = false } pallet-tendermint = { path = "../tendermint/pallet", default-features = false }
serai-runtime = { path = "../runtime" } serai-runtime = { path = "../runtime" }
serai-consensus = { path = "../consensus" } serai-consensus = { path = "../tendermint/client" }
[build-dependencies] [build-dependencies]
substrate-build-script-utils = { git = "https://github.com/serai-dex/substrate.git" } substrate-build-script-utils = { git = "https://github.com/serai-dex/substrate.git" }

View file

@ -29,6 +29,8 @@ sp-block-builder = { git = "https://github.com/serai-dex/substrate", default-fea
sp-runtime = { git = "https://github.com/serai-dex/substrate", default-features = false } sp-runtime = { git = "https://github.com/serai-dex/substrate", default-features = false }
sp-api = { git = "https://github.com/serai-dex/substrate", default-features = false } sp-api = { git = "https://github.com/serai-dex/substrate", default-features = false }
sp-tendermint = { path = "../tendermint/primitives", default-features = false }
frame-system = { git = "https://github.com/serai-dex/substrate", default-features = false } frame-system = { git = "https://github.com/serai-dex/substrate", default-features = false }
frame-support = { git = "https://github.com/serai-dex/substrate", default-features = false } frame-support = { git = "https://github.com/serai-dex/substrate", default-features = false }
frame-executive = { git = "https://github.com/serai-dex/substrate", default-features = false } frame-executive = { git = "https://github.com/serai-dex/substrate", default-features = false }
@ -43,7 +45,7 @@ pallet-contracts-primitives = { git = "https://github.com/serai-dex/substrate",
pallet-contracts = { git = "https://github.com/serai-dex/substrate", default-features = false } pallet-contracts = { git = "https://github.com/serai-dex/substrate", default-features = false }
pallet-session = { git = "https://github.com/serai-dex/substrate", default-features = false } pallet-session = { git = "https://github.com/serai-dex/substrate", default-features = false }
pallet-tendermint = { path = "../pallet-tendermint", default-features = false } pallet-tendermint = { path = "../tendermint/pallet", default-features = false }
frame-system-rpc-runtime-api = { git = "https://github.com/serai-dex/substrate", default-features = false } frame-system-rpc-runtime-api = { git = "https://github.com/serai-dex/substrate", default-features = false }
pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/serai-dex/substrate", default-features = false } pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/serai-dex/substrate", default-features = false }
@ -68,6 +70,8 @@ std = [
"sp-runtime/std", "sp-runtime/std",
"sp-api/std", "sp-api/std",
"sp-tendermint/std",
"frame-system/std", "frame-system/std",
"frame-support/std", "frame-support/std",
"frame-executive/std", "frame-executive/std",

View file

@ -361,6 +361,16 @@ sp_api::impl_runtime_apis! {
} }
} }
impl sp_tendermint::TendermintApi<Block> for Runtime {
fn current_session() -> u32 {
Tendermint::session()
}
fn validators() -> Vec<Public> {
Session::validators()
}
}
impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Index> for Runtime { impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Index> for Runtime {
fn account_nonce(account: AccountId) -> Index { fn account_nonce(account: AccountId) -> Index {
System::account_nonce(account) System::account_nonce(account)

View file

@ -30,6 +30,8 @@ sp-runtime = { git = "https://github.com/serai-dex/substrate" }
sp-api = { git = "https://github.com/serai-dex/substrate" } sp-api = { git = "https://github.com/serai-dex/substrate" }
sp-consensus = { git = "https://github.com/serai-dex/substrate" } sp-consensus = { git = "https://github.com/serai-dex/substrate" }
sp-tendermint = { path = "../primitives" }
sc-transaction-pool = { git = "https://github.com/serai-dex/substrate" } sc-transaction-pool = { git = "https://github.com/serai-dex/substrate" }
sc-basic-authorship = { git = "https://github.com/serai-dex/substrate" } sc-basic-authorship = { git = "https://github.com/serai-dex/substrate" }
sc-executor = { git = "https://github.com/serai-dex/substrate" } sc-executor = { git = "https://github.com/serai-dex/substrate" }
@ -43,6 +45,6 @@ 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" }
tendermint-machine = { path = "../tendermint", features = ["substrate"] } tendermint-machine = { path = "../machine", features = ["substrate"] }
serai-runtime = { path = "../runtime" } serai-runtime = { path = "../../runtime" }

View file

@ -2,7 +2,6 @@ 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;
@ -12,7 +11,7 @@ use sc_consensus::{BlockCheckParams, BlockImportParams, ImportResult, BlockImpor
use sc_client_api::Backend; use sc_client_api::Backend;
use frame_support::traits::ValidatorSet; use sp_tendermint::TendermintApi;
use crate::{ use crate::{
tendermint::{TendermintClient, TendermintImport}, tendermint::{TendermintClient, TendermintImport},
@ -32,7 +31,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>, C::Api: TendermintApi<B>,
{ {
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, sr25519::Public}; use sp_core::Decode;
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,13 +19,13 @@ 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,
}; };
use sp_tendermint::TendermintApi;
use crate::{ use crate::{
CONSENSUS_ID, CONSENSUS_ID,
validators::TendermintValidators, validators::TendermintValidators,
@ -100,7 +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>, C::Api: TendermintApi<B>,
{ {
let import = TendermintImport::new(client, announce, providers, env); let import = TendermintImport::new(client, announce, providers, env);
@ -119,7 +119,7 @@ where
Ok(best) => BlockNumber(best), Ok(best) => BlockNumber(best),
Err(_) => panic!("BlockNumber exceeded u64"), Err(_) => panic!("BlockNumber exceeded u64"),
}, },
Commit::<TendermintValidators<B, C>>::decode( Commit::<TendermintValidators<B, Be, C>>::decode(
&mut import_clone &mut import_clone
.client .client
.justifications(&BlockId::Number(best)) .justifications(&BlockId::Number(best))

View file

@ -10,10 +10,7 @@ use log::warn;
use tokio::sync::RwLock as AsyncRwLock; use tokio::sync::RwLock as AsyncRwLock;
use sp_core::{ use sp_core::{Encode, Decode, 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},
@ -28,13 +25,13 @@ 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,
}; };
use sp_tendermint::TendermintApi;
use crate::{ use crate::{
CONSENSUS_ID, CONSENSUS_ID,
validators::TendermintValidators, validators::TendermintValidators,
@ -53,7 +50,7 @@ pub trait TendermintClient<B: Block, Be: Backend<B> + 'static>:
+ 'static + 'static
where where
TransactionFor<Self, B>: Send + Sync + 'static, TransactionFor<Self, B>: Send + Sync + 'static,
Self::Api: ValidatorSet<Public>, Self::Api: TendermintApi<B>,
{ {
} }
impl< impl<
@ -70,7 +67,7 @@ impl<
> TendermintClient<B, Be> for C > TendermintClient<B, Be> for C
where where
TransactionFor<C, B>: Send + Sync + 'static, 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>, A: Announce<B>,
> where > where
TransactionFor<C, B>: Send + Sync + 'static, TransactionFor<C, B>: Send + Sync + 'static,
C::Api: ValidatorSet<Public>, C::Api: TendermintApi<B>,
{ {
_block: PhantomData<B>, _block: PhantomData<B>,
_backend: PhantomData<Be>, _backend: PhantomData<Be>,
validators: Arc<TendermintValidators<B, C>>, validators: Arc<TendermintValidators<B, Be, 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>>>>,
@ -111,7 +108,7 @@ 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>, C::Api: TendermintApi<B>,
{ {
fn clone(&self) -> Self { fn clone(&self) -> Self {
TendermintImport { TendermintImport {
@ -143,7 +140,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>, C::Api: TendermintApi<B>,
{ {
pub(crate) fn new( pub(crate) fn new(
client: Arc<C>, client: Arc<C>,
@ -155,7 +152,7 @@ where
_block: PhantomData, _block: PhantomData,
_backend: PhantomData, _backend: PhantomData,
validators: TendermintValidators::new(client), validators: Arc::new(TendermintValidators::new(client.clone())),
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)),
@ -215,7 +212,7 @@ where
Err(Error::InvalidJustification)?; 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)?; 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)?;
@ -328,20 +325,20 @@ 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>, C::Api: TendermintApi<B>,
{ {
type ValidatorId = u16; type ValidatorId = u16;
type SignatureScheme = TendermintValidators<B, C>; type SignatureScheme = TendermintValidators<B, Be, C>;
type Weights = TendermintValidators<B, C>; type Weights = TendermintValidators<B, Be, 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<B, C>> { fn signature_scheme(&self) -> Arc<TendermintValidators<B, Be, C>> {
self.validators.clone() self.validators.clone()
} }
fn weights(&self) -> Arc<TendermintValidators<B, C>> { fn weights(&self) -> Arc<TendermintValidators<B, Be, C>> {
self.validators.clone() self.validators.clone()
} }
@ -410,7 +407,7 @@ where
Ok(()) 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 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

@ -8,12 +8,16 @@ use sp_application_crypto::{
use sp_runtime::traits::Block; use sp_runtime::traits::Block;
use sp_staking::SessionIndex; 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 tendermint_machine::ext::{BlockNumber, Round, Weights, SignatureScheme};
use sp_tendermint::TendermintApi;
use crate::tendermint::TendermintClient;
struct TendermintValidatorsStruct { struct TendermintValidatorsStruct {
session: SessionIndex, session: SessionIndex,
@ -25,17 +29,21 @@ struct TendermintValidatorsStruct {
} }
impl TendermintValidatorsStruct { impl TendermintValidatorsStruct {
fn from_module<B: Block, C: Send + Sync + ProvideRuntimeApi<B>>( fn from_module<B: Block, Be: Backend<B> + 'static, C: TendermintClient<B, Be>>(
client: C, client: &Arc<C>,
) -> TendermintValidatorsStruct ) -> TendermintValidatorsStruct
where 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); assert_eq!(validators.len(), 1);
let keys = Pair::from_string("//Alice", None).unwrap(); let keys = Pair::from_string("//Alice", None).unwrap();
TendermintValidatorsStruct { TendermintValidatorsStruct {
session: client.runtime_api().session_index(), session,
// TODO // TODO
total_weight: validators.len().try_into().unwrap(), 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 // 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>, _block: PhantomData<B>,
client: C, _backend: PhantomData<Be>,
client: Arc<C>,
_refresh: Arc<RwLock<TendermintValidatorsStruct>>, _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 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 // 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 != self.client.runtime_api().session_index() { if session !=
*self._refresh.write().unwrap() = TendermintValidatorsStruct::from_module(self.client); 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 where
C::Api: ValidatorSet<Public>, TransactionFor<C, B>: Send + Sync + 'static,
C::Api: TendermintApi<B>,
{ {
type Target = RwLock<TendermintValidatorsStruct>; type Target = RwLock<TendermintValidatorsStruct>;
fn deref(&self) -> &RwLock<TendermintValidatorsStruct> { fn deref(&self) -> &RwLock<TendermintValidatorsStruct> {
@ -77,25 +100,36 @@ where
} }
} }
pub(crate) struct TendermintValidators<B: Block, C: Send + Sync + ProvideRuntimeApi<B>>( pub(crate) struct TendermintValidators<
Refresh<B, C>, B: Block,
); Be: Backend<B> + 'static,
impl<B: Block, C: Send + Sync + ProvideRuntimeApi<B>> TendermintValidators<B, C> C: TendermintClient<B, Be>,
>(Refresh<B, Be, C>)
where 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 { TendermintValidators(Refresh {
_block: PhantomData, _block: PhantomData,
_backend: PhantomData,
_refresh: Arc::new(RwLock::new(TendermintValidatorsStruct::from_module(&client))),
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 where
C::Api: ValidatorSet<Public>, TransactionFor<C, B>: Send + Sync + 'static,
C::Api: TendermintApi<B>,
{ {
type ValidatorId = u16; type ValidatorId = u16;
type Signature = Signature; 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 where
C::Api: ValidatorSet<Public>, TransactionFor<C, B>: Send + Sync + 'static,
C::Api: TendermintApi<B>,
{ {
type ValidatorId = u16; type ValidatorId = u16;

View file

@ -2,7 +2,6 @@ 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;
@ -12,7 +11,7 @@ use sc_consensus::{BlockImportParams, BlockImport, Verifier};
use sc_client_api::Backend; use sc_client_api::Backend;
use frame_support::traits::ValidatorSet; use sp_tendermint::TendermintApi;
use crate::{ use crate::{
tendermint::{TendermintClient, TendermintImport}, tendermint::{TendermintClient, TendermintImport},
@ -32,7 +31,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>, C::Api: TendermintApi<B>,
{ {
async fn verify( async fn verify(
&mut self, &mut self,

View file

@ -15,6 +15,8 @@ rustdoc-args = ["--cfg", "docsrs"]
parity-scale-codec = { version = "3", default-features = false, features = ["derive"] } parity-scale-codec = { version = "3", default-features = false, features = ["derive"] }
scale-info = { version = "2", default-features = false, features = ["derive"] } scale-info = { version = "2", default-features = false, features = ["derive"] }
sp-core = { git = "https://github.com/serai-dex/substrate", default-features = false }
sp-std = { git = "https://github.com/serai-dex/substrate", default-features = false }
sp-application-crypto = { git = "https://github.com/serai-dex/substrate", default-features = false } sp-application-crypto = { git = "https://github.com/serai-dex/substrate", default-features = false }
frame-system = { git = "https://github.com/serai-dex/substrate", default-features = false } frame-system = { git = "https://github.com/serai-dex/substrate", default-features = false }

View file

@ -1,60 +1,73 @@
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
use frame_support::traits::OneSessionHandler;
#[frame_support::pallet] #[frame_support::pallet]
pub mod pallet { pub mod pallet {
use sp_std::vec::Vec;
use sp_core::sr25519::Public;
use frame_support::pallet_prelude::*; use frame_support::pallet_prelude::*;
use frame_support::traits::{ConstU32, OneSessionHandler};
type MaxValidators = ConstU32<{ u16::MAX as u32 }>;
#[pallet::config] #[pallet::config]
pub trait Config: frame_system::Config {} pub trait Config: frame_system::Config {}
#[pallet::pallet] #[pallet::pallet]
#[pallet::generate_store(pub(super) trait Store)]
pub struct Pallet<T>(PhantomData<T>); pub struct Pallet<T>(PhantomData<T>);
#[pallet::storage]
#[pallet::getter(fn session)]
pub type Session<T: Config> = StorageValue<_, u32, ValueQuery>;
#[pallet::storage]
#[pallet::getter(fn validators)]
pub type Validators<T: Config> = StorageValue<_, BoundedVec<Public, MaxValidators>, ValueQuery>;
pub mod crypto {
use sp_application_crypto::{KeyTypeId, app_crypto, sr25519};
app_crypto!(sr25519, KeyTypeId(*b"tend"));
impl<T> sp_application_crypto::BoundToRuntimeAppPublic for crate::Pallet<T> {
type Public = Public;
}
sp_application_crypto::with_pair! {
pub type AuthorityPair = Pair;
}
pub type AuthoritySignature = Signature;
pub type AuthorityId = Public;
}
impl<T: Config, V> OneSessionHandler<V> for Pallet<T> {
type Key = crypto::Public;
fn on_genesis_session<'a, I: 'a>(_validators: I)
where
I: Iterator<Item = (&'a V, Self::Key)>,
V: 'a,
{
}
fn on_new_session<'a, I: 'a>(changed: bool, validators: I, _queued: I)
where
I: Iterator<Item = (&'a V, Self::Key)>,
V: 'a,
{
if !changed {
return;
}
Session::<T>::put(Self::session() + 1);
Validators::<T>::put(
BoundedVec::try_from(validators.map(|(_, key)| key.into()).collect::<Vec<Public>>())
.unwrap(),
);
}
fn on_disabled(_validator_index: u32) {}
}
} }
pub use pallet::*; pub use pallet::*;
pub mod crypto {
use sp_application_crypto::{KeyTypeId, app_crypto, sr25519};
app_crypto!(sr25519, KeyTypeId(*b"tend"));
impl<C> sp_application_crypto::BoundToRuntimeAppPublic for crate::Pallet<C> {
type Public = Public;
}
sp_application_crypto::with_pair! {
pub type AuthorityPair = Pair;
}
pub type AuthoritySignature = Signature;
pub type AuthorityId = Public;
}
impl<C, V> OneSessionHandler<V> for Pallet<C> {
type Key = crypto::Public;
fn on_genesis_session<'a, I: 'a>(_validators: I)
where
I: Iterator<Item = (&'a V, Self::Key)>,
V: 'a,
{
}
fn on_new_session<'a, I: 'a>(_changed: bool, _validators: I, _queued: I)
where
I: Iterator<Item = (&'a V, Self::Key)>,
V: 'a,
{
/*
if !changed {
return;
}
for validator in validators {
...
}
*/
}
fn on_disabled(_validator_index: u32) {}
}

View file

@ -10,3 +10,12 @@ edition = "2021"
[package.metadata.docs.rs] [package.metadata.docs.rs]
all-features = true all-features = true
rustdoc-args = ["--cfg", "docsrs"] rustdoc-args = ["--cfg", "docsrs"]
[dependencies]
sp-core = { git = "https://github.com/serai-dex/substrate", default-features = false }
sp-std = { git = "https://github.com/serai-dex/substrate", default-features = false }
sp-api = { git = "https://github.com/serai-dex/substrate", default-features = false }
[features]
std = ["sp-core/std", "sp-std/std", "sp-api/std"]
default = ["std"]

View file

@ -1,7 +1,15 @@
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
use sp_core::sr25519::Public; use sp_core::sr25519::Public;
use sp_std::vec::Vec;
trait TendermintApi { sp_api::decl_runtime_apis! {
fn validators() -> Vec<Public>; pub trait TendermintApi {
/// Current session number. A session is NOT a fixed length of blocks, yet rather a continuous
/// set of validators.
fn current_session() -> u32;
/// Current validators.
fn validators() -> Vec<Public>;
}
} }