mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 11:07:56 +00:00
Move proof generation to the type system level (#8185)
* Start * Finish!!!! * Update client/basic-authorship/src/basic_authorship.rs Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> * Review comments Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>
This commit is contained in:
@@ -36,7 +36,7 @@ use sp_runtime::{
|
||||
generic::BlockId, traits::{Block as BlockT, DigestFor, NumberFor, HashFor},
|
||||
};
|
||||
use futures::prelude::*;
|
||||
pub use sp_inherents::InherentData;
|
||||
use sp_state_machine::StorageProof;
|
||||
|
||||
pub mod block_validation;
|
||||
pub mod offline_tracker;
|
||||
@@ -55,6 +55,7 @@ pub use block_import::{
|
||||
pub use select_chain::SelectChain;
|
||||
pub use sp_state_machine::Backend as StateBackend;
|
||||
pub use import_queue::DefaultImportQueue;
|
||||
pub use sp_inherents::InherentData;
|
||||
|
||||
/// Block status.
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
@@ -89,53 +90,81 @@ pub trait Environment<B: BlockT> {
|
||||
}
|
||||
|
||||
/// A proposal that is created by a [`Proposer`].
|
||||
pub struct Proposal<Block: BlockT, Transaction> {
|
||||
pub struct Proposal<Block: BlockT, Transaction, Proof> {
|
||||
/// The block that was build.
|
||||
pub block: Block,
|
||||
/// Optional proof that was recorded while building the block.
|
||||
pub proof: Option<sp_state_machine::StorageProof>,
|
||||
/// Proof that was recorded while building the block.
|
||||
pub proof: Proof,
|
||||
/// The storage changes while building this block.
|
||||
pub storage_changes: sp_state_machine::StorageChanges<Transaction, HashFor<Block>, NumberFor<Block>>,
|
||||
}
|
||||
|
||||
/// Used as parameter to [`Proposer`] to tell the requirement on recording a proof.
|
||||
/// Error that is returned when [`ProofRecording`] requested to record a proof,
|
||||
/// but no proof was recorded.
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[error("Proof should be recorded, but no proof was provided.")]
|
||||
pub struct NoProofRecorded;
|
||||
|
||||
/// A trait to express the state of proof recording on type system level.
|
||||
///
|
||||
/// When `RecordProof::Yes` is given, all accessed trie nodes should be saved. These recorded
|
||||
/// trie nodes can be used by a third party to proof this proposal without having access to the
|
||||
/// full storage.
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
pub enum RecordProof {
|
||||
/// `Yes`, record a proof.
|
||||
Yes,
|
||||
/// `No`, don't record any proof.
|
||||
No,
|
||||
/// This is used by [`Proposer`] to signal if proof recording is enabled. This can be used by
|
||||
/// downstream users of the [`Proposer`] trait to enforce that proof recording is activated when
|
||||
/// required. The only two implementations of this trait are [`DisableProofRecording`] and
|
||||
/// [`EnableProofRecording`].
|
||||
///
|
||||
/// This trait is sealed and can not be implemented outside of this crate!
|
||||
pub trait ProofRecording: Send + Sync + private::Sealed + 'static {
|
||||
/// The proof type that will be used internally.
|
||||
type Proof: Send + Sync + 'static;
|
||||
/// Is proof recording enabled?
|
||||
const ENABLED: bool;
|
||||
/// Convert the given `storage_proof` into [`Self::Proof`].
|
||||
///
|
||||
/// Internally Substrate uses `Option<StorageProof>` to express the both states of proof
|
||||
/// recording (for now) and as [`Self::Proof`] is some different type, we need to provide a
|
||||
/// function to convert this value.
|
||||
///
|
||||
/// If the proof recording was requested, but `None` is given, this will return
|
||||
/// `Err(NoProofRecorded)`.
|
||||
fn into_proof(storage_proof: Option<StorageProof>) -> Result<Self::Proof, NoProofRecorded>;
|
||||
}
|
||||
|
||||
impl RecordProof {
|
||||
/// Returns if `Self` == `Yes`.
|
||||
pub fn yes(&self) -> bool {
|
||||
match self {
|
||||
Self::Yes => true,
|
||||
Self::No => false,
|
||||
}
|
||||
/// Express that proof recording is disabled.
|
||||
///
|
||||
/// For more information see [`ProofRecording`].
|
||||
pub struct DisableProofRecording;
|
||||
|
||||
impl ProofRecording for DisableProofRecording {
|
||||
type Proof = ();
|
||||
const ENABLED: bool = false;
|
||||
|
||||
fn into_proof(_: Option<StorageProof>) -> Result<Self::Proof, NoProofRecorded> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Will return [`RecordProof::No`] as default value.
|
||||
impl Default for RecordProof {
|
||||
fn default() -> Self {
|
||||
Self::No
|
||||
/// Express that proof recording is enabled.
|
||||
///
|
||||
/// For more information see [`ProofRecording`].
|
||||
pub struct EnableProofRecording;
|
||||
|
||||
impl ProofRecording for EnableProofRecording {
|
||||
type Proof = sp_state_machine::StorageProof;
|
||||
const ENABLED: bool = true;
|
||||
|
||||
fn into_proof(proof: Option<StorageProof>) -> Result<Self::Proof, NoProofRecorded> {
|
||||
proof.ok_or_else(|| NoProofRecorded)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<bool> for RecordProof {
|
||||
fn from(val: bool) -> Self {
|
||||
if val {
|
||||
Self::Yes
|
||||
} else {
|
||||
Self::No
|
||||
}
|
||||
}
|
||||
/// Provides `Sealed` trait to prevent implementing trait [`ProofRecording`] outside of this crate.
|
||||
mod private {
|
||||
/// Special trait that prevents the implementation of [`super::ProofRecording`] outside of this
|
||||
/// crate.
|
||||
pub trait Sealed {}
|
||||
|
||||
impl Sealed for super::DisableProofRecording {}
|
||||
impl Sealed for super::EnableProofRecording {}
|
||||
}
|
||||
|
||||
/// Logic for a proposer.
|
||||
@@ -150,8 +179,16 @@ pub trait Proposer<B: BlockT> {
|
||||
/// The transaction type used by the backend.
|
||||
type Transaction: Default + Send + 'static;
|
||||
/// Future that resolves to a committed proposal with an optional proof.
|
||||
type Proposal: Future<Output = Result<Proposal<B, Self::Transaction>, Self::Error>> +
|
||||
Send + Unpin + 'static;
|
||||
type Proposal:
|
||||
Future<Output = Result<Proposal<B, Self::Transaction, Self::Proof>, Self::Error>>
|
||||
+ Send
|
||||
+ Unpin
|
||||
+ 'static;
|
||||
/// The supported proof recording by the implementator of this trait. See [`ProofRecording`]
|
||||
/// for more information.
|
||||
type ProofRecording: self::ProofRecording<Proof = Self::Proof> + Send + Sync + 'static;
|
||||
/// The proof type used by [`Self::ProofRecording`].
|
||||
type Proof: Send + Sync + 'static;
|
||||
|
||||
/// Create a proposal.
|
||||
///
|
||||
@@ -167,7 +204,6 @@ pub trait Proposer<B: BlockT> {
|
||||
inherent_data: InherentData,
|
||||
inherent_digests: DigestFor<B>,
|
||||
max_duration: Duration,
|
||||
record_proof: RecordProof,
|
||||
) -> Self::Proposal;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user