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