diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock
index a65ca56cee..a5fa0aafcf 100644
--- a/substrate/Cargo.lock
+++ b/substrate/Cargo.lock
@@ -6691,7 +6691,6 @@ dependencies = [
"sp-api",
"sp-block-builder",
"sp-blockchain",
- "sp-consensus",
"sp-core",
"sp-inherents",
"sp-runtime",
diff --git a/substrate/bin/node/bench/src/construct.rs b/substrate/bin/node/bench/src/construct.rs
index a8a02f19c3..b64ffec641 100644
--- a/substrate/bin/node/bench/src/construct.rs
+++ b/substrate/bin/node/bench/src/construct.rs
@@ -48,7 +48,7 @@ use sp_transaction_pool::{
TransactionStatusStreamFor,
TxHash,
};
-use sp_consensus::{Environment, Proposer, RecordProof};
+use sp_consensus::{Environment, Proposer};
use crate::{
common::SizeType,
@@ -170,7 +170,6 @@ impl core::Benchmark for ConstructionBenchmark {
inherent_data_providers.create_inherent_data().expect("Create inherent data failed"),
Default::default(),
std::time::Duration::from_secs(20),
- RecordProof::Yes,
),
).map(|r| r.block).expect("Proposing failed");
diff --git a/substrate/bin/node/cli/src/service.rs b/substrate/bin/node/cli/src/service.rs
index 312a0226fc..b6cad3c52d 100644
--- a/substrate/bin/node/cli/src/service.rs
+++ b/substrate/bin/node/cli/src/service.rs
@@ -478,7 +478,6 @@ mod tests {
use sc_consensus_epochs::descendent_query;
use sp_consensus::{
Environment, Proposer, BlockImportParams, BlockOrigin, ForkChoiceStrategy, BlockImport,
- RecordProof,
};
use node_primitives::{Block, DigestItem, Signature};
use node_runtime::{BalancesCall, Call, UncheckedExtrinsic, Address};
@@ -611,7 +610,6 @@ mod tests {
inherent_data,
digest,
std::time::Duration::from_secs(1),
- RecordProof::Yes,
).await
}).expect("Error making test block").block;
diff --git a/substrate/client/basic-authorship/README.md b/substrate/client/basic-authorship/README.md
index 1a20593c09..d29ce258e5 100644
--- a/substrate/client/basic-authorship/README.md
+++ b/substrate/client/basic-authorship/README.md
@@ -20,7 +20,6 @@ let future = proposer.propose(
Default::default(),
Default::default(),
Duration::from_secs(2),
- RecordProof::Yes,
);
// We wait until the proposition is performed.
@@ -29,4 +28,4 @@ println!("Generated block: {:?}", block.block);
```
-License: GPL-3.0-or-later WITH Classpath-exception-2.0
\ No newline at end of file
+License: GPL-3.0-or-later WITH Classpath-exception-2.0
diff --git a/substrate/client/basic-authorship/src/basic_authorship.rs b/substrate/client/basic-authorship/src/basic_authorship.rs
index 067695e5a8..0c5bb7abef 100644
--- a/substrate/client/basic-authorship/src/basic_authorship.rs
+++ b/substrate/client/basic-authorship/src/basic_authorship.rs
@@ -23,7 +23,7 @@
use std::{pin::Pin, time, sync::Arc};
use sc_client_api::backend;
use codec::Decode;
-use sp_consensus::{evaluation, Proposal, RecordProof};
+use sp_consensus::{evaluation, Proposal, ProofRecording, DisableProofRecording, EnableProofRecording};
use sp_core::traits::SpawnNamed;
use sp_inherents::InherentData;
use log::{error, info, debug, trace, warn};
@@ -52,7 +52,7 @@ use sc_proposer_metrics::MetricsLink as PrometheusMetrics;
pub const DEFAULT_MAX_BLOCK_SIZE: usize = 4 * 1024 * 1024 + 512;
/// Proposer factory.
-pub struct ProposerFactory {
+pub struct ProposerFactory {
spawn_handle: Box,
/// The client instance.
client: Arc,
@@ -60,12 +60,15 @@ pub struct ProposerFactory {
transaction_pool: Arc,
/// Prometheus Link,
metrics: PrometheusMetrics,
- /// phantom member to pin the `Backend` type.
- _phantom: PhantomData,
+ /// phantom member to pin the `Backend`/`ProofRecording` type.
+ _phantom: PhantomData<(B, PR)>,
max_block_size: usize,
}
-impl ProposerFactory {
+impl ProposerFactory {
+ /// Create a new proposer factory.
+ ///
+ /// Proof recording will be disabled when using proposers built by this instance to build blocks.
pub fn new(
spawn_handle: impl SpawnNamed + 'static,
client: Arc,
@@ -81,7 +84,30 @@ impl ProposerFactory {
max_block_size: DEFAULT_MAX_BLOCK_SIZE,
}
}
+}
+impl ProposerFactory {
+ /// Create a new proposer factory with proof recording enabled.
+ ///
+ /// Each proposer created by this instance will record a proof while building a block.
+ pub fn with_proof_recording(
+ spawn_handle: impl SpawnNamed + 'static,
+ client: Arc,
+ transaction_pool: Arc,
+ prometheus: Option<&PrometheusRegistry>,
+ ) -> Self {
+ ProposerFactory {
+ spawn_handle: Box::new(spawn_handle),
+ client,
+ transaction_pool,
+ metrics: PrometheusMetrics::new(prometheus),
+ _phantom: PhantomData,
+ max_block_size: DEFAULT_MAX_BLOCK_SIZE,
+ }
+ }
+}
+
+impl ProposerFactory {
/// Set the maximum block size in bytes.
///
/// The default value for the maximum block size is:
@@ -91,7 +117,7 @@ impl ProposerFactory {
}
}
-impl ProposerFactory
+impl ProposerFactory
where
A: TransactionPool + 'static,
B: backend::Backend + Send + Sync + 'static,
@@ -101,18 +127,18 @@ impl ProposerFactory
C::Api: ApiExt>
+ BlockBuilderApi,
{
- pub fn init_with_now(
+ fn init_with_now(
&mut self,
parent_header: &::Header,
now: Box time::Instant + Send + Sync>,
- ) -> Proposer {
+ ) -> Proposer {
let parent_hash = parent_header.hash();
let id = BlockId::hash(parent_hash);
info!("🙌 Starting consensus session on top of parent {:?}", parent_hash);
- let proposer = Proposer {
+ let proposer = Proposer::<_, _, _, _, PR> {
spawn_handle: self.spawn_handle.clone(),
client: self.client.clone(),
parent_hash,
@@ -129,8 +155,8 @@ impl ProposerFactory
}
}
-impl sp_consensus::Environment for
- ProposerFactory
+impl sp_consensus::Environment for
+ ProposerFactory
where
A: TransactionPool + 'static,
B: backend::Backend + Send + Sync + 'static,
@@ -139,9 +165,10 @@ impl sp_consensus::Environment for
+ Send + Sync + 'static,
C::Api: ApiExt>
+ BlockBuilderApi,
+ PR: ProofRecording,
{
type CreateProposer = future::Ready>;
- type Proposer = Proposer;
+ type Proposer = Proposer;
type Error = sp_blockchain::Error;
fn init(
@@ -153,7 +180,7 @@ impl sp_consensus::Environment for
}
/// The proposer logic.
-pub struct Proposer {
+pub struct Proposer {
spawn_handle: Box,
client: Arc,
parent_hash: ::Hash,
@@ -162,12 +189,12 @@ pub struct Proposer {
transaction_pool: Arc,
now: Box time::Instant + Send + Sync>,
metrics: PrometheusMetrics,
- _phantom: PhantomData,
+ _phantom: PhantomData<(B, PR)>,
max_block_size: usize,
}
-impl sp_consensus::Proposer for
- Proposer
+impl sp_consensus::Proposer for
+ Proposer
where
A: TransactionPool + 'static,
B: backend::Backend + Send + Sync + 'static,
@@ -176,19 +203,21 @@ impl sp_consensus::Proposer for
+ Send + Sync + 'static,
C::Api: ApiExt>
+ BlockBuilderApi,
+ PR: ProofRecording,
{
type Transaction = backend::TransactionFor;
type Proposal = Pin, Self::Error>
+ Output = Result, Self::Error>
> + Send>>;
type Error = sp_blockchain::Error;
+ type ProofRecording = PR;
+ type Proof = PR::Proof;
fn propose(
self,
inherent_data: InherentData,
inherent_digests: DigestFor,
max_duration: time::Duration,
- record_proof: RecordProof,
) -> Self::Proposal {
let (tx, rx) = oneshot::channel();
let spawn_handle = self.spawn_handle.clone();
@@ -200,7 +229,6 @@ impl sp_consensus::Proposer for
inherent_data,
inherent_digests,
deadline,
- record_proof,
).await;
if tx.send(res).is_err() {
trace!("Could not send block production result to proposer!");
@@ -213,7 +241,7 @@ impl sp_consensus::Proposer for
}
}
-impl Proposer
+impl Proposer
where
A: TransactionPool,
B: backend::Backend + Send + Sync + 'static,
@@ -222,14 +250,14 @@ impl Proposer
+ Send + Sync + 'static,
C::Api: ApiExt>
+ BlockBuilderApi,
+ PR: ProofRecording,
{
async fn propose_with(
self,
inherent_data: InherentData,
inherent_digests: DigestFor,
deadline: time::Instant,
- record_proof: RecordProof,
- ) -> Result>, sp_blockchain::Error> {
+ ) -> Result, PR::Proof>, sp_blockchain::Error> {
/// If the block is full we will attempt to push at most
/// this number of transactions before quitting for real.
/// It allows us to increase block utilization.
@@ -238,7 +266,7 @@ impl Proposer
let mut block_builder = self.client.new_block_at(
&self.parent_id,
inherent_digests,
- record_proof,
+ PR::ENABLED,
)?;
for inherent in block_builder.create_inherents(inherent_data)? {
@@ -361,6 +389,8 @@ impl Proposer
error!("Failed to evaluate authored block: {:?}", err);
}
+ let proof = PR::into_proof(proof)
+ .map_err(|e| sp_blockchain::Error::Application(Box::new(e)))?;
Ok(Proposal { block, proof, storage_changes })
}
}
@@ -452,7 +482,7 @@ mod tests {
// when
let deadline = time::Duration::from_secs(3);
let block = futures::executor::block_on(
- proposer.propose(Default::default(), Default::default(), deadline, RecordProof::No)
+ proposer.propose(Default::default(), Default::default(), deadline)
).map(|r| r.block).unwrap();
// then
@@ -497,7 +527,7 @@ mod tests {
let deadline = time::Duration::from_secs(1);
futures::executor::block_on(
- proposer.propose(Default::default(), Default::default(), deadline, RecordProof::No)
+ proposer.propose(Default::default(), Default::default(), deadline)
).map(|r| r.block).unwrap();
}
@@ -543,7 +573,7 @@ mod tests {
let deadline = time::Duration::from_secs(9);
let proposal = futures::executor::block_on(
- proposer.propose(Default::default(), Default::default(), deadline, RecordProof::No),
+ proposer.propose(Default::default(), Default::default(), deadline),
).unwrap();
assert_eq!(proposal.block.extrinsics().len(), 1);
@@ -624,7 +654,7 @@ mod tests {
// when
let deadline = time::Duration::from_secs(9);
let block = futures::executor::block_on(
- proposer.propose(Default::default(), Default::default(), deadline, RecordProof::No)
+ proposer.propose(Default::default(), Default::default(), deadline)
).map(|r| r.block).unwrap();
// then
diff --git a/substrate/client/basic-authorship/src/lib.rs b/substrate/client/basic-authorship/src/lib.rs
index 224dccd36b..ccf73cc93f 100644
--- a/substrate/client/basic-authorship/src/lib.rs
+++ b/substrate/client/basic-authorship/src/lib.rs
@@ -22,7 +22,7 @@
//!
//! ```
//! # use sc_basic_authorship::ProposerFactory;
-//! # use sp_consensus::{Environment, Proposer, RecordProof};
+//! # use sp_consensus::{Environment, Proposer};
//! # use sp_runtime::generic::BlockId;
//! # use std::{sync::Arc, time::Duration};
//! # use substrate_test_runtime_client::{
@@ -61,7 +61,6 @@
//! Default::default(),
//! Default::default(),
//! Duration::from_secs(2),
-//! RecordProof::Yes,
//! );
//!
//! // We wait until the proposition is performed.
diff --git a/substrate/client/block-builder/Cargo.toml b/substrate/client/block-builder/Cargo.toml
index dda5edde36..1019e2411c 100644
--- a/substrate/client/block-builder/Cargo.toml
+++ b/substrate/client/block-builder/Cargo.toml
@@ -17,7 +17,6 @@ targets = ["x86_64-unknown-linux-gnu"]
sp-state-machine = { version = "0.9.0", path = "../../primitives/state-machine" }
sp-runtime = { version = "3.0.0", path = "../../primitives/runtime" }
sp-api = { version = "3.0.0", path = "../../primitives/api" }
-sp-consensus = { version = "0.9.0", path = "../../primitives/consensus/common" }
sp-blockchain = { version = "3.0.0", path = "../../primitives/blockchain" }
sp-core = { version = "3.0.0", path = "../../primitives/core" }
sp-block-builder = { version = "3.0.0", path = "../../primitives/block-builder" }
diff --git a/substrate/client/block-builder/src/lib.rs b/substrate/client/block-builder/src/lib.rs
index 5f700da891..4893072a71 100644
--- a/substrate/client/block-builder/src/lib.rs
+++ b/substrate/client/block-builder/src/lib.rs
@@ -37,12 +37,48 @@ use sp_core::ExecutionContext;
use sp_api::{
Core, ApiExt, ApiRef, ProvideRuntimeApi, StorageChanges, StorageProof, TransactionOutcome,
};
-use sp_consensus::RecordProof;
pub use sp_block_builder::BlockBuilder as BlockBuilderApi;
use sc_client_api::backend;
+/// 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, 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 {
+ fn default() -> Self {
+ Self::No
+ }
+}
+
+impl From for RecordProof {
+ 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
diff --git a/substrate/client/consensus/aura/src/lib.rs b/substrate/client/consensus/aura/src/lib.rs
index 29c4a40155..746ee6597e 100644
--- a/substrate/client/consensus/aura/src/lib.rs
+++ b/substrate/client/consensus/aura/src/lib.rs
@@ -179,7 +179,7 @@ pub fn start_aura(
&inherent_data_providers,
slot_duration.slot_duration()
)?;
- Ok(sc_consensus_slots::start_slot_worker::<_, _, _, _, _, AuraSlotCompatible, _>(
+ Ok(sc_consensus_slots::start_slot_worker::<_, _, _, _, _, AuraSlotCompatible, _, _>(
slot_duration,
select_chain,
worker,
@@ -877,7 +877,9 @@ pub fn import_queue(
#[cfg(test)]
mod tests {
use super::*;
- use sp_consensus::{NoNetwork as DummyOracle, Proposal, RecordProof, AlwaysCanAuthor};
+ use sp_consensus::{
+ NoNetwork as DummyOracle, Proposal, AlwaysCanAuthor, DisableProofRecording,
+ };
use sc_network_test::{Block as TestBlock, *};
use sp_runtime::traits::{Block as BlockT, DigestFor};
use sc_network::config::ProtocolConfig;
@@ -916,20 +918,21 @@ mod tests {
substrate_test_runtime_client::Backend,
TestBlock
>;
- type Proposal = future::Ready, Error>>;
+ type Proposal = future::Ready, Error>>;
+ type ProofRecording = DisableProofRecording;
+ type Proof = ();
fn propose(
self,
_: InherentData,
digests: DigestFor,
_: Duration,
- _: RecordProof,
) -> Self::Proposal {
let r = self.1.new_block(digests).unwrap().build().map_err(|e| e.into());
future::ready(r.map(|b| Proposal {
block: b.block,
- proof: b.proof,
+ proof: (),
storage_changes: b.storage_changes,
}))
}
diff --git a/substrate/client/consensus/babe/src/tests.rs b/substrate/client/consensus/babe/src/tests.rs
index 9d03a3266d..a33a509ddc 100644
--- a/substrate/client/consensus/babe/src/tests.rs
+++ b/substrate/client/consensus/babe/src/tests.rs
@@ -32,11 +32,10 @@ use sp_consensus_babe::{AuthorityPair, Slot, AllowedSlots, make_transcript, make
use sc_consensus_slots::BackoffAuthoringOnFinalizedHeadLagging;
use sc_block_builder::{BlockBuilder, BlockBuilderProvider};
use sp_consensus::{
- NoNetwork as DummyOracle, Proposal, RecordProof, AlwaysCanAuthor,
+ NoNetwork as DummyOracle, Proposal, DisableProofRecording, AlwaysCanAuthor,
import_queue::{BoxBlockImport, BoxJustificationImport},
};
-use sc_network_test::*;
-use sc_network_test::{Block as TestBlock, PeersClient};
+use sc_network_test::{Block as TestBlock, *};
use sc_network::config::ProtocolConfig;
use sp_runtime::{generic::DigestItem, traits::{Block as BlockT, DigestFor}};
use sc_client_api::{BlockchainEvents, backend::TransactionFor};
@@ -44,8 +43,7 @@ use log::debug;
use std::{time::Duration, cell::RefCell, task::Poll};
use rand::RngCore;
use rand_chacha::{
- rand_core::SeedableRng,
- ChaChaRng,
+ rand_core::SeedableRng, ChaChaRng,
};
use sc_keystore::LocalKeystore;
use sp_application_crypto::key_types::BABE;
@@ -112,7 +110,8 @@ impl DummyProposer {
Result<
Proposal<
TestBlock,
- sc_client_api::TransactionFor
+ sc_client_api::TransactionFor,
+ ()
>,
Error
>
@@ -163,21 +162,22 @@ impl DummyProposer {
// mutate the block header according to the mutator.
(self.factory.mutator)(&mut block.header, Stage::PreSeal);
- future::ready(Ok(Proposal { block, proof: None, storage_changes: Default::default() }))
+ future::ready(Ok(Proposal { block, proof: (), storage_changes: Default::default() }))
}
}
impl Proposer for DummyProposer {
type Error = Error;
type Transaction = sc_client_api::TransactionFor;
- type Proposal = future::Ready, Error>>;
+ type Proposal = future::Ready, Error>>;
+ type ProofRecording = DisableProofRecording;
+ type Proof = ();
fn propose(
mut self,
_: InherentData,
pre_digests: DigestFor,
_: Duration,
- _: RecordProof,
) -> Self::Proposal {
self.propose_with(pre_digests)
}
diff --git a/substrate/client/consensus/manual-seal/src/seal_block.rs b/substrate/client/consensus/manual-seal/src/seal_block.rs
index 59b99349bf..2176973f3a 100644
--- a/substrate/client/consensus/manual-seal/src/seal_block.rs
+++ b/substrate/client/consensus/manual-seal/src/seal_block.rs
@@ -123,8 +123,11 @@ pub async fn seal_block(
Default::default()
};
- let proposal = proposer.propose(id.clone(), digest, Duration::from_secs(MAX_PROPOSAL_DURATION), false.into())
- .map_err(|err| Error::StringError(format!("{:?}", err))).await?;
+ let proposal = proposer.propose(
+ id.clone(),
+ digest,
+ Duration::from_secs(MAX_PROPOSAL_DURATION),
+ ).map_err(|err| Error::StringError(format!("{:?}", err))).await?;
if proposal.block.extrinsics().len() == inherents_len && !create_empty {
return Err(Error::EmptyTransactionPool)
diff --git a/substrate/client/consensus/pow/src/lib.rs b/substrate/client/consensus/pow/src/lib.rs
index 3c7f1a832d..19f339cf10 100644
--- a/substrate/client/consensus/pow/src/lib.rs
+++ b/substrate/client/consensus/pow/src/lib.rs
@@ -52,8 +52,7 @@ use sp_consensus_pow::{Seal, TotalDifficulty, POW_ENGINE_ID};
use sp_inherents::{InherentDataProviders, InherentData};
use sp_consensus::{
BlockImportParams, BlockOrigin, ForkChoiceStrategy, SyncOracle, Environment, Proposer,
- SelectChain, Error as ConsensusError, CanAuthorWith, RecordProof, BlockImport,
- BlockCheckParams, ImportResult,
+ SelectChain, Error as ConsensusError, CanAuthorWith, BlockImport, BlockCheckParams, ImportResult,
};
use sp_consensus::import_queue::{
BoxBlockImport, BasicQueue, Verifier, BoxJustificationImport,
@@ -549,7 +548,10 @@ pub fn start_mining_worker(
timeout: Duration,
build_time: Duration,
can_author_with: CAW,
-) -> (Arc>>, impl Future