// Copyright 2017-2019 Parity Technologies (UK) Ltd. // This file is part of Substrate. // Substrate 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. // Substrate 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 Substrate. If not, see . //! Blockchain access trait use sc_client::Client as SubstrateClient; use sp_blockchain::Error; use sc_client_api::{ChangesProof, StorageProof, ClientInfo, CallExecutor}; use sp_consensus::{BlockImport, BlockStatus, Error as ConsensusError}; use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; use sp_runtime::generic::{BlockId}; use sp_runtime::Justification; use sp_core::{H256, Blake2Hasher}; use sp_core::storage::{StorageKey, ChildInfo}; /// Local client abstraction for the network. pub trait Client: Send + Sync { /// Get blockchain info. fn info(&self) -> ClientInfo; /// Get block status. fn block_status(&self, id: &BlockId) -> Result; /// Get block hash by number. fn block_hash(&self, block_number: ::Number) -> Result, Error>; /// Get block header. fn header(&self, id: &BlockId) -> Result, Error>; /// Get block body. fn body(&self, id: &BlockId) -> Result>, Error>; /// Get block justification. fn justification(&self, id: &BlockId) -> Result, Error>; /// Get block header proof. fn header_proof(&self, block_number: ::Number) -> Result<(Block::Header, StorageProof), Error>; /// Get storage read execution proof. fn read_proof(&self, block: &Block::Hash, keys: &[Vec]) -> Result; /// Get child storage read execution proof. fn read_child_proof( &self, block: &Block::Hash, storage_key: &[u8], child_info: ChildInfo, keys: &[Vec], ) -> Result; /// Get method execution proof. fn execution_proof(&self, block: &Block::Hash, method: &str, data: &[u8]) -> Result<(Vec, StorageProof), Error>; /// Get key changes proof. fn key_changes_proof( &self, first: Block::Hash, last: Block::Hash, min: Block::Hash, max: Block::Hash, storage_key: Option<&StorageKey>, key: &StorageKey ) -> Result, Error>; /// Returns `true` if the given `block` is a descendent of `base`. fn is_descendent_of(&self, base: &Block::Hash, block: &Block::Hash) -> Result; } /// Finality proof provider. pub trait FinalityProofProvider: Send + Sync { /// Prove finality of the block. fn prove_finality(&self, for_block: Block::Hash, request: &[u8]) -> Result>, Error>; } impl FinalityProofProvider for () { fn prove_finality(&self, _for_block: Block::Hash, _request: &[u8]) -> Result>, Error> { Ok(None) } } impl Client for SubstrateClient where B: sc_client_api::backend::Backend + Send + Sync + 'static, E: CallExecutor + Send + Sync + 'static, Self: BlockImport, Block: BlockT, RA: Send + Sync { fn info(&self) -> ClientInfo { (self as &SubstrateClient).info() } fn block_status(&self, id: &BlockId) -> Result { (self as &SubstrateClient).block_status(id) } fn block_hash(&self, block_number: ::Number) -> Result, Error> { (self as &SubstrateClient).block_hash(block_number) } fn header(&self, id: &BlockId) -> Result, Error> { (self as &SubstrateClient).header(id) } fn body(&self, id: &BlockId) -> Result>, Error> { (self as &SubstrateClient).body(id) } fn justification(&self, id: &BlockId) -> Result, Error> { (self as &SubstrateClient).justification(id) } fn header_proof(&self, block_number: ::Number) -> Result<(Block::Header, StorageProof), Error> { (self as &SubstrateClient).header_proof(&BlockId::Number(block_number)) } fn read_proof(&self, block: &Block::Hash, keys: &[Vec]) -> Result { (self as &SubstrateClient).read_proof(&BlockId::Hash(block.clone()), keys) } fn read_child_proof( &self, block: &Block::Hash, storage_key: &[u8], child_info: ChildInfo, keys: &[Vec], ) -> Result { (self as &SubstrateClient) .read_child_proof(&BlockId::Hash(block.clone()), storage_key, child_info, keys) } fn execution_proof(&self, block: &Block::Hash, method: &str, data: &[u8]) -> Result<(Vec, StorageProof), Error> { (self as &SubstrateClient).execution_proof(&BlockId::Hash(block.clone()), method, data) } fn key_changes_proof( &self, first: Block::Hash, last: Block::Hash, min: Block::Hash, max: Block::Hash, storage_key: Option<&StorageKey>, key: &StorageKey, ) -> Result, Error> { (self as &SubstrateClient).key_changes_proof(first, last, min, max, storage_key, key) } fn is_descendent_of(&self, base: &Block::Hash, block: &Block::Hash) -> Result { if base == block { return Ok(false); } let ancestor = sp_blockchain::lowest_common_ancestor(self, *block, *base)?; Ok(ancestor.hash == *base) } }