mirror of
https://github.com/hinto-janai/cuprate.git
synced 2024-12-23 03:59:37 +00:00
Compare commits
6 commits
f9ff59345c
...
e7f052f1d0
Author | SHA1 | Date | |
---|---|---|---|
|
e7f052f1d0 | ||
|
42d6f97847 | ||
|
64a3e5d5e9 | ||
|
cf331885b6 | ||
|
41f4b788b3 | ||
|
a003e0588d |
45 changed files with 517 additions and 172 deletions
4
.github/labeler.yml
vendored
4
.github/labeler.yml
vendored
|
@ -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
10
Cargo.lock
generated
|
@ -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",
|
||||
]
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ resolver = "2"
|
|||
|
||||
members = [
|
||||
"binaries/cuprated",
|
||||
"constants",
|
||||
"consensus",
|
||||
"consensus/fast-sync",
|
||||
"consensus/rules",
|
||||
|
|
|
@ -116,7 +116,7 @@ pub struct CupratedRpcHandler {
|
|||
}
|
||||
|
||||
impl CupratedRpcHandler {
|
||||
/// TODO
|
||||
/// Create a new [`Self`].
|
||||
pub const fn new(
|
||||
restricted: bool,
|
||||
blockchain_read: BlockchainReadHandle,
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//! Functions for TODO: doc enum message.
|
||||
//! Functions for [`BlockchainManagerRequest`] & [`BlockchainManagerResponse`].
|
||||
|
||||
use anyhow::Error;
|
||||
use monero_serai::block::Block;
|
||||
|
|
|
@ -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`]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
22
constants/Cargo.toml
Normal 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
3
constants/README.md
Normal 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.
|
|
@ -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
11
constants/src/block.rs
Normal 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
22
constants/src/build.rs
Normal 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
12
constants/src/lib.rs
Normal 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
35
constants/src/macros.rs
Normal 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
101
constants/src/rpc.rs
Normal 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;
|
|
@ -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 }
|
||||
|
|
|
@ -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 {}
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -7,6 +7,7 @@ authors = ["Boog900"]
|
|||
|
||||
|
||||
[dependencies]
|
||||
cuprate-constants = { path = "../../constants" }
|
||||
cuprate-pruning = { path = "../../pruning" }
|
||||
cuprate-p2p-core = { path = "../p2p-core" }
|
||||
|
||||
|
|
|
@ -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
|
||||
})?;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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`]
|
||||
|
|
|
@ -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"] }
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
);
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@ default = []
|
|||
borsh = ["dep:borsh"]
|
||||
|
||||
[dependencies]
|
||||
cuprate-constants = { path = "../constants" }
|
||||
|
||||
thiserror = { workspace = true }
|
||||
|
||||
borsh = { workspace = true, features = ["derive", "std"], optional = true }
|
||||
|
|
|
@ -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`
|
||||
///
|
||||
|
|
|
@ -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" }
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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!()))
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
14
storage/txpool/src/tx.rs
Normal 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,
|
||||
}
|
|
@ -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),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue