From ff30738425f1cbd0cc4e338ce2ea694976d95866 Mon Sep 17 00:00:00 2001 From: Boog900 <54e72d8a-345f-4599-bd90-c6b9bc7d0ec5@aleeas.com> Date: Mon, 12 Aug 2024 22:46:37 +0100 Subject: [PATCH] add more docs --- storage/blockchain/src/constants.rs | 15 --- storage/blockchain/src/lib.rs | 2 +- storage/txpool/Cargo.toml | 49 ++++++---- storage/txpool/README.md | 124 ++++++++++++++++++++++++ storage/txpool/src/config.rs | 27 +++--- storage/txpool/src/free.rs | 2 +- storage/txpool/src/lib.rs | 7 +- storage/txpool/src/ops.rs | 86 +++++++++++++++- storage/txpool/src/ops/key_images.rs | 3 +- storage/txpool/src/ops/tx_write.rs | 11 ++- storage/txpool/src/service.rs | 6 +- storage/txpool/src/service/interface.rs | 27 +++++- storage/txpool/src/tables.rs | 30 +++++- storage/txpool/src/types.rs | 13 ++- 14 files changed, 338 insertions(+), 64 deletions(-) create mode 100644 storage/txpool/README.md diff --git a/storage/blockchain/src/constants.rs b/storage/blockchain/src/constants.rs index 7f00d4cd8..872688580 100644 --- a/storage/blockchain/src/constants.rs +++ b/storage/blockchain/src/constants.rs @@ -14,21 +14,6 @@ /// pub const DATABASE_VERSION: u64 = 0; -//---------------------------------------------------------------------------------------------------- Error Messages -/// Corrupt database error message. -/// -/// The error message shown to end-users in panic -/// messages if we think the database is corrupted. -/// -/// This is meant to be user-friendly. -pub const DATABASE_CORRUPT_MSG: &str = r"Cuprate has encountered a fatal error. The database may be corrupted. - -TODO: instructions on: -1. What to do -2. How to fix (re-sync, recover, etc) -3. General advice for preventing corruption -4. etc"; - //---------------------------------------------------------------------------------------------------- Tests #[cfg(test)] mod test {} diff --git a/storage/blockchain/src/lib.rs b/storage/blockchain/src/lib.rs index 9db0862a1..93ecd1b30 100644 --- a/storage/blockchain/src/lib.rs +++ b/storage/blockchain/src/lib.rs @@ -117,7 +117,7 @@ compile_error!("Cuprate is only compatible with 64-bit CPUs"); mod constants; mod free; -pub use constants::{DATABASE_CORRUPT_MSG, DATABASE_VERSION}; +pub use constants::DATABASE_VERSION; pub use cuprate_database; pub use free::open; diff --git a/storage/txpool/Cargo.toml b/storage/txpool/Cargo.toml index 8d56542cd..0ab0bd778 100644 --- a/storage/txpool/Cargo.toml +++ b/storage/txpool/Cargo.toml @@ -1,35 +1,42 @@ [package] -name = "cuprate-txpool" -version = "0.0.0" -edition = "2021" +name = "cuprate-txpool" +version = "0.0.0" +edition = "2021" description = "Cuprate's transaction pool database" -license = "MIT" -authors = ["Boog900"] -repository = "https://github.com/Cuprate/cuprate/tree/main/storage/txpool" -keywords = ["cuprate", "txpool", "transaction", "pool", "database"] +license = "MIT" +authors = ["Boog900"] +repository = "https://github.com/Cuprate/cuprate/tree/main/storage/txpool" +keywords = ["cuprate", "txpool", "transaction", "pool", "database"] [features] +default = ["heed", "service"] +# default = ["redb", "service"] +# default = ["redb-memory", "service"] +heed = ["cuprate-database/heed"] +redb = ["cuprate-database/redb"] +redb-memory = ["cuprate-database/redb-memory"] +service = ["dep:tower", "dep:rayon", "dep:cuprate-database-service"] [dependencies] cuprate-database = { path = "../database", features = ["heed"] } -cuprate-database-service = { path = "../service" } -cuprate-types = { path = "../../types" } -cuprate-helper = { path = "../../helper" , default-features = false, features = ["constants"] } +cuprate-database-service = { path = "../service", optional = true } +cuprate-types = { path = "../../types" } +cuprate-helper = { path = "../../helper", default-features = false, features = ["constants"] } -monero-serai = { workspace = true, features = ["std"] } -bytemuck = { workspace = true, features = ["must_cast", "derive", "min_const_generics", "extern_crate_alloc"] } -bitflags = { workspace = true, features = ["std", "serde", "bytemuck"] } -thiserror = { workspace = true } -hex = { workspace = true } -tower = { workspace = true } +monero-serai = { workspace = true, features = ["std"] } +bytemuck = { workspace = true, features = ["must_cast", "derive", "min_const_generics", "extern_crate_alloc"] } +bitflags = { workspace = true, features = ["std", "serde", "bytemuck"] } +thiserror = { workspace = true } +hex = { workspace = true } -rayon = { workspace = true } +tower = { workspace = true, optional = true } +rayon = { workspace = true, optional = true } -serde = { workspace = true, optional = true } +serde = { workspace = true, optional = true } [dev-dependencies] cuprate-test-utils = { path = "../../test-utils" } -tokio = { workspace = true } -tempfile = { workspace = true } -hex-literal = { workspace = true } +tokio = { workspace = true } +tempfile = { workspace = true } +hex-literal = { workspace = true } diff --git a/storage/txpool/README.md b/storage/txpool/README.md new file mode 100644 index 000000000..5ddd93e22 --- /dev/null +++ b/storage/txpool/README.md @@ -0,0 +1,124 @@ +Cuprate's tx-pool database. + +This documentation is mostly for practical usage of `cuprate_txpool`. + +For a high-level overview, see the database section in +[Cuprate's architecture book](https://architecture.cuprate.org). + +If you're looking for a database crate, consider using the lower-level +[`cuprate-database`](https://doc.cuprate.org/cuprate_database) +crate that this crate is built on-top of. + +# Purpose + +This crate does 3 things: + +1. Uses [`cuprate_database`] as a base database layer +1. Implements various transaction pool related [operations](ops), [tables], and [types] +1. Exposes a [`tower::Service`] backed by a thread-pool + +Each layer builds on-top of the previous. + +As a user of `cuprate_txpool`, consider using the higher-level [`service`] module, +or at the very least the [`ops`] module instead of interacting with the `cuprate_database` traits directly. + +# `cuprate_database` + +Consider reading `cuprate_database`'s crate documentation before this crate, as it is the first layer. + +If/when this crate needs is used, be sure to use the version that this crate re-exports, e.g.: + +```rust +use cuprate_txpool::{ + cuprate_database::RuntimeError, +}; +``` + +This ensures the types/traits used from `cuprate_database` are the same ones used by `cuprate_txpool` internally. + +# Feature flags + +The `service` module requires the `service` feature to be enabled. +See the module for more documentation. + +Different database backends are enabled by the feature flags: + +- `heed` (LMDB) +- `redb` + +The default is `heed`. + +`tracing` is always enabled and cannot be disabled via feature-flag. + + +# Invariants when not using `service` + +`cuprate_txpool` can be used without the `service` feature enabled but +there are some things that must be kept in mind when doing so. + +Failing to uphold these invariants may cause panics. + +1. `LMDB` requires the user to resize the memory map resizing (see [`cuprate_database::RuntimeError::ResizeNeeded`] +1. `LMDB` has a maximum reader transaction count, + currently, [it is set to `126`](https://github.com/LMDB/lmdb/blob/b8e54b4c31378932b69f1298972de54a565185b1/libraries/liblmdb/mdb.c#L794-L799) +1. `LMDB` + has [maximum key/value byte size](http://www.lmdb.tech/doc/group__internal.html#gac929399f5d93cef85f874b9e9b1d09e0) + which must not be exceeded + +# Examples + +The below is an example of using `cuprate_txpool`'s +lowest API, i.e. using a mix of this crate and `cuprate_database`'s traits directly - +**this is NOT recommended.** + +For examples of the higher-level APIs, see: + +- [`ops`] +- [`service`] + +```rust +use cuprate_txpool::{ + cuprate_database::{ + ConcreteEnv, + Env, EnvInner, + DatabaseRo, DatabaseRw, TxRo, TxRw, + }, + config::ConfigBuilder, + tables::{Tables, TablesMut, OpenTables}, +}; + +# fn main() -> Result<(), Box> { + // Create a configuration for the database environment. + let tmp_dir = tempfile::tempdir()?; + let db_dir = tmp_dir.path().to_owned(); + let config = ConfigBuilder::new() + .db_directory(db_dir.into()) + .build(); + + // Initialize the database environment. + let env = cuprate_txpool::open(config)?; + + // Open up a transaction + tables for writing. + let env_inner = env.env_inner(); + let tx_rw = env_inner.tx_rw()?; + let mut tables = env_inner.open_tables_mut(&tx_rw)?; + + // ⚠️ Write data to the tables directly. + // (not recommended, use `ops` or `service`). + const KEY_IMAGE: [u8; 32] = [88; 32]; + const TX_HASH: [u8; 32] = [88; 32]; + tables.spent_key_images_mut().put(&KEY_IMAGE, &TX_HASH)?; + + // Commit the data written. + drop(tables); + TxRw::commit(tx_rw)?; + + // Read the data, assert it is correct. + let tx_ro = env_inner.tx_ro()?; + let tables = env_inner.open_tables(&tx_ro)?; + let (key_image, tx_hash) = tables.spent_key_images().first()?; + assert_eq!(key_image, KEY_IMAGE); + assert_eq!(tx_hash, TX_HASH); + # Ok(()) +} +``` diff --git a/storage/txpool/src/config.rs b/storage/txpool/src/config.rs index 659f18af5..d07358689 100644 --- a/storage/txpool/src/config.rs +++ b/storage/txpool/src/config.rs @@ -1,9 +1,12 @@ -use cuprate_database::config::{Config as DbConfig, SyncMode}; -use cuprate_database::resize::ResizeAlgorithm; +//! The transaction pool [`Config`]. +use std::{borrow::Cow, path::Path}; + +use cuprate_database::{ + config::{Config as DbConfig, SyncMode}, + resize::ResizeAlgorithm, +}; use cuprate_database_service::ReaderThreads; -use cuprate_helper::fs::{cuprate_blockchain_dir, cuprate_txpool_dir}; -use std::borrow::Cow; -use std::path::Path; +use cuprate_helper::fs::cuprate_txpool_dir; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -40,7 +43,7 @@ impl ConfigBuilder { Self { db_directory: None, db_config: cuprate_database::config::ConfigBuilder::new(Cow::Borrowed( - cuprate_blockchain_dir(), + cuprate_txpool_dir(), )), reader_threads: None, max_txpool_weight: None, @@ -51,7 +54,7 @@ impl ConfigBuilder { /// /// # Default values /// If [`ConfigBuilder::db_directory`] was not called, - /// the default [`cuprate_blockchain_dir`] will be used. + /// the default [`cuprate_txpool_dir`] will be used. /// /// For all other values, [`Default::default`] is used. pub fn build(self) -> Config { @@ -59,7 +62,7 @@ impl ConfigBuilder { // in `helper::fs`. No need to do them here. let db_directory = self .db_directory - .unwrap_or_else(|| Cow::Borrowed(cuprate_blockchain_dir())); + .unwrap_or_else(|| Cow::Borrowed(cuprate_txpool_dir())); let reader_threads = self.reader_threads.unwrap_or_default(); @@ -121,7 +124,7 @@ impl ConfigBuilder { #[must_use] pub fn fast(mut self) -> Self { self.db_config = - cuprate_database::config::ConfigBuilder::new(Cow::Borrowed(cuprate_blockchain_dir())) + cuprate_database::config::ConfigBuilder::new(Cow::Borrowed(cuprate_txpool_dir())) .fast(); self.reader_threads = Some(ReaderThreads::OnePerThread); @@ -135,7 +138,7 @@ impl ConfigBuilder { #[must_use] pub fn low_power(mut self) -> Self { self.db_config = - cuprate_database::config::ConfigBuilder::new(Cow::Borrowed(cuprate_blockchain_dir())) + cuprate_database::config::ConfigBuilder::new(Cow::Borrowed(cuprate_txpool_dir())) .low_power(); self.reader_threads = Some(ReaderThreads::One); @@ -145,7 +148,7 @@ impl ConfigBuilder { impl Default for ConfigBuilder { fn default() -> Self { - let db_directory = Cow::Borrowed(cuprate_blockchain_dir()); + let db_directory = Cow::Borrowed(cuprate_txpool_dir()); Self { db_directory: Some(db_directory.clone()), db_config: cuprate_database::config::ConfigBuilder::new(db_directory), @@ -180,7 +183,7 @@ impl Config { /// Create a new [`Config`] with sane default settings. /// /// The [`DbConfig::db_directory`] - /// will be set to [`cuprate_blockchain_dir`]. + /// will be set to [`cuprate_txpool_dir`]. /// /// All other values will be [`Default::default`]. /// diff --git a/storage/txpool/src/free.rs b/storage/txpool/src/free.rs index 6c1ddc4c2..d394002b0 100644 --- a/storage/txpool/src/free.rs +++ b/storage/txpool/src/free.rs @@ -1,4 +1,4 @@ -//! General free functions (related to the database). +//! General free functions (related to the tx-pool database). //---------------------------------------------------------------------------------------------------- Import use cuprate_database::{ConcreteEnv, Env, EnvInner, InitError, RuntimeError, TxRw}; diff --git a/storage/txpool/src/lib.rs b/storage/txpool/src/lib.rs index 1efd4a9af..f200c3486 100644 --- a/storage/txpool/src/lib.rs +++ b/storage/txpool/src/lib.rs @@ -1,9 +1,12 @@ +#![doc = include_str!("../README.md")] + pub mod config; mod free; -mod ops; +pub mod ops; +#[cfg(feature = "service")] pub mod service; pub mod tables; -mod types; +pub mod types; pub use config::Config; pub use free::open; diff --git a/storage/txpool/src/ops.rs b/storage/txpool/src/ops.rs index bb496c6d9..d49a1800b 100644 --- a/storage/txpool/src/ops.rs +++ b/storage/txpool/src/ops.rs @@ -1,3 +1,86 @@ +//! Abstracted Monero tx-pool database operations. +//! +//! This module contains many free functions that use the +//! traits in [`cuprate_database`] to generically call Monero-related +//! tx-pool database operations. +//! +//! # `impl Table` +//! Functions in this module take [`Tables`](crate::tables::Tables) and +//! [`TablesMut`](crate::tables::TablesMut) directly - these are +//! _already opened_ database tables. +//! +//! As such, the responsibility of +//! transactions, tables, etc, are on the caller. +//! +//! Notably, this means that these functions are as lean +//! as possible, so calling them in a loop should be okay. +//! +//! # Atomicity +//! As transactions are handled by the _caller_ of these functions, +//! it is up to the caller to decide what happens if one them return +//! an error. +//! +//! To maintain atomicity, transactions should be [`abort`](cuprate_database::TxRw::abort)ed +//! if one of the functions failed. +//! +//! For example, if [`add_transaction`] is called and returns an [`Err`], +//! `abort`ing the transaction that opened the input `TableMut` would reverse all tables +//! mutated by [`add_transaction`] up until the error, leaving it in the state it was in before +//! [`add_transaction`] was called. +//! +//! # Example +//! Simple usage of `ops`. +//! +//! ```rust +//! use hex_literal::hex; +//! +//! use cuprate_test_utils::data::tx_v1_sig2; +//! use cuprate_txpool::{ +//! cuprate_database::{ +//! ConcreteEnv, +//! Env, EnvInner, +//! DatabaseRo, DatabaseRw, TxRo, TxRw, +//! }, +//! config::ConfigBuilder, +//! tables::{Tables, TablesMut, OpenTables}, +//! ops::{add_transaction, get_transaction_verification_data}, +//! }; +//! +//! # fn main() -> Result<(), Box> { +//! // Create a configuration for the database environment. +//! let tmp_dir = tempfile::tempdir()?; +//! let db_dir = tmp_dir.path().to_owned(); +//! let config = ConfigBuilder::new() +//! .db_directory(db_dir.into()) +//! .build(); +//! +//! // Initialize the database environment. +//! let env = cuprate_txpool::open(config)?; +//! +//! // Open up a transaction + tables for writing. +//! let env_inner = env.env_inner(); +//! let tx_rw = env_inner.tx_rw()?; +//! let mut tables = env_inner.open_tables_mut(&tx_rw)?; +//! +//! // Write a tx to the database. +//! let mut tx = tx_v1_sig2().clone(); +//! let tx_hash = tx.tx_hash; +//! add_transaction(&tx.try_into().unwrap(), true, &mut tables)?; +//! +//! // Commit the data written. +//! drop(tables); +//! TxRw::commit(tx_rw)?; +//! +//! // Read the data, assert it is correct. +//! let tx_rw = env_inner.tx_rw()?; +//! let mut tables = env_inner.open_tables_mut(&tx_rw)?; +//! let tx = get_transaction_verification_data(&tx_hash, &mut tables)?; +//! +//! assert_eq!(tx.tx_hash, tx_hash); +//! assert_eq!(tx.tx, tx_v1_sig2().tx); +//! # Ok(()) } +//! ``` + mod key_images; mod tx_read; mod tx_write; @@ -5,6 +88,7 @@ mod tx_write; pub use tx_read::get_transaction_verification_data; pub use tx_write::{add_transaction, remove_transaction}; +/// An error that can occur on some tx-write ops. #[derive(thiserror::Error, Debug)] pub enum TxPoolWriteError { /// The transaction could not be added as it double spends another tx in the pool. @@ -15,4 +99,4 @@ pub enum TxPoolWriteError { /// A database error. #[error("Database error: {0}")] Database(#[from] cuprate_database::RuntimeError), -} \ No newline at end of file +} diff --git a/storage/txpool/src/ops/key_images.rs b/storage/txpool/src/ops/key_images.rs index 443adf1f4..c6e441521 100644 --- a/storage/txpool/src/ops/key_images.rs +++ b/storage/txpool/src/ops/key_images.rs @@ -1,8 +1,9 @@ +//! Tx-pool key image ops. use monero_serai::transaction::Input; use cuprate_database::{DatabaseRw, RuntimeError}; -use crate::{tables::SpentKeyImages, types::TransactionHash, ops::TxPoolWriteError}; +use crate::{ops::TxPoolWriteError, tables::SpentKeyImages, types::TransactionHash}; /// Adds the transaction key images to the [`SpentKeyImages`] table. /// diff --git a/storage/txpool/src/ops/tx_write.rs b/storage/txpool/src/ops/tx_write.rs index 036a73acd..55de34695 100644 --- a/storage/txpool/src/ops/tx_write.rs +++ b/storage/txpool/src/ops/tx_write.rs @@ -7,14 +7,21 @@ use monero_serai::transaction::{NotPruned, Transaction}; use cuprate_database::{DatabaseRw, RuntimeError, StorableVec}; use cuprate_types::TransactionVerificationData; -use crate::{ops::{key_images::{add_tx_key_images, remove_tx_key_images}, TxPoolWriteError}, tables::TablesMut, types::{TransactionHash, TransactionInfo, TxStateFlags}}; +use crate::{ + ops::{ + key_images::{add_tx_key_images, remove_tx_key_images}, + TxPoolWriteError, + }, + tables::TablesMut, + types::{TransactionHash, TransactionInfo, TxStateFlags}, +}; /// Adds a transaction to the tx-pool. /// /// This function fills in all tables necessary to add the transaction to the pool. /// /// # Panics -/// This function will panic if the transactions inputs are not all of type [`Input::ToKey`]. +/// This function will panic if the transactions inputs are not all of type [`Input::ToKey`](monero_serai::transaction::Input::ToKey). pub fn add_transaction( tx: &TransactionVerificationData, state_stem: bool, diff --git a/storage/txpool/src/service.rs b/storage/txpool/src/service.rs index b346ea236..795cf8fe5 100644 --- a/storage/txpool/src/service.rs +++ b/storage/txpool/src/service.rs @@ -54,8 +54,8 @@ //! //! [req_w]: interface::TxpoolWriteRequest //! -//! // TODO: we have 2 responses -//! +//! // TODO: we have 2 responses +//! //! [resp]: interface::TxpoolWriteResponse //! //! # Example @@ -133,4 +133,4 @@ mod types; mod write; pub use free::init; -pub use types::{TxpoolWriteHandle, TxpoolReadHandle}; +pub use types::{TxpoolReadHandle, TxpoolWriteHandle}; diff --git a/storage/txpool/src/service/interface.rs b/storage/txpool/src/service/interface.rs index 6ac3ec2dc..4bc8c0804 100644 --- a/storage/txpool/src/service/interface.rs +++ b/storage/txpool/src/service/interface.rs @@ -1,9 +1,14 @@ -use crate::types::TransactionHash; -use cuprate_types::TransactionVerificationData; +//! Tx-pool [`service`](super) interface. +//! +//! This module contains `cuprate_txpool`'s [`tower::Service`] request and response enums. use std::sync::Arc; +use cuprate_types::TransactionVerificationData; + +use crate::types::TransactionHash; + //---------------------------------------------------------------------------------------------------- TxpoolReadRequest -/// The transaction pool [`tower::Service`] request type. +/// The transaction pool [`tower::Service`] read request type. pub enum TxpoolReadRequest { /// A request for the blob (raw bytes) of a transaction with the given hash. TxBlob(TransactionHash), @@ -12,6 +17,7 @@ pub enum TxpoolReadRequest { } //---------------------------------------------------------------------------------------------------- TxpoolReadResponse +/// The transaction pool [`tower::Service`] read response type. pub enum TxpoolReadResponse { /// A response containing the raw bytes of a transaction. // TODO: use bytes::Bytes. @@ -21,17 +27,32 @@ pub enum TxpoolReadResponse { } //---------------------------------------------------------------------------------------------------- TxpoolWriteRequest +/// The transaction pool [`tower::Service`] write request type. pub enum TxpoolWriteRequest { + /// Add a transaction to the pool. + /// + /// Returns [`TxpoolWriteResponse::AddTransaction`]. AddTransaction { + /// The tx to add. tx: Arc, + /// A bool denoting the routing state of this tx. + /// + /// [`true`] if this tx is in the stem state. state_stem: bool, }, + /// Remove a transaction with the given hash from the pool. + /// + /// Returns [`TxpoolWriteResponse::Ok`]. RemoveTransaction(TransactionHash), } //---------------------------------------------------------------------------------------------------- TxpoolWriteResponse +/// The transaction pool [`tower::Service`] write response type. #[derive(Debug, Ord, PartialOrd, Eq, PartialEq)] pub enum TxpoolWriteResponse { + /// A [`TxpoolWriteRequest::AddTransaction`] response. + /// + /// If the inner value is [`Some`] the tx was not added to the pool as it double spends a tx with the given hash. AddTransaction(Option), Ok, } diff --git a/storage/txpool/src/tables.rs b/storage/txpool/src/tables.rs index 1dba28f8b..dbb686ae1 100644 --- a/storage/txpool/src/tables.rs +++ b/storage/txpool/src/tables.rs @@ -1,17 +1,45 @@ +//! Tx-pool Database tables. +//! +//! # Table marker structs +//! This module contains all the table definitions used by [`cuprate_txpool`](crate). +//! +//! The zero-sized structs here represents the table type; +//! they all are essentially marker types that implement [`cuprate_database::Table`]. +//! +//! Table structs are `CamelCase`, and their static string +//! names used by the actual database backend are `snake_case`. +//! +//! For example: [`TransactionBlobs`] -> `transaction_blobs`. +//! +//! # Traits +//! This module also contains a set of traits for +//! accessing _all_ tables defined here at once. use cuprate_database::{define_tables, StorableVec}; use crate::types::{KeyImage, RawCachedVerificationState, TransactionHash, TransactionInfo}; define_tables! { + /// Serialized transaction blobs. + /// + /// This table contains the transaction blobs of all the transactions in the pool. 0 => TransactionBlobs, TransactionHash => StorableVec, - 1 => TransactionInformation, + /// Transaction information. + /// + /// This table contains information of all transactions currently in the pool. + 1 => TransactionInfos, TransactionHash => TransactionInfo, + /// Cached transaction verification state. + /// + /// This table contains the cached verification state of all translations in the pool. 2 => CachedVerificationState, TransactionHash => RawCachedVerificationState, + /// Spent key images. + /// + /// This table contains the spent key images from all transactions in the pool. 3 => SpentKeyImages, KeyImage => TransactionHash } diff --git a/storage/txpool/src/types.rs b/storage/txpool/src/types.rs index 20392e429..0d349886a 100644 --- a/storage/txpool/src/types.rs +++ b/storage/txpool/src/types.rs @@ -1,3 +1,10 @@ +//! Tx-pool [table](crate::tables) types. +//! +//! This module contains all types used by the database tables, +//! and aliases for common types that use the same underlying +//! primitive type. +//! +//! use bytemuck::{Pod, Zeroable}; use monero_serai::transaction::Timelock; @@ -32,7 +39,9 @@ pub struct TransactionInfo { pub weight: usize, /// [`TxStateFlags`] of this transaction. pub flags: TxStateFlags, - + /// Explicit padding so that we have no implicit padding bytes in `repr(C)`. + /// + /// Allows potential future expansion of this type. pub _padding: [u8; 7], } @@ -48,6 +57,8 @@ pub struct RawCachedVerificationState { raw_hf: u8, /// The raw timestamp, will be `0` if there is no timestamp that needs to be passed for this to /// be valid. + /// + /// Not a [`u64`] as if it was this type would have an alignment requirement. raw_valid_past_timestamp: [u8; 8], }