feat(db): models crate (#10314)

Co-authored-by: Miguel Oliveira <migueloliveiradev@gmail.com>
This commit is contained in:
Alexey Shekhirin
2024-08-17 10:25:34 -07:00
committed by GitHub
parent b6edbe36dc
commit 6bf3ca320a
14 changed files with 220 additions and 133 deletions

View File

@ -14,11 +14,12 @@ workspace = true
[dependencies]
# reth
reth-codecs.workspace = true
reth-db-models.workspace = true
reth-primitives = { workspace = true, features = ["reth-codec"] }
reth-primitives-traits.workspace = true
reth-prune-types.workspace = true
reth-storage-errors.workspace = true
reth-stages-types.workspace = true
reth-storage-errors.workspace = true
reth-trie-common.workspace = true
# codecs

View File

@ -7,57 +7,9 @@ use crate::{
table::{Decode, Encode},
DatabaseError,
};
use reth_codecs::{add_arbitrary_tests, Compact};
use reth_primitives::{Account, Address, BlockNumber, Buf, StorageKey};
use reth_primitives::{Address, BlockNumber, StorageKey};
use serde::{Deserialize, Serialize};
/// Account as it is saved in the database.
///
/// [`Address`] is the subkey.
#[derive(Debug, Default, Clone, Eq, PartialEq, Serialize)]
#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))]
#[add_arbitrary_tests(compact)]
pub struct AccountBeforeTx {
/// Address for the account. Acts as `DupSort::SubKey`.
pub address: Address,
/// Account state before the transaction.
pub info: Option<Account>,
}
// NOTE: Removing reth_codec and manually encode subkey
// and compress second part of the value. If we have compression
// over whole value (Even SubKey) that would mess up fetching of values with seek_by_key_subkey
impl Compact for AccountBeforeTx {
fn to_compact<B>(&self, buf: &mut B) -> usize
where
B: bytes::BufMut + AsMut<[u8]>,
{
// for now put full bytes and later compress it.
buf.put_slice(self.address.as_slice());
let mut acc_len = 0;
if let Some(account) = self.info {
acc_len = account.to_compact(buf);
}
acc_len + 20
}
fn from_compact(mut buf: &[u8], len: usize) -> (Self, &[u8]) {
let address = Address::from_slice(&buf[..20]);
buf.advance(20);
let info = if len - 20 > 0 {
let (acc, advanced_buf) = Account::from_compact(buf, len - 20);
buf = advanced_buf;
Some(acc)
} else {
None
};
(Self { address, info }, buf)
}
}
/// [`BlockNumber`] concatenated with [`Address`].
///
/// Since it's used as a key, it isn't compressed when encoding it.

View File

@ -1,71 +1,8 @@
//! Block related models and types.
use reth_codecs::{add_arbitrary_tests, Compact};
use reth_primitives::{Header, TxNumber, Withdrawals, B256};
use reth_primitives::{Header, Withdrawals, B256};
use serde::{Deserialize, Serialize};
use std::ops::Range;
/// Total number of transactions.
pub type NumTransactions = u64;
/// The storage of the block body indices.
///
/// It has the pointer to the transaction Number of the first
/// transaction in the block and the total number of transactions.
#[derive(Debug, Default, Eq, PartialEq, Clone, Serialize, Deserialize, Compact)]
#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))]
#[add_arbitrary_tests(compact)]
pub struct StoredBlockBodyIndices {
/// The number of the first transaction in this block
///
/// Note: If the block is empty, this is the number of the first transaction
/// in the next non-empty block.
pub first_tx_num: TxNumber,
/// The total number of transactions in the block
///
/// NOTE: Number of transitions is equal to number of transactions with
/// additional transition for block change if block has block reward or withdrawal.
pub tx_count: NumTransactions,
}
impl StoredBlockBodyIndices {
/// Return the range of transaction ids for this block.
pub const fn tx_num_range(&self) -> Range<TxNumber> {
self.first_tx_num..self.first_tx_num + self.tx_count
}
/// Return the index of last transaction in this block unless the block
/// is empty in which case it refers to the last transaction in a previous
/// non-empty block
pub const fn last_tx_num(&self) -> TxNumber {
self.first_tx_num.saturating_add(self.tx_count).saturating_sub(1)
}
/// First transaction index.
///
/// Caution: If the block is empty, this is the number of the first transaction
/// in the next non-empty block.
pub const fn first_tx_num(&self) -> TxNumber {
self.first_tx_num
}
/// Return the index of the next transaction after this block.
pub const fn next_tx_num(&self) -> TxNumber {
self.first_tx_num + self.tx_count
}
/// Return a flag whether the block is empty
pub const fn is_empty(&self) -> bool {
self.tx_count == 0
}
/// Return number of transaction inside block
///
/// NOTE: This is not the same as the number of transitions.
pub const fn tx_count(&self) -> NumTransactions {
self.tx_count
}
}
/// The storage representation of a block's ommers.
///
@ -105,17 +42,4 @@ mod tests {
StoredBlockOmmers::decompress::<Vec<_>>(ommer.compress()).unwrap()
);
}
#[test]
fn block_indices() {
let first_tx_num = 10;
let tx_count = 6;
let block_indices = StoredBlockBodyIndices { first_tx_num, tx_count };
assert_eq!(block_indices.first_tx_num(), first_tx_num);
assert_eq!(block_indices.last_tx_num(), first_tx_num + tx_count - 1);
assert_eq!(block_indices.next_tx_num(), first_tx_num + tx_count);
assert_eq!(block_indices.tx_count(), tx_count);
assert_eq!(block_indices.tx_num_range(), first_tx_num..first_tx_num + tx_count);
}
}

View File

@ -21,6 +21,7 @@ pub mod storage_sharded_key;
pub use accounts::*;
pub use blocks::*;
pub use client_version::ClientVersion;
pub use reth_db_models::{AccountBeforeTx, StoredBlockBodyIndices};
pub use sharded_key::ShardedKey;
/// Macro that implements [`Encode`] and [`Decode`] for uint types.