Database: Split BlockBlobs table + Miscellaneous fixes (#290)
Some checks are pending
Audit / audit (push) Waiting to run
CI / fmt (push) Waiting to run
CI / typo (push) Waiting to run
CI / ci (macos-latest, stable, bash) (push) Waiting to run
CI / ci (ubuntu-latest, stable, bash) (push) Waiting to run
CI / ci (windows-latest, stable-x86_64-pc-windows-gnu, msys2 {0}) (push) Waiting to run
Deny / audit (push) Waiting to run
Doc / build (push) Waiting to run
Doc / deploy (push) Blocked by required conditions

* Split `BlockBlobs` database table + misc fixes

- Split the `BlockBlobs` database table into two new tables: `BlockHeaderBlobs` and `BlockTxsHashes`.
- `add_block`, `pop_block` and `get_block_extended_header` have been edited consequently.
- `VerifiedBlockInformation` now have a `mining_tx_index: u64` field.
- Made `cuprate-helper`'s `thread` feature a dependency of the `service` feature
- Edited service test mapping of output. It is now a full iterator.

* fix fmt

* Update storage/blockchain/src/types.rs

Co-authored-by: Boog900 <boog900@tutanota.com>

* Update storage/blockchain/src/ops/block.rs

Co-authored-by: Boog900 <boog900@tutanota.com>

* fix warning

---------

Co-authored-by: Boog900 <boog900@tutanota.com>
This commit is contained in:
Asurar 2024-09-19 21:05:41 +02:00 committed by GitHub
parent 4169c45c58
commit e7c6bba63d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 128 additions and 93 deletions

View file

@ -15,15 +15,12 @@ default = ["heed", "service"]
heed = ["cuprate-database/heed"] heed = ["cuprate-database/heed"]
redb = ["cuprate-database/redb"] redb = ["cuprate-database/redb"]
redb-memory = ["cuprate-database/redb-memory"] redb-memory = ["cuprate-database/redb-memory"]
service = ["dep:thread_local", "dep:rayon"] service = ["dep:thread_local", "dep:rayon", "cuprate-helper/thread"]
[dependencies] [dependencies]
# FIXME:
# We only need the `thread` feature if `service` is enabled.
# Figure out how to enable features of an already pulled in dependency conditionally.
cuprate-database = { path = "../database" } cuprate-database = { path = "../database" }
cuprate-database-service = { path = "../service" } cuprate-database-service = { path = "../service" }
cuprate-helper = { path = "../../helper", features = ["fs", "thread", "map"] } cuprate-helper = { path = "../../helper", features = ["fs", "map"] }
cuprate-types = { path = "../../types", features = ["blockchain"] } cuprate-types = { path = "../../types", features = ["blockchain"] }
cuprate-pruning = { path = "../../pruning" } cuprate-pruning = { path = "../../pruning" }

View file

@ -2,7 +2,10 @@
//---------------------------------------------------------------------------------------------------- Import //---------------------------------------------------------------------------------------------------- Import
use bytemuck::TransparentWrapper; use bytemuck::TransparentWrapper;
use monero_serai::block::{Block, BlockHeader}; use monero_serai::{
block::{Block, BlockHeader},
transaction::Transaction,
};
use cuprate_database::{ use cuprate_database::{
RuntimeError, StorableVec, {DatabaseRo, DatabaseRw}, RuntimeError, StorableVec, {DatabaseRo, DatabaseRw},
@ -76,10 +79,10 @@ pub fn add_block(
//------------------------------------------------------ Transaction / Outputs / Key Images //------------------------------------------------------ Transaction / Outputs / Key Images
// Add the miner transaction first. // Add the miner transaction first.
{ let mining_tx_index = {
let tx = &block.block.miner_transaction; let tx = &block.block.miner_transaction;
add_tx(tx, &tx.serialize(), &tx.hash(), &chain_height, tables)?; add_tx(tx, &tx.serialize(), &tx.hash(), &chain_height, tables)?
} };
for tx in &block.txs { for tx in &block.txs {
add_tx(&tx.tx, &tx.tx_blob, &tx.tx_hash, &chain_height, tables)?; add_tx(&tx.tx, &tx.tx_blob, &tx.tx_hash, &chain_height, tables)?;
@ -111,13 +114,21 @@ pub fn add_block(
block_hash: block.block_hash, block_hash: block.block_hash,
weight: block.weight, weight: block.weight,
long_term_weight: block.long_term_weight, long_term_weight: block.long_term_weight,
mining_tx_index,
}, },
)?; )?;
// Block blobs. // Block header blob.
tables tables.block_header_blobs_mut().put(
.block_blobs_mut() &block.height,
.put(&block.height, StorableVec::wrap_ref(&block.block_blob))?; StorableVec::wrap_ref(&block.block.header.serialize()),
)?;
// Block transaction hashes
tables.block_txs_hashes_mut().put(
&block.height,
StorableVec::wrap_ref(&block.block.transactions),
)?;
// Block heights. // Block heights.
tables tables
@ -151,10 +162,18 @@ pub fn pop_block(
tables.block_heights_mut().delete(&block_info.block_hash)?; tables.block_heights_mut().delete(&block_info.block_hash)?;
// Block blobs. // Block blobs.
// We deserialize the block blob into a `Block`, such //
// that we can remove the associated transactions later. // We deserialize the block header blob and mining transaction blob
let block_blob = tables.block_blobs_mut().take(&block_height)?.0; // to form a `Block`, such that we can remove the associated transactions
let block = Block::read(&mut block_blob.as_slice())?; // later.
let block_header = tables.block_header_blobs_mut().take(&block_height)?.0;
let block_txs_hashes = tables.block_txs_hashes_mut().take(&block_height)?.0;
let miner_transaction = tables.tx_blobs().get(&block_info.mining_tx_index)?.0;
let block = Block {
header: BlockHeader::read(&mut block_header.as_slice())?,
miner_transaction: Transaction::read(&mut miner_transaction.as_slice())?,
transactions: block_txs_hashes,
};
//------------------------------------------------------ Transaction / Outputs / Key Images //------------------------------------------------------ Transaction / Outputs / Key Images
remove_tx(&block.miner_transaction.hash(), tables)?; remove_tx(&block.miner_transaction.hash(), tables)?;
@ -181,7 +200,7 @@ pub fn pop_block(
alt_block::add_alt_block( alt_block::add_alt_block(
&AltBlockInformation { &AltBlockInformation {
block: block.clone(), block: block.clone(),
block_blob, block_blob: block.serialize(),
txs, txs,
block_hash: block_info.block_hash, block_hash: block_info.block_hash,
// We know the PoW is valid for this block so just set it so it will always verify as valid. // We know the PoW is valid for this block so just set it so it will always verify as valid.
@ -236,8 +255,8 @@ pub fn get_block_extended_header_from_height(
tables: &impl Tables, tables: &impl Tables,
) -> Result<ExtendedBlockHeader, RuntimeError> { ) -> Result<ExtendedBlockHeader, RuntimeError> {
let block_info = tables.block_infos().get(block_height)?; let block_info = tables.block_infos().get(block_height)?;
let block_blob = tables.block_blobs().get(block_height)?.0; let block_header_blob = tables.block_header_blobs().get(block_height)?.0;
let block_header = BlockHeader::read(&mut block_blob.as_slice())?; let block_header = BlockHeader::read(&mut block_header_blob.as_slice())?;
let cumulative_difficulty = combine_low_high_bits_to_u128( let cumulative_difficulty = combine_low_high_bits_to_u128(
block_info.cumulative_difficulty_low, block_info.cumulative_difficulty_low,
@ -304,7 +323,7 @@ pub fn block_exists(
//---------------------------------------------------------------------------------------------------- Tests //---------------------------------------------------------------------------------------------------- Tests
#[cfg(test)] #[cfg(test)]
#[expect(clippy::significant_drop_tightening, clippy::too_many_lines)] #[expect(clippy::too_many_lines)]
mod test { mod test {
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
@ -370,7 +389,8 @@ mod test {
// Assert only the proper tables were added to. // Assert only the proper tables were added to.
AssertTableLen { AssertTableLen {
block_infos: 3, block_infos: 3,
block_blobs: 3, block_header_blobs: 3,
block_txs_hashes: 3,
block_heights: 3, block_heights: 3,
key_images: 69, key_images: 69,
num_outputs: 41, num_outputs: 41,

View file

@ -138,7 +138,8 @@ mod test {
// Assert reads are correct. // Assert reads are correct.
AssertTableLen { AssertTableLen {
block_infos: 3, block_infos: 3,
block_blobs: 3, block_header_blobs: 3,
block_txs_hashes: 3,
block_heights: 3, block_heights: 3,
key_images: 69, key_images: 69,
num_outputs: 41, num_outputs: 41,

View file

@ -316,7 +316,8 @@ mod test {
// Assert proper tables were added to. // Assert proper tables were added to.
AssertTableLen { AssertTableLen {
block_infos: 0, block_infos: 0,
block_blobs: 0, block_header_blobs: 0,
block_txs_hashes: 0,
block_heights: 0, block_heights: 0,
key_images: 0, key_images: 0,
num_outputs: 1, num_outputs: 1,

View file

@ -366,7 +366,8 @@ mod test {
// Assert only the proper tables were added to. // Assert only the proper tables were added to.
AssertTableLen { AssertTableLen {
block_infos: 0, block_infos: 0,
block_blobs: 0, block_header_blobs: 0,
block_txs_hashes: 0,
block_heights: 0, block_heights: 0,
key_images: 4, // added to key images key_images: 4, // added to key images
pruned_tx_blobs: 0, pruned_tx_blobs: 0,

View file

@ -241,18 +241,20 @@ async fn test_template(
//----------------------------------------------------------------------- Output checks //----------------------------------------------------------------------- Output checks
// Create the map of amounts and amount indices. // Create the map of amounts and amount indices.
//
// FIXME: There's definitely a better way to map
// `Vec<PreRctOutputId>` -> `HashMap<u64, HashSet<u64>>`
let (map, output_count) = { let (map, output_count) = {
let mut ids = tables let mut map = HashMap::<Amount, HashSet<AmountIndex>>::new();
// Used later to compare the amount of Outputs
// returned in the Response is equal to the amount
// we asked for.
let mut output_count: usize = 0;
tables
.outputs_iter() .outputs_iter()
.keys() .keys()
.unwrap() .unwrap()
.map(Result::unwrap) .map(Result::unwrap)
.collect::<Vec<PreRctOutputId>>(); .chain(
ids.extend(
tables tables
.rct_outputs_iter() .rct_outputs_iter()
.keys() .keys()
@ -262,21 +264,15 @@ async fn test_template(
amount: 0, amount: 0,
amount_index, amount_index,
}), }),
); )
.for_each(|id| {
// Used later to compare the amount of Outputs output_count += 1;
// returned in the Response is equal to the amount
// we asked for.
let output_count = ids.len();
let mut map = HashMap::<Amount, HashSet<AmountIndex>>::new();
for id in ids {
map.entry(id.amount) map.entry(id.amount)
.and_modify(|set| { .and_modify(|set| {
set.insert(id.amount_index); set.insert(id.amount_index);
}) })
.or_insert_with(|| HashSet::from([id.amount_index])); .or_insert_with(|| HashSet::from([id.amount_index]));
} });
(map, output_count) (map, output_count)
}; };
@ -347,7 +343,8 @@ async fn v1_tx2() {
14_535_350_982_449, 14_535_350_982_449,
AssertTableLen { AssertTableLen {
block_infos: 1, block_infos: 1,
block_blobs: 1, block_header_blobs: 1,
block_txs_hashes: 1,
block_heights: 1, block_heights: 1,
key_images: 65, key_images: 65,
num_outputs: 41, num_outputs: 41,
@ -373,7 +370,8 @@ async fn v9_tx3() {
3_403_774_022_163, 3_403_774_022_163,
AssertTableLen { AssertTableLen {
block_infos: 1, block_infos: 1,
block_blobs: 1, block_header_blobs: 1,
block_txs_hashes: 1,
block_heights: 1, block_heights: 1,
key_images: 4, key_images: 4,
num_outputs: 0, num_outputs: 0,
@ -399,7 +397,8 @@ async fn v16_tx0() {
600_000_000_000, 600_000_000_000,
AssertTableLen { AssertTableLen {
block_infos: 1, block_infos: 1,
block_blobs: 1, block_header_blobs: 1,
block_txs_hashes: 1,
block_heights: 1, block_heights: 1,
key_images: 0, key_images: 0,
num_outputs: 0, num_outputs: 0,

View file

@ -9,7 +9,7 @@
//! Table structs are `CamelCase`, and their static string //! Table structs are `CamelCase`, and their static string
//! names used by the actual database backend are `snake_case`. //! names used by the actual database backend are `snake_case`.
//! //!
//! For example: [`BlockBlobs`] -> `block_blobs`. //! For example: [`BlockHeaderBlobs`] -> `block_header_blobs`.
//! //!
//! # Traits //! # Traits
//! This module also contains a set of traits for //! This module also contains a set of traits for
@ -18,9 +18,9 @@
//---------------------------------------------------------------------------------------------------- Import //---------------------------------------------------------------------------------------------------- Import
use crate::types::{ use crate::types::{
AltBlockHeight, AltChainInfo, AltTransactionInfo, Amount, AmountIndex, AmountIndices, AltBlockHeight, AltChainInfo, AltTransactionInfo, Amount, AmountIndex, AmountIndices,
BlockBlob, BlockHash, BlockHeight, BlockInfo, CompactAltBlockInfo, KeyImage, Output, BlockBlob, BlockHash, BlockHeaderBlob, BlockHeight, BlockInfo, BlockTxHashes,
PreRctOutputId, PrunableBlob, PrunableHash, PrunedBlob, RawChainId, RctOutput, TxBlob, TxHash, CompactAltBlockInfo, KeyImage, Output, PreRctOutputId, PrunableBlob, PrunableHash, PrunedBlob,
TxId, UnlockTime, RawChainId, RctOutput, TxBlob, TxHash, TxId, UnlockTime,
}; };
//---------------------------------------------------------------------------------------------------- Tables //---------------------------------------------------------------------------------------------------- Tables
@ -30,22 +30,28 @@ use crate::types::{
// - If adding/changing a table also edit: // - If adding/changing a table also edit:
// - the tests in `src/backend/tests.rs` // - the tests in `src/backend/tests.rs`
cuprate_database::define_tables! { cuprate_database::define_tables! {
/// Serialized block blobs (bytes). /// Serialized block header blobs (bytes).
/// ///
/// Contains the serialized version of all blocks. /// Contains the serialized version of all blocks headers.
0 => BlockBlobs, 0 => BlockHeaderBlobs,
BlockHeight => BlockBlob, BlockHeight => BlockHeaderBlob,
/// Block transactions hashes
///
/// Contains all the transaction hashes of all blocks.
1 => BlockTxsHashes,
BlockHeight => BlockTxHashes,
/// Block heights. /// Block heights.
/// ///
/// Contains the height of all blocks. /// Contains the height of all blocks.
1 => BlockHeights, 2 => BlockHeights,
BlockHash => BlockHeight, BlockHash => BlockHeight,
/// Block information. /// Block information.
/// ///
/// Contains metadata of all blocks. /// Contains metadata of all blocks.
2 => BlockInfos, 3 => BlockInfos,
BlockHeight => BlockInfo, BlockHeight => BlockInfo,
/// Set of key images. /// Set of key images.
@ -54,38 +60,38 @@ cuprate_database::define_tables! {
/// ///
/// This table has `()` as the value type, as in, /// This table has `()` as the value type, as in,
/// it is a set of key images. /// it is a set of key images.
3 => KeyImages, 4 => KeyImages,
KeyImage => (), KeyImage => (),
/// Maps an output's amount to the number of outputs with that amount. /// Maps an output's amount to the number of outputs with that amount.
/// ///
/// For example, if there are 5 outputs with `amount = 123` /// For example, if there are 5 outputs with `amount = 123`
/// then calling `get(123)` on this table will return 5. /// then calling `get(123)` on this table will return 5.
4 => NumOutputs, 5 => NumOutputs,
Amount => u64, Amount => u64,
/// Pre-RCT output data. /// Pre-RCT output data.
5 => Outputs, 6 => Outputs,
PreRctOutputId => Output, PreRctOutputId => Output,
/// Pruned transaction blobs (bytes). /// Pruned transaction blobs (bytes).
/// ///
/// Contains the pruned portion of serialized transaction data. /// Contains the pruned portion of serialized transaction data.
6 => PrunedTxBlobs, 7 => PrunedTxBlobs,
TxId => PrunedBlob, TxId => PrunedBlob,
/// Prunable transaction blobs (bytes). /// Prunable transaction blobs (bytes).
/// ///
/// Contains the prunable portion of serialized transaction data. /// Contains the prunable portion of serialized transaction data.
// SOMEDAY: impl when `monero-serai` supports pruning // SOMEDAY: impl when `monero-serai` supports pruning
7 => PrunableTxBlobs, 8 => PrunableTxBlobs,
TxId => PrunableBlob, TxId => PrunableBlob,
/// Prunable transaction hashes. /// Prunable transaction hashes.
/// ///
/// Contains the prunable portion of transaction hashes. /// Contains the prunable portion of transaction hashes.
// SOMEDAY: impl when `monero-serai` supports pruning // SOMEDAY: impl when `monero-serai` supports pruning
8 => PrunableHashes, 9 => PrunableHashes,
TxId => PrunableHash, TxId => PrunableHash,
// SOMEDAY: impl a properties table: // SOMEDAY: impl a properties table:
@ -95,74 +101,74 @@ cuprate_database::define_tables! {
// StorableString => StorableVec, // StorableString => StorableVec,
/// RCT output data. /// RCT output data.
9 => RctOutputs, 10 => RctOutputs,
AmountIndex => RctOutput, AmountIndex => RctOutput,
/// Transaction blobs (bytes). /// Transaction blobs (bytes).
/// ///
/// Contains the serialized version of all transactions. /// Contains the serialized version of all transactions.
// SOMEDAY: remove when `monero-serai` supports pruning // SOMEDAY: remove when `monero-serai` supports pruning
10 => TxBlobs, 11 => TxBlobs,
TxId => TxBlob, TxId => TxBlob,
/// Transaction indices. /// Transaction indices.
/// ///
/// Contains the indices all transactions. /// Contains the indices all transactions.
11 => TxIds, 12 => TxIds,
TxHash => TxId, TxHash => TxId,
/// Transaction heights. /// Transaction heights.
/// ///
/// Contains the block height associated with all transactions. /// Contains the block height associated with all transactions.
12 => TxHeights, 13 => TxHeights,
TxId => BlockHeight, TxId => BlockHeight,
/// Transaction outputs. /// Transaction outputs.
/// ///
/// Contains the list of `AmountIndex`'s of the /// Contains the list of `AmountIndex`'s of the
/// outputs associated with all transactions. /// outputs associated with all transactions.
13 => TxOutputs, 14 => TxOutputs,
TxId => AmountIndices, TxId => AmountIndices,
/// Transaction unlock time. /// Transaction unlock time.
/// ///
/// Contains the unlock time of transactions IF they have one. /// Contains the unlock time of transactions IF they have one.
/// Transactions without unlock times will not exist in this table. /// Transactions without unlock times will not exist in this table.
14 => TxUnlockTime, 15 => TxUnlockTime,
TxId => UnlockTime, TxId => UnlockTime,
/// Information on alt-chains. /// Information on alt-chains.
15 => AltChainInfos, 16 => AltChainInfos,
RawChainId => AltChainInfo, RawChainId => AltChainInfo,
/// Alt-block heights. /// Alt-block heights.
/// ///
/// Contains the height of all alt-blocks. /// Contains the height of all alt-blocks.
16 => AltBlockHeights, 17 => AltBlockHeights,
BlockHash => AltBlockHeight, BlockHash => AltBlockHeight,
/// Alt-block information. /// Alt-block information.
/// ///
/// Contains information on all alt-blocks. /// Contains information on all alt-blocks.
17 => AltBlocksInfo, 18 => AltBlocksInfo,
AltBlockHeight => CompactAltBlockInfo, AltBlockHeight => CompactAltBlockInfo,
/// Alt-block blobs. /// Alt-block blobs.
/// ///
/// Contains the raw bytes of all alt-blocks. /// Contains the raw bytes of all alt-blocks.
18 => AltBlockBlobs, 19 => AltBlockBlobs,
AltBlockHeight => BlockBlob, AltBlockHeight => BlockBlob,
/// Alt-block transaction blobs. /// Alt-block transaction blobs.
/// ///
/// Contains the raw bytes of alt transactions, if those transactions are not in the main-chain. /// Contains the raw bytes of alt transactions, if those transactions are not in the main-chain.
19 => AltTransactionBlobs, 20 => AltTransactionBlobs,
TxHash => TxBlob, TxHash => TxBlob,
/// Alt-block transaction information. /// Alt-block transaction information.
/// ///
/// Contains information on all alt transactions, even if they are in the main-chain. /// Contains information on all alt transactions, even if they are in the main-chain.
20 => AltTransactionInfos, 21 => AltTransactionInfos,
TxHash => AltTransactionInfo, TxHash => AltTransactionInfo,
} }

View file

@ -9,7 +9,7 @@ use std::{borrow::Cow, fmt::Debug};
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
use cuprate_database::{ConcreteEnv, DatabaseRo, Env, EnvInner}; use cuprate_database::{DatabaseRo, Env, EnvInner};
use cuprate_types::{AltBlockInformation, ChainId, VerifiedBlockInformation}; use cuprate_types::{AltBlockInformation, ChainId, VerifiedBlockInformation};
use crate::{ use crate::{
@ -26,7 +26,8 @@ use crate::{
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub(crate) struct AssertTableLen { pub(crate) struct AssertTableLen {
pub(crate) block_infos: u64, pub(crate) block_infos: u64,
pub(crate) block_blobs: u64, pub(crate) block_header_blobs: u64,
pub(crate) block_txs_hashes: u64,
pub(crate) block_heights: u64, pub(crate) block_heights: u64,
pub(crate) key_images: u64, pub(crate) key_images: u64,
pub(crate) num_outputs: u64, pub(crate) num_outputs: u64,
@ -46,7 +47,8 @@ impl AssertTableLen {
pub(crate) fn assert(self, tables: &impl Tables) { pub(crate) fn assert(self, tables: &impl Tables) {
let other = Self { let other = Self {
block_infos: tables.block_infos().len().unwrap(), block_infos: tables.block_infos().len().unwrap(),
block_blobs: tables.block_blobs().len().unwrap(), block_header_blobs: tables.block_header_blobs().len().unwrap(),
block_txs_hashes: tables.block_txs_hashes().len().unwrap(),
block_heights: tables.block_heights().len().unwrap(), block_heights: tables.block_heights().len().unwrap(),
key_images: tables.key_images().len().unwrap(), key_images: tables.key_images().len().unwrap(),
num_outputs: tables.num_outputs().len().unwrap(), num_outputs: tables.num_outputs().len().unwrap(),
@ -69,8 +71,7 @@ impl AssertTableLen {
/// Create an `Env` in a temporarily directory. /// Create an `Env` in a temporarily directory.
/// The directory is automatically removed after the `TempDir` is dropped. /// The directory is automatically removed after the `TempDir` is dropped.
/// ///
/// FIXME: changing this to `-> impl Env` causes lifetime errors... pub(crate) fn tmp_concrete_env() -> (impl Env, tempfile::TempDir) {
pub(crate) fn tmp_concrete_env() -> (ConcreteEnv, tempfile::TempDir) {
let tempdir = tempfile::tempdir().unwrap(); let tempdir = tempfile::tempdir().unwrap();
let config = ConfigBuilder::new() let config = ConfigBuilder::new()
.db_directory(Cow::Owned(tempdir.path().into())) .db_directory(Cow::Owned(tempdir.path().into()))
@ -82,7 +83,7 @@ pub(crate) fn tmp_concrete_env() -> (ConcreteEnv, tempfile::TempDir) {
} }
/// Assert all the tables in the environment are empty. /// Assert all the tables in the environment are empty.
pub(crate) fn assert_all_tables_are_empty(env: &ConcreteEnv) { pub(crate) fn assert_all_tables_are_empty(env: &impl Env) {
let env_inner = env.env_inner(); let env_inner = env.env_inner();
let tx_ro = env_inner.tx_ro().unwrap(); let tx_ro = env_inner.tx_ro().unwrap();
let tables = env_inner.open_tables(&tx_ro).unwrap(); let tables = env_inner.open_tables(&tx_ro).unwrap();

View file

@ -66,6 +66,12 @@ pub type AmountIndices = StorableVec<AmountIndex>;
/// A serialized block. /// A serialized block.
pub type BlockBlob = StorableVec<u8>; pub type BlockBlob = StorableVec<u8>;
/// A serialized block header
pub type BlockHeaderBlob = StorableVec<u8>;
/// A block transaction hashes
pub type BlockTxHashes = StorableVec<[u8; 32]>;
/// A block's hash. /// A block's hash.
pub type BlockHash = [u8; 32]; pub type BlockHash = [u8; 32];
@ -166,6 +172,7 @@ impl Key for PreRctOutputId {}
/// block_hash: [54; 32], /// block_hash: [54; 32],
/// cumulative_rct_outs: 2389, /// cumulative_rct_outs: 2389,
/// long_term_weight: 2389, /// long_term_weight: 2389,
/// mining_tx_index: 23
/// }; /// };
/// let b = Storable::as_bytes(&a); /// let b = Storable::as_bytes(&a);
/// let c: BlockInfo = Storable::from_bytes(b); /// let c: BlockInfo = Storable::from_bytes(b);
@ -175,7 +182,7 @@ impl Key for PreRctOutputId {}
/// # Size & Alignment /// # Size & Alignment
/// ```rust /// ```rust
/// # use cuprate_blockchain::types::*; /// # use cuprate_blockchain::types::*;
/// assert_eq!(size_of::<BlockInfo>(), 88); /// assert_eq!(size_of::<BlockInfo>(), 96);
/// assert_eq!(align_of::<BlockInfo>(), 8); /// assert_eq!(align_of::<BlockInfo>(), 8);
/// ``` /// ```
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
@ -202,6 +209,8 @@ pub struct BlockInfo {
/// ///
/// See [`long_term_weight`](https://monero-book.cuprate.org/consensus_rules/blocks/weights.html#long-term-block-weight). /// See [`long_term_weight`](https://monero-book.cuprate.org/consensus_rules/blocks/weights.html#long-term-block-weight).
pub long_term_weight: usize, pub long_term_weight: usize,
/// [`TxId`] (u64) of the block coinbase transaction.
pub mining_tx_index: TxId,
} }
//---------------------------------------------------------------------------------------------------- OutputFlags //---------------------------------------------------------------------------------------------------- OutputFlags