pub mod car;
mod memory;
pub mod parity_db;
pub mod parity_db_config;
mod gc;
pub mod ttl;
pub use gc::MarkAndSweep;
pub use memory::MemoryDB;
use setting_keys::ETH_MAPPING_UP_TO_DATE_KEY;
mod db_mode;
pub mod migration;
use crate::rpc::eth::types::EthHash;
use anyhow::Context as _;
use cid::Cid;
use serde::de::DeserializeOwned;
use serde::Serialize;
use std::sync::Arc;
pub const CAR_DB_DIR_NAME: &str = "car_db";
pub mod setting_keys {
pub const HEAD_KEY: &str = "head";
pub const MPOOL_CONFIG_KEY: &str = "/mpool/config";
pub const ETH_MAPPING_UP_TO_DATE_KEY: &str = "eth_mapping_up_to_date";
}
pub trait SettingsStore {
fn read_bin(&self, key: &str) -> anyhow::Result<Option<Vec<u8>>>;
fn write_bin(&self, key: &str, value: &[u8]) -> anyhow::Result<()>;
fn exists(&self, key: &str) -> anyhow::Result<bool>;
fn setting_keys(&self) -> anyhow::Result<Vec<String>>;
}
impl<T: SettingsStore> SettingsStore for Arc<T> {
fn read_bin(&self, key: &str) -> anyhow::Result<Option<Vec<u8>>> {
SettingsStore::read_bin(self.as_ref(), key)
}
fn write_bin(&self, key: &str, value: &[u8]) -> anyhow::Result<()> {
SettingsStore::write_bin(self.as_ref(), key, value)
}
fn exists(&self, key: &str) -> anyhow::Result<bool> {
SettingsStore::exists(self.as_ref(), key)
}
fn setting_keys(&self) -> anyhow::Result<Vec<String>> {
SettingsStore::setting_keys(self.as_ref())
}
}
pub trait SettingsStoreExt {
fn read_obj<V: DeserializeOwned>(&self, key: &str) -> anyhow::Result<Option<V>>;
fn write_obj<V: Serialize>(&self, key: &str, value: &V) -> anyhow::Result<()>;
fn require_obj<V: DeserializeOwned>(&self, key: &str) -> anyhow::Result<V>;
}
impl<T: ?Sized + SettingsStore> SettingsStoreExt for T {
fn read_obj<V: DeserializeOwned>(&self, key: &str) -> anyhow::Result<Option<V>> {
match self.read_bin(key)? {
Some(bytes) => Ok(Some(serde_json::from_slice(&bytes)?)),
None => Ok(None),
}
}
fn write_obj<V: Serialize>(&self, key: &str, value: &V) -> anyhow::Result<()> {
self.write_bin(key, &serde_json::to_vec(value)?)
}
fn require_obj<V: DeserializeOwned>(&self, key: &str) -> anyhow::Result<V> {
self.read_bin(key)?
.with_context(|| format!("Key {key} not found"))
.and_then(|bytes| serde_json::from_slice(&bytes).map_err(Into::into))
}
}
pub trait SettingsExt {
fn set_eth_mapping_up_to_date(&self) -> anyhow::Result<()>;
fn eth_mapping_up_to_date(&self) -> anyhow::Result<Option<bool>>;
}
impl<T: ?Sized + SettingsStoreExt> SettingsExt for T {
fn set_eth_mapping_up_to_date(&self) -> anyhow::Result<()> {
self.write_obj(ETH_MAPPING_UP_TO_DATE_KEY, &true)
}
fn eth_mapping_up_to_date(&self) -> anyhow::Result<Option<bool>> {
self.read_obj(ETH_MAPPING_UP_TO_DATE_KEY)
}
}
pub trait EthMappingsStore {
fn read_bin(&self, key: &EthHash) -> anyhow::Result<Option<Vec<u8>>>;
fn write_bin(&self, key: &EthHash, value: &[u8]) -> anyhow::Result<()>;
fn exists(&self, key: &EthHash) -> anyhow::Result<bool>;
fn get_message_cids(&self) -> anyhow::Result<Vec<(Cid, u64)>>;
fn delete(&self, keys: Vec<EthHash>) -> anyhow::Result<()>;
}
impl<T: EthMappingsStore> EthMappingsStore for Arc<T> {
fn read_bin(&self, key: &EthHash) -> anyhow::Result<Option<Vec<u8>>> {
EthMappingsStore::read_bin(self.as_ref(), key)
}
fn write_bin(&self, key: &EthHash, value: &[u8]) -> anyhow::Result<()> {
EthMappingsStore::write_bin(self.as_ref(), key, value)
}
fn exists(&self, key: &EthHash) -> anyhow::Result<bool> {
EthMappingsStore::exists(self.as_ref(), key)
}
fn get_message_cids(&self) -> anyhow::Result<Vec<(Cid, u64)>> {
EthMappingsStore::get_message_cids(self.as_ref())
}
fn delete(&self, keys: Vec<EthHash>) -> anyhow::Result<()> {
EthMappingsStore::delete(self.as_ref(), keys)
}
}
pub trait EthMappingsStoreExt {
fn read_obj<V: DeserializeOwned>(&self, key: &EthHash) -> anyhow::Result<Option<V>>;
fn write_obj<V: Serialize>(&self, key: &EthHash, value: &V) -> anyhow::Result<()>;
}
impl<T: ?Sized + EthMappingsStore> EthMappingsStoreExt for T {
fn read_obj<V: DeserializeOwned>(&self, key: &EthHash) -> anyhow::Result<Option<V>> {
match self.read_bin(key)? {
Some(bytes) => Ok(Some(fvm_ipld_encoding::from_slice(&bytes)?)),
None => Ok(None),
}
}
fn write_obj<V: Serialize>(&self, key: &EthHash, value: &V) -> anyhow::Result<()> {
self.write_bin(key, &fvm_ipld_encoding::to_vec(value)?)
}
}
pub trait DBStatistics {
fn get_statistics(&self) -> Option<String> {
None
}
}
impl<DB: DBStatistics> DBStatistics for std::sync::Arc<DB> {
fn get_statistics(&self) -> Option<String> {
self.as_ref().get_statistics()
}
}
pub trait GarbageCollectable<T> {
fn get_keys(&self) -> anyhow::Result<T>;
fn remove_keys(&self, keys: T) -> anyhow::Result<u32>;
}
pub mod db_engine {
use std::path::{Path, PathBuf};
use super::db_mode::choose_db;
pub type Db = crate::db::parity_db::ParityDb;
pub type DbConfig = crate::db::parity_db_config::ParityDbConfig;
pub fn db_root(chain_data_root: &Path) -> anyhow::Result<PathBuf> {
choose_db(chain_data_root)
}
pub fn open_db(path: PathBuf, config: DbConfig) -> anyhow::Result<Db> {
Db::open(path, &config).map_err(Into::into)
}
}
#[cfg(test)]
mod tests {
pub mod db_utils;
mod mem_test;
mod parity_test;
pub mod subtests;
}