Compare commits

..

6 commits

Author SHA1 Message Date
hinto.janai
e7f052f1d0
fixes
Some checks failed
Audit / audit (push) Has been cancelled
Deny / audit (push) Has been cancelled
2024-10-02 20:20:01 -04:00
hinto.janai
42d6f97847
AlternateChains, docs 2024-10-02 20:02:07 -04:00
hinto.janai
64a3e5d5e9
blockchain docs/types 2024-10-02 17:04:02 -04:00
hinto.janai
cf331885b6
txpool docs/types 2024-10-02 16:06:49 -04:00
hinto.janai
41f4b788b3
Merge branch 'main' into rpc-msgs 2024-10-02 15:32:56 -04:00
hinto-janai
a003e0588d
Add constants/ crate (#280)
Some checks failed
Architecture mdBook / build (push) Has been cancelled
Audit / audit (push) Has been cancelled
CI / fmt (push) Has been cancelled
CI / typo (push) Has been cancelled
CI / ci (macos-latest, stable, bash) (push) Has been cancelled
CI / ci (ubuntu-latest, stable, bash) (push) Has been cancelled
CI / ci (windows-latest, stable-x86_64-pc-windows-gnu, msys2 {0}) (push) Has been cancelled
Deny / audit (push) Has been cancelled
Doc / build (push) Has been cancelled
Doc / deploy (push) Has been cancelled
* add `constants/`

* ci: add `A-constants` labeler

* add modules, move `cuprate_helper::constants`

* add `genesis.rs`

* `rpc.rs` docs

* remove todos

* `CRYPTONOTE_MAX_BLOCK_HEIGHT`

* add genesis data for all networks

* features

* fix feature cfgs

* test fixes

* add to architecture book

* fix comment

* remove `genesis` add other constants

* fixes

* revert

* fix
2024-10-02 18:51:58 +01:00
45 changed files with 517 additions and 172 deletions

4
.github/labeler.yml vendored
View file

@ -56,6 +56,10 @@ A-cryptonight:
- changed-files:
- any-glob-to-any-file: cryptonight/**
A-constants:
- changed-files:
- any-glob-to-any-file: constants/**
A-storage:
- changed-files:
- any-glob-to-any-file: storage/**

10
Cargo.lock generated
View file

@ -518,6 +518,7 @@ name = "cuprate-address-book"
version = "0.1.0"
dependencies = [
"borsh",
"cuprate-constants",
"cuprate-p2p-core",
"cuprate-pruning",
"cuprate-test-utils",
@ -547,6 +548,7 @@ version = "0.0.0"
dependencies = [
"bitflags 2.6.0",
"bytemuck",
"cuprate-constants",
"cuprate-database",
"cuprate-database-service",
"cuprate-helper",
@ -602,6 +604,7 @@ version = "0.1.0"
dependencies = [
"cfg-if",
"crypto-bigint",
"cuprate-constants",
"cuprate-cryptonight",
"cuprate-helper",
"cuprate-types",
@ -618,6 +621,10 @@ dependencies = [
"tracing",
]
[[package]]
name = "cuprate-constants"
version = "0.1.0"
[[package]]
name = "cuprate-cryptonight"
version = "0.1.0"
@ -719,6 +726,7 @@ version = "0.1.0"
dependencies = [
"chrono",
"crossbeam",
"cuprate-constants",
"curve25519-dalek",
"dirs",
"futures",
@ -764,6 +772,7 @@ dependencies = [
"bytes",
"cuprate-address-book",
"cuprate-async-buffer",
"cuprate-constants",
"cuprate-fixed-bytes",
"cuprate-helper",
"cuprate-p2p-core",
@ -817,6 +826,7 @@ name = "cuprate-pruning"
version = "0.1.0"
dependencies = [
"borsh",
"cuprate-constants",
"thiserror",
]

View file

@ -3,6 +3,7 @@ resolver = "2"
members = [
"binaries/cuprated",
"constants",
"consensus",
"consensus/fast-sync",
"consensus/rules",

View file

@ -116,7 +116,7 @@ pub struct CupratedRpcHandler {
}
impl CupratedRpcHandler {
/// TODO
/// Create a new [`Self`].
pub const fn new(
restricted: bool,
blockchain_read: BlockchainReadHandle,

View file

@ -12,7 +12,8 @@ use tower::{Service, ServiceExt};
use cuprate_helper::cast::{u64_to_usize, usize_to_u64};
use cuprate_types::{
blockchain::{BlockchainReadRequest, BlockchainResponse},
Chain, ExtendedBlockHeader, OutputOnChain,
Chain, CoinbaseTxSum, ExtendedBlockHeader, MinerData, OutputHistogramEntry,
OutputHistogramInput, OutputOnChain,
};
/// [`BlockchainReadRequest::BlockExtendedHeader`].
@ -290,38 +291,46 @@ pub(super) async fn difficulty(
/// [`BlockchainReadRequest::OutputHistogram`]
pub(super) async fn output_histogram(
mut blockchain_read: BlockchainReadHandle,
) -> Result<(), Error> {
let BlockchainResponse::OutputHistogram(_) = blockchain_read
input: OutputHistogramInput,
) -> Result<Vec<OutputHistogramEntry>, Error> {
let BlockchainResponse::OutputHistogram(histogram) = blockchain_read
.ready()
.await?
.call(BlockchainReadRequest::OutputHistogram)
.call(BlockchainReadRequest::OutputHistogram(input))
.await?
else {
unreachable!();
};
Ok(todo!())
Ok(histogram)
}
/// [`BlockchainReadRequest::CoinbaseTxSum`]
pub(super) async fn coinbase_tx_sum(
mut blockchain_read: BlockchainReadHandle,
) -> Result<(), Error> {
let BlockchainResponse::CoinbaseTxSum(_) = blockchain_read
height: u64,
count: u64,
) -> Result<CoinbaseTxSum, Error> {
let BlockchainResponse::CoinbaseTxSum(sum) = blockchain_read
.ready()
.await?
.call(BlockchainReadRequest::CoinbaseTxSum)
.call(BlockchainReadRequest::CoinbaseTxSum {
height: u64_to_usize(height),
count,
})
.await?
else {
unreachable!();
};
Ok(todo!())
Ok(sum)
}
/// [`BlockchainReadRequest::MinerData`]
pub(super) async fn miner_data(mut blockchain_read: BlockchainReadHandle) -> Result<(), Error> {
let BlockchainResponse::MinerData(_) = blockchain_read
pub(super) async fn miner_data(
mut blockchain_read: BlockchainReadHandle,
) -> Result<MinerData, Error> {
let BlockchainResponse::MinerData(data) = blockchain_read
.ready()
.await?
.call(BlockchainReadRequest::MinerData)
@ -330,5 +339,5 @@ pub(super) async fn miner_data(mut blockchain_read: BlockchainReadHandle) -> Res
unreachable!();
};
Ok(todo!())
Ok(data)
}

View file

@ -9,7 +9,7 @@ use cuprate_consensus::context::{
BlockChainContext, BlockChainContextRequest, BlockChainContextResponse,
BlockChainContextService,
};
use cuprate_types::HardFork;
use cuprate_types::{FeeEstimate, HardFork, HardForkInfo};
/// [`BlockChainContextRequest::Context`].
pub(super) async fn context(
@ -34,7 +34,7 @@ pub(super) async fn context(
pub(super) async fn hard_fork_info(
service: &mut BlockChainContextService,
hard_fork: HardFork,
) -> Result<Infallible, Error> {
) -> Result<HardForkInfo, Error> {
let BlockChainContextResponse::HardForkInfo(hf_info) = service
.ready()
.await
@ -53,8 +53,8 @@ pub(super) async fn hard_fork_info(
pub(super) async fn fee_estimate(
service: &mut BlockChainContextService,
grace_blocks: u64,
) -> Result<Infallible, Error> {
let BlockChainContextResponse::FeeEstimate(hf_info) = service
) -> Result<FeeEstimate, Error> {
let BlockChainContextResponse::FeeEstimate(fee) = service
.ready()
.await
.expect("TODO")
@ -65,5 +65,5 @@ pub(super) async fn fee_estimate(
unreachable!();
};
Ok(hf_info)
Ok(fee)
}

View file

@ -1,4 +1,4 @@
//! Functions for TODO: doc enum message.
//! Functions for [`BlockchainManagerRequest`] & [`BlockchainManagerResponse`].
use anyhow::Error;
use monero_serai::block::Block;

View file

@ -1,4 +1,4 @@
//! Functions for TODO: doc enum message.
//! Functions for [`TxpoolReadRequest`].
use std::convert::Infallible;
@ -6,14 +6,17 @@ use anyhow::Error;
use tower::{Service, ServiceExt};
use cuprate_helper::cast::usize_to_u64;
use cuprate_txpool::service::{
interface::{TxpoolReadRequest, TxpoolReadResponse},
TxpoolReadHandle,
use cuprate_txpool::{
service::{
interface::{TxpoolReadRequest, TxpoolReadResponse},
TxpoolReadHandle,
},
TxEntry,
};
/// [`TxpoolReadRequest::Backlog`]
pub(super) async fn backlog(txpool_read: &mut TxpoolReadHandle) -> Result<Vec<Infallible>, Error> {
let TxpoolReadResponse::Backlog(backlog) = txpool_read
pub(super) async fn backlog(txpool_read: &mut TxpoolReadHandle) -> Result<Vec<TxEntry>, Error> {
let TxpoolReadResponse::Backlog(tx_entries) = txpool_read
.ready()
.await
.expect("TODO")
@ -24,7 +27,7 @@ pub(super) async fn backlog(txpool_read: &mut TxpoolReadHandle) -> Result<Vec<In
unreachable!();
};
Ok(backlog)
Ok(tx_entries)
}
/// [`TxpoolReadRequest::Size`]

View file

@ -55,6 +55,7 @@ cargo doc --open --package cuprate-blockchain
## 1-off crates
| Crate | In-tree path | Purpose |
|-------|--------------|---------|
| [`cuprate-constants`](https://doc.cuprate.org/cuprate_constants) | [`constants/`](https://github.com/Cuprate/cuprate/tree/main/constants) | Shared `const/static` data across Cuprate
| [`cuprate-cryptonight`](https://doc.cuprate.org/cuprate_cryptonight) | [`cryptonight/`](https://github.com/Cuprate/cuprate/tree/main/cryptonight) | CryptoNight hash functions
| [`cuprate-pruning`](https://doc.cuprate.org/cuprate_pruning) | [`pruning/`](https://github.com/Cuprate/cuprate/tree/main/pruning) | Monero pruning logic/types
| [`cuprate-helper`](https://doc.cuprate.org/cuprate_helper) | [`helper/`](https://github.com/Cuprate/cuprate/tree/main/helper) | Kitchen-sink helper crate for Cuprate

View file

@ -11,6 +11,7 @@ proptest = ["cuprate-types/proptest"]
rayon = ["dep:rayon"]
[dependencies]
cuprate-constants = { path = "../../constants", default-features = false }
cuprate-helper = { path = "../../helper", default-features = false, features = ["std", "cast"] }
cuprate-types = { path = "../../types", default-features = false }
cuprate-cryptonight = {path = "../../cryptonight"}

View file

@ -1,5 +1,6 @@
use monero_serai::transaction::{Input, Output, Timelock, Transaction};
use cuprate_constants::block::MAX_BLOCK_HEIGHT_USIZE;
use cuprate_types::TxVersion;
use crate::{is_decomposed_amount, transactions::check_output_types, HardFork};
@ -112,7 +113,7 @@ const fn check_time_lock(time_lock: &Timelock, chain_height: usize) -> Result<()
&Timelock::Block(till_height) => {
// Lock times above this amount are timestamps not blocks.
// This is just for safety though and shouldn't actually be hit.
if till_height > 500_000_000 {
if till_height > MAX_BLOCK_HEIGHT_USIZE {
return Err(MinerTxError::InvalidLockTime);
}
if till_height == chain_height + MINER_TX_TIME_LOCKED_BLOCKS {

View file

@ -9,6 +9,7 @@ use proptest::{collection::vec, prelude::*};
use monero_serai::transaction::Output;
use cuprate_constants::block::MAX_BLOCK_HEIGHT;
use cuprate_helper::cast::u64_to_usize;
use super::*;
@ -160,10 +161,10 @@ prop_compose! {
/// Returns a [`Timelock`] that is locked given a height and time.
fn locked_timelock(height: u64, time_for_time_lock: u64)(
timebased in any::<bool>(),
lock_height in (height+1)..500_000_001,
lock_height in (height+1)..=MAX_BLOCK_HEIGHT,
time_for_time_lock in (time_for_time_lock+121)..,
) -> Timelock {
if timebased || lock_height > 500_000_000 {
if timebased || lock_height > MAX_BLOCK_HEIGHT {
Timelock::Time(time_for_time_lock)
} else {
Timelock::Block(u64_to_usize(lock_height))
@ -240,7 +241,7 @@ proptest! {
}
#[test]
fn test_timestamp_time_lock(timestamp in 500_000_001..u64::MAX) {
fn test_timestamp_time_lock(timestamp in MAX_BLOCK_HEIGHT+1..u64::MAX) {
prop_assert!(check_timestamp_time_lock(timestamp, timestamp - 120, HardFork::V16));
prop_assert!(!check_timestamp_time_lock(timestamp, timestamp - 121, HardFork::V16));
prop_assert!(check_timestamp_time_lock(timestamp, timestamp, HardFork::V16));

View file

@ -31,7 +31,7 @@ mod alt_chains;
mod task;
mod tokens;
use cuprate_types::Chain;
use cuprate_types::{Chain, ChainInfo, FeeEstimate, HardForkInfo};
use difficulty::DifficultyCache;
use rx_vms::RandomXVm;
use weight::BlockWeightsCache;
@ -254,9 +254,21 @@ pub enum BlockChainContextRequest {
numb_blocks: usize,
},
/// Get information on a certain hardfork.
HardForkInfo(HardFork),
/// Get the current fee estimate.
FeeEstimate {
/// TODO
grace_blocks: u64,
},
/// Clear the alt chain context caches.
ClearAltCache,
/// Get information on all the current alternate chains.
AltChains,
//----------------------------------------------------------------------------------------------------------- AltChainRequests
/// A request for an alt chain context cache.
///
@ -318,15 +330,6 @@ pub enum BlockChainContextRequest {
/// An internal token to prevent external crates calling this request.
_token: AltChainRequestToken,
},
/// TODO
HardForkInfo(HardFork),
/// TODO
FeeEstimate {
/// TODO
grace_blocks: u64,
},
}
pub enum BlockChainContextResponse {
@ -343,7 +346,6 @@ pub enum BlockChainContextResponse {
/// Response to [`BlockChainContextRequest::Context`]
Context(BlockChainContext),
// TODO: why does this return a `HashMap` when the request is `CurrentRxVm`?
/// Response to [`BlockChainContextRequest::CurrentRxVm`]
///
/// A map of seed height to `RandomX` VMs.
@ -352,6 +354,17 @@ pub enum BlockChainContextResponse {
/// A list of difficulties.
BatchDifficulties(Vec<u128>),
/// Response to [`BlockChainContextRequest::HardForkInfo`]
HardForkInfo(HardForkInfo),
/// Response to [`BlockChainContextRequest::FeeEstimate`]
FeeEstimate(FeeEstimate),
/// Response to [`BlockChainContextRequest::AltChains`]
///
/// If the inner [`Vec::is_empty`], there were no alternate chains.
AltChains(Vec<ChainInfo>),
/// An alt chain context cache.
AltChainContextCache(Box<AltChainContextCache>),
@ -363,16 +376,6 @@ pub enum BlockChainContextResponse {
/// A weight cache for an alt chain
AltChainWeightCache(BlockWeightsCache),
/// Response to [`BlockChainContextRequest::HardForkInfo`]
///
/// TODO
HardForkInfo(std::convert::Infallible /* TODO */),
/// Response to [`BlockChainContextRequest::FeeEstimate`]
///
/// TODO
FeeEstimate(std::convert::Infallible /* TODO */),
}
/// The blockchain context service.

View file

@ -326,7 +326,8 @@ impl<D: Database + Clone + Send + 'static> ContextTask<D> {
BlockChainContextResponse::Ok
}
BlockChainContextRequest::HardForkInfo(_)
| BlockChainContextRequest::FeeEstimate { .. } => {
| BlockChainContextRequest::FeeEstimate { .. }
| BlockChainContextRequest::AltChains => {
todo!("finish https://github.com/Cuprate/cuprate/pull/297")
}
})

22
constants/Cargo.toml Normal file
View file

@ -0,0 +1,22 @@
[package]
name = "cuprate-constants"
version = "0.1.0"
edition = "2021"
description = "Constant/static data used throughout Cuprate"
license = "MIT"
authors = ["hinto-janai"]
repository = "https://github.com/Cuprate/cuprate/tree/main/constants"
keywords = ["cuprate", "constants"]
[features]
default = []
block = []
build = []
rpc = []
[dependencies]
[dev-dependencies]
[lints]
workspace = true

3
constants/README.md Normal file
View file

@ -0,0 +1,3 @@
# cuprate-constants
This crate contains general constants that are not specific to any particular
part of the codebase yet are used in multiple places such as the maximum block height.

View file

@ -1,9 +1,7 @@
fn main() {
#[cfg(feature = "constants")]
set_commit_env();
}
#[cfg(feature = "constants")]
/// This sets the git `COMMIT` environment variable.
fn set_commit_env() {
const PATH: &str = "../.git/refs/heads/";

11
constants/src/block.rs Normal file
View file

@ -0,0 +1,11 @@
//! Block related.
use crate::macros::monero_definition_link;
/// The maximum block height possible.
#[doc = monero_definition_link!(a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623, "/src/cryptonote_config.h", 40)]
pub const MAX_BLOCK_HEIGHT: u64 = 500_000_000;
/// [`MAX_BLOCK_HEIGHT`] as a [`usize`].
#[expect(clippy::cast_possible_truncation, reason = "will not be truncated")]
pub const MAX_BLOCK_HEIGHT_USIZE: usize = MAX_BLOCK_HEIGHT as usize;

22
constants/src/build.rs Normal file
View file

@ -0,0 +1,22 @@
//! Build related metadata.
/// The current commit hash of the root Cuprate repository.
///
/// # Case & length
/// It is guaranteed that `COMMIT` will be:
/// - Lowercase ASCII
/// - 40 characters long (no newline)
///
/// ```rust
/// # use cuprate_constants::build::*;
/// assert!(COMMIT.is_ascii());
/// assert_eq!(COMMIT.as_bytes().len(), 40);
/// assert_eq!(COMMIT.to_lowercase(), COMMIT);
/// ```
pub const COMMIT: &str = core::env!("COMMIT"); // Set in `constants/build.rs`.
/// `true` if debug build, else `false`.
pub const DEBUG: bool = cfg!(debug_assertions);
/// `true` if release build, else `false`.
pub const RELEASE: bool = !DEBUG;

12
constants/src/lib.rs Normal file
View file

@ -0,0 +1,12 @@
#![doc = include_str!("../README.md")]
#![deny(missing_docs, reason = "all constants should document what they are")]
#![no_std] // This can be removed if we eventually need `std`.
mod macros;
#[cfg(feature = "block")]
pub mod block;
#[cfg(feature = "build")]
pub mod build;
#[cfg(feature = "rpc")]
pub mod rpc;

35
constants/src/macros.rs Normal file
View file

@ -0,0 +1,35 @@
/// Output a string link to `monerod` source code.
#[allow(
clippy::allow_attributes,
unused_macros,
reason = "used in feature gated modules"
)]
macro_rules! monero_definition_link {
(
$commit:ident, // Git commit hash
$file_path:literal, // File path within `monerod`'s `src/`, e.g. `rpc/core_rpc_server_commands_defs.h`
$start:literal$(..=$end:literal)? // File lines, e.g. `0..=123` or `0`
) => {
concat!(
"",
"[Original definition](https://github.com/monero-project/monero/blob/",
stringify!($commit),
"/src/",
$file_path,
"#L",
stringify!($start),
$(
"-L",
stringify!($end),
)?
")."
)
};
}
#[allow(
clippy::allow_attributes,
unused_imports,
reason = "used in feature gated modules"
)]
pub(crate) use monero_definition_link;

101
constants/src/rpc.rs Normal file
View file

@ -0,0 +1,101 @@
//! RPC related.
use core::time::Duration;
use crate::macros::monero_definition_link;
/// Maximum requestable block header range.
#[doc = monero_definition_link!(a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623, "/src/rpc/core_rpc_server.cpp", 74)]
///
/// This is the maximum amount of blocks that can be requested
/// per invocation of `get_block_headers` if the RPC server is
/// in restricted mode.
///
/// Used at:
/// - <https://github.com/monero-project/monero/blob/a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623/src/rpc/core_rpc_server.cpp#L2593>
pub const RESTRICTED_BLOCK_HEADER_RANGE: u64 = 1000;
/// Maximum requestable transaction count.
#[doc = monero_definition_link!(a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623, "/src/rpc/core_rpc_server.cpp", 75)]
///
/// This is the maximum amount of transactions that can be requested
/// per invocation of `get_transactions` and `get_indexes` if the
/// RPC server is in restricted mode.
///
/// Used at:
/// - <https://github.com/monero-project/monero/blob/a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623/src/rpc/core_rpc_server.cpp#L660>
/// - <https://github.com/monero-project/monero/blob/a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623/src/rpc/core_rpc_server.cpp#L998>
pub const RESTRICTED_TRANSACTIONS_COUNT: usize = 100;
/// Maximum amount of requestable key image checks.
#[doc = monero_definition_link!(a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623, "/src/rpc/core_rpc_server.cpp", 76)]
///
/// This is the maximum amount of key images that can be requested
/// to be checked per `/is_key_image_spent` call if the RPC server
/// is in restricted mode.
///
/// Used at:
/// - <https://github.com/monero-project/monero/blob/a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623/src/rpc/core_rpc_server.cpp#L1248>
/// - <https://github.com/monero-project/monero/blob/a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623/src/rpc/core_rpc_server.cpp#L3570>
pub const RESTRICTED_SPENT_KEY_IMAGES_COUNT: usize = 5000;
/// Maximum amount of requestable blocks.
#[doc = monero_definition_link!(a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623, "/src/rpc/core_rpc_server.cpp", 77)]
///
/// This is the maximum amount of blocks that can be
/// requested if the RPC server is in restricted mode.
///
/// Used at:
/// - <https://github.com/monero-project/monero/blob/a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623/src/rpc/core_rpc_server.cpp#L834>
/// - <https://github.com/monero-project/monero/blob/a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623/src/rpc/core_rpc_server.cpp#L2519>
pub const RESTRICTED_BLOCK_COUNT: usize = 1000;
/// Maximum amount of fake outputs.
#[doc = monero_definition_link!(a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623, "/src/rpc/core_rpc_server.cpp", 67)]
///
/// This is the maximum amount of outputs that can be
/// requested if the RPC server is in restricted mode.
///
/// Used at:
/// - <https://github.com/monero-project/monero/blob/a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623/src/rpc/core_rpc_server.cpp#L905>
/// - <https://github.com/monero-project/monero/blob/a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623/src/rpc/core_rpc_server.cpp#L935>
pub const MAX_RESTRICTED_GLOBAL_FAKE_OUTS_COUNT: usize = 5000;
/// Maximum output histrogram cutoff.
#[doc = monero_definition_link!(a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623, "/src/rpc/core_rpc_server.cpp", 69)]
///
/// This is the maximum cutoff duration allowed in `get_output_histogram` (3 days).
///
/// ```rust
/// # use cuprate_constants::rpc::*;
/// assert_eq!(OUTPUT_HISTOGRAM_RECENT_CUTOFF_RESTRICTION.as_secs(), 86_400 * 3);
/// ```
///
/// Used at:
/// <https://github.com/monero-project/monero/blob/a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623/src/rpc/core_rpc_server.cpp#L2961>
pub const OUTPUT_HISTOGRAM_RECENT_CUTOFF_RESTRICTION: Duration = Duration::from_secs(86400 * 3);
/// Maximum amount of requestable blocks in `/get_blocks.bin`.
#[doc = monero_definition_link!(a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623, "/src/cryptonote_config.h", 128)]
pub const GET_BLOCKS_BIN_MAX_BLOCK_COUNT: u64 = 1000;
/// Maximum amount of requestable transactions in `/get_blocks.bin`.
#[doc = monero_definition_link!(a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623, "/src/cryptonote_config.h", 129)]
pub const GET_BLOCKS_BIN_MAX_TX_COUNT: u64 = 20_000;
/// Max message content length in the RPC server.
#[doc = monero_definition_link!(a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623, "/src/cryptonote_config.h", 130)]
///
/// This is the maximum amount of bytes an HTTP request
/// body can be before the RPC server rejects it (1 megabyte).
pub const MAX_RPC_CONTENT_LENGTH: u64 = 1_048_576;
/// Amount of fails before blocking a remote RPC server.
#[doc = monero_definition_link!(a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623, "/src/cryptonote_config.h", 159)]
///
/// This is the amount of times an RPC will attempt to
/// connect to another remote IP before blocking it.
///
/// RPC servers connect to nodes when they themselves
/// lack the data to fulfill the response.
pub const RPC_IP_FAILS_BEFORE_BLOCK: u64 = 3;

View file

@ -18,12 +18,14 @@ cast = []
constants = []
fs = ["dep:dirs"]
num = []
map = ["cast", "dep:monero-serai"]
map = ["cast", "dep:monero-serai", "dep:cuprate-constants"]
time = ["dep:chrono", "std"]
thread = ["std", "dep:target_os_lib"]
tx = ["dep:monero-serai"]
[dependencies]
cuprate-constants = { path = "../constants", optional = true, features = ["block"] }
crossbeam = { workspace = true, optional = true }
chrono = { workspace = true, optional = true, features = ["std", "clock"] }
dirs = { workspace = true, optional = true }

View file

@ -1,22 +0,0 @@
//! General `const`ants and `static`s.
//!
//! `#[no_std]` compatible.
//---------------------------------------------------------------------------------------------------- Commit
/// The current commit hash of the root Cuprate repository.
///
/// # Case & length
/// It is guaranteed that `COMMIT` will be:
/// - Lowercase
/// - 40 characters long (no newline)
///
/// ```rust
/// # use cuprate_helper::constants::*;
/// assert_eq!(COMMIT.as_bytes().len(), 40);
/// assert_eq!(COMMIT.to_lowercase(), COMMIT);
/// ```
pub const COMMIT: &str = core::env!("COMMIT"); // Set in `helper/build.rs`.
//---------------------------------------------------------------------------------------------------- Tests
#[cfg(test)]
mod test {}

View file

@ -11,9 +11,6 @@ pub mod atomic;
#[cfg(feature = "cast")]
pub mod cast;
#[cfg(feature = "constants")]
pub mod constants;
#[cfg(feature = "fs")]
pub mod fs;

View file

@ -7,6 +7,8 @@
//---------------------------------------------------------------------------------------------------- Use
use monero_serai::transaction::Timelock;
use cuprate_constants::block::MAX_BLOCK_HEIGHT;
use crate::cast::{u64_to_usize, usize_to_u64};
//---------------------------------------------------------------------------------------------------- `(u64, u64) <-> u128`
@ -61,7 +63,7 @@ pub const fn combine_low_high_bits_to_u128(low_bits: u64, high_bits: u64) -> u12
/// Map a [`u64`] to a [`Timelock`].
///
/// Height/time is not differentiated via type, but rather:
/// "height is any value less than `500_000_000` and timestamp is any value above"
/// "height is any value less than [`MAX_BLOCK_HEIGHT`] and timestamp is any value above"
/// so the `u64/usize` is stored without any tag.
///
/// See [`timelock_to_u64`] for the inverse function.
@ -72,14 +74,15 @@ pub const fn combine_low_high_bits_to_u128(low_bits: u64, high_bits: u64) -> u12
/// ```rust
/// # use cuprate_helper::map::*;
/// # use monero_serai::transaction::*;
/// use cuprate_constants::block::{MAX_BLOCK_HEIGHT, MAX_BLOCK_HEIGHT_USIZE};
/// assert_eq!(u64_to_timelock(0), Timelock::None);
/// assert_eq!(u64_to_timelock(499_999_999), Timelock::Block(499_999_999));
/// assert_eq!(u64_to_timelock(500_000_000), Timelock::Time(500_000_000));
/// assert_eq!(u64_to_timelock(MAX_BLOCK_HEIGHT-1), Timelock::Block(MAX_BLOCK_HEIGHT_USIZE-1));
/// assert_eq!(u64_to_timelock(MAX_BLOCK_HEIGHT), Timelock::Time(MAX_BLOCK_HEIGHT));
/// ```
pub const fn u64_to_timelock(u: u64) -> Timelock {
if u == 0 {
Timelock::None
} else if u < 500_000_000 {
} else if u < MAX_BLOCK_HEIGHT {
Timelock::Block(u64_to_usize(u))
} else {
Timelock::Time(u)
@ -93,9 +96,10 @@ pub const fn u64_to_timelock(u: u64) -> Timelock {
/// ```rust
/// # use cuprate_helper::map::*;
/// # use monero_serai::transaction::*;
/// use cuprate_constants::block::{MAX_BLOCK_HEIGHT, MAX_BLOCK_HEIGHT_USIZE};
/// assert_eq!(timelock_to_u64(Timelock::None), 0);
/// assert_eq!(timelock_to_u64(Timelock::Block(499_999_999)), 499_999_999);
/// assert_eq!(timelock_to_u64(Timelock::Time(500_000_000)), 500_000_000);
/// assert_eq!(timelock_to_u64(Timelock::Block(MAX_BLOCK_HEIGHT_USIZE-1)), MAX_BLOCK_HEIGHT-1);
/// assert_eq!(timelock_to_u64(Timelock::Time(MAX_BLOCK_HEIGHT)), MAX_BLOCK_HEIGHT);
/// ```
pub const fn timelock_to_u64(timelock: Timelock) -> u64 {
match timelock {

View file

@ -7,6 +7,7 @@ authors = ["Boog900"]
[dependencies]
cuprate-constants = { path = "../../constants" }
cuprate-pruning = { path = "../../pruning" }
cuprate-p2p-core = { path = "../p2p-core" }

View file

@ -3,8 +3,9 @@ use std::collections::{BTreeMap, HashMap, HashSet};
use indexmap::IndexMap;
use rand::prelude::*;
use cuprate_constants::block::MAX_BLOCK_HEIGHT_USIZE;
use cuprate_p2p_core::{services::ZoneSpecificPeerListEntryBase, NetZoneAddress, NetworkZone};
use cuprate_pruning::{PruningSeed, CRYPTONOTE_MAX_BLOCK_HEIGHT};
use cuprate_pruning::PruningSeed;
#[cfg(test)]
pub(crate) mod tests;
@ -97,7 +98,7 @@ impl<Z: NetworkZone> PeerList<Z> {
if let Some(needed_height) = block_needed {
let (_, addresses_with_block) = self.pruning_seeds.iter().find(|(seed, _)| {
// TODO: factor in peer blockchain height?
seed.get_next_unpruned_block(needed_height, CRYPTONOTE_MAX_BLOCK_HEIGHT)
seed.get_next_unpruned_block(needed_height, MAX_BLOCK_HEIGHT_USIZE)
.expect("Block needed is higher than max block allowed.")
== needed_height
})?;

View file

@ -4,14 +4,14 @@ use std::time::{Duration, Instant};
use crate::NetZoneAddress;
/// TODO
/// Data within [`crate::services::AddressBookRequest::SetBan`].
pub struct SetBan<A: NetZoneAddress> {
pub address: A,
pub ban: bool,
pub duration: Duration,
}
/// TODO
/// Data within [`crate::services::AddressBookResponse::GetBans`].
pub struct BanState<A: NetZoneAddress> {
pub address: A,
pub banned: bool,

View file

@ -133,7 +133,7 @@ pub enum AddressBookRequest<Z: NetworkZone> {
/// A response from the address book service.
pub enum AddressBookResponse<Z: NetworkZone> {
/// TODO
/// Generic OK response.
///
/// Response to:
/// - [`AddressBookRequest::NewConnection`]

View file

@ -6,6 +6,7 @@ license = "MIT"
authors = ["Boog900"]
[dependencies]
cuprate-constants = { path = "../../constants" }
cuprate-fixed-bytes = { path = "../../net/fixed-bytes" }
cuprate-wire = { path = "../../net/wire" }
cuprate-p2p-core = { path = "../p2p-core", features = ["borsh"] }

View file

@ -22,8 +22,9 @@ use tower::{Service, ServiceExt};
use tracing::{instrument, Instrument, Span};
use cuprate_async_buffer::{BufferAppender, BufferStream};
use cuprate_constants::block::MAX_BLOCK_HEIGHT_USIZE;
use cuprate_p2p_core::{handles::ConnectionHandle, NetworkZone};
use cuprate_pruning::{PruningSeed, CRYPTONOTE_MAX_BLOCK_HEIGHT};
use cuprate_pruning::PruningSeed;
use crate::{
client_pool::{ClientPool, ClientPoolDropGuard},
@ -670,8 +671,8 @@ const fn client_has_block_in_range(
start_height: usize,
length: usize,
) -> bool {
pruning_seed.has_full_block(start_height, CRYPTONOTE_MAX_BLOCK_HEIGHT)
&& pruning_seed.has_full_block(start_height + length, CRYPTONOTE_MAX_BLOCK_HEIGHT)
pruning_seed.has_full_block(start_height, MAX_BLOCK_HEIGHT_USIZE)
&& pruning_seed.has_full_block(start_height + length, MAX_BLOCK_HEIGHT_USIZE)
}
/// Calculates the next amount of blocks to request in a batch.

View file

@ -119,12 +119,13 @@ mod tests {
use proptest::{collection::vec, prelude::*};
use tokio_test::block_on;
use cuprate_constants::block::MAX_BLOCK_HEIGHT_USIZE;
use cuprate_p2p_core::handles::HandleBuilder;
use super::*;
prop_compose! {
fn ready_batch_strategy()(start_height in 0_usize..500_000_000) -> ReadyQueueBatch {
fn ready_batch_strategy()(start_height in 0..MAX_BLOCK_HEIGHT_USIZE) -> ReadyQueueBatch {
let (_, peer_handle) = HandleBuilder::new().build();
ReadyQueueBatch {

View file

@ -2,8 +2,9 @@ use std::{cmp::min, collections::VecDeque};
use cuprate_fixed_bytes::ByteArrayVec;
use cuprate_constants::block::MAX_BLOCK_HEIGHT_USIZE;
use cuprate_p2p_core::{client::InternalPeerID, handles::ConnectionHandle, NetworkZone};
use cuprate_pruning::{PruningSeed, CRYPTONOTE_MAX_BLOCK_HEIGHT};
use cuprate_pruning::PruningSeed;
use crate::constants::MEDIUM_BAN;
@ -87,7 +88,7 @@ impl<N: NetworkZone> ChainTracker<N> {
/// Returns `true` if the peer is expected to have the next block after our highest seen block
/// according to their pruning seed.
pub(crate) fn should_ask_for_next_chain_entry(&self, seed: &PruningSeed) -> bool {
seed.has_full_block(self.top_height(), CRYPTONOTE_MAX_BLOCK_HEIGHT)
seed.has_full_block(self.top_height(), MAX_BLOCK_HEIGHT_USIZE)
}
/// Returns the simple history, the highest seen block and the genesis block.
@ -162,7 +163,7 @@ impl<N: NetworkZone> ChainTracker<N> {
pruning_seed: &PruningSeed,
max_blocks: usize,
) -> Option<BlocksToRetrieve<N>> {
if !pruning_seed.has_full_block(self.first_height, CRYPTONOTE_MAX_BLOCK_HEIGHT) {
if !pruning_seed.has_full_block(self.first_height, MAX_BLOCK_HEIGHT_USIZE) {
return None;
}
@ -175,10 +176,10 @@ impl<N: NetworkZone> ChainTracker<N> {
let end_idx = min(
min(entry.ids.len(), max_blocks),
pruning_seed
.get_next_pruned_block(self.first_height, CRYPTONOTE_MAX_BLOCK_HEIGHT)
.get_next_pruned_block(self.first_height, MAX_BLOCK_HEIGHT_USIZE)
.expect("We use local values to calculate height which should be below the sanity limit")
// Use a big value as a fallback if the seed does no pruning.
.unwrap_or(CRYPTONOTE_MAX_BLOCK_HEIGHT)
.unwrap_or(MAX_BLOCK_HEIGHT_USIZE)
- self.first_height,
);

View file

@ -10,6 +10,8 @@ default = []
borsh = ["dep:borsh"]
[dependencies]
cuprate-constants = { path = "../constants" }
thiserror = { workspace = true }
borsh = { workspace = true, features = ["derive", "std"], optional = true }

View file

@ -20,9 +20,10 @@
use std::cmp::Ordering;
use cuprate_constants::block::MAX_BLOCK_HEIGHT_USIZE;
use thiserror::Error;
pub const CRYPTONOTE_MAX_BLOCK_HEIGHT: usize = 500000000;
/// The default log stripes for Monero pruning.
pub const CRYPTONOTE_PRUNING_LOG_STRIPES: u32 = 3;
/// The amount of blocks that peers keep before another stripe starts storing blocks.
@ -41,9 +42,9 @@ pub enum PruningError {
LogStripesOutOfRange,
#[error("Stripe is out of range")]
StripeOutOfRange,
#[error("The block height is greater than `CRYPTONOTE_MAX_BLOCK_HEIGHT`")]
#[error("The block height is greater than `MAX_BLOCK_HEIGHT_USIZE`")]
BlockHeightTooLarge,
#[error("The blockchain height is greater than `CRYPTONOTE_MAX_BLOCK_HEIGHT`")]
#[error("The blockchain height is greater than `MAX_BLOCK_HEIGHT_USIZE`")]
BlockChainHeightTooLarge,
#[error("The calculated height is smaller than the block height entered")]
CalculatedHeightSmallerThanEnteredBlock,
@ -144,7 +145,7 @@ impl PruningSeed {
/// ### Errors
///
/// This function will return an Error if the inputted `block_height` or
/// `blockchain_height` is greater than [`CRYPTONOTE_MAX_BLOCK_HEIGHT`].
/// `blockchain_height` is greater than [`MAX_BLOCK_HEIGHT_USIZE`].
///
/// This function will also error if `block_height` > `blockchain_height`
pub fn get_next_pruned_block(
@ -167,7 +168,7 @@ impl PruningSeed {
/// ### Errors
///
/// This function will return an Error if the inputted `block_height` or
/// `blockchain_height` is greater than [`CRYPTONOTE_MAX_BLOCK_HEIGHT`].
/// `blockchain_height` is greater than [`MAX_BLOCK_HEIGHT_USIZE`].
///
/// This function will also error if `block_height` > `blockchain_height`
///
@ -322,7 +323,7 @@ impl DecompressedPruningSeed {
/// ### Errors
///
/// This function will return an Error if the inputted `block_height` or
/// `blockchain_height` is greater than [`CRYPTONOTE_MAX_BLOCK_HEIGHT`].
/// `blockchain_height` is greater than [`MAX_BLOCK_HEIGHT_USIZE`].
///
/// This function will also error if `block_height` > `blockchain_height`
///
@ -331,11 +332,11 @@ impl DecompressedPruningSeed {
block_height: usize,
blockchain_height: usize,
) -> Result<usize, PruningError> {
if block_height > CRYPTONOTE_MAX_BLOCK_HEIGHT || block_height > blockchain_height {
if block_height > MAX_BLOCK_HEIGHT_USIZE || block_height > blockchain_height {
return Err(PruningError::BlockHeightTooLarge);
}
if blockchain_height > CRYPTONOTE_MAX_BLOCK_HEIGHT {
if blockchain_height > MAX_BLOCK_HEIGHT_USIZE {
return Err(PruningError::BlockChainHeightTooLarge);
}
@ -388,7 +389,7 @@ impl DecompressedPruningSeed {
/// ### Errors
///
/// This function will return an Error if the inputted `block_height` or
/// `blockchain_height` is greater than [`CRYPTONOTE_MAX_BLOCK_HEIGHT`].
/// `blockchain_height` is greater than [`MAX_BLOCK_HEIGHT_USIZE`].
///
/// This function will also error if `block_height` > `blockchain_height`
///

View file

@ -37,6 +37,7 @@ thread_local = { workspace = true, optional = true }
rayon = { workspace = true, optional = true }
[dev-dependencies]
cuprate-constants = { path = "../../constants" }
cuprate-helper = { path = "../../helper", features = ["thread", "cast"] }
cuprate-test-utils = { path = "../../test-utils" }

View file

@ -128,11 +128,13 @@ pub(super) fn map_valid_alt_block_to_verified_block(
mod tests {
use proptest::prelude::*;
use cuprate_constants::block::MAX_BLOCK_HEIGHT_USIZE;
use super::*;
proptest! {
#[test]
fn compact_history(top_height in 0_usize..500_000_000) {
fn compact_history(top_height in 0..MAX_BLOCK_HEIGHT_USIZE) {
let mut heights = (0..)
.map(compact_history_index_to_height_offset::<11>)
.map_while(|i| top_height.checked_sub(i))

View file

@ -4,6 +4,7 @@
unreachable_code,
unused_variables,
clippy::unnecessary_wraps,
clippy::needless_pass_by_value,
reason = "TODO: finish implementing the signatures from <https://github.com/Cuprate/cuprate/pull/297>"
)]
@ -25,7 +26,7 @@ use cuprate_database_service::{init_thread_pool, DatabaseReadService, ReaderThre
use cuprate_helper::map::combine_low_high_bits_to_u128;
use cuprate_types::{
blockchain::{BlockchainReadRequest, BlockchainResponse},
Chain, ChainId, ExtendedBlockHeader, OutputOnChain,
Chain, ChainId, ExtendedBlockHeader, OutputHistogramInput, OutputOnChain,
};
use crate::{
@ -114,13 +115,13 @@ fn map_request(
R::CompactChainHistory => compact_chain_history(env),
R::FindFirstUnknown(block_ids) => find_first_unknown(env, &block_ids),
R::AltBlocksInChain(chain_id) => alt_blocks_in_chain(env, chain_id),
R::Block(height) => block(env, height),
R::Block { height } => block(env, height),
R::BlockByHash(hash) => block_by_hash(env, hash),
R::TotalTxCount => total_tx_count(env),
R::DatabaseSize => database_size(env),
R::Difficulty(height) => difficulty(env, height),
R::OutputHistogram => output_histogram(env),
R::CoinbaseTxSum => coinbase_tx_sum(env),
R::OutputHistogram(input) => output_histogram(env, input),
R::CoinbaseTxSum { height, count } => coinbase_tx_sum(env, height, count),
R::MinerData => miner_data(env),
}
@ -646,12 +647,12 @@ fn difficulty(env: &ConcreteEnv, block_height: BlockHeight) -> ResponseResult {
}
/// [`BlockchainReadRequest::OutputHistogram`]
fn output_histogram(env: &ConcreteEnv) -> ResponseResult {
fn output_histogram(env: &ConcreteEnv, input: OutputHistogramInput) -> ResponseResult {
Ok(BlockchainResponse::OutputHistogram(todo!()))
}
/// [`BlockchainReadRequest::CoinbaseTxSum`]
fn coinbase_tx_sum(env: &ConcreteEnv) -> ResponseResult {
fn coinbase_tx_sum(env: &ConcreteEnv, height: usize, count: u64) -> ResponseResult {
Ok(BlockchainResponse::CoinbaseTxSum(todo!()))
}

View file

@ -10,10 +10,12 @@ pub mod ops;
#[cfg(feature = "service")]
pub mod service;
pub mod tables;
mod tx;
pub mod types;
pub use config::Config;
pub use free::open;
pub use tx::TxEntry;
//re-exports
pub use cuprate_database;

View file

@ -5,7 +5,7 @@ use std::sync::Arc;
use cuprate_types::TransactionVerificationData;
use crate::types::TransactionHash;
use crate::{tx::TxEntry, types::TransactionHash};
//---------------------------------------------------------------------------------------------------- TxpoolReadRequest
/// The transaction pool [`tower::Service`] read request type.
@ -16,10 +16,10 @@ pub enum TxpoolReadRequest {
/// A request for the [`TransactionVerificationData`] of a transaction in the tx pool.
TxVerificationData(TransactionHash),
/// TODO
/// Get information on all transactions in the pool.
Backlog,
/// TODO
/// Get the number of transactions in the pool.
Size,
}
@ -38,12 +38,14 @@ pub enum TxpoolReadResponse {
/// Response to [`TxpoolReadRequest::Backlog`].
///
/// TODO
Backlog(Vec<std::convert::Infallible>),
/// The inner `Vec` contains information on all
/// the transactions currently in the pool.
Backlog(Vec<TxEntry>),
/// Response to [`TxpoolReadRequest::Size`].
///
/// TODO
/// The inner value is the amount of
/// transactions currently in the pool.
Size(usize),
}

14
storage/txpool/src/tx.rs Normal file
View file

@ -0,0 +1,14 @@
//! Transaction metadata.
/// Data about a transaction in the pool.
///
/// Used in [`TxpoolReadResponse::Backlog`](crate::service::interface::TxpoolReadResponse::Backlog).
#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
pub struct TxEntry {
/// The transaction's weight.
pub weight: u64,
/// The transaction's fee.
pub fee: u64,
/// How long the transaction has been in the pool.
pub time_in_pool: std::time::Duration,
}

View file

@ -12,7 +12,8 @@ use monero_serai::block::Block;
use crate::{
types::{Chain, ExtendedBlockHeader, OutputOnChain, VerifiedBlockInformation},
AltBlockInformation, ChainId,
AltBlockInformation, ChainId, CoinbaseTxSum, MinerData, OutputHistogramEntry,
OutputHistogramInput,
};
//---------------------------------------------------------------------------------------------------- ReadRequest
@ -106,28 +107,38 @@ pub enum BlockchainReadRequest {
/// A request for all alt blocks in the chain with the given [`ChainId`].
AltBlocksInChain(ChainId),
/// TODO
Block(usize),
/// Get a [`Block`] by its height.
Block {
height: usize,
},
/// TODO
/// Get a [`Block`] by its hash.
BlockByHash([u8; 32]),
/// TODO
/// Get the total amount of non-coinbase transactions in the chain.
TotalTxCount,
/// TODO
/// Get the current size of the database.
DatabaseSize,
// TODO
// Get the difficulty for the next block in the chain.
Difficulty(usize),
/// TODO
OutputHistogram,
/// Get an output histogram.
///
/// TODO: document fields after impl.
OutputHistogram(OutputHistogramInput),
/// TODO
CoinbaseTxSum,
/// Get the coinbase amount and the fees amount for
/// `N` last blocks starting at particular height.
///
/// TODO: document fields after impl.
CoinbaseTxSum {
height: usize,
count: u64,
},
/// TODO
/// Get the necessary data to create a custom block template.
MinerData,
}
@ -242,54 +253,46 @@ pub enum BlockchainResponse {
cumulative_difficulty: u128,
},
/// The response for [`BlockchainReadRequest::FindFirstUnknown`].
/// Response to [`BlockchainReadRequest::FindFirstUnknown`].
///
/// Contains the index of the first unknown block and its expected height.
///
/// This will be [`None`] if all blocks were known.
FindFirstUnknown(Option<(usize, usize)>),
/// The response for [`BlockchainReadRequest::AltBlocksInChain`].
/// Response to [`BlockchainReadRequest::AltBlocksInChain`].
///
/// Contains all the alt blocks in the alt-chain in chronological order.
AltBlocksInChain(Vec<AltBlockInformation>),
/// The response for:
/// Response to:
/// - [`BlockchainReadRequest::Block`].
/// - [`BlockchainReadRequest::BlockByHash`].
///
/// TODO
Block(Block),
/// The response for [`BlockchainReadRequest::TotalTxCount`].
///
/// TODO
/// Response to [`BlockchainReadRequest::TotalTxCount`].
TotalTxCount(usize),
/// The response for [`BlockchainReadRequest::TotalTxCount`].
///
/// TODO
DatabaseSize { database_size: u64, free_space: u64 },
/// Response to [`BlockchainReadRequest::DatabaseSize`].
DatabaseSize {
/// The size of the database file in bytes.
database_size: u64,
/// The amount of free bytes there are
/// the disk where the database is located.
free_space: u64,
},
/// The response for [`BlockchainReadRequest::TotalTxCount`].
///
// TODO
/// Response to [`BlockchainReadRequest::Difficulty`].
Difficulty(u128),
/// The response for [`BlockchainReadRequest::TotalTxCount`].
///
/// TODO
OutputHistogram(std::convert::Infallible),
/// Response to [`BlockchainReadRequest::OutputHistogram`].
OutputHistogram(Vec<OutputHistogramEntry>),
/// The response for [`BlockchainReadRequest::TotalTxCount`].
///
/// TODO
CoinbaseTxSum(std::convert::Infallible),
/// Response to [`BlockchainReadRequest::CoinbaseTxSum`].
CoinbaseTxSum(CoinbaseTxSum),
/// The response for [`BlockchainReadRequest::TotalTxCount`].
///
/// TODO
MinerData(std::convert::Infallible),
/// Response to [`BlockchainReadRequest::MinerData`].
MinerData(MinerData),
//------------------------------------------------------ Writes
/// A generic Ok response to indicate a request was successfully handled.
@ -301,7 +304,7 @@ pub enum BlockchainResponse {
/// - [`BlockchainWriteRequest::FlushAltBlocks`]
Ok,
/// The response for [`BlockchainWriteRequest::PopBlocks`].
/// Response to [`BlockchainWriteRequest::PopBlocks`].
///
/// The inner value is the alt-chain ID for the old main chain blocks.
PopBlocks(ChainId),

View file

@ -20,8 +20,9 @@ pub use transaction_verification_data::{
CachedVerificationState, TransactionVerificationData, TxVersion,
};
pub use types::{
AltBlockInformation, Chain, ChainId, ExtendedBlockHeader, OutputOnChain,
VerifiedBlockInformation, VerifiedTransactionInformation,
AltBlockInformation, Chain, ChainId, ChainInfo, CoinbaseTxSum, ExtendedBlockHeader,
FeeEstimate, HardForkInfo, MinerData, MinerDataTxBacklogEntry, OutputHistogramEntry,
OutputHistogramInput, OutputOnChain, VerifiedBlockInformation, VerifiedTransactionInformation,
};
//---------------------------------------------------------------------------------------------------- Feature-gated

View file

@ -1,6 +1,5 @@
//! Various shared data types in Cuprate.
//---------------------------------------------------------------------------------------------------- Import
use std::num::NonZero;
use curve25519_dalek::edwards::EdwardsPoint;
@ -11,7 +10,6 @@ use monero_serai::{
use crate::HardFork;
//---------------------------------------------------------------------------------------------------- ExtendedBlockHeader
/// Extended header data of a block.
///
/// This contains various metadata of a block, but not the block blob itself.
@ -37,7 +35,6 @@ pub struct ExtendedBlockHeader {
pub long_term_weight: usize,
}
//---------------------------------------------------------------------------------------------------- VerifiedTransactionInformation
/// Verified information of a transaction.
///
/// This represents a valid transaction
@ -61,7 +58,6 @@ pub struct VerifiedTransactionInformation {
pub tx_hash: [u8; 32],
}
//---------------------------------------------------------------------------------------------------- VerifiedBlockInformation
/// Verified information of a block.
///
/// This represents a block that has already been verified to be correct.
@ -94,14 +90,12 @@ pub struct VerifiedBlockInformation {
pub cumulative_difficulty: u128,
}
//---------------------------------------------------------------------------------------------------- ChainID
/// A unique ID for an alt chain.
///
/// The inner value is meaningless.
#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
pub struct ChainId(pub NonZero<u64>);
//---------------------------------------------------------------------------------------------------- Chain
/// An identifier for a chain.
#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
pub enum Chain {
@ -111,7 +105,6 @@ pub enum Chain {
Alt(ChainId),
}
//---------------------------------------------------------------------------------------------------- AltBlockInformation
/// A block on an alternative chain.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct AltBlockInformation {
@ -141,7 +134,6 @@ pub struct AltBlockInformation {
pub chain_id: ChainId,
}
//---------------------------------------------------------------------------------------------------- OutputOnChain
/// An already existing transaction output.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct OutputOnChain {
@ -155,6 +147,104 @@ pub struct OutputOnChain {
pub commitment: EdwardsPoint,
}
/// Input required to generate an output histogram.
///
/// Used in RPC's `get_output_histogram`.
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct OutputHistogramInput {
pub amounts: Vec<u64>,
pub min_count: u64,
pub max_count: u64,
pub unlocked: bool,
pub recent_cutoff: u64,
}
/// A single entry in an output histogram.
///
/// Used in RPC's `get_output_histogram`.
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct OutputHistogramEntry {
pub amount: u64,
pub total_instances: u64,
pub unlocked_instances: u64,
pub recent_instances: u64,
}
/// Data of summed coinbase transactions.
///
/// Used in RPC's `get_coinbase_tx_sum`.
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct CoinbaseTxSum {
pub emission_amount: u128,
pub fee_amount: u128,
pub wide_emission_amount: u128,
pub wide_fee_amount: u128,
}
/// Data to create a custom block template.
///
/// Used in RPC's `get_miner_data`.
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct MinerData {
pub major_version: u8,
pub height: u64,
pub prev_id: [u8; 32],
pub seed_hash: [u8; 32],
pub difficulty: u128,
pub median_weight: u64,
pub already_generated_coins: u64,
pub tx_backlog: Vec<MinerDataTxBacklogEntry>,
}
/// A transaction in the txpool.
///
/// Used in [`MinerData::tx_backlog`].
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct MinerDataTxBacklogEntry {
pub id: [u8; 32],
pub weight: u64,
pub fee: u64,
}
/// Information on a [`HardFork`].
///
/// Used in RPC's `hard_fork_info`.
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct HardForkInfo {
pub earliest_height: u64,
pub enabled: bool,
pub state: u32,
pub threshold: u32,
pub version: u8,
pub votes: u32,
pub voting: u8,
pub window: u32,
}
/// Estimated fee data.
///
/// Used in RPC's `get_fee_estimate`.
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct FeeEstimate {
pub fee: u64,
pub fees: Vec<u64>,
pub quantization_mask: u64,
}
/// Information on a (maybe alternate) chain.
///
/// Used in RPC's `get_alternate_chains`.
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ChainInfo {
pub block_hash: [u8; 32],
pub block_hashes: Vec<[u8; 32]>,
pub difficulty: u128,
pub height: u64,
pub length: u64,
pub main_chain_parent_block: [u8; 32],
pub wide_difficulty: u128,
}
//---------------------------------------------------------------------------------------------------- Tests
#[cfg(test)]
mod test {