mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 22:11:06 +00:00
Migrate basic-authorship, cli and client-db crates to 2018 edition (#1529)
This commit is contained in:
committed by
Gav Wood
parent
ac065a96ba
commit
28c37ef419
+6
-4
@@ -41,12 +41,14 @@
|
||||
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
use log::warn;
|
||||
|
||||
use client::error::{ErrorKind as ClientErrorKind, Result as ClientResult};
|
||||
use runtime_primitives::traits::{Block as BlockT, NumberFor, As, Zero};
|
||||
|
||||
use cache::{CacheItemT, ComplexBlockId};
|
||||
use cache::list_entry::{Entry, StorageEntry};
|
||||
use cache::list_storage::{Storage, StorageTransaction, Metadata};
|
||||
use crate::cache::{CacheItemT, ComplexBlockId};
|
||||
use crate::cache::list_entry::{Entry, StorageEntry};
|
||||
use crate::cache::list_storage::{Storage, StorageTransaction, Metadata};
|
||||
|
||||
/// List-based cache.
|
||||
pub struct ListCache<Block: BlockT, T: CacheItemT, S: Storage<Block, T>> {
|
||||
@@ -585,7 +587,7 @@ fn read_forks<Block: BlockT, T: CacheItemT, S: Storage<Block, T>>(
|
||||
pub mod tests {
|
||||
use runtime_primitives::testing::{Header, Block as RawBlock, ExtrinsicWrapper};
|
||||
use runtime_primitives::traits::Header as HeaderT;
|
||||
use cache::list_storage::tests::{DummyStorage, FaultyStorage, DummyTransaction};
|
||||
use crate::cache::list_storage::tests::{DummyStorage, FaultyStorage, DummyTransaction};
|
||||
use super::*;
|
||||
|
||||
type Block = RawBlock<ExtrinsicWrapper<u64>>;
|
||||
|
||||
+5
-4
@@ -18,9 +18,10 @@
|
||||
|
||||
use client::error::Result as ClientResult;
|
||||
use runtime_primitives::traits::{Block as BlockT, NumberFor};
|
||||
use parity_codec_derive::{Encode, Decode};
|
||||
|
||||
use cache::{CacheItemT, ComplexBlockId};
|
||||
use cache::list_storage::{Storage};
|
||||
use crate::cache::{CacheItemT, ComplexBlockId};
|
||||
use crate::cache::list_storage::{Storage};
|
||||
|
||||
/// Single list-based cache entry.
|
||||
#[derive(Debug)]
|
||||
@@ -112,8 +113,8 @@ impl<Block: BlockT, T: CacheItemT> StorageEntry<Block, T> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use cache::list_cache::tests::test_id;
|
||||
use cache::list_storage::tests::{DummyStorage, FaultyStorage};
|
||||
use crate::cache::list_cache::tests::test_id;
|
||||
use crate::cache::list_storage::tests::{DummyStorage, FaultyStorage};
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
|
||||
+5
-5
@@ -21,14 +21,14 @@ use std::sync::Arc;
|
||||
use kvdb::{KeyValueDB, DBTransaction};
|
||||
|
||||
use client::error::{Error as ClientError, ErrorKind as ClientErrorKind, Result as ClientResult};
|
||||
use codec::{Encode, Decode};
|
||||
use parity_codec::{Encode, Decode};
|
||||
use runtime_primitives::generic::BlockId;
|
||||
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor};
|
||||
use utils::{self, db_err, meta_keys};
|
||||
use crate::utils::{self, db_err, meta_keys};
|
||||
|
||||
use cache::{CacheItemT, ComplexBlockId};
|
||||
use cache::list_cache::{CommitOperation, Fork};
|
||||
use cache::list_entry::{Entry, StorageEntry};
|
||||
use crate::cache::{CacheItemT, ComplexBlockId};
|
||||
use crate::cache::list_cache::{CommitOperation, Fork};
|
||||
use crate::cache::list_entry::{Entry, StorageEntry};
|
||||
|
||||
/// Single list-cache metadata.
|
||||
#[derive(Debug)]
|
||||
|
||||
+3
-2
@@ -23,10 +23,11 @@ use kvdb::{KeyValueDB, DBTransaction};
|
||||
|
||||
use client::blockchain::Cache as BlockchainCache;
|
||||
use client::error::Result as ClientResult;
|
||||
use codec::{Encode, Decode};
|
||||
use parity_codec::{Encode, Decode};
|
||||
use parity_codec_derive::{Encode, Decode};
|
||||
use runtime_primitives::generic::BlockId;
|
||||
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT, NumberFor, As, AuthorityIdFor};
|
||||
use utils::{self, COLUMN_META};
|
||||
use crate::utils::{self, COLUMN_META};
|
||||
|
||||
use self::list_cache::ListCache;
|
||||
|
||||
|
||||
@@ -24,32 +24,6 @@
|
||||
//!
|
||||
//! Finality implies canonicality but not vice-versa.
|
||||
|
||||
extern crate substrate_client as client;
|
||||
extern crate kvdb_rocksdb;
|
||||
extern crate kvdb;
|
||||
extern crate hash_db;
|
||||
extern crate parking_lot;
|
||||
extern crate lru_cache;
|
||||
extern crate substrate_state_machine as state_machine;
|
||||
extern crate substrate_primitives as primitives;
|
||||
extern crate sr_primitives as runtime_primitives;
|
||||
extern crate parity_codec as codec;
|
||||
extern crate substrate_executor as executor;
|
||||
extern crate substrate_state_db as state_db;
|
||||
extern crate substrate_trie as trie;
|
||||
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
|
||||
#[macro_use]
|
||||
extern crate parity_codec_derive;
|
||||
|
||||
#[cfg(test)]
|
||||
extern crate substrate_test_client as test_client;
|
||||
|
||||
#[cfg(test)]
|
||||
extern crate kvdb_memorydb;
|
||||
|
||||
pub mod light;
|
||||
|
||||
mod cache;
|
||||
@@ -61,7 +35,7 @@ use std::path::PathBuf;
|
||||
use std::io;
|
||||
|
||||
use client::backend::NewBlockState;
|
||||
use codec::{Decode, Encode};
|
||||
use parity_codec::{Decode, Encode};
|
||||
use hash_db::Hasher;
|
||||
use kvdb::{KeyValueDB, DBTransaction};
|
||||
use trie::MemoryDB;
|
||||
@@ -78,6 +52,7 @@ use utils::{Meta, db_err, meta_keys, open_database, read_db, block_id_to_lookup_
|
||||
use client::LeafSet;
|
||||
use state_db::StateDb;
|
||||
use storage_cache::{CachingState, SharedCache, new_shared_cache};
|
||||
use log::{trace, debug, warn};
|
||||
pub use state_db::PruningMode;
|
||||
|
||||
const CANONICALIZATION_DELAY: u64 = 256;
|
||||
@@ -116,7 +91,7 @@ pub fn new_client<E, S, Block, RA>(
|
||||
}
|
||||
|
||||
mod columns {
|
||||
pub const META: Option<u32> = ::utils::COLUMN_META;
|
||||
pub const META: Option<u32> = crate::utils::COLUMN_META;
|
||||
pub const STATE: Option<u32> = Some(1);
|
||||
pub const STATE_META: Option<u32> = Some(2);
|
||||
/// maps hashes to lookup keys and numbers to canon hashes.
|
||||
@@ -191,7 +166,7 @@ impl<Block: BlockT> BlockchainDb<Block> {
|
||||
|
||||
impl<Block: BlockT> client::blockchain::HeaderBackend<Block> for BlockchainDb<Block> {
|
||||
fn header(&self, id: BlockId<Block>) -> Result<Option<Block::Header>, client::error::Error> {
|
||||
::utils::read_header(&*self.db, columns::KEY_LOOKUP, columns::HEADER, id)
|
||||
utils::read_header(&*self.db, columns::KEY_LOOKUP, columns::HEADER, id)
|
||||
}
|
||||
|
||||
fn info(&self) -> Result<client::blockchain::Info<Block>, client::error::Error> {
|
||||
@@ -486,7 +461,7 @@ impl<Block: BlockT> state_machine::ChangesTrieRootsStorage<Blake2Hasher> for DbC
|
||||
// the block is not finalized
|
||||
let mut current_num = anchor.number;
|
||||
let mut current_hash: Block::Hash = convert_hash(&anchor.hash);
|
||||
let maybe_anchor_header: Block::Header = ::utils::require_header::<Block>(
|
||||
let maybe_anchor_header: Block::Header = utils::require_header::<Block>(
|
||||
&*self.db, columns::KEY_LOOKUP, columns::HEADER, BlockId::Number(As::sa(current_num))
|
||||
).map_err(|e| e.to_string())?;
|
||||
if maybe_anchor_header.hash() == current_hash {
|
||||
@@ -497,7 +472,7 @@ impl<Block: BlockT> state_machine::ChangesTrieRootsStorage<Blake2Hasher> for DbC
|
||||
// => we should find the required block hash by traversing
|
||||
// back from the anchor to the block with given number
|
||||
while current_num != block {
|
||||
let current_header: Block::Header = ::utils::require_header::<Block>(
|
||||
let current_header: Block::Header = utils::require_header::<Block>(
|
||||
&*self.db, columns::KEY_LOOKUP, columns::HEADER, BlockId::Hash(current_hash)
|
||||
).map_err(|e| e.to_string())?;
|
||||
|
||||
@@ -509,7 +484,7 @@ impl<Block: BlockT> state_machine::ChangesTrieRootsStorage<Blake2Hasher> for DbC
|
||||
}
|
||||
};
|
||||
|
||||
Ok(::utils::require_header::<Block>(&*self.db, columns::KEY_LOOKUP, columns::HEADER, block_id)
|
||||
Ok(utils::require_header::<Block>(&*self.db, columns::KEY_LOOKUP, columns::HEADER, block_id)
|
||||
.map_err(|e| e.to_string())?
|
||||
.digest().log(DigestItem::as_changes_trie_root)
|
||||
.map(|root| H256::from_slice(root.as_ref())))
|
||||
@@ -638,7 +613,7 @@ impl<Block: BlockT> Backend<Block> {
|
||||
).into())
|
||||
}
|
||||
|
||||
let lookup_key = ::utils::number_and_hash_to_lookup_key(f_num, f_hash.clone());
|
||||
let lookup_key = utils::number_and_hash_to_lookup_key(f_num, f_hash.clone());
|
||||
transaction.put(columns::META, meta_keys::FINALIZED_BLOCK, &lookup_key);
|
||||
|
||||
let commit = self.storage.state_db.canonicalize_block(&f_hash);
|
||||
@@ -725,7 +700,7 @@ impl<Block> client::backend::Backend<Block, Blake2Hasher> for Backend<Block> whe
|
||||
let number = pending_block.header.number().clone();
|
||||
|
||||
// blocks are keyed by number + hash.
|
||||
let lookup_key = ::utils::number_and_hash_to_lookup_key(number, hash);
|
||||
let lookup_key = utils::number_and_hash_to_lookup_key(number, hash);
|
||||
|
||||
let mut enacted = Vec::default();
|
||||
let mut retracted = Vec::default();
|
||||
@@ -752,7 +727,7 @@ impl<Block> client::backend::Backend<Block, Blake2Hasher> for Backend<Block> whe
|
||||
return Err(::client::error::ErrorKind::NotInFinalizedChain.into());
|
||||
}
|
||||
|
||||
::utils::remove_number_to_key_mapping(
|
||||
utils::remove_number_to_key_mapping(
|
||||
&mut transaction,
|
||||
columns::KEY_LOOKUP,
|
||||
r.number
|
||||
@@ -762,7 +737,7 @@ impl<Block> client::backend::Backend<Block, Blake2Hasher> for Backend<Block> whe
|
||||
// canonicalize: set the number lookup to map to this block's hash.
|
||||
for e in tree_route.enacted() {
|
||||
enacted.push(e.hash.clone());
|
||||
::utils::insert_number_to_key_mapping(
|
||||
utils::insert_number_to_key_mapping(
|
||||
&mut transaction,
|
||||
columns::KEY_LOOKUP,
|
||||
e.number,
|
||||
@@ -772,7 +747,7 @@ impl<Block> client::backend::Backend<Block, Blake2Hasher> for Backend<Block> whe
|
||||
}
|
||||
|
||||
transaction.put(columns::META, meta_keys::BEST_BLOCK, &lookup_key);
|
||||
::utils::insert_number_to_key_mapping(
|
||||
utils::insert_number_to_key_mapping(
|
||||
&mut transaction,
|
||||
columns::KEY_LOOKUP,
|
||||
number,
|
||||
@@ -780,7 +755,7 @@ impl<Block> client::backend::Backend<Block, Blake2Hasher> for Backend<Block> whe
|
||||
);
|
||||
}
|
||||
|
||||
::utils::insert_hash_to_key_mapping(
|
||||
utils::insert_hash_to_key_mapping(
|
||||
&mut transaction,
|
||||
columns::KEY_LOOKUP,
|
||||
number,
|
||||
@@ -880,7 +855,7 @@ impl<Block> client::backend::Backend<Block, Blake2Hasher> for Backend<Block> whe
|
||||
let number = header.number().clone();
|
||||
transaction.put(
|
||||
columns::JUSTIFICATION,
|
||||
&::utils::number_and_hash_to_lookup_key(number, hash.clone()),
|
||||
&utils::number_and_hash_to_lookup_key(number, hash.clone()),
|
||||
&justification.encode(),
|
||||
);
|
||||
}
|
||||
@@ -920,7 +895,7 @@ impl<Block> client::backend::Backend<Block, Blake2Hasher> for Backend<Block> whe
|
||||
let hash = self.blockchain.hash(best)?.ok_or_else(
|
||||
|| client::error::ErrorKind::UnknownBlock(
|
||||
format!("Error reverting to {}. Block hash not found.", best)))?;
|
||||
let key = ::utils::number_and_hash_to_lookup_key(best.clone(), hash.clone());
|
||||
let key = utils::number_and_hash_to_lookup_key(best.clone(), hash.clone());
|
||||
transaction.put(columns::META, meta_keys::BEST_BLOCK, &key);
|
||||
transaction.delete(columns::KEY_LOOKUP, removed.hash().as_ref());
|
||||
self.storage.db.write(transaction).map_err(db_err)?;
|
||||
@@ -978,6 +953,7 @@ where Block: BlockT<Hash=H256> {}
|
||||
mod tests {
|
||||
use hash_db::HashDB;
|
||||
use super::*;
|
||||
use crate::columns;
|
||||
use client::backend::Backend as BTrait;
|
||||
use client::backend::BlockImportOperation as Op;
|
||||
use client::blockchain::HeaderBackend as BlockchainHeaderBackend;
|
||||
@@ -1205,7 +1181,7 @@ mod tests {
|
||||
|
||||
backend.commit_operation(op).unwrap();
|
||||
|
||||
assert_eq!(backend.storage.db.get(::columns::STATE, key.as_bytes()).unwrap().unwrap(), &b"hello"[..]);
|
||||
assert_eq!(backend.storage.db.get(columns::STATE, key.as_bytes()).unwrap().unwrap(), &b"hello"[..]);
|
||||
hash
|
||||
};
|
||||
|
||||
@@ -1239,7 +1215,7 @@ mod tests {
|
||||
|
||||
backend.commit_operation(op).unwrap();
|
||||
|
||||
assert_eq!(backend.storage.db.get(::columns::STATE, key.as_bytes()).unwrap().unwrap(), &b"hello"[..]);
|
||||
assert_eq!(backend.storage.db.get(columns::STATE, key.as_bytes()).unwrap().unwrap(), &b"hello"[..]);
|
||||
hash
|
||||
};
|
||||
|
||||
@@ -1271,12 +1247,12 @@ mod tests {
|
||||
|
||||
backend.commit_operation(op).unwrap();
|
||||
|
||||
assert!(backend.storage.db.get(::columns::STATE, key.as_bytes()).unwrap().is_none());
|
||||
assert!(backend.storage.db.get(columns::STATE, key.as_bytes()).unwrap().is_none());
|
||||
}
|
||||
|
||||
backend.finalize_block(BlockId::Number(1), None).unwrap();
|
||||
backend.finalize_block(BlockId::Number(2), None).unwrap();
|
||||
assert!(backend.storage.db.get(::columns::STATE, key.as_bytes()).unwrap().is_none());
|
||||
assert!(backend.storage.db.get(columns::STATE, key.as_bytes()).unwrap().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -27,18 +27,19 @@ use client::blockchain::{BlockStatus, Cache as BlockchainCache,
|
||||
use client::{cht, LeafSet};
|
||||
use client::error::{ErrorKind as ClientErrorKind, Result as ClientResult};
|
||||
use client::light::blockchain::Storage as LightBlockchainStorage;
|
||||
use codec::{Decode, Encode};
|
||||
use parity_codec::{Decode, Encode};
|
||||
use primitives::Blake2Hasher;
|
||||
use runtime_primitives::generic::BlockId;
|
||||
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT,
|
||||
Zero, One, As, NumberFor, Digest, DigestItem, AuthorityIdFor};
|
||||
use cache::{DbCacheSync, DbCache, ComplexBlockId};
|
||||
use utils::{meta_keys, Meta, db_err, open_database,
|
||||
use crate::cache::{DbCacheSync, DbCache, ComplexBlockId};
|
||||
use crate::utils::{self, meta_keys, Meta, db_err, open_database,
|
||||
read_db, block_id_to_lookup_key, read_meta};
|
||||
use DatabaseSettings;
|
||||
use crate::DatabaseSettings;
|
||||
use log::{trace, warn, debug};
|
||||
|
||||
pub(crate) mod columns {
|
||||
pub const META: Option<u32> = ::utils::COLUMN_META;
|
||||
pub const META: Option<u32> = crate::utils::COLUMN_META;
|
||||
pub const KEY_LOOKUP: Option<u32> = Some(1);
|
||||
pub const HEADER: Option<u32> = Some(2);
|
||||
pub const CACHE: Option<u32> = Some(3);
|
||||
@@ -135,7 +136,7 @@ impl<Block> BlockchainHeaderBackend<Block> for LightStorage<Block>
|
||||
Block: BlockT,
|
||||
{
|
||||
fn header(&self, id: BlockId<Block>) -> ClientResult<Option<Block::Header>> {
|
||||
::utils::read_header(&*self.db, columns::KEY_LOOKUP, columns::HEADER, id)
|
||||
utils::read_header(&*self.db, columns::KEY_LOOKUP, columns::HEADER, id)
|
||||
}
|
||||
|
||||
fn info(&self) -> ClientResult<BlockchainInfo<Block>> {
|
||||
@@ -167,7 +168,7 @@ impl<Block> BlockchainHeaderBackend<Block> for LightStorage<Block>
|
||||
|
||||
fn number(&self, hash: Block::Hash) -> ClientResult<Option<NumberFor<Block>>> {
|
||||
if let Some(lookup_key) = block_id_to_lookup_key::<Block>(&*self.db, columns::KEY_LOOKUP, BlockId::Hash(hash))? {
|
||||
let number = ::utils::lookup_key_to_number(&lookup_key)?;
|
||||
let number = utils::lookup_key_to_number(&lookup_key)?;
|
||||
Ok(Some(number))
|
||||
} else {
|
||||
Ok(None)
|
||||
@@ -203,7 +204,7 @@ impl<Block: BlockT> LightStorage<Block> {
|
||||
).into())
|
||||
}
|
||||
|
||||
let lookup_key = ::utils::number_and_hash_to_lookup_key(header.number().clone(), hash);
|
||||
let lookup_key = utils::number_and_hash_to_lookup_key(header.number().clone(), hash);
|
||||
transaction.put(columns::META, meta_keys::FINALIZED_BLOCK, &lookup_key);
|
||||
|
||||
// build new CHT(s) if required
|
||||
@@ -243,7 +244,7 @@ impl<Block: BlockT> LightStorage<Block> {
|
||||
if let Some(hash) = self.hash(prune_block)? {
|
||||
let lookup_key = block_id_to_lookup_key::<Block>(&*self.db, columns::KEY_LOOKUP, BlockId::Number(prune_block))?
|
||||
.expect("retrieved hash for `prune_block` right above. therefore retrieving lookup key must succeed. q.e.d.");
|
||||
::utils::remove_key_mappings(
|
||||
utils::remove_key_mappings(
|
||||
transaction,
|
||||
columns::KEY_LOOKUP,
|
||||
prune_block,
|
||||
@@ -324,7 +325,7 @@ impl<Block> LightBlockchainStorage<Block> for LightStorage<Block>
|
||||
}
|
||||
|
||||
// blocks are keyed by number + hash.
|
||||
let lookup_key = ::utils::number_and_hash_to_lookup_key(number, hash);
|
||||
let lookup_key = utils::number_and_hash_to_lookup_key(number, hash);
|
||||
|
||||
if leaf_state.is_best() {
|
||||
// handle reorg.
|
||||
@@ -345,7 +346,7 @@ impl<Block> LightBlockchainStorage<Block> for LightStorage<Block>
|
||||
(&retracted.number, &retracted.hash));
|
||||
}
|
||||
|
||||
::utils::remove_number_to_key_mapping(
|
||||
utils::remove_number_to_key_mapping(
|
||||
&mut transaction,
|
||||
columns::KEY_LOOKUP,
|
||||
retracted.number
|
||||
@@ -353,7 +354,7 @@ impl<Block> LightBlockchainStorage<Block> for LightStorage<Block>
|
||||
}
|
||||
|
||||
for enacted in tree_route.enacted() {
|
||||
::utils::insert_number_to_key_mapping(
|
||||
utils::insert_number_to_key_mapping(
|
||||
&mut transaction,
|
||||
columns::KEY_LOOKUP,
|
||||
enacted.number,
|
||||
@@ -364,7 +365,7 @@ impl<Block> LightBlockchainStorage<Block> for LightStorage<Block>
|
||||
}
|
||||
|
||||
transaction.put(columns::META, meta_keys::BEST_BLOCK, &lookup_key);
|
||||
::utils::insert_number_to_key_mapping(
|
||||
utils::insert_number_to_key_mapping(
|
||||
&mut transaction,
|
||||
columns::KEY_LOOKUP,
|
||||
number,
|
||||
@@ -372,7 +373,7 @@ impl<Block> LightBlockchainStorage<Block> for LightStorage<Block>
|
||||
);
|
||||
}
|
||||
|
||||
::utils::insert_hash_to_key_mapping(
|
||||
utils::insert_hash_to_key_mapping(
|
||||
&mut transaction,
|
||||
columns::KEY_LOOKUP,
|
||||
number,
|
||||
@@ -473,7 +474,7 @@ impl<Block> LightBlockchainStorage<Block> for LightStorage<Block>
|
||||
/// Build the key for inserting header-CHT at given block.
|
||||
fn cht_key<N: As<u64>>(cht_type: u8, block: N) -> [u8; 5] {
|
||||
let mut key = [cht_type; 5];
|
||||
key[1..].copy_from_slice(&::utils::number_index_key(block));
|
||||
key[1..].copy_from_slice(&utils::number_index_key(block));
|
||||
key
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ use lru_cache::LruCache;
|
||||
use hash_db::Hasher;
|
||||
use runtime_primitives::traits::{Block, Header};
|
||||
use state_machine::{backend::Backend as StateBackend, TrieBackend};
|
||||
use log::trace;
|
||||
|
||||
const STATE_CACHE_BLOCKS: usize = 12;
|
||||
|
||||
|
||||
@@ -22,13 +22,14 @@ use std::io;
|
||||
|
||||
use kvdb::{KeyValueDB, DBTransaction};
|
||||
use kvdb_rocksdb::{Database, DatabaseConfig};
|
||||
use log::debug;
|
||||
|
||||
use client;
|
||||
use codec::Decode;
|
||||
use parity_codec::Decode;
|
||||
use trie::DBValue;
|
||||
use runtime_primitives::generic::BlockId;
|
||||
use runtime_primitives::traits::{As, Block as BlockT, Header as HeaderT, Zero};
|
||||
use DatabaseSettings;
|
||||
use crate::DatabaseSettings;
|
||||
|
||||
/// Number of columns in the db. Must be the same for both full && light dbs.
|
||||
/// Otherwise RocksDb will fail to open database && check its type.
|
||||
|
||||
Reference in New Issue
Block a user