Skip to content

Commit

Permalink
Merge branch 'main' into A0-3390-kozoun
Browse files Browse the repository at this point in the history
  • Loading branch information
timorleph committed Nov 6, 2023
2 parents 909d5c0 + d7a9236 commit ef0b7cf
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 25 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion finality-aleph/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,13 @@ sp-runtime = { workspace = true }
sp-state-machine = { workspace = true }
sp-timestamp = { workspace = true }
sp-trie = { workspace = true }
aleph-runtime = { workspace = true }

[dev-dependencies]
substrate-test-runtime-client = { workspace = true }
substrate-test-runtime = { workspace = true }
substrate-test-client = { workspace = true }
sc-block-builder = { workspace = true }
aleph-runtime = { workspace = true }

[features]
only_legacy = []
18 changes: 11 additions & 7 deletions finality-aleph/src/idx_to_account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use sp_runtime::traits::{Block, Header};

use crate::{
abft::NodeIndex,
runtime_api::RuntimeApi,
session::{SessionBoundaryInfo, SessionId},
session_map::{AuthorityProvider, AuthorityProviderImpl},
ClientForAleph,
Expand All @@ -16,43 +17,46 @@ pub trait ValidatorIndexToAccountIdConverter {
fn account(&self, session: SessionId, validator_index: NodeIndex) -> Option<AccountId>;
}

pub struct ValidatorIndexToAccountIdConverterImpl<C, B, BE>
pub struct ValidatorIndexToAccountIdConverterImpl<C, B, BE, RA>
where
C: ClientForAleph<B, BE> + Send + Sync + 'static,
C::Api: crate::aleph_primitives::AlephSessionApi<B> + AuraApi<B, AuraId>,
B: Block<Hash = BlockHash>,
BE: Backend<B> + 'static,
RA: RuntimeApi,
{
client: Arc<C>,
session_boundary_info: SessionBoundaryInfo,
authority_provider: AuthorityProviderImpl<C, B, BE>,
authority_provider: AuthorityProviderImpl<C, B, BE, RA>,
}

impl<C, B, BE> ValidatorIndexToAccountIdConverterImpl<C, B, BE>
impl<C, B, BE, RA> ValidatorIndexToAccountIdConverterImpl<C, B, BE, RA>
where
C: ClientForAleph<B, BE> + Send + Sync + 'static,
C::Api: crate::aleph_primitives::AlephSessionApi<B> + AuraApi<B, AuraId>,
B: Block<Hash = BlockHash>,
B::Header: Header<Number = BlockNumber>,
BE: Backend<B> + 'static,
RA: RuntimeApi,
{
pub fn new(client: Arc<C>, session_boundary_info: SessionBoundaryInfo) -> Self {
pub fn new(client: Arc<C>, session_boundary_info: SessionBoundaryInfo, api: RA) -> Self {
Self {
client: client.clone(),
session_boundary_info,
authority_provider: AuthorityProviderImpl::new(client),
authority_provider: AuthorityProviderImpl::new(client, api),
}
}
}

impl<C, B, BE> ValidatorIndexToAccountIdConverter
for ValidatorIndexToAccountIdConverterImpl<C, B, BE>
impl<C, B, BE, RA> ValidatorIndexToAccountIdConverter
for ValidatorIndexToAccountIdConverterImpl<C, B, BE, RA>
where
C: ClientForAleph<B, BE> + Send + Sync + 'static,
C::Api: crate::aleph_primitives::AlephSessionApi<B> + AuraApi<B, AuraId>,
B: Block<Hash = BlockHash>,
B::Header: Header<Number = BlockNumber>,
BE: Backend<B> + 'static,
RA: RuntimeApi,
{
fn account(&self, session: SessionId, validator_index: NodeIndex) -> Option<AccountId> {
let block_number = self
Expand Down
8 changes: 6 additions & 2 deletions finality-aleph/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ use parity_scale_codec::{Decode, Encode, Output};
use primitives as aleph_primitives;
use primitives::{AuthorityId, Block as AlephBlock, BlockHash, BlockNumber, Hash as AlephHash};
use sc_client_api::{
Backend, BlockBackend, BlockchainEvents, Finalizer, LockImportRun, TransactionFor,
Backend, BlockBackend, BlockchainEvents, Finalizer, LockImportRun, StorageProvider,
TransactionFor,
};
use sc_consensus::BlockImport;
use sc_network::NetworkService;
Expand Down Expand Up @@ -51,6 +52,7 @@ mod metrics;
mod network;
mod nodes;
mod party;
mod runtime_api;
mod session;
mod session_map;
mod sync;
Expand Down Expand Up @@ -209,6 +211,7 @@ pub trait ClientForAleph<B, BE>:
+ HeaderMetadata<B, Error = sp_blockchain::Error>
+ BlockchainEvents<B>
+ BlockBackend<B>
+ StorageProvider<B, BE>
where
BE: Backend<B>,
B: Block,
Expand All @@ -226,7 +229,8 @@ where
+ HeaderMetadata<B, Error = sp_blockchain::Error>
+ BlockchainEvents<B>
+ BlockImport<B, Transaction = TransactionFor<BE, B>, Error = sp_consensus::Error>
+ BlockBackend<B>,
+ BlockBackend<B>
+ StorageProvider<B, BE>,
{
}

Expand Down
11 changes: 8 additions & 3 deletions finality-aleph/src/nodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use crate::{
impls::ChainStateImpl, manager::NodeSessionManagerImpl, ConsensusParty,
ConsensusPartyParams,
},
runtime_api::RuntimeApiImpl,
session::SessionBoundaryInfo,
session_map::{AuthorityProviderImpl, FinalityNotifierImpl, SessionMapUpdater},
sync::{
Expand Down Expand Up @@ -124,7 +125,7 @@ where
let gossip_network_task = async move { gossip_network_service.run().await };

let map_updater = SessionMapUpdater::new(
AuthorityProviderImpl::new(client.clone()),
AuthorityProviderImpl::new(client.clone(), RuntimeApiImpl::new(client.clone())),
FinalityNotifierImpl::new(client.clone()),
session_period,
);
Expand All @@ -149,7 +150,7 @@ where
let verifier = VerifierCache::new(
session_info.clone(),
SubstrateFinalizationInfo::new(client.clone()),
AuthorityProviderImpl::new(client.clone()),
AuthorityProviderImpl::new(client.clone(), RuntimeApiImpl::new(client.clone())),
VERIFIER_CACHE_SIZE,
genesis_header,
);
Expand All @@ -172,7 +173,11 @@ where

let validator_address_cache_updater = validator_address_cache_updater(
validator_address_cache,
ValidatorIndexToAccountIdConverterImpl::new(client.clone(), session_info.clone()),
ValidatorIndexToAccountIdConverterImpl::new(
client.clone(),
session_info.clone(),
RuntimeApiImpl::new(client.clone()),
),
);

let (connection_manager_service, connection_manager) = ConnectionManager::new(
Expand Down
110 changes: 110 additions & 0 deletions finality-aleph/src/runtime_api.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
use std::{
fmt::{Display, Formatter},
marker::PhantomData,
sync::Arc,
};

use aleph_runtime::SessionKeys;
use parity_scale_codec::{Decode, DecodeAll, Error as DecodeError};
use sc_client_api::Backend;
use sp_application_crypto::key_types::AURA;
use sp_core::twox_128;
use sp_runtime::traits::{Block, OpaqueKeys};

use crate::{
aleph_primitives::{AccountId, AlephSessionApi, AuraId},
BlockHash, ClientForAleph,
};

/// Trait handling connection between host code and runtime storage
pub trait RuntimeApi {
type Error: Display;
/// Returns aura authorities for the next session using state from block `at`
fn next_aura_authorities(&self, at: BlockHash) -> Result<Vec<AuraId>, Self::Error>;
}

type QueuedKeys = Vec<(AccountId, SessionKeys)>;

#[derive(Clone)]
pub struct RuntimeApiImpl<C, B, BE>
where
C: ClientForAleph<B, BE> + Send + Sync + 'static,
C::Api: AlephSessionApi<B>,
B: Block<Hash = BlockHash>,
BE: Backend<B> + 'static,
{
client: Arc<C>,
_phantom: PhantomData<(B, BE)>,
}

impl<C, B, BE> RuntimeApiImpl<C, B, BE>
where
C: ClientForAleph<B, BE> + Send + Sync + 'static,
C::Api: AlephSessionApi<B>,
B: Block<Hash = BlockHash>,
BE: Backend<B> + 'static,
{
pub fn new(client: Arc<C>) -> Self {
Self {
client,
_phantom: PhantomData,
}
}

fn read_storage<D: Decode>(
&self,
pallet: &str,
item: &str,
at_block: BlockHash,
) -> Result<D, ApiError> {
let storage_key = [twox_128(pallet.as_bytes()), twox_128(item.as_bytes())].concat();

let encoded = match self
.client
.storage(at_block, &sc_client_api::StorageKey(storage_key))
{
Ok(Some(e)) => e,
_ => return Err(ApiError::NoStorage(pallet.to_string(), item.to_string())),
};

D::decode_all(&mut encoded.0.as_ref()).map_err(ApiError::DecodeError)
}
}

#[derive(Clone, Debug)]
pub enum ApiError {
NoStorage(String, String),
DecodeError(DecodeError),
}

impl Display for ApiError {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
match self {
ApiError::NoStorage(pallet, item) => write!(f, "no storage under {}.{}", pallet, item),
ApiError::DecodeError(error) => write!(f, "decode error: {:?}", error),
}
}
}

impl<C, B, BE> RuntimeApi for RuntimeApiImpl<C, B, BE>
where
C: ClientForAleph<B, BE> + Send + Sync + 'static,
C::Api: AlephSessionApi<B>,
B: Block<Hash = BlockHash>,
BE: Backend<B> + 'static,
{
type Error = ApiError;

fn next_aura_authorities(&self, at: BlockHash) -> Result<Vec<AuraId>, Self::Error> {
if let Ok(authorities) = self.client.runtime_api().next_session_aura_authorities(at) {
return Ok(authorities);
}

let queued_keys: QueuedKeys = self.read_storage("Session", "QueuedKeys", at)?;

Ok(queued_keys
.into_iter()
.filter_map(|(_, keys)| keys.get(AURA))
.collect())
}
}
23 changes: 13 additions & 10 deletions finality-aleph/src/session_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ use tokio::sync::{

use crate::{
aleph_primitives::{AlephSessionApi, AuraId, BlockHash, BlockNumber, SessionAuthorityData},
runtime_api::RuntimeApi,
session::SessionBoundaryInfo,
ClientForAleph, SessionId, SessionPeriod,
};

const PRUNING_THRESHOLD: u32 = 10;
const LOG_TARGET: &str = "aleph-session-updater";
type SessionMap = HashMap<SessionId, SessionAuthorityData>;
Expand All @@ -36,28 +36,32 @@ pub trait AuthorityProvider {
/// Default implementation of authority provider trait.
/// If state pruning is on and set to `n`, will no longer be able to
/// answer for `num < finalized_number - n`.
pub struct AuthorityProviderImpl<C, B, BE>
pub struct AuthorityProviderImpl<C, B, BE, RA>
where
C: ClientForAleph<B, BE> + Send + Sync + 'static,
C::Api: crate::aleph_primitives::AlephSessionApi<B> + AuraApi<B, AuraId>,
B: Block<Hash = BlockHash>,
BE: Backend<B> + 'static,
RA: RuntimeApi,
{
client: Arc<C>,
api: RA,
_phantom: PhantomData<(B, BE)>,
}

impl<C, B, BE> AuthorityProviderImpl<C, B, BE>
impl<C, B, BE, RA> AuthorityProviderImpl<C, B, BE, RA>
where
C: ClientForAleph<B, BE> + Send + Sync + 'static,
C::Api: crate::aleph_primitives::AlephSessionApi<B> + AuraApi<B, AuraId>,
B: Block<Hash = BlockHash>,
B::Header: Header<Number = BlockNumber>,
BE: Backend<B> + 'static,
RA: RuntimeApi,
{
pub fn new(client: Arc<C>) -> Self {
pub fn new(client: Arc<C>, api: RA) -> Self {
Self {
client,
api,
_phantom: PhantomData,
}
}
Expand All @@ -76,13 +80,14 @@ where
}
}

impl<C, B, BE> AuthorityProvider for AuthorityProviderImpl<C, B, BE>
impl<C, B, BE, RA> AuthorityProvider for AuthorityProviderImpl<C, B, BE, RA>
where
C: ClientForAleph<B, BE> + Send + Sync + 'static,
C::Api: AlephSessionApi<B> + AuraApi<B, AuraId>,
B: Block<Hash = BlockHash>,
B::Header: Header<Number = BlockNumber>,
BE: Backend<B> + 'static,
RA: RuntimeApi,
{
fn aura_authorities(&self, block_number: BlockNumber) -> Option<Vec<AuraId>> {
AuraApi::authorities(
Expand All @@ -93,11 +98,9 @@ where
}

fn next_aura_authorities(&self, block_number: BlockNumber) -> Option<Vec<AuraId>> {
AlephSessionApi::next_session_aura_authorities(
self.client.runtime_api().deref(),
self.block_hash(block_number)?,
)
.ok()
self.api
.next_aura_authorities(self.block_hash(block_number)?)
.ok()
}

fn authority_data(&self, block_number: BlockNumber) -> Option<SessionAuthorityData> {
Expand Down

0 comments on commit ef0b7cf

Please sign in to comment.