fc_db/kv/
utils.rs

1// This file is part of Frontier.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
5
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <https://www.gnu.org/licenses/>.
18
19use std::{path::Path, sync::Arc};
20
21// Substrate
22use sp_blockchain::HeaderBackend;
23use sp_runtime::traits::Block as BlockT;
24
25use super::{Database, DatabaseSettings, DatabaseSource, DbHash};
26
27pub fn open_database<Block: BlockT, C: HeaderBackend<Block>>(
28	client: Arc<C>,
29	config: &DatabaseSettings,
30) -> Result<Arc<dyn Database<DbHash>>, String> {
31	let db: Arc<dyn Database<DbHash>> = match &config.source {
32		DatabaseSource::Auto {
33			paritydb_path,
34			rocksdb_path,
35			..
36		} => {
37			match open_kvdb_rocksdb::<Block, C>(client.clone(), rocksdb_path, false, &config.source)
38			{
39				Ok(db) => db,
40				Err(_) => open_parity_db::<Block, C>(client, paritydb_path, &config.source)?,
41			}
42		}
43		#[cfg(feature = "rocksdb")]
44		DatabaseSource::RocksDb { path, .. } => {
45			open_kvdb_rocksdb::<Block, C>(client, path, true, &config.source)?
46		}
47		DatabaseSource::ParityDb { path } => {
48			open_parity_db::<Block, C>(client, path, &config.source)?
49		}
50		_ => return Err("Supported db sources: `auto` | `rocksdb` | `paritydb`".to_string()),
51	};
52	Ok(db)
53}
54
55#[allow(unused_variables)]
56#[cfg(feature = "rocksdb")]
57fn open_kvdb_rocksdb<Block: BlockT, C: HeaderBackend<Block>>(
58	client: Arc<C>,
59	path: &Path,
60	create: bool,
61	_source: &DatabaseSource,
62) -> Result<Arc<dyn Database<DbHash>>, String> {
63	// first upgrade database to required version
64	#[cfg(not(test))]
65	match super::upgrade::upgrade_db::<Block, C>(client, path, _source) {
66		Ok(_) => (),
67		Err(_) => return Err("Frontier DB upgrade error".to_string()),
68	}
69
70	let mut db_config = kvdb_rocksdb::DatabaseConfig::with_columns(super::columns::NUM_COLUMNS);
71	db_config.create_if_missing = create;
72
73	let db = kvdb_rocksdb::Database::open(&db_config, path).map_err(|err| format!("{err}"))?;
74	// write database version only after the database is successfully opened
75	#[cfg(not(test))]
76	super::upgrade::update_version(path).map_err(|_| "Cannot update db version".to_string())?;
77	Ok(sp_database::as_database(db))
78}
79
80#[cfg(not(feature = "rocksdb"))]
81fn open_kvdb_rocksdb<Block: BlockT, C: HeaderBackend<Block>>(
82	_client: Arc<C>,
83	_path: &Path,
84	_create: bool,
85	_source: &DatabaseSource,
86) -> Result<Arc<dyn Database<DbHash>>, String> {
87	Err("Missing feature flags `rocksdb`".to_string())
88}
89
90#[allow(unused_variables)]
91fn open_parity_db<Block: BlockT, C: HeaderBackend<Block>>(
92	client: Arc<C>,
93	path: &Path,
94	_source: &DatabaseSource,
95) -> Result<Arc<dyn Database<DbHash>>, String> {
96	// first upgrade database to required version
97	#[cfg(not(test))]
98	match super::upgrade::upgrade_db::<Block, C>(client, path, _source) {
99		Ok(_) => (),
100		Err(_) => return Err("Frontier DB upgrade error".to_string()),
101	}
102	let mut config = parity_db::Options::with_columns(path, super::columns::NUM_COLUMNS as u8);
103	config.columns[super::columns::BLOCK_MAPPING as usize].btree_index = true;
104
105	let db = parity_db::Db::open_or_create(&config).map_err(|err| format!("{err}"))?;
106	// write database version only after the database is successfully opened
107	#[cfg(not(test))]
108	super::upgrade::update_version(path).map_err(|_| "Cannot update db version".to_string())?;
109	Ok(Arc::new(super::parity_db_adapter::DbAdapter(db)))
110}