|
| 1 | +// Copyright 2015-2019 Parity Technologies (UK) Ltd. |
| 2 | +// This file is part of Parity Ethereum. |
| 3 | + |
| 4 | +// Parity Ethereum is free software: you can redistribute it and/or modify |
| 5 | +// it under the terms of the GNU General Public License as published by |
| 6 | +// the Free Software Foundation, either version 3 of the License, or |
| 7 | +// (at your option) any later version. |
| 8 | + |
| 9 | +// Parity Ethereum is distributed in the hope that it will be useful, |
| 10 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | +// GNU General Public License for more details. |
| 13 | + |
| 14 | +// You should have received a copy of the GNU General Public License |
| 15 | +// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>. |
| 16 | + |
| 17 | +use std::sync::{Arc, atomic::AtomicBool}; |
| 18 | + |
| 19 | +use blockchain::{BlockChain, BlockChainDB}; |
| 20 | +use bytes::Bytes; |
| 21 | +use client_traits::{BlockChainClient, BlockInfo, DatabaseRestore, BlockChainReset}; |
| 22 | +use common_types::{ |
| 23 | + ids::BlockId, |
| 24 | + errors::{EthcoreError as Error, SnapshotError}, |
| 25 | + snapshot::{ManifestData, ChunkSink, Progress, RestorationStatus}, |
| 26 | +}; |
| 27 | +use engine::Engine; |
| 28 | +use ethereum_types::H256; |
| 29 | +use parking_lot::RwLock; |
| 30 | + |
| 31 | +use crate::io::SnapshotWriter; |
| 32 | + |
| 33 | +/// The interface for a snapshot network service. |
| 34 | +/// This handles: |
| 35 | +/// - restoration of snapshots to temporary databases. |
| 36 | +/// - responding to queries for snapshot manifests and chunks |
| 37 | +pub trait SnapshotService : Sync + Send { |
| 38 | + /// Query the most recent manifest data. |
| 39 | + fn manifest(&self) -> Option<ManifestData>; |
| 40 | + |
| 41 | + /// Get the supported range of snapshot version numbers. |
| 42 | + /// `None` indicates warp sync isn't supported by the consensus engine. |
| 43 | + fn supported_versions(&self) -> Option<(u64, u64)>; |
| 44 | + |
| 45 | + /// Returns a list of the completed chunks |
| 46 | + fn completed_chunks(&self) -> Option<Vec<H256>>; |
| 47 | + |
| 48 | + /// Get raw chunk for a given hash. |
| 49 | + fn chunk(&self, hash: H256) -> Option<Bytes>; |
| 50 | + |
| 51 | + /// Ask the snapshot service for the restoration status. |
| 52 | + fn status(&self) -> RestorationStatus; |
| 53 | + |
| 54 | + /// Begin snapshot restoration. |
| 55 | + /// If a restoration is in progress, this will reset it and clear all data. |
| 56 | + fn begin_restore(&self, manifest: ManifestData); |
| 57 | + |
| 58 | + /// Abort an in-progress restoration if there is one. |
| 59 | + fn abort_restore(&self); |
| 60 | + |
| 61 | + /// Feed a raw state chunk to the service to be processed asynchronously. |
| 62 | + /// no-op if not currently restoring. |
| 63 | + fn restore_state_chunk(&self, hash: H256, chunk: Bytes); |
| 64 | + |
| 65 | + /// Feed a raw block chunk to the service to be processed asynchronously. |
| 66 | + /// no-op if currently restoring. |
| 67 | + fn restore_block_chunk(&self, hash: H256, chunk: Bytes); |
| 68 | + |
| 69 | + /// Abort in-progress snapshotting if there is one. |
| 70 | + fn abort_snapshot(&self); |
| 71 | + |
| 72 | + /// Shutdown the Snapshot Service by aborting any ongoing restore |
| 73 | + fn shutdown(&self); |
| 74 | +} |
| 75 | + |
| 76 | +/// Restore from secondary snapshot chunks. |
| 77 | +pub trait Rebuilder: Send { |
| 78 | + /// Feed a chunk, potentially out of order. |
| 79 | + /// |
| 80 | + /// Check `abort_flag` periodically while doing heavy work. If set to `false`, should bail with |
| 81 | + /// `Error::RestorationAborted`. |
| 82 | + fn feed( |
| 83 | + &mut self, |
| 84 | + chunk: &[u8], |
| 85 | + engine: &dyn Engine, |
| 86 | + abort_flag: &AtomicBool, |
| 87 | + ) -> Result<(), Error>; |
| 88 | + |
| 89 | + /// Finalize the restoration. Will be done after all chunks have been |
| 90 | + /// fed successfully. |
| 91 | + /// |
| 92 | + /// This should apply the necessary "glue" between chunks, |
| 93 | + /// and verify against the restored state. |
| 94 | + fn finalize(&mut self) -> Result<(), Error>; |
| 95 | +} |
| 96 | + |
| 97 | +/// Components necessary for snapshot creation and restoration. |
| 98 | +pub trait SnapshotComponents: Send { |
| 99 | + /// Create secondary snapshot chunks; these corroborate the state data |
| 100 | + /// in the state chunks. |
| 101 | + /// |
| 102 | + /// Chunks shouldn't exceed the given preferred size, and should be fed |
| 103 | + /// uncompressed into the sink. |
| 104 | + /// |
| 105 | + /// This will vary by consensus engine, so it's exposed as a trait. |
| 106 | + fn chunk_all( |
| 107 | + &mut self, |
| 108 | + chain: &BlockChain, |
| 109 | + block_at: H256, |
| 110 | + chunk_sink: &mut ChunkSink, |
| 111 | + progress: &RwLock<Progress>, |
| 112 | + preferred_size: usize, |
| 113 | + ) -> Result<(), SnapshotError>; |
| 114 | + |
| 115 | + /// Create a rebuilder, which will have chunks fed into it in arbitrary |
| 116 | + /// order and then be finalized. |
| 117 | + /// |
| 118 | + /// The manifest, a database, and fresh `BlockChain` are supplied. |
| 119 | + /// |
| 120 | + /// The engine passed to the `Rebuilder` methods will be the same instance |
| 121 | + /// that created the `SnapshotComponents`. |
| 122 | + fn rebuilder( |
| 123 | + &self, |
| 124 | + chain: BlockChain, |
| 125 | + db: Arc<dyn BlockChainDB>, |
| 126 | + manifest: &ManifestData, |
| 127 | + ) -> Result<Box<dyn Rebuilder>, Error>; |
| 128 | + |
| 129 | + /// Minimum supported snapshot version number. |
| 130 | + fn min_supported_version(&self) -> u64; |
| 131 | + |
| 132 | + /// Current version number |
| 133 | + fn current_version(&self) -> u64; |
| 134 | +} |
| 135 | + |
| 136 | +/// Snapshot related functionality |
| 137 | +pub trait SnapshotClient: BlockChainClient + BlockInfo + DatabaseRestore + BlockChainReset { |
| 138 | + /// Take a snapshot at the given block. |
| 139 | + /// If the BlockId is 'Latest', this will default to 1000 blocks behind. |
| 140 | + fn take_snapshot<W: SnapshotWriter + Send>( |
| 141 | + &self, |
| 142 | + writer: W, |
| 143 | + at: BlockId, |
| 144 | + p: &RwLock<Progress>, |
| 145 | + ) -> Result<(), Error>; |
| 146 | +} |
| 147 | + |
| 148 | +/// Helper trait for broadcasting a block to take a snapshot at. |
| 149 | +pub trait Broadcast: Send + Sync { |
| 150 | + /// Start a snapshot from the given block number. |
| 151 | + fn request_snapshot_at(&self, num: u64); |
| 152 | +} |
| 153 | + |
| 154 | + |
| 155 | +/// Helper trait for transforming hashes to block numbers and checking if syncing. |
| 156 | +pub trait Oracle: Send + Sync { |
| 157 | + /// Maps a block hash to a block number |
| 158 | + fn to_number(&self, hash: H256) -> Option<u64>; |
| 159 | + |
| 160 | + /// Are we currently syncing? |
| 161 | + fn is_major_importing(&self) -> bool; |
| 162 | +} |
0 commit comments