Skip to content

Commit

Permalink
cleanup block builder
Browse files Browse the repository at this point in the history
  • Loading branch information
vedhavyas committed Jan 7, 2025
1 parent 7a05903 commit a0b69b0
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 116 deletions.
117 changes: 6 additions & 111 deletions domains/client/block-builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,112 +32,37 @@ mod custom_api;
use codec::Encode;
pub use custom_api::{create_delta_backend, DeltaBackend};
use sc_client_api::backend;
use sp_api::{
ApiExt, ApiRef, Core, ProvideRuntimeApi, StorageChanges, StorageProof, TransactionOutcome,
};
use sp_api::{ApiExt, ApiRef, Core, ProvideRuntimeApi, StorageChanges, TransactionOutcome};
pub use sp_block_builder::BlockBuilder as BlockBuilderApi;
use sp_blockchain::{ApplyExtrinsicFailed, Error};
use sp_runtime::generic::BlockId;
use sp_runtime::traits::{Block as BlockT, Hash, HashingFor, Header as HeaderT, NumberFor, One};
use sp_runtime::Digest;
use std::collections::VecDeque;

/// Used as parameter to [`BlockBuilderProvider`] to express if proof recording should be enabled.
///
/// 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, Eq, PartialEq)]
pub enum RecordProof {
/// `Yes`, record a proof.
Yes,
/// `No`, don't record any proof.
No,
}

impl RecordProof {
/// Returns if `Self` == `Yes`.
pub fn yes(&self) -> bool {
matches!(self, Self::Yes)
}
}

/// Will return [`RecordProof::No`] as default value.
impl Default for RecordProof {
#[inline]
fn default() -> Self {
Self::No
}
}

impl From<bool> for RecordProof {
#[inline]
fn from(val: bool) -> Self {
if val {
Self::Yes
} else {
Self::No
}
}
}

/// A block that was build by [`BlockBuilder`] plus some additional data.
///
/// This additional data includes the `storage_changes`, these changes can be applied to the
/// backend to get the state of the block. Furthermore an optional `proof` is included which
/// can be used to proof that the build block contains the expected data. The `proof` will
/// only be set when proof recording was activated.
/// backend to get the state of the block.
pub struct BuiltBlock<Block: BlockT> {
/// The actual block that was build.
pub block: Block,
/// The changes that need to be applied to the backend to get the state of the build block.
pub storage_changes: StorageChanges<Block>,
/// An optional proof that was recorded while building the block.
pub proof: Option<StorageProof>,
}

impl<Block: BlockT> BuiltBlock<Block> {
/// Convert into the inner values.
pub fn into_inner(self) -> (Block, StorageChanges<Block>, Option<StorageProof>) {
(self.block, self.storage_changes, self.proof)
pub fn into_inner(self) -> (Block, StorageChanges<Block>) {
(self.block, self.storage_changes)
}
}

/// Block builder provider
pub trait BlockBuilderProvider<B, Block, RA>
where
Block: BlockT,
B: backend::Backend<Block>,
Self: Sized,
RA: ProvideRuntimeApi<Block>,
{
/// Create a new block, built on top of `parent`.
///
/// When proof recording is enabled, all accessed trie nodes are saved.
/// These recorded trie nodes can be used by a third party to proof the
/// output of this block builder without having access to the full storage.
fn new_block_at<R: Into<RecordProof>>(
&self,
parent: &BlockId<Block>,
inherent_digests: Digest,
record_proof: R,
) -> sp_blockchain::Result<BlockBuilder<Block, RA, B>>;

/// Create a new block, built on the head of the chain.
fn new_block(
&self,
inherent_digests: Digest,
) -> sp_blockchain::Result<BlockBuilder<Block, RA, B>>;
}

/// Utility for building new (valid) blocks from a stream of extrinsics.
pub struct BlockBuilder<'a, Block: BlockT, A: ProvideRuntimeApi<Block>, B> {
extrinsics: VecDeque<Block::Extrinsic>,
api: ApiRef<'a, A::Api>,
parent_hash: Block::Hash,
backend: &'a B,
/// The estimated size of the block header.
estimated_header_size: usize,
}

impl<'a, Block, A, B> BlockBuilder<'a, Block, A, B>
Expand All @@ -157,7 +82,6 @@ where
api: &'a A,
parent_hash: Block::Hash,
parent_number: NumberFor<Block>,
record_proof: RecordProof,
inherent_digests: Digest,
backend: &'a B,
mut extrinsics: VecDeque<Block::Extrinsic>,
Expand All @@ -171,14 +95,7 @@ where
inherent_digests,
);

let estimated_header_size = header.encoded_size();

let mut api = api.runtime_api();

if record_proof.yes() {
api.record_proof();
}

let api = api.runtime_api();
api.initialize_block(parent_hash, &header)?;

if let Some(inherent_data) = maybe_inherent_data {
Expand All @@ -195,7 +112,6 @@ where
extrinsics,
api,
backend,
estimated_header_size,
})
}

Expand Down Expand Up @@ -273,7 +189,7 @@ where
/// Returns the build `Block`, the changes to the storage and an optional `StorageProof`
/// supplied by `self.api`, combined as [`BuiltBlock`].
/// The storage proof will be `Some(_)` when proof recording was enabled.
pub fn build(mut self) -> Result<BuiltBlock<Block>, Error> {
pub fn build(self) -> Result<BuiltBlock<Block>, Error> {
self.execute_extrinsics()?;

let header = self.api.finalize_block(self.parent_hash)?;
Expand All @@ -286,14 +202,11 @@ where
),
);

let proof = self.api.extract_proof();

let storage_changes = self.collect_storage_changes()?;

Ok(BuiltBlock {
block: Block::new(header, self.extrinsics.into()),
storage_changes,
proof,
})
}

Expand All @@ -314,24 +227,6 @@ where
.map_err(|e| Error::Application(Box::new(e)))?;
Ok(VecDeque::from(exts))
}

/// Estimate the size of the block in the current state.
///
/// If `include_proof` is `true`, the estimated size of the storage proof will be added
/// to the estimation.
pub fn estimate_block_size(&self, include_proof: bool) -> usize {
let size = self.estimated_header_size + self.extrinsics.encoded_size();

if include_proof {
size + self
.api
.proof_recorder()
.map(|pr| pr.estimate_encoded_size())
.unwrap_or(0)
} else {
size
}
}
}

// TODO: Unlock this test, it got broken in https://github.com/autonomys/subspace/pull/1548 and
Expand Down
4 changes: 1 addition & 3 deletions domains/client/domain-operator/src/domain_block_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::fraud_proof::FraudProofGenerator;
use crate::utils::{DomainBlockImportNotification, DomainImportNotificationSinks};
use crate::ExecutionReceiptFor;
use codec::{Decode, Encode};
use domain_block_builder::{BlockBuilder, BuiltBlock, RecordProof};
use domain_block_builder::{BlockBuilder, BuiltBlock};
use domain_block_preprocessor::inherents::get_inherent_data;
use domain_block_preprocessor::PreprocessResult;
use sc_client_api::{AuxStore, BlockBackend, Finalizer, ProofProvider};
Expand Down Expand Up @@ -426,7 +426,6 @@ where
&*self.client,
parent_hash,
parent_number,
RecordProof::No,
inherent_digests,
&*self.backend,
extrinsics,
Expand All @@ -436,7 +435,6 @@ where
let BuiltBlock {
block,
storage_changes,
proof: _,
} = block_builder.build()?;

let (header, body) = block.deconstruct();
Expand Down
3 changes: 1 addition & 2 deletions domains/client/domain-operator/src/fraud_proof.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::aux_schema::BundleMismatchType;
use crate::ExecutionReceiptFor;
use codec::{Decode, Encode};
use domain_block_builder::{BlockBuilder, RecordProof};
use domain_block_builder::BlockBuilder;
use domain_runtime_primitives::opaque::AccountId;
use domain_runtime_primitives::CheckExtrinsicsValidityError;
use sc_client_api::{AuxStore, BlockBackend, ProofProvider};
Expand Down Expand Up @@ -232,7 +232,6 @@ where
&*self.client,
parent_header.hash(),
*parent_header.number(),
RecordProof::No,
inherent_digests.clone(),
&*self.backend,
extrinsics.into(),
Expand Down

0 comments on commit a0b69b0

Please sign in to comment.