diff --git a/Cargo.lock b/Cargo.lock index 6b6f1a585..b93193d6a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -467,22 +467,17 @@ name = "bioauth-consensus" version = "0.1.0" dependencies = [ "async-trait", - "humanode-runtime", "mockall", "node-primitives", - "pallet-aura", "pallet-bioauth", "sc-client-api", "sc-consensus", "sc-service", - "sc-tracing 4.0.0-dev", "sp-api", "sp-application-crypto", "sp-blockchain", "sp-consensus", "sp-consensus-aura", - "sp-consensus-slots", - "sp-core", "sp-runtime", "thiserror", "tokio 1.9.0", diff --git a/crates/bioauth-consensus/Cargo.toml b/crates/bioauth-consensus/Cargo.toml index da37684a8..8e0659183 100644 --- a/crates/bioauth-consensus/Cargo.toml +++ b/crates/bioauth-consensus/Cargo.toml @@ -6,20 +6,16 @@ authors = ["Humanode Team "] publish = false [dependencies] -humanode-runtime = { version = "0.1", path = "../humanode-runtime" } -pallet-bioauth = { version = "0.1", path = "../pallet-bioauth" } +pallet-bioauth = { version = "0.1", path = "../pallet-bioauth", optional = true } async-trait = "0.1.42" -pallet-aura = { git = "https://github.com/humanode-network/substrate", branch = "master" } sc-client-api = { git = "https://github.com/humanode-network/substrate", branch = "master" } sc-consensus = { git = "https://github.com/humanode-network/substrate", branch = "master" } -sc-tracing = { git = "https://github.com/humanode-network/substrate", branch = "master" } sp-api = { git = "https://github.com/humanode-network/substrate", branch = "master" } -sp-application-crypto = { git = "https://github.com/humanode-network/substrate", branch = "master" } +sp-application-crypto = { git = "https://github.com/humanode-network/substrate", branch = "master", optional = true } sp-blockchain = { git = "https://github.com/humanode-network/substrate", branch = "master" } sp-consensus = { git = "https://github.com/humanode-network/substrate", branch = "master" } -sp-consensus-aura = { git = "https://github.com/humanode-network/substrate", branch = "master" } -sp-consensus-slots = { git = "https://github.com/humanode-network/substrate", branch = "master" } +sp-consensus-aura = { git = "https://github.com/humanode-network/substrate", branch = "master", optional = true } sp-runtime = { git = "https://github.com/humanode-network/substrate", branch = "master" } thiserror = "1" @@ -27,7 +23,11 @@ thiserror = "1" mockall = "0.10" node-primitives = { git = "https://github.com/humanode-network/substrate", branch = "master" } sc-service = { git = "https://github.com/humanode-network/substrate", branch = "master" } -sp-core = { git = "https://github.com/humanode-network/substrate", branch = "master" } tokio = { version = "1", features = ["full"] } [features] +default = [] +test = ["all"] +all = ["aura-integration", "bioauth-pallet-integration"] +aura-integration = ["sp-consensus-aura", "sp-application-crypto"] +bioauth-pallet-integration = ["pallet-bioauth"] diff --git a/crates/bioauth-consensus/src/aura.rs b/crates/bioauth-consensus/src/aura.rs new file mode 100644 index 000000000..60ec0ba85 --- /dev/null +++ b/crates/bioauth-consensus/src/aura.rs @@ -0,0 +1,94 @@ +//! Aura consensus integration. + +use sp_api::{BlockId, Decode, ProvideRuntimeApi}; +use sp_application_crypto::Public; +use sp_blockchain::HeaderBackend; +use sp_consensus_aura::{AuraApi, Slot}; +use sp_runtime::generic::OpaqueDigestItemId; +use sp_runtime::traits::{Block as BlockT, Header}; +use std::{marker::PhantomData, sync::Arc}; + +/// Encapsulates block author extraction logic for aura consensus. +#[derive(Debug)] +pub struct BlockAuthorExtractor { + /// Client provides access to the runtime. + client: Arc, + /// The type from the block used in the chain. + _phantom_block: PhantomData, +} + +/// An error that can occur during block author extraction with the aura consensus. +#[derive(Debug, thiserror::Error)] +pub enum AuraBlockAuthorExtractorError { + /// Unable to extract aura authorities from the chain state via the runtime. + #[error("unable to extract aura authorities: {0}")] + UnableToExtractAuthorities(sp_api::ApiError), + /// Unable to obtain the slot from the block header. + #[error("unable to obtaion the slot from the block header")] + UnableToObtainSlot, + /// Unable to decode the slot. + #[error("unable to decode the slot")] + UnableToDecodeSlot, +} + +impl BlockAuthorExtractor { + /// Create a new [`AuraBlockAuthorExtractor`]. + pub fn new(client: Arc) -> Self { + Self { + client, + _phantom_block: PhantomData, + } + } +} + +impl Clone for BlockAuthorExtractor { + fn clone(&self) -> Self { + Self { + client: Arc::clone(&self.client), + _phantom_block: PhantomData, + } + } +} + +impl crate::BlockAuthorExtractor for BlockAuthorExtractor +where + Client: HeaderBackend + ProvideRuntimeApi, + Client::Api: AuraApi, +{ + type Error = AuraBlockAuthorExtractorError; + type Block = Block; + type PublicKeyType = Vec; + + fn extract_block_author( + &self, + at: &BlockId, + block_header: &::Header, + ) -> Result, Self::Error> { + // Extract aura authorities list. + let authorities = self + .client + .runtime_api() + .authorities(at) + .map_err(AuraBlockAuthorExtractorError::UnableToExtractAuthorities)?; + + // Extract the slot of a block. + let mut slot = block_header + .digest() + .log(|l| l.try_as_raw(OpaqueDigestItemId::PreRuntime(b"aura"))) + .ok_or(AuraBlockAuthorExtractorError::UnableToObtainSlot)?; + + // Decode slot number. + let slot_decoded = Slot::decode(&mut slot) + .map_err(|_| AuraBlockAuthorExtractorError::UnableToDecodeSlot)?; + + // Author index in aura is current slot number mod authories. + let author_index = *slot_decoded % authorities.len() as u64; + + // Determine the author of a block. + let author_public_key = authorities + .get(author_index as usize) + .expect("author index is mod authories list len; qed"); + + Ok(author_public_key.to_raw_vec()) + } +} diff --git a/crates/bioauth-consensus/src/bioauth.rs b/crates/bioauth-consensus/src/bioauth.rs new file mode 100644 index 000000000..902b9858f --- /dev/null +++ b/crates/bioauth-consensus/src/bioauth.rs @@ -0,0 +1,73 @@ +//! Bioauth pallet integration. + +use pallet_bioauth::BioauthApi; +use sp_api::{BlockId, ProvideRuntimeApi}; +use sp_blockchain::HeaderBackend; +use sp_runtime::traits::Block as BlockT; +use std::{marker::PhantomData, sync::Arc}; + +/// Provides an authorization verifier on top of stored auth tickets. +#[derive(Debug)] +pub struct AuthorizationVerifier { + /// The client provides access to the runtime. + client: Arc, + /// The type from the block used in the chain. + _phantom_block: PhantomData, +} + +/// An error that can occur during aura authorization verification. +#[derive(Debug, thiserror::Error)] +pub enum AuraAuthorizationVerifierError { + /// Something went wrong while extracting the stored auth tickets from the chain state via + /// the runtime. + #[error("unable to extract stored auth tickets: {0}")] + UnableToExtractStoredAuthTickets(sp_api::ApiError), +} + +impl AuthorizationVerifier { + /// Create a new [`AuraAuthorizationVerifier`]. + pub fn new(client: Arc) -> Self { + Self { + client, + _phantom_block: PhantomData, + } + } +} + +impl Clone for AuthorizationVerifier { + fn clone(&self) -> Self { + Self { + client: Arc::clone(&self.client), + _phantom_block: PhantomData, + } + } +} + +impl crate::AuthorizationVerifier for AuthorizationVerifier +where + Client: HeaderBackend + ProvideRuntimeApi, + Client::Api: BioauthApi, +{ + type Error = AuraAuthorizationVerifierError; + type Block = Block; + type PublicKeyType = [u8]; + + fn is_authorized( + &self, + at: &BlockId, + author_public_key: &Self::PublicKeyType, + ) -> Result { + // Get current stored tickets. + let stored_tickets = self + .client + .runtime_api() + .stored_auth_tickets(at) + .map_err(AuraAuthorizationVerifierError::UnableToExtractStoredAuthTickets)?; + + let is_authorized = stored_tickets + .iter() + .any(|ticket| ticket.public_key == author_public_key); + + Ok(is_authorized) + } +} diff --git a/crates/bioauth-consensus/src/lib.rs b/crates/bioauth-consensus/src/lib.rs index 6cc09ed30..000249cff 100644 --- a/crates/bioauth-consensus/src/lib.rs +++ b/crates/bioauth-consensus/src/lib.rs @@ -6,26 +6,36 @@ clippy::clone_on_ref_ptr )] -use pallet_bioauth::BioauthApi; use sc_client_api::{backend::Backend, Finalizer}; use sc_consensus::{BlockCheckParams, BlockImport, BlockImportParams, ImportResult}; -use sp_api::{Decode, ProvideRuntimeApi, TransactionFor}; -use sp_application_crypto::Public; +use sp_api::{ProvideRuntimeApi, TransactionFor}; use sp_blockchain::{well_known_cache_keys, HeaderBackend}; use sp_consensus::Error as ConsensusError; -use sp_consensus_aura::{AuraApi, Slot}; -use sp_runtime::generic::OpaqueDigestItemId; -use sp_runtime::traits::{Block as BlockT, Header}; +use sp_runtime::traits::Block as BlockT; use std::{collections::HashMap, marker::PhantomData, sync::Arc}; use thiserror::Error; +#[cfg(any(test, feature = "aura-integration"))] +pub mod aura; + +#[cfg(any(test, feature = "bioauth-pallet-integration"))] +pub mod bioauth; + #[cfg(test)] mod tests; +mod traits; + +pub use traits::*; + /// A block-import handler for Bioauth. -pub struct BioauthBlockImport { +pub struct BioauthBlockImport { /// The client to interact with the chain. inner: Arc, + /// The block author extractor. + block_author_extractor: BAX, + /// The bioauth auhtrization verifier. + authorization_verifier: AV, /// A phantom data for Backend. _phantom_back_end: PhantomData, /// A phantom data for Block. @@ -34,39 +44,48 @@ pub struct BioauthBlockImport { /// BioauthBlockImport Error Type. #[derive(Error, Debug, Eq, PartialEq)] -pub enum BioauthBlockImportError { - /// Block Author isn't Bioauth authorized. - #[error("Block Author isn't bioauth-authorized")] +pub enum BioauthBlockImportError +where + BAX: std::error::Error, + AV: std::error::Error, +{ + /// The block author isn't Bioauth authorized. + #[error("the block author isn't bioauth-authorized")] NotBioauthAuthorized, - /// Invalid slot number. - #[error("Invalid slot number")] - InvalidSlotNumber, - /// Error with extracting current stored auth tickets. - #[error("Can't get current stored auth tickets")] - ErrorExtractStoredAuthTickets, - /// Error with extracting current authorities list. - #[error("Can't get current authorities list")] - ErrorExtractAuthorities, + /// Block author extraction error. + #[error("unable to extract block author: {0}")] + BlockAuthorExtraction(BAX), + /// Authorization verification error. + #[error("unable verify the authorization: {0}")] + AuthorizationVerifier(AV), } -impl Clone for BioauthBlockImport { - fn clone(&self) -> Self { - BioauthBlockImport { - inner: Arc::clone(&self.inner), +impl BioauthBlockImport { + /// Simple constructor. + pub fn new(inner: Arc, block_author_extractor: BAX, authorization_verifier: AV) -> Self + where + BE: Backend + 'static, + { + Self { + inner, + block_author_extractor, + authorization_verifier, _phantom_back_end: PhantomData, _phantom_block: PhantomData, } } } -impl BioauthBlockImport { - /// Simple constructor. - pub fn new(inner: Arc) -> Self - where - BE: Backend + 'static, - { - BioauthBlockImport { - inner, +impl Clone for BioauthBlockImport +where + BAX: Clone, + AV: Clone, +{ + fn clone(&self) -> Self { + Self { + inner: Arc::clone(&self.inner), + block_author_extractor: self.block_author_extractor.clone(), + authorization_verifier: self.authorization_verifier.clone(), _phantom_back_end: PhantomData, _phantom_block: PhantomData, } @@ -74,14 +93,20 @@ impl BioauthBlockImport { } #[async_trait::async_trait] -impl BlockImport for BioauthBlockImport +impl BlockImport + for BioauthBlockImport where Client: HeaderBackend + ProvideRuntimeApi + Send + Sync + Finalizer, for<'a> &'a Client: BlockImport>, TransactionFor: 'static, - Client::Api: AuraApi, - Client::Api: BioauthApi, + BAX: BlockAuthorExtractor + Send, + AV: AuthorizationVerifier + Send, + ::PublicKeyType: Send, + ::PublicKeyType: + AsRef<::PublicKeyType>, + ::Error: std::error::Error + Send + Sync + 'static, + ::Error: std::error::Error + Send + Sync + 'static, BE: Backend, { type Error = ConsensusError; @@ -104,64 +129,29 @@ where cache: HashMap>, ) -> Result { // Extract a number of the last imported block. - let at = &sp_api::BlockId::Hash(self.inner.info().best_hash); - - // Extract current valid Aura authorities list. - let authorities = self.inner.runtime_api().authorities(at).map_err(|_| { - sp_consensus::Error::Other(Box::new(BioauthBlockImportError::ErrorExtractAuthorities)) - })?; - - // Extract current slot of a new produced block. - let mut slot = block - .header - .digest() - .log(|l| l.try_as_raw(OpaqueDigestItemId::PreRuntime(b"aura"))) - .ok_or_else(|| { - sp_consensus::Error::Other(Box::new(BioauthBlockImportError::InvalidSlotNumber)) - })?; - - // Decode slot number. - let slot_decoded = Slot::decode(&mut slot).map_err(|_| { - sp_consensus::Error::Other(Box::new(BioauthBlockImportError::InvalidSlotNumber)) - })?; - - // Get Author index of a new proposed block. - let author_index = *slot_decoded % authorities.len() as u64; - - // Determine an Author of a new proposed block. - let author_public_key = - authorities - .get(author_index as usize) - .cloned() - .ok_or_else(|| { - sp_consensus::Error::Other(Box::new(BioauthBlockImportError::InvalidSlotNumber)) - })?; - let author_public_key = author_public_key.as_slice(); - - // Get current stored tickets. - let stored_tickets = self - .inner - .runtime_api() - .stored_auth_tickets(at) - .map_err(|_| { - sp_consensus::Error::Other(Box::new( - BioauthBlockImportError::ErrorExtractStoredAuthTickets, - )) - })?; - - let is_authorized = stored_tickets - .iter() - .any(|ticket| ticket.public_key == author_public_key); + let at = sp_api::BlockId::Hash(self.inner.info().best_hash); + + let mkerr = |err: BioauthBlockImportError| -> ConsensusError { + ConsensusError::Other(Box::new(err)) + }; + + let author_public_key = self + .block_author_extractor + .extract_block_author(&at, &block.header) + .map_err(|err| mkerr(BioauthBlockImportError::BlockAuthorExtraction(err)))?; + + let is_authorized = self + .authorization_verifier + .is_authorized(&at, author_public_key.as_ref()) + .map_err(|err| mkerr(BioauthBlockImportError::AuthorizationVerifier(err)))?; if !is_authorized { - return Err(sp_consensus::Error::Other(Box::new( - BioauthBlockImportError::NotBioauthAuthorized, - ))); + return Err(mkerr(BioauthBlockImportError::NotBioauthAuthorized)); } // Finalize previous imported block. self.inner - .finalize_block(*at, None, false) + .finalize_block(at, None, false) .map_err(|_| sp_consensus::Error::CannotPropose)?; // Import a new block. diff --git a/crates/bioauth-consensus/src/tests.rs b/crates/bioauth-consensus/src/tests.rs index 6257425c2..0dac1c939 100644 --- a/crates/bioauth-consensus/src/tests.rs +++ b/crates/bioauth-consensus/src/tests.rs @@ -1,17 +1,20 @@ -use super::*; use mockall::predicate::*; use mockall::*; use node_primitives::{Block, BlockNumber, Hash, Header}; -use pallet_bioauth::StoredAuthTicket; -use sp_api::{ApiError, ApiRef, NativeOrEncoded}; -use sp_consensus::BlockOrigin; -use sp_consensus_aura::digests::CompatibleDigestItem; -use sp_consensus_aura::sr25519::AuthorityId as AuraId; -use sp_consensus_aura::Slot; -use sp_core::crypto::Pair; -use sp_runtime::traits::DigestItemFor; -use sp_runtime::Digest; -use std::str::FromStr; +use pallet_bioauth::{BioauthApi, StoredAuthTicket}; +use sc_client_api::Finalizer; +use sc_consensus::{BlockCheckParams, BlockImport, BlockImportParams, ImportResult}; +use sp_api::{ApiError, ApiRef, NativeOrEncoded, ProvideRuntimeApi, TransactionFor}; +use sp_application_crypto::{Pair, Public}; +use sp_blockchain::{well_known_cache_keys, HeaderBackend}; +use sp_consensus::{BlockOrigin, Error as ConsensusError}; +use sp_consensus_aura::{ + digests::CompatibleDigestItem, sr25519::AuthorityId as AuraId, AuraApi, Slot, +}; +use sp_runtime::{traits::DigestItemFor, Digest}; +use std::{collections::HashMap, str::FromStr, sync::Arc}; + +use crate::{BioauthBlockImport, BioauthBlockImportError}; mock! { RuntimeApi { @@ -175,14 +178,37 @@ fn prepare_block_import_with_aura_pre_digest( ) } -fn assert_sp_consensus_error(err: sp_consensus::Error, bioauth_err: BioauthBlockImportError) { - if let sp_consensus::Error::Other(e) = err { - if let Some(v) = e.downcast_ref::() { - assert_eq!(*v, bioauth_err); - return; +fn extract_bioauth_err( + err: &sp_consensus::Error, +) -> &BioauthBlockImportError< + crate::aura::AuraBlockAuthorExtractorError, + crate::bioauth::AuraAuthorizationVerifierError, +> { + if let sp_consensus::Error::Other(boxed_err) = err { + if let Some(raw_err) = boxed_err.downcast_ref::>() { + return raw_err; + } + } + panic!("Unexpected consensus error: {}", err); +} + +macro_rules! assert_consensus_error { + ($expression:expr, $( $pattern:pat_param )|+ $( if $guard: expr )? $(,)?) => { + { + let err_hold = $expression; + let err = extract_bioauth_err(&err_hold); + match err { + $( $pattern )|+ $( if $guard )? => (), + ref e => panic!( + "assertion failed: `{:?}` does not match `{}`", + e, stringify!($( $pattern )|+ $( if $guard )?) + ) + } } } - panic!("Unexpected error"); } #[tokio::test] @@ -207,7 +233,13 @@ async fn it_denies_block_import_with_error_extract_authorities() { sc_service::TFullBackend, _, MockClient, - > = BioauthBlockImport::new(Arc::clone(&client)); + _, + _, + > = BioauthBlockImport::new( + Arc::clone(&client), + crate::aura::BlockAuthorExtractor::new(Arc::clone(&client)), + crate::bioauth::AuthorizationVerifier::new(Arc::clone(&client)), + ); let res = bioauth_block_import .import_block( @@ -216,9 +248,11 @@ async fn it_denies_block_import_with_error_extract_authorities() { ) .await; - assert_sp_consensus_error( + assert_consensus_error!( res.unwrap_err(), - BioauthBlockImportError::ErrorExtractAuthorities, + BioauthBlockImportError::BlockAuthorExtraction( + crate::aura::AuraBlockAuthorExtractorError::UnableToExtractAuthorities(err), + ) if err.to_string() == "Test error", ); } @@ -248,7 +282,13 @@ async fn it_denies_block_import_with_invalid_slot_number() { sc_service::TFullBackend, _, MockClient, - > = BioauthBlockImport::new(Arc::clone(&client)); + _, + _, + > = BioauthBlockImport::new( + Arc::clone(&client), + crate::aura::BlockAuthorExtractor::new(Arc::clone(&client)), + crate::bioauth::AuthorizationVerifier::new(Arc::clone(&client)), + ); let res = bioauth_block_import .import_block( @@ -257,7 +297,10 @@ async fn it_denies_block_import_with_invalid_slot_number() { ) .await; - assert_sp_consensus_error(res.unwrap_err(), BioauthBlockImportError::InvalidSlotNumber); + assert_consensus_error!( + res.unwrap_err(), + BioauthBlockImportError::BlockAuthorExtraction(_) + ); } #[tokio::test] @@ -292,7 +335,13 @@ async fn it_denies_block_import_with_error_extract_stored_auth_ticket() { sc_service::TFullBackend, _, MockClient, - > = BioauthBlockImport::new(Arc::clone(&client)); + _, + _, + > = BioauthBlockImport::new( + Arc::clone(&client), + crate::aura::BlockAuthorExtractor::new(Arc::clone(&client)), + crate::bioauth::AuthorizationVerifier::new(Arc::clone(&client)), + ); let res = bioauth_block_import .import_block( @@ -301,9 +350,11 @@ async fn it_denies_block_import_with_error_extract_stored_auth_ticket() { ) .await; - assert_sp_consensus_error( + assert_consensus_error!( res.unwrap_err(), - BioauthBlockImportError::ErrorExtractStoredAuthTickets, + BioauthBlockImportError::AuthorizationVerifier( + crate::bioauth::AuraAuthorizationVerifierError::UnableToExtractStoredAuthTickets(_) + ), ); } @@ -344,7 +395,13 @@ async fn it_denies_block_import_with_not_bioauth_authorized() { sc_service::TFullBackend, _, MockClient, - > = BioauthBlockImport::new(Arc::clone(&client)); + _, + _, + > = BioauthBlockImport::new( + Arc::clone(&client), + crate::aura::BlockAuthorExtractor::new(Arc::clone(&client)), + crate::bioauth::AuthorizationVerifier::new(Arc::clone(&client)), + ); let res = bioauth_block_import .import_block( @@ -353,7 +410,7 @@ async fn it_denies_block_import_with_not_bioauth_authorized() { ) .await; - assert_sp_consensus_error( + assert_consensus_error!( res.unwrap_err(), BioauthBlockImportError::NotBioauthAuthorized, ); @@ -410,7 +467,13 @@ async fn it_permits_block_import_with_valid_data() { sc_service::TFullBackend, _, MockClient, - > = BioauthBlockImport::new(Arc::clone(&client)); + _, + _, + > = BioauthBlockImport::new( + Arc::clone(&client), + crate::aura::BlockAuthorExtractor::new(Arc::clone(&client)), + crate::bioauth::AuthorizationVerifier::new(Arc::clone(&client)), + ); let res = bioauth_block_import .import_block( diff --git a/crates/bioauth-consensus/src/traits.rs b/crates/bioauth-consensus/src/traits.rs new file mode 100644 index 000000000..64a5eaf2d --- /dev/null +++ b/crates/bioauth-consensus/src/traits.rs @@ -0,0 +1,41 @@ +//! Traits for abstracting away the integration with the underlying consensus. + +use sp_api::BlockId; +use sp_runtime::traits::Block as BlockT; + +/// BlockAuthorExtractor provides functionality to extract +/// block author public key for a particular block. +pub trait BlockAuthorExtractor { + /// An error that can occur during block author extraction. + type Error; + /// The block type used in the chain. + type Block: BlockT; + /// The public key type used by the block authors to sign blocks. + type PublicKeyType; + + /// Extract the public key used to sign the block from the specified block header. + fn extract_block_author( + &self, + at: &BlockId, + block_header: &::Header, + ) -> Result; +} + +/// AuthorizationVerifier provides a functionality to verify +/// whether a particular author is authorized to be a validator. +pub trait AuthorizationVerifier { + /// An error that can occur during the authrization verification. + type Error; + /// The block type used in the chain. + type Block: BlockT; + /// The public key that is used for block signing by validators. + type PublicKeyType: ?Sized; + + /// Verify that a provided validator public key is authorized for the purposes to produce + /// blocks for the bioauth purposes. + fn is_authorized( + &self, + at: &BlockId, + public_key: &Self::PublicKeyType, + ) -> Result; +} diff --git a/crates/humanode-peer/Cargo.toml b/crates/humanode-peer/Cargo.toml index eaff56ab9..591683b8a 100644 --- a/crates/humanode-peer/Cargo.toml +++ b/crates/humanode-peer/Cargo.toml @@ -6,7 +6,10 @@ authors = ["Humanode Team "] publish = false [dependencies] -bioauth-consensus = { version = "0.1", path = "../bioauth-consensus" } +bioauth-consensus = { version = "0.1", path = "../bioauth-consensus", features = [ + "aura-integration", + "bioauth-pallet-integration", +] } bioauth-flow = { version = "0.1", path = "../bioauth-flow" } humanode-rpc = { version = "0.1", path = "../humanode-rpc" } humanode-runtime = { version = "0.1", path = "../humanode-runtime" } diff --git a/crates/humanode-peer/src/service.rs b/crates/humanode-peer/src/service.rs index 2518025c9..e83d9f042 100644 --- a/crates/humanode-peer/src/service.rs +++ b/crates/humanode-peer/src/service.rs @@ -50,7 +50,13 @@ pub fn new_partial( sc_consensus::DefaultImportQueue, sc_transaction_pool::FullPool, ( - bioauth_consensus::BioauthBlockImport, + bioauth_consensus::BioauthBlockImport< + FullBackend, + Block, + FullClient, + bioauth_consensus::aura::BlockAuthorExtractor, + bioauth_consensus::bioauth::AuthorizationVerifier, + >, SlotDuration, Duration, ), @@ -74,8 +80,17 @@ pub fn new_partial( ); let select_chain = sc_consensus::LongestChain::new(Arc::clone(&backend)); - let bioauth_consensus_block_import: bioauth_consensus::BioauthBlockImport = - bioauth_consensus::BioauthBlockImport::new(Arc::clone(&client)); + let bioauth_consensus_block_import: bioauth_consensus::BioauthBlockImport< + FullBackend, + _, + _, + _, + _, + > = bioauth_consensus::BioauthBlockImport::new( + Arc::clone(&client), + bioauth_consensus::aura::BlockAuthorExtractor::new(Arc::clone(&client)), + bioauth_consensus::bioauth::AuthorizationVerifier::new(Arc::clone(&client)), + ); let slot_duration = sc_consensus_aura::slot_duration(&*client)?; let raw_slot_duration = slot_duration.slot_duration();