mirror of
https://github.com/hinto-janai/cuprate.git
synced 2024-12-23 03:59:37 +00:00
Compare commits
2 commits
825f54cebf
...
13bb6fbd8f
Author | SHA1 | Date | |
---|---|---|---|
|
13bb6fbd8f | ||
|
84b3719c99 |
10 changed files with 33 additions and 214 deletions
9
Cargo.lock
generated
9
Cargo.lock
generated
|
@ -604,14 +604,6 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cuprate-constants"
|
name = "cuprate-constants"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"hex",
|
|
||||||
"hex-literal",
|
|
||||||
"monero-serai",
|
|
||||||
"paste",
|
|
||||||
"pretty_assertions",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cuprate-cryptonight"
|
name = "cuprate-cryptonight"
|
||||||
|
@ -904,6 +896,7 @@ name = "cuprate-types"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
|
"cuprate-constants",
|
||||||
"cuprate-epee-encoding",
|
"cuprate-epee-encoding",
|
||||||
"cuprate-fixed-bytes",
|
"cuprate-fixed-bytes",
|
||||||
"curve25519-dalek",
|
"curve25519-dalek",
|
||||||
|
|
|
@ -12,18 +12,12 @@ keywords = ["cuprate", "constants"]
|
||||||
default = []
|
default = []
|
||||||
block = []
|
block = []
|
||||||
build = []
|
build = []
|
||||||
genesis = ["dep:monero-serai", "dep:hex-literal", "dep:paste"]
|
|
||||||
rpc = []
|
rpc = []
|
||||||
|
output = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cfg-if = { workspace = true }
|
|
||||||
monero-serai = { workspace = true, optional = true }
|
|
||||||
hex-literal = { workspace = true, optional = true }
|
|
||||||
paste = { workspace = true, optional = true }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
hex = { workspace = true, features = ["std"] }
|
|
||||||
pretty_assertions = { workspace = true }
|
|
||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
workspace = true
|
workspace = true
|
|
@ -1,6 +1,3 @@
|
||||||
# cuprate-constants
|
# cuprate-constants
|
||||||
This crate contains general constants that are not specific to any particular
|
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.
|
part of the codebase yet are used in multiple places such as the maximum block height.
|
||||||
|
|
||||||
## Static data
|
|
||||||
This crate also contains `static` data used in multiple places such as the genesis block.
|
|
|
@ -1,5 +1,7 @@
|
||||||
//! Block related.
|
//! Block related.
|
||||||
|
|
||||||
|
use core::time::Duration;
|
||||||
|
|
||||||
use crate::macros::monero_definition_link;
|
use crate::macros::monero_definition_link;
|
||||||
|
|
||||||
/// The maximum block height possible.
|
/// The maximum block height possible.
|
||||||
|
@ -9,3 +11,15 @@ pub const MAX_BLOCK_HEIGHT: u64 = 500_000_000;
|
||||||
/// [`MAX_BLOCK_HEIGHT`] as a [`usize`].
|
/// [`MAX_BLOCK_HEIGHT`] as a [`usize`].
|
||||||
#[expect(clippy::cast_possible_truncation, reason = "will not be truncated")]
|
#[expect(clippy::cast_possible_truncation, reason = "will not be truncated")]
|
||||||
pub const MAX_BLOCK_HEIGHT_USIZE: usize = MAX_BLOCK_HEIGHT as usize;
|
pub const MAX_BLOCK_HEIGHT_USIZE: usize = MAX_BLOCK_HEIGHT as usize;
|
||||||
|
|
||||||
|
/// Target block time for hardfork 1.
|
||||||
|
#[doc = monero_definition_link!(a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623, "/src/cryptonote_config.h", 81)]
|
||||||
|
///
|
||||||
|
/// ref: <https://monero-book.cuprate.org/consensus_rules/blocks/difficulty.html#target-seconds>
|
||||||
|
pub const BLOCK_TIME_V1: Duration = Duration::from_secs(60);
|
||||||
|
|
||||||
|
/// Target block time from hardfork v2.
|
||||||
|
#[doc = monero_definition_link!(a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623, "/src/cryptonote_config.h", 80)]
|
||||||
|
///
|
||||||
|
/// ref: <https://monero-book.cuprate.org/consensus_rules/blocks/difficulty.html#target-seconds>
|
||||||
|
pub const BLOCK_TIME_V2: Duration = Duration::from_secs(120);
|
||||||
|
|
|
@ -1,177 +0,0 @@
|
||||||
//! Genesis block/transaction data.
|
|
||||||
|
|
||||||
#![expect(const_item_mutation, reason = "&mut is needed for `Read`")]
|
|
||||||
|
|
||||||
/// Generate genesis block/transaction data and tests for multiple networks.
|
|
||||||
///
|
|
||||||
/// Input string literals are in hexadecimal form.
|
|
||||||
macro_rules! generate_genesis_consts {
|
|
||||||
($(
|
|
||||||
$network:ident {
|
|
||||||
nonce: $nonce:literal,
|
|
||||||
block: $block:literal,
|
|
||||||
block_hash: $block_hash:literal,
|
|
||||||
tx: $tx:literal,
|
|
||||||
tx_hash: $tx_hash:literal,
|
|
||||||
}
|
|
||||||
)*) => { paste::paste! {
|
|
||||||
$(
|
|
||||||
#[doc = concat!(stringify!([<$network:camel>]), " data.")]
|
|
||||||
pub mod [<$network:lower>] {
|
|
||||||
use monero_serai::{block::Block, transaction::Transaction};
|
|
||||||
use std::sync::LazyLock;
|
|
||||||
|
|
||||||
#[doc = concat!("The ", stringify!([<$network:lower>]), " genesis block in [`Block`] form.")]
|
|
||||||
pub static GENESIS_BLOCK: LazyLock<Block> =
|
|
||||||
LazyLock::new(|| Block::read(&mut GENESIS_BLOCK_BYTES).unwrap());
|
|
||||||
|
|
||||||
#[doc = concat!("The ", stringify!([<$network:lower>]), " genesis block in hexadecimal form.")]
|
|
||||||
pub const GENESIS_BLOCK_HEX: &str = $block;
|
|
||||||
|
|
||||||
#[doc = concat!("The ", stringify!([<$network:lower>]), " genesis block in byte form.")]
|
|
||||||
pub const GENESIS_BLOCK_BYTES: &[u8] = &hex_literal::hex!($block);
|
|
||||||
|
|
||||||
#[doc = concat!("The hash of the ", stringify!([<$network:lower>]), " genesis block in hexadecimal form.")]
|
|
||||||
pub const GENESIS_BLOCK_HASH_HEX: &str = $block_hash;
|
|
||||||
|
|
||||||
#[doc = concat!("The hash of the ", stringify!([<$network:lower>]), " genesis block in byte form.")]
|
|
||||||
pub const GENESIS_BLOCK_HASH_BYTES: [u8; 32] = hex_literal::hex!($block_hash);
|
|
||||||
|
|
||||||
#[doc = concat!("The ", stringify!([<$network:lower>]), " genesis block in [`Transaction`] form.")]
|
|
||||||
pub static GENESIS_TX: LazyLock<Transaction> =
|
|
||||||
LazyLock::new(|| Transaction::read(&mut GENESIS_TX_BYTES).unwrap());
|
|
||||||
|
|
||||||
#[doc = concat!("The ", stringify!([<$network:lower>]), " genesis transaction in hexadecimal form.")]
|
|
||||||
pub const GENESIS_TX_HEX: &str = $tx;
|
|
||||||
|
|
||||||
#[doc = concat!("The ", stringify!([<$network:lower>]), " genesis transaction in byte form.")]
|
|
||||||
pub const GENESIS_TX_BYTES: &[u8] = &hex_literal::hex!($tx);
|
|
||||||
|
|
||||||
#[doc = concat!("The hash of the ", stringify!([<$network:lower>]), " genesis transaction in hexadecimal form.")]
|
|
||||||
pub const GENESIS_TX_HASH_HEX: &str = $tx_hash;
|
|
||||||
|
|
||||||
#[doc = concat!("The hash of the ", stringify!([<$network:lower>]), " genesis transaction in byte form.")]
|
|
||||||
pub const GENESIS_TX_HASH_BYTES: [u8; 32] = hex_literal::hex!($tx_hash);
|
|
||||||
|
|
||||||
#[doc = concat!("The nonce of the ", stringify!([<$network:lower>]), " genesis block.")]
|
|
||||||
pub const GENESIS_NONCE: u32 = $nonce;
|
|
||||||
|
|
||||||
// Generate tests for all input networks.
|
|
||||||
#[cfg(test)]
|
|
||||||
mod test {
|
|
||||||
use monero_serai::{block::Block, transaction::Transaction};
|
|
||||||
use pretty_assertions::assert_eq;
|
|
||||||
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
/// Assert the block bytes/hash are correct.
|
|
||||||
fn genesis_block() {
|
|
||||||
let block = Block::read(&mut GENESIS_BLOCK_BYTES).unwrap();
|
|
||||||
assert_eq!(block.serialize(), &*GENESIS_BLOCK_BYTES);
|
|
||||||
assert_eq!(block.hash(), GENESIS_BLOCK_HASH_BYTES);
|
|
||||||
assert_eq!(block.hash(), GENESIS_BLOCK.hash());
|
|
||||||
assert_eq!(&block, &*GENESIS_BLOCK);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
/// Assert the genesis transaction in the block is correct.
|
|
||||||
fn genesis_block_tx() {
|
|
||||||
let block = Block::read(&mut GENESIS_BLOCK_BYTES).unwrap();
|
|
||||||
assert_eq!(block.miner_transaction.serialize(), &*GENESIS_TX_BYTES);
|
|
||||||
assert_eq!(block.miner_transaction.hash(), GENESIS_TX_HASH_BYTES);
|
|
||||||
assert_eq!(block.miner_transaction.hash(), GENESIS_BLOCK.miner_transaction.hash());
|
|
||||||
assert_eq!(&block.miner_transaction, &GENESIS_BLOCK.miner_transaction);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
/// Assert the hex is the same as the bytes.
|
|
||||||
fn genesis_block_hex_same_as_bytes() {
|
|
||||||
assert_eq!(
|
|
||||||
hex::decode(GENESIS_BLOCK_HEX).unwrap(),
|
|
||||||
GENESIS_BLOCK_BYTES
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
GENESIS_BLOCK_HEX,
|
|
||||||
hex::encode(GENESIS_BLOCK_BYTES)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
/// Assert the hash hex is the same as the bytes.
|
|
||||||
fn genesis_block_hash_hex_same_as_bytes() {
|
|
||||||
assert_eq!(
|
|
||||||
hex::decode(GENESIS_BLOCK_HASH_HEX).unwrap(),
|
|
||||||
GENESIS_BLOCK_HASH_BYTES
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
GENESIS_BLOCK_HASH_HEX,
|
|
||||||
hex::encode(GENESIS_BLOCK_HASH_BYTES)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
/// Assert the transaction bytes/hash are correct.
|
|
||||||
fn genesis_tx() {
|
|
||||||
let tx = Transaction::read(&mut GENESIS_TX_BYTES).unwrap();
|
|
||||||
assert_eq!(tx.hash(), GENESIS_TX_HASH_BYTES);
|
|
||||||
assert_eq!(tx.hash(), GENESIS_TX.hash());
|
|
||||||
assert_eq!(&tx, &*GENESIS_TX);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
/// Assert the hex is the same as the bytes.
|
|
||||||
fn genesis_tx_hex_same_as_bytes() {
|
|
||||||
assert_eq!(
|
|
||||||
hex::decode(GENESIS_TX_HEX).unwrap(),
|
|
||||||
GENESIS_TX_BYTES
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
GENESIS_TX_HEX,
|
|
||||||
hex::encode(GENESIS_TX_BYTES)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
/// Assert the hash hex is the same as the bytes.
|
|
||||||
fn genesis_tx_hash_hex_same_as_bytes() {
|
|
||||||
assert_eq!(
|
|
||||||
hex::decode(GENESIS_TX_HASH_HEX).unwrap(),
|
|
||||||
GENESIS_TX_HASH_BYTES
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
GENESIS_TX_HASH_HEX,
|
|
||||||
hex::encode(GENESIS_TX_HASH_BYTES)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)*
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
|
|
||||||
generate_genesis_consts! {
|
|
||||||
Mainnet {
|
|
||||||
nonce: 10000,
|
|
||||||
block: "010000000000000000000000000000000000000000000000000000000000000000000010270000013c01ff0001ffffffffffff03029b2e4c0281c0b02e7c53291a94d1d0cbff8883f8024f5142ee494ffbbd08807121017767aafcde9be00dcfd098715ebcf7f410daebc582fda69d24a28e9d0bc890d100",
|
|
||||||
block_hash: "418015bb9ae982a1975da7d79277c2705727a56894ba0fb246adaabb1f4632e3",
|
|
||||||
tx: "013c01ff0001ffffffffffff03029b2e4c0281c0b02e7c53291a94d1d0cbff8883f8024f5142ee494ffbbd08807121017767aafcde9be00dcfd098715ebcf7f410daebc582fda69d24a28e9d0bc890d1",
|
|
||||||
tx_hash: "c88ce9783b4f11190d7b9c17a69c1c52200f9faaee8e98dd07e6811175177139",
|
|
||||||
}
|
|
||||||
|
|
||||||
Testnet {
|
|
||||||
nonce: 10001,
|
|
||||||
block: "010000000000000000000000000000000000000000000000000000000000000000000011270000013c01ff0001ffffffffffff03029b2e4c0281c0b02e7c53291a94d1d0cbff8883f8024f5142ee494ffbbd08807121017767aafcde9be00dcfd098715ebcf7f410daebc582fda69d24a28e9d0bc890d100",
|
|
||||||
block_hash: "48ca7cd3c8de5b6a4d53d2861fbdaedca141553559f9be9520068053cda8430b",
|
|
||||||
tx: "013c01ff0001ffffffffffff03029b2e4c0281c0b02e7c53291a94d1d0cbff8883f8024f5142ee494ffbbd08807121017767aafcde9be00dcfd098715ebcf7f410daebc582fda69d24a28e9d0bc890d1",
|
|
||||||
tx_hash: "c88ce9783b4f11190d7b9c17a69c1c52200f9faaee8e98dd07e6811175177139",
|
|
||||||
}
|
|
||||||
|
|
||||||
Stagenet {
|
|
||||||
nonce: 10002,
|
|
||||||
block: "010000000000000000000000000000000000000000000000000000000000000000000012270000013c01ff0001ffffffffffff0302df5d56da0c7d643ddd1ce61901c7bdc5fb1738bfe39fbe69c28a3a7032729c0f2101168d0c4ca86fb55a4cf6a36d31431be1c53a3bd7411bb24e8832410289fa6f3b00",
|
|
||||||
block_hash: "76ee3cc98646292206cd3e86f74d88b4dcc1d937088645e9b0cbca84b7ce74eb",
|
|
||||||
tx: "013c01ff0001ffffffffffff0302df5d56da0c7d643ddd1ce61901c7bdc5fb1738bfe39fbe69c28a3a7032729c0f2101168d0c4ca86fb55a4cf6a36d31431be1c53a3bd7411bb24e8832410289fa6f3b",
|
|
||||||
tx_hash: "c099809301da6ad2fde11969b0e9cb291fc698f8dc678cef00506e7baf561de4",
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,13 +1,6 @@
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
#![deny(missing_docs, reason = "all constants should document what they are")]
|
#![deny(missing_docs, reason = "all constants should document what they are")]
|
||||||
|
#![no_std] // This can be removed if we eventually need `std`.
|
||||||
cfg_if::cfg_if! {
|
|
||||||
// Used in test modules.
|
|
||||||
if #[cfg(test)] {
|
|
||||||
use hex as _;
|
|
||||||
use pretty_assertions as _;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod macros;
|
mod macros;
|
||||||
|
|
||||||
|
@ -15,7 +8,7 @@ mod macros;
|
||||||
pub mod block;
|
pub mod block;
|
||||||
#[cfg(feature = "build")]
|
#[cfg(feature = "build")]
|
||||||
pub mod build;
|
pub mod build;
|
||||||
#[cfg(feature = "genesis")]
|
#[cfg(feature = "output")]
|
||||||
pub mod genesis;
|
pub mod output;
|
||||||
#[cfg(feature = "rpc")]
|
#[cfg(feature = "rpc")]
|
||||||
pub mod rpc;
|
pub mod rpc;
|
||||||
|
|
11
constants/src/output.rs
Normal file
11
constants/src/output.rs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
//! Output related.
|
||||||
|
|
||||||
|
use crate::macros::monero_definition_link;
|
||||||
|
|
||||||
|
/// The minimum amount of blocks a coinbase output is locked for.
|
||||||
|
#[doc = monero_definition_link!(a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623, "/src/cryptonote_config.h", 40)]
|
||||||
|
pub const COINBASE_LOCK_WINDOW: usize = 60;
|
||||||
|
|
||||||
|
/// The minimum amount of blocks an output is locked for.
|
||||||
|
#[doc = monero_definition_link!(a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623, "/src/cryptonote_config.h", 49)]
|
||||||
|
pub const DEFAULT_LOCK_WINDOW: usize = 10;
|
|
@ -1,6 +1,6 @@
|
||||||
//! RPC related.
|
//! RPC related.
|
||||||
|
|
||||||
use std::time::Duration;
|
use core::time::Duration;
|
||||||
|
|
||||||
use crate::macros::monero_definition_link;
|
use crate::macros::monero_definition_link;
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ serde = ["dep:serde"]
|
||||||
proptest = ["dep:proptest", "dep:proptest-derive"]
|
proptest = ["dep:proptest", "dep:proptest-derive"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
cuprate-constants = { path = "../constants", features = ["block"] }
|
||||||
cuprate-epee-encoding = { path = "../net/epee-encoding", optional = true }
|
cuprate-epee-encoding = { path = "../net/epee-encoding", optional = true }
|
||||||
cuprate-fixed-bytes = { path = "../net/fixed-bytes" }
|
cuprate-fixed-bytes = { path = "../net/fixed-bytes" }
|
||||||
|
|
||||||
|
|
|
@ -3,14 +3,7 @@ use std::time::Duration;
|
||||||
|
|
||||||
use monero_serai::block::BlockHeader;
|
use monero_serai::block::BlockHeader;
|
||||||
|
|
||||||
/// Target block time for hf 1.
|
use cuprate_constants::block::{BLOCK_TIME_V1, BLOCK_TIME_V2};
|
||||||
///
|
|
||||||
/// ref: <https://monero-book.cuprate.org/consensus_rules/blocks/difficulty.html#target-seconds>
|
|
||||||
const BLOCK_TIME_V1: Duration = Duration::from_secs(60);
|
|
||||||
/// Target block time from v2.
|
|
||||||
///
|
|
||||||
/// ref: <https://monero-book.cuprate.org/consensus_rules/blocks/difficulty.html#target-seconds>
|
|
||||||
const BLOCK_TIME_V2: Duration = Duration::from_secs(120);
|
|
||||||
|
|
||||||
/// An error working with a [`HardFork`].
|
/// An error working with a [`HardFork`].
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, thiserror::Error)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, thiserror::Error)]
|
||||||
|
|
Loading…
Reference in a new issue