Skip to content
This repository has been archived by the owner on Nov 10, 2023. It is now read-only.

Commit

Permalink
substrate state machine implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
dharjeezy committed Jul 13, 2023
1 parent 143b583 commit dab1b02
Show file tree
Hide file tree
Showing 13 changed files with 333 additions and 248 deletions.
26 changes: 24 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ members = [
"pallet-ismp/rpc",
"pallet-ismp/runtime-api",
"pallet-ismp/primitives",
"pallet-ismp/primitives/state-machine",
"pallet-ismp",
"parachain/inherent",
"parachain/runtime-api",
Expand Down
2 changes: 2 additions & 0 deletions grandpa/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-
cumulus-primitives-core = { git = "https://github.com/paritytech/cumulus", branch = "release-v0.9.420", default-features = false }

ismp-primitives = { path = "../pallet-ismp/primitives", default-features = false }
state-machine-primitives = { path = "../pallet-ismp/primitives/state-machine", default-features = false }

[features]
default = ["std"]
Expand All @@ -52,4 +53,5 @@ std = [
"verifier/std",
"merkle-mountain-range/std",
"ismp-primitives/std",
"state-machine-primitives/std"
]
4 changes: 0 additions & 4 deletions grandpa/primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ edition = "2021"

[dependencies]
# crates.io
serde = { version = "1.0.136", features = ["derive"], optional = true }
anyhow = { version = "1.0.64", default-features = false }
hash-db = { version = "0.16.0", default-features = false }
derive_more = { version = "0.99.17", default-features = false, features = ["display"] }
Expand All @@ -21,7 +20,6 @@ sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0
frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42", default-features = false }
sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42", default-features = false }
sp-trie = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42", default-features = false }
sp-consensus-aura = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" }

#polytope
ismp = { git = "https://github.com/polytope-labs/ismp-rs", branch = "main", default-features = false }
Expand All @@ -36,12 +34,10 @@ std = [
"codec/std",
"sp-core/std",
"sp-runtime/std",
"sp-consensus-aura/std",
"sp-io/std",
"frame-support/std",
"sp-finality-grandpa/std",
"sp-std/std",
"sp-trie/std",
"ismp/std",
"serde",
]
73 changes: 3 additions & 70 deletions grandpa/primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,11 @@ extern crate alloc;

use alloc::collections::BTreeMap;
use codec::{Decode, Encode};
use core::{fmt::Debug, time::Duration};
use frame_support::sp_runtime::Digest;
use ismp::{error::Error, host::StateMachine};
use sp_consensus_aura::{Slot, AURA_ENGINE_ID};
use core::fmt::Debug;
use ismp::host::StateMachine;
use sp_core::{sp_std, H256};
use sp_finality_grandpa::{AuthorityId, AuthorityList, AuthoritySignature};
use sp_runtime::{traits::Header, DigestItem};
use sp_runtime::traits::Header;
use sp_std::prelude::*;
use sp_storage::StorageKey;

Expand Down Expand Up @@ -106,36 +104,6 @@ pub struct ParachainHeadersWithFinalityProof<H: codec::Codec> {
pub parachain_headers: BTreeMap<Hash, ParachainHeaderProofs>,
}

/// Hashing algorithm for the state proof
#[derive(Debug, Encode, Decode, Clone)]
#[cfg_attr(feature = "std", derive(serde::Deserialize, serde::Serialize))]
pub enum HashAlgorithm {
/// For chains that use keccak as their hashing algo
Keccak,
/// For chains that use blake2 as their hashing algo
Blake2,
}

/// Holds the relevant data needed for state proof verification
#[derive(Debug, Encode, Decode, Clone)]
pub struct SubstrateStateProof {
/// Algorithm to use for state proof verification
pub hasher: HashAlgorithm,
/// Storage proof for the parachain headers
pub storage_proof: Vec<Vec<u8>>,
}

/// Holds the relevant data needed for request/response proof verification
#[derive(Debug, Encode, Decode, Clone)]
pub struct MembershipProof {
/// Size of the mmr at the time this proof was generated
pub mmr_size: u64,
/// Leaf indices for the proof
pub leaf_indices: Vec<u64>,
/// Mmr proof
pub proof: Vec<H256>,
}

/// This returns the storage key for a parachain header on the relay chain.
pub fn parachain_header_storage_key(para_id: u32) -> StorageKey {
let mut storage_key = frame_support::storage::storage_prefix(b"Paras", b"Heads").to_vec();
Expand All @@ -144,38 +112,3 @@ pub fn parachain_header_storage_key(para_id: u32) -> StorageKey {
storage_key.extend_from_slice(&encoded_para_id);
StorageKey(storage_key)
}

/// Fetches the overlay(ismp) root and timestamp from the header digest
pub fn fetch_overlay_root_and_timestamp(
digest: &Digest,
slot_duration: u64,
) -> Result<(u64, H256), Error> {
let (mut timestamp, mut overlay_root) = (0, H256::default());

for digest in digest.logs.iter() {
match digest {
DigestItem::PreRuntime(consensus_engine_id, value)
if *consensus_engine_id == AURA_ENGINE_ID =>
{
let slot = Slot::decode(&mut &value[..])
.map_err(|e| Error::ImplementationSpecific(format!("Cannot slot: {e:?}")))?;
timestamp = Duration::from_millis(*slot * slot_duration).as_secs();
}
DigestItem::Consensus(consensus_engine_id, value)
if *consensus_engine_id == ISMP_ID =>
{
if value.len() != 32 {
Err(Error::ImplementationSpecific(
"Header contains an invalid ismp root".into(),
))?
}

overlay_root = H256::from_slice(&value);
}
// don't really care about the rest
_ => {}
};
}

Ok((timestamp, overlay_root))
}
8 changes: 4 additions & 4 deletions grandpa/src/consensus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ use ismp::{
host::{IsmpHost, StateMachine},
messaging::StateCommitmentHeight,
};
use ismp_primitives::fetch_overlay_root_and_timestamp;
use primitive_types::H256;
use primitives::{
fetch_overlay_root_and_timestamp, ConsensusState, ParachainHeadersWithFinalityProof,
};
use primitives::{ConsensusState, ParachainHeadersWithFinalityProof};
use sp_runtime::traits::Header;
use state_machine_primitives::SubstrateStateMachine;
use verifier::{
verify_grandpa_finality_proof, verify_parachain_headers_with_grandpa_finality_proof,
};
Expand Down Expand Up @@ -183,6 +183,6 @@ where
}

fn state_machine(&self, _id: StateMachine) -> Result<Box<dyn StateMachineClient>, Error> {
todo!()
Ok(Box::new(SubstrateStateMachine::<T>::default()))
}
}
3 changes: 0 additions & 3 deletions grandpa/src/consensus_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
// See the License for the specific lang
use alloc::collections::BTreeMap;
use codec::{Decode, Encode};
use ismp::consensus::StateMachineId;
use primitives::{FinalityProof, ParachainHeaderProofs};
use sp_core::H256;
use sp_runtime::traits::BlakeTwo256;
Expand All @@ -34,8 +33,6 @@ pub enum ConsensusMessage {
pub struct StandaloneChainMessage {
/// finality proof
pub finality_proof: FinalityProof<SubstrateHeader>,
/// state machine id
pub state_machine_id: StateMachineId,
}

#[derive(Clone, Debug, Encode, Decode)]
Expand Down
8 changes: 7 additions & 1 deletion pallet-ismp/primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ codec = { package = "parity-scale-codec", version = "3.1.3", default-features =
primitive-types = { version = "0.12.1", default-features = false }
serde = { version = "1.0.136", features = ["derive"], optional = true }
scale-info = { version = "2.1.1", default-features = false, features = ["derive"] }
frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42", default-features = false }
sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42" }
sp-consensus-aura = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" }

[features]
default = ["std"]
Expand All @@ -29,5 +32,8 @@ std = [
"sp-runtime/std",
"primitive-types/std",
"scale-info/std",
"serde"
"serde",
"frame-support/std",
"sp-core/std",
"sp-consensus-aura/std",
]
76 changes: 75 additions & 1 deletion pallet-ismp/primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,19 @@
#![deny(missing_docs)]

//! Primitives for the MMR implementation
use ismp::host::StateMachine;
use codec::{Decode, Encode};
use core::{fmt::Debug, time::Duration};
use frame_support::sp_runtime::Digest;
use ismp::{error::Error, host::StateMachine};
use sp_consensus_aura::{Slot, AURA_ENGINE_ID};
use sp_core::H256;
use sp_runtime::DigestItem;

pub mod mmr;

/// The `ConsensusEngineId` of ISMP digest in the parachain header.
pub const ISMP_ID: sp_runtime::ConsensusEngineId = *b"ISMP";

/// Queries a request leaf in the mmr
#[derive(codec::Encode, codec::Decode, scale_info::TypeInfo)]
#[cfg_attr(feature = "std", derive(serde::Deserialize, serde::Serialize))]
Expand All @@ -34,3 +43,68 @@ pub struct LeafIndexQuery {
/// The request nonce
pub nonce: u64,
}

/// Hashing algorithm for the state proof
#[derive(Debug, Encode, Decode, Clone)]
#[cfg_attr(feature = "std", derive(serde::Deserialize, serde::Serialize))]
pub enum HashAlgorithm {
/// For chains that use keccak as their hashing algo
Keccak,
/// For chains that use blake2 as their hashing algo
Blake2,
}

/// Holds the relevant data needed for state proof verification
#[derive(Debug, Encode, Decode, Clone)]
pub struct SubstrateStateProof {
/// Algorithm to use for state proof verification
pub hasher: HashAlgorithm,
/// Storage proof for the parachain headers
pub storage_proof: Vec<Vec<u8>>,
}

/// Holds the relevant data needed for request/response proof verification
#[derive(Debug, Encode, Decode, Clone)]
pub struct MembershipProof {
/// Size of the mmr at the time this proof was generated
pub mmr_size: u64,
/// Leaf indices for the proof
pub leaf_indices: Vec<u64>,
/// Mmr proof
pub proof: Vec<H256>,
}

/// Fetches the overlay(ismp) root and timestamp from the header digest
pub fn fetch_overlay_root_and_timestamp(
digest: &Digest,
slot_duration: u64,
) -> Result<(u64, H256), Error> {
let (mut timestamp, mut overlay_root) = (0, H256::default());

for digest in digest.logs.iter() {
match digest {
DigestItem::PreRuntime(consensus_engine_id, value)
if *consensus_engine_id == AURA_ENGINE_ID =>
{
let slot = Slot::decode(&mut &value[..])
.map_err(|e| Error::ImplementationSpecific(format!("Cannot slot: {e:?}")))?;
timestamp = Duration::from_millis(*slot * slot_duration).as_secs();
}
DigestItem::Consensus(consensus_engine_id, value)
if *consensus_engine_id == ISMP_ID =>
{
if value.len() != 32 {
Err(Error::ImplementationSpecific(
"Header contains an invalid ismp root".into(),
))?
}

overlay_root = H256::from_slice(&value);
}
// don't really care about the rest
_ => {}
};
}

Ok((timestamp, overlay_root))
}
Loading

0 comments on commit dab1b02

Please sign in to comment.