mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-09 12:49:23 +00:00
Initial work on an import queue
This commit is contained in:
5
Cargo.lock
generated
5
Cargo.lock
generated
@@ -7426,6 +7426,7 @@ checksum = "930c0acf610d3fdb5e2ab6213019aaa04e227ebe9547b0649ba599b16d788bd7"
|
|||||||
name = "serai-consensus"
|
name = "serai-consensus"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
"sc-basic-authorship",
|
"sc-basic-authorship",
|
||||||
"sc-client-api",
|
"sc-client-api",
|
||||||
"sc-consensus",
|
"sc-consensus",
|
||||||
@@ -7436,13 +7437,17 @@ dependencies = [
|
|||||||
"sc-transaction-pool",
|
"sc-transaction-pool",
|
||||||
"serai-runtime",
|
"serai-runtime",
|
||||||
"sp-api",
|
"sp-api",
|
||||||
|
"sp-application-crypto",
|
||||||
|
"sp-blockchain",
|
||||||
"sp-consensus",
|
"sp-consensus",
|
||||||
"sp-consensus-pow",
|
"sp-consensus-pow",
|
||||||
"sp-core",
|
"sp-core",
|
||||||
|
"sp-inherents",
|
||||||
"sp-runtime",
|
"sp-runtime",
|
||||||
"sp-timestamp",
|
"sp-timestamp",
|
||||||
"sp-trie",
|
"sp-trie",
|
||||||
"substrate-prometheus-endpoint",
|
"substrate-prometheus-endpoint",
|
||||||
|
"tendermint-machine",
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -13,11 +13,24 @@ all-features = true
|
|||||||
rustdoc-args = ["--cfg", "docsrs"]
|
rustdoc-args = ["--cfg", "docsrs"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
async-trait = "0.1"
|
||||||
|
|
||||||
sp-core = { git = "https://github.com/serai-dex/substrate" }
|
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-trie = { git = "https://github.com/serai-dex/substrate" }
|
||||||
sp-timestamp = { 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-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-consensus-pow = { 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-network = { git = "https://github.com/serai-dex/substrate" }
|
||||||
sc-service = { git = "https://github.com/serai-dex/substrate", features = ["wasmtime"] }
|
sc-service = { git = "https://github.com/serai-dex/substrate", features = ["wasmtime"] }
|
||||||
sc-executor = { 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" }
|
substrate-prometheus-endpoint = { git = "https://github.com/serai-dex/substrate" }
|
||||||
|
|
||||||
sc-client-api = { 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" }
|
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};
|
use serai_runtime::{self, opaque::Block, RuntimeApi};
|
||||||
|
|
||||||
mod algorithm;
|
mod algorithm;
|
||||||
mod tendermint;
|
|
||||||
|
mod signature_scheme;
|
||||||
|
mod import;
|
||||||
|
//mod tendermint;
|
||||||
|
|
||||||
pub struct ExecutorDispatch;
|
pub struct ExecutorDispatch;
|
||||||
impl sc_executor::NativeExecutionDispatch for ExecutorDispatch {
|
impl sc_executor::NativeExecutionDispatch for ExecutorDispatch {
|
||||||
|
|||||||
Reference in New Issue
Block a user