CI: add cargo hack (#170)

* add workflow

* fix errors

* fix workflow

* install dependencies

* fix more errors

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

Co-authored-by: hinto-janai <hinto.janai@protonmail.com>

* fix hack + enable it for cuprate-database

* move hack to main CI

* fix docs

* fix ci formatting

* fix txpool tests

* fix CONTRIBUTING.md formatting

* service -> tower::Service

* review fixes

* review fixes

* fix CI

---------

Co-authored-by: hinto-janai <hinto.janai@protonmail.com>
This commit is contained in:
Boog900 2024-11-01 20:22:14 +00:00 committed by GitHub
parent b57ee2f4cf
commit 44981f2b24
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
34 changed files with 99 additions and 88 deletions

View file

@ -133,7 +133,12 @@ jobs:
- name: Test
run: |
cargo test --all-features --workspace
cargo test --package cuprate-blockchain --no-default-features --features redb --features service
cargo test --package cuprate-blockchain --no-default-features --features redb
- name: Hack Check
run: |
cargo install cargo-hack --locked
cargo hack --workspace check --feature-powerset --no-dev-deps
# TODO: upload binaries with `actions/upload-artifact@v3`
- name: Build

View file

@ -121,11 +121,14 @@ Before pushing your code, please run the following at the root of the repository
After that, ensure all other CI passes by running:
| Command | Does what |
|------------------------------------------------------------------------|-----------|
| `RUSTDOCFLAGS='-D warnings' cargo doc --workspace --all-features` | Checks documentation is OK
| `cargo clippy --workspace --all-features --all-targets -- -D warnings` | Checks clippy lints are satisfied
| `cargo test --all-features --workspace` | Runs all tests
| `cargo build --all-features --all-targets --workspace` | Builds all code
|------------------------------------------------------------------------|-------------------------------------------------------------------------|
| `RUSTDOCFLAGS='-D warnings' cargo doc --workspace --all-features` | Checks documentation is OK |
| `cargo clippy --workspace --all-features --all-targets -- -D warnings` | Checks clippy lints are satisfied |
| `cargo test --all-features --workspace` | Runs all tests |
| `cargo build --all-features --all-targets --workspace` | Builds all code |
| `cargo hack --workspace check --feature-powerset --no-dev-deps` | Uses `cargo hack` to check our crates build with different features set |
`cargo hack` can be installed with `cargo` from: https://github.com/taiki-e/cargo-hack.
**Note: in order for some tests to work, you will need to place a [`monerod`](https://www.getmonero.org/downloads/) binary at the root of the repository.**

View file

@ -24,7 +24,7 @@ cuprate-p2p-core = { workspace = true }
cuprate-dandelion-tower = { workspace = true, features = ["txpool"] }
cuprate-async-buffer = { workspace = true }
cuprate-address-book = { workspace = true }
cuprate-blockchain = { workspace = true, features = ["service"] }
cuprate-blockchain = { workspace = true }
cuprate-database-service = { workspace = true }
cuprate-txpool = { workspace = true }
cuprate-database = { workspace = true }

View file

@ -17,7 +17,7 @@ asynch = ["dep:futures", "dep:rayon"]
cast = []
constants = []
crypto = ["dep:curve25519-dalek", "dep:monero-serai", "std"]
fs = ["dep:dirs"]
fs = ["dep:dirs", "std"]
num = []
map = ["cast", "dep:monero-serai", "dep:cuprate-constants"]
time = ["dep:chrono", "std"]

View file

@ -11,7 +11,7 @@ pub mod atomic;
#[cfg(feature = "cast")]
pub mod cast;
#[cfg(feature = "fs")]
#[cfg(all(feature = "fs", feature = "std"))]
pub mod fs;
pub mod network;

View file

@ -1,3 +1,5 @@
use alloc::{string::ToString, vec, vec::Vec};
use bytes::{Buf, BufMut, Bytes, BytesMut};
use ref_cast::RefCast;

View file

@ -1,3 +1,4 @@
use alloc::string::{String, ToString};
use core::{
fmt::{Debug, Formatter},
num::TryFromIntError,

View file

@ -64,6 +64,7 @@ use hex as _;
extern crate alloc;
use alloc::string::ToString;
use core::str::from_utf8 as str_from_utf8;
use bytes::{Buf, BufMut, Bytes, BytesMut};

View file

@ -1,7 +1,7 @@
//! This module contains a [`EpeeValue`] trait and
//! impls for some possible base epee values.
use alloc::{string::String, vec::Vec};
use alloc::{string::String, vec, vec::Vec};
use core::fmt::Debug;
use bytes::{Buf, BufMut, Bytes, BytesMut};

View file

@ -9,7 +9,7 @@ authors = ["Boog900"]
[dependencies]
cuprate-constants = { workspace = true }
cuprate-pruning = { workspace = true }
cuprate-p2p-core = { workspace = true }
cuprate-p2p-core = { workspace = true, features = ["borsh"] }
tower = { workspace = true, features = ["util"] }
tokio = { workspace = true, features = ["time", "fs", "rt"]}

View file

@ -10,7 +10,7 @@ default = []
borsh = ["dep:borsh"]
[dependencies]
cuprate-constants = { workspace = true }
cuprate-constants = { workspace = true, features = ["block"] }
thiserror = { workspace = true }

View file

@ -10,20 +10,20 @@ keywords = ["cuprate", "rpc", "interface"]
[features]
default = ["dummy", "serde"]
dummy = []
dummy = ["dep:cuprate-helper", "dep:futures"]
[dependencies]
cuprate-epee-encoding = { workspace = true, default-features = false }
cuprate-json-rpc = { workspace = true, default-features = false }
cuprate-rpc-types = { workspace = true, features = ["serde", "epee"], default-features = false }
cuprate-helper = { workspace = true, features = ["asynch"], default-features = false }
cuprate-helper = { workspace = true, features = ["asynch"], default-features = false, optional = true }
anyhow = { workspace = true }
axum = { version = "0.7.5", features = ["json"], default-features = false }
serde = { workspace = true, optional = true }
tower = { workspace = true }
tower = { workspace = true, features = ["util"] }
paste = { workspace = true }
futures = { workspace = true }
futures = { workspace = true, optional = true }
[dev-dependencies]
cuprate-test-utils = { workspace = true }

View file

@ -20,12 +20,16 @@ use cuprate_types::BlockCompleteEntry;
use crate::{
base::AccessResponseBase,
defaults::{default_false, default_zero},
macros::{define_request, define_request_and_response, define_request_and_response_doc},
misc::{BlockOutputIndices, GetOutputsOut, OutKeyBin, PoolInfoExtent, PoolTxInfo, Status},
misc::{BlockOutputIndices, GetOutputsOut, OutKeyBin, PoolTxInfo, Status},
rpc_call::RpcCallValue,
};
#[cfg(any(feature = "epee", feature = "serde"))]
use crate::defaults::{default_false, default_zero};
#[cfg(feature = "epee")]
use crate::misc::PoolInfoExtent;
//---------------------------------------------------------------------------------------------------- Definitions
define_request_and_response! {
get_blocks_by_heightbin,

View file

@ -8,10 +8,6 @@ use serde::{Deserialize, Serialize};
use crate::{
base::{AccessResponseBase, ResponseBase},
defaults::{
default_false, default_height, default_one, default_string, default_true, default_vec,
default_zero,
},
macros::define_request_and_response,
misc::{
AuxPow, BlockHeader, ChainInfo, ConnectionInfo, Distribution, GetBan,
@ -21,6 +17,12 @@ use crate::{
rpc_call::RpcCallValue,
};
#[cfg(any(feature = "epee", feature = "serde"))]
use crate::defaults::{
default_false, default_height, default_one, default_string, default_true, default_vec,
default_zero,
};
//---------------------------------------------------------------------------------------------------- Macro
/// Adds a (de)serialization doc-test to a type in `json.rs`.
///

View file

@ -6,6 +6,7 @@
)]
mod constants;
#[cfg(any(feature = "serde", feature = "epee"))]
mod defaults;
mod free;
mod macros;

View file

@ -20,8 +20,8 @@ use cuprate_epee_encoding::{
"rpc/core_rpc_server_commands_defs.h",
45..=55
)]
#[cfg(feature = "epee")]
fn compress_integer_array(_: &[u64]) -> error::Result<Vec<u8>> {
#[cfg(any(feature = "epee", feature = "serde"))]
fn compress_integer_array(_: &[u64]) -> Vec<u8> {
todo!()
}
@ -33,6 +33,7 @@ fn compress_integer_array(_: &[u64]) -> error::Result<Vec<u8>> {
"rpc/core_rpc_server_commands_defs.h",
57..=72
)]
#[cfg(any(feature = "epee", feature = "serde"))]
fn decompress_integer_array(_: &[u8]) -> Vec<u64> {
todo!()
}
@ -135,12 +136,7 @@ fn serialize_distribution_as_compressed_data<S>(v: &Vec<u64>, s: S) -> Result<S:
where
S: serde::Serializer,
{
match compress_integer_array(v) {
Ok(compressed_data) => compressed_data.serialize(s),
Err(_) => Err(serde::ser::Error::custom(
"error compressing distribution array",
)),
}
compress_integer_array(v).serialize(s)
}
/// Deserializer function for [`DistributionCompressedBinary::distribution`].
@ -256,7 +252,7 @@ impl EpeeObject for Distribution {
distribution,
amount,
}) => {
let compressed_data = compress_integer_array(&distribution)?;
let compressed_data = compress_integer_array(&distribution);
start_height.write(w)?;
base.write(w)?;

View file

@ -11,10 +11,10 @@ use serde::{Deserialize, Serialize};
#[cfg(feature = "epee")]
use cuprate_epee_encoding::epee_object;
use crate::{
defaults::{default_string, default_zero},
macros::monero_definition_link,
};
use crate::macros::monero_definition_link;
#[cfg(any(feature = "epee", feature = "serde"))]
use crate::defaults::default_zero;
//---------------------------------------------------------------------------------------------------- Macros
/// This macro (local to this file) defines all the misc types.
@ -148,7 +148,7 @@ define_struct_and_impl_epee! {
)]
/// Used in [`crate::json::SetBansRequest`].
SetBan {
#[cfg_attr(feature = "serde", serde(default = "default_string"))]
#[cfg_attr(feature = "serde", serde(default = "crate::defaults::default_string"))]
host: String,
#[cfg_attr(feature = "serde", serde(default = "default_zero"))]
ip: u32,

View file

@ -8,7 +8,6 @@ use serde::{Deserialize, Serialize};
use crate::{
base::{AccessResponseBase, ResponseBase},
defaults::{default_false, default_string, default_true, default_vec, default_zero},
macros::define_request_and_response,
misc::{
GetOutputsOut, OutKey, Peer, PublicNode, SpentKeyImageInfo, Status, TxEntry, TxInfo,
@ -17,6 +16,9 @@ use crate::{
RpcCallValue,
};
#[cfg(any(feature = "serde", feature = "epee"))]
use crate::defaults::{default_false, default_string, default_true, default_vec, default_zero};
//---------------------------------------------------------------------------------------------------- Macro
/// Adds a (de)serialization doc-test to a type in `other.rs`.
///

View file

@ -9,32 +9,31 @@ repository = "https://github.com/Cuprate/cuprate/tree/main/storage/cuprate-bloc
keywords = ["cuprate", "blockchain", "database"]
[features]
default = ["heed", "service"]
default = ["heed"]
# default = ["redb", "service"]
# default = ["redb-memory", "service"]
heed = ["cuprate-database/heed"]
redb = ["cuprate-database/redb"]
redb-memory = ["cuprate-database/redb-memory"]
service = ["dep:thread_local", "dep:rayon", "cuprate-helper/thread"]
serde = ["dep:serde", "cuprate-database/serde", "cuprate-database-service/serde"]
[dependencies]
cuprate-database = { workspace = true }
cuprate-database-service = { workspace = true }
cuprate-helper = { workspace = true, features = ["fs", "map", "crypto"] }
cuprate-helper = { workspace = true, features = ["fs", "map", "crypto", "tx", "thread"] }
cuprate-types = { workspace = true, features = ["blockchain"] }
cuprate-pruning = { workspace = true }
bitflags = { workspace = true, features = ["std", "serde", "bytemuck"] }
bytemuck = { workspace = true, features = ["must_cast", "derive", "min_const_generics", "extern_crate_alloc"] }
curve25519-dalek = { workspace = true }
rand = { workspace = true }
rand = { workspace = true, features = ["std", "std_rng"] }
monero-serai = { workspace = true, features = ["std"] }
serde = { workspace = true, optional = true }
# `service` feature.
tower = { workspace = true }
thread_local = { workspace = true, optional = true }
rayon = { workspace = true, optional = true }
thread_local = { workspace = true }
rayon = { workspace = true }
[dev-dependencies]
cuprate-constants = { workspace = true }

View file

@ -32,9 +32,6 @@ use cuprate_blockchain::{
This ensures the types/traits used from `cuprate_database` are the same ones used by `cuprate_blockchain` 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`
@ -45,7 +42,7 @@ The default is `heed`.
<!-- FIXME: tracing should be behind a feature flag -->
# Invariants when not using `service`
`cuprate_blockchain` can be used without the `service` feature enabled but
`cuprate_blockchain` can be used without the `service` module but
there are some things that must be kept in mind when doing so.
Failing to uphold these invariants may cause panics.

View file

@ -29,16 +29,12 @@ pub use free::open;
pub mod config;
pub mod ops;
pub mod service;
pub mod tables;
pub mod types;
//---------------------------------------------------------------------------------------------------- Feature-gated
#[cfg(feature = "service")]
pub mod service;
//---------------------------------------------------------------------------------------------------- Private
#[cfg(test)]
pub(crate) mod tests;
#[cfg(feature = "service")] // only needed in `service` for now
pub(crate) mod unsafe_sendable;

View file

@ -10,8 +10,6 @@
//!
//! The system is managed by this crate, and only requires [`init`] by the user.
//!
//! This module must be enabled with the `service` feature.
//!
//! ## Handles
//! The 2 handles to the database are:
//! - [`BlockchainReadHandle`]

View file

@ -9,10 +9,10 @@ repository = "https://github.com/Cuprate/cuprate/tree/main/storage/database"
keywords = ["cuprate", "database"]
[features]
# default = ["heed"]
default = ["heed"]
# default = ["redb"]
# default = ["redb-memory"]
heed = ["dep:heed"]
heed = []
redb = ["dep:redb"]
redb-memory = ["redb"]
@ -25,7 +25,7 @@ paste = { workspace = true }
thiserror = { workspace = true }
# Optional features.
heed = { version = "0.20.5", features = ["read-txn-no-tls"], optional = true }
heed = { version = "0.20.5", features = ["read-txn-no-tls"] }
redb = { version = "2.1.3", optional = true }
serde = { workspace = true, optional = true }

View file

@ -4,6 +4,8 @@ cfg_if::cfg_if! {
// If both backends are enabled, fallback to `heed`.
// This is useful when using `--all-features`.
if #[cfg(all(feature = "redb", not(feature = "heed")))] {
use heed as _;
mod redb;
pub use redb::ConcreteEnv;
} else {

View file

@ -8,14 +8,20 @@ authors = ["Boog900"]
repository = "https://github.com/Cuprate/cuprate/tree/main/storage/service"
keywords = ["cuprate", "service", "database"]
[features]
default = ["heed"]
heed = ["cuprate-database/heed"]
redb = ["cuprate-database/redb"]
redb-memorey = ["cuprate-database/redb-memory"]
[dependencies]
cuprate-database = { workspace = true }
cuprate-helper = { workspace = true, features = ["fs", "thread", "map"] }
cuprate-helper = { workspace = true, features = ["fs", "thread", "map", "asynch"] }
serde = { workspace = true, optional = true }
rayon = { workspace = true }
tower = { workspace = true }
futures = { workspace = true }
futures = { workspace = true, features = ["std"] }
crossbeam = { workspace = true, features = ["std"] }
[lints]

View file

@ -9,18 +9,17 @@ repository = "https://github.com/Cuprate/cuprate/tree/main/storage/txpool"
keywords = ["cuprate", "txpool", "transaction", "pool", "database"]
[features]
default = ["heed", "service"]
default = ["heed"]
# 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"]
serde = ["dep:serde", "cuprate-database/serde", "cuprate-database-service/serde"]
[dependencies]
cuprate-database = { workspace = true, features = ["heed"] }
cuprate-database-service = { workspace = true, optional = true }
cuprate-database-service = { workspace = true }
cuprate-types = { workspace = true }
cuprate-helper = { workspace = true, default-features = false, features = ["constants"] }
@ -28,11 +27,11 @@ 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 }
hex = { workspace = true, features = ["std"] }
blake3 = { workspace = true, features = ["std"] }
tower = { workspace = true, optional = true }
rayon = { workspace = true, optional = true }
tower = { workspace = true }
rayon = { workspace = true }
serde = { workspace = true, optional = true }

View file

@ -37,10 +37,6 @@ use cuprate_txpool::{
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)

View file

@ -4,10 +4,12 @@
clippy::significant_drop_tightening
)]
// Used in docs: <https://github.com/Cuprate/cuprate/pull/170#discussion_r1823644357>.
use tower as _;
pub mod config;
mod free;
pub mod ops;
#[cfg(feature = "service")]
pub mod service;
pub mod tables;
mod tx;
@ -20,8 +22,6 @@ pub use tx::TxEntry;
//re-exports
pub use cuprate_database;
// TODO: remove when used.
use tower as _;
#[cfg(test)]
mod test {
use cuprate_test_utils as _;

View file

@ -10,8 +10,6 @@
//!
//! The system is managed by this crate, and only requires [`init`] by the user.
//!
//! This module must be enabled with the `service` feature.
//!
//! ## Handles
//! The 2 handles to the database are:
//! - [`TxpoolReadHandle`]
@ -42,7 +40,7 @@
//! To interact with the database (whether reading or writing data),
//! a `Request` can be sent using one of the above handles.
//!
//! Both the handles implement `tower::Service`, so they can be [`tower::Service::call`]ed.
//! Both the handles implement [`tower::Service`], so they can be [`tower::Service::call`]ed.
//!
//! An `async`hronous channel will be returned from the call.
//! This channel can be `.await`ed upon to (eventually) receive

View file

@ -12,21 +12,23 @@ keywords = ["cuprate", "types"]
default = ["blockchain", "epee", "serde", "json", "hex"]
blockchain = []
epee = ["dep:cuprate-epee-encoding"]
serde = ["dep:serde"]
serde = ["dep:serde", "hex"]
proptest = ["dep:proptest", "dep:proptest-derive"]
json = ["hex", "dep:cuprate-helper"]
hex = ["dep:hex"]
# We sadly have no choice but to enable serde here as otherwise we will get warnings from the `hex` dep being unused.
# This isn't too bad as `HexBytes` only makes sense with serde anyway.
hex = ["serde", "dep:hex"]
[dependencies]
cuprate-epee-encoding = { workspace = true, optional = true, features = ["std"] }
cuprate-helper = { workspace = true, optional = true, features = ["cast"] }
cuprate-fixed-bytes = { workspace = true }
cuprate-fixed-bytes = { workspace = true, features = ["std", "serde"] }
bytes = { workspace = true }
curve25519-dalek = { workspace = true }
monero-serai = { workspace = true }
hex = { workspace = true, features = ["serde", "alloc"], optional = true }
serde = { workspace = true, features = ["derive"], optional = true }
serde = { workspace = true, features = ["std", "derive"], optional = true }
strum = { workspace = true, features = ["derive"] }
thiserror = { workspace = true }

View file

@ -22,6 +22,7 @@ pub struct HexBytes<const N: usize>(
#[cfg_attr(feature = "serde", serde(with = "hex::serde"))] pub [u8; N],
);
#[cfg(feature = "serde")]
impl<'de, const N: usize> Deserialize<'de> for HexBytes<N>
where
[u8; N]: hex::FromHex,

View file

@ -51,17 +51,17 @@ impl From<block::Block> for Block {
/// [`Block::miner_tx`].
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[serde(untagged)]
#[cfg_attr(feature = "serde", serde(untagged))]
pub enum MinerTransaction {
V1 {
/// This field is [flattened](https://serde.rs/field-attrs.html#flatten).
#[serde(flatten)]
#[cfg_attr(feature = "serde", serde(flatten))]
prefix: MinerTransactionPrefix,
signatures: [(); 0],
},
V2 {
/// This field is [flattened](https://serde.rs/field-attrs.html#flatten).
#[serde(flatten)]
#[cfg_attr(feature = "serde", serde(flatten))]
prefix: MinerTransactionPrefix,
rct_signatures: MinerTransactionRctSignatures,
},

View file

@ -20,7 +20,7 @@ pub struct Output {
/// [`Output::target`].
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[serde(untagged)]
#[cfg_attr(feature = "serde", serde(untagged))]
pub enum Target {
Key { key: HexBytes<32> },
TaggedKey { tagged_key: TaggedKey },

View file

@ -24,17 +24,17 @@ use crate::{
/// - [`/get_transaction_pool` -> `tx_json`](https://www.getmonero.org/resources/developer-guides/daemon-rpc.html#get_transaction_pool)
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[serde(untagged)]
#[cfg_attr(feature = "serde", serde(untagged))]
pub enum Transaction {
V1 {
/// This field is [flattened](https://serde.rs/field-attrs.html#flatten).
#[serde(flatten)]
#[cfg_attr(feature = "serde", serde(flatten))]
prefix: TransactionPrefix,
signatures: Vec<HexBytes<64>>,
},
V2 {
/// This field is [flattened](https://serde.rs/field-attrs.html#flatten).
#[serde(flatten)]
#[cfg_attr(feature = "serde", serde(flatten))]
prefix: TransactionPrefix,
rct_signatures: RctSignatures,
/// This field is [`Some`] if [`Self::V2::rct_signatures`]