mirror of
https://github.com/hinto-janai/cuprate.git
synced 2024-12-22 11:39:30 +00:00
workspace: add/fix 1.83 lints (#353)
Some checks failed
Deny / audit (push) Has been cancelled
Doc / build (push) Has been cancelled
CI / fmt (push) Has been cancelled
CI / typo (push) Has been cancelled
CI / ci (macos-latest, stable, bash) (push) Has been cancelled
CI / ci (ubuntu-latest, stable, bash) (push) Has been cancelled
CI / ci (windows-latest, stable-x86_64-pc-windows-gnu, msys2 {0}) (push) Has been cancelled
Doc / deploy (push) Has been cancelled
Some checks failed
Deny / audit (push) Has been cancelled
Doc / build (push) Has been cancelled
CI / fmt (push) Has been cancelled
CI / typo (push) Has been cancelled
CI / ci (macos-latest, stable, bash) (push) Has been cancelled
CI / ci (ubuntu-latest, stable, bash) (push) Has been cancelled
CI / ci (windows-latest, stable-x86_64-pc-windows-gnu, msys2 {0}) (push) Has been cancelled
Doc / deploy (push) Has been cancelled
* 1.83 `cargo clippy --fix` * fix type complexity, add `DbResult` * clippy fix * redb fix * Update consensus/context/src/difficulty.rs Co-authored-by: hinto-janai <hinto.janai@protonmail.com> --------- Co-authored-by: Boog900 <boog900@tutanota.com>
This commit is contained in:
parent
01150ab84c
commit
38541dbfda
56 changed files with 269 additions and 316 deletions
|
@ -279,6 +279,9 @@ rest_pat_in_fully_bound_structs = "deny"
|
||||||
redundant_type_annotations = "deny"
|
redundant_type_annotations = "deny"
|
||||||
infinite_loop = "deny"
|
infinite_loop = "deny"
|
||||||
zero_repeat_side_effects = "deny"
|
zero_repeat_side_effects = "deny"
|
||||||
|
non_zero_suggestions = "deny"
|
||||||
|
manual_is_power_of_two = "deny"
|
||||||
|
used_underscore_items = "deny"
|
||||||
|
|
||||||
# Warm
|
# Warm
|
||||||
cast_possible_truncation = "deny"
|
cast_possible_truncation = "deny"
|
||||||
|
@ -371,6 +374,7 @@ unused_lifetimes = "deny"
|
||||||
unused_macro_rules = "deny"
|
unused_macro_rules = "deny"
|
||||||
ambiguous_glob_imports = "deny"
|
ambiguous_glob_imports = "deny"
|
||||||
unused_unsafe = "deny"
|
unused_unsafe = "deny"
|
||||||
|
rust_2024_compatibility = "deny"
|
||||||
|
|
||||||
# Warm
|
# Warm
|
||||||
let_underscore = { level = "deny", priority = -1 }
|
let_underscore = { level = "deny", priority = -1 }
|
||||||
|
|
|
@ -82,7 +82,7 @@ impl_from_str_benchmark! {
|
||||||
macro_rules! impl_to_string_pretty_benchmark {
|
macro_rules! impl_to_string_pretty_benchmark {
|
||||||
(
|
(
|
||||||
$(
|
$(
|
||||||
$fn_name:ident => $request_constructor:expr,
|
$fn_name:ident => $request_constructor:expr_2021,
|
||||||
)*
|
)*
|
||||||
) => {
|
) => {
|
||||||
$(
|
$(
|
||||||
|
|
|
@ -13,7 +13,7 @@ use std::{
|
||||||
macro_rules! define_init_lazylock_statics {
|
macro_rules! define_init_lazylock_statics {
|
||||||
($(
|
($(
|
||||||
$( #[$attr:meta] )*
|
$( #[$attr:meta] )*
|
||||||
$name:ident: $t:ty = $init_fn:expr;
|
$name:ident: $t:ty = $init_fn:expr_2021;
|
||||||
)*) => {
|
)*) => {
|
||||||
/// Initialize global static `LazyLock` data.
|
/// Initialize global static `LazyLock` data.
|
||||||
pub fn init_lazylock_statics() {
|
pub fn init_lazylock_statics() {
|
||||||
|
|
|
@ -328,8 +328,8 @@ fn next_difficulty(
|
||||||
time_span = 1;
|
time_span = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: do checked operations here and unwrap so we don't silently overflow?
|
// TODO: do `checked_mul` here and unwrap so we don't silently overflow?
|
||||||
(windowed_work * u128::from(hf.block_time().as_secs()) + time_span - 1) / time_span
|
(windowed_work * u128::from(hf.block_time().as_secs())).div_ceil(time_span)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the start and end of the window to calculate difficulty.
|
/// Get the start and end of the window to calculate difficulty.
|
||||||
|
|
|
@ -9,7 +9,7 @@ use clap::Parser;
|
||||||
use tower::{Service, ServiceExt};
|
use tower::{Service, ServiceExt};
|
||||||
|
|
||||||
use cuprate_blockchain::{
|
use cuprate_blockchain::{
|
||||||
config::ConfigBuilder, cuprate_database::RuntimeError, service::BlockchainReadHandle,
|
config::ConfigBuilder, cuprate_database::DbResult, service::BlockchainReadHandle,
|
||||||
};
|
};
|
||||||
use cuprate_types::{
|
use cuprate_types::{
|
||||||
blockchain::{BlockchainReadRequest, BlockchainResponse},
|
blockchain::{BlockchainReadRequest, BlockchainResponse},
|
||||||
|
@ -23,7 +23,7 @@ const BATCH_SIZE: usize = 512;
|
||||||
async fn read_batch(
|
async fn read_batch(
|
||||||
handle: &mut BlockchainReadHandle,
|
handle: &mut BlockchainReadHandle,
|
||||||
height_from: usize,
|
height_from: usize,
|
||||||
) -> Result<Vec<BlockId>, RuntimeError> {
|
) -> DbResult<Vec<BlockId>> {
|
||||||
let mut block_ids = Vec::<BlockId>::with_capacity(BATCH_SIZE);
|
let mut block_ids = Vec::<BlockId>::with_capacity(BATCH_SIZE);
|
||||||
|
|
||||||
for height in height_from..(height_from + BATCH_SIZE) {
|
for height in height_from..(height_from + BATCH_SIZE) {
|
||||||
|
|
|
@ -76,14 +76,14 @@ macro_rules! epee_object {
|
||||||
// All this does is return the second (right) arg if present otherwise the left is returned.
|
// All this does is return the second (right) arg if present otherwise the left is returned.
|
||||||
(
|
(
|
||||||
@internal_try_right_then_left
|
@internal_try_right_then_left
|
||||||
$a:expr, $b:expr
|
$a:expr_2021, $b:expr_2021
|
||||||
) => {
|
) => {
|
||||||
$b
|
$b
|
||||||
};
|
};
|
||||||
|
|
||||||
(
|
(
|
||||||
@internal_try_right_then_left
|
@internal_try_right_then_left
|
||||||
$a:expr,
|
$a:expr_2021,
|
||||||
) => {
|
) => {
|
||||||
$a
|
$a
|
||||||
};
|
};
|
||||||
|
@ -122,7 +122,7 @@ macro_rules! epee_object {
|
||||||
// ------------------------------------------------------------------------ Entry Point
|
// ------------------------------------------------------------------------ Entry Point
|
||||||
(
|
(
|
||||||
$obj:ident,
|
$obj:ident,
|
||||||
$($field: ident $(($alt_name: literal))?: $ty:ty $(as $ty_as:ty )? $(= $default:expr)? $(=> $read_fn:expr, $write_fn:expr, $should_write_fn:expr)?, )*
|
$($field: ident $(($alt_name: literal))?: $ty:ty $(as $ty_as:ty )? $(= $default:expr_2021)? $(=> $read_fn:expr_2021, $write_fn:expr_2021, $should_write_fn:expr_2021)?, )*
|
||||||
$(!flatten: $flat_field: ident: $flat_ty:ty ,)*
|
$(!flatten: $flat_field: ident: $flat_ty:ty ,)*
|
||||||
|
|
||||||
) => {
|
) => {
|
||||||
|
|
|
@ -157,7 +157,7 @@ pub struct BufferSinkSend<'a, T> {
|
||||||
item: Option<T>,
|
item: Option<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Future for BufferSinkSend<'a, T> {
|
impl<T> Future for BufferSinkSend<'_, T> {
|
||||||
type Output = Result<(), BufferError>;
|
type Output = Result<(), BufferError>;
|
||||||
|
|
||||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
|
@ -183,7 +183,7 @@ pub struct BufferSinkReady<'a, T> {
|
||||||
size_needed: usize,
|
size_needed: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Future for BufferSinkReady<'a, T> {
|
impl<T> Future for BufferSinkReady<'_, T> {
|
||||||
type Output = ();
|
type Output = ();
|
||||||
|
|
||||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
|
|
|
@ -12,6 +12,7 @@ use crate::{
|
||||||
OutboundPeer, State,
|
OutboundPeer, State,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[expect(clippy::type_complexity)]
|
||||||
pub(crate) fn mock_discover_svc<Req: Send + 'static>() -> (
|
pub(crate) fn mock_discover_svc<Req: Send + 'static>() -> (
|
||||||
impl Stream<
|
impl Stream<
|
||||||
Item = Result<
|
Item = Result<
|
||||||
|
|
|
@ -121,7 +121,6 @@ pub trait NetZoneAddress:
|
||||||
///
|
///
|
||||||
/// - TODO: IP zone banning?
|
/// - TODO: IP zone banning?
|
||||||
/// - TODO: rename this to Host.
|
/// - TODO: rename this to Host.
|
||||||
|
|
||||||
type BanID: Debug + Hash + Eq + Clone + Copy + Send + 'static;
|
type BanID: Debug + Hash + Eq + Clone + Copy + Send + 'static;
|
||||||
|
|
||||||
/// Changes the port of this address to `port`.
|
/// Changes the port of this address to `port`.
|
||||||
|
|
|
@ -146,9 +146,9 @@ fn deserialize_batch(
|
||||||
|
|
||||||
// Check the height lines up as expected.
|
// Check the height lines up as expected.
|
||||||
// This must happen after the hash check.
|
// This must happen after the hash check.
|
||||||
if !block
|
if block
|
||||||
.number()
|
.number()
|
||||||
.is_some_and(|height| height == expected_height)
|
.is_none_or(|height| height != expected_height)
|
||||||
{
|
{
|
||||||
tracing::warn!(
|
tracing::warn!(
|
||||||
"Invalid chain, expected height: {expected_height}, got height: {:?}",
|
"Invalid chain, expected height: {expected_height}, got height: {:?}",
|
||||||
|
|
|
@ -57,6 +57,7 @@ impl Default for BroadcastConfig {
|
||||||
/// - The [`BroadcastSvc`]
|
/// - The [`BroadcastSvc`]
|
||||||
/// - A function that takes in [`InternalPeerID`]s and produces [`BroadcastMessageStream`]s to give to **outbound** peers.
|
/// - A function that takes in [`InternalPeerID`]s and produces [`BroadcastMessageStream`]s to give to **outbound** peers.
|
||||||
/// - A function that takes in [`InternalPeerID`]s and produces [`BroadcastMessageStream`]s to give to **inbound** peers.
|
/// - A function that takes in [`InternalPeerID`]s and produces [`BroadcastMessageStream`]s to give to **inbound** peers.
|
||||||
|
#[expect(clippy::type_complexity)]
|
||||||
pub(crate) fn init_broadcast_channels<N: NetworkZone>(
|
pub(crate) fn init_broadcast_channels<N: NetworkZone>(
|
||||||
config: BroadcastConfig,
|
config: BroadcastConfig,
|
||||||
) -> (
|
) -> (
|
||||||
|
|
|
@ -327,7 +327,7 @@ impl DecompressedPruningSeed {
|
||||||
///
|
///
|
||||||
/// This function will also error if `block_height` > `blockchain_height`
|
/// This function will also error if `block_height` > `blockchain_height`
|
||||||
///
|
///
|
||||||
pub fn get_next_unpruned_block(
|
pub const fn get_next_unpruned_block(
|
||||||
&self,
|
&self,
|
||||||
block_height: usize,
|
block_height: usize,
|
||||||
blockchain_height: usize,
|
blockchain_height: usize,
|
||||||
|
|
|
@ -68,7 +68,7 @@ macro_rules! generate_endpoints_with_no_input {
|
||||||
/// - [`generate_endpoints_with_input`]
|
/// - [`generate_endpoints_with_input`]
|
||||||
/// - [`generate_endpoints_with_no_input`]
|
/// - [`generate_endpoints_with_no_input`]
|
||||||
macro_rules! generate_endpoints_inner {
|
macro_rules! generate_endpoints_inner {
|
||||||
($variant:ident, $handler:ident, $request:expr) => {
|
($variant:ident, $handler:ident, $request:expr_2021) => {
|
||||||
paste::paste! {
|
paste::paste! {
|
||||||
{
|
{
|
||||||
// Check if restricted.
|
// Check if restricted.
|
||||||
|
|
|
@ -71,7 +71,7 @@ macro_rules! generate_endpoints_with_no_input {
|
||||||
/// - [`generate_endpoints_with_input`]
|
/// - [`generate_endpoints_with_input`]
|
||||||
/// - [`generate_endpoints_with_no_input`]
|
/// - [`generate_endpoints_with_no_input`]
|
||||||
macro_rules! generate_endpoints_inner {
|
macro_rules! generate_endpoints_inner {
|
||||||
($variant:ident, $handler:ident, $request:expr) => {
|
($variant:ident, $handler:ident, $request:expr_2021) => {
|
||||||
paste::paste! {
|
paste::paste! {
|
||||||
{
|
{
|
||||||
// Check if restricted.
|
// Check if restricted.
|
||||||
|
|
|
@ -37,7 +37,7 @@ macro_rules! serde_doc_test {
|
||||||
(
|
(
|
||||||
// `const` string from `cuprate_test_utils::rpc::data`
|
// `const` string from `cuprate_test_utils::rpc::data`
|
||||||
// v
|
// v
|
||||||
$cuprate_test_utils_rpc_const:ident => $expected:expr
|
$cuprate_test_utils_rpc_const:ident => $expected:expr_2021
|
||||||
// ^
|
// ^
|
||||||
// Expected value as an expression
|
// Expected value as an expression
|
||||||
) => {
|
) => {
|
||||||
|
|
|
@ -77,7 +77,7 @@ macro_rules! define_request_and_response {
|
||||||
$( #[$request_field_attr:meta] )* // Field attribute.
|
$( #[$request_field_attr:meta] )* // Field attribute.
|
||||||
$request_field:ident: $request_field_type:ty // field_name: field type
|
$request_field:ident: $request_field_type:ty // field_name: field type
|
||||||
$(as $request_field_type_as:ty)? // (optional) alternative type (de)serialization
|
$(as $request_field_type_as:ty)? // (optional) alternative type (de)serialization
|
||||||
$(= $request_field_type_default:expr, $request_field_type_default_string:literal)?, // (optional) default value
|
$(= $request_field_type_default:expr_2021, $request_field_type_default_string:literal)?, // (optional) default value
|
||||||
)*
|
)*
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ macro_rules! define_request_and_response {
|
||||||
$( #[$response_field_attr:meta] )*
|
$( #[$response_field_attr:meta] )*
|
||||||
$response_field:ident: $response_field_type:ty
|
$response_field:ident: $response_field_type:ty
|
||||||
$(as $response_field_type_as:ty)?
|
$(as $response_field_type_as:ty)?
|
||||||
$(= $response_field_type_default:expr, $response_field_type_default_string:literal)?,
|
$(= $response_field_type_default:expr_2021, $response_field_type_default_string:literal)?,
|
||||||
)*
|
)*
|
||||||
}
|
}
|
||||||
) => { paste::paste! {
|
) => { paste::paste! {
|
||||||
|
@ -229,7 +229,7 @@ macro_rules! define_request {
|
||||||
// field_name: FieldType
|
// field_name: FieldType
|
||||||
$field:ident: $field_type:ty
|
$field:ident: $field_type:ty
|
||||||
$(as $field_as:ty)?
|
$(as $field_as:ty)?
|
||||||
$(= $field_default:expr, $field_default_string:literal)?,
|
$(= $field_default:expr_2021, $field_default_string:literal)?,
|
||||||
// The $field_default is an optional extra token that represents
|
// The $field_default is an optional extra token that represents
|
||||||
// a default value to pass to [`cuprate_epee_encoding::epee_object`],
|
// a default value to pass to [`cuprate_epee_encoding::epee_object`],
|
||||||
// see it for usage.
|
// see it for usage.
|
||||||
|
@ -286,7 +286,7 @@ macro_rules! define_response {
|
||||||
$( #[$field_attr:meta] )*
|
$( #[$field_attr:meta] )*
|
||||||
$field:ident: $field_type:ty
|
$field:ident: $field_type:ty
|
||||||
$(as $field_as:ty)?
|
$(as $field_as:ty)?
|
||||||
$(= $field_default:expr, $field_default_string:literal)?,
|
$(= $field_default:expr_2021, $field_default_string:literal)?,
|
||||||
)*
|
)*
|
||||||
}
|
}
|
||||||
) => {
|
) => {
|
||||||
|
@ -323,7 +323,7 @@ macro_rules! define_response {
|
||||||
$( #[$field_attr:meta] )*
|
$( #[$field_attr:meta] )*
|
||||||
$field:ident: $field_type:ty
|
$field:ident: $field_type:ty
|
||||||
$(as $field_as:ty)?
|
$(as $field_as:ty)?
|
||||||
$(= $field_default:expr, $field_default_string:literal)?,
|
$(= $field_default:expr_2021, $field_default_string:literal)?,
|
||||||
)*
|
)*
|
||||||
}
|
}
|
||||||
) => {
|
) => {
|
||||||
|
|
|
@ -37,7 +37,7 @@ macro_rules! define_struct_and_impl_epee {
|
||||||
$(
|
$(
|
||||||
$( #[$field_attr:meta] )* // Field attributes
|
$( #[$field_attr:meta] )* // Field attributes
|
||||||
// Field name => the type => optional `epee_object` default value.
|
// Field name => the type => optional `epee_object` default value.
|
||||||
$field_name:ident: $field_type:ty $(= $field_default:expr)?,
|
$field_name:ident: $field_type:ty $(= $field_default:expr_2021)?,
|
||||||
)*
|
)*
|
||||||
}
|
}
|
||||||
) => {
|
) => {
|
||||||
|
|
|
@ -65,7 +65,7 @@ macro_rules! serde_doc_test {
|
||||||
(
|
(
|
||||||
// `const` string from `cuprate_test_utils::rpc::data`
|
// `const` string from `cuprate_test_utils::rpc::data`
|
||||||
// v
|
// v
|
||||||
$cuprate_test_utils_rpc_const:ident => $expected:expr
|
$cuprate_test_utils_rpc_const:ident => $expected:expr_2021
|
||||||
// ^
|
// ^
|
||||||
// Expected value as an expression
|
// Expected value as an expression
|
||||||
) => {
|
) => {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use bytemuck::TransparentWrapper;
|
use bytemuck::TransparentWrapper;
|
||||||
use monero_serai::block::{Block, BlockHeader};
|
use monero_serai::block::{Block, BlockHeader};
|
||||||
|
|
||||||
use cuprate_database::{DatabaseRo, DatabaseRw, RuntimeError, StorableVec};
|
use cuprate_database::{DatabaseRo, DatabaseRw, DbResult, StorableVec};
|
||||||
use cuprate_helper::map::{combine_low_high_bits_to_u128, split_u128_into_low_high_bits};
|
use cuprate_helper::map::{combine_low_high_bits_to_u128, split_u128_into_low_high_bits};
|
||||||
use cuprate_types::{AltBlockInformation, Chain, ChainId, ExtendedBlockHeader, HardFork};
|
use cuprate_types::{AltBlockInformation, Chain, ChainId, ExtendedBlockHeader, HardFork};
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ use crate::{
|
||||||
pub fn flush_alt_blocks<'a, E: cuprate_database::EnvInner<'a>>(
|
pub fn flush_alt_blocks<'a, E: cuprate_database::EnvInner<'a>>(
|
||||||
env_inner: &E,
|
env_inner: &E,
|
||||||
tx_rw: &mut E::Rw<'_>,
|
tx_rw: &mut E::Rw<'_>,
|
||||||
) -> Result<(), RuntimeError> {
|
) -> DbResult<()> {
|
||||||
use crate::tables::{
|
use crate::tables::{
|
||||||
AltBlockBlobs, AltBlockHeights, AltBlocksInfo, AltChainInfos, AltTransactionBlobs,
|
AltBlockBlobs, AltBlockHeights, AltBlocksInfo, AltChainInfos, AltTransactionBlobs,
|
||||||
AltTransactionInfos,
|
AltTransactionInfos,
|
||||||
|
@ -47,10 +47,7 @@ pub fn flush_alt_blocks<'a, E: cuprate_database::EnvInner<'a>>(
|
||||||
/// - `alt_block.height` is == `0`
|
/// - `alt_block.height` is == `0`
|
||||||
/// - `alt_block.txs.len()` != `alt_block.block.transactions.len()`
|
/// - `alt_block.txs.len()` != `alt_block.block.transactions.len()`
|
||||||
///
|
///
|
||||||
pub fn add_alt_block(
|
pub fn add_alt_block(alt_block: &AltBlockInformation, tables: &mut impl TablesMut) -> DbResult<()> {
|
||||||
alt_block: &AltBlockInformation,
|
|
||||||
tables: &mut impl TablesMut,
|
|
||||||
) -> Result<(), RuntimeError> {
|
|
||||||
let alt_block_height = AltBlockHeight {
|
let alt_block_height = AltBlockHeight {
|
||||||
chain_id: alt_block.chain_id.into(),
|
chain_id: alt_block.chain_id.into(),
|
||||||
height: alt_block.height,
|
height: alt_block.height,
|
||||||
|
@ -100,7 +97,7 @@ pub fn add_alt_block(
|
||||||
pub fn get_alt_block(
|
pub fn get_alt_block(
|
||||||
alt_block_height: &AltBlockHeight,
|
alt_block_height: &AltBlockHeight,
|
||||||
tables: &impl Tables,
|
tables: &impl Tables,
|
||||||
) -> Result<AltBlockInformation, RuntimeError> {
|
) -> DbResult<AltBlockInformation> {
|
||||||
let block_info = tables.alt_blocks_info().get(alt_block_height)?;
|
let block_info = tables.alt_blocks_info().get(alt_block_height)?;
|
||||||
|
|
||||||
let block_blob = tables.alt_block_blobs().get(alt_block_height)?.0;
|
let block_blob = tables.alt_block_blobs().get(alt_block_height)?.0;
|
||||||
|
@ -111,7 +108,7 @@ pub fn get_alt_block(
|
||||||
.transactions
|
.transactions
|
||||||
.iter()
|
.iter()
|
||||||
.map(|tx_hash| get_alt_transaction(tx_hash, tables))
|
.map(|tx_hash| get_alt_transaction(tx_hash, tables))
|
||||||
.collect::<Result<_, RuntimeError>>()?;
|
.collect::<DbResult<_>>()?;
|
||||||
|
|
||||||
Ok(AltBlockInformation {
|
Ok(AltBlockInformation {
|
||||||
block,
|
block,
|
||||||
|
@ -141,7 +138,7 @@ pub fn get_alt_block_hash(
|
||||||
block_height: &BlockHeight,
|
block_height: &BlockHeight,
|
||||||
alt_chain: ChainId,
|
alt_chain: ChainId,
|
||||||
tables: &impl Tables,
|
tables: &impl Tables,
|
||||||
) -> Result<BlockHash, RuntimeError> {
|
) -> DbResult<BlockHash> {
|
||||||
let alt_chains = tables.alt_chain_infos();
|
let alt_chains = tables.alt_chain_infos();
|
||||||
|
|
||||||
// First find what [`ChainId`] this block would be stored under.
|
// First find what [`ChainId`] this block would be stored under.
|
||||||
|
@ -188,7 +185,7 @@ pub fn get_alt_block_hash(
|
||||||
pub fn get_alt_block_extended_header_from_height(
|
pub fn get_alt_block_extended_header_from_height(
|
||||||
height: &AltBlockHeight,
|
height: &AltBlockHeight,
|
||||||
table: &impl Tables,
|
table: &impl Tables,
|
||||||
) -> Result<ExtendedBlockHeader, RuntimeError> {
|
) -> DbResult<ExtendedBlockHeader> {
|
||||||
let block_info = table.alt_blocks_info().get(height)?;
|
let block_info = table.alt_blocks_info().get(height)?;
|
||||||
|
|
||||||
let block_blob = table.alt_block_blobs().get(height)?.0;
|
let block_blob = table.alt_block_blobs().get(height)?.0;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::cmp::{max, min};
|
use std::cmp::{max, min};
|
||||||
|
|
||||||
use cuprate_database::{DatabaseRo, DatabaseRw, RuntimeError};
|
use cuprate_database::{DatabaseRo, DatabaseRw, DbResult, RuntimeError};
|
||||||
use cuprate_types::{Chain, ChainId};
|
use cuprate_types::{Chain, ChainId};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -21,7 +21,7 @@ pub fn update_alt_chain_info(
|
||||||
alt_block_height: &AltBlockHeight,
|
alt_block_height: &AltBlockHeight,
|
||||||
prev_hash: &BlockHash,
|
prev_hash: &BlockHash,
|
||||||
tables: &mut impl TablesMut,
|
tables: &mut impl TablesMut,
|
||||||
) -> Result<(), RuntimeError> {
|
) -> DbResult<()> {
|
||||||
let parent_chain = match tables.alt_block_heights().get(prev_hash) {
|
let parent_chain = match tables.alt_block_heights().get(prev_hash) {
|
||||||
Ok(alt_parent_height) => Chain::Alt(alt_parent_height.chain_id.into()),
|
Ok(alt_parent_height) => Chain::Alt(alt_parent_height.chain_id.into()),
|
||||||
Err(RuntimeError::KeyNotFound) => Chain::Main,
|
Err(RuntimeError::KeyNotFound) => Chain::Main,
|
||||||
|
@ -74,7 +74,7 @@ pub fn get_alt_chain_history_ranges(
|
||||||
range: std::ops::Range<BlockHeight>,
|
range: std::ops::Range<BlockHeight>,
|
||||||
alt_chain: ChainId,
|
alt_chain: ChainId,
|
||||||
alt_chain_infos: &impl DatabaseRo<AltChainInfos>,
|
alt_chain_infos: &impl DatabaseRo<AltChainInfos>,
|
||||||
) -> Result<Vec<(Chain, std::ops::Range<BlockHeight>)>, RuntimeError> {
|
) -> DbResult<Vec<(Chain, std::ops::Range<BlockHeight>)>> {
|
||||||
let mut ranges = Vec::with_capacity(5);
|
let mut ranges = Vec::with_capacity(5);
|
||||||
|
|
||||||
let mut i = range.end;
|
let mut i = range.end;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use bytemuck::TransparentWrapper;
|
use bytemuck::TransparentWrapper;
|
||||||
use monero_serai::transaction::Transaction;
|
use monero_serai::transaction::Transaction;
|
||||||
|
|
||||||
use cuprate_database::{DatabaseRo, DatabaseRw, RuntimeError, StorableVec};
|
use cuprate_database::{DatabaseRo, DatabaseRw, DbResult, RuntimeError, StorableVec};
|
||||||
use cuprate_types::VerifiedTransactionInformation;
|
use cuprate_types::VerifiedTransactionInformation;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -22,7 +22,7 @@ use crate::{
|
||||||
pub fn add_alt_transaction_blob(
|
pub fn add_alt_transaction_blob(
|
||||||
tx: &VerifiedTransactionInformation,
|
tx: &VerifiedTransactionInformation,
|
||||||
tables: &mut impl TablesMut,
|
tables: &mut impl TablesMut,
|
||||||
) -> Result<(), RuntimeError> {
|
) -> DbResult<()> {
|
||||||
tables.alt_transaction_infos_mut().put(
|
tables.alt_transaction_infos_mut().put(
|
||||||
&tx.tx_hash,
|
&tx.tx_hash,
|
||||||
&AltTransactionInfo {
|
&AltTransactionInfo {
|
||||||
|
@ -51,7 +51,7 @@ pub fn add_alt_transaction_blob(
|
||||||
pub fn get_alt_transaction(
|
pub fn get_alt_transaction(
|
||||||
tx_hash: &TxHash,
|
tx_hash: &TxHash,
|
||||||
tables: &impl Tables,
|
tables: &impl Tables,
|
||||||
) -> Result<VerifiedTransactionInformation, RuntimeError> {
|
) -> DbResult<VerifiedTransactionInformation> {
|
||||||
let tx_info = tables.alt_transaction_infos().get(tx_hash)?;
|
let tx_info = tables.alt_transaction_infos().get(tx_hash)?;
|
||||||
|
|
||||||
let tx_blob = match tables.alt_transaction_blobs().get(tx_hash) {
|
let tx_blob = match tables.alt_transaction_blobs().get(tx_hash) {
|
||||||
|
|
|
@ -8,7 +8,7 @@ use monero_serai::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use cuprate_database::{
|
use cuprate_database::{
|
||||||
RuntimeError, StorableVec, {DatabaseRo, DatabaseRw},
|
DbResult, RuntimeError, StorableVec, {DatabaseRo, DatabaseRw},
|
||||||
};
|
};
|
||||||
use cuprate_helper::{
|
use cuprate_helper::{
|
||||||
map::{combine_low_high_bits_to_u128, split_u128_into_low_high_bits},
|
map::{combine_low_high_bits_to_u128, split_u128_into_low_high_bits},
|
||||||
|
@ -44,10 +44,7 @@ use crate::{
|
||||||
/// - `block.height > u32::MAX` (not normally possible)
|
/// - `block.height > u32::MAX` (not normally possible)
|
||||||
/// - `block.height` is != [`chain_height`]
|
/// - `block.height` is != [`chain_height`]
|
||||||
// no inline, too big.
|
// no inline, too big.
|
||||||
pub fn add_block(
|
pub fn add_block(block: &VerifiedBlockInformation, tables: &mut impl TablesMut) -> DbResult<()> {
|
||||||
block: &VerifiedBlockInformation,
|
|
||||||
tables: &mut impl TablesMut,
|
|
||||||
) -> Result<(), RuntimeError> {
|
|
||||||
//------------------------------------------------------ Check preconditions first
|
//------------------------------------------------------ Check preconditions first
|
||||||
|
|
||||||
// Cast height to `u32` for storage (handled at top of function).
|
// Cast height to `u32` for storage (handled at top of function).
|
||||||
|
@ -153,7 +150,7 @@ pub fn add_block(
|
||||||
pub fn pop_block(
|
pub fn pop_block(
|
||||||
move_to_alt_chain: Option<ChainId>,
|
move_to_alt_chain: Option<ChainId>,
|
||||||
tables: &mut impl TablesMut,
|
tables: &mut impl TablesMut,
|
||||||
) -> Result<(BlockHeight, BlockHash, Block), RuntimeError> {
|
) -> DbResult<(BlockHeight, BlockHash, Block)> {
|
||||||
//------------------------------------------------------ Block Info
|
//------------------------------------------------------ Block Info
|
||||||
// Remove block data from tables.
|
// Remove block data from tables.
|
||||||
let (block_height, block_info) = tables.block_infos_mut().pop_last()?;
|
let (block_height, block_info) = tables.block_infos_mut().pop_last()?;
|
||||||
|
@ -195,7 +192,7 @@ pub fn pop_block(
|
||||||
tx,
|
tx,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<VerifiedTransactionInformation>, RuntimeError>>()?;
|
.collect::<DbResult<Vec<VerifiedTransactionInformation>>>()?;
|
||||||
|
|
||||||
alt_block::add_alt_block(
|
alt_block::add_alt_block(
|
||||||
&AltBlockInformation {
|
&AltBlockInformation {
|
||||||
|
@ -239,7 +236,7 @@ pub fn pop_block(
|
||||||
pub fn get_block_extended_header(
|
pub fn get_block_extended_header(
|
||||||
block_hash: &BlockHash,
|
block_hash: &BlockHash,
|
||||||
tables: &impl Tables,
|
tables: &impl Tables,
|
||||||
) -> Result<ExtendedBlockHeader, RuntimeError> {
|
) -> DbResult<ExtendedBlockHeader> {
|
||||||
get_block_extended_header_from_height(&tables.block_heights().get(block_hash)?, tables)
|
get_block_extended_header_from_height(&tables.block_heights().get(block_hash)?, tables)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,7 +250,7 @@ pub fn get_block_extended_header(
|
||||||
pub fn get_block_extended_header_from_height(
|
pub fn get_block_extended_header_from_height(
|
||||||
block_height: &BlockHeight,
|
block_height: &BlockHeight,
|
||||||
tables: &impl Tables,
|
tables: &impl Tables,
|
||||||
) -> Result<ExtendedBlockHeader, RuntimeError> {
|
) -> DbResult<ExtendedBlockHeader> {
|
||||||
let block_info = tables.block_infos().get(block_height)?;
|
let block_info = tables.block_infos().get(block_height)?;
|
||||||
let block_header_blob = tables.block_header_blobs().get(block_height)?.0;
|
let block_header_blob = tables.block_header_blobs().get(block_height)?.0;
|
||||||
let block_header = BlockHeader::read(&mut block_header_blob.as_slice())?;
|
let block_header = BlockHeader::read(&mut block_header_blob.as_slice())?;
|
||||||
|
@ -279,7 +276,7 @@ pub fn get_block_extended_header_from_height(
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_block_extended_header_top(
|
pub fn get_block_extended_header_top(
|
||||||
tables: &impl Tables,
|
tables: &impl Tables,
|
||||||
) -> Result<(ExtendedBlockHeader, BlockHeight), RuntimeError> {
|
) -> DbResult<(ExtendedBlockHeader, BlockHeight)> {
|
||||||
let height = chain_height(tables.block_heights())?.saturating_sub(1);
|
let height = chain_height(tables.block_heights())?.saturating_sub(1);
|
||||||
let header = get_block_extended_header_from_height(&height, tables)?;
|
let header = get_block_extended_header_from_height(&height, tables)?;
|
||||||
Ok((header, height))
|
Ok((header, height))
|
||||||
|
@ -292,7 +289,7 @@ pub fn get_block_extended_header_top(
|
||||||
pub fn get_block_info(
|
pub fn get_block_info(
|
||||||
block_height: &BlockHeight,
|
block_height: &BlockHeight,
|
||||||
table_block_infos: &impl DatabaseRo<BlockInfos>,
|
table_block_infos: &impl DatabaseRo<BlockInfos>,
|
||||||
) -> Result<BlockInfo, RuntimeError> {
|
) -> DbResult<BlockInfo> {
|
||||||
table_block_infos.get(block_height)
|
table_block_infos.get(block_height)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,7 +299,7 @@ pub fn get_block_info(
|
||||||
pub fn get_block_height(
|
pub fn get_block_height(
|
||||||
block_hash: &BlockHash,
|
block_hash: &BlockHash,
|
||||||
table_block_heights: &impl DatabaseRo<BlockHeights>,
|
table_block_heights: &impl DatabaseRo<BlockHeights>,
|
||||||
) -> Result<BlockHeight, RuntimeError> {
|
) -> DbResult<BlockHeight> {
|
||||||
table_block_heights.get(block_hash)
|
table_block_heights.get(block_hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,7 +314,7 @@ pub fn get_block_height(
|
||||||
pub fn block_exists(
|
pub fn block_exists(
|
||||||
block_hash: &BlockHash,
|
block_hash: &BlockHash,
|
||||||
table_block_heights: &impl DatabaseRo<BlockHeights>,
|
table_block_heights: &impl DatabaseRo<BlockHeights>,
|
||||||
) -> Result<bool, RuntimeError> {
|
) -> DbResult<bool> {
|
||||||
table_block_heights.contains(block_hash)
|
table_block_heights.contains(block_hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//! Blockchain functions - chain height, generated coins, etc.
|
//! Blockchain functions - chain height, generated coins, etc.
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Import
|
//---------------------------------------------------------------------------------------------------- Import
|
||||||
use cuprate_database::{DatabaseRo, RuntimeError};
|
use cuprate_database::{DatabaseRo, DbResult, RuntimeError};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ops::macros::doc_error,
|
ops::macros::doc_error,
|
||||||
|
@ -22,9 +22,7 @@ use crate::{
|
||||||
/// So the height of a new block would be `chain_height()`.
|
/// So the height of a new block would be `chain_height()`.
|
||||||
#[doc = doc_error!()]
|
#[doc = doc_error!()]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn chain_height(
|
pub fn chain_height(table_block_heights: &impl DatabaseRo<BlockHeights>) -> DbResult<BlockHeight> {
|
||||||
table_block_heights: &impl DatabaseRo<BlockHeights>,
|
|
||||||
) -> Result<BlockHeight, RuntimeError> {
|
|
||||||
#[expect(clippy::cast_possible_truncation, reason = "we enforce 64-bit")]
|
#[expect(clippy::cast_possible_truncation, reason = "we enforce 64-bit")]
|
||||||
table_block_heights.len().map(|height| height as usize)
|
table_block_heights.len().map(|height| height as usize)
|
||||||
}
|
}
|
||||||
|
@ -45,7 +43,7 @@ pub fn chain_height(
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn top_block_height(
|
pub fn top_block_height(
|
||||||
table_block_heights: &impl DatabaseRo<BlockHeights>,
|
table_block_heights: &impl DatabaseRo<BlockHeights>,
|
||||||
) -> Result<BlockHeight, RuntimeError> {
|
) -> DbResult<BlockHeight> {
|
||||||
match table_block_heights.len()? {
|
match table_block_heights.len()? {
|
||||||
0 => Err(RuntimeError::KeyNotFound),
|
0 => Err(RuntimeError::KeyNotFound),
|
||||||
#[expect(clippy::cast_possible_truncation, reason = "we enforce 64-bit")]
|
#[expect(clippy::cast_possible_truncation, reason = "we enforce 64-bit")]
|
||||||
|
@ -70,7 +68,7 @@ pub fn top_block_height(
|
||||||
pub fn cumulative_generated_coins(
|
pub fn cumulative_generated_coins(
|
||||||
block_height: &BlockHeight,
|
block_height: &BlockHeight,
|
||||||
table_block_infos: &impl DatabaseRo<BlockInfos>,
|
table_block_infos: &impl DatabaseRo<BlockInfos>,
|
||||||
) -> Result<u64, RuntimeError> {
|
) -> DbResult<u64> {
|
||||||
match table_block_infos.get(block_height) {
|
match table_block_infos.get(block_height) {
|
||||||
Ok(block_info) => Ok(block_info.cumulative_generated_coins),
|
Ok(block_info) => Ok(block_info.cumulative_generated_coins),
|
||||||
Err(RuntimeError::KeyNotFound) if block_height == &0 => Ok(0),
|
Err(RuntimeError::KeyNotFound) if block_height == &0 => Ok(0),
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//! Key image functions.
|
//! Key image functions.
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Import
|
//---------------------------------------------------------------------------------------------------- Import
|
||||||
use cuprate_database::{DatabaseRo, DatabaseRw, RuntimeError};
|
use cuprate_database::{DatabaseRo, DatabaseRw, DbResult};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ops::macros::{doc_add_block_inner_invariant, doc_error},
|
ops::macros::{doc_add_block_inner_invariant, doc_error},
|
||||||
|
@ -17,7 +17,7 @@ use crate::{
|
||||||
pub fn add_key_image(
|
pub fn add_key_image(
|
||||||
key_image: &KeyImage,
|
key_image: &KeyImage,
|
||||||
table_key_images: &mut impl DatabaseRw<KeyImages>,
|
table_key_images: &mut impl DatabaseRw<KeyImages>,
|
||||||
) -> Result<(), RuntimeError> {
|
) -> DbResult<()> {
|
||||||
table_key_images.put(key_image, &())
|
table_key_images.put(key_image, &())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ pub fn add_key_image(
|
||||||
pub fn remove_key_image(
|
pub fn remove_key_image(
|
||||||
key_image: &KeyImage,
|
key_image: &KeyImage,
|
||||||
table_key_images: &mut impl DatabaseRw<KeyImages>,
|
table_key_images: &mut impl DatabaseRw<KeyImages>,
|
||||||
) -> Result<(), RuntimeError> {
|
) -> DbResult<()> {
|
||||||
table_key_images.delete(key_image)
|
table_key_images.delete(key_image)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ pub fn remove_key_image(
|
||||||
pub fn key_image_exists(
|
pub fn key_image_exists(
|
||||||
key_image: &KeyImage,
|
key_image: &KeyImage,
|
||||||
table_key_images: &impl DatabaseRo<KeyImages>,
|
table_key_images: &impl DatabaseRo<KeyImages>,
|
||||||
) -> Result<bool, RuntimeError> {
|
) -> DbResult<bool> {
|
||||||
table_key_images.contains(key_image)
|
table_key_images.contains(key_image)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
macro_rules! doc_error {
|
macro_rules! doc_error {
|
||||||
() => {
|
() => {
|
||||||
r#"# Errors
|
r#"# Errors
|
||||||
This function returns [`RuntimeError::KeyNotFound`] if the input (if applicable) doesn't exist or other `RuntimeError`'s on database errors."#
|
This function returns [`cuprate_database::RuntimeError::KeyNotFound`] if the input (if applicable) doesn't exist or other `RuntimeError`'s on database errors."#
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
pub(super) use doc_error;
|
pub(super) use doc_error;
|
||||||
|
|
|
@ -5,7 +5,7 @@ use curve25519_dalek::edwards::CompressedEdwardsY;
|
||||||
use monero_serai::transaction::Timelock;
|
use monero_serai::transaction::Timelock;
|
||||||
|
|
||||||
use cuprate_database::{
|
use cuprate_database::{
|
||||||
RuntimeError, {DatabaseRo, DatabaseRw},
|
DbResult, RuntimeError, {DatabaseRo, DatabaseRw},
|
||||||
};
|
};
|
||||||
use cuprate_helper::crypto::compute_zero_commitment;
|
use cuprate_helper::crypto::compute_zero_commitment;
|
||||||
use cuprate_helper::map::u64_to_timelock;
|
use cuprate_helper::map::u64_to_timelock;
|
||||||
|
@ -30,7 +30,7 @@ pub fn add_output(
|
||||||
amount: Amount,
|
amount: Amount,
|
||||||
output: &Output,
|
output: &Output,
|
||||||
tables: &mut impl TablesMut,
|
tables: &mut impl TablesMut,
|
||||||
) -> Result<PreRctOutputId, RuntimeError> {
|
) -> DbResult<PreRctOutputId> {
|
||||||
// FIXME: this would be much better expressed with a
|
// FIXME: this would be much better expressed with a
|
||||||
// `btree_map::Entry`-like API, fix `trait DatabaseRw`.
|
// `btree_map::Entry`-like API, fix `trait DatabaseRw`.
|
||||||
let num_outputs = match tables.num_outputs().get(&amount) {
|
let num_outputs = match tables.num_outputs().get(&amount) {
|
||||||
|
@ -61,7 +61,7 @@ pub fn add_output(
|
||||||
pub fn remove_output(
|
pub fn remove_output(
|
||||||
pre_rct_output_id: &PreRctOutputId,
|
pre_rct_output_id: &PreRctOutputId,
|
||||||
tables: &mut impl TablesMut,
|
tables: &mut impl TablesMut,
|
||||||
) -> Result<(), RuntimeError> {
|
) -> DbResult<()> {
|
||||||
// Decrement the amount index by 1, or delete the entry out-right.
|
// Decrement the amount index by 1, or delete the entry out-right.
|
||||||
// FIXME: this would be much better expressed with a
|
// FIXME: this would be much better expressed with a
|
||||||
// `btree_map::Entry`-like API, fix `trait DatabaseRw`.
|
// `btree_map::Entry`-like API, fix `trait DatabaseRw`.
|
||||||
|
@ -86,7 +86,7 @@ pub fn remove_output(
|
||||||
pub fn get_output(
|
pub fn get_output(
|
||||||
pre_rct_output_id: &PreRctOutputId,
|
pre_rct_output_id: &PreRctOutputId,
|
||||||
table_outputs: &impl DatabaseRo<Outputs>,
|
table_outputs: &impl DatabaseRo<Outputs>,
|
||||||
) -> Result<Output, RuntimeError> {
|
) -> DbResult<Output> {
|
||||||
table_outputs.get(pre_rct_output_id)
|
table_outputs.get(pre_rct_output_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ pub fn get_output(
|
||||||
/// This returns the amount of pre-RCT outputs currently stored.
|
/// This returns the amount of pre-RCT outputs currently stored.
|
||||||
#[doc = doc_error!()]
|
#[doc = doc_error!()]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_num_outputs(table_outputs: &impl DatabaseRo<Outputs>) -> Result<u64, RuntimeError> {
|
pub fn get_num_outputs(table_outputs: &impl DatabaseRo<Outputs>) -> DbResult<u64> {
|
||||||
table_outputs.len()
|
table_outputs.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ pub fn get_num_outputs(table_outputs: &impl DatabaseRo<Outputs>) -> Result<u64,
|
||||||
pub fn add_rct_output(
|
pub fn add_rct_output(
|
||||||
rct_output: &RctOutput,
|
rct_output: &RctOutput,
|
||||||
table_rct_outputs: &mut impl DatabaseRw<RctOutputs>,
|
table_rct_outputs: &mut impl DatabaseRw<RctOutputs>,
|
||||||
) -> Result<AmountIndex, RuntimeError> {
|
) -> DbResult<AmountIndex> {
|
||||||
let amount_index = get_rct_num_outputs(table_rct_outputs)?;
|
let amount_index = get_rct_num_outputs(table_rct_outputs)?;
|
||||||
table_rct_outputs.put(&amount_index, rct_output)?;
|
table_rct_outputs.put(&amount_index, rct_output)?;
|
||||||
Ok(amount_index)
|
Ok(amount_index)
|
||||||
|
@ -123,7 +123,7 @@ pub fn add_rct_output(
|
||||||
pub fn remove_rct_output(
|
pub fn remove_rct_output(
|
||||||
amount_index: &AmountIndex,
|
amount_index: &AmountIndex,
|
||||||
table_rct_outputs: &mut impl DatabaseRw<RctOutputs>,
|
table_rct_outputs: &mut impl DatabaseRw<RctOutputs>,
|
||||||
) -> Result<(), RuntimeError> {
|
) -> DbResult<()> {
|
||||||
table_rct_outputs.delete(amount_index)
|
table_rct_outputs.delete(amount_index)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@ pub fn remove_rct_output(
|
||||||
pub fn get_rct_output(
|
pub fn get_rct_output(
|
||||||
amount_index: &AmountIndex,
|
amount_index: &AmountIndex,
|
||||||
table_rct_outputs: &impl DatabaseRo<RctOutputs>,
|
table_rct_outputs: &impl DatabaseRo<RctOutputs>,
|
||||||
) -> Result<RctOutput, RuntimeError> {
|
) -> DbResult<RctOutput> {
|
||||||
table_rct_outputs.get(amount_index)
|
table_rct_outputs.get(amount_index)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,9 +142,7 @@ pub fn get_rct_output(
|
||||||
/// This returns the amount of RCT outputs currently stored.
|
/// This returns the amount of RCT outputs currently stored.
|
||||||
#[doc = doc_error!()]
|
#[doc = doc_error!()]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_rct_num_outputs(
|
pub fn get_rct_num_outputs(table_rct_outputs: &impl DatabaseRo<RctOutputs>) -> DbResult<u64> {
|
||||||
table_rct_outputs: &impl DatabaseRo<RctOutputs>,
|
|
||||||
) -> Result<u64, RuntimeError> {
|
|
||||||
table_rct_outputs.len()
|
table_rct_outputs.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,7 +153,7 @@ pub fn output_to_output_on_chain(
|
||||||
output: &Output,
|
output: &Output,
|
||||||
amount: Amount,
|
amount: Amount,
|
||||||
table_tx_unlock_time: &impl DatabaseRo<TxUnlockTime>,
|
table_tx_unlock_time: &impl DatabaseRo<TxUnlockTime>,
|
||||||
) -> Result<OutputOnChain, RuntimeError> {
|
) -> DbResult<OutputOnChain> {
|
||||||
let commitment = compute_zero_commitment(amount);
|
let commitment = compute_zero_commitment(amount);
|
||||||
|
|
||||||
let time_lock = if output
|
let time_lock = if output
|
||||||
|
@ -191,7 +189,7 @@ pub fn output_to_output_on_chain(
|
||||||
pub fn rct_output_to_output_on_chain(
|
pub fn rct_output_to_output_on_chain(
|
||||||
rct_output: &RctOutput,
|
rct_output: &RctOutput,
|
||||||
table_tx_unlock_time: &impl DatabaseRo<TxUnlockTime>,
|
table_tx_unlock_time: &impl DatabaseRo<TxUnlockTime>,
|
||||||
) -> Result<OutputOnChain, RuntimeError> {
|
) -> DbResult<OutputOnChain> {
|
||||||
// INVARIANT: Commitments stored are valid when stored by the database.
|
// INVARIANT: Commitments stored are valid when stored by the database.
|
||||||
let commitment = CompressedEdwardsY::from_slice(&rct_output.commitment)
|
let commitment = CompressedEdwardsY::from_slice(&rct_output.commitment)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
@ -223,10 +221,7 @@ pub fn rct_output_to_output_on_chain(
|
||||||
///
|
///
|
||||||
/// Note that this still support RCT outputs, in that case, [`PreRctOutputId::amount`] should be `0`.
|
/// Note that this still support RCT outputs, in that case, [`PreRctOutputId::amount`] should be `0`.
|
||||||
#[doc = doc_error!()]
|
#[doc = doc_error!()]
|
||||||
pub fn id_to_output_on_chain(
|
pub fn id_to_output_on_chain(id: &PreRctOutputId, tables: &impl Tables) -> DbResult<OutputOnChain> {
|
||||||
id: &PreRctOutputId,
|
|
||||||
tables: &impl Tables,
|
|
||||||
) -> Result<OutputOnChain, RuntimeError> {
|
|
||||||
// v2 transactions.
|
// v2 transactions.
|
||||||
if id.amount == 0 {
|
if id.amount == 0 {
|
||||||
let rct_output = get_rct_output(&id.amount_index, tables.rct_outputs())?;
|
let rct_output = get_rct_output(&id.amount_index, tables.rct_outputs())?;
|
||||||
|
|
|
@ -3,10 +3,9 @@
|
||||||
//! SOMEDAY: the database `properties` table is not yet implemented.
|
//! SOMEDAY: the database `properties` table is not yet implemented.
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Import
|
//---------------------------------------------------------------------------------------------------- Import
|
||||||
|
use cuprate_database::DbResult;
|
||||||
use cuprate_pruning::PruningSeed;
|
use cuprate_pruning::PruningSeed;
|
||||||
|
|
||||||
use cuprate_database::RuntimeError;
|
|
||||||
|
|
||||||
use crate::ops::macros::doc_error;
|
use crate::ops::macros::doc_error;
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Free Functions
|
//---------------------------------------------------------------------------------------------------- Free Functions
|
||||||
|
@ -20,7 +19,7 @@ use crate::ops::macros::doc_error;
|
||||||
/// // SOMEDAY
|
/// // SOMEDAY
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn get_blockchain_pruning_seed() -> Result<PruningSeed, RuntimeError> {
|
pub const fn get_blockchain_pruning_seed() -> DbResult<PruningSeed> {
|
||||||
// SOMEDAY: impl pruning.
|
// SOMEDAY: impl pruning.
|
||||||
// We need a DB properties table.
|
// We need a DB properties table.
|
||||||
Ok(PruningSeed::NotPruned)
|
Ok(PruningSeed::NotPruned)
|
||||||
|
@ -36,7 +35,7 @@ pub const fn get_blockchain_pruning_seed() -> Result<PruningSeed, RuntimeError>
|
||||||
/// // SOMEDAY
|
/// // SOMEDAY
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn db_version() -> Result<u64, RuntimeError> {
|
pub const fn db_version() -> DbResult<u64> {
|
||||||
// SOMEDAY: We need a DB properties table.
|
// SOMEDAY: We need a DB properties table.
|
||||||
Ok(crate::constants::DATABASE_VERSION)
|
Ok(crate::constants::DATABASE_VERSION)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
use bytemuck::TransparentWrapper;
|
use bytemuck::TransparentWrapper;
|
||||||
use monero_serai::transaction::{Input, Timelock, Transaction};
|
use monero_serai::transaction::{Input, Timelock, Transaction};
|
||||||
|
|
||||||
use cuprate_database::{DatabaseRo, DatabaseRw, RuntimeError, StorableVec};
|
use cuprate_database::{DatabaseRo, DatabaseRw, DbResult, RuntimeError, StorableVec};
|
||||||
use cuprate_helper::crypto::compute_zero_commitment;
|
use cuprate_helper::crypto::compute_zero_commitment;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -52,7 +52,7 @@ pub fn add_tx(
|
||||||
tx_hash: &TxHash,
|
tx_hash: &TxHash,
|
||||||
block_height: &BlockHeight,
|
block_height: &BlockHeight,
|
||||||
tables: &mut impl TablesMut,
|
tables: &mut impl TablesMut,
|
||||||
) -> Result<TxId, RuntimeError> {
|
) -> DbResult<TxId> {
|
||||||
let tx_id = get_num_tx(tables.tx_ids_mut())?;
|
let tx_id = get_num_tx(tables.tx_ids_mut())?;
|
||||||
|
|
||||||
//------------------------------------------------------ Transaction data
|
//------------------------------------------------------ Transaction data
|
||||||
|
@ -129,7 +129,7 @@ pub fn add_tx(
|
||||||
)?
|
)?
|
||||||
.amount_index)
|
.amount_index)
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<_>, RuntimeError>>()?,
|
.collect::<DbResult<Vec<_>>>()?,
|
||||||
Transaction::V2 { prefix, proofs } => prefix
|
Transaction::V2 { prefix, proofs } => prefix
|
||||||
.outputs
|
.outputs
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -186,10 +186,7 @@ pub fn add_tx(
|
||||||
///
|
///
|
||||||
#[doc = doc_error!()]
|
#[doc = doc_error!()]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn remove_tx(
|
pub fn remove_tx(tx_hash: &TxHash, tables: &mut impl TablesMut) -> DbResult<(TxId, Transaction)> {
|
||||||
tx_hash: &TxHash,
|
|
||||||
tables: &mut impl TablesMut,
|
|
||||||
) -> Result<(TxId, Transaction), RuntimeError> {
|
|
||||||
//------------------------------------------------------ Transaction data
|
//------------------------------------------------------ Transaction data
|
||||||
let tx_id = tables.tx_ids_mut().take(tx_hash)?;
|
let tx_id = tables.tx_ids_mut().take(tx_hash)?;
|
||||||
let tx_blob = tables.tx_blobs_mut().take(&tx_id)?;
|
let tx_blob = tables.tx_blobs_mut().take(&tx_id)?;
|
||||||
|
@ -267,7 +264,7 @@ pub fn get_tx(
|
||||||
tx_hash: &TxHash,
|
tx_hash: &TxHash,
|
||||||
table_tx_ids: &impl DatabaseRo<TxIds>,
|
table_tx_ids: &impl DatabaseRo<TxIds>,
|
||||||
table_tx_blobs: &impl DatabaseRo<TxBlobs>,
|
table_tx_blobs: &impl DatabaseRo<TxBlobs>,
|
||||||
) -> Result<Transaction, RuntimeError> {
|
) -> DbResult<Transaction> {
|
||||||
get_tx_from_id(&table_tx_ids.get(tx_hash)?, table_tx_blobs)
|
get_tx_from_id(&table_tx_ids.get(tx_hash)?, table_tx_blobs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,7 +274,7 @@ pub fn get_tx(
|
||||||
pub fn get_tx_from_id(
|
pub fn get_tx_from_id(
|
||||||
tx_id: &TxId,
|
tx_id: &TxId,
|
||||||
table_tx_blobs: &impl DatabaseRo<TxBlobs>,
|
table_tx_blobs: &impl DatabaseRo<TxBlobs>,
|
||||||
) -> Result<Transaction, RuntimeError> {
|
) -> DbResult<Transaction> {
|
||||||
let tx_blob = table_tx_blobs.get(tx_id)?.0;
|
let tx_blob = table_tx_blobs.get(tx_id)?.0;
|
||||||
Ok(Transaction::read(&mut tx_blob.as_slice())?)
|
Ok(Transaction::read(&mut tx_blob.as_slice())?)
|
||||||
}
|
}
|
||||||
|
@ -294,7 +291,7 @@ pub fn get_tx_from_id(
|
||||||
/// - etc
|
/// - etc
|
||||||
#[doc = doc_error!()]
|
#[doc = doc_error!()]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_num_tx(table_tx_ids: &impl DatabaseRo<TxIds>) -> Result<u64, RuntimeError> {
|
pub fn get_num_tx(table_tx_ids: &impl DatabaseRo<TxIds>) -> DbResult<u64> {
|
||||||
table_tx_ids.len()
|
table_tx_ids.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,10 +301,7 @@ pub fn get_num_tx(table_tx_ids: &impl DatabaseRo<TxIds>) -> Result<u64, RuntimeE
|
||||||
/// Returns `true` if it does, else `false`.
|
/// Returns `true` if it does, else `false`.
|
||||||
#[doc = doc_error!()]
|
#[doc = doc_error!()]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn tx_exists(
|
pub fn tx_exists(tx_hash: &TxHash, table_tx_ids: &impl DatabaseRo<TxIds>) -> DbResult<bool> {
|
||||||
tx_hash: &TxHash,
|
|
||||||
table_tx_ids: &impl DatabaseRo<TxIds>,
|
|
||||||
) -> Result<bool, RuntimeError> {
|
|
||||||
table_tx_ids.contains(tx_hash)
|
table_tx_ids.contains(tx_hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ use rayon::{
|
||||||
};
|
};
|
||||||
use thread_local::ThreadLocal;
|
use thread_local::ThreadLocal;
|
||||||
|
|
||||||
use cuprate_database::{ConcreteEnv, DatabaseRo, Env, EnvInner, RuntimeError};
|
use cuprate_database::{ConcreteEnv, DatabaseRo, DbResult, Env, EnvInner, RuntimeError};
|
||||||
use cuprate_database_service::{init_thread_pool, DatabaseReadService, ReaderThreads};
|
use cuprate_database_service::{init_thread_pool, DatabaseReadService, ReaderThreads};
|
||||||
use cuprate_helper::map::combine_low_high_bits_to_u128;
|
use cuprate_helper::map::combine_low_high_bits_to_u128;
|
||||||
use cuprate_types::{
|
use cuprate_types::{
|
||||||
|
@ -305,7 +305,7 @@ fn block_extended_header_in_range(
|
||||||
let tables = get_tables!(env_inner, tx_ro, tables)?.as_ref();
|
let tables = get_tables!(env_inner, tx_ro, tables)?.as_ref();
|
||||||
get_block_extended_header_from_height(&block_height, tables)
|
get_block_extended_header_from_height(&block_height, tables)
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<ExtendedBlockHeader>, RuntimeError>>()?,
|
.collect::<DbResult<Vec<ExtendedBlockHeader>>>()?,
|
||||||
Chain::Alt(chain_id) => {
|
Chain::Alt(chain_id) => {
|
||||||
let ranges = {
|
let ranges = {
|
||||||
let tx_ro = tx_ro.get_or_try(|| env_inner.tx_ro())?;
|
let tx_ro = tx_ro.get_or_try(|| env_inner.tx_ro())?;
|
||||||
|
@ -381,7 +381,7 @@ fn outputs(env: &ConcreteEnv, outputs: HashMap<Amount, HashSet<AmountIndex>>) ->
|
||||||
|
|
||||||
// The 2nd mapping function.
|
// The 2nd mapping function.
|
||||||
// This is pulled out from the below `map()` for readability.
|
// This is pulled out from the below `map()` for readability.
|
||||||
let inner_map = |amount, amount_index| -> Result<(AmountIndex, OutputOnChain), RuntimeError> {
|
let inner_map = |amount, amount_index| -> DbResult<(AmountIndex, OutputOnChain)> {
|
||||||
let tx_ro = tx_ro.get_or_try(|| env_inner.tx_ro())?;
|
let tx_ro = tx_ro.get_or_try(|| env_inner.tx_ro())?;
|
||||||
let tables = get_tables!(env_inner, tx_ro, tables)?.as_ref();
|
let tables = get_tables!(env_inner, tx_ro, tables)?.as_ref();
|
||||||
|
|
||||||
|
@ -404,10 +404,10 @@ fn outputs(env: &ConcreteEnv, outputs: HashMap<Amount, HashSet<AmountIndex>>) ->
|
||||||
amount_index_set
|
amount_index_set
|
||||||
.into_par_iter()
|
.into_par_iter()
|
||||||
.map(|amount_index| inner_map(amount, amount_index))
|
.map(|amount_index| inner_map(amount, amount_index))
|
||||||
.collect::<Result<HashMap<AmountIndex, OutputOnChain>, RuntimeError>>()?,
|
.collect::<DbResult<HashMap<AmountIndex, OutputOnChain>>>()?,
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
.collect::<Result<HashMap<Amount, HashMap<AmountIndex, OutputOnChain>>, RuntimeError>>()?;
|
.collect::<DbResult<HashMap<Amount, HashMap<AmountIndex, OutputOnChain>>>>()?;
|
||||||
|
|
||||||
Ok(BlockchainResponse::Outputs(map))
|
Ok(BlockchainResponse::Outputs(map))
|
||||||
}
|
}
|
||||||
|
@ -456,7 +456,7 @@ fn number_outputs_with_amount(env: &ConcreteEnv, amounts: Vec<Amount>) -> Respon
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect::<Result<HashMap<Amount, usize>, RuntimeError>>()?;
|
.collect::<DbResult<HashMap<Amount, usize>>>()?;
|
||||||
|
|
||||||
Ok(BlockchainResponse::NumberOutputsWithAmount(map))
|
Ok(BlockchainResponse::NumberOutputsWithAmount(map))
|
||||||
}
|
}
|
||||||
|
@ -522,7 +522,7 @@ fn compact_chain_history(env: &ConcreteEnv) -> ResponseResult {
|
||||||
.map(compact_history_index_to_height_offset::<INITIAL_BLOCKS>)
|
.map(compact_history_index_to_height_offset::<INITIAL_BLOCKS>)
|
||||||
.map_while(|i| top_block_height.checked_sub(i))
|
.map_while(|i| top_block_height.checked_sub(i))
|
||||||
.map(|height| Ok(get_block_info(&height, &table_block_infos)?.block_hash))
|
.map(|height| Ok(get_block_info(&height, &table_block_infos)?.block_hash))
|
||||||
.collect::<Result<Vec<_>, RuntimeError>>()?;
|
.collect::<DbResult<Vec<_>>>()?;
|
||||||
|
|
||||||
if compact_history_genesis_not_included::<INITIAL_BLOCKS>(top_block_height) {
|
if compact_history_genesis_not_included::<INITIAL_BLOCKS>(top_block_height) {
|
||||||
block_ids.push(get_block_info(&0, &table_block_infos)?.block_hash);
|
block_ids.push(get_block_info(&0, &table_block_infos)?.block_hash);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//! Database service type aliases.
|
//! Database service type aliases.
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Use
|
//---------------------------------------------------------------------------------------------------- Use
|
||||||
use cuprate_database::RuntimeError;
|
use cuprate_database::DbResult;
|
||||||
use cuprate_database_service::{DatabaseReadService, DatabaseWriteHandle};
|
use cuprate_database_service::{DatabaseReadService, DatabaseWriteHandle};
|
||||||
use cuprate_types::blockchain::{
|
use cuprate_types::blockchain::{
|
||||||
BlockchainReadRequest, BlockchainResponse, BlockchainWriteRequest,
|
BlockchainReadRequest, BlockchainResponse, BlockchainWriteRequest,
|
||||||
|
@ -11,7 +11,7 @@ use cuprate_types::blockchain::{
|
||||||
/// The actual type of the response.
|
/// The actual type of the response.
|
||||||
///
|
///
|
||||||
/// Either our [`BlockchainResponse`], or a database error occurred.
|
/// Either our [`BlockchainResponse`], or a database error occurred.
|
||||||
pub(super) type ResponseResult = Result<BlockchainResponse, RuntimeError>;
|
pub(super) type ResponseResult = DbResult<BlockchainResponse>;
|
||||||
|
|
||||||
/// The blockchain database write service.
|
/// The blockchain database write service.
|
||||||
pub type BlockchainWriteHandle = DatabaseWriteHandle<BlockchainWriteRequest, BlockchainResponse>;
|
pub type BlockchainWriteHandle = DatabaseWriteHandle<BlockchainWriteRequest, BlockchainResponse>;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
//---------------------------------------------------------------------------------------------------- Import
|
//---------------------------------------------------------------------------------------------------- Import
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use cuprate_database::{ConcreteEnv, DatabaseRo, Env, EnvInner, RuntimeError, TxRw};
|
use cuprate_database::{ConcreteEnv, DatabaseRo, DbResult, Env, EnvInner, TxRw};
|
||||||
use cuprate_database_service::DatabaseWriteHandle;
|
use cuprate_database_service::DatabaseWriteHandle;
|
||||||
use cuprate_types::{
|
use cuprate_types::{
|
||||||
blockchain::{BlockchainResponse, BlockchainWriteRequest},
|
blockchain::{BlockchainResponse, BlockchainWriteRequest},
|
||||||
|
@ -36,7 +36,7 @@ pub fn init_write_service(env: Arc<ConcreteEnv>) -> BlockchainWriteHandle {
|
||||||
fn handle_blockchain_request(
|
fn handle_blockchain_request(
|
||||||
env: &ConcreteEnv,
|
env: &ConcreteEnv,
|
||||||
req: &BlockchainWriteRequest,
|
req: &BlockchainWriteRequest,
|
||||||
) -> Result<BlockchainResponse, RuntimeError> {
|
) -> DbResult<BlockchainResponse> {
|
||||||
match req {
|
match req {
|
||||||
BlockchainWriteRequest::WriteBlock(block) => write_block(env, block),
|
BlockchainWriteRequest::WriteBlock(block) => write_block(env, block),
|
||||||
BlockchainWriteRequest::WriteAltBlock(alt_block) => write_alt_block(env, alt_block),
|
BlockchainWriteRequest::WriteAltBlock(alt_block) => write_alt_block(env, alt_block),
|
||||||
|
|
|
@ -6,7 +6,7 @@ use std::{cell::RefCell, ops::RangeBounds};
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::heed::types::HeedDb,
|
backend::heed::types::HeedDb,
|
||||||
database::{DatabaseIter, DatabaseRo, DatabaseRw},
|
database::{DatabaseIter, DatabaseRo, DatabaseRw},
|
||||||
error::RuntimeError,
|
error::{DbResult, RuntimeError},
|
||||||
table::Table,
|
table::Table,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -54,16 +54,13 @@ fn get<T: Table>(
|
||||||
db: &HeedDb<T::Key, T::Value>,
|
db: &HeedDb<T::Key, T::Value>,
|
||||||
tx_ro: &heed::RoTxn<'_>,
|
tx_ro: &heed::RoTxn<'_>,
|
||||||
key: &T::Key,
|
key: &T::Key,
|
||||||
) -> Result<T::Value, RuntimeError> {
|
) -> DbResult<T::Value> {
|
||||||
db.get(tx_ro, key)?.ok_or(RuntimeError::KeyNotFound)
|
db.get(tx_ro, key)?.ok_or(RuntimeError::KeyNotFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Shared [`DatabaseRo::len()`].
|
/// Shared [`DatabaseRo::len()`].
|
||||||
#[inline]
|
#[inline]
|
||||||
fn len<T: Table>(
|
fn len<T: Table>(db: &HeedDb<T::Key, T::Value>, tx_ro: &heed::RoTxn<'_>) -> DbResult<u64> {
|
||||||
db: &HeedDb<T::Key, T::Value>,
|
|
||||||
tx_ro: &heed::RoTxn<'_>,
|
|
||||||
) -> Result<u64, RuntimeError> {
|
|
||||||
Ok(db.len(tx_ro)?)
|
Ok(db.len(tx_ro)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +69,7 @@ fn len<T: Table>(
|
||||||
fn first<T: Table>(
|
fn first<T: Table>(
|
||||||
db: &HeedDb<T::Key, T::Value>,
|
db: &HeedDb<T::Key, T::Value>,
|
||||||
tx_ro: &heed::RoTxn<'_>,
|
tx_ro: &heed::RoTxn<'_>,
|
||||||
) -> Result<(T::Key, T::Value), RuntimeError> {
|
) -> DbResult<(T::Key, T::Value)> {
|
||||||
db.first(tx_ro)?.ok_or(RuntimeError::KeyNotFound)
|
db.first(tx_ro)?.ok_or(RuntimeError::KeyNotFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,16 +78,13 @@ fn first<T: Table>(
|
||||||
fn last<T: Table>(
|
fn last<T: Table>(
|
||||||
db: &HeedDb<T::Key, T::Value>,
|
db: &HeedDb<T::Key, T::Value>,
|
||||||
tx_ro: &heed::RoTxn<'_>,
|
tx_ro: &heed::RoTxn<'_>,
|
||||||
) -> Result<(T::Key, T::Value), RuntimeError> {
|
) -> DbResult<(T::Key, T::Value)> {
|
||||||
db.last(tx_ro)?.ok_or(RuntimeError::KeyNotFound)
|
db.last(tx_ro)?.ok_or(RuntimeError::KeyNotFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Shared [`DatabaseRo::is_empty()`].
|
/// Shared [`DatabaseRo::is_empty()`].
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_empty<T: Table>(
|
fn is_empty<T: Table>(db: &HeedDb<T::Key, T::Value>, tx_ro: &heed::RoTxn<'_>) -> DbResult<bool> {
|
||||||
db: &HeedDb<T::Key, T::Value>,
|
|
||||||
tx_ro: &heed::RoTxn<'_>,
|
|
||||||
) -> Result<bool, RuntimeError> {
|
|
||||||
Ok(db.is_empty(tx_ro)?)
|
Ok(db.is_empty(tx_ro)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +94,7 @@ impl<T: Table> DatabaseIter<T> for HeedTableRo<'_, T> {
|
||||||
fn get_range<'a, Range>(
|
fn get_range<'a, Range>(
|
||||||
&'a self,
|
&'a self,
|
||||||
range: Range,
|
range: Range,
|
||||||
) -> Result<impl Iterator<Item = Result<T::Value, RuntimeError>> + 'a, RuntimeError>
|
) -> DbResult<impl Iterator<Item = DbResult<T::Value>> + 'a>
|
||||||
where
|
where
|
||||||
Range: RangeBounds<T::Key> + 'a,
|
Range: RangeBounds<T::Key> + 'a,
|
||||||
{
|
{
|
||||||
|
@ -108,24 +102,17 @@ impl<T: Table> DatabaseIter<T> for HeedTableRo<'_, T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn iter(
|
fn iter(&self) -> DbResult<impl Iterator<Item = DbResult<(T::Key, T::Value)>> + '_> {
|
||||||
&self,
|
|
||||||
) -> Result<impl Iterator<Item = Result<(T::Key, T::Value), RuntimeError>> + '_, RuntimeError>
|
|
||||||
{
|
|
||||||
Ok(self.db.iter(self.tx_ro)?.map(|res| Ok(res?)))
|
Ok(self.db.iter(self.tx_ro)?.map(|res| Ok(res?)))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn keys(
|
fn keys(&self) -> DbResult<impl Iterator<Item = DbResult<T::Key>> + '_> {
|
||||||
&self,
|
|
||||||
) -> Result<impl Iterator<Item = Result<T::Key, RuntimeError>> + '_, RuntimeError> {
|
|
||||||
Ok(self.db.iter(self.tx_ro)?.map(|res| Ok(res?.0)))
|
Ok(self.db.iter(self.tx_ro)?.map(|res| Ok(res?.0)))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn values(
|
fn values(&self) -> DbResult<impl Iterator<Item = DbResult<T::Value>> + '_> {
|
||||||
&self,
|
|
||||||
) -> Result<impl Iterator<Item = Result<T::Value, RuntimeError>> + '_, RuntimeError> {
|
|
||||||
Ok(self.db.iter(self.tx_ro)?.map(|res| Ok(res?.1)))
|
Ok(self.db.iter(self.tx_ro)?.map(|res| Ok(res?.1)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -134,27 +121,27 @@ impl<T: Table> DatabaseIter<T> for HeedTableRo<'_, T> {
|
||||||
// SAFETY: `HeedTableRo: !Send` as it holds a reference to `heed::RoTxn: Send + !Sync`.
|
// SAFETY: `HeedTableRo: !Send` as it holds a reference to `heed::RoTxn: Send + !Sync`.
|
||||||
unsafe impl<T: Table> DatabaseRo<T> for HeedTableRo<'_, T> {
|
unsafe impl<T: Table> DatabaseRo<T> for HeedTableRo<'_, T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get(&self, key: &T::Key) -> Result<T::Value, RuntimeError> {
|
fn get(&self, key: &T::Key) -> DbResult<T::Value> {
|
||||||
get::<T>(&self.db, self.tx_ro, key)
|
get::<T>(&self.db, self.tx_ro, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn len(&self) -> Result<u64, RuntimeError> {
|
fn len(&self) -> DbResult<u64> {
|
||||||
len::<T>(&self.db, self.tx_ro)
|
len::<T>(&self.db, self.tx_ro)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn first(&self) -> Result<(T::Key, T::Value), RuntimeError> {
|
fn first(&self) -> DbResult<(T::Key, T::Value)> {
|
||||||
first::<T>(&self.db, self.tx_ro)
|
first::<T>(&self.db, self.tx_ro)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn last(&self) -> Result<(T::Key, T::Value), RuntimeError> {
|
fn last(&self) -> DbResult<(T::Key, T::Value)> {
|
||||||
last::<T>(&self.db, self.tx_ro)
|
last::<T>(&self.db, self.tx_ro)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_empty(&self) -> Result<bool, RuntimeError> {
|
fn is_empty(&self) -> DbResult<bool> {
|
||||||
is_empty::<T>(&self.db, self.tx_ro)
|
is_empty::<T>(&self.db, self.tx_ro)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -164,45 +151,45 @@ unsafe impl<T: Table> DatabaseRo<T> for HeedTableRo<'_, T> {
|
||||||
// `HeedTableRw`'s write transaction is `!Send`.
|
// `HeedTableRw`'s write transaction is `!Send`.
|
||||||
unsafe impl<T: Table> DatabaseRo<T> for HeedTableRw<'_, '_, T> {
|
unsafe impl<T: Table> DatabaseRo<T> for HeedTableRw<'_, '_, T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get(&self, key: &T::Key) -> Result<T::Value, RuntimeError> {
|
fn get(&self, key: &T::Key) -> DbResult<T::Value> {
|
||||||
get::<T>(&self.db, &self.tx_rw.borrow(), key)
|
get::<T>(&self.db, &self.tx_rw.borrow(), key)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn len(&self) -> Result<u64, RuntimeError> {
|
fn len(&self) -> DbResult<u64> {
|
||||||
len::<T>(&self.db, &self.tx_rw.borrow())
|
len::<T>(&self.db, &self.tx_rw.borrow())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn first(&self) -> Result<(T::Key, T::Value), RuntimeError> {
|
fn first(&self) -> DbResult<(T::Key, T::Value)> {
|
||||||
first::<T>(&self.db, &self.tx_rw.borrow())
|
first::<T>(&self.db, &self.tx_rw.borrow())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn last(&self) -> Result<(T::Key, T::Value), RuntimeError> {
|
fn last(&self) -> DbResult<(T::Key, T::Value)> {
|
||||||
last::<T>(&self.db, &self.tx_rw.borrow())
|
last::<T>(&self.db, &self.tx_rw.borrow())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_empty(&self) -> Result<bool, RuntimeError> {
|
fn is_empty(&self) -> DbResult<bool> {
|
||||||
is_empty::<T>(&self.db, &self.tx_rw.borrow())
|
is_empty::<T>(&self.db, &self.tx_rw.borrow())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Table> DatabaseRw<T> for HeedTableRw<'_, '_, T> {
|
impl<T: Table> DatabaseRw<T> for HeedTableRw<'_, '_, T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn put(&mut self, key: &T::Key, value: &T::Value) -> Result<(), RuntimeError> {
|
fn put(&mut self, key: &T::Key, value: &T::Value) -> DbResult<()> {
|
||||||
Ok(self.db.put(&mut self.tx_rw.borrow_mut(), key, value)?)
|
Ok(self.db.put(&mut self.tx_rw.borrow_mut(), key, value)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn delete(&mut self, key: &T::Key) -> Result<(), RuntimeError> {
|
fn delete(&mut self, key: &T::Key) -> DbResult<()> {
|
||||||
self.db.delete(&mut self.tx_rw.borrow_mut(), key)?;
|
self.db.delete(&mut self.tx_rw.borrow_mut(), key)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn take(&mut self, key: &T::Key) -> Result<T::Value, RuntimeError> {
|
fn take(&mut self, key: &T::Key) -> DbResult<T::Value> {
|
||||||
// LMDB/heed does not return the value on deletion.
|
// LMDB/heed does not return the value on deletion.
|
||||||
// So, fetch it first - then delete.
|
// So, fetch it first - then delete.
|
||||||
let value = get::<T>(&self.db, &self.tx_rw.borrow(), key)?;
|
let value = get::<T>(&self.db, &self.tx_rw.borrow(), key)?;
|
||||||
|
@ -216,7 +203,7 @@ impl<T: Table> DatabaseRw<T> for HeedTableRw<'_, '_, T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn pop_first(&mut self) -> Result<(T::Key, T::Value), RuntimeError> {
|
fn pop_first(&mut self) -> DbResult<(T::Key, T::Value)> {
|
||||||
let tx_rw = &mut self.tx_rw.borrow_mut();
|
let tx_rw = &mut self.tx_rw.borrow_mut();
|
||||||
|
|
||||||
// Get the value first...
|
// Get the value first...
|
||||||
|
@ -235,7 +222,7 @@ impl<T: Table> DatabaseRw<T> for HeedTableRw<'_, '_, T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn pop_last(&mut self) -> Result<(T::Key, T::Value), RuntimeError> {
|
fn pop_last(&mut self) -> DbResult<(T::Key, T::Value)> {
|
||||||
let tx_rw = &mut self.tx_rw.borrow_mut();
|
let tx_rw = &mut self.tx_rw.borrow_mut();
|
||||||
|
|
||||||
// Get the value first...
|
// Get the value first...
|
||||||
|
|
|
@ -18,7 +18,7 @@ use crate::{
|
||||||
config::{Config, SyncMode},
|
config::{Config, SyncMode},
|
||||||
database::{DatabaseIter, DatabaseRo, DatabaseRw},
|
database::{DatabaseIter, DatabaseRo, DatabaseRw},
|
||||||
env::{Env, EnvInner},
|
env::{Env, EnvInner},
|
||||||
error::{InitError, RuntimeError},
|
error::{DbResult, InitError, RuntimeError},
|
||||||
key::{Key, KeyCompare},
|
key::{Key, KeyCompare},
|
||||||
resize::ResizeAlgorithm,
|
resize::ResizeAlgorithm,
|
||||||
table::Table,
|
table::Table,
|
||||||
|
@ -203,7 +203,7 @@ impl Env for ConcreteEnv {
|
||||||
&self.config
|
&self.config
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sync(&self) -> Result<(), RuntimeError> {
|
fn sync(&self) -> DbResult<()> {
|
||||||
Ok(self.env.read().unwrap().force_sync()?)
|
Ok(self.env.read().unwrap().force_sync()?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,12 +253,12 @@ where
|
||||||
type Rw<'a> = RefCell<heed::RwTxn<'a>>;
|
type Rw<'a> = RefCell<heed::RwTxn<'a>>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn tx_ro(&self) -> Result<Self::Ro<'_>, RuntimeError> {
|
fn tx_ro(&self) -> DbResult<Self::Ro<'_>> {
|
||||||
Ok(self.read_txn()?)
|
Ok(self.read_txn()?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn tx_rw(&self) -> Result<Self::Rw<'_>, RuntimeError> {
|
fn tx_rw(&self) -> DbResult<Self::Rw<'_>> {
|
||||||
Ok(RefCell::new(self.write_txn()?))
|
Ok(RefCell::new(self.write_txn()?))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,7 +266,7 @@ where
|
||||||
fn open_db_ro<T: Table>(
|
fn open_db_ro<T: Table>(
|
||||||
&self,
|
&self,
|
||||||
tx_ro: &Self::Ro<'_>,
|
tx_ro: &Self::Ro<'_>,
|
||||||
) -> Result<impl DatabaseRo<T> + DatabaseIter<T>, RuntimeError> {
|
) -> DbResult<impl DatabaseRo<T> + DatabaseIter<T>> {
|
||||||
// Open up a read-only database using our table's const metadata.
|
// Open up a read-only database using our table's const metadata.
|
||||||
//
|
//
|
||||||
// INVARIANT: LMDB caches the ordering / comparison function from [`EnvInner::create_db`],
|
// INVARIANT: LMDB caches the ordering / comparison function from [`EnvInner::create_db`],
|
||||||
|
@ -281,10 +281,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn open_db_rw<T: Table>(
|
fn open_db_rw<T: Table>(&self, tx_rw: &Self::Rw<'_>) -> DbResult<impl DatabaseRw<T>> {
|
||||||
&self,
|
|
||||||
tx_rw: &Self::Rw<'_>,
|
|
||||||
) -> Result<impl DatabaseRw<T>, RuntimeError> {
|
|
||||||
// Open up a read/write database using our table's const metadata.
|
// Open up a read/write database using our table's const metadata.
|
||||||
//
|
//
|
||||||
// INVARIANT: LMDB caches the ordering / comparison function from [`EnvInner::create_db`],
|
// INVARIANT: LMDB caches the ordering / comparison function from [`EnvInner::create_db`],
|
||||||
|
@ -296,7 +293,7 @@ where
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_db<T: Table>(&self, tx_rw: &Self::Rw<'_>) -> Result<(), RuntimeError> {
|
fn create_db<T: Table>(&self, tx_rw: &Self::Rw<'_>) -> DbResult<()> {
|
||||||
// Create a database using our:
|
// Create a database using our:
|
||||||
// - [`Table`]'s const metadata.
|
// - [`Table`]'s const metadata.
|
||||||
// - (potentially) our [`Key`] comparison function
|
// - (potentially) our [`Key`] comparison function
|
||||||
|
@ -328,7 +325,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn clear_db<T: Table>(&self, tx_rw: &mut Self::Rw<'_>) -> Result<(), RuntimeError> {
|
fn clear_db<T: Table>(&self, tx_rw: &mut Self::Rw<'_>) -> DbResult<()> {
|
||||||
let tx_rw = tx_rw.get_mut();
|
let tx_rw = tx_rw.get_mut();
|
||||||
|
|
||||||
// Open the table. We don't care about flags or key
|
// Open the table. We don't care about flags or key
|
||||||
|
|
|
@ -4,31 +4,31 @@ use std::cell::RefCell;
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Import
|
//---------------------------------------------------------------------------------------------------- Import
|
||||||
use crate::{
|
use crate::{
|
||||||
error::RuntimeError,
|
error::DbResult,
|
||||||
transaction::{TxRo, TxRw},
|
transaction::{TxRo, TxRw},
|
||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- TxRo
|
//---------------------------------------------------------------------------------------------------- TxRo
|
||||||
impl TxRo<'_> for heed::RoTxn<'_> {
|
impl TxRo<'_> for heed::RoTxn<'_> {
|
||||||
fn commit(self) -> Result<(), RuntimeError> {
|
fn commit(self) -> DbResult<()> {
|
||||||
Ok(heed::RoTxn::commit(self)?)
|
Ok(heed::RoTxn::commit(self)?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- TxRw
|
//---------------------------------------------------------------------------------------------------- TxRw
|
||||||
impl TxRo<'_> for RefCell<heed::RwTxn<'_>> {
|
impl TxRo<'_> for RefCell<heed::RwTxn<'_>> {
|
||||||
fn commit(self) -> Result<(), RuntimeError> {
|
fn commit(self) -> DbResult<()> {
|
||||||
TxRw::commit(self)
|
TxRw::commit(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TxRw<'_> for RefCell<heed::RwTxn<'_>> {
|
impl TxRw<'_> for RefCell<heed::RwTxn<'_>> {
|
||||||
fn commit(self) -> Result<(), RuntimeError> {
|
fn commit(self) -> DbResult<()> {
|
||||||
Ok(heed::RwTxn::commit(self.into_inner())?)
|
Ok(heed::RwTxn::commit(self.into_inner())?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This function is infallible.
|
/// This function is infallible.
|
||||||
fn abort(self) -> Result<(), RuntimeError> {
|
fn abort(self) -> DbResult<()> {
|
||||||
heed::RwTxn::abort(self.into_inner());
|
heed::RwTxn::abort(self.into_inner());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ use crate::{
|
||||||
types::{RedbTableRo, RedbTableRw},
|
types::{RedbTableRo, RedbTableRw},
|
||||||
},
|
},
|
||||||
database::{DatabaseIter, DatabaseRo, DatabaseRw},
|
database::{DatabaseIter, DatabaseRo, DatabaseRw},
|
||||||
error::RuntimeError,
|
error::{DbResult, RuntimeError},
|
||||||
table::Table,
|
table::Table,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ use crate::{
|
||||||
fn get<T: Table + 'static>(
|
fn get<T: Table + 'static>(
|
||||||
db: &impl ReadableTable<StorableRedb<T::Key>, StorableRedb<T::Value>>,
|
db: &impl ReadableTable<StorableRedb<T::Key>, StorableRedb<T::Value>>,
|
||||||
key: &T::Key,
|
key: &T::Key,
|
||||||
) -> Result<T::Value, RuntimeError> {
|
) -> DbResult<T::Value> {
|
||||||
Ok(db.get(key)?.ok_or(RuntimeError::KeyNotFound)?.value())
|
Ok(db.get(key)?.ok_or(RuntimeError::KeyNotFound)?.value())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ fn get<T: Table + 'static>(
|
||||||
#[inline]
|
#[inline]
|
||||||
fn len<T: Table>(
|
fn len<T: Table>(
|
||||||
db: &impl ReadableTable<StorableRedb<T::Key>, StorableRedb<T::Value>>,
|
db: &impl ReadableTable<StorableRedb<T::Key>, StorableRedb<T::Value>>,
|
||||||
) -> Result<u64, RuntimeError> {
|
) -> DbResult<u64> {
|
||||||
Ok(db.len()?)
|
Ok(db.len()?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ fn len<T: Table>(
|
||||||
#[inline]
|
#[inline]
|
||||||
fn first<T: Table>(
|
fn first<T: Table>(
|
||||||
db: &impl ReadableTable<StorableRedb<T::Key>, StorableRedb<T::Value>>,
|
db: &impl ReadableTable<StorableRedb<T::Key>, StorableRedb<T::Value>>,
|
||||||
) -> Result<(T::Key, T::Value), RuntimeError> {
|
) -> DbResult<(T::Key, T::Value)> {
|
||||||
let (key, value) = db.first()?.ok_or(RuntimeError::KeyNotFound)?;
|
let (key, value) = db.first()?.ok_or(RuntimeError::KeyNotFound)?;
|
||||||
Ok((key.value(), value.value()))
|
Ok((key.value(), value.value()))
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ fn first<T: Table>(
|
||||||
#[inline]
|
#[inline]
|
||||||
fn last<T: Table>(
|
fn last<T: Table>(
|
||||||
db: &impl ReadableTable<StorableRedb<T::Key>, StorableRedb<T::Value>>,
|
db: &impl ReadableTable<StorableRedb<T::Key>, StorableRedb<T::Value>>,
|
||||||
) -> Result<(T::Key, T::Value), RuntimeError> {
|
) -> DbResult<(T::Key, T::Value)> {
|
||||||
let (key, value) = db.last()?.ok_or(RuntimeError::KeyNotFound)?;
|
let (key, value) = db.last()?.ok_or(RuntimeError::KeyNotFound)?;
|
||||||
Ok((key.value(), value.value()))
|
Ok((key.value(), value.value()))
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ fn last<T: Table>(
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_empty<T: Table>(
|
fn is_empty<T: Table>(
|
||||||
db: &impl ReadableTable<StorableRedb<T::Key>, StorableRedb<T::Value>>,
|
db: &impl ReadableTable<StorableRedb<T::Key>, StorableRedb<T::Value>>,
|
||||||
) -> Result<bool, RuntimeError> {
|
) -> DbResult<bool> {
|
||||||
Ok(db.is_empty()?)
|
Ok(db.is_empty()?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ impl<T: Table + 'static> DatabaseIter<T> for RedbTableRo<T::Key, T::Value> {
|
||||||
fn get_range<'a, Range>(
|
fn get_range<'a, Range>(
|
||||||
&'a self,
|
&'a self,
|
||||||
range: Range,
|
range: Range,
|
||||||
) -> Result<impl Iterator<Item = Result<T::Value, RuntimeError>> + 'a, RuntimeError>
|
) -> DbResult<impl Iterator<Item = DbResult<T::Value>> + 'a>
|
||||||
where
|
where
|
||||||
Range: RangeBounds<T::Key> + 'a,
|
Range: RangeBounds<T::Key> + 'a,
|
||||||
{
|
{
|
||||||
|
@ -80,10 +80,7 @@ impl<T: Table + 'static> DatabaseIter<T> for RedbTableRo<T::Key, T::Value> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn iter(
|
fn iter(&self) -> DbResult<impl Iterator<Item = DbResult<(T::Key, T::Value)>> + '_> {
|
||||||
&self,
|
|
||||||
) -> Result<impl Iterator<Item = Result<(T::Key, T::Value), RuntimeError>> + '_, RuntimeError>
|
|
||||||
{
|
|
||||||
Ok(ReadableTable::iter(self)?.map(|result| {
|
Ok(ReadableTable::iter(self)?.map(|result| {
|
||||||
let (key, value) = result?;
|
let (key, value) = result?;
|
||||||
Ok((key.value(), value.value()))
|
Ok((key.value(), value.value()))
|
||||||
|
@ -91,9 +88,7 @@ impl<T: Table + 'static> DatabaseIter<T> for RedbTableRo<T::Key, T::Value> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn keys(
|
fn keys(&self) -> DbResult<impl Iterator<Item = DbResult<T::Key>> + '_> {
|
||||||
&self,
|
|
||||||
) -> Result<impl Iterator<Item = Result<T::Key, RuntimeError>> + '_, RuntimeError> {
|
|
||||||
Ok(ReadableTable::iter(self)?.map(|result| {
|
Ok(ReadableTable::iter(self)?.map(|result| {
|
||||||
let (key, _value) = result?;
|
let (key, _value) = result?;
|
||||||
Ok(key.value())
|
Ok(key.value())
|
||||||
|
@ -101,9 +96,7 @@ impl<T: Table + 'static> DatabaseIter<T> for RedbTableRo<T::Key, T::Value> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn values(
|
fn values(&self) -> DbResult<impl Iterator<Item = DbResult<T::Value>> + '_> {
|
||||||
&self,
|
|
||||||
) -> Result<impl Iterator<Item = Result<T::Value, RuntimeError>> + '_, RuntimeError> {
|
|
||||||
Ok(ReadableTable::iter(self)?.map(|result| {
|
Ok(ReadableTable::iter(self)?.map(|result| {
|
||||||
let (_key, value) = result?;
|
let (_key, value) = result?;
|
||||||
Ok(value.value())
|
Ok(value.value())
|
||||||
|
@ -115,27 +108,27 @@ impl<T: Table + 'static> DatabaseIter<T> for RedbTableRo<T::Key, T::Value> {
|
||||||
// SAFETY: Both `redb`'s transaction and table types are `Send + Sync`.
|
// SAFETY: Both `redb`'s transaction and table types are `Send + Sync`.
|
||||||
unsafe impl<T: Table + 'static> DatabaseRo<T> for RedbTableRo<T::Key, T::Value> {
|
unsafe impl<T: Table + 'static> DatabaseRo<T> for RedbTableRo<T::Key, T::Value> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get(&self, key: &T::Key) -> Result<T::Value, RuntimeError> {
|
fn get(&self, key: &T::Key) -> DbResult<T::Value> {
|
||||||
get::<T>(self, key)
|
get::<T>(self, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn len(&self) -> Result<u64, RuntimeError> {
|
fn len(&self) -> DbResult<u64> {
|
||||||
len::<T>(self)
|
len::<T>(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn first(&self) -> Result<(T::Key, T::Value), RuntimeError> {
|
fn first(&self) -> DbResult<(T::Key, T::Value)> {
|
||||||
first::<T>(self)
|
first::<T>(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn last(&self) -> Result<(T::Key, T::Value), RuntimeError> {
|
fn last(&self) -> DbResult<(T::Key, T::Value)> {
|
||||||
last::<T>(self)
|
last::<T>(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_empty(&self) -> Result<bool, RuntimeError> {
|
fn is_empty(&self) -> DbResult<bool> {
|
||||||
is_empty::<T>(self)
|
is_empty::<T>(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,27 +137,27 @@ unsafe impl<T: Table + 'static> DatabaseRo<T> for RedbTableRo<T::Key, T::Value>
|
||||||
// SAFETY: Both `redb`'s transaction and table types are `Send + Sync`.
|
// SAFETY: Both `redb`'s transaction and table types are `Send + Sync`.
|
||||||
unsafe impl<T: Table + 'static> DatabaseRo<T> for RedbTableRw<'_, T::Key, T::Value> {
|
unsafe impl<T: Table + 'static> DatabaseRo<T> for RedbTableRw<'_, T::Key, T::Value> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get(&self, key: &T::Key) -> Result<T::Value, RuntimeError> {
|
fn get(&self, key: &T::Key) -> DbResult<T::Value> {
|
||||||
get::<T>(self, key)
|
get::<T>(self, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn len(&self) -> Result<u64, RuntimeError> {
|
fn len(&self) -> DbResult<u64> {
|
||||||
len::<T>(self)
|
len::<T>(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn first(&self) -> Result<(T::Key, T::Value), RuntimeError> {
|
fn first(&self) -> DbResult<(T::Key, T::Value)> {
|
||||||
first::<T>(self)
|
first::<T>(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn last(&self) -> Result<(T::Key, T::Value), RuntimeError> {
|
fn last(&self) -> DbResult<(T::Key, T::Value)> {
|
||||||
last::<T>(self)
|
last::<T>(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_empty(&self) -> Result<bool, RuntimeError> {
|
fn is_empty(&self) -> DbResult<bool> {
|
||||||
is_empty::<T>(self)
|
is_empty::<T>(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -173,19 +166,19 @@ impl<T: Table + 'static> DatabaseRw<T> for RedbTableRw<'_, T::Key, T::Value> {
|
||||||
// `redb` returns the value after function calls so we end with Ok(()) instead.
|
// `redb` returns the value after function calls so we end with Ok(()) instead.
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn put(&mut self, key: &T::Key, value: &T::Value) -> Result<(), RuntimeError> {
|
fn put(&mut self, key: &T::Key, value: &T::Value) -> DbResult<()> {
|
||||||
redb::Table::insert(self, key, value)?;
|
redb::Table::insert(self, key, value)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn delete(&mut self, key: &T::Key) -> Result<(), RuntimeError> {
|
fn delete(&mut self, key: &T::Key) -> DbResult<()> {
|
||||||
redb::Table::remove(self, key)?;
|
redb::Table::remove(self, key)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn take(&mut self, key: &T::Key) -> Result<T::Value, RuntimeError> {
|
fn take(&mut self, key: &T::Key) -> DbResult<T::Value> {
|
||||||
if let Some(value) = redb::Table::remove(self, key)? {
|
if let Some(value) = redb::Table::remove(self, key)? {
|
||||||
Ok(value.value())
|
Ok(value.value())
|
||||||
} else {
|
} else {
|
||||||
|
@ -194,13 +187,13 @@ impl<T: Table + 'static> DatabaseRw<T> for RedbTableRw<'_, T::Key, T::Value> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn pop_first(&mut self) -> Result<(T::Key, T::Value), RuntimeError> {
|
fn pop_first(&mut self) -> DbResult<(T::Key, T::Value)> {
|
||||||
let (key, value) = redb::Table::pop_first(self)?.ok_or(RuntimeError::KeyNotFound)?;
|
let (key, value) = redb::Table::pop_first(self)?.ok_or(RuntimeError::KeyNotFound)?;
|
||||||
Ok((key.value(), value.value()))
|
Ok((key.value(), value.value()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn pop_last(&mut self) -> Result<(T::Key, T::Value), RuntimeError> {
|
fn pop_last(&mut self) -> DbResult<(T::Key, T::Value)> {
|
||||||
let (key, value) = redb::Table::pop_last(self)?.ok_or(RuntimeError::KeyNotFound)?;
|
let (key, value) = redb::Table::pop_last(self)?.ok_or(RuntimeError::KeyNotFound)?;
|
||||||
Ok((key.value(), value.value()))
|
Ok((key.value(), value.value()))
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ use crate::{
|
||||||
config::{Config, SyncMode},
|
config::{Config, SyncMode},
|
||||||
database::{DatabaseIter, DatabaseRo, DatabaseRw},
|
database::{DatabaseIter, DatabaseRo, DatabaseRw},
|
||||||
env::{Env, EnvInner},
|
env::{Env, EnvInner},
|
||||||
error::{InitError, RuntimeError},
|
error::{DbResult, InitError, RuntimeError},
|
||||||
table::Table,
|
table::Table,
|
||||||
TxRw,
|
TxRw,
|
||||||
};
|
};
|
||||||
|
@ -105,7 +105,7 @@ impl Env for ConcreteEnv {
|
||||||
&self.config
|
&self.config
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sync(&self) -> Result<(), RuntimeError> {
|
fn sync(&self) -> DbResult<()> {
|
||||||
// `redb`'s syncs are tied with write transactions,
|
// `redb`'s syncs are tied with write transactions,
|
||||||
// so just create one, don't do anything and commit.
|
// so just create one, don't do anything and commit.
|
||||||
let mut tx_rw = self.env.begin_write()?;
|
let mut tx_rw = self.env.begin_write()?;
|
||||||
|
@ -127,12 +127,12 @@ where
|
||||||
type Rw<'a> = redb::WriteTransaction;
|
type Rw<'a> = redb::WriteTransaction;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn tx_ro(&self) -> Result<redb::ReadTransaction, RuntimeError> {
|
fn tx_ro(&self) -> DbResult<redb::ReadTransaction> {
|
||||||
Ok(self.0.begin_read()?)
|
Ok(self.0.begin_read()?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn tx_rw(&self) -> Result<redb::WriteTransaction, RuntimeError> {
|
fn tx_rw(&self) -> DbResult<redb::WriteTransaction> {
|
||||||
// `redb` has sync modes on the TX level, unlike heed,
|
// `redb` has sync modes on the TX level, unlike heed,
|
||||||
// which sets it at the Environment level.
|
// which sets it at the Environment level.
|
||||||
//
|
//
|
||||||
|
@ -146,7 +146,7 @@ where
|
||||||
fn open_db_ro<T: Table>(
|
fn open_db_ro<T: Table>(
|
||||||
&self,
|
&self,
|
||||||
tx_ro: &Self::Ro<'_>,
|
tx_ro: &Self::Ro<'_>,
|
||||||
) -> Result<impl DatabaseRo<T> + DatabaseIter<T>, RuntimeError> {
|
) -> DbResult<impl DatabaseRo<T> + DatabaseIter<T>> {
|
||||||
// Open up a read-only database using our `T: Table`'s const metadata.
|
// Open up a read-only database using our `T: Table`'s const metadata.
|
||||||
let table: redb::TableDefinition<'static, StorableRedb<T::Key>, StorableRedb<T::Value>> =
|
let table: redb::TableDefinition<'static, StorableRedb<T::Key>, StorableRedb<T::Value>> =
|
||||||
redb::TableDefinition::new(T::NAME);
|
redb::TableDefinition::new(T::NAME);
|
||||||
|
@ -155,10 +155,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn open_db_rw<T: Table>(
|
fn open_db_rw<T: Table>(&self, tx_rw: &Self::Rw<'_>) -> DbResult<impl DatabaseRw<T>> {
|
||||||
&self,
|
|
||||||
tx_rw: &Self::Rw<'_>,
|
|
||||||
) -> Result<impl DatabaseRw<T>, RuntimeError> {
|
|
||||||
// Open up a read/write database using our `T: Table`'s const metadata.
|
// Open up a read/write database using our `T: Table`'s const metadata.
|
||||||
let table: redb::TableDefinition<'static, StorableRedb<T::Key>, StorableRedb<T::Value>> =
|
let table: redb::TableDefinition<'static, StorableRedb<T::Key>, StorableRedb<T::Value>> =
|
||||||
redb::TableDefinition::new(T::NAME);
|
redb::TableDefinition::new(T::NAME);
|
||||||
|
@ -168,14 +165,14 @@ where
|
||||||
Ok(tx_rw.open_table(table)?)
|
Ok(tx_rw.open_table(table)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_db<T: Table>(&self, tx_rw: &redb::WriteTransaction) -> Result<(), RuntimeError> {
|
fn create_db<T: Table>(&self, tx_rw: &redb::WriteTransaction) -> DbResult<()> {
|
||||||
// INVARIANT: `redb` creates tables if they don't exist.
|
// INVARIANT: `redb` creates tables if they don't exist.
|
||||||
self.open_db_rw::<T>(tx_rw)?;
|
self.open_db_rw::<T>(tx_rw)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn clear_db<T: Table>(&self, tx_rw: &mut redb::WriteTransaction) -> Result<(), RuntimeError> {
|
fn clear_db<T: Table>(&self, tx_rw: &mut redb::WriteTransaction) -> DbResult<()> {
|
||||||
let table: redb::TableDefinition<
|
let table: redb::TableDefinition<
|
||||||
'static,
|
'static,
|
||||||
StorableRedb<<T as Table>::Key>,
|
StorableRedb<<T as Table>::Key>,
|
||||||
|
|
|
@ -34,8 +34,14 @@ impl<T> redb::Value for StorableRedb<T>
|
||||||
where
|
where
|
||||||
T: Storable + 'static,
|
T: Storable + 'static,
|
||||||
{
|
{
|
||||||
type SelfType<'a> = T where Self: 'a;
|
type SelfType<'a>
|
||||||
type AsBytes<'a> = &'a [u8] where Self: 'a;
|
= T
|
||||||
|
where
|
||||||
|
Self: 'a;
|
||||||
|
type AsBytes<'a>
|
||||||
|
= &'a [u8]
|
||||||
|
where
|
||||||
|
Self: 'a;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn fixed_width() -> Option<usize> {
|
fn fixed_width() -> Option<usize> {
|
||||||
|
|
|
@ -2,14 +2,14 @@
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Import
|
//---------------------------------------------------------------------------------------------------- Import
|
||||||
use crate::{
|
use crate::{
|
||||||
error::RuntimeError,
|
error::DbResult,
|
||||||
transaction::{TxRo, TxRw},
|
transaction::{TxRo, TxRw},
|
||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- TxRo
|
//---------------------------------------------------------------------------------------------------- TxRo
|
||||||
impl TxRo<'_> for redb::ReadTransaction {
|
impl TxRo<'_> for redb::ReadTransaction {
|
||||||
/// This function is infallible.
|
/// This function is infallible.
|
||||||
fn commit(self) -> Result<(), RuntimeError> {
|
fn commit(self) -> DbResult<()> {
|
||||||
// `redb`'s read transactions cleanup automatically when all references are dropped.
|
// `redb`'s read transactions cleanup automatically when all references are dropped.
|
||||||
//
|
//
|
||||||
// There is `close()`:
|
// There is `close()`:
|
||||||
|
@ -22,11 +22,11 @@ impl TxRo<'_> for redb::ReadTransaction {
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- TxRw
|
//---------------------------------------------------------------------------------------------------- TxRw
|
||||||
impl TxRw<'_> for redb::WriteTransaction {
|
impl TxRw<'_> for redb::WriteTransaction {
|
||||||
fn commit(self) -> Result<(), RuntimeError> {
|
fn commit(self) -> DbResult<()> {
|
||||||
Ok(self.commit()?)
|
Ok(self.commit()?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn abort(self) -> Result<(), RuntimeError> {
|
fn abort(self) -> DbResult<()> {
|
||||||
Ok(self.abort()?)
|
Ok(self.abort()?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
//! based on these values.
|
//! based on these values.
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Import
|
//---------------------------------------------------------------------------------------------------- Import
|
||||||
|
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,10 @@
|
||||||
//---------------------------------------------------------------------------------------------------- Import
|
//---------------------------------------------------------------------------------------------------- Import
|
||||||
use std::ops::RangeBounds;
|
use std::ops::RangeBounds;
|
||||||
|
|
||||||
use crate::{error::RuntimeError, table::Table};
|
use crate::{
|
||||||
|
error::{DbResult, RuntimeError},
|
||||||
|
table::Table,
|
||||||
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- DatabaseIter
|
//---------------------------------------------------------------------------------------------------- DatabaseIter
|
||||||
/// Generic post-fix documentation for `DatabaseIter` methods.
|
/// Generic post-fix documentation for `DatabaseIter` methods.
|
||||||
|
@ -48,27 +51,22 @@ pub trait DatabaseIter<T: Table> {
|
||||||
fn get_range<'a, Range>(
|
fn get_range<'a, Range>(
|
||||||
&'a self,
|
&'a self,
|
||||||
range: Range,
|
range: Range,
|
||||||
) -> Result<impl Iterator<Item = Result<T::Value, RuntimeError>> + 'a, RuntimeError>
|
) -> DbResult<impl Iterator<Item = DbResult<T::Value>> + 'a>
|
||||||
where
|
where
|
||||||
Range: RangeBounds<T::Key> + 'a;
|
Range: RangeBounds<T::Key> + 'a;
|
||||||
|
|
||||||
/// Get an [`Iterator`] that returns the `(key, value)` types for this database.
|
/// Get an [`Iterator`] that returns the `(key, value)` types for this database.
|
||||||
#[doc = doc_iter!()]
|
#[doc = doc_iter!()]
|
||||||
#[expect(clippy::iter_not_returning_iterator)]
|
#[expect(clippy::iter_not_returning_iterator)]
|
||||||
fn iter(
|
fn iter(&self) -> DbResult<impl Iterator<Item = DbResult<(T::Key, T::Value)>> + '_>;
|
||||||
&self,
|
|
||||||
) -> Result<impl Iterator<Item = Result<(T::Key, T::Value), RuntimeError>> + '_, RuntimeError>;
|
|
||||||
|
|
||||||
/// Get an [`Iterator`] that returns _only_ the `key` type for this database.
|
/// Get an [`Iterator`] that returns _only_ the `key` type for this database.
|
||||||
#[doc = doc_iter!()]
|
#[doc = doc_iter!()]
|
||||||
fn keys(&self)
|
fn keys(&self) -> DbResult<impl Iterator<Item = DbResult<T::Key>> + '_>;
|
||||||
-> Result<impl Iterator<Item = Result<T::Key, RuntimeError>> + '_, RuntimeError>;
|
|
||||||
|
|
||||||
/// Get an [`Iterator`] that returns _only_ the `value` type for this database.
|
/// Get an [`Iterator`] that returns _only_ the `value` type for this database.
|
||||||
#[doc = doc_iter!()]
|
#[doc = doc_iter!()]
|
||||||
fn values(
|
fn values(&self) -> DbResult<impl Iterator<Item = DbResult<T::Value>> + '_>;
|
||||||
&self,
|
|
||||||
) -> Result<impl Iterator<Item = Result<T::Value, RuntimeError>> + '_, RuntimeError>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- DatabaseRo
|
//---------------------------------------------------------------------------------------------------- DatabaseRo
|
||||||
|
@ -76,7 +74,7 @@ pub trait DatabaseIter<T: Table> {
|
||||||
macro_rules! doc_database {
|
macro_rules! doc_database {
|
||||||
() => {
|
() => {
|
||||||
r"# Errors
|
r"# Errors
|
||||||
This will return [`RuntimeError::KeyNotFound`] if:
|
This will return [`crate::RuntimeError::KeyNotFound`] if:
|
||||||
- Input does not exist OR
|
- Input does not exist OR
|
||||||
- Database is empty"
|
- Database is empty"
|
||||||
};
|
};
|
||||||
|
@ -111,7 +109,7 @@ This will return [`RuntimeError::KeyNotFound`] if:
|
||||||
pub unsafe trait DatabaseRo<T: Table> {
|
pub unsafe trait DatabaseRo<T: Table> {
|
||||||
/// Get the value corresponding to a key.
|
/// Get the value corresponding to a key.
|
||||||
#[doc = doc_database!()]
|
#[doc = doc_database!()]
|
||||||
fn get(&self, key: &T::Key) -> Result<T::Value, RuntimeError>;
|
fn get(&self, key: &T::Key) -> DbResult<T::Value>;
|
||||||
|
|
||||||
/// Returns `true` if the database contains a value for the specified key.
|
/// Returns `true` if the database contains a value for the specified key.
|
||||||
///
|
///
|
||||||
|
@ -120,7 +118,7 @@ pub unsafe trait DatabaseRo<T: Table> {
|
||||||
/// as in that case, `Ok(false)` will be returned.
|
/// as in that case, `Ok(false)` will be returned.
|
||||||
///
|
///
|
||||||
/// Other errors may still occur.
|
/// Other errors may still occur.
|
||||||
fn contains(&self, key: &T::Key) -> Result<bool, RuntimeError> {
|
fn contains(&self, key: &T::Key) -> DbResult<bool> {
|
||||||
match self.get(key) {
|
match self.get(key) {
|
||||||
Ok(_) => Ok(true),
|
Ok(_) => Ok(true),
|
||||||
Err(RuntimeError::KeyNotFound) => Ok(false),
|
Err(RuntimeError::KeyNotFound) => Ok(false),
|
||||||
|
@ -132,21 +130,21 @@ pub unsafe trait DatabaseRo<T: Table> {
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
/// This will never return [`RuntimeError::KeyNotFound`].
|
/// This will never return [`RuntimeError::KeyNotFound`].
|
||||||
fn len(&self) -> Result<u64, RuntimeError>;
|
fn len(&self) -> DbResult<u64>;
|
||||||
|
|
||||||
/// Returns the first `(key, value)` pair in the database.
|
/// Returns the first `(key, value)` pair in the database.
|
||||||
#[doc = doc_database!()]
|
#[doc = doc_database!()]
|
||||||
fn first(&self) -> Result<(T::Key, T::Value), RuntimeError>;
|
fn first(&self) -> DbResult<(T::Key, T::Value)>;
|
||||||
|
|
||||||
/// Returns the last `(key, value)` pair in the database.
|
/// Returns the last `(key, value)` pair in the database.
|
||||||
#[doc = doc_database!()]
|
#[doc = doc_database!()]
|
||||||
fn last(&self) -> Result<(T::Key, T::Value), RuntimeError>;
|
fn last(&self) -> DbResult<(T::Key, T::Value)>;
|
||||||
|
|
||||||
/// Returns `true` if the database contains no `(key, value)` pairs.
|
/// Returns `true` if the database contains no `(key, value)` pairs.
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
/// This can only return [`RuntimeError::Io`] on errors.
|
/// This can only return [`RuntimeError::Io`] on errors.
|
||||||
fn is_empty(&self) -> Result<bool, RuntimeError>;
|
fn is_empty(&self) -> DbResult<bool>;
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- DatabaseRw
|
//---------------------------------------------------------------------------------------------------- DatabaseRw
|
||||||
|
@ -161,7 +159,7 @@ pub trait DatabaseRw<T: Table>: DatabaseRo<T> {
|
||||||
#[doc = doc_database!()]
|
#[doc = doc_database!()]
|
||||||
///
|
///
|
||||||
/// This will never [`RuntimeError::KeyExists`].
|
/// This will never [`RuntimeError::KeyExists`].
|
||||||
fn put(&mut self, key: &T::Key, value: &T::Value) -> Result<(), RuntimeError>;
|
fn put(&mut self, key: &T::Key, value: &T::Value) -> DbResult<()>;
|
||||||
|
|
||||||
/// Delete a key-value pair in the database.
|
/// Delete a key-value pair in the database.
|
||||||
///
|
///
|
||||||
|
@ -170,7 +168,7 @@ pub trait DatabaseRw<T: Table>: DatabaseRo<T> {
|
||||||
#[doc = doc_database!()]
|
#[doc = doc_database!()]
|
||||||
///
|
///
|
||||||
/// This will never [`RuntimeError::KeyExists`].
|
/// This will never [`RuntimeError::KeyExists`].
|
||||||
fn delete(&mut self, key: &T::Key) -> Result<(), RuntimeError>;
|
fn delete(&mut self, key: &T::Key) -> DbResult<()>;
|
||||||
|
|
||||||
/// Delete and return a key-value pair in the database.
|
/// Delete and return a key-value pair in the database.
|
||||||
///
|
///
|
||||||
|
@ -178,7 +176,7 @@ pub trait DatabaseRw<T: Table>: DatabaseRo<T> {
|
||||||
/// it will serialize the `T::Value` and return it.
|
/// it will serialize the `T::Value` and return it.
|
||||||
///
|
///
|
||||||
#[doc = doc_database!()]
|
#[doc = doc_database!()]
|
||||||
fn take(&mut self, key: &T::Key) -> Result<T::Value, RuntimeError>;
|
fn take(&mut self, key: &T::Key) -> DbResult<T::Value>;
|
||||||
|
|
||||||
/// Fetch the value, and apply a function to it - or delete the entry.
|
/// Fetch the value, and apply a function to it - or delete the entry.
|
||||||
///
|
///
|
||||||
|
@ -192,7 +190,7 @@ pub trait DatabaseRw<T: Table>: DatabaseRo<T> {
|
||||||
/// - If `f` returns `None`, the entry will be [`DatabaseRw::delete`]d
|
/// - If `f` returns `None`, the entry will be [`DatabaseRw::delete`]d
|
||||||
///
|
///
|
||||||
#[doc = doc_database!()]
|
#[doc = doc_database!()]
|
||||||
fn update<F>(&mut self, key: &T::Key, mut f: F) -> Result<(), RuntimeError>
|
fn update<F>(&mut self, key: &T::Key, mut f: F) -> DbResult<()>
|
||||||
where
|
where
|
||||||
F: FnMut(T::Value) -> Option<T::Value>,
|
F: FnMut(T::Value) -> Option<T::Value>,
|
||||||
{
|
{
|
||||||
|
@ -207,10 +205,10 @@ pub trait DatabaseRw<T: Table>: DatabaseRo<T> {
|
||||||
/// Removes and returns the first `(key, value)` pair in the database.
|
/// Removes and returns the first `(key, value)` pair in the database.
|
||||||
///
|
///
|
||||||
#[doc = doc_database!()]
|
#[doc = doc_database!()]
|
||||||
fn pop_first(&mut self) -> Result<(T::Key, T::Value), RuntimeError>;
|
fn pop_first(&mut self) -> DbResult<(T::Key, T::Value)>;
|
||||||
|
|
||||||
/// Removes and returns the last `(key, value)` pair in the database.
|
/// Removes and returns the last `(key, value)` pair in the database.
|
||||||
///
|
///
|
||||||
#[doc = doc_database!()]
|
#[doc = doc_database!()]
|
||||||
fn pop_last(&mut self) -> Result<(T::Key, T::Value), RuntimeError>;
|
fn pop_last(&mut self) -> DbResult<(T::Key, T::Value)>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ use std::num::NonZeroUsize;
|
||||||
use crate::{
|
use crate::{
|
||||||
config::Config,
|
config::Config,
|
||||||
database::{DatabaseIter, DatabaseRo, DatabaseRw},
|
database::{DatabaseIter, DatabaseRo, DatabaseRw},
|
||||||
error::{InitError, RuntimeError},
|
error::{DbResult, InitError},
|
||||||
resize::ResizeAlgorithm,
|
resize::ResizeAlgorithm,
|
||||||
table::Table,
|
table::Table,
|
||||||
transaction::{TxRo, TxRw},
|
transaction::{TxRo, TxRw},
|
||||||
|
@ -39,7 +39,7 @@ pub trait Env: Sized {
|
||||||
///
|
///
|
||||||
/// # Invariant
|
/// # Invariant
|
||||||
/// If this is `false`, that means this [`Env`]
|
/// If this is `false`, that means this [`Env`]
|
||||||
/// must _never_ return a [`RuntimeError::ResizeNeeded`].
|
/// must _never_ return a [`crate::RuntimeError::ResizeNeeded`].
|
||||||
///
|
///
|
||||||
/// If this is `true`, [`Env::resize_map`] & [`Env::current_map_size`]
|
/// If this is `true`, [`Env::resize_map`] & [`Env::current_map_size`]
|
||||||
/// _must_ be re-implemented, as it just panics by default.
|
/// _must_ be re-implemented, as it just panics by default.
|
||||||
|
@ -88,7 +88,7 @@ pub trait Env: Sized {
|
||||||
/// This will error if the database file could not be opened.
|
/// This will error if the database file could not be opened.
|
||||||
///
|
///
|
||||||
/// This is the only [`Env`] function that will return
|
/// This is the only [`Env`] function that will return
|
||||||
/// an [`InitError`] instead of a [`RuntimeError`].
|
/// an [`InitError`] instead of a [`crate::RuntimeError`].
|
||||||
fn open(config: Config) -> Result<Self, InitError>;
|
fn open(config: Config) -> Result<Self, InitError>;
|
||||||
|
|
||||||
/// Return the [`Config`] that this database was [`Env::open`]ed with.
|
/// Return the [`Config`] that this database was [`Env::open`]ed with.
|
||||||
|
@ -107,7 +107,7 @@ pub trait Env: Sized {
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
/// If there is a synchronization error, this should return an error.
|
/// If there is a synchronization error, this should return an error.
|
||||||
fn sync(&self) -> Result<(), RuntimeError>;
|
fn sync(&self) -> DbResult<()>;
|
||||||
|
|
||||||
/// Resize the database's memory map to a
|
/// Resize the database's memory map to a
|
||||||
/// new (bigger) size using a [`ResizeAlgorithm`].
|
/// new (bigger) size using a [`ResizeAlgorithm`].
|
||||||
|
@ -218,14 +218,14 @@ pub trait EnvInner<'env> {
|
||||||
/// Create a read-only transaction.
|
/// Create a read-only transaction.
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
/// This will only return [`RuntimeError::Io`] if it errors.
|
/// This will only return [`crate::RuntimeError::Io`] if it errors.
|
||||||
fn tx_ro(&self) -> Result<Self::Ro<'_>, RuntimeError>;
|
fn tx_ro(&self) -> DbResult<Self::Ro<'_>>;
|
||||||
|
|
||||||
/// Create a read/write transaction.
|
/// Create a read/write transaction.
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
/// This will only return [`RuntimeError::Io`] if it errors.
|
/// This will only return [`crate::RuntimeError::Io`] if it errors.
|
||||||
fn tx_rw(&self) -> Result<Self::Rw<'_>, RuntimeError>;
|
fn tx_rw(&self) -> DbResult<Self::Rw<'_>>;
|
||||||
|
|
||||||
/// Open a database in read-only mode.
|
/// Open a database in read-only mode.
|
||||||
///
|
///
|
||||||
|
@ -269,17 +269,17 @@ pub trait EnvInner<'env> {
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
/// This will only return [`RuntimeError::Io`] on normal errors.
|
/// This will only return [`crate::RuntimeError::Io`] on normal errors.
|
||||||
///
|
///
|
||||||
/// If the specified table is not created upon before this function is called,
|
/// If the specified table is not created upon before this function is called,
|
||||||
/// this will return [`RuntimeError::TableNotFound`].
|
/// this will return [`crate::RuntimeError::TableNotFound`].
|
||||||
///
|
///
|
||||||
/// # Invariant
|
/// # Invariant
|
||||||
#[doc = doc_heed_create_db_invariant!()]
|
#[doc = doc_heed_create_db_invariant!()]
|
||||||
fn open_db_ro<T: Table>(
|
fn open_db_ro<T: Table>(
|
||||||
&self,
|
&self,
|
||||||
tx_ro: &Self::Ro<'_>,
|
tx_ro: &Self::Ro<'_>,
|
||||||
) -> Result<impl DatabaseRo<T> + DatabaseIter<T>, RuntimeError>;
|
) -> DbResult<impl DatabaseRo<T> + DatabaseIter<T>>;
|
||||||
|
|
||||||
/// Open a database in read/write mode.
|
/// Open a database in read/write mode.
|
||||||
///
|
///
|
||||||
|
@ -293,25 +293,22 @@ pub trait EnvInner<'env> {
|
||||||
/// passed as a generic to this function.
|
/// passed as a generic to this function.
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
/// This will only return [`RuntimeError::Io`] on errors.
|
/// This will only return [`crate::RuntimeError::Io`] on errors.
|
||||||
///
|
///
|
||||||
/// # Invariant
|
/// # Invariant
|
||||||
#[doc = doc_heed_create_db_invariant!()]
|
#[doc = doc_heed_create_db_invariant!()]
|
||||||
fn open_db_rw<T: Table>(
|
fn open_db_rw<T: Table>(&self, tx_rw: &Self::Rw<'_>) -> DbResult<impl DatabaseRw<T>>;
|
||||||
&self,
|
|
||||||
tx_rw: &Self::Rw<'_>,
|
|
||||||
) -> Result<impl DatabaseRw<T>, RuntimeError>;
|
|
||||||
|
|
||||||
/// Create a database table.
|
/// Create a database table.
|
||||||
///
|
///
|
||||||
/// This will create the database [`Table`] passed as a generic to this function.
|
/// This will create the database [`Table`] passed as a generic to this function.
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
/// This will only return [`RuntimeError::Io`] on errors.
|
/// This will only return [`crate::RuntimeError::Io`] on errors.
|
||||||
///
|
///
|
||||||
/// # Invariant
|
/// # Invariant
|
||||||
#[doc = doc_heed_create_db_invariant!()]
|
#[doc = doc_heed_create_db_invariant!()]
|
||||||
fn create_db<T: Table>(&self, tx_rw: &Self::Rw<'_>) -> Result<(), RuntimeError>;
|
fn create_db<T: Table>(&self, tx_rw: &Self::Rw<'_>) -> DbResult<()>;
|
||||||
|
|
||||||
/// Clear all `(key, value)`'s from a database table.
|
/// Clear all `(key, value)`'s from a database table.
|
||||||
///
|
///
|
||||||
|
@ -322,9 +319,9 @@ pub trait EnvInner<'env> {
|
||||||
/// function's effects can be aborted using [`TxRw::abort`].
|
/// function's effects can be aborted using [`TxRw::abort`].
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
/// This will return [`RuntimeError::Io`] on normal errors.
|
/// This will return [`crate::RuntimeError::Io`] on normal errors.
|
||||||
///
|
///
|
||||||
/// If the specified table is not created upon before this function is called,
|
/// If the specified table is not created upon before this function is called,
|
||||||
/// this will return [`RuntimeError::TableNotFound`].
|
/// this will return [`crate::RuntimeError::TableNotFound`].
|
||||||
fn clear_db<T: Table>(&self, tx_rw: &mut Self::Rw<'_>) -> Result<(), RuntimeError>;
|
fn clear_db<T: Table>(&self, tx_rw: &mut Self::Rw<'_>) -> DbResult<()>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,9 @@ use std::fmt::Debug;
|
||||||
/// Alias for a thread-safe boxed error.
|
/// Alias for a thread-safe boxed error.
|
||||||
type BoxError = Box<dyn std::error::Error + Send + Sync + 'static>;
|
type BoxError = Box<dyn std::error::Error + Send + Sync + 'static>;
|
||||||
|
|
||||||
|
/// [`Result`] with [`RuntimeError`] as the error.
|
||||||
|
pub type DbResult<T> = Result<T, RuntimeError>;
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- InitError
|
//---------------------------------------------------------------------------------------------------- InitError
|
||||||
/// Errors that occur during ([`Env::open`](crate::env::Env::open)).
|
/// Errors that occur during ([`Env::open`](crate::env::Env::open)).
|
||||||
///
|
///
|
||||||
|
|
|
@ -50,7 +50,7 @@ pub use constants::{
|
||||||
};
|
};
|
||||||
pub use database::{DatabaseIter, DatabaseRo, DatabaseRw};
|
pub use database::{DatabaseIter, DatabaseRo, DatabaseRw};
|
||||||
pub use env::{Env, EnvInner};
|
pub use env::{Env, EnvInner};
|
||||||
pub use error::{InitError, RuntimeError};
|
pub use error::{DbResult, InitError, RuntimeError};
|
||||||
pub use key::{Key, KeyCompare};
|
pub use key::{Key, KeyCompare};
|
||||||
pub use storable::{Storable, StorableBytes, StorableStr, StorableVec};
|
pub use storable::{Storable, StorableBytes, StorableStr, StorableVec};
|
||||||
pub use table::Table;
|
pub use table::Table;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
//! Database table abstraction; `trait Table`.
|
//! Database table abstraction; `trait Table`.
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Import
|
//---------------------------------------------------------------------------------------------------- Import
|
||||||
|
|
||||||
use crate::{key::Key, storable::Storable};
|
use crate::{key::Key, storable::Storable};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Table
|
//---------------------------------------------------------------------------------------------------- Table
|
||||||
|
|
|
@ -211,7 +211,7 @@ macro_rules! define_tables {
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
/// This returns errors on regular database errors.
|
/// This returns errors on regular database errors.
|
||||||
fn all_tables_empty(&self) -> Result<bool, $crate::RuntimeError>;
|
fn all_tables_empty(&self) -> $crate::DbResult<bool>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Object containing all opened [`Table`](cuprate_database::Table)s in read + iter mode.
|
/// Object containing all opened [`Table`](cuprate_database::Table)s in read + iter mode.
|
||||||
|
@ -293,7 +293,7 @@ macro_rules! define_tables {
|
||||||
}
|
}
|
||||||
)*
|
)*
|
||||||
|
|
||||||
fn all_tables_empty(&self) -> Result<bool, $crate::RuntimeError> {
|
fn all_tables_empty(&self) -> $crate::DbResult<bool> {
|
||||||
$(
|
$(
|
||||||
if !$crate::DatabaseRo::is_empty(&self.$index)? {
|
if !$crate::DatabaseRo::is_empty(&self.$index)? {
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
|
@ -369,7 +369,7 @@ macro_rules! define_tables {
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
/// This will only return [`cuprate_database::RuntimeError::Io`] if it errors.
|
/// This will only return [`cuprate_database::RuntimeError::Io`] if it errors.
|
||||||
fn open_tables(&self, tx_ro: &Self::Ro<'_>) -> Result<impl TablesIter, $crate::RuntimeError>;
|
fn open_tables(&self, tx_ro: &Self::Ro<'_>) -> $crate::DbResult<impl TablesIter>;
|
||||||
|
|
||||||
/// Open all tables in read-write mode.
|
/// Open all tables in read-write mode.
|
||||||
///
|
///
|
||||||
|
@ -378,7 +378,7 @@ macro_rules! define_tables {
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
/// This will only return [`cuprate_database::RuntimeError::Io`] on errors.
|
/// This will only return [`cuprate_database::RuntimeError::Io`] on errors.
|
||||||
fn open_tables_mut(&self, tx_rw: &Self::Rw<'_>) -> Result<impl TablesMut, $crate::RuntimeError>;
|
fn open_tables_mut(&self, tx_rw: &Self::Rw<'_>) -> $crate::DbResult<impl TablesMut>;
|
||||||
|
|
||||||
/// Create all database tables.
|
/// Create all database tables.
|
||||||
///
|
///
|
||||||
|
@ -386,7 +386,7 @@ macro_rules! define_tables {
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
/// This will only return [`cuprate_database::RuntimeError::Io`] on errors.
|
/// This will only return [`cuprate_database::RuntimeError::Io`] on errors.
|
||||||
fn create_tables(&self, tx_rw: &Self::Rw<'_>) -> Result<(), $crate::RuntimeError>;
|
fn create_tables(&self, tx_rw: &Self::Rw<'_>) -> $crate::DbResult<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'env, Ei> OpenTables<'env> for Ei
|
impl<'env, Ei> OpenTables<'env> for Ei
|
||||||
|
@ -396,19 +396,19 @@ macro_rules! define_tables {
|
||||||
type Ro<'tx> = <Ei as $crate::EnvInner<'env>>::Ro<'tx>;
|
type Ro<'tx> = <Ei as $crate::EnvInner<'env>>::Ro<'tx>;
|
||||||
type Rw<'tx> = <Ei as $crate::EnvInner<'env>>::Rw<'tx>;
|
type Rw<'tx> = <Ei as $crate::EnvInner<'env>>::Rw<'tx>;
|
||||||
|
|
||||||
fn open_tables(&self, tx_ro: &Self::Ro<'_>) -> Result<impl TablesIter, $crate::RuntimeError> {
|
fn open_tables(&self, tx_ro: &Self::Ro<'_>) -> $crate::DbResult<impl TablesIter> {
|
||||||
Ok(($(
|
Ok(($(
|
||||||
Self::open_db_ro::<[<$table:camel>]>(self, tx_ro)?,
|
Self::open_db_ro::<[<$table:camel>]>(self, tx_ro)?,
|
||||||
)*))
|
)*))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_tables_mut(&self, tx_rw: &Self::Rw<'_>) -> Result<impl TablesMut, $crate::RuntimeError> {
|
fn open_tables_mut(&self, tx_rw: &Self::Rw<'_>) -> $crate::DbResult<impl TablesMut> {
|
||||||
Ok(($(
|
Ok(($(
|
||||||
Self::open_db_rw::<[<$table:camel>]>(self, tx_rw)?,
|
Self::open_db_rw::<[<$table:camel>]>(self, tx_rw)?,
|
||||||
)*))
|
)*))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_tables(&self, tx_rw: &Self::Rw<'_>) -> Result<(), $crate::RuntimeError> {
|
fn create_tables(&self, tx_rw: &Self::Rw<'_>) -> $crate::DbResult<()> {
|
||||||
let result = Ok(($(
|
let result = Ok(($(
|
||||||
Self::create_db::<[<$table:camel>]>(self, tx_rw),
|
Self::create_db::<[<$table:camel>]>(self, tx_rw),
|
||||||
)*));
|
)*));
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//! Database transaction abstraction; `trait TxRo`, `trait TxRw`.
|
//! Database transaction abstraction; `trait TxRo`, `trait TxRw`.
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Import
|
//---------------------------------------------------------------------------------------------------- Import
|
||||||
use crate::error::RuntimeError;
|
use crate::error::DbResult;
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- TxRo
|
//---------------------------------------------------------------------------------------------------- TxRo
|
||||||
/// Read-only database transaction.
|
/// Read-only database transaction.
|
||||||
|
@ -16,7 +16,7 @@ pub trait TxRo<'tx> {
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
/// This operation will always return `Ok(())` with the `redb` backend.
|
/// This operation will always return `Ok(())` with the `redb` backend.
|
||||||
fn commit(self) -> Result<(), RuntimeError>;
|
fn commit(self) -> DbResult<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- TxRw
|
//---------------------------------------------------------------------------------------------------- TxRw
|
||||||
|
@ -32,12 +32,12 @@ pub trait TxRw<'tx> {
|
||||||
/// This operation will always return `Ok(())` with the `redb` backend.
|
/// This operation will always return `Ok(())` with the `redb` backend.
|
||||||
///
|
///
|
||||||
/// If `Env::MANUAL_RESIZE == true`,
|
/// If `Env::MANUAL_RESIZE == true`,
|
||||||
/// [`RuntimeError::ResizeNeeded`] may be returned.
|
/// [`crate::RuntimeError::ResizeNeeded`] may be returned.
|
||||||
fn commit(self) -> Result<(), RuntimeError>;
|
fn commit(self) -> DbResult<()>;
|
||||||
|
|
||||||
/// Abort the transaction, erasing any writes that have occurred.
|
/// Abort the transaction, erasing any writes that have occurred.
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
/// This operation will always return `Ok(())` with the `heed` backend.
|
/// This operation will always return `Ok(())` with the `heed` backend.
|
||||||
fn abort(self) -> Result<(), RuntimeError>;
|
fn abort(self) -> DbResult<()>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use futures::channel::oneshot;
|
||||||
use rayon::ThreadPool;
|
use rayon::ThreadPool;
|
||||||
use tower::Service;
|
use tower::Service;
|
||||||
|
|
||||||
use cuprate_database::{ConcreteEnv, RuntimeError};
|
use cuprate_database::{ConcreteEnv, DbResult, RuntimeError};
|
||||||
use cuprate_helper::asynch::InfallibleOneshotReceiver;
|
use cuprate_helper::asynch::InfallibleOneshotReceiver;
|
||||||
|
|
||||||
/// The [`rayon::ThreadPool`] service.
|
/// The [`rayon::ThreadPool`] service.
|
||||||
|
@ -24,7 +24,7 @@ pub struct DatabaseReadService<Req, Res> {
|
||||||
pool: Arc<ThreadPool>,
|
pool: Arc<ThreadPool>,
|
||||||
|
|
||||||
/// The function used to handle request.
|
/// The function used to handle request.
|
||||||
inner_handler: Arc<dyn Fn(Req) -> Result<Res, RuntimeError> + Send + Sync + 'static>,
|
inner_handler: Arc<dyn Fn(Req) -> DbResult<Res> + Send + Sync + 'static>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deriving [`Clone`] means `Req` & `Res` need to be `Clone`, even if they aren't.
|
// Deriving [`Clone`] means `Req` & `Res` need to be `Clone`, even if they aren't.
|
||||||
|
@ -51,7 +51,7 @@ where
|
||||||
pub fn new(
|
pub fn new(
|
||||||
env: Arc<ConcreteEnv>,
|
env: Arc<ConcreteEnv>,
|
||||||
pool: Arc<ThreadPool>,
|
pool: Arc<ThreadPool>,
|
||||||
req_handler: impl Fn(&ConcreteEnv, Req) -> Result<Res, RuntimeError> + Send + Sync + 'static,
|
req_handler: impl Fn(&ConcreteEnv, Req) -> DbResult<Res> + Send + Sync + 'static,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let inner_handler = Arc::new(move |req| req_handler(&env, req));
|
let inner_handler = Arc::new(move |req| req_handler(&env, req));
|
||||||
|
|
||||||
|
@ -69,9 +69,9 @@ where
|
||||||
{
|
{
|
||||||
type Response = Res;
|
type Response = Res;
|
||||||
type Error = RuntimeError;
|
type Error = RuntimeError;
|
||||||
type Future = InfallibleOneshotReceiver<Result<Self::Response, Self::Error>>;
|
type Future = InfallibleOneshotReceiver<DbResult<Self::Response>>;
|
||||||
|
|
||||||
fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll<DbResult<()>> {
|
||||||
Poll::Ready(Ok(()))
|
Poll::Ready(Ok(()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ use std::{
|
||||||
|
|
||||||
use futures::channel::oneshot;
|
use futures::channel::oneshot;
|
||||||
|
|
||||||
use cuprate_database::{ConcreteEnv, Env, RuntimeError};
|
use cuprate_database::{ConcreteEnv, DbResult, Env, RuntimeError};
|
||||||
use cuprate_helper::asynch::InfallibleOneshotReceiver;
|
use cuprate_helper::asynch::InfallibleOneshotReceiver;
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Constants
|
//---------------------------------------------------------------------------------------------------- Constants
|
||||||
|
@ -26,8 +26,7 @@ pub struct DatabaseWriteHandle<Req, Res> {
|
||||||
/// Sender channel to the database write thread-pool.
|
/// Sender channel to the database write thread-pool.
|
||||||
///
|
///
|
||||||
/// We provide the response channel for the thread-pool.
|
/// We provide the response channel for the thread-pool.
|
||||||
pub(super) sender:
|
pub(super) sender: crossbeam::channel::Sender<(Req, oneshot::Sender<DbResult<Res>>)>,
|
||||||
crossbeam::channel::Sender<(Req, oneshot::Sender<Result<Res, RuntimeError>>)>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Req, Res> Clone for DatabaseWriteHandle<Req, Res> {
|
impl<Req, Res> Clone for DatabaseWriteHandle<Req, Res> {
|
||||||
|
@ -48,7 +47,7 @@ where
|
||||||
#[inline(never)] // Only called once.
|
#[inline(never)] // Only called once.
|
||||||
pub fn init(
|
pub fn init(
|
||||||
env: Arc<ConcreteEnv>,
|
env: Arc<ConcreteEnv>,
|
||||||
inner_handler: impl Fn(&ConcreteEnv, &Req) -> Result<Res, RuntimeError> + Send + 'static,
|
inner_handler: impl Fn(&ConcreteEnv, &Req) -> DbResult<Res> + Send + 'static,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
// Initialize `Request/Response` channels.
|
// Initialize `Request/Response` channels.
|
||||||
let (sender, receiver) = crossbeam::channel::unbounded();
|
let (sender, receiver) = crossbeam::channel::unbounded();
|
||||||
|
@ -66,10 +65,10 @@ where
|
||||||
impl<Req, Res> tower::Service<Req> for DatabaseWriteHandle<Req, Res> {
|
impl<Req, Res> tower::Service<Req> for DatabaseWriteHandle<Req, Res> {
|
||||||
type Response = Res;
|
type Response = Res;
|
||||||
type Error = RuntimeError;
|
type Error = RuntimeError;
|
||||||
type Future = InfallibleOneshotReceiver<Result<Res, RuntimeError>>;
|
type Future = InfallibleOneshotReceiver<DbResult<Res>>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll<DbResult<()>> {
|
||||||
Poll::Ready(Ok(()))
|
Poll::Ready(Ok(()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,8 +88,8 @@ impl<Req, Res> tower::Service<Req> for DatabaseWriteHandle<Req, Res> {
|
||||||
/// The main function of the writer thread.
|
/// The main function of the writer thread.
|
||||||
fn database_writer<Req, Res>(
|
fn database_writer<Req, Res>(
|
||||||
env: &ConcreteEnv,
|
env: &ConcreteEnv,
|
||||||
receiver: &crossbeam::channel::Receiver<(Req, oneshot::Sender<Result<Res, RuntimeError>>)>,
|
receiver: &crossbeam::channel::Receiver<(Req, oneshot::Sender<DbResult<Res>>)>,
|
||||||
inner_handler: impl Fn(&ConcreteEnv, &Req) -> Result<Res, RuntimeError>,
|
inner_handler: impl Fn(&ConcreteEnv, &Req) -> DbResult<Res>,
|
||||||
) where
|
) where
|
||||||
Req: Send + 'static,
|
Req: Send + 'static,
|
||||||
Res: Debug + Send + 'static,
|
Res: Debug + Send + 'static,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//! Tx-pool key image ops.
|
//! Tx-pool key image ops.
|
||||||
use monero_serai::transaction::Input;
|
use monero_serai::transaction::Input;
|
||||||
|
|
||||||
use cuprate_database::{DatabaseRw, RuntimeError};
|
use cuprate_database::{DatabaseRw, DbResult};
|
||||||
|
|
||||||
use crate::{ops::TxPoolWriteError, tables::SpentKeyImages, types::TransactionHash};
|
use crate::{ops::TxPoolWriteError, tables::SpentKeyImages, types::TransactionHash};
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ pub(super) fn add_tx_key_images(
|
||||||
pub(super) fn remove_tx_key_images(
|
pub(super) fn remove_tx_key_images(
|
||||||
inputs: &[Input],
|
inputs: &[Input],
|
||||||
kis_table: &mut impl DatabaseRw<SpentKeyImages>,
|
kis_table: &mut impl DatabaseRw<SpentKeyImages>,
|
||||||
) -> Result<(), RuntimeError> {
|
) -> DbResult<()> {
|
||||||
for ki in inputs.iter().map(ki_from_input) {
|
for ki in inputs.iter().map(ki_from_input) {
|
||||||
kis_table.delete(&ki)?;
|
kis_table.delete(&ki)?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use std::sync::Mutex;
|
||||||
|
|
||||||
use monero_serai::transaction::Transaction;
|
use monero_serai::transaction::Transaction;
|
||||||
|
|
||||||
use cuprate_database::{DatabaseRo, RuntimeError};
|
use cuprate_database::{DatabaseRo, DbResult};
|
||||||
use cuprate_types::{TransactionVerificationData, TxVersion};
|
use cuprate_types::{TransactionVerificationData, TxVersion};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -17,7 +17,7 @@ use crate::{
|
||||||
pub fn get_transaction_verification_data(
|
pub fn get_transaction_verification_data(
|
||||||
tx_hash: &TransactionHash,
|
tx_hash: &TransactionHash,
|
||||||
tables: &impl Tables,
|
tables: &impl Tables,
|
||||||
) -> Result<TransactionVerificationData, RuntimeError> {
|
) -> DbResult<TransactionVerificationData> {
|
||||||
let tx_blob = tables.transaction_blobs().get(tx_hash)?.0;
|
let tx_blob = tables.transaction_blobs().get(tx_hash)?.0;
|
||||||
|
|
||||||
let tx_info = tables.transaction_infos().get(tx_hash)?;
|
let tx_info = tables.transaction_infos().get(tx_hash)?;
|
||||||
|
@ -45,7 +45,7 @@ pub fn get_transaction_verification_data(
|
||||||
pub fn in_stem_pool(
|
pub fn in_stem_pool(
|
||||||
tx_hash: &TransactionHash,
|
tx_hash: &TransactionHash,
|
||||||
tx_infos: &impl DatabaseRo<TransactionInfos>,
|
tx_infos: &impl DatabaseRo<TransactionInfos>,
|
||||||
) -> Result<bool, RuntimeError> {
|
) -> DbResult<bool> {
|
||||||
Ok(tx_infos
|
Ok(tx_infos
|
||||||
.get(tx_hash)?
|
.get(tx_hash)?
|
||||||
.flags
|
.flags
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
use bytemuck::TransparentWrapper;
|
use bytemuck::TransparentWrapper;
|
||||||
use monero_serai::transaction::{NotPruned, Transaction};
|
use monero_serai::transaction::{NotPruned, Transaction};
|
||||||
|
|
||||||
use cuprate_database::{DatabaseRw, RuntimeError, StorableVec};
|
use cuprate_database::{DatabaseRw, DbResult, StorableVec};
|
||||||
use cuprate_types::TransactionVerificationData;
|
use cuprate_types::TransactionVerificationData;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -67,10 +67,7 @@ pub fn add_transaction(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes a transaction from the transaction pool.
|
/// Removes a transaction from the transaction pool.
|
||||||
pub fn remove_transaction(
|
pub fn remove_transaction(tx_hash: &TransactionHash, tables: &mut impl TablesMut) -> DbResult<()> {
|
||||||
tx_hash: &TransactionHash,
|
|
||||||
tables: &mut impl TablesMut,
|
|
||||||
) -> Result<(), RuntimeError> {
|
|
||||||
// Remove the tx blob from table 0.
|
// Remove the tx blob from table 0.
|
||||||
let tx_blob = tables.transaction_blobs_mut().take(tx_hash)?.0;
|
let tx_blob = tables.transaction_blobs_mut().take(tx_hash)?.0;
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ use std::{
|
||||||
|
|
||||||
use rayon::ThreadPool;
|
use rayon::ThreadPool;
|
||||||
|
|
||||||
use cuprate_database::{ConcreteEnv, DatabaseRo, Env, EnvInner, RuntimeError};
|
use cuprate_database::{ConcreteEnv, DatabaseRo, DbResult, Env, EnvInner, RuntimeError};
|
||||||
use cuprate_database_service::{init_thread_pool, DatabaseReadService, ReaderThreads};
|
use cuprate_database_service::{init_thread_pool, DatabaseReadService, ReaderThreads};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -137,7 +137,7 @@ fn filter_known_tx_blob_hashes(
|
||||||
|
|
||||||
// A closure that returns `true` if a tx with a certain blob hash is unknown.
|
// A closure that returns `true` if a tx with a certain blob hash is unknown.
|
||||||
// This also fills in `stem_tx_hashes`.
|
// This also fills in `stem_tx_hashes`.
|
||||||
let mut tx_unknown = |blob_hash| -> Result<bool, RuntimeError> {
|
let mut tx_unknown = |blob_hash| -> DbResult<bool> {
|
||||||
match tx_blob_hashes.get(&blob_hash) {
|
match tx_blob_hashes.get(&blob_hash) {
|
||||||
Ok(tx_hash) => {
|
Ok(tx_hash) => {
|
||||||
if in_stem_pool(&tx_hash, &tx_infos)? {
|
if in_stem_pool(&tx_hash, &tx_infos)? {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
//!
|
//!
|
||||||
//! Only used internally for our [`tower::Service`] impls.
|
//! Only used internally for our [`tower::Service`] impls.
|
||||||
|
|
||||||
use cuprate_database::RuntimeError;
|
use cuprate_database::DbResult;
|
||||||
use cuprate_database_service::{DatabaseReadService, DatabaseWriteHandle};
|
use cuprate_database_service::{DatabaseReadService, DatabaseWriteHandle};
|
||||||
|
|
||||||
use crate::service::interface::{
|
use crate::service::interface::{
|
||||||
|
@ -12,7 +12,7 @@ use crate::service::interface::{
|
||||||
/// The actual type of the response.
|
/// The actual type of the response.
|
||||||
///
|
///
|
||||||
/// Either our [`TxpoolReadResponse`], or a database error occurred.
|
/// Either our [`TxpoolReadResponse`], or a database error occurred.
|
||||||
pub(super) type ReadResponseResult = Result<TxpoolReadResponse, RuntimeError>;
|
pub(super) type ReadResponseResult = DbResult<TxpoolReadResponse>;
|
||||||
|
|
||||||
/// The transaction pool database write service.
|
/// The transaction pool database write service.
|
||||||
pub type TxpoolWriteHandle = DatabaseWriteHandle<TxpoolWriteRequest, TxpoolWriteResponse>;
|
pub type TxpoolWriteHandle = DatabaseWriteHandle<TxpoolWriteRequest, TxpoolWriteResponse>;
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use cuprate_database::{ConcreteEnv, DatabaseRo, DatabaseRw, Env, EnvInner, RuntimeError, TxRw};
|
use cuprate_database::{
|
||||||
|
ConcreteEnv, DatabaseRo, DatabaseRw, DbResult, Env, EnvInner, RuntimeError, TxRw,
|
||||||
|
};
|
||||||
use cuprate_database_service::DatabaseWriteHandle;
|
use cuprate_database_service::DatabaseWriteHandle;
|
||||||
use cuprate_types::TransactionVerificationData;
|
use cuprate_types::TransactionVerificationData;
|
||||||
|
|
||||||
|
@ -25,7 +27,7 @@ pub(super) fn init_write_service(env: Arc<ConcreteEnv>) -> TxpoolWriteHandle {
|
||||||
fn handle_txpool_request(
|
fn handle_txpool_request(
|
||||||
env: &ConcreteEnv,
|
env: &ConcreteEnv,
|
||||||
req: &TxpoolWriteRequest,
|
req: &TxpoolWriteRequest,
|
||||||
) -> Result<TxpoolWriteResponse, RuntimeError> {
|
) -> DbResult<TxpoolWriteResponse> {
|
||||||
match req {
|
match req {
|
||||||
TxpoolWriteRequest::AddTransaction { tx, state_stem } => {
|
TxpoolWriteRequest::AddTransaction { tx, state_stem } => {
|
||||||
add_transaction(env, tx, *state_stem)
|
add_transaction(env, tx, *state_stem)
|
||||||
|
@ -50,7 +52,7 @@ fn add_transaction(
|
||||||
env: &ConcreteEnv,
|
env: &ConcreteEnv,
|
||||||
tx: &TransactionVerificationData,
|
tx: &TransactionVerificationData,
|
||||||
state_stem: bool,
|
state_stem: bool,
|
||||||
) -> Result<TxpoolWriteResponse, RuntimeError> {
|
) -> DbResult<TxpoolWriteResponse> {
|
||||||
let env_inner = env.env_inner();
|
let env_inner = env.env_inner();
|
||||||
let tx_rw = env_inner.tx_rw()?;
|
let tx_rw = env_inner.tx_rw()?;
|
||||||
|
|
||||||
|
@ -83,7 +85,7 @@ fn add_transaction(
|
||||||
fn remove_transaction(
|
fn remove_transaction(
|
||||||
env: &ConcreteEnv,
|
env: &ConcreteEnv,
|
||||||
tx_hash: &TransactionHash,
|
tx_hash: &TransactionHash,
|
||||||
) -> Result<TxpoolWriteResponse, RuntimeError> {
|
) -> DbResult<TxpoolWriteResponse> {
|
||||||
let env_inner = env.env_inner();
|
let env_inner = env.env_inner();
|
||||||
let tx_rw = env_inner.tx_rw()?;
|
let tx_rw = env_inner.tx_rw()?;
|
||||||
|
|
||||||
|
@ -105,10 +107,7 @@ fn remove_transaction(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`TxpoolWriteRequest::Promote`]
|
/// [`TxpoolWriteRequest::Promote`]
|
||||||
fn promote(
|
fn promote(env: &ConcreteEnv, tx_hash: &TransactionHash) -> DbResult<TxpoolWriteResponse> {
|
||||||
env: &ConcreteEnv,
|
|
||||||
tx_hash: &TransactionHash,
|
|
||||||
) -> Result<TxpoolWriteResponse, RuntimeError> {
|
|
||||||
let env_inner = env.env_inner();
|
let env_inner = env.env_inner();
|
||||||
let tx_rw = env_inner.tx_rw()?;
|
let tx_rw = env_inner.tx_rw()?;
|
||||||
|
|
||||||
|
@ -134,10 +133,7 @@ fn promote(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`TxpoolWriteRequest::NewBlock`]
|
/// [`TxpoolWriteRequest::NewBlock`]
|
||||||
fn new_block(
|
fn new_block(env: &ConcreteEnv, spent_key_images: &[KeyImage]) -> DbResult<TxpoolWriteResponse> {
|
||||||
env: &ConcreteEnv,
|
|
||||||
spent_key_images: &[KeyImage],
|
|
||||||
) -> Result<TxpoolWriteResponse, RuntimeError> {
|
|
||||||
let env_inner = env.env_inner();
|
let env_inner = env.env_inner();
|
||||||
let tx_rw = env_inner.tx_rw()?;
|
let tx_rw = env_inner.tx_rw()?;
|
||||||
|
|
||||||
|
|
|
@ -104,7 +104,7 @@ macro_rules! const_tx_blob {
|
||||||
hash: $hash:literal, // Transaction hash
|
hash: $hash:literal, // Transaction hash
|
||||||
data_path: $data_path:literal, // Path to the transaction blob
|
data_path: $data_path:literal, // Path to the transaction blob
|
||||||
version: $version:literal, // Transaction version
|
version: $version:literal, // Transaction version
|
||||||
timelock: $timelock:expr, // Transaction's timelock (use the real type `Timelock`)
|
timelock: $timelock:expr_2021, // Transaction's timelock (use the real type `Timelock`)
|
||||||
input_len: $input_len:literal, // Amount of inputs
|
input_len: $input_len:literal, // Amount of inputs
|
||||||
output_len: $output_len:literal, // Amount of outputs
|
output_len: $output_len:literal, // Amount of outputs
|
||||||
) => {
|
) => {
|
||||||
|
|
|
@ -25,11 +25,11 @@ macro_rules! define_request_and_response {
|
||||||
|
|
||||||
// The request type (and any doc comments, derives, etc).
|
// The request type (and any doc comments, derives, etc).
|
||||||
$( #[$request_attr:meta] )*
|
$( #[$request_attr:meta] )*
|
||||||
Request = $request:expr;
|
Request = $request:expr_2021;
|
||||||
|
|
||||||
// The response type (and any doc comments, derives, etc).
|
// The response type (and any doc comments, derives, etc).
|
||||||
$( #[$response_attr:meta] )*
|
$( #[$response_attr:meta] )*
|
||||||
Response = $response:expr;
|
Response = $response:expr_2021;
|
||||||
) => { paste::paste! {
|
) => { paste::paste! {
|
||||||
#[doc = $crate::rpc::data::macros::define_request_and_response_doc!(
|
#[doc = $crate::rpc::data::macros::define_request_and_response_doc!(
|
||||||
"response" => [<$name:upper _RESPONSE>],
|
"response" => [<$name:upper _RESPONSE>],
|
||||||
|
|
Loading…
Reference in a new issue