grandpa_verifier_primitives/lib.rs
1// Copyright (c) 2025 Polytope Labs.
2// SPDX-License-Identifier: Apache-2.0
3
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16//! Primitive types and traits used by the GRANDPA prover & verifier.
17
18#![cfg_attr(not(feature = "std"), no_std)]
19#![allow(clippy::all)]
20#![deny(missing_docs)]
21
22extern crate alloc;
23
24use alloc::collections::BTreeMap;
25use codec::{Decode, Encode};
26use core::fmt::Debug;
27use ismp::host::StateMachine;
28use polkadot_sdk::*;
29use sp_consensus_grandpa::{AuthorityId, AuthorityList, AuthoritySignature};
30use sp_core::{sp_std, H256};
31use sp_runtime::traits::Header;
32use sp_std::prelude::*;
33use sp_storage::StorageKey;
34
35/// GRANDPA justification utilities
36pub mod justification;
37
38/// Represents a Hash in this library
39pub type Hash = H256;
40/// A commit message for this chain's block type.
41pub type Commit<H> = finality_grandpa::Commit<
42 <H as Header>::Hash,
43 <H as Header>::Number,
44 AuthoritySignature,
45 AuthorityId,
46>;
47
48/// The default header type that can be used with the GRANDPA prover.
49///
50/// This type is compatible with our consensus implementation, using
51/// [BlakeTwo256](sp_runtime::traits::BlakeTwo256) for hashing and a 32-bit
52/// block number type.
53pub type DefaultHeader = sp_runtime::generic::Header<u32, sp_runtime::traits::BlakeTwo256>;
54
55/// Finality for block B is proved by providing:
56/// 1) the justification for the descendant block F;
57/// 2) headers sub-chain (B; F] if B != F;
58#[derive(Debug, PartialEq, Encode, Decode, Clone)]
59pub struct FinalityProof<H: codec::Codec> {
60 /// The hash of block F for which justification is provided.
61 pub block: Hash,
62 /// Justification of the block F.
63 pub justification: Vec<u8>,
64 /// The set of headers in the range (B; F] that we believe are unknown to the caller. Ordered.
65 pub unknown_headers: Vec<H>,
66}
67
68/// Previous light client state.
69#[derive(Debug, PartialEq, Encode, Decode, Clone)]
70pub struct ConsensusState {
71 /// Current authority set
72 pub current_authorities: AuthorityList,
73 /// Id of the current authority set.
74 pub current_set_id: u64,
75 /// latest finalized height on relay chain or standalone chain
76 pub latest_height: u32,
77 /// latest finalized hash on relay chain or standalone chain.
78 pub latest_hash: Hash,
79 /// slot duration for the standalone chain
80 pub slot_duration: u64,
81 /// State machine for this consensus state
82 pub state_machine: StateMachine,
83}
84
85/// Holds relavant parachain proofs for both header and timestamp extrinsic.
86#[derive(Clone, Debug, Encode, Decode)]
87pub struct ParachainHeaderProofs {
88 /// State proofs that prove a parachain headers exists at a given relay chain height
89 pub state_proof: Vec<Vec<u8>>,
90 /// The parachain ids
91 pub para_ids: Vec<u32>,
92}
93
94/// Parachain headers with a Grandpa finality proof.
95#[derive(Clone, Encode, Decode)]
96pub struct ParachainHeadersWithFinalityProof<H: codec::Codec> {
97 /// The grandpa finality proof: contains relay chain headers from the
98 /// last known finalized grandpa block.
99 pub finality_proof: FinalityProof<H>,
100 /// Contains a map of relay chain header hashes to parachain headers
101 /// finalized at the relay chain height. We check for this parachain header finalization
102 /// via state proofs. Also contains extrinsic proof for timestamp.
103 pub parachain_headers: BTreeMap<Hash, ParachainHeaderProofs>,
104}
105
106/// This returns the storage key for a parachain header on the relay chain.
107pub fn parachain_header_storage_key(para_id: u32) -> StorageKey {
108 let mut storage_key = frame_support::storage::storage_prefix(b"Paras", b"Heads").to_vec();
109 let encoded_para_id = para_id.encode();
110 storage_key.extend_from_slice(sp_io::hashing::twox_64(&encoded_para_id).as_slice());
111 storage_key.extend_from_slice(&encoded_para_id);
112 StorageKey(storage_key)
113}