Skip to content

Commit 7087523

Browse files
committed
wip/included head not present in relay storage proof
1 parent d29abb0 commit 7087523

File tree

6 files changed

+463
-14
lines changed

6 files changed

+463
-14
lines changed

crates/anvil-polkadot/Cargo.toml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,21 @@ polkadot-sdk = { git = "https://github.com/paritytech/polkadot-sdk.git", branch
6767
"substrate-frame-rpc-system",
6868
"substrate-rpc-client",
6969
"substrate-wasm-builder",
70+
71+
"sc-consensus-aura",
72+
"polkadot-primitives",
73+
"cumulus-client-parachain-inherent",
74+
"sp-arithmetic",
75+
"cumulus-client-service",
76+
"cumulus-primitives-aura",
77+
78+
"cumulus-primitives-core",
79+
"sp-inherents",
7080
] }
81+
hex = "0.4"
82+
indicatif.workspace = true
83+
84+
7185
anvil.workspace = true
7286
anvil-core.workspace = true
7387
anvil-server = { workspace = true, features = ["clap"] }

crates/anvil-polkadot/src/cmd.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ pub struct NodeArgs {
9898

9999
#[command(flatten)]
100100
pub server_config: ServerConfig,
101+
102+
#[command(flatten)]
103+
pub fork: ForkArgs,
101104
}
102105

103106
/// The default IPC endpoint
@@ -148,6 +151,8 @@ impl NodeArgs {
148151
.with_eth_rpc_url(self.evm.fork_url.map(|fork| fork.url))
149152
.fork_request_timeout(self.evm.fork_request_timeout.map(Duration::from_millis))
150153
.fork_request_retries(self.evm.fork_request_retries);
154+
// for my testing
155+
.with_fork_block_hash(self.fork.fork_block_hash);
151156

152157
let substrate_node_config = SubstrateNodeConfig::new(&anvil_config);
153158

@@ -357,6 +362,22 @@ fn duration_from_secs_f64(s: &str) -> Result<Duration, String> {
357362
Duration::try_from_secs_f64(s).map_err(|e| e.to_string())
358363
}
359364

365+
#[derive(Clone, Debug, Parser)]
366+
#[command(next_help_heading = "Fork options")]
367+
pub struct ForkArgs {
368+
/// Fetch state over a remote endpoint instead of starting from an empty state.
369+
#[arg(
370+
long = "fork-url",
371+
short = 'f',
372+
value_name = "URL",
373+
)]
374+
pub fork_url: Option<String>,
375+
376+
/// Fetch state from a specific block hash over a remote endpoint.
377+
#[arg(long, value_name = "BLOCK")]
378+
pub fork_block_hash: Option<String>,
379+
}
380+
360381
#[cfg(test)]
361382
mod tests {
362383
use super::*;

crates/anvil-polkadot/src/config.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,8 @@ pub struct AnvilNodeConfig {
332332
pub fork_request_timeout: Duration,
333333
/// Number of request retries for spurious networks
334334
pub fork_request_retries: u32,
335+
/// Fetch state from a specific block hash over a remote endpoint.
336+
pub fork_block_hash: Option<String>,
335337
}
336338

337339
impl AnvilNodeConfig {
@@ -557,6 +559,7 @@ impl Default for AnvilNodeConfig {
557559
fork_choice: None,
558560
fork_request_timeout: REQUEST_TIMEOUT,
559561
fork_request_retries: 5,
562+
fork_block_hash: None,
560563
}
561564
}
562565
}
@@ -901,6 +904,13 @@ impl AnvilNodeConfig {
901904
}
902905
self
903906
}
907+
908+
// For my own testing
909+
#[must_use]
910+
pub fn with_fork_block_hash(mut self, fork_block_hash: Option<String>) -> Self {
911+
self.fork_block_hash = fork_block_hash;
912+
self
913+
}
904914
}
905915

906916
/// Fork delimiter used to specify which block or transaction to fork from.

crates/anvil-polkadot/src/substrate_node/service/consensus.rs

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,22 @@
1+
2+
use crate::{
3+
substrate_node::{
4+
service::{AuxStore, ProvideRuntimeApi, UsageProvider, AuraApi, AuthorityId, TIMESTAMP}
5+
},
6+
};
17
use polkadot_sdk::{
28
sc_consensus::BlockImportParams,
3-
sc_consensus_aura::CompatibleDigestItem,
9+
sc_consensus_aura::{self,CompatibleDigestItem},
410
sc_consensus_manual_seal::{ConsensusDataProvider, Error},
511
sp_consensus_aura::ed25519::AuthoritySignature,
612
sp_consensus_babe::Slot,
713
sp_inherents::InherentData,
814
sp_runtime::{Digest, DigestItem, traits::Block as BlockT},
15+
sp_timestamp::TimestampInherentData,
916
};
1017
use std::marker::PhantomData;
18+
use std::sync::atomic::{ Ordering};
19+
use std::sync::Arc;
1120

1221
/// Consensus data provider for Aura. This will always use slot 0 (used to determine the
1322
/// index of the AURA authority from the authorities set by AURA runtimes) for the aura
@@ -55,3 +64,74 @@ where
5564
Ok(())
5665
}
5766
}
67+
68+
// Mine /// Consensus data provider for Aura. This allows to use manual-seal driven nodes to author valid
69+
/// AURA blocks. It will inspect incoming [`InherentData`] and look for included timestamps. Based
70+
/// on these timestamps, the [`AuraConsensusDataProvider`] will emit fitting digest items.
71+
pub struct AuraConsensusDataProvider<B, P> {
72+
// slot duration
73+
slot_duration: sc_consensus_aura::SlotDuration,
74+
// phantom data for required generics
75+
_phantom: PhantomData<(B, P)>,
76+
}
77+
78+
impl<B, P> AuraConsensusDataProvider<B, P>
79+
where
80+
B: BlockT,
81+
{
82+
/// Creates a new instance of the [`AuraConsensusDataProvider`], requires that `client`
83+
/// implements [`sp_consensus_aura::AuraApi`]
84+
pub fn new<C>(client: Arc<C>) -> Self
85+
where
86+
C: AuxStore + ProvideRuntimeApi<B> + UsageProvider<B>,
87+
C::Api: AuraApi<B, AuthorityId>,
88+
{
89+
let slot_duration = sc_consensus_aura::slot_duration(&*client)
90+
.expect("slot_duration is always present; qed.");
91+
92+
Self { slot_duration, _phantom: PhantomData }
93+
}
94+
95+
/// Creates a new instance of the [`AuraConsensusDataProvider`]
96+
pub fn new_with_slot_duration(slot_duration: sc_consensus_aura::SlotDuration) -> Self {
97+
Self { slot_duration, _phantom: PhantomData }
98+
}
99+
}
100+
101+
impl<B, P> ConsensusDataProvider<B> for AuraConsensusDataProvider<B, P>
102+
where
103+
B: BlockT,
104+
P: Send + Sync,
105+
{
106+
type Proof = P;
107+
108+
fn create_digest(
109+
&self,
110+
_parent: &B::Header,
111+
inherents: &InherentData,
112+
) -> Result<Digest, Error> {
113+
let timestamp =
114+
inherents.timestamp_inherent_data()?.expect("Timestamp is always present; qed");
115+
116+
print!("time da {}", timestamp);
117+
print!("time db {}", TIMESTAMP.load(Ordering::SeqCst));
118+
119+
// we always calculate the new slot number based on the current time-stamp and the slot
120+
// duration.
121+
let digest_item = <DigestItem as CompatibleDigestItem<AuthoritySignature>>::aura_pre_digest(
122+
Slot::from_timestamp(timestamp, self.slot_duration),
123+
);
124+
125+
Ok(Digest { logs: vec![digest_item] })
126+
}
127+
128+
fn append_block_import(
129+
&self,
130+
_parent: &B::Header,
131+
_params: &mut BlockImportParams<B>,
132+
_inherents: &InherentData,
133+
_proof: Self::Proof,
134+
) -> Result<(), Error> {
135+
Ok(())
136+
}
137+
}

crates/anvil-polkadot/src/substrate_node/service/executor.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,14 @@ use polkadot_sdk::{
1616
sp_storage::ChildInfo,
1717
sp_version,
1818
sp_wasm_interface::ExtendedHostFunctions,
19+
cumulus_client_service::ParachainHostFunctions,
1920
};
2021
use std::{cell::RefCell, sync::Arc};
2122

2223
/// Wasm executor which overrides the signature checking host functions for impersonation.
2324
pub type WasmExecutor = sc_executor::WasmExecutor<
2425
ExtendedHostFunctions<
25-
ExtendedHostFunctions<sp_io::SubstrateHostFunctions, SenderAddressRecoveryOverride>,
26+
ExtendedHostFunctions<ParachainHostFunctions, SenderAddressRecoveryOverride>,
2627
PublicKeyToHashOverride,
2728
>,
2829
>;

0 commit comments

Comments
 (0)