2024-06-04 17:19:35 +00:00
|
|
|
//! Database [`BCReadRequest`]s, [`BCWriteRequest`]s, and [`BCResponse`]s.
|
2024-05-05 14:21:28 +00:00
|
|
|
//!
|
|
|
|
//! Tests that assert particular requests lead to particular
|
2024-06-04 17:19:35 +00:00
|
|
|
//! responses are also tested in Cuprate's blockchain database crate.
|
2024-03-27 00:46:32 +00:00
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------- Import
|
|
|
|
use std::{
|
|
|
|
collections::{HashMap, HashSet},
|
|
|
|
ops::Range,
|
|
|
|
};
|
|
|
|
|
|
|
|
#[cfg(feature = "borsh")]
|
|
|
|
use borsh::{BorshDeserialize, BorshSerialize};
|
|
|
|
#[cfg(feature = "serde")]
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
|
|
|
|
use crate::types::{ExtendedBlockHeader, OutputOnChain, VerifiedBlockInformation};
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------- ReadRequest
|
2024-06-04 17:19:35 +00:00
|
|
|
/// A read request to the blockchain database.
|
2024-05-05 14:21:28 +00:00
|
|
|
///
|
2024-06-04 17:19:35 +00:00
|
|
|
/// This pairs with [`BCResponse`], where each variant here
|
|
|
|
/// matches in name with a [`BCResponse`] variant. For example,
|
|
|
|
/// the proper response for a [`BCReadRequest::BlockHash`]
|
|
|
|
/// would be a [`BCResponse::BlockHash`].
|
2024-05-05 14:21:28 +00:00
|
|
|
///
|
|
|
|
/// See `Response` for the expected responses per `Request`.
|
2024-03-27 00:46:32 +00:00
|
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
2024-06-04 17:19:35 +00:00
|
|
|
pub enum BCReadRequest {
|
2024-05-05 14:21:28 +00:00
|
|
|
/// Request a block's extended header.
|
|
|
|
///
|
|
|
|
/// The input is the block's height.
|
2024-03-27 00:46:32 +00:00
|
|
|
BlockExtendedHeader(u64),
|
2024-05-05 14:21:28 +00:00
|
|
|
|
|
|
|
/// Request a block's hash.
|
|
|
|
///
|
|
|
|
/// The input is the block's height.
|
2024-03-27 00:46:32 +00:00
|
|
|
BlockHash(u64),
|
2024-05-05 14:21:28 +00:00
|
|
|
|
2024-06-04 17:19:35 +00:00
|
|
|
/// Removes the block hashes that are not in the _main_ chain.
|
|
|
|
///
|
|
|
|
/// This should filter (remove) hashes in alt-blocks as well.
|
|
|
|
FilterUnknownHashes(HashSet<[u8; 32]>),
|
|
|
|
|
2024-05-05 14:21:28 +00:00
|
|
|
/// Request a range of block extended headers.
|
|
|
|
///
|
|
|
|
/// The input is a range of block heights.
|
2024-03-27 00:46:32 +00:00
|
|
|
BlockExtendedHeaderInRange(Range<u64>),
|
2024-05-05 14:21:28 +00:00
|
|
|
|
|
|
|
/// Request the current chain height.
|
|
|
|
///
|
|
|
|
/// Note that this is not the top-block height.
|
2024-03-27 00:46:32 +00:00
|
|
|
ChainHeight,
|
2024-05-05 14:21:28 +00:00
|
|
|
|
|
|
|
/// Request the total amount of generated coins (atomic units) so far.
|
2024-03-27 00:46:32 +00:00
|
|
|
GeneratedCoins,
|
2024-05-05 14:21:28 +00:00
|
|
|
|
|
|
|
/// Request data for multiple outputs.
|
|
|
|
///
|
|
|
|
/// The input is a `HashMap` where:
|
|
|
|
/// - Key = output amount
|
|
|
|
/// - Value = set of amount indices
|
|
|
|
///
|
|
|
|
/// For pre-RCT outputs, the amount is non-zero,
|
|
|
|
/// and the amount indices represent the wanted
|
|
|
|
/// indices of duplicate amount outputs, i.e.:
|
|
|
|
///
|
|
|
|
/// ```ignore
|
|
|
|
/// // list of outputs with amount 10
|
|
|
|
/// [0, 1, 2, 3, 4, 5]
|
|
|
|
/// // ^ ^
|
|
|
|
/// // we only want these two, so we would provide
|
|
|
|
/// // `amount: 10, amount_index: {1, 3}`
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// For RCT outputs, the amounts would be `0` and
|
|
|
|
/// the amount indices would represent the global
|
|
|
|
/// RCT output indices.
|
2024-03-27 00:46:32 +00:00
|
|
|
Outputs(HashMap<u64, HashSet<u64>>),
|
2024-05-05 14:21:28 +00:00
|
|
|
|
|
|
|
/// Request the amount of outputs with a certain amount.
|
|
|
|
///
|
|
|
|
/// The input is a list of output amounts.
|
2024-03-27 00:46:32 +00:00
|
|
|
NumberOutputsWithAmount(Vec<u64>),
|
2024-05-05 14:21:28 +00:00
|
|
|
|
|
|
|
/// Check that all key images within a set arer not spent.
|
|
|
|
///
|
|
|
|
/// Input is a set of key images.
|
2024-06-04 17:19:35 +00:00
|
|
|
KeyImagesSpent(HashSet<[u8; 32]>),
|
2024-03-27 00:46:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------- WriteRequest
|
2024-06-04 17:19:35 +00:00
|
|
|
/// A write request to the blockchain database.
|
2024-05-05 14:21:28 +00:00
|
|
|
///
|
|
|
|
/// There is currently only 1 write request to the database,
|
2024-06-04 17:19:35 +00:00
|
|
|
/// as such, the only valid [`BCResponse`] to this request is
|
|
|
|
/// the proper response for a [`BCResponse::WriteBlockOk`].
|
2024-03-27 00:46:32 +00:00
|
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
2024-06-04 17:19:35 +00:00
|
|
|
pub enum BCWriteRequest {
|
2024-05-05 14:21:28 +00:00
|
|
|
/// Request that a block be written to the database.
|
|
|
|
///
|
|
|
|
/// Input is an already verified block.
|
2024-03-27 00:46:32 +00:00
|
|
|
WriteBlock(VerifiedBlockInformation),
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------- Response
|
|
|
|
/// A response from the database.
|
2024-05-05 14:21:28 +00:00
|
|
|
///
|
|
|
|
/// These are the data types returned when using sending a `Request`.
|
|
|
|
///
|
2024-06-04 17:19:35 +00:00
|
|
|
/// This pairs with [`BCReadRequest`] and [`BCWriteRequest`],
|
2024-05-05 14:21:28 +00:00
|
|
|
/// see those two for more info.
|
2024-03-27 00:46:32 +00:00
|
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
2024-06-04 17:19:35 +00:00
|
|
|
pub enum BCResponse {
|
2024-03-27 00:46:32 +00:00
|
|
|
//------------------------------------------------------ Reads
|
2024-06-04 17:19:35 +00:00
|
|
|
/// Response to [`BCReadRequest::BlockExtendedHeader`].
|
2024-05-05 14:21:28 +00:00
|
|
|
///
|
|
|
|
/// Inner value is the extended headed of the requested block.
|
2024-03-27 00:46:32 +00:00
|
|
|
BlockExtendedHeader(ExtendedBlockHeader),
|
2024-05-05 14:21:28 +00:00
|
|
|
|
2024-06-04 17:19:35 +00:00
|
|
|
/// Response to [`BCReadRequest::BlockHash`].
|
2024-05-05 14:21:28 +00:00
|
|
|
///
|
|
|
|
/// Inner value is the hash of the requested block.
|
2024-03-27 00:46:32 +00:00
|
|
|
BlockHash([u8; 32]),
|
2024-05-05 14:21:28 +00:00
|
|
|
|
2024-06-04 17:19:35 +00:00
|
|
|
/// Response to [`BCReadRequest::FilterUnknownHashes`].
|
|
|
|
///
|
|
|
|
/// Inner value is the list of hashes that were in the main chain.
|
|
|
|
FilterUnknownHashes(HashSet<[u8; 32]>),
|
|
|
|
|
|
|
|
/// Response to [`BCReadRequest::BlockExtendedHeaderInRange`].
|
2024-05-05 14:21:28 +00:00
|
|
|
///
|
|
|
|
/// Inner value is the list of extended header(s) of the requested block(s).
|
2024-03-27 00:46:32 +00:00
|
|
|
BlockExtendedHeaderInRange(Vec<ExtendedBlockHeader>),
|
2024-05-05 14:21:28 +00:00
|
|
|
|
2024-06-04 17:19:35 +00:00
|
|
|
/// Response to [`BCReadRequest::ChainHeight`].
|
2024-05-05 14:21:28 +00:00
|
|
|
///
|
|
|
|
/// Inner value is the chain height, and the top block's hash.
|
2024-03-27 00:46:32 +00:00
|
|
|
ChainHeight(u64, [u8; 32]),
|
2024-05-05 14:21:28 +00:00
|
|
|
|
2024-06-04 17:19:35 +00:00
|
|
|
/// Response to [`BCReadRequest::GeneratedCoins`].
|
2024-05-05 14:21:28 +00:00
|
|
|
///
|
|
|
|
/// Inner value is the total amount of generated coins so far, in atomic units.
|
2024-03-27 00:46:32 +00:00
|
|
|
GeneratedCoins(u64),
|
2024-05-05 14:21:28 +00:00
|
|
|
|
2024-06-04 17:19:35 +00:00
|
|
|
/// Response to [`BCReadRequest::Outputs`].
|
2024-05-05 14:21:28 +00:00
|
|
|
///
|
|
|
|
/// Inner value is all the outputs requested,
|
|
|
|
/// associated with their amount and amount index.
|
2024-03-27 00:46:32 +00:00
|
|
|
Outputs(HashMap<u64, HashMap<u64, OutputOnChain>>),
|
2024-05-05 14:21:28 +00:00
|
|
|
|
2024-06-04 17:19:35 +00:00
|
|
|
/// Response to [`BCReadRequest::NumberOutputsWithAmount`].
|
2024-05-05 14:21:28 +00:00
|
|
|
///
|
|
|
|
/// Inner value is a `HashMap` of all the outputs requested where:
|
|
|
|
/// - Key = output amount
|
|
|
|
/// - Value = count of outputs with the same amount
|
2024-03-27 00:46:32 +00:00
|
|
|
NumberOutputsWithAmount(HashMap<u64, usize>),
|
2024-05-05 14:21:28 +00:00
|
|
|
|
2024-06-04 17:19:35 +00:00
|
|
|
/// Response to [`BCReadRequest::KeyImagesSpent`].
|
2024-05-05 14:21:28 +00:00
|
|
|
///
|
|
|
|
/// The inner value is `true` if _any_ of the key images
|
2024-06-04 17:19:35 +00:00
|
|
|
/// were spent (existed in the database already).
|
2024-05-05 14:21:28 +00:00
|
|
|
///
|
|
|
|
/// The inner value is `false` if _none_ of the key images were spent.
|
2024-06-04 17:19:35 +00:00
|
|
|
KeyImagesSpent(bool),
|
2024-03-27 00:46:32 +00:00
|
|
|
|
|
|
|
//------------------------------------------------------ Writes
|
2024-06-04 17:19:35 +00:00
|
|
|
/// Response to [`BCWriteRequest::WriteBlock`].
|
2024-05-05 14:21:28 +00:00
|
|
|
///
|
|
|
|
/// This response indicates that the requested block has
|
|
|
|
/// successfully been written to the database without error.
|
2024-03-27 00:46:32 +00:00
|
|
|
WriteBlockOk,
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------- Tests
|
|
|
|
#[cfg(test)]
|
|
|
|
mod test {
|
|
|
|
// use super::*;
|
|
|
|
}
|