frame_remote_externalities/
config.rs1use codec::{Compact, Decode, Encode};
21use sp_runtime::{traits::Block as BlockT, StateVersion};
22use std::{
23 fs,
24 path::{Path, PathBuf},
25};
26
27use crate::Result;
28
29pub(crate) const DEFAULT_HTTP_ENDPOINT: &str = "https://try-runtime.polkadot.io:443";
30pub(crate) type SnapshotVersion = Compact<u16>;
31pub(crate) const SNAPSHOT_VERSION: SnapshotVersion = Compact(4);
32
33#[derive(Clone)]
35pub enum Mode<H> {
36 Online(OnlineConfig<H>),
38 Offline(OfflineConfig),
40 OfflineOrElseOnline(OfflineConfig, OnlineConfig<H>),
42}
43
44impl<H> Default for Mode<H> {
45 fn default() -> Self {
46 Mode::Online(OnlineConfig::default())
47 }
48}
49
50#[derive(Clone)]
54pub struct OfflineConfig {
55 pub state_snapshot: SnapshotConfig,
57}
58
59#[derive(Clone)]
63pub struct OnlineConfig<H> {
64 pub at: Option<H>,
67 pub state_snapshot: Option<SnapshotConfig>,
69 pub pallets: Vec<String>,
71 pub transport_uris: Vec<String>,
73 pub child_trie: bool,
75 pub hashed_prefixes: Vec<Vec<u8>>,
78 pub hashed_keys: Vec<Vec<u8>>,
80}
81
82impl<H: Clone> OnlineConfig<H> {
83 pub(crate) fn at_expected(&self) -> H {
84 self.at.clone().expect("block at must be initialized; qed")
85 }
86}
87
88impl<H> Default for OnlineConfig<H> {
89 fn default() -> Self {
90 Self {
91 transport_uris: vec![DEFAULT_HTTP_ENDPOINT.to_owned()],
92 child_trie: true,
93 at: None,
94 state_snapshot: None,
95 pallets: Default::default(),
96 hashed_keys: Default::default(),
97 hashed_prefixes: Default::default(),
98 }
99 }
100}
101
102impl<H> From<String> for OnlineConfig<H> {
103 fn from(uri: String) -> Self {
104 Self { transport_uris: vec![uri], ..Default::default() }
105 }
106}
107
108#[derive(Clone)]
110pub struct SnapshotConfig {
111 pub path: PathBuf,
113}
114
115impl SnapshotConfig {
116 pub fn new<P: Into<PathBuf>>(path: P) -> Self {
117 Self { path: path.into() }
118 }
119}
120
121impl From<String> for SnapshotConfig {
122 fn from(s: String) -> Self {
123 Self::new(s)
124 }
125}
126
127impl Default for SnapshotConfig {
128 fn default() -> Self {
129 Self { path: Path::new("SNAPSHOT").into() }
130 }
131}
132
133#[derive(Decode, Encode)]
135pub(crate) struct Snapshot<B: BlockT> {
136 snapshot_version: SnapshotVersion,
137 pub(crate) state_version: StateVersion,
138 pub(crate) raw_storage: Vec<(Vec<u8>, (Vec<u8>, i32))>,
139 pub(crate) storage_root: B::Hash,
140 pub(crate) header: B::Header,
141}
142
143impl<B: BlockT> Snapshot<B> {
144 pub(crate) fn new(
145 state_version: StateVersion,
146 raw_storage: Vec<(Vec<u8>, (Vec<u8>, i32))>,
147 storage_root: B::Hash,
148 header: B::Header,
149 ) -> Self {
150 Self {
151 snapshot_version: SNAPSHOT_VERSION,
152 state_version,
153 raw_storage,
154 storage_root,
155 header,
156 }
157 }
158
159 pub(crate) fn load(path: &PathBuf) -> Result<Snapshot<B>> {
160 let bytes = fs::read(path).map_err(|_| "fs::read failed.")?;
161 let snapshot_version = SnapshotVersion::decode(&mut &*bytes)
164 .map_err(|_| "Failed to decode snapshot version")?;
165
166 if snapshot_version != SNAPSHOT_VERSION {
167 return Err("Unsupported snapshot version detected. Please create a new snapshot.");
168 }
169
170 Decode::decode(&mut &*bytes).map_err(|_| "Decode failed")
171 }
172}