mirror of
https://github.com/serai-dex/serai.git
synced 2025-03-12 09:26:51 +00:00
Initial work on an import queue
This commit is contained in:
parent
975c9d7456
commit
eb59dd5a55
4 changed files with 155 additions and 5 deletions
5
Cargo.lock
generated
5
Cargo.lock
generated
|
@ -7426,6 +7426,7 @@ checksum = "930c0acf610d3fdb5e2ab6213019aaa04e227ebe9547b0649ba599b16d788bd7"
|
|||
name = "serai-consensus"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"sc-basic-authorship",
|
||||
"sc-client-api",
|
||||
"sc-consensus",
|
||||
|
@ -7436,13 +7437,17 @@ dependencies = [
|
|||
"sc-transaction-pool",
|
||||
"serai-runtime",
|
||||
"sp-api",
|
||||
"sp-application-crypto",
|
||||
"sp-blockchain",
|
||||
"sp-consensus",
|
||||
"sp-consensus-pow",
|
||||
"sp-core",
|
||||
"sp-inherents",
|
||||
"sp-runtime",
|
||||
"sp-timestamp",
|
||||
"sp-trie",
|
||||
"substrate-prometheus-endpoint",
|
||||
"tendermint-machine",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
|
|
|
@ -13,11 +13,24 @@ all-features = true
|
|||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
||||
[dependencies]
|
||||
async-trait = "0.1"
|
||||
|
||||
sp-core = { git = "https://github.com/serai-dex/substrate" }
|
||||
sp-application-crypto = { git = "https://github.com/serai-dex/substrate" }
|
||||
sp-inherents = { git = "https://github.com/serai-dex/substrate" }
|
||||
sp-runtime = { git = "https://github.com/serai-dex/substrate" }
|
||||
sp-blockchain = { 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" }
|
||||
sc-consensus = { git = "https://github.com/serai-dex/substrate" }
|
||||
|
||||
tendermint-machine = { path = "../tendermint" }
|
||||
|
||||
# --
|
||||
|
||||
sp-trie = { git = "https://github.com/serai-dex/substrate" }
|
||||
sp-timestamp = { git = "https://github.com/serai-dex/substrate" }
|
||||
sc-consensus = { git = "https://github.com/serai-dex/substrate" }
|
||||
sp-consensus = { 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-consensus-pow = { git = "https://github.com/serai-dex/substrate" }
|
||||
|
@ -26,12 +39,10 @@ sp-consensus-pow = { git = "https://github.com/serai-dex/substrate" }
|
|||
sc-network = { git = "https://github.com/serai-dex/substrate" }
|
||||
sc-service = { git = "https://github.com/serai-dex/substrate", features = ["wasmtime"] }
|
||||
sc-executor = { git = "https://github.com/serai-dex/substrate", features = ["wasmtime"] }
|
||||
sp-runtime = { git = "https://github.com/serai-dex/substrate" }
|
||||
|
||||
substrate-prometheus-endpoint = { git = "https://github.com/serai-dex/substrate" }
|
||||
|
||||
sc-client-api = { git = "https://github.com/serai-dex/substrate" }
|
||||
sp-api = { git = "https://github.com/serai-dex/substrate" }
|
||||
|
||||
serai-runtime = { path = "../runtime" }
|
||||
|
||||
|
|
131
substrate/consensus/src/import.rs
Normal file
131
substrate/consensus/src/import.rs
Normal file
|
@ -0,0 +1,131 @@
|
|||
use std::{marker::PhantomData, sync::Arc, collections::HashMap};
|
||||
|
||||
use sp_core::Decode;
|
||||
use sp_inherents::CreateInherentDataProviders;
|
||||
use sp_runtime::traits::{Header, Block};
|
||||
use sp_blockchain::HeaderBackend;
|
||||
use sp_api::{ProvideRuntimeApi, TransactionFor};
|
||||
|
||||
use sp_consensus::{Error, CacheKeyId};
|
||||
#[rustfmt::skip]
|
||||
use sc_consensus::{
|
||||
ForkChoiceStrategy,
|
||||
BlockCheckParams,
|
||||
BlockImportParams,
|
||||
ImportResult,
|
||||
BlockImport,
|
||||
};
|
||||
|
||||
use tendermint_machine::ext::*;
|
||||
|
||||
use crate::signature_scheme::TendermintSigner;
|
||||
|
||||
struct TendermintBlockImport<
|
||||
B: Block,
|
||||
C: Send + Sync + HeaderBackend<B> + ProvideRuntimeApi<B> + 'static,
|
||||
I: Send + Sync + BlockImport<B, Transaction = TransactionFor<C, B>>,
|
||||
CIDP: CreateInherentDataProviders<B, ()>,
|
||||
> {
|
||||
_block: PhantomData<B>,
|
||||
client: Arc<C>,
|
||||
inner: I,
|
||||
providers: Arc<CIDP>,
|
||||
}
|
||||
|
||||
impl<
|
||||
B: Block,
|
||||
C: Send + Sync + HeaderBackend<B> + ProvideRuntimeApi<B>,
|
||||
I: Send + Sync + BlockImport<B, Transaction = TransactionFor<C, B>>,
|
||||
CIDP: CreateInherentDataProviders<B, ()>,
|
||||
> TendermintBlockImport<B, C, I, CIDP>
|
||||
{
|
||||
async fn check_inherents(
|
||||
&self,
|
||||
block: B,
|
||||
providers: CIDP::InherentDataProviders,
|
||||
) -> Result<(), Error> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
// The Tendermint machine will call add_block for any block which is committed to, regardless of
|
||||
// validity. To determine validity, it expects a validate function, which Substrate doesn't
|
||||
// directly offer, and an add function. In order to comply with Serai's modified view of inherent
|
||||
// transactions, validate MUST check inherents, yet add_block must not.
|
||||
//
|
||||
// In order to acquire a validate function, any block proposed by a legitimate proposer is
|
||||
// imported. This performs full validation and makes the block available as a tip. While this would
|
||||
// be incredibly unsafe thanks to the unchecked inherents, it's defined as a tip with less work,
|
||||
// despite being a child of some parent. This means it won't be moved to nor operated on by the
|
||||
// node.
|
||||
//
|
||||
// When Tendermint completes, the block is finalized, setting it as the tip regardless of work.
|
||||
|
||||
const CONSENSUS_ID: [u8; 4] = *b"tend";
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl<
|
||||
B: Block,
|
||||
C: Send + Sync + HeaderBackend<B> + ProvideRuntimeApi<B>,
|
||||
I: Send + Sync + BlockImport<B, Transaction = TransactionFor<C, B>>,
|
||||
CIDP: CreateInherentDataProviders<B, ()>,
|
||||
> BlockImport<B> for TendermintBlockImport<B, C, I, CIDP>
|
||||
where
|
||||
I::Error: Into<Error>,
|
||||
{
|
||||
type Error = Error;
|
||||
type Transaction = TransactionFor<C, B>;
|
||||
|
||||
async fn check_block(&mut self, block: BlockCheckParams<B>) -> Result<ImportResult, Self::Error> {
|
||||
self.inner.check_block(block).await.map_err(Into::into)
|
||||
}
|
||||
|
||||
async fn import_block(
|
||||
&mut self,
|
||||
mut block: BlockImportParams<B, Self::Transaction>,
|
||||
new_cache: HashMap<CacheKeyId, Vec<u8>>,
|
||||
) -> Result<ImportResult, Self::Error> {
|
||||
let parent_hash = *block.header.parent_hash();
|
||||
if self.client.info().best_hash != parent_hash {
|
||||
Err(Error::Other("non-sequential import".into()))?;
|
||||
}
|
||||
|
||||
if let Some(body) = block.body.clone() {
|
||||
if let Some(justifications) = block.justifications {
|
||||
let mut iter = justifications.iter();
|
||||
let next = iter.next();
|
||||
if next.is_none() || iter.next().is_some() {
|
||||
Err(Error::InvalidJustification)?;
|
||||
}
|
||||
let justification = next.unwrap();
|
||||
|
||||
let commit: Commit<TendermintSigner> =
|
||||
Commit::decode(&mut justification.1.as_ref()).map_err(|_| Error::InvalidJustification)?;
|
||||
if justification.0 != CONSENSUS_ID {
|
||||
Err(Error::InvalidJustification)?;
|
||||
}
|
||||
|
||||
// verify_commit
|
||||
todo!()
|
||||
} else {
|
||||
self
|
||||
.check_inherents(
|
||||
B::new(block.header.clone(), body),
|
||||
self.providers.create_inherent_data_providers(parent_hash, ()).await?,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
|
||||
if !block.post_digests.is_empty() {
|
||||
Err(Error::Other("post-digests included".into()))?;
|
||||
}
|
||||
if !block.auxiliary.is_empty() {
|
||||
Err(Error::Other("auxiliary included".into()))?;
|
||||
}
|
||||
|
||||
block.fork_choice = Some(ForkChoiceStrategy::Custom(false));
|
||||
self.inner.import_block(block, new_cache).await.map_err(Into::into)
|
||||
}
|
||||
}
|
||||
|
|
@ -9,7 +9,10 @@ use sc_service::TaskManager;
|
|||
use serai_runtime::{self, opaque::Block, RuntimeApi};
|
||||
|
||||
mod algorithm;
|
||||
mod tendermint;
|
||||
|
||||
mod signature_scheme;
|
||||
mod import;
|
||||
//mod tendermint;
|
||||
|
||||
pub struct ExecutorDispatch;
|
||||
impl sc_executor::NativeExecutionDispatch for ExecutorDispatch {
|
||||
|
|
Loading…
Reference in a new issue