Repository: paritytech/substrate
File: utils/frame/remote-externalities/src/lib.rs (Rust)

Code before:
}

#[derive(Decode, Encode)]
struct SnapshotOnlyVersion {
	snapshot_version: Compact<u16>,
}

impl<B: BlockT> Snapshot<B> {
	pub fn new(
		state_version: StateVersion,
		block_hash: B::Hash,
		raw_storage: Vec<(H256, (Vec<u8>, i32))>,
		storage_root: H256,
	) -> Self {
		Self {
			snapshot_version: SNAPSHOT_VERSION,
			state_version,
			block_hash,
			raw_storage,
			storage_root,
		}
	}

	fn load(path: &PathBuf) -> Result<Snapshot<B>, &'static str> {
		let bytes = fs::read(path).map_err(|_| "fs::read failed.")?;
		let maybe_version: Result<SnapshotOnlyVersion, _> = Decode::decode(&mut &*bytes);
		match maybe_version {
			Ok(snapshot_only_version) => {
				if snapshot_only_version.snapshot_version != SNAPSHOT_VERSION {
					return Err(
						"Unsupported snapshot version detected. Please create a new snapshot.",
					)
				}
				match Decode::decode(&mut &*bytes) {
					Ok(snapshot) => return Ok(snapshot),
					Err(_) => Err("Decode failed"),
				}
			},
			Err(_) => Err("Decode failed"),
		}
	}
}

/// An externalities that acts exactly the same as [`sp_io::TestExternalities`] but has a few extra
/// bits and pieces to it, and can be loaded remotely.
pub struct RemoteExternalities<B: BlockT> {
	/// The inner externalities.
	pub inner_ext: TestExternalities,
	/// The block hash it which we created this externality env.
	pub block_hash: B::Hash,
}

Review comment (suggestion):
The `C` in SCALE stands for Concatenated, so if you put the `StorageVersion` at the end of the `Snapshot`, then you can just try to decode it after the `Snapshot` was decoded without any hacking. (probably need to change `bytes` to be `mut`)

Code after:
	storage_root: H256,
}

impl<B: BlockT> Snapshot<B> {
	pub fn new(
		state_version: StateVersion,
		block_hash: B::Hash,
		raw_storage: Vec<(H256, (Vec<u8>, i32))>,
		storage_root: H256,
	) -> Self {
		Self {
			snapshot_version: SNAPSHOT_VERSION,
			state_version,
			block_hash,
			raw_storage,
			storage_root,
		}
	}

	fn load(path: &PathBuf) -> Result<Snapshot<B>, &'static str> {
		let bytes = fs::read(path).map_err(|_| "fs::read failed.")?;
		// The first item in the SCALE encoded struct bytes is the snapshot version. We decode and
		// check that first, before proceeding to decode the rest of the snapshot.
		let maybe_version: Result<SnapshotVersion, _> = Decode::decode(&mut &*bytes);
		match maybe_version {
			Ok(snapshot_version) => {
				if snapshot_version != SNAPSHOT_VERSION {
					return Err(
						"Unsupported snapshot version detected. Please create a new snapshot.",
					)
				}
				match Decode::decode(&mut &*bytes) {
					Ok(snapshot) => return Ok(snapshot),
					Err(_) => Err("Decode failed"),
				}
			},
			Err(_) => Err("Decode failed"),
		}
	}
}

/// An externalities that acts exactly the same as [`sp_io::TestExternalities`] but has a few extra
/// bits and pieces to it, and can be loaded remotely.
pub struct RemoteExternalities<B: BlockT> {
	/// The inner externalities.
	pub inner_ext: TestExternalities,
	/// The block hash it which we created this externality env.
	pub block_hash: B::Hash,
}

impl<B: BlockT> Deref for RemoteExternalities<B> {