// This file is part of Substrate.
// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
// This program 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.
// This program 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 this program. If not, see .
//! Substrate Client data backend
use std::sync::Arc;
use std::collections::HashMap;
use sp_core::ChangesTrieConfigurationRange;
use sp_core::offchain::{OffchainStorage,storage::OffchainOverlayedChanges};
use sp_runtime::{generic::BlockId, Justification, Storage};
use sp_runtime::traits::{Block as BlockT, NumberFor, HashFor};
use sp_state_machine::{
ChangesTrieState, ChangesTrieStorage as StateChangesTrieStorage, ChangesTrieTransaction,
StorageCollection, ChildStorageCollection,
};
use sp_storage::{StorageData, StorageKey, PrefixedStorageKey, ChildInfo};
use crate::{
blockchain::{
Backend as BlockchainBackend, well_known_cache_keys
},
light::RemoteBlockchain,
UsageInfo,
};
use sp_blockchain;
use sp_consensus::BlockOrigin;
use parking_lot::RwLock;
pub use sp_state_machine::Backend as StateBackend;
use std::marker::PhantomData;
/// Extracts the state backend type for the given backend.
pub type StateBackendFor = >::State;
/// Extracts the transaction for the given state backend.
pub type TransactionForSB = >>::Transaction;
/// Extracts the transaction for the given backend.
pub type TransactionFor = TransactionForSB, Block>;
/// Import operation summary.
///
/// Contains information about the block that just got imported,
/// including storage changes, reorged blocks, etc.
pub struct ImportSummary {
/// Block hash of the imported block.
pub hash: Block::Hash,
/// Import origin.
pub origin: BlockOrigin,
/// Header of the imported block.
pub header: Block::Header,
/// Is this block a new best block.
pub is_new_best: bool,
/// Optional storage changes.
pub storage_changes: Option<(StorageCollection, ChildStorageCollection)>,
/// Tree route from old best to new best.
///
/// If `None`, there was no re-org while importing.
pub tree_route: Option>,
}
/// Import operation wrapper
pub struct ClientImportOperation> {
/// DB Operation.
pub op: B::BlockImportOperation,
/// Summary of imported block.
pub notify_imported: Option>,
/// A list of hashes of blocks that got finalized.
pub notify_finalized: Vec,
}
/// Helper function to apply auxiliary data insertion into an operation.
pub fn apply_aux<'a, 'b: 'a, 'c: 'a, B, Block, D, I>(
operation: &mut ClientImportOperation,
insert: I,
delete: D,
) -> sp_blockchain::Result<()>
where
Block: BlockT,
B: Backend,
I: IntoIterator,
D: IntoIterator,
{
operation.op.insert_aux(
insert.into_iter()
.map(|(k, v)| (k.to_vec(), Some(v.to_vec())))
.chain(delete.into_iter().map(|k| (k.to_vec(), None)))
)
}
/// State of a new block.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum NewBlockState {
/// Normal block.
Normal,
/// New best block.
Best,
/// Newly finalized block (implicitly best).
Final,
}
impl NewBlockState {
/// Whether this block is the new best block.
pub fn is_best(self) -> bool {
match self {
NewBlockState::Best | NewBlockState::Final => true,
NewBlockState::Normal => false,
}
}
/// Whether this block is considered final.
pub fn is_final(self) -> bool {
match self {
NewBlockState::Final => true,
NewBlockState::Best | NewBlockState::Normal => false,
}
}
}
/// Block insertion operation.
///
/// Keeps hold if the inserted block state and data.
pub trait BlockImportOperation {
/// Associated state backend type.
type State: StateBackend>;
/// Returns pending state.
///
/// Returns None for backends with locally-unavailable state data.
fn state(&self) -> sp_blockchain::Result