Implement types/ (#94)

* workspace: add `bytemuck` to workspace

* add `types/`

* workspace: add `cuprate-types` to members

* copy `consensus/` types to `types/`

* remove `hard_fork/`

* extended_block_header: impl `Pod`, fix layout

* update `Request/Response`

* impl types

* fix `Response/Request`

* impl `borsh`

* workspace: add `strum`

* service: add `strum` traits

* remove `paste`, `serde_json`, `thiserror`

* remove `strum`

* VerifiedBlockInformation: remove `hf_vote`

* Update Cargo.toml

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

---------

Co-authored-by: Boog900 <boog900@tutanota.com>
This commit is contained in:
hinto-janai 2024-03-26 20:46:32 -04:00 committed by GitHub
parent 5e7ee57482
commit d503548716
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 348 additions and 1 deletions

11
Cargo.lock generated
View file

@ -643,6 +643,17 @@ dependencies = [
"zip", "zip",
] ]
[[package]]
name = "cuprate-types"
version = "0.0.0"
dependencies = [
"borsh",
"cfg-if",
"curve25519-dalek",
"monero-serai",
"serde",
]
[[package]] [[package]]
name = "curve25519-dalek" name = "curve25519-dalek"
version = "4.1.2" version = "4.1.2"

View file

@ -15,6 +15,7 @@ members = [
"p2p/address-book", "p2p/address-book",
"pruning", "pruning",
"test-utils", "test-utils",
"types",
] ]
[profile.release] [profile.release]
@ -39,6 +40,7 @@ opt-level = 3
async-trait = { version = "0.1.74", default-features = false } async-trait = { version = "0.1.74", default-features = false }
bitflags = { version = "2.4.2", default-features = false } bitflags = { version = "2.4.2", default-features = false }
borsh = { version = "1.2.1", default-features = false } borsh = { version = "1.2.1", default-features = false }
bytemuck = { version = "1.14.3", default-features = false }
bytes = { version = "1.5.0", default-features = false } bytes = { version = "1.5.0", default-features = false }
cfg-if = { version = "1.0.0", default-features = false } cfg-if = { version = "1.0.0", default-features = false }
clap = { version = "4.4.7", default-features = false } clap = { version = "4.4.7", default-features = false }
@ -87,7 +89,6 @@ proptest-derive = { version = "0.4.0" }
# open = { version = "5.0.0" } # Open PATH/URL, probably for binaries | https://github.com/byron/open-rs # open = { version = "5.0.0" } # Open PATH/URL, probably for binaries | https://github.com/byron/open-rs
# regex = { version = "1.10.2" } # Regular expressions | https://github.com/rust-lang/regex # regex = { version = "1.10.2" } # Regular expressions | https://github.com/rust-lang/regex
# ryu = { version = "1.0.15" } # Fast float to string formatting | https://github.com/dtolnay/ryu # ryu = { version = "1.0.15" } # Fast float to string formatting | https://github.com/dtolnay/ryu
# strum = { version = "0.25.0" } # Enum macros/traits | https://github.com/Peternator7/strum
# Maybe one day. # Maybe one day.
# disk = { version = "*" } # (De)serialization to/from disk with various file formats | https://github.com/hinto-janai/disk # disk = { version = "*" } # (De)serialization to/from disk with various file formats | https://github.com/hinto-janai/disk

22
types/Cargo.toml Normal file
View file

@ -0,0 +1,22 @@
[package]
name = "cuprate-types"
version = "0.0.0"
edition = "2021"
description = "Cuprate data types"
license = "MIT"
authors = ["hinto-janai"]
repository = "https://github.com/Cuprate/cuprate/tree/main/types"
keywords = ["cuprate", "types"]
[features]
default = ["service"]
service = []
[dependencies]
borsh = { workspace = true, optional = true }
cfg-if = { workspace = true }
curve25519-dalek = { workspace = true }
monero-serai = { workspace = true }
serde = { workspace = true, optional = true }
[dev-dependencies]

21
types/README.md Normal file
View file

@ -0,0 +1,21 @@
# `cuprate-types`
Various data types shared by Cuprate.
<!-- Did you know markdown automatically increments number lists, even if they are all 1...? -->
1. [File Structure](#file-structure)
- [`src/`](#src)
---
# File Structure
A quick reference of the structure of the folders & files in `cuprate-types`.
Note that `lib.rs/mod.rs` files are purely for re-exporting/visibility/lints, and contain no code. Each sub-directory has a corresponding `mod.rs`.
## `src/`
The top-level `src/` files.
| File | Purpose |
|---------------------|---------|
| `service.rs` | Types used in database requests; `enum {Request,Response}`
| `types.rs` | Various general types used by Cuprate

101
types/src/lib.rs Normal file
View file

@ -0,0 +1,101 @@
//! Cuprate shared data types.
//!
//! TODO
//---------------------------------------------------------------------------------------------------- Lints
// Forbid lints.
// Our code, and code generated (e.g macros) cannot overrule these.
#![forbid(
// `unsafe` is allowed but it _must_ be
// commented with `SAFETY: reason`.
clippy::undocumented_unsafe_blocks,
// Never.
unused_unsafe,
redundant_semicolons,
unused_allocation,
coherence_leak_check,
single_use_lifetimes,
while_true,
clippy::missing_docs_in_private_items,
// Maybe can be put into `#[deny]`.
unconditional_recursion,
for_loops_over_fallibles,
unused_braces,
unused_doc_comments,
unused_labels,
keyword_idents,
non_ascii_idents,
variant_size_differences,
// Probably can be put into `#[deny]`.
future_incompatible,
let_underscore,
break_with_label_and_loop,
duplicate_macro_attributes,
exported_private_dependencies,
large_assignments,
overlapping_range_endpoints,
semicolon_in_expressions_from_macros,
noop_method_call,
unreachable_pub,
)]
// Deny lints.
// Some of these are `#[allow]`'ed on a per-case basis.
#![deny(
clippy::all,
clippy::correctness,
clippy::suspicious,
clippy::style,
clippy::complexity,
clippy::perf,
clippy::pedantic,
clippy::nursery,
clippy::cargo,
unused_mut,
missing_docs,
deprecated,
unused_comparisons,
nonstandard_style
)]
#![allow(unreachable_code, unused_variables, dead_code, unused_imports)] // TODO: remove
#![allow(
// FIXME: this lint affects crates outside of
// `database/` for some reason, allow for now.
clippy::cargo_common_metadata,
// FIXME: adding `#[must_use]` onto everything
// might just be more annoying than useful...
// although it is sometimes nice.
clippy::must_use_candidate,
// TODO: should be removed after all `todo!()`'s are gone.
clippy::diverging_sub_expression,
clippy::module_name_repetitions,
clippy::module_inception,
clippy::redundant_pub_crate,
clippy::option_if_let_else,
)]
// Allow some lints when running in debug mode.
#![cfg_attr(debug_assertions, allow(clippy::todo, clippy::multiple_crate_versions))]
//---------------------------------------------------------------------------------------------------- Public API
// Import private modules, export public types.
//
// Documentation for each module is located in the respective file.
mod types;
pub use types::{
ExtendedBlockHeader, OutputOnChain, TransactionVerificationData, VerifiedBlockInformation,
};
//---------------------------------------------------------------------------------------------------- Feature-gated
cfg_if::cfg_if! {
if #[cfg(feature = "service")] {
pub mod service;
}
}
//---------------------------------------------------------------------------------------------------- Private

88
types/src/service.rs Normal file
View file

@ -0,0 +1,88 @@
//! Database [`ReadRequest`]s, [`WriteRequest`]s, and [`Response`]s.
//---------------------------------------------------------------------------------------------------- Import
use std::{
collections::{HashMap, HashSet},
ops::Range,
};
use monero_serai::{block::Block, transaction::Transaction};
#[cfg(feature = "borsh")]
use borsh::{BorshDeserialize, BorshSerialize};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use crate::types::{ExtendedBlockHeader, OutputOnChain, VerifiedBlockInformation};
//---------------------------------------------------------------------------------------------------- ReadRequest
/// A read request to the database.
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
pub enum ReadRequest {
/// TODO
BlockExtendedHeader(u64),
/// TODO
BlockHash(u64),
/// TODO
BlockExtendedHeaderInRange(Range<u64>),
/// TODO
ChainHeight,
/// TODO
GeneratedCoins,
/// TODO
Outputs(HashMap<u64, HashSet<u64>>),
/// TODO
NumberOutputsWithAmount(Vec<u64>),
/// TODO
CheckKIsNotSpent(HashSet<[u8; 32]>),
/// TODO
BlockBatchInRange(Range<u64>),
}
//---------------------------------------------------------------------------------------------------- WriteRequest
/// A write request to the database.
#[derive(Debug, Clone, PartialEq, Eq)]
// #[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
pub enum WriteRequest {
/// TODO
WriteBlock(VerifiedBlockInformation),
}
//---------------------------------------------------------------------------------------------------- Response
/// A response from the database.
#[derive(Debug, Clone, PartialEq, Eq)]
// #[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
pub enum Response {
//------------------------------------------------------ Reads
/// TODO
BlockExtendedHeader(ExtendedBlockHeader),
/// TODO
BlockHash([u8; 32]),
/// TODO
BlockExtendedHeaderInRange(Vec<ExtendedBlockHeader>),
/// TODO
ChainHeight(u64, [u8; 32]),
/// TODO
GeneratedCoins(u64),
/// TODO
Outputs(HashMap<u64, HashMap<u64, OutputOnChain>>),
/// TODO
NumberOutputsWithAmount(HashMap<u64, usize>),
/// TODO
/// returns true if key images are spent
CheckKIsNotSpent(bool),
/// TODO
BlockBatchInRange(Vec<(Block, Vec<Transaction>)>),
//------------------------------------------------------ Writes
/// TODO
WriteBlockOk,
}
//---------------------------------------------------------------------------------------------------- Tests
#[cfg(test)]
mod test {
// use super::*;
}

103
types/src/types.rs Normal file
View file

@ -0,0 +1,103 @@
//! TODO
//---------------------------------------------------------------------------------------------------- Import
use std::sync::Arc;
use curve25519_dalek::edwards::EdwardsPoint;
use monero_serai::{
block::Block,
transaction::{Timelock, Transaction},
};
#[cfg(feature = "borsh")]
use borsh::{BorshDeserialize, BorshSerialize};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
//---------------------------------------------------------------------------------------------------- ExtendedBlockHeader
/// TODO
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
pub struct ExtendedBlockHeader {
/// TODO
/// This is a `cuprate_consensus::HardFork`.
pub version: u8,
/// TODO
/// This is a `cuprate_consensus::HardFork`.
pub vote: u8,
/// TODO
pub timestamp: u64,
/// TODO
pub cumulative_difficulty: u128,
/// TODO
pub block_weight: usize,
/// TODO
pub long_term_weight: usize,
}
//---------------------------------------------------------------------------------------------------- TransactionVerificationData
/// TODO
#[derive(Clone, Debug, PartialEq, Eq)]
// #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] // FIXME: monero_serai
// #[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
pub struct TransactionVerificationData {
/// TODO
pub tx: Transaction,
/// TODO
pub tx_blob: Vec<u8>,
/// TODO
pub tx_weight: usize,
/// TODO
pub fee: u64,
/// TODO
pub tx_hash: [u8; 32],
}
//---------------------------------------------------------------------------------------------------- VerifiedBlockInformation
/// TODO
#[derive(Clone, Debug, PartialEq, Eq)]
// #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] // FIXME: monero_serai
// #[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
pub struct VerifiedBlockInformation {
/// TODO
pub block: Block,
/// TODO
pub txs: Vec<Arc<TransactionVerificationData>>,
/// TODO
pub block_hash: [u8; 32],
/// TODO
pub pow_hash: [u8; 32],
/// TODO
pub height: u64,
/// TODO
pub generated_coins: u64,
/// TODO
pub weight: usize,
/// TODO
pub long_term_weight: usize,
/// TODO
pub cumulative_difficulty: u128,
}
//---------------------------------------------------------------------------------------------------- OutputOnChain
/// An already approved previous transaction output.
#[derive(Clone, Debug, PartialEq, Eq)]
// #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] // FIXME: monero_serai
// #[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
pub struct OutputOnChain {
/// TODO
pub height: u64,
/// TODO
pub time_lock: Timelock,
/// TODO
pub key: Option<EdwardsPoint>,
/// TODO
pub commitment: EdwardsPoint,
}
//---------------------------------------------------------------------------------------------------- Tests
#[cfg(test)]
mod test {
// use super::*;
}