// Copyright 2019-2021 Parity Technologies (UK) Ltd. // This file is part of Parity Bridges Common. // Parity Bridges Common is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // Parity Bridges Common is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . //! Tools for teyrchain head proof verification. use crate::{Config, GrandpaPalletOf, RelayBlockHash, RelayBlockHasher}; use bp_header_pez_chain::{HeaderChain, HeaderChainError}; use bp_pezkuwi_core::teyrchains::{ParaHead, ParaId}; use bp_teyrchains::teyrchain_head_storage_key_at_source; use codec::Decode; use pezbp_runtime::{RawStorageProof, StorageProofChecker, StorageProofError}; use pezframe_support::traits::Get; /// Abstraction over storage proof manipulation, hiding implementation details of actual storage /// proofs. pub trait StorageProofAdapter, I: 'static> { /// Read and decode optional value from the proof. fn read_and_decode_optional_value( &mut self, key: &impl AsRef<[u8]>, ) -> Result, StorageProofError>; /// Checks if each key was read. fn ensure_no_unused_keys(self) -> Result<(), StorageProofError>; /// Read teyrchain head from storage proof. fn read_teyrchain_head( &mut self, teyrchain: ParaId, ) -> Result, StorageProofError> { let teyrchain_head_key = teyrchain_head_storage_key_at_source(T::ParasPalletName::get(), teyrchain); self.read_and_decode_optional_value(&teyrchain_head_key) } } /// Actual storage proof adapter for teyrchain proofs. pub type TeyrchainsStorageProofAdapter = RawStorageProofAdapter; /// A `StorageProofAdapter` implementation for raw storage proofs. pub struct RawStorageProofAdapter, I: 'static> { storage: StorageProofChecker, _dummy: pezsp_std::marker::PhantomData<(T, I)>, } impl, I: 'static> RawStorageProofAdapter { /// Try to create a new instance of `RawStorageProofAdapter`. pub fn try_new_with_verified_storage_proof( relay_block_hash: RelayBlockHash, storage_proof: RawStorageProof, ) -> Result { GrandpaPalletOf::::verify_storage_proof(relay_block_hash, storage_proof) .map(|storage| RawStorageProofAdapter:: { storage, _dummy: Default::default() }) } } impl, I: 'static> StorageProofAdapter for RawStorageProofAdapter { fn read_and_decode_optional_value( &mut self, key: &impl AsRef<[u8]>, ) -> Result, StorageProofError> { self.storage.read_and_decode_opt_value(key.as_ref()) } fn ensure_no_unused_keys(self) -> Result<(), StorageProofError> { self.storage.ensure_no_unused_nodes() } }